Remove todos os logs e refina back-end

This commit is contained in:
LeoMortari
2025-09-15 09:28:13 -03:00
parent 896184be94
commit f3ec966c3d
10 changed files with 10 additions and 156 deletions

View File

@@ -12,11 +12,6 @@ services:
DATABASE_URL: postgresql://leolitas:L@l321321321@postgres:5432/clipperia?schema=public DATABASE_URL: postgresql://leolitas:L@l321321321@postgres:5432/clipperia?schema=public
networks: networks:
- dokploy-network - 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: networks:
dokploy-network: dokploy-network:

View File

@@ -9,7 +9,6 @@ import { VideosController } from './videos/videos.controller';
import { UsuariosModule } from './usuarios/usuarios.module'; import { UsuariosModule } from './usuarios/usuarios.module';
import { LoggerMiddleware } from './middleware/logger.middleware'; import { LoggerMiddleware } from './middleware/logger.middleware';
import { RolesGuard } from './auth/roles.guard'; import { RolesGuard } from './auth/roles.guard';
import { TestModule } from './test/test.module';
@Module({ @Module({
imports: [ imports: [
@@ -18,7 +17,6 @@ import { TestModule } from './test/test.module';
VideosModule, VideosModule,
AuthModule, AuthModule,
UsuariosModule, UsuariosModule,
TestModule,
], ],
controllers: [AppController], controllers: [AppController],
providers: [AppService, RolesGuard], providers: [AppService, RolesGuard],

View File

@@ -1,21 +1,16 @@
import { Injectable, Logger, UnauthorizedException } from '@nestjs/common'; import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport'; import { AuthGuard } from '@nestjs/passport';
import type { JwtPayload } from './keycloak.strategy'; import type { JwtPayload } from './keycloak.strategy';
@Injectable() @Injectable()
export class KeycloakAuthGuard extends AuthGuard('jwt') { export class KeycloakAuthGuard extends AuthGuard('jwt') {
private readonly logger = new Logger(KeycloakAuthGuard.name);
handleRequest<TUser = JwtPayload>( handleRequest<TUser = JwtPayload>(
err: unknown, err: unknown,
user: JwtPayload | false, user: JwtPayload | false,
info: unknown, info: unknown,
context: import('@nestjs/common').ExecutionContext, context: import('@nestjs/common').ExecutionContext,
): TUser { ): TUser {
this.logger.log(`KEYCLOAK_URL: ${process.env.KEYCLOAK_URL}`);
this.logger.log(`NODE_ENV: ${process.env.NODE_ENV}`);
if (err || !user) { if (err || !user) {
if (err instanceof UnauthorizedException) { if (err instanceof UnauthorizedException) {
throw err; throw err;

View File

@@ -49,71 +49,23 @@ export class KeycloakJwtStrategy extends PassportStrategy(Strategy, 'jwt') {
issuer: 'https://auth.clipperia.com.br/realms/clipperia', issuer: 'https://auth.clipperia.com.br/realms/clipperia',
ignoreExpiration: false, ignoreExpiration: false,
}); });
this.logger.verbose(`Using Keycloak URL: ${baseUrl}`);
} }
validate(payload: JwtPayload): JwtPayload { validate(payload: JwtPayload) {
try { 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); const now = Math.floor(Date.now() / 1000);
if (payload.exp < now) { 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'); throw new UnauthorizedException('Token expirado');
} }
this.logger.verbose('=== JWT Validation Successful ===');
return payload; return payload;
} catch (error: unknown) { } catch (error: unknown) {
const errorMessage = error instanceof Error ? error.stack : String(error); const errorMessage = error instanceof Error ? error.stack : String(error);
this.logger.error('JWT Validation Error:', errorMessage); this.logger.error('JWT Validation Error:', errorMessage);
throw error; throw error;
} }
return payload;
} }
} }

View File

@@ -3,7 +3,6 @@ import {
CanActivate, CanActivate,
ExecutionContext, ExecutionContext,
ForbiddenException, ForbiddenException,
Logger,
} from '@nestjs/common'; } from '@nestjs/common';
import { Reflector } from '@nestjs/core'; import { Reflector } from '@nestjs/core';
import { ROLES_KEY } from './decorator/roles.decorator'; import { ROLES_KEY } from './decorator/roles.decorator';
@@ -14,38 +13,22 @@ import type { JwtPayload } from './keycloak.strategy';
export class RolesGuard implements CanActivate { export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {} constructor(private reflector: Reflector) {}
private readonly logger = new Logger(RolesGuard.name);
private extractRoles(user: JwtPayload): string[] { private extractRoles(user: JwtPayload): string[] {
const roles: 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) { if (user.realm_access?.roles) {
this.logger.log(
`Found realm roles: ${JSON.stringify(user.realm_access.roles)}`,
);
roles.push(...user.realm_access.roles); roles.push(...user.realm_access.roles);
} }
if (user.resource_access) { if (user.resource_access) {
this.logger.log('Processing resource_access'); Object.entries(user.resource_access).forEach(([, resource]) => {
Object.entries(user.resource_access).forEach(
([resourceName, resource]) => {
this.logger.log(
`Resource ${resourceName} roles: ${JSON.stringify(resource?.roles)}`,
);
if (resource?.roles) { if (resource?.roles) {
roles.push(...resource.roles); roles.push(...resource.roles);
} }
}, });
);
} }
const uniqueRoles = [...new Set(roles)]; const uniqueRoles = [...new Set(roles)];
this.logger.log(`Final extracted roles: ${JSON.stringify(uniqueRoles)}`);
return uniqueRoles; return uniqueRoles;
} }
@@ -55,22 +38,14 @@ export class RolesGuard implements CanActivate {
[context.getHandler(), context.getClass()], [context.getHandler(), context.getClass()],
); );
this.logger.log(`Required roles: ${JSON.stringify(requiredRoles)}`);
if (!requiredRoles || !requiredRoles.length) { if (!requiredRoles || !requiredRoles.length) {
this.logger.log('No roles required for this route');
return true; return true;
} }
const request = context.switchToHttp().getRequest<{ user: JwtPayload }>(); const request = context.switchToHttp().getRequest<{ user: JwtPayload }>();
const user = request.user; const user = request.user;
this.logger.log(
`User object from request: ${JSON.stringify(user, null, 2)}`,
);
if (!user) { if (!user) {
this.logger.error('No user found in request');
throw new ForbiddenException('Usuário não autenticado'); throw new ForbiddenException('Usuário não autenticado');
} }

View File

@@ -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();
});
});

View File

@@ -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);
}
}

View File

@@ -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 {}

View File

@@ -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();
});
});

View File

@@ -1,4 +0,0 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class TestService {}