ajuste no command
This commit is contained in:
14
package-lock.json
generated
14
package-lock.json
generated
@@ -13,6 +13,7 @@
|
|||||||
"@nestjs/common": "^11.0.12",
|
"@nestjs/common": "^11.0.12",
|
||||||
"@nestjs/config": "^4.0.2",
|
"@nestjs/config": "^4.0.2",
|
||||||
"@nestjs/core": "^11.0.12",
|
"@nestjs/core": "^11.0.12",
|
||||||
|
"@nestjs/cqrs": "^11.0.3",
|
||||||
"@nestjs/jwt": "^11.0.0",
|
"@nestjs/jwt": "^11.0.0",
|
||||||
"@nestjs/mapped-types": "^1.0.0",
|
"@nestjs/mapped-types": "^1.0.0",
|
||||||
"@nestjs/microservices": "^11.0.12",
|
"@nestjs/microservices": "^11.0.12",
|
||||||
@@ -1905,6 +1906,7 @@
|
|||||||
"version": "11.0.12",
|
"version": "11.0.12",
|
||||||
"resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.0.12.tgz",
|
"resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.0.12.tgz",
|
||||||
"integrity": "sha512-6PXxmDe2iYmb57xacnxzpW1NAxRZ7Gf+acMT7/hmRB/4KpZiFU/cNvLWwgbM2BL5QSzQulOwY6ny5bbKnPpB+A==",
|
"integrity": "sha512-6PXxmDe2iYmb57xacnxzpW1NAxRZ7Gf+acMT7/hmRB/4KpZiFU/cNvLWwgbM2BL5QSzQulOwY6ny5bbKnPpB+A==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"iterare": "1.2.1",
|
"iterare": "1.2.1",
|
||||||
"tslib": "2.8.1",
|
"tslib": "2.8.1",
|
||||||
@@ -1984,6 +1986,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@nestjs/cqrs": {
|
||||||
|
"version": "11.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nestjs/cqrs/-/cqrs-11.0.3.tgz",
|
||||||
|
"integrity": "sha512-2ezBftiXqVfNTzjCrmhazohYhIQzgm8rvM0aKndv73IOOBcVlNuNiQ3HHiHdd4c2w/3MOQDtsGbQHgZUuW6DPw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
||||||
|
"@nestjs/core": "^10.0.0 || ^11.0.0",
|
||||||
|
"reflect-metadata": "^0.1.13 || ^0.2.0",
|
||||||
|
"rxjs": "^7.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nestjs/jwt": {
|
"node_modules/@nestjs/jwt": {
|
||||||
"version": "11.0.0",
|
"version": "11.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-11.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-11.0.0.tgz",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"@nestjs/common": "^11.0.12",
|
"@nestjs/common": "^11.0.12",
|
||||||
"@nestjs/config": "^4.0.2",
|
"@nestjs/config": "^4.0.2",
|
||||||
"@nestjs/core": "^11.0.12",
|
"@nestjs/core": "^11.0.12",
|
||||||
|
"@nestjs/cqrs": "^11.0.3",
|
||||||
"@nestjs/jwt": "^11.0.0",
|
"@nestjs/jwt": "^11.0.0",
|
||||||
"@nestjs/mapped-types": "^1.0.0",
|
"@nestjs/mapped-types": "^1.0.0",
|
||||||
"@nestjs/microservices": "^11.0.12",
|
"@nestjs/microservices": "^11.0.12",
|
||||||
|
|||||||
@@ -5,28 +5,26 @@ import {
|
|||||||
HttpStatus,
|
HttpStatus,
|
||||||
Post,
|
Post,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { AuthService } from './auth.service';
|
import { CommandBus } from '@nestjs/cqrs';
|
||||||
import { UsersService } from '../users/users.service';
|
import { CqrsModule } from '@nestjs/cqrs';
|
||||||
import { LoginDto } from '../auth/dto/login.dto';
|
import { AuthenticateUserCommand } from './authenticate-user.command';
|
||||||
import { ResultModel } from 'src/core/models/result.model';
|
|
||||||
import { ApiBody, ApiOkResponse, ApiUnauthorizedResponse } from '@nestjs/swagger';
|
|
||||||
import { ApiTags } from '@nestjs/swagger';
|
|
||||||
import { ApiResponse } from '@nestjs/swagger';
|
|
||||||
import { ApiOperation } from '@nestjs/swagger';
|
|
||||||
import { ApiBearerAuth } from '@nestjs/swagger';
|
|
||||||
import { ApiCreatedResponse } from '@nestjs/swagger';
|
|
||||||
import { ApiBadRequestResponse } from '@nestjs/swagger';
|
|
||||||
import { ApiNotFoundResponse } from '@nestjs/swagger';
|
|
||||||
import { ApiInternalServerErrorResponse } from '@nestjs/swagger';
|
|
||||||
import { ApiForbiddenResponse } from '@nestjs/swagger';
|
|
||||||
import { LoginResponseDto } from './dto/LoginResponseDto';
|
import { LoginResponseDto } from './dto/LoginResponseDto';
|
||||||
|
import { LoginDto } from './dto/login.dto';
|
||||||
|
import { ResultModel } from 'src/core/models/result.model';
|
||||||
|
import { AuthService } from './auth.service';
|
||||||
|
import {
|
||||||
|
ApiTags,
|
||||||
|
ApiOperation,
|
||||||
|
ApiBody,
|
||||||
|
ApiOkResponse,
|
||||||
|
ApiUnauthorizedResponse,
|
||||||
|
} from '@nestjs/swagger';
|
||||||
|
|
||||||
@ApiTags('Auth')
|
@ApiTags('Auth')
|
||||||
@Controller('api/v1/auth')
|
@Controller('api/v1/auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly usersService: UsersService,
|
private readonly commandBus: CommandBus,
|
||||||
private readonly authService: AuthService,
|
private readonly authService: AuthService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -38,11 +36,9 @@ export class AuthController {
|
|||||||
type: LoginResponseDto,
|
type: LoginResponseDto,
|
||||||
})
|
})
|
||||||
@ApiUnauthorizedResponse({ description: 'Usuário ou senha inválidos' })
|
@ApiUnauthorizedResponse({ description: 'Usuário ou senha inválidos' })
|
||||||
async login(@Body() model: LoginDto): Promise<LoginResponseDto> {
|
async login(@Body() dto: LoginDto): Promise<LoginResponseDto> {
|
||||||
const result = await this.usersService.authenticate({
|
const command = new AuthenticateUserCommand(dto.username, dto.password);
|
||||||
userName: model.username,
|
const result = await this.commandBus.execute(command);
|
||||||
password: model.password,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
@@ -52,7 +48,6 @@ export class AuthController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const user = result.data;
|
const user = result.data;
|
||||||
|
|
||||||
const token = await this.authService.createToken(
|
const token = await this.authService.createToken(
|
||||||
user.id,
|
user.id,
|
||||||
user.sellerId,
|
user.sellerId,
|
||||||
|
|||||||
@@ -6,20 +6,30 @@ import { JwtStrategy } from '../strategies/jwt-strategy';
|
|||||||
import { RedisModule } from 'src/core/configs/cache/redis.module';
|
import { RedisModule } from 'src/core/configs/cache/redis.module';
|
||||||
import { UsersModule } from '../users/users.module';
|
import { UsersModule } from '../users/users.module';
|
||||||
import { AuthController } from './auth.controller';
|
import { AuthController } from './auth.controller';
|
||||||
|
import { CqrsModule } from '@nestjs/cqrs';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
import { AuthenticateUserHandler } from './authenticate-user.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
JwtModule.register({
|
CqrsModule,
|
||||||
secret: '4557C0D7-DFB0-40DA-BF83-91A75103F7A9',
|
ConfigModule,
|
||||||
signOptions: { expiresIn: '8h' },
|
JwtModule.registerAsync({
|
||||||
|
imports: [ConfigModule],
|
||||||
|
useFactory: async (configService: ConfigService) => ({
|
||||||
|
secret: configService.get<string>('JWT_SECRET'),
|
||||||
|
signOptions: {
|
||||||
|
expiresIn: configService.get<string>('JWT_EXPIRES_IN'),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
inject: [ConfigService],
|
||||||
}),
|
}),
|
||||||
PassportModule.register({ defaultStrategy: 'jwt' }),
|
PassportModule.register({ defaultStrategy: 'jwt' }),
|
||||||
RedisModule,
|
RedisModule,
|
||||||
UsersModule,
|
UsersModule,
|
||||||
|
|
||||||
],
|
],
|
||||||
controllers: [AuthController],
|
controllers: [AuthController],
|
||||||
providers: [AuthService, JwtStrategy],
|
providers: [AuthService, JwtStrategy, AuthenticateUserHandler],
|
||||||
exports: [AuthService],
|
exports: [AuthService],
|
||||||
})
|
})
|
||||||
export class AuthModule {}
|
export class AuthModule {}
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
/* eslint-disable prettier/prettier */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { JwtService, JwtSignOptions } from '@nestjs/jwt';
|
import { JwtService, JwtSignOptions } from '@nestjs/jwt';
|
||||||
import { UsersService } from '../users/users.service';
|
import { UsersService } from '../users/users.service';
|
||||||
import { JwtPayload } from '../models/jwt-payload.model';
|
import { JwtPayload } from '../models/jwt-payload.model';
|
||||||
import Redis from 'ioredis';
|
import { UserRepository } from '../users/UserRepository';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -14,6 +10,7 @@ export class AuthService {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly usersService: UsersService,
|
private readonly usersService: UsersService,
|
||||||
private readonly jwtService: JwtService,
|
private readonly jwtService: JwtService,
|
||||||
|
private readonly userRepository: UserRepository,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async createToken(id: number, sellerId: number, username: string, email: string, storeId: string) {
|
async createToken(id: number, sellerId: number, username: string, email: string, storeId: string) {
|
||||||
@@ -29,6 +26,15 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async validateUser(payload: JwtPayload): Promise<JwtPayload | null> {
|
async validateUser(payload: JwtPayload): Promise<JwtPayload | null> {
|
||||||
return payload;
|
const user = await this.userRepository.findById(payload.id);
|
||||||
|
if (!user || !user.active) return null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: user.id,
|
||||||
|
sellerId: user.sellerId,
|
||||||
|
storeId: user.storeId,
|
||||||
|
username: user.username,
|
||||||
|
email: user.email,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
export class AuthenticateUserCommand {
|
export class AuthenticateUserCommand {
|
||||||
constructor(
|
constructor(
|
||||||
public readonly username: string,
|
public readonly username: string,
|
||||||
public readonly password: string,
|
public readonly password: string,
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
import { Injectable, ForbiddenException } from '@nestjs/common';
|
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
|
||||||
import { UserRepository } from '../users/UserRepository';
|
|
||||||
import { AuthenticateUserCommand } from './authenticate-user.command';
|
import { AuthenticateUserCommand } from './authenticate-user.command';
|
||||||
|
import { UserRepository } from '../users/UserRepository';
|
||||||
import { Result } from '../models/result';
|
import { Result } from '../models/result';
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { UserModel } from 'src/core/models/user.model';
|
||||||
|
|
||||||
|
@CommandHandler(AuthenticateUserCommand)
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthenticateUserService {
|
export class AuthenticateUserHandler implements ICommandHandler<AuthenticateUserCommand> {
|
||||||
constructor(private readonly userRepository: UserRepository) {}
|
constructor(private readonly userRepository: UserRepository) {}
|
||||||
|
|
||||||
async execute(command: AuthenticateUserCommand): Promise<Result<any>> {
|
async execute(command: AuthenticateUserCommand): Promise<Result<UserModel>> {
|
||||||
const { username, password } = command;
|
const { username, password } = command;
|
||||||
|
|
||||||
const user = await this.userRepository.findByUsernameAndPassword(username, password);
|
const user = await this.userRepository.findByUsernameAndPassword(username, password);
|
||||||
@@ -17,13 +20,18 @@ export class AuthenticateUserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (user.dataDesligamento !== null) {
|
if (user.dataDesligamento !== null) {
|
||||||
return Result.fail('Usuário desligado da empresa, login não permitido, Procure o setor de RH!');
|
return Result.fail('Usuário desligado da empresa, login não permitido!');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.situacao === 'I') {
|
if (user.situacao === 'I') {
|
||||||
return Result.fail('Usuário inativo, login não permitido!');
|
return Result.fail('Usuário inativo, login não permitido!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user.situacao === 'B') {
|
||||||
|
return Result.fail('Usuário bloqueado, login não permitido!');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return Result.ok(user);
|
return Result.ok(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,53 @@
|
|||||||
Controller
|
// Documentação atualizada da funcionalidade de autenticação usando Command + Microservice
|
||||||
↓ recebe LoginDto
|
|
||||||
UsersService
|
/*
|
||||||
↓ monta o AuthenticateUserCommand
|
Fluxo atualizado:
|
||||||
AuthenticateUserService
|
|
||||||
|
Client (HTTP POST /api/v1/auth/login)
|
||||||
|
↓ envia LoginRequestDto
|
||||||
|
AuthController
|
||||||
|
↓ envia AuthenticateUserCommand para CommandBus
|
||||||
|
AuthenticateUserHandler (CommandHandler)
|
||||||
↓ executa regras de negócio
|
↓ executa regras de negócio
|
||||||
UserRepository
|
UserRepository
|
||||||
↓ executa query no banco
|
↓ executa query no banco
|
||||||
Result<User>
|
Result<User>
|
||||||
← resposta encapsulada
|
← resposta encapsulada
|
||||||
|
AuthController
|
||||||
|
↓ gera JWT com AuthService
|
||||||
|
Resposta final: LoginResponseDto com token
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 1. AuthController
|
||||||
|
// Entrada da requisição HTTP (POST /api/v1/auth/login)
|
||||||
|
// - Recebe LoginRequestDto com username e password
|
||||||
|
// - Cria AuthenticateUserCommand
|
||||||
|
// - Envia para CommandBus
|
||||||
|
// - Se sucesso, gera JWT via AuthService e retorna LoginResponseDto
|
||||||
|
|
||||||
1. LoginController
|
// 2. AuthenticateUserCommand
|
||||||
Entrada da requisição HTTP (POST /auth/login)
|
// Representa a intenção de autenticação
|
||||||
|
// - Dados: username, password
|
||||||
|
|
||||||
Recebe LoginDto com email e password
|
// 3. AuthenticateUserHandler
|
||||||
|
// Executa o caso de uso de autenticação
|
||||||
|
// - Busca usuário no UserRepository
|
||||||
|
// - Verifica se o usuário está desligado ou inativo
|
||||||
|
// - Retorna Result<User>
|
||||||
|
|
||||||
Encaminha para o UsersService
|
// 4. UserRepository
|
||||||
|
// Camada de persistência (interface com o banco de dados)
|
||||||
|
// - Executa query findByUsernameAndPassword(username, password)
|
||||||
|
|
||||||
2. UsersService
|
// 5. Result<T>
|
||||||
Cria e valida o comando AuthenticateUserCommand
|
// Objeto genérico de retorno que encapsula:
|
||||||
|
// - Sucesso (success = true, data: User)
|
||||||
|
// - Falha (success = false, error: string)
|
||||||
|
|
||||||
Chama o serviço de autenticação de domínio (AuthenticateUserService)
|
// 6. AuthService
|
||||||
|
// Gera token JWT com base nos dados do usuário
|
||||||
|
// - Pode gerar access token e refresh token (se necessário)
|
||||||
|
|
||||||
3. AuthenticateUserService
|
// Estrutura atual suporta futura extração do AuthModule como microserviço
|
||||||
Lógica de negócio da autenticação:
|
// - Usando @MessagePattern('auth.login') no AuthController do microserviço
|
||||||
|
// - Consumo via ClientProxy na aplicação principal com ClientModule
|
||||||
Busca usuário pelo e-mail
|
|
||||||
|
|
||||||
Verifica se o usuário está ativo
|
|
||||||
|
|
||||||
Valida a senha com hash
|
|
||||||
|
|
||||||
Retorna Result<User>
|
|
||||||
|
|
||||||
4. UserRepository
|
|
||||||
Camada de persistência (interface com o banco de dados)
|
|
||||||
|
|
||||||
Executa a query findByEmail(email: string)
|
|
||||||
|
|
||||||
5. Result<T>
|
|
||||||
Objeto genérico de retorno que encapsula:
|
|
||||||
|
|
||||||
Sucesso (success = true, com data: User)
|
|
||||||
|
|
||||||
Falha (success = false, com error: string)
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Documentação - Fluxo de Login</title>
|
<title>Documentação - Fluxo de Login com Microserviço</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
@@ -47,12 +47,11 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>🔐 Fluxo de Login - Portal Juru API</h1>
|
<h1>🔐 Fluxo de Login com Microserviço - Portal Juru API</h1>
|
||||||
|
|
||||||
<h2>📌 Rota de Login</h2>
|
<h2>📌 Rota de Login</h2>
|
||||||
<p><strong>URL:</strong> <code>POST /api/v1/auth/login</code></p>
|
<p><strong>URL:</strong> <code>POST /api/v1/auth/login</code></p>
|
||||||
<p><strong>Descrição:</strong> Autentica o usuário, valida regras de negócio e retorna um token JWT.</p>
|
<p><strong>Descrição:</strong> Autentica o usuário via microserviço e retorna um token JWT.</p>
|
||||||
<p><strong>Acesso:</strong> Público</p>
|
|
||||||
|
|
||||||
<h3>📤 Body (JSON)</h3>
|
<h3>📤 Body (JSON)</h3>
|
||||||
<pre>{
|
<pre>{
|
||||||
@@ -79,40 +78,40 @@
|
|||||||
"error": "Usuário ou senha inválidos."
|
"error": "Usuário ou senha inválidos."
|
||||||
}</pre>
|
}</pre>
|
||||||
|
|
||||||
<h2>🧱 Camadas e Responsabilidades</h2>
|
<h2>🧱 Camadas e Responsabilidades (CQRS + Microservice)</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr><th>Camada</th><th>Responsabilidade</th></tr>
|
<tr><th>Componente</th><th>Responsabilidade</th></tr>
|
||||||
<tr><td>AuthController</td><td>Recebe requisição e coordena autenticação</td></tr>
|
<tr><td>AuthController</td><td>Recebe requisição HTTP e envia AuthenticateUserCommand ao CommandBus</td></tr>
|
||||||
<tr><td>UsersService</td><td>Orquestra os casos de uso (login, reset, troca senha)</td></tr>
|
<tr><td>AuthenticateUserCommand</td><td>Representa a intenção de autenticar um usuário</td></tr>
|
||||||
<tr><td>AuthenticateUserService</td><td>Executa lógica de autenticação e validações</td></tr>
|
<tr><td>AuthenticateUserHandler</td><td>Executa regras de autenticação com base no comando</td></tr>
|
||||||
<tr><td>UserRepository</td><td>Executa SQL diretamente no Oracle</td></tr>
|
<tr><td>UserRepository</td><td>Consulta o banco para obter dados do usuário</td></tr>
|
||||||
<tr><td>AuthService</td><td>Gera o token JWT com os dados do usuário</td></tr>
|
<tr><td>Result<T></td><td>Encapsula sucesso ou falha com mensagens claras</td></tr>
|
||||||
<tr><td>JwtStrategy</td><td>Valida o token em rotas protegidas, usando Redis como cache</td></tr>
|
<tr><td>AuthService</td><td>Gera token JWT e/ou Refresh Token</td></tr>
|
||||||
<tr><td>RedisClientAdapter</td><td>Wrapper de acesso ao Redis com interface genérica e TTL</td></tr>
|
<tr><td>Auth Microservice</td><td>Escuta o evento 'auth.login' e executa a autenticação</td></tr>
|
||||||
|
<tr><td>ClientProxy</td><td>Faz chamada ao microserviço de autenticação</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<h2>🧊 Redis na Autenticação</h2>
|
<h2>🔗 Comunicação via Microserviço</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Chave:</strong> <code>session:{userId}</code></li>
|
<li><strong>Protocolo:</strong> TCP</li>
|
||||||
<li><strong>Valor:</strong> JSON serializado do usuário autenticado</li>
|
<li><strong>Evento:</strong> <code>auth.login</code></li>
|
||||||
<li><strong>TTL:</strong> 8 horas</li>
|
<li><strong>Porta:</strong> 3001</li>
|
||||||
<li><strong>Fallback:</strong> Se o cache não existir, consulta ao banco</li>
|
<li><strong>Formato:</strong> <code>{ username, password }</code></li>
|
||||||
<li><strong>Auditoria:</strong> espaço reservado para log de acesso</li>
|
<li><strong>Resposta:</strong> <code>Result<User></code></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>🔐 Proteção de Rotas</h2>
|
<h2>🛡️ Proteção com JWT</h2>
|
||||||
<p>Rotas protegidas utilizam <code>@UseGuards(JwtAuthGuard)</code> e <code>@ApiBearerAuth()</code>.</p>
|
<p>Após o login, o token JWT é retornado e deve ser enviado em todas as requisições protegidas.</p>
|
||||||
<p><strong>Header necessário:</strong></p>
|
|
||||||
<code>Authorization: Bearer <token></code>
|
<code>Authorization: Bearer <token></code>
|
||||||
|
|
||||||
<h2>🚀 Melhorias Futuras</h2>
|
<h2>🚀 Melhorias Futuras</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>[ ] Blacklist de tokens para logout</li>
|
<li>[ ] Blacklist de tokens</li>
|
||||||
<li>[ ] Log de auditoria</li>
|
|
||||||
<li>[ ] Refresh Token</li>
|
<li>[ ] Refresh Token</li>
|
||||||
<li>[ ] Controle de permissões/roles</li>
|
<li>[ ] Log de auditoria</li>
|
||||||
|
<li>[ ] Controle de permissões e roles</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p><strong>Última atualização:</strong> 28/03/2025</p>
|
<p><strong>Última atualização:</strong> 31/03/2025</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { TypeOrmModule } from '@nestjs/typeorm'; // <-- importe aqui
|
|||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
import { UserRepository } from './UserRepository';
|
import { UserRepository } from './UserRepository';
|
||||||
|
|
||||||
import { AuthenticateUserService } from '../auth/authenticate-user.service';
|
import { AuthenticateUserHandler } from '../auth/authenticate-user.service';
|
||||||
import { ResetPasswordService } from './reset-password.service';
|
import { ResetPasswordService } from './reset-password.service';
|
||||||
import { ChangePasswordService } from './change-password.service';
|
import { ChangePasswordService } from './change-password.service';
|
||||||
import { EmailService } from './email.service';
|
import { EmailService } from './email.service';
|
||||||
@@ -16,7 +16,7 @@ import { EmailService } from './email.service';
|
|||||||
providers: [
|
providers: [
|
||||||
UsersService,
|
UsersService,
|
||||||
UserRepository,
|
UserRepository,
|
||||||
AuthenticateUserService,
|
AuthenticateUserHandler,
|
||||||
ResetPasswordService,
|
ResetPasswordService,
|
||||||
ChangePasswordService,
|
ChangePasswordService,
|
||||||
EmailService,
|
EmailService,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { AuthenticateUserService } from '../auth/authenticate-user.service';
|
import { AuthenticateUserHandler } from '../auth/authenticate-user.service';
|
||||||
import { ResetPasswordService } from './reset-password.service';
|
import { ResetPasswordService } from './reset-password.service';
|
||||||
import { ChangePasswordService } from './change-password.service';
|
import { ChangePasswordService } from './change-password.service';
|
||||||
import { AuthenticateUserCommand } from '../auth/authenticate-user.command';
|
import { AuthenticateUserCommand } from '../auth/authenticate-user.command';
|
||||||
@@ -9,7 +9,7 @@ import { AuthenticateUserCommand } from '../auth/authenticate-user.command';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class UsersService {
|
export class UsersService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly authenticateUserService: AuthenticateUserService,
|
private readonly authenticateUserService: AuthenticateUserHandler,
|
||||||
private readonly resetPasswordService: ResetPasswordService,
|
private readonly resetPasswordService: ResetPasswordService,
|
||||||
private readonly changePasswordService: ChangePasswordService,
|
private readonly changePasswordService: ChangePasswordService,
|
||||||
) {}
|
) {}
|
||||||
|
|||||||
Reference in New Issue
Block a user