- Reorganized admin settings into tabbed interface (General, Security, Payment Methods) - Vertical tabs on desktop, horizontal scrollable on mobile - Moved Payment Methods from separate menu to Settings tab - Fixed admin profile reuse and dashboard blocking - Fixed maintenance mode guard to use AppConfig model - Added admin auto-redirect after login (admins → /admin, users → /) - Reorganized documentation into docs/ folder structure - Created comprehensive README and documentation index - Added PWA and Web Push notifications to to-do list
73 lines
2.1 KiB
TypeScript
73 lines
2.1 KiB
TypeScript
import {
|
|
Injectable,
|
|
CanActivate,
|
|
ExecutionContext,
|
|
ServiceUnavailableException,
|
|
} from '@nestjs/common';
|
|
import { Reflector } from '@nestjs/core';
|
|
import { PrismaService } from '../../prisma/prisma.service';
|
|
import { JwtService } from '@nestjs/jwt';
|
|
|
|
@Injectable()
|
|
export class MaintenanceGuard implements CanActivate {
|
|
constructor(
|
|
private reflector: Reflector,
|
|
private prisma: PrismaService,
|
|
private jwtService: JwtService,
|
|
) {}
|
|
|
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
// Check if route is exempt from maintenance mode (auth, health, admin routes)
|
|
const isExempt = this.reflector.get<boolean>('skipMaintenance', context.getHandler());
|
|
const isControllerExempt = this.reflector.get<boolean>('skipMaintenance', context.getClass());
|
|
|
|
if (isExempt || isControllerExempt) {
|
|
return true;
|
|
}
|
|
|
|
// Get maintenance mode status from config
|
|
const maintenanceConfig = await this.prisma.appConfig.findUnique({
|
|
where: { key: 'maintenance_mode' },
|
|
});
|
|
|
|
const isMaintenanceMode = maintenanceConfig?.value === 'true';
|
|
|
|
if (!isMaintenanceMode) {
|
|
return true;
|
|
}
|
|
|
|
// Try to extract user from JWT token (if exists)
|
|
const request = context.switchToHttp().getRequest();
|
|
const authHeader = request.headers.authorization;
|
|
|
|
if (authHeader && authHeader.startsWith('Bearer ')) {
|
|
try {
|
|
const token = authHeader.substring(7);
|
|
const payload = this.jwtService.verify(token);
|
|
|
|
// If user is admin, allow access
|
|
if (payload.role === 'admin') {
|
|
return true;
|
|
}
|
|
} catch (error) {
|
|
// Invalid token, continue to block
|
|
}
|
|
}
|
|
|
|
// Get maintenance message
|
|
const messageConfig = await this.prisma.appConfig.findUnique({
|
|
where: { key: 'maintenance_message' },
|
|
});
|
|
|
|
const message =
|
|
messageConfig?.value ||
|
|
'System is under maintenance. Please try again later.';
|
|
|
|
throw new ServiceUnavailableException({
|
|
statusCode: 503,
|
|
message: message,
|
|
maintenanceMode: true,
|
|
});
|
|
}
|
|
}
|