Remove todos os logs e refina back-end
This commit is contained in:
@@ -12,11 +12,6 @@ services:
|
||||
DATABASE_URL: postgresql://leolitas:L@l321321321@postgres:5432/clipperia?schema=public
|
||||
networks:
|
||||
- dokploy-network
|
||||
labels:
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.http.routers.backend.rule=Host(`api.clipperia.com.br`)'
|
||||
- 'traefik.http.routers.backend.entrypoints=websecure'
|
||||
- 'traefik.http.routers.backend.tls.certresolver=letsencrypt'
|
||||
|
||||
networks:
|
||||
dokploy-network:
|
||||
|
||||
@@ -9,7 +9,6 @@ import { VideosController } from './videos/videos.controller';
|
||||
import { UsuariosModule } from './usuarios/usuarios.module';
|
||||
import { LoggerMiddleware } from './middleware/logger.middleware';
|
||||
import { RolesGuard } from './auth/roles.guard';
|
||||
import { TestModule } from './test/test.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -18,7 +17,6 @@ import { TestModule } from './test/test.module';
|
||||
VideosModule,
|
||||
AuthModule,
|
||||
UsuariosModule,
|
||||
TestModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService, RolesGuard],
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
import { Injectable, Logger, UnauthorizedException } from '@nestjs/common';
|
||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
import type { JwtPayload } from './keycloak.strategy';
|
||||
|
||||
@Injectable()
|
||||
export class KeycloakAuthGuard extends AuthGuard('jwt') {
|
||||
private readonly logger = new Logger(KeycloakAuthGuard.name);
|
||||
|
||||
handleRequest<TUser = JwtPayload>(
|
||||
err: unknown,
|
||||
user: JwtPayload | false,
|
||||
info: unknown,
|
||||
context: import('@nestjs/common').ExecutionContext,
|
||||
): TUser {
|
||||
this.logger.log(`KEYCLOAK_URL: ${process.env.KEYCLOAK_URL}`);
|
||||
this.logger.log(`NODE_ENV: ${process.env.NODE_ENV}`);
|
||||
|
||||
if (err || !user) {
|
||||
if (err instanceof UnauthorizedException) {
|
||||
throw err;
|
||||
|
||||
@@ -49,71 +49,23 @@ export class KeycloakJwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
||||
issuer: 'https://auth.clipperia.com.br/realms/clipperia',
|
||||
ignoreExpiration: false,
|
||||
});
|
||||
|
||||
this.logger.verbose(`Using Keycloak URL: ${baseUrl}`);
|
||||
}
|
||||
|
||||
validate(payload: JwtPayload): JwtPayload {
|
||||
validate(payload: JwtPayload) {
|
||||
try {
|
||||
this.logger.verbose('=== JWT Validation Start ===');
|
||||
|
||||
this.logger.verbose(`Subject (sub): ${payload.sub}`);
|
||||
this.logger.verbose(`Issuer (iss): ${payload.iss}`);
|
||||
this.logger.verbose(`Audience (aud): ${JSON.stringify(payload.aud)}`);
|
||||
this.logger.verbose(
|
||||
`Issued At (iat): ${new Date(payload.iat * 1000).toISOString()}`,
|
||||
);
|
||||
this.logger.verbose(
|
||||
`Expiration (exp): ${new Date(payload.exp * 1000).toISOString()}`,
|
||||
);
|
||||
this.logger.verbose('--- User Info ---');
|
||||
this.logger.verbose(`Email: ${payload.email || 'N/A'}`);
|
||||
this.logger.verbose(`Username: ${payload.preferred_username || 'N/A'}`);
|
||||
this.logger.verbose(
|
||||
`Name: ${payload.given_name || ''} ${payload.family_name || ''}`.trim() ||
|
||||
'N/A',
|
||||
);
|
||||
|
||||
// Realm roles
|
||||
this.logger.verbose('--- Realm Access ---');
|
||||
if (payload.realm_access?.roles?.length) {
|
||||
payload.realm_access.roles.forEach((role: string) => {
|
||||
this.logger.verbose(`- ${role}`);
|
||||
});
|
||||
} else {
|
||||
this.logger.verbose('No realm roles found');
|
||||
}
|
||||
|
||||
// Resource access
|
||||
this.logger.verbose('--- Resource Access ---');
|
||||
if (payload.resource_access) {
|
||||
Object.entries(payload.resource_access).forEach(([resource, data]) => {
|
||||
if (data?.roles?.length) {
|
||||
this.logger.verbose(`${resource} roles:`);
|
||||
data.roles.forEach((role: string) => {
|
||||
this.logger.verbose(` - ${role}`);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.logger.verbose('No resource access found');
|
||||
}
|
||||
|
||||
// Token expiration check
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
|
||||
if (payload.exp < now) {
|
||||
const minutesAgo = Math.round((now - payload.exp) / 60);
|
||||
this.logger.warn(`Token expired ${minutesAgo} minutes ago`);
|
||||
throw new UnauthorizedException('Token expirado');
|
||||
}
|
||||
|
||||
this.logger.verbose('=== JWT Validation Successful ===');
|
||||
return payload;
|
||||
} catch (error: unknown) {
|
||||
const errorMessage = error instanceof Error ? error.stack : String(error);
|
||||
|
||||
this.logger.error('JWT Validation Error:', errorMessage);
|
||||
|
||||
throw error;
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
ForbiddenException,
|
||||
Logger,
|
||||
} from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { ROLES_KEY } from './decorator/roles.decorator';
|
||||
@@ -14,38 +13,22 @@ import type { JwtPayload } from './keycloak.strategy';
|
||||
export class RolesGuard implements CanActivate {
|
||||
constructor(private reflector: Reflector) {}
|
||||
|
||||
private readonly logger = new Logger(RolesGuard.name);
|
||||
|
||||
private extractRoles(user: JwtPayload): string[] {
|
||||
const roles: string[] = [];
|
||||
|
||||
this.logger.log('Extracting roles from user object');
|
||||
this.logger.log(`realm_access: ${JSON.stringify(user.realm_access)}`);
|
||||
this.logger.log(`resource_access: ${JSON.stringify(user.resource_access)}`);
|
||||
|
||||
if (user.realm_access?.roles) {
|
||||
this.logger.log(
|
||||
`Found realm roles: ${JSON.stringify(user.realm_access.roles)}`,
|
||||
);
|
||||
roles.push(...user.realm_access.roles);
|
||||
}
|
||||
|
||||
if (user.resource_access) {
|
||||
this.logger.log('Processing resource_access');
|
||||
Object.entries(user.resource_access).forEach(
|
||||
([resourceName, resource]) => {
|
||||
this.logger.log(
|
||||
`Resource ${resourceName} roles: ${JSON.stringify(resource?.roles)}`,
|
||||
);
|
||||
if (resource?.roles) {
|
||||
roles.push(...resource.roles);
|
||||
}
|
||||
},
|
||||
);
|
||||
Object.entries(user.resource_access).forEach(([, resource]) => {
|
||||
if (resource?.roles) {
|
||||
roles.push(...resource.roles);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const uniqueRoles = [...new Set(roles)];
|
||||
this.logger.log(`Final extracted roles: ${JSON.stringify(uniqueRoles)}`);
|
||||
return uniqueRoles;
|
||||
}
|
||||
|
||||
@@ -55,22 +38,14 @@ export class RolesGuard implements CanActivate {
|
||||
[context.getHandler(), context.getClass()],
|
||||
);
|
||||
|
||||
this.logger.log(`Required roles: ${JSON.stringify(requiredRoles)}`);
|
||||
|
||||
if (!requiredRoles || !requiredRoles.length) {
|
||||
this.logger.log('No roles required for this route');
|
||||
return true;
|
||||
}
|
||||
|
||||
const request = context.switchToHttp().getRequest<{ user: JwtPayload }>();
|
||||
const user = request.user;
|
||||
|
||||
this.logger.log(
|
||||
`User object from request: ${JSON.stringify(user, null, 2)}`,
|
||||
);
|
||||
|
||||
if (!user) {
|
||||
this.logger.error('No user found in request');
|
||||
throw new ForbiddenException('Usuário não autenticado');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { TestController } from './test.controller';
|
||||
|
||||
describe('TestController', () => {
|
||||
let controller: TestController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [TestController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<TestController>(TestController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Controller, Get, Req } from '@nestjs/common';
|
||||
import type { Request } from 'express';
|
||||
|
||||
@Controller('test')
|
||||
export class TestController {
|
||||
@Get()
|
||||
debug(@Req() req: Request): string {
|
||||
console.log('HEADERS:', req.headers);
|
||||
|
||||
return JSON.stringify(req.headers);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TestController } from './test.controller';
|
||||
import { TestService } from './test.service';
|
||||
|
||||
@Module({
|
||||
controllers: [TestController],
|
||||
providers: [TestService]
|
||||
})
|
||||
export class TestModule {}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { TestService } from './test.service';
|
||||
|
||||
describe('TestService', () => {
|
||||
let service: TestService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [TestService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<TestService>(TestService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -1,4 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class TestService {}
|
||||
Reference in New Issue
Block a user