crud product
This commit is contained in:
@@ -17,7 +17,6 @@ import { PermissionsService } from 'src/modules/roles/providers/permissions.serv
|
||||
|
||||
export interface AdminAuthRequest extends Request {
|
||||
adminId: string;
|
||||
restId: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
@@ -61,7 +60,7 @@ export class AdminAuthGuard implements CanActivate {
|
||||
}
|
||||
|
||||
request['adminId'] = payload.adminId;
|
||||
request['restId'] = payload.restId;
|
||||
|
||||
|
||||
// check if the user has the required permissions
|
||||
const requiredPermissions =
|
||||
|
||||
@@ -6,7 +6,6 @@ import { ITokenPayload } from '../interfaces/IToken-payload';
|
||||
|
||||
export interface UserAuthRequest extends Request {
|
||||
userId: string;
|
||||
restId: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
@@ -26,10 +25,7 @@ export class AuthGuard implements CanActivate {
|
||||
try {
|
||||
const secret = this.configService.getOrThrow<string>('JWT_SECRET');
|
||||
const token = this.extractTokenFromHeader(request);
|
||||
const slug = this.extractSlugFromHeader(request);
|
||||
if (!slug) {
|
||||
throw new UnauthorizedException('Slug is required');
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
@@ -42,11 +38,9 @@ export class AuthGuard implements CanActivate {
|
||||
this.logger.error('Invalid token payload structure', payload);
|
||||
throw new UnauthorizedException('Invalid token payload');
|
||||
}
|
||||
if (payload.slug !== slug) {
|
||||
throw new UnauthorizedException('Invalid slug');
|
||||
}
|
||||
|
||||
request['userId'] = payload.userId;
|
||||
request['restId'] = payload.restId;
|
||||
|
||||
} catch {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
@@ -64,9 +58,5 @@ export class AuthGuard implements CanActivate {
|
||||
const [type, token] = request.headers.authorization?.split(' ') ?? [];
|
||||
return type === 'Bearer' ? token : undefined;
|
||||
}
|
||||
private extractSlugFromHeader(request: Request): string | undefined {
|
||||
// Fastify normalizes headers to lowercase, so check both cases
|
||||
const slug = (request.headers['x-slug'] || request.headers['X-Slug']) as string;
|
||||
return slug;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
import { CanActivate, ExecutionContext, Injectable, Inject, Logger } from '@nestjs/common';
|
||||
import { Request } from 'express';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { ITokenPayload } from '../interfaces/IToken-payload';
|
||||
|
||||
export interface UserOptionalAuthRequest extends Request {
|
||||
userId?: string;
|
||||
restId?: string;
|
||||
slug?: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class OptionalAuthGuard implements CanActivate {
|
||||
private readonly logger = new Logger(OptionalAuthGuard.name);
|
||||
|
||||
constructor(
|
||||
@Inject(JwtService)
|
||||
private readonly jwtService: JwtService,
|
||||
@Inject(ConfigService)
|
||||
private readonly configService: ConfigService,
|
||||
) {}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const request = context.switchToHttp().getRequest<UserOptionalAuthRequest>();
|
||||
const token = this.extractTokenFromHeader(request);
|
||||
const slug = this.extractSlugFromHeader(request);
|
||||
|
||||
// If no token is provided, allow the request without authentication
|
||||
if (!slug) {
|
||||
console.log('No slug provided');
|
||||
this.logger.warn('No slug provided');
|
||||
return false;
|
||||
}
|
||||
if (!token) {
|
||||
request['slug'] = slug;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to verify the token if it exists
|
||||
try {
|
||||
const secret = this.configService.getOrThrow<string>('JWT_SECRET');
|
||||
const payload = await this.jwtService.verifyAsync<ITokenPayload>(token, {
|
||||
secret,
|
||||
});
|
||||
|
||||
// Validate payload structure
|
||||
if (!payload.userId || !payload.restId) {
|
||||
this.logger.warn('Invalid token payload structure', payload);
|
||||
// Allow request but don't set user info
|
||||
request['slug'] = slug;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Validate slug if provided
|
||||
if (slug && payload.slug !== slug) {
|
||||
this.logger.warn('Token slug does not match header slug', {
|
||||
tokenSlug: payload.slug,
|
||||
headerSlug: slug,
|
||||
});
|
||||
// Allow request but don't set user info
|
||||
request['slug'] = slug;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Token is valid, set user info
|
||||
request['userId'] = payload.userId;
|
||||
request['restId'] = payload.restId;
|
||||
request['slug'] = slug;
|
||||
return true;
|
||||
} catch (err) {
|
||||
// Token is invalid or expired, but allow the request anyway
|
||||
this.logger.debug('Token verification failed in OptionalAuthGuard', {
|
||||
error: err instanceof Error ? err.message : 'Unknown error',
|
||||
});
|
||||
// Set restId from slug
|
||||
|
||||
request['slug'] = slug;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private extractTokenFromHeader(request: Request): string | undefined {
|
||||
const [type, token] = request.headers.authorization?.split(' ') ?? [];
|
||||
return type === 'Bearer' ? token : undefined;
|
||||
}
|
||||
|
||||
private extractSlugFromHeader(request: Request): string | undefined {
|
||||
// Fastify normalizes headers to lowercase, so check both cases
|
||||
const slug = (request.headers['x-slug'] || request.headers['X-Slug']) as string;
|
||||
return slug;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
import { CanActivate, ExecutionContext, Injectable, UnauthorizedException, Inject, Logger } from '@nestjs/common';
|
||||
import { Request } from 'express';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@Injectable()
|
||||
export class SuperAdminAuthGuard implements CanActivate {
|
||||
private readonly logger = new Logger(SuperAdminAuthGuard.name);
|
||||
|
||||
constructor(
|
||||
@Inject(ConfigService)
|
||||
private readonly configService: ConfigService,
|
||||
) {}
|
||||
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
const request = context.switchToHttp().getRequest<Request>();
|
||||
|
||||
try {
|
||||
const credentials = this.extractBasicAuthCredentials(request);
|
||||
if (!credentials) {
|
||||
throw new UnauthorizedException('Basic authentication required');
|
||||
}
|
||||
|
||||
const { username, password } = credentials;
|
||||
const expectedUsername = this.configService.get<string>('SUPER_ADMIN_USERNAME') ?? 'danak@dsc.com';
|
||||
const expectedPassword = this.configService.get<string>('SUPER_ADMIN_PASSWORD') ?? 'DsCdAnAk?@ABC';
|
||||
if (username !== expectedUsername || password !== expectedPassword) {
|
||||
this.logger.warn(`Invalid super admin credentials attempt for username: ${username}`);
|
||||
throw new UnauthorizedException('Invalid credentials');
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
if (err instanceof UnauthorizedException) {
|
||||
throw err;
|
||||
}
|
||||
this.logger.error('error in SuperAdminAuthGuard', err);
|
||||
throw new UnauthorizedException('Authentication failed');
|
||||
}
|
||||
}
|
||||
|
||||
private extractBasicAuthCredentials(request: Request): { username: string; password: string } | null {
|
||||
const authHeader = request.headers.authorization;
|
||||
if (!authHeader) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [type, encoded] = authHeader.split(' ');
|
||||
if (type?.toLowerCase() !== 'basic' || !encoded) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');
|
||||
const [username, password] = decoded.split(':');
|
||||
|
||||
if (!username || !password) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { username, password };
|
||||
} catch (error) {
|
||||
this.logger.error('Failed to decode Basic Auth credentials', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user