@ministerjs/auth 2.0.1 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -8
- package/dist/nestjs.d.mts +163 -8
- package/dist/nestjs.d.ts +163 -8
- package/dist/nestjs.js +429 -35
- package/dist/nestjs.mjs +410 -16
- package/dist/vue.d.mts +2 -0
- package/dist/vue.d.ts +2 -0
- package/dist/vue.js +20 -0
- package/dist/vue.mjs +20 -0
- package/package.json +12 -7
- package/types/nestjs/AuthController.d.ts +1 -0
- package/types/nestjs/AuthModule.d.ts +2 -0
- package/types/nestjs/JwtPrismaCookieAuthDriver.d.ts +64 -6
- package/types/nestjs/guards/JwtAuthGuard.d.ts +17 -0
- package/types/nestjs/guards/RolesGuard.d.ts +8 -0
- package/types/nestjs/guards/index.d.ts +2 -0
- package/types/nestjs/index.d.ts +3 -0
- package/types/nestjs/rbac.d.ts +3 -0
- package/types/nestjs/stores.d.ts +36 -0
- package/types/nestjs/types.d.ts +37 -2
- package/types/vue/VueAuth.d.ts +2 -0
package/README.md
CHANGED
|
@@ -1,19 +1,64 @@
|
|
|
1
1
|
# @ministerjs/auth
|
|
2
2
|
|
|
3
|
-
Biblioteca de
|
|
4
|
-
- **Vue (front)** — helpers reativos para estado de autenticação.
|
|
5
|
-
- **NestJS (back)** — módulo com controllers e drivers plugáveis (inclui driver padrão JWT + Prisma + cookies).
|
|
3
|
+
Biblioteca de autenticacao JWT com dois alvos:
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
- [Uso no backend (NestJS)](./src/nestjs/README.md)
|
|
5
|
+
- **Vue (front)** — classe reativa para estado de autenticacao, login, signup, logout, checkIn e roles.
|
|
6
|
+
- **NestJS (back)** — modulo com controllers, guards, RBAC, drivers plugaveis e driver padrao JWT + Prisma + cookies.
|
|
10
7
|
|
|
11
|
-
##
|
|
8
|
+
## Instalacao
|
|
12
9
|
|
|
13
10
|
```bash
|
|
14
11
|
pnpm add @ministerjs/auth
|
|
15
12
|
```
|
|
16
13
|
|
|
17
|
-
Escolha o subpath conforme o lado da
|
|
14
|
+
Escolha o subpath conforme o lado da aplicacao:
|
|
15
|
+
|
|
18
16
|
- Front: `@ministerjs/auth/vue`
|
|
19
17
|
- Back: `@ministerjs/auth/nestjs`
|
|
18
|
+
|
|
19
|
+
## Documentacao
|
|
20
|
+
|
|
21
|
+
- [Vue (front)](./src/vue/README.md)
|
|
22
|
+
- [NestJS (back)](./src/nestjs/README.md)
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
### Seguranca
|
|
27
|
+
|
|
28
|
+
- Cookie `secure` automatico em producao
|
|
29
|
+
- Pinagem de algoritmo HS256 (sign + verify)
|
|
30
|
+
- Re-assinatura de JWT no checkIn (evita reuso de tokens antigos)
|
|
31
|
+
- CSRF double-submit cookie (opcional)
|
|
32
|
+
- Account lockout com janela temporal (plugavel via `LockoutStore`)
|
|
33
|
+
- Rate limiting hook (`onRateLimitCheck`)
|
|
34
|
+
- Audit logging hook (`onAudit`)
|
|
35
|
+
|
|
36
|
+
### Autenticacao
|
|
37
|
+
|
|
38
|
+
- Login com credenciais + comparacao de senha obrigatoria (`comparePassword`)
|
|
39
|
+
- CheckIn (valida sessao ativa via cookie/JWT)
|
|
40
|
+
- Logout com limpeza de cookies e revogacao de tokens
|
|
41
|
+
- SignUp (Vue)
|
|
42
|
+
- Refresh token rotation com `jti` e revogacao automatica
|
|
43
|
+
|
|
44
|
+
### Autorizacao
|
|
45
|
+
|
|
46
|
+
- `JwtAuthGuard` — extrai JWT de cookie ou header `Authorization: Bearer`
|
|
47
|
+
- `@Roles()` decorator + `RolesGuard` para RBAC
|
|
48
|
+
- `AuthModule.createGuard()` factory para instanciar guards
|
|
49
|
+
|
|
50
|
+
### Tipagem
|
|
51
|
+
|
|
52
|
+
- `LoginPayload`, `JwtAccessPayload`, `JwtRefreshPayload` — tipos JWT exportados
|
|
53
|
+
- `AuthenticatedUser` — tipo do `request.user` populado pelo guard
|
|
54
|
+
- `PrismaModelDelegate` / `PrismaClientLike` — tipagem do client Prisma
|
|
55
|
+
- `AuthDriver<User>` — interface para drivers customizados
|
|
56
|
+
|
|
57
|
+
## Migration v2 → v3
|
|
58
|
+
|
|
59
|
+
### Breaking changes
|
|
60
|
+
|
|
61
|
+
1. **`comparePassword` agora e obrigatorio** — nao existe mais fallback para plain-text.
|
|
62
|
+
2. **`AuthPayload` narrowed** — substituido por `LoginPayload` (`Record<string, string>`). O alias `AuthPayload` continua exportado como deprecated.
|
|
63
|
+
3. **Cookie `secure: true` em producao** — `defaultCookieOptions.secure` agora e `process.env.NODE_ENV === "production"`.
|
|
64
|
+
4. **`NestJsAuthenticationController` removido do `@ministerjs/server`** — use `@ministerjs/auth/nestjs` como substituto.
|
package/dist/nestjs.d.mts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { Request, Response, CookieOptions } from 'express';
|
|
2
|
-
import
|
|
2
|
+
import * as _nestjs_common from '@nestjs/common';
|
|
3
|
+
import { CanActivate, ExecutionContext, Type, DynamicModule } from '@nestjs/common';
|
|
4
|
+
import { Reflector } from '@nestjs/core';
|
|
3
5
|
import { SignOptions } from 'jsonwebtoken';
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
interface LoginPayload {
|
|
8
|
+
[key: string]: string;
|
|
9
|
+
}
|
|
10
|
+
/** @deprecated Use LoginPayload */
|
|
11
|
+
type AuthPayload = LoginPayload;
|
|
6
12
|
interface AuthResponse<User> {
|
|
7
13
|
message: string;
|
|
8
14
|
data: User;
|
|
@@ -10,11 +16,37 @@ interface AuthResponse<User> {
|
|
|
10
16
|
interface LogoutResponse {
|
|
11
17
|
message: string;
|
|
12
18
|
}
|
|
19
|
+
interface JwtAccessPayload {
|
|
20
|
+
sub: string;
|
|
21
|
+
roles?: string[];
|
|
22
|
+
iat?: number;
|
|
23
|
+
exp?: number;
|
|
24
|
+
}
|
|
25
|
+
interface JwtRefreshPayload {
|
|
26
|
+
sub: string;
|
|
27
|
+
jti: string;
|
|
28
|
+
iat?: number;
|
|
29
|
+
exp?: number;
|
|
30
|
+
}
|
|
31
|
+
interface AuthenticatedUser {
|
|
32
|
+
id: string;
|
|
33
|
+
roles: string[];
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
interface AuditEvent {
|
|
37
|
+
action: "login" | "logout" | "checkin" | "refresh" | "lockout";
|
|
38
|
+
userId?: string;
|
|
39
|
+
ip?: string;
|
|
40
|
+
userAgent?: string;
|
|
41
|
+
timestamp: Date;
|
|
42
|
+
success: boolean;
|
|
43
|
+
metadata?: Record<string, unknown>;
|
|
44
|
+
}
|
|
13
45
|
interface AuthDriver<User = any> {
|
|
14
46
|
/**
|
|
15
47
|
* Deve validar o payload recebido e retornar o usuário autenticado.
|
|
16
48
|
*/
|
|
17
|
-
login(payload:
|
|
49
|
+
login(payload: LoginPayload, request: Request, response: Response): Promise<User> | User;
|
|
18
50
|
/**
|
|
19
51
|
* Deve recuperar o usuário a partir do contexto (cookies, headers, sessão, etc.).
|
|
20
52
|
* Retorne `null` ou `undefined` quando não houver sessão ativa.
|
|
@@ -24,15 +56,80 @@ interface AuthDriver<User = any> {
|
|
|
24
56
|
* Deve encerrar a sessão/tokens do usuário.
|
|
25
57
|
*/
|
|
26
58
|
logout(request: Request, response: Response): Promise<void> | void;
|
|
59
|
+
/**
|
|
60
|
+
* Renova os tokens usando um refresh token.
|
|
61
|
+
* Opcional — drivers que não implementam retornam undefined.
|
|
62
|
+
*/
|
|
63
|
+
refresh?(request: Request, response: Response): Promise<User | null | undefined> | User | null | undefined;
|
|
27
64
|
}
|
|
28
65
|
|
|
29
66
|
declare const AUTH_DRIVER: unique symbol;
|
|
30
67
|
|
|
68
|
+
interface LockoutStore {
|
|
69
|
+
recordFailure(key: string): Promise<void>;
|
|
70
|
+
getFailures(key: string): Promise<number>;
|
|
71
|
+
reset(key: string): Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
declare class InMemoryLockoutStore implements LockoutStore {
|
|
74
|
+
private readonly windowMs;
|
|
75
|
+
private entries;
|
|
76
|
+
constructor(windowMs: number);
|
|
77
|
+
recordFailure(key: string): Promise<void>;
|
|
78
|
+
getFailures(key: string): Promise<number>;
|
|
79
|
+
reset(key: string): Promise<void>;
|
|
80
|
+
}
|
|
81
|
+
interface RefreshTokenStore {
|
|
82
|
+
save(jti: string, userId: string, expiresAt: Date): Promise<void>;
|
|
83
|
+
find(jti: string): Promise<{
|
|
84
|
+
userId: string;
|
|
85
|
+
expiresAt: Date;
|
|
86
|
+
} | null>;
|
|
87
|
+
revoke(jti: string): Promise<void>;
|
|
88
|
+
revokeAll(userId: string): Promise<void>;
|
|
89
|
+
}
|
|
90
|
+
interface RefreshTokenEntry {
|
|
91
|
+
userId: string;
|
|
92
|
+
expiresAt: Date;
|
|
93
|
+
}
|
|
94
|
+
declare class InMemoryRefreshTokenStore implements RefreshTokenStore {
|
|
95
|
+
private tokens;
|
|
96
|
+
private userJtis;
|
|
97
|
+
save(jti: string, userId: string, expiresAt: Date): Promise<void>;
|
|
98
|
+
find(jti: string): Promise<RefreshTokenEntry | null>;
|
|
99
|
+
revoke(jti: string): Promise<void>;
|
|
100
|
+
revokeAll(userId: string): Promise<void>;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
declare const ROLES_KEY = "ministerjs:roles";
|
|
104
|
+
declare const Roles: (...roles: string[]) => _nestjs_common.CustomDecorator<string>;
|
|
105
|
+
|
|
106
|
+
interface JwtAuthGuardOptions {
|
|
107
|
+
jwtSecret: string;
|
|
108
|
+
cookieName?: string;
|
|
109
|
+
csrfEnabled?: boolean;
|
|
110
|
+
}
|
|
111
|
+
declare class JwtAuthGuard implements CanActivate {
|
|
112
|
+
private readonly jwtSecret;
|
|
113
|
+
private readonly cookieName;
|
|
114
|
+
private readonly csrfEnabled;
|
|
115
|
+
constructor(options: JwtAuthGuardOptions);
|
|
116
|
+
canActivate(context: ExecutionContext): boolean;
|
|
117
|
+
private extractToken;
|
|
118
|
+
private validateCsrf;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
declare class RolesGuard implements CanActivate {
|
|
122
|
+
private readonly reflector;
|
|
123
|
+
constructor(reflector: Reflector);
|
|
124
|
+
canActivate(context: ExecutionContext): boolean;
|
|
125
|
+
}
|
|
126
|
+
|
|
31
127
|
declare class AuthController<User extends Record<string, any> = Record<string, any>> {
|
|
32
128
|
private readonly driver;
|
|
33
129
|
constructor(driver: AuthDriver<User>);
|
|
34
130
|
login(body: AuthPayload, request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
35
131
|
checkIn(request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
132
|
+
refresh(request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
36
133
|
logout(request: Request, response: Response): Promise<LogoutResponse>;
|
|
37
134
|
}
|
|
38
135
|
|
|
@@ -62,10 +159,16 @@ interface AuthModuleAsyncOptions<User = any> {
|
|
|
62
159
|
declare class AuthModule {
|
|
63
160
|
static register<User = any>(options: AuthModuleOptions<User>): DynamicModule;
|
|
64
161
|
static registerAsync<User = any>(options: AuthModuleAsyncOptions<User>): DynamicModule;
|
|
162
|
+
static createGuard(options: JwtAuthGuardOptions): JwtAuthGuard;
|
|
65
163
|
private static normalizeDriverProvider;
|
|
66
164
|
}
|
|
67
165
|
|
|
68
|
-
|
|
166
|
+
interface PrismaModelDelegate {
|
|
167
|
+
findUnique(args: {
|
|
168
|
+
where: Record<string, unknown>;
|
|
169
|
+
}): Promise<any>;
|
|
170
|
+
}
|
|
171
|
+
type PrismaClientLike = Record<string, PrismaModelDelegate | undefined>;
|
|
69
172
|
interface JwtPrismaDriverOptions {
|
|
70
173
|
prisma: PrismaClientLike;
|
|
71
174
|
/**
|
|
@@ -102,12 +205,52 @@ interface JwtPrismaDriverOptions {
|
|
|
102
205
|
cookieOptions?: Partial<CookieOptions>;
|
|
103
206
|
/**
|
|
104
207
|
* Função de comparação de senha (p.ex. bcrypt.compare).
|
|
208
|
+
* Obrigatório — não há fallback para comparação em plain-text.
|
|
105
209
|
*/
|
|
106
|
-
comparePassword
|
|
210
|
+
comparePassword: (provided: string, stored: unknown) => Promise<boolean> | boolean;
|
|
107
211
|
/**
|
|
108
212
|
* Permite alterar a shape do usuário retornado.
|
|
109
213
|
*/
|
|
110
214
|
transformUser?: <T extends Record<string, any>>(user: T) => any;
|
|
215
|
+
/**
|
|
216
|
+
* Habilita proteção CSRF via double-submit cookie.
|
|
217
|
+
* No login, emite um cookie `csrf_token` (não-httpOnly) que o cliente
|
|
218
|
+
* deve enviar no header `x-csrf-token` em requisições autenticadas.
|
|
219
|
+
*/
|
|
220
|
+
csrf?: boolean;
|
|
221
|
+
/**
|
|
222
|
+
* Callback de auditoria chamado em cada evento de autenticação.
|
|
223
|
+
*/
|
|
224
|
+
onAudit?: (event: AuditEvent) => void | Promise<void>;
|
|
225
|
+
/**
|
|
226
|
+
* Callback de rate limiting chamado antes de cada tentativa de login.
|
|
227
|
+
* Retorne `false` para bloquear a tentativa.
|
|
228
|
+
*/
|
|
229
|
+
onRateLimitCheck?: (ip: string, identifier: string) => Promise<boolean> | boolean;
|
|
230
|
+
/**
|
|
231
|
+
* Configuração de account lockout.
|
|
232
|
+
*/
|
|
233
|
+
lockout?: {
|
|
234
|
+
/** Número máximo de tentativas antes de bloquear (default: 5). */
|
|
235
|
+
maxAttempts?: number;
|
|
236
|
+
/** Janela de tempo em ms para contar falhas (default: 15 min). */
|
|
237
|
+
windowMs?: number;
|
|
238
|
+
/** Store customizado para persistir falhas (default: InMemoryLockoutStore). */
|
|
239
|
+
store?: LockoutStore;
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Configuração de refresh token rotation.
|
|
243
|
+
* Quando habilitado, login emite um par access + refresh token.
|
|
244
|
+
*/
|
|
245
|
+
refreshToken?: {
|
|
246
|
+
enabled: boolean;
|
|
247
|
+
/** Nome do cookie do refresh token (default: "refresh_token"). */
|
|
248
|
+
cookieName?: string;
|
|
249
|
+
/** Tempo de expiração do refresh token (default: "30d"). */
|
|
250
|
+
expiresIn?: SignOptions["expiresIn"];
|
|
251
|
+
/** Store para persistir refresh tokens (default: InMemoryRefreshTokenStore). */
|
|
252
|
+
store?: RefreshTokenStore;
|
|
253
|
+
};
|
|
111
254
|
}
|
|
112
255
|
declare class JwtPrismaCookieAuthDriver<User extends Record<string, any>> implements AuthDriver<User> {
|
|
113
256
|
private readonly prismaModel;
|
|
@@ -120,10 +263,22 @@ declare class JwtPrismaCookieAuthDriver<User extends Record<string, any>> implem
|
|
|
120
263
|
private readonly cookieOptions;
|
|
121
264
|
private readonly comparePassword;
|
|
122
265
|
private readonly transformUser;
|
|
266
|
+
private readonly csrf;
|
|
267
|
+
private readonly onAudit?;
|
|
268
|
+
private readonly onRateLimitCheck?;
|
|
269
|
+
private readonly lockoutStore?;
|
|
270
|
+
private readonly lockoutMaxAttempts;
|
|
271
|
+
private readonly refreshTokenEnabled;
|
|
272
|
+
private readonly refreshTokenCookieName;
|
|
273
|
+
private readonly refreshTokenExpiresIn;
|
|
274
|
+
private readonly refreshTokenStore?;
|
|
123
275
|
constructor(options: JwtPrismaDriverOptions);
|
|
124
|
-
login(payload:
|
|
276
|
+
login(payload: LoginPayload, req: Request, res: Response): Promise<User>;
|
|
125
277
|
checkIn(req: Request, res: Response): Promise<User | null>;
|
|
126
|
-
logout(
|
|
278
|
+
logout(req: Request, res: Response): Promise<void>;
|
|
279
|
+
refresh(req: Request, res: Response): Promise<User | null>;
|
|
280
|
+
private issueRefreshToken;
|
|
281
|
+
private emitAudit;
|
|
127
282
|
}
|
|
128
283
|
|
|
129
|
-
export { AUTH_DRIVER, AuthController, type AuthDriver, AuthModule, type AuthModuleAsyncOptions, type AuthModuleOptions, type AuthPayload, type AuthResponse, type DriverProvider, JwtPrismaCookieAuthDriver, type JwtPrismaDriverOptions, type LogoutResponse };
|
|
284
|
+
export { AUTH_DRIVER, type AuditEvent, AuthController, type AuthDriver, AuthModule, type AuthModuleAsyncOptions, type AuthModuleOptions, type AuthPayload, type AuthResponse, type AuthenticatedUser, type DriverProvider, InMemoryLockoutStore, InMemoryRefreshTokenStore, type JwtAccessPayload, JwtAuthGuard, type JwtAuthGuardOptions, JwtPrismaCookieAuthDriver, type JwtPrismaDriverOptions, type JwtRefreshPayload, type LockoutStore, type LoginPayload, type LogoutResponse, type PrismaClientLike, type PrismaModelDelegate, ROLES_KEY, type RefreshTokenStore, Roles, RolesGuard };
|
package/dist/nestjs.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { Request, Response, CookieOptions } from 'express';
|
|
2
|
-
import
|
|
2
|
+
import * as _nestjs_common from '@nestjs/common';
|
|
3
|
+
import { CanActivate, ExecutionContext, Type, DynamicModule } from '@nestjs/common';
|
|
4
|
+
import { Reflector } from '@nestjs/core';
|
|
3
5
|
import { SignOptions } from 'jsonwebtoken';
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
interface LoginPayload {
|
|
8
|
+
[key: string]: string;
|
|
9
|
+
}
|
|
10
|
+
/** @deprecated Use LoginPayload */
|
|
11
|
+
type AuthPayload = LoginPayload;
|
|
6
12
|
interface AuthResponse<User> {
|
|
7
13
|
message: string;
|
|
8
14
|
data: User;
|
|
@@ -10,11 +16,37 @@ interface AuthResponse<User> {
|
|
|
10
16
|
interface LogoutResponse {
|
|
11
17
|
message: string;
|
|
12
18
|
}
|
|
19
|
+
interface JwtAccessPayload {
|
|
20
|
+
sub: string;
|
|
21
|
+
roles?: string[];
|
|
22
|
+
iat?: number;
|
|
23
|
+
exp?: number;
|
|
24
|
+
}
|
|
25
|
+
interface JwtRefreshPayload {
|
|
26
|
+
sub: string;
|
|
27
|
+
jti: string;
|
|
28
|
+
iat?: number;
|
|
29
|
+
exp?: number;
|
|
30
|
+
}
|
|
31
|
+
interface AuthenticatedUser {
|
|
32
|
+
id: string;
|
|
33
|
+
roles: string[];
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
interface AuditEvent {
|
|
37
|
+
action: "login" | "logout" | "checkin" | "refresh" | "lockout";
|
|
38
|
+
userId?: string;
|
|
39
|
+
ip?: string;
|
|
40
|
+
userAgent?: string;
|
|
41
|
+
timestamp: Date;
|
|
42
|
+
success: boolean;
|
|
43
|
+
metadata?: Record<string, unknown>;
|
|
44
|
+
}
|
|
13
45
|
interface AuthDriver<User = any> {
|
|
14
46
|
/**
|
|
15
47
|
* Deve validar o payload recebido e retornar o usuário autenticado.
|
|
16
48
|
*/
|
|
17
|
-
login(payload:
|
|
49
|
+
login(payload: LoginPayload, request: Request, response: Response): Promise<User> | User;
|
|
18
50
|
/**
|
|
19
51
|
* Deve recuperar o usuário a partir do contexto (cookies, headers, sessão, etc.).
|
|
20
52
|
* Retorne `null` ou `undefined` quando não houver sessão ativa.
|
|
@@ -24,15 +56,80 @@ interface AuthDriver<User = any> {
|
|
|
24
56
|
* Deve encerrar a sessão/tokens do usuário.
|
|
25
57
|
*/
|
|
26
58
|
logout(request: Request, response: Response): Promise<void> | void;
|
|
59
|
+
/**
|
|
60
|
+
* Renova os tokens usando um refresh token.
|
|
61
|
+
* Opcional — drivers que não implementam retornam undefined.
|
|
62
|
+
*/
|
|
63
|
+
refresh?(request: Request, response: Response): Promise<User | null | undefined> | User | null | undefined;
|
|
27
64
|
}
|
|
28
65
|
|
|
29
66
|
declare const AUTH_DRIVER: unique symbol;
|
|
30
67
|
|
|
68
|
+
interface LockoutStore {
|
|
69
|
+
recordFailure(key: string): Promise<void>;
|
|
70
|
+
getFailures(key: string): Promise<number>;
|
|
71
|
+
reset(key: string): Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
declare class InMemoryLockoutStore implements LockoutStore {
|
|
74
|
+
private readonly windowMs;
|
|
75
|
+
private entries;
|
|
76
|
+
constructor(windowMs: number);
|
|
77
|
+
recordFailure(key: string): Promise<void>;
|
|
78
|
+
getFailures(key: string): Promise<number>;
|
|
79
|
+
reset(key: string): Promise<void>;
|
|
80
|
+
}
|
|
81
|
+
interface RefreshTokenStore {
|
|
82
|
+
save(jti: string, userId: string, expiresAt: Date): Promise<void>;
|
|
83
|
+
find(jti: string): Promise<{
|
|
84
|
+
userId: string;
|
|
85
|
+
expiresAt: Date;
|
|
86
|
+
} | null>;
|
|
87
|
+
revoke(jti: string): Promise<void>;
|
|
88
|
+
revokeAll(userId: string): Promise<void>;
|
|
89
|
+
}
|
|
90
|
+
interface RefreshTokenEntry {
|
|
91
|
+
userId: string;
|
|
92
|
+
expiresAt: Date;
|
|
93
|
+
}
|
|
94
|
+
declare class InMemoryRefreshTokenStore implements RefreshTokenStore {
|
|
95
|
+
private tokens;
|
|
96
|
+
private userJtis;
|
|
97
|
+
save(jti: string, userId: string, expiresAt: Date): Promise<void>;
|
|
98
|
+
find(jti: string): Promise<RefreshTokenEntry | null>;
|
|
99
|
+
revoke(jti: string): Promise<void>;
|
|
100
|
+
revokeAll(userId: string): Promise<void>;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
declare const ROLES_KEY = "ministerjs:roles";
|
|
104
|
+
declare const Roles: (...roles: string[]) => _nestjs_common.CustomDecorator<string>;
|
|
105
|
+
|
|
106
|
+
interface JwtAuthGuardOptions {
|
|
107
|
+
jwtSecret: string;
|
|
108
|
+
cookieName?: string;
|
|
109
|
+
csrfEnabled?: boolean;
|
|
110
|
+
}
|
|
111
|
+
declare class JwtAuthGuard implements CanActivate {
|
|
112
|
+
private readonly jwtSecret;
|
|
113
|
+
private readonly cookieName;
|
|
114
|
+
private readonly csrfEnabled;
|
|
115
|
+
constructor(options: JwtAuthGuardOptions);
|
|
116
|
+
canActivate(context: ExecutionContext): boolean;
|
|
117
|
+
private extractToken;
|
|
118
|
+
private validateCsrf;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
declare class RolesGuard implements CanActivate {
|
|
122
|
+
private readonly reflector;
|
|
123
|
+
constructor(reflector: Reflector);
|
|
124
|
+
canActivate(context: ExecutionContext): boolean;
|
|
125
|
+
}
|
|
126
|
+
|
|
31
127
|
declare class AuthController<User extends Record<string, any> = Record<string, any>> {
|
|
32
128
|
private readonly driver;
|
|
33
129
|
constructor(driver: AuthDriver<User>);
|
|
34
130
|
login(body: AuthPayload, request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
35
131
|
checkIn(request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
132
|
+
refresh(request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
36
133
|
logout(request: Request, response: Response): Promise<LogoutResponse>;
|
|
37
134
|
}
|
|
38
135
|
|
|
@@ -62,10 +159,16 @@ interface AuthModuleAsyncOptions<User = any> {
|
|
|
62
159
|
declare class AuthModule {
|
|
63
160
|
static register<User = any>(options: AuthModuleOptions<User>): DynamicModule;
|
|
64
161
|
static registerAsync<User = any>(options: AuthModuleAsyncOptions<User>): DynamicModule;
|
|
162
|
+
static createGuard(options: JwtAuthGuardOptions): JwtAuthGuard;
|
|
65
163
|
private static normalizeDriverProvider;
|
|
66
164
|
}
|
|
67
165
|
|
|
68
|
-
|
|
166
|
+
interface PrismaModelDelegate {
|
|
167
|
+
findUnique(args: {
|
|
168
|
+
where: Record<string, unknown>;
|
|
169
|
+
}): Promise<any>;
|
|
170
|
+
}
|
|
171
|
+
type PrismaClientLike = Record<string, PrismaModelDelegate | undefined>;
|
|
69
172
|
interface JwtPrismaDriverOptions {
|
|
70
173
|
prisma: PrismaClientLike;
|
|
71
174
|
/**
|
|
@@ -102,12 +205,52 @@ interface JwtPrismaDriverOptions {
|
|
|
102
205
|
cookieOptions?: Partial<CookieOptions>;
|
|
103
206
|
/**
|
|
104
207
|
* Função de comparação de senha (p.ex. bcrypt.compare).
|
|
208
|
+
* Obrigatório — não há fallback para comparação em plain-text.
|
|
105
209
|
*/
|
|
106
|
-
comparePassword
|
|
210
|
+
comparePassword: (provided: string, stored: unknown) => Promise<boolean> | boolean;
|
|
107
211
|
/**
|
|
108
212
|
* Permite alterar a shape do usuário retornado.
|
|
109
213
|
*/
|
|
110
214
|
transformUser?: <T extends Record<string, any>>(user: T) => any;
|
|
215
|
+
/**
|
|
216
|
+
* Habilita proteção CSRF via double-submit cookie.
|
|
217
|
+
* No login, emite um cookie `csrf_token` (não-httpOnly) que o cliente
|
|
218
|
+
* deve enviar no header `x-csrf-token` em requisições autenticadas.
|
|
219
|
+
*/
|
|
220
|
+
csrf?: boolean;
|
|
221
|
+
/**
|
|
222
|
+
* Callback de auditoria chamado em cada evento de autenticação.
|
|
223
|
+
*/
|
|
224
|
+
onAudit?: (event: AuditEvent) => void | Promise<void>;
|
|
225
|
+
/**
|
|
226
|
+
* Callback de rate limiting chamado antes de cada tentativa de login.
|
|
227
|
+
* Retorne `false` para bloquear a tentativa.
|
|
228
|
+
*/
|
|
229
|
+
onRateLimitCheck?: (ip: string, identifier: string) => Promise<boolean> | boolean;
|
|
230
|
+
/**
|
|
231
|
+
* Configuração de account lockout.
|
|
232
|
+
*/
|
|
233
|
+
lockout?: {
|
|
234
|
+
/** Número máximo de tentativas antes de bloquear (default: 5). */
|
|
235
|
+
maxAttempts?: number;
|
|
236
|
+
/** Janela de tempo em ms para contar falhas (default: 15 min). */
|
|
237
|
+
windowMs?: number;
|
|
238
|
+
/** Store customizado para persistir falhas (default: InMemoryLockoutStore). */
|
|
239
|
+
store?: LockoutStore;
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Configuração de refresh token rotation.
|
|
243
|
+
* Quando habilitado, login emite um par access + refresh token.
|
|
244
|
+
*/
|
|
245
|
+
refreshToken?: {
|
|
246
|
+
enabled: boolean;
|
|
247
|
+
/** Nome do cookie do refresh token (default: "refresh_token"). */
|
|
248
|
+
cookieName?: string;
|
|
249
|
+
/** Tempo de expiração do refresh token (default: "30d"). */
|
|
250
|
+
expiresIn?: SignOptions["expiresIn"];
|
|
251
|
+
/** Store para persistir refresh tokens (default: InMemoryRefreshTokenStore). */
|
|
252
|
+
store?: RefreshTokenStore;
|
|
253
|
+
};
|
|
111
254
|
}
|
|
112
255
|
declare class JwtPrismaCookieAuthDriver<User extends Record<string, any>> implements AuthDriver<User> {
|
|
113
256
|
private readonly prismaModel;
|
|
@@ -120,10 +263,22 @@ declare class JwtPrismaCookieAuthDriver<User extends Record<string, any>> implem
|
|
|
120
263
|
private readonly cookieOptions;
|
|
121
264
|
private readonly comparePassword;
|
|
122
265
|
private readonly transformUser;
|
|
266
|
+
private readonly csrf;
|
|
267
|
+
private readonly onAudit?;
|
|
268
|
+
private readonly onRateLimitCheck?;
|
|
269
|
+
private readonly lockoutStore?;
|
|
270
|
+
private readonly lockoutMaxAttempts;
|
|
271
|
+
private readonly refreshTokenEnabled;
|
|
272
|
+
private readonly refreshTokenCookieName;
|
|
273
|
+
private readonly refreshTokenExpiresIn;
|
|
274
|
+
private readonly refreshTokenStore?;
|
|
123
275
|
constructor(options: JwtPrismaDriverOptions);
|
|
124
|
-
login(payload:
|
|
276
|
+
login(payload: LoginPayload, req: Request, res: Response): Promise<User>;
|
|
125
277
|
checkIn(req: Request, res: Response): Promise<User | null>;
|
|
126
|
-
logout(
|
|
278
|
+
logout(req: Request, res: Response): Promise<void>;
|
|
279
|
+
refresh(req: Request, res: Response): Promise<User | null>;
|
|
280
|
+
private issueRefreshToken;
|
|
281
|
+
private emitAudit;
|
|
127
282
|
}
|
|
128
283
|
|
|
129
|
-
export { AUTH_DRIVER, AuthController, type AuthDriver, AuthModule, type AuthModuleAsyncOptions, type AuthModuleOptions, type AuthPayload, type AuthResponse, type DriverProvider, JwtPrismaCookieAuthDriver, type JwtPrismaDriverOptions, type LogoutResponse };
|
|
284
|
+
export { AUTH_DRIVER, type AuditEvent, AuthController, type AuthDriver, AuthModule, type AuthModuleAsyncOptions, type AuthModuleOptions, type AuthPayload, type AuthResponse, type AuthenticatedUser, type DriverProvider, InMemoryLockoutStore, InMemoryRefreshTokenStore, type JwtAccessPayload, JwtAuthGuard, type JwtAuthGuardOptions, JwtPrismaCookieAuthDriver, type JwtPrismaDriverOptions, type JwtRefreshPayload, type LockoutStore, type LoginPayload, type LogoutResponse, type PrismaClientLike, type PrismaModelDelegate, ROLES_KEY, type RefreshTokenStore, Roles, RolesGuard };
|