@ministerjs/auth 1.0.2 → 2.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 +10 -112
- package/dist/nestjs.d.mts +129 -0
- package/dist/nestjs.d.ts +129 -0
- package/dist/nestjs.js +237 -0
- package/dist/nestjs.mjs +219 -0
- package/dist/{Auth.js → vue.js} +6 -4
- package/dist/{Auth.mjs → vue.mjs} +1 -1
- package/package.json +39 -10
- package/types/index.d.ts +2 -0
- package/types/nestjs/AuthController.d.ts +10 -0
- package/types/nestjs/AuthModule.d.ts +32 -0
- package/types/nestjs/JwtPrismaCookieAuthDriver.d.ts +65 -0
- package/types/nestjs/index.d.ts +5 -0
- package/types/nestjs/token.d.ts +2 -0
- package/types/nestjs/types.d.ts +24 -0
- package/types/vue/VueAuth.d.ts +32 -0
- package/types/vue/index.d.ts +1 -0
- /package/dist/{Auth.d.mts → vue.d.mts} +0 -0
- /package/dist/{Auth.d.ts → vue.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# @ministerjs/auth
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Biblioteca de autenticação com dois alvos:
|
|
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).
|
|
6
|
+
|
|
7
|
+
## Sumário
|
|
8
|
+
- [Uso no front (Vue)](./src/vue/README.md)
|
|
9
|
+
- [Uso no backend (NestJS)](./src/nestjs/README.md)
|
|
4
10
|
|
|
5
11
|
## Instalação
|
|
6
12
|
|
|
@@ -8,114 +14,6 @@ Classe para gerenciar autenticação de usuários em aplicações Vue.
|
|
|
8
14
|
pnpm add @ministerjs/auth
|
|
9
15
|
```
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
import { Auth } from "@ministerjs/auth/Auth";
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Exemplo de Uso
|
|
19
|
-
|
|
20
|
-
```ts
|
|
21
|
-
import { Auth } from "@ministerjs/auth/Auth";
|
|
22
|
-
|
|
23
|
-
const auth = new Auth({
|
|
24
|
-
fetch: window.fetch.bind(window),
|
|
25
|
-
mapUser: (user) => {
|
|
26
|
-
// Transformar ou filtrar dados do usuário antes de salvar
|
|
27
|
-
return {
|
|
28
|
-
...user,
|
|
29
|
-
fullName: `${user.firstName} ${user.lastName}`,
|
|
30
|
-
};
|
|
31
|
-
},
|
|
32
|
-
routes: {
|
|
33
|
-
login: "/api/login",
|
|
34
|
-
checkIn: "/api/checkin",
|
|
35
|
-
logout: "/api/logout",
|
|
36
|
-
},
|
|
37
|
-
afterLogout: () => {
|
|
38
|
-
// Ações após fazer logout
|
|
39
|
-
console.log("Usuário deslogado!");
|
|
40
|
-
},
|
|
41
|
-
afterCheckIn: (result) => {
|
|
42
|
-
// Ações após verificação do estado de login
|
|
43
|
-
console.log("CheckIn foi bem-sucedido?", result);
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Atributos Importantes
|
|
49
|
-
|
|
50
|
-
- **`auth.user`**: contém os dados do usuário autenticado (ou `null` se não autenticado).
|
|
51
|
-
- **`auth.on`**: booleano que indica se o usuário está logado (`true`/`false`).
|
|
52
|
-
- **`auth.loading`**: booleano que indica se há uma operação de login, checkIn ou logout em andamento.
|
|
53
|
-
- **`auth.checkedIn`**: booleano que indica se o `checkIn()` já foi executado.
|
|
54
|
-
|
|
55
|
-
### Métodos
|
|
56
|
-
|
|
57
|
-
#### `login(payload: Record<string, any>)`
|
|
58
|
-
|
|
59
|
-
- Faz a chamada de login para a rota configurada em `routes.login`.
|
|
60
|
-
- Ao receber resposta:
|
|
61
|
-
- Define `auth.on` como `true`.
|
|
62
|
-
- Armazena o usuário em `auth.user`.
|
|
63
|
-
- Define `auth.loading` como `false`.
|
|
64
|
-
|
|
65
|
-
**Exemplo**:
|
|
66
|
-
```ts
|
|
67
|
-
await auth.login({ username: "john", password: "1234" });
|
|
68
|
-
console.log(auth.user.value); // Dados do usuário logado
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
#### `checkIn()`
|
|
72
|
-
|
|
73
|
-
- Verifica se o usuário já está autenticado (ex.: mantém a sessão em abas novas).
|
|
74
|
-
- Atualiza `auth.user` e `auth.on` conforme o resultado.
|
|
75
|
-
- Chama o callback `afterCheckIn(true|false)` dependendo do sucesso ou falha na verificação.
|
|
76
|
-
- Atualiza `auth.checkedIn` para `true` quando finaliza.
|
|
77
|
-
|
|
78
|
-
**Exemplo**:
|
|
79
|
-
```ts
|
|
80
|
-
await auth.checkIn();
|
|
81
|
-
console.log(auth.on.value); // true ou false
|
|
82
|
-
console.log(auth.checkedIn.value); // true
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
#### `logout()`
|
|
86
|
-
|
|
87
|
-
- Faz a chamada de logout para a rota configurada em `routes.logout`.
|
|
88
|
-
- Define `auth.on` como `false`, limpa `auth.user` e chama `afterLogout()` após concluir.
|
|
89
|
-
|
|
90
|
-
**Exemplo**:
|
|
91
|
-
```ts
|
|
92
|
-
await auth.logout();
|
|
93
|
-
console.log(auth.on.value); // false
|
|
94
|
-
console.log(auth.user.value); // null
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Opções do Construtor
|
|
98
|
-
|
|
99
|
-
- **`fetch: Fetch`**
|
|
100
|
-
Instância de Fetch responsável pelas requisições HTTP.
|
|
101
|
-
|
|
102
|
-
- **`mapUser?: (user: User) => User`**
|
|
103
|
-
Callback para ajustar dados do usuário antes de armazenar em `auth.user`.
|
|
104
|
-
|
|
105
|
-
- **`routes?: { login?: string; checkIn?: string; logout?: string; }`**
|
|
106
|
-
Rotas customizadas para as operações de login, checkIn e logout.
|
|
107
|
-
|
|
108
|
-
- **`afterLogout?: () => void | Promise<void>`**
|
|
109
|
-
Executado logo após o logout.
|
|
110
|
-
|
|
111
|
-
- **`afterCheckIn?: (result: boolean) => void | Promise<void>`**
|
|
112
|
-
Executado após a tentativa de checkIn, recebendo `true` ou `false` como resultado.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
## Rotas do Backend
|
|
116
|
-
|
|
117
|
-
Para que a classe Auth funcione corretamente, o backend deve expor as rotas (por padrão: `/api/login`, `/api/checkin`, `/api/logout`).
|
|
118
|
-
|
|
119
|
-
- **Login**: recebe as credenciais no corpo da requisição, valida e retorna `{ message, data }`.
|
|
120
|
-
- **CheckIn**: verifica a sessão e retorna `{ message, data }` se o usuário estiver autenticado, ou algum erro/status caso não esteja.
|
|
121
|
-
- **Logout**: invalida a sessão/tokens e retorna `{ message }`.
|
|
17
|
+
Escolha o subpath conforme o lado da aplicação:
|
|
18
|
+
- Front: `@ministerjs/auth/vue`
|
|
19
|
+
- Back: `@ministerjs/auth/nestjs`
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { Request, Response, CookieOptions } from 'express';
|
|
2
|
+
import { Type, DynamicModule } from '@nestjs/common';
|
|
3
|
+
import { SignOptions } from 'jsonwebtoken';
|
|
4
|
+
|
|
5
|
+
type AuthPayload = Record<string, any>;
|
|
6
|
+
interface AuthResponse<User> {
|
|
7
|
+
message: string;
|
|
8
|
+
data: User;
|
|
9
|
+
}
|
|
10
|
+
interface LogoutResponse {
|
|
11
|
+
message: string;
|
|
12
|
+
}
|
|
13
|
+
interface AuthDriver<User = any> {
|
|
14
|
+
/**
|
|
15
|
+
* Deve validar o payload recebido e retornar o usuário autenticado.
|
|
16
|
+
*/
|
|
17
|
+
login(payload: AuthPayload, request: Request, response: Response): Promise<User> | User;
|
|
18
|
+
/**
|
|
19
|
+
* Deve recuperar o usuário a partir do contexto (cookies, headers, sessão, etc.).
|
|
20
|
+
* Retorne `null` ou `undefined` quando não houver sessão ativa.
|
|
21
|
+
*/
|
|
22
|
+
checkIn(request: Request, response: Response): Promise<User | null | undefined> | User | null | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Deve encerrar a sessão/tokens do usuário.
|
|
25
|
+
*/
|
|
26
|
+
logout(request: Request, response: Response): Promise<void> | void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare const AUTH_DRIVER: unique symbol;
|
|
30
|
+
|
|
31
|
+
declare class AuthController<User extends Record<string, any> = Record<string, any>> {
|
|
32
|
+
private readonly driver;
|
|
33
|
+
constructor(driver: AuthDriver<User>);
|
|
34
|
+
login(body: AuthPayload, request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
35
|
+
checkIn(request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
36
|
+
logout(request: Request, response: Response): Promise<LogoutResponse>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type DriverProvider<User> = AuthDriver<User> | {
|
|
40
|
+
useValue: AuthDriver<User>;
|
|
41
|
+
} | {
|
|
42
|
+
useClass: Type<AuthDriver<User>>;
|
|
43
|
+
} | {
|
|
44
|
+
useFactory: (...args: any[]) => Promise<AuthDriver<User>> | AuthDriver<User>;
|
|
45
|
+
inject?: any[];
|
|
46
|
+
} | Type<AuthDriver<User>>;
|
|
47
|
+
interface AuthModuleOptions<User = any> {
|
|
48
|
+
/**
|
|
49
|
+
* Provider que implementa a interface AuthDriver.
|
|
50
|
+
* Aceita instância direta, classe Nest provider ou useFactory.
|
|
51
|
+
*/
|
|
52
|
+
driver: DriverProvider<User>;
|
|
53
|
+
}
|
|
54
|
+
interface AuthModuleAsyncOptions<User = any> {
|
|
55
|
+
imports?: any[];
|
|
56
|
+
/**
|
|
57
|
+
* Factory que devolve uma instância de AuthDriver.
|
|
58
|
+
*/
|
|
59
|
+
useFactory: (...args: any[]) => Promise<AuthDriver<User>> | AuthDriver<User>;
|
|
60
|
+
inject?: any[];
|
|
61
|
+
}
|
|
62
|
+
declare class AuthModule {
|
|
63
|
+
static register<User = any>(options: AuthModuleOptions<User>): DynamicModule;
|
|
64
|
+
static registerAsync<User = any>(options: AuthModuleAsyncOptions<User>): DynamicModule;
|
|
65
|
+
private static normalizeDriverProvider;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type PrismaClientLike = Record<string, any>;
|
|
69
|
+
interface JwtPrismaDriverOptions {
|
|
70
|
+
prisma: PrismaClientLike;
|
|
71
|
+
/**
|
|
72
|
+
* Nome do model Prisma (ex.: "user").
|
|
73
|
+
*/
|
|
74
|
+
modelName: string;
|
|
75
|
+
/**
|
|
76
|
+
* Campo usado como identificador de login (ex.: "email").
|
|
77
|
+
*/
|
|
78
|
+
identifierField?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Campo usado como senha (hash) no banco.
|
|
81
|
+
*/
|
|
82
|
+
passwordField?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Campo de ID primário (usado no payload do token).
|
|
85
|
+
*/
|
|
86
|
+
idField?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Segredo para assinar/verificar JWT.
|
|
89
|
+
*/
|
|
90
|
+
jwtSecret: string;
|
|
91
|
+
/**
|
|
92
|
+
* Tempo de expiração (aceita formato jsonwebtoken, ex.: "7d").
|
|
93
|
+
*/
|
|
94
|
+
jwtExpiresIn?: SignOptions["expiresIn"];
|
|
95
|
+
/**
|
|
96
|
+
* Nome do cookie que armazena o token.
|
|
97
|
+
*/
|
|
98
|
+
cookieName?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Opções do cookie (secure, sameSite etc).
|
|
101
|
+
*/
|
|
102
|
+
cookieOptions?: Partial<CookieOptions>;
|
|
103
|
+
/**
|
|
104
|
+
* Função de comparação de senha (p.ex. bcrypt.compare).
|
|
105
|
+
*/
|
|
106
|
+
comparePassword?: (provided: string, stored: unknown) => Promise<boolean> | boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Permite alterar a shape do usuário retornado.
|
|
109
|
+
*/
|
|
110
|
+
transformUser?: <T extends Record<string, any>>(user: T) => any;
|
|
111
|
+
}
|
|
112
|
+
declare class JwtPrismaCookieAuthDriver<User extends Record<string, any>> implements AuthDriver<User> {
|
|
113
|
+
private readonly prismaModel;
|
|
114
|
+
private readonly identifierField;
|
|
115
|
+
private readonly passwordField;
|
|
116
|
+
private readonly idField;
|
|
117
|
+
private readonly jwtSecret;
|
|
118
|
+
private readonly jwtExpiresIn;
|
|
119
|
+
private readonly cookieName;
|
|
120
|
+
private readonly cookieOptions;
|
|
121
|
+
private readonly comparePassword;
|
|
122
|
+
private readonly transformUser;
|
|
123
|
+
constructor(options: JwtPrismaDriverOptions);
|
|
124
|
+
login(payload: AuthPayload, _req: Request, res: Response): Promise<User>;
|
|
125
|
+
checkIn(req: Request, res: Response): Promise<User | null>;
|
|
126
|
+
logout(_req: Request, res: Response): Promise<void>;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export { AUTH_DRIVER, AuthController, type AuthDriver, AuthModule, type AuthModuleAsyncOptions, type AuthModuleOptions, type AuthPayload, type AuthResponse, type DriverProvider, JwtPrismaCookieAuthDriver, type JwtPrismaDriverOptions, type LogoutResponse };
|
package/dist/nestjs.d.ts
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { Request, Response, CookieOptions } from 'express';
|
|
2
|
+
import { Type, DynamicModule } from '@nestjs/common';
|
|
3
|
+
import { SignOptions } from 'jsonwebtoken';
|
|
4
|
+
|
|
5
|
+
type AuthPayload = Record<string, any>;
|
|
6
|
+
interface AuthResponse<User> {
|
|
7
|
+
message: string;
|
|
8
|
+
data: User;
|
|
9
|
+
}
|
|
10
|
+
interface LogoutResponse {
|
|
11
|
+
message: string;
|
|
12
|
+
}
|
|
13
|
+
interface AuthDriver<User = any> {
|
|
14
|
+
/**
|
|
15
|
+
* Deve validar o payload recebido e retornar o usuário autenticado.
|
|
16
|
+
*/
|
|
17
|
+
login(payload: AuthPayload, request: Request, response: Response): Promise<User> | User;
|
|
18
|
+
/**
|
|
19
|
+
* Deve recuperar o usuário a partir do contexto (cookies, headers, sessão, etc.).
|
|
20
|
+
* Retorne `null` ou `undefined` quando não houver sessão ativa.
|
|
21
|
+
*/
|
|
22
|
+
checkIn(request: Request, response: Response): Promise<User | null | undefined> | User | null | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Deve encerrar a sessão/tokens do usuário.
|
|
25
|
+
*/
|
|
26
|
+
logout(request: Request, response: Response): Promise<void> | void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare const AUTH_DRIVER: unique symbol;
|
|
30
|
+
|
|
31
|
+
declare class AuthController<User extends Record<string, any> = Record<string, any>> {
|
|
32
|
+
private readonly driver;
|
|
33
|
+
constructor(driver: AuthDriver<User>);
|
|
34
|
+
login(body: AuthPayload, request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
35
|
+
checkIn(request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
36
|
+
logout(request: Request, response: Response): Promise<LogoutResponse>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type DriverProvider<User> = AuthDriver<User> | {
|
|
40
|
+
useValue: AuthDriver<User>;
|
|
41
|
+
} | {
|
|
42
|
+
useClass: Type<AuthDriver<User>>;
|
|
43
|
+
} | {
|
|
44
|
+
useFactory: (...args: any[]) => Promise<AuthDriver<User>> | AuthDriver<User>;
|
|
45
|
+
inject?: any[];
|
|
46
|
+
} | Type<AuthDriver<User>>;
|
|
47
|
+
interface AuthModuleOptions<User = any> {
|
|
48
|
+
/**
|
|
49
|
+
* Provider que implementa a interface AuthDriver.
|
|
50
|
+
* Aceita instância direta, classe Nest provider ou useFactory.
|
|
51
|
+
*/
|
|
52
|
+
driver: DriverProvider<User>;
|
|
53
|
+
}
|
|
54
|
+
interface AuthModuleAsyncOptions<User = any> {
|
|
55
|
+
imports?: any[];
|
|
56
|
+
/**
|
|
57
|
+
* Factory que devolve uma instância de AuthDriver.
|
|
58
|
+
*/
|
|
59
|
+
useFactory: (...args: any[]) => Promise<AuthDriver<User>> | AuthDriver<User>;
|
|
60
|
+
inject?: any[];
|
|
61
|
+
}
|
|
62
|
+
declare class AuthModule {
|
|
63
|
+
static register<User = any>(options: AuthModuleOptions<User>): DynamicModule;
|
|
64
|
+
static registerAsync<User = any>(options: AuthModuleAsyncOptions<User>): DynamicModule;
|
|
65
|
+
private static normalizeDriverProvider;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type PrismaClientLike = Record<string, any>;
|
|
69
|
+
interface JwtPrismaDriverOptions {
|
|
70
|
+
prisma: PrismaClientLike;
|
|
71
|
+
/**
|
|
72
|
+
* Nome do model Prisma (ex.: "user").
|
|
73
|
+
*/
|
|
74
|
+
modelName: string;
|
|
75
|
+
/**
|
|
76
|
+
* Campo usado como identificador de login (ex.: "email").
|
|
77
|
+
*/
|
|
78
|
+
identifierField?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Campo usado como senha (hash) no banco.
|
|
81
|
+
*/
|
|
82
|
+
passwordField?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Campo de ID primário (usado no payload do token).
|
|
85
|
+
*/
|
|
86
|
+
idField?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Segredo para assinar/verificar JWT.
|
|
89
|
+
*/
|
|
90
|
+
jwtSecret: string;
|
|
91
|
+
/**
|
|
92
|
+
* Tempo de expiração (aceita formato jsonwebtoken, ex.: "7d").
|
|
93
|
+
*/
|
|
94
|
+
jwtExpiresIn?: SignOptions["expiresIn"];
|
|
95
|
+
/**
|
|
96
|
+
* Nome do cookie que armazena o token.
|
|
97
|
+
*/
|
|
98
|
+
cookieName?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Opções do cookie (secure, sameSite etc).
|
|
101
|
+
*/
|
|
102
|
+
cookieOptions?: Partial<CookieOptions>;
|
|
103
|
+
/**
|
|
104
|
+
* Função de comparação de senha (p.ex. bcrypt.compare).
|
|
105
|
+
*/
|
|
106
|
+
comparePassword?: (provided: string, stored: unknown) => Promise<boolean> | boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Permite alterar a shape do usuário retornado.
|
|
109
|
+
*/
|
|
110
|
+
transformUser?: <T extends Record<string, any>>(user: T) => any;
|
|
111
|
+
}
|
|
112
|
+
declare class JwtPrismaCookieAuthDriver<User extends Record<string, any>> implements AuthDriver<User> {
|
|
113
|
+
private readonly prismaModel;
|
|
114
|
+
private readonly identifierField;
|
|
115
|
+
private readonly passwordField;
|
|
116
|
+
private readonly idField;
|
|
117
|
+
private readonly jwtSecret;
|
|
118
|
+
private readonly jwtExpiresIn;
|
|
119
|
+
private readonly cookieName;
|
|
120
|
+
private readonly cookieOptions;
|
|
121
|
+
private readonly comparePassword;
|
|
122
|
+
private readonly transformUser;
|
|
123
|
+
constructor(options: JwtPrismaDriverOptions);
|
|
124
|
+
login(payload: AuthPayload, _req: Request, res: Response): Promise<User>;
|
|
125
|
+
checkIn(req: Request, res: Response): Promise<User | null>;
|
|
126
|
+
logout(_req: Request, res: Response): Promise<void>;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export { AUTH_DRIVER, AuthController, type AuthDriver, AuthModule, type AuthModuleAsyncOptions, type AuthModuleOptions, type AuthPayload, type AuthResponse, type DriverProvider, JwtPrismaCookieAuthDriver, type JwtPrismaDriverOptions, type LogoutResponse };
|
package/dist/nestjs.js
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
20
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
21
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
22
|
+
if (decorator = decorators[i])
|
|
23
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
24
|
+
if (kind && result) __defProp(target, key, result);
|
|
25
|
+
return result;
|
|
26
|
+
};
|
|
27
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
28
|
+
|
|
29
|
+
// src/nestjs/index.ts
|
|
30
|
+
var nestjs_exports = {};
|
|
31
|
+
__export(nestjs_exports, {
|
|
32
|
+
AUTH_DRIVER: () => AUTH_DRIVER,
|
|
33
|
+
AuthController: () => AuthController,
|
|
34
|
+
AuthModule: () => AuthModule,
|
|
35
|
+
JwtPrismaCookieAuthDriver: () => JwtPrismaCookieAuthDriver
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(nestjs_exports);
|
|
38
|
+
|
|
39
|
+
// src/nestjs/token.ts
|
|
40
|
+
var AUTH_DRIVER = Symbol("AUTH_DRIVER");
|
|
41
|
+
|
|
42
|
+
// src/nestjs/AuthController.ts
|
|
43
|
+
var import_common = require("@nestjs/common");
|
|
44
|
+
var AuthController = class {
|
|
45
|
+
constructor(driver) {
|
|
46
|
+
this.driver = driver;
|
|
47
|
+
}
|
|
48
|
+
async login(body, request, response) {
|
|
49
|
+
const user = await this.driver.login(body, request, response);
|
|
50
|
+
return { message: "ok", data: user };
|
|
51
|
+
}
|
|
52
|
+
async checkIn(request, response) {
|
|
53
|
+
const user = await this.driver.checkIn(request, response);
|
|
54
|
+
if (!user) {
|
|
55
|
+
throw new import_common.UnauthorizedException("Not authenticated");
|
|
56
|
+
}
|
|
57
|
+
return { message: "ok", data: user };
|
|
58
|
+
}
|
|
59
|
+
async logout(request, response) {
|
|
60
|
+
await this.driver.logout(request, response);
|
|
61
|
+
return { message: "ok" };
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
__decorateClass([
|
|
65
|
+
(0, import_common.Post)("/login"),
|
|
66
|
+
(0, import_common.HttpCode)(200),
|
|
67
|
+
__decorateParam(0, (0, import_common.Body)()),
|
|
68
|
+
__decorateParam(1, (0, import_common.Req)()),
|
|
69
|
+
__decorateParam(2, (0, import_common.Res)({ passthrough: true }))
|
|
70
|
+
], AuthController.prototype, "login", 1);
|
|
71
|
+
__decorateClass([
|
|
72
|
+
(0, import_common.Post)("/checkin"),
|
|
73
|
+
(0, import_common.HttpCode)(200),
|
|
74
|
+
__decorateParam(0, (0, import_common.Req)()),
|
|
75
|
+
__decorateParam(1, (0, import_common.Res)({ passthrough: true }))
|
|
76
|
+
], AuthController.prototype, "checkIn", 1);
|
|
77
|
+
__decorateClass([
|
|
78
|
+
(0, import_common.Post)("/logout"),
|
|
79
|
+
(0, import_common.HttpCode)(200),
|
|
80
|
+
__decorateParam(0, (0, import_common.Req)()),
|
|
81
|
+
__decorateParam(1, (0, import_common.Res)({ passthrough: true }))
|
|
82
|
+
], AuthController.prototype, "logout", 1);
|
|
83
|
+
AuthController = __decorateClass([
|
|
84
|
+
(0, import_common.Controller)(),
|
|
85
|
+
__decorateParam(0, (0, import_common.Inject)(AUTH_DRIVER))
|
|
86
|
+
], AuthController);
|
|
87
|
+
|
|
88
|
+
// src/nestjs/AuthModule.ts
|
|
89
|
+
var import_common2 = require("@nestjs/common");
|
|
90
|
+
var AuthModule = class {
|
|
91
|
+
static register(options) {
|
|
92
|
+
const driverProvider = this.normalizeDriverProvider(options.driver);
|
|
93
|
+
return {
|
|
94
|
+
module: AuthModule,
|
|
95
|
+
controllers: [AuthController],
|
|
96
|
+
providers: [driverProvider],
|
|
97
|
+
exports: [driverProvider]
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
static registerAsync(options) {
|
|
101
|
+
const driverProvider = {
|
|
102
|
+
provide: AUTH_DRIVER,
|
|
103
|
+
useFactory: options.useFactory,
|
|
104
|
+
inject: options.inject ?? []
|
|
105
|
+
};
|
|
106
|
+
return {
|
|
107
|
+
module: AuthModule,
|
|
108
|
+
imports: options.imports ?? [],
|
|
109
|
+
controllers: [AuthController],
|
|
110
|
+
providers: [driverProvider],
|
|
111
|
+
exports: [driverProvider]
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
static normalizeDriverProvider(driver) {
|
|
115
|
+
if (typeof driver === "function") {
|
|
116
|
+
return { provide: AUTH_DRIVER, useClass: driver };
|
|
117
|
+
}
|
|
118
|
+
if ("useClass" in driver) {
|
|
119
|
+
return { provide: AUTH_DRIVER, useClass: driver.useClass };
|
|
120
|
+
}
|
|
121
|
+
if ("useFactory" in driver) {
|
|
122
|
+
return {
|
|
123
|
+
provide: AUTH_DRIVER,
|
|
124
|
+
useFactory: driver.useFactory,
|
|
125
|
+
inject: driver.inject ?? []
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if ("useValue" in driver) {
|
|
129
|
+
return { provide: AUTH_DRIVER, useValue: driver.useValue };
|
|
130
|
+
}
|
|
131
|
+
return { provide: AUTH_DRIVER, useValue: driver };
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
AuthModule = __decorateClass([
|
|
135
|
+
(0, import_common2.Module)({})
|
|
136
|
+
], AuthModule);
|
|
137
|
+
|
|
138
|
+
// src/nestjs/JwtPrismaCookieAuthDriver.ts
|
|
139
|
+
var import_common3 = require("@nestjs/common");
|
|
140
|
+
var import_jsonwebtoken = require("jsonwebtoken");
|
|
141
|
+
var defaultCookieOptions = {
|
|
142
|
+
httpOnly: true,
|
|
143
|
+
sameSite: "lax",
|
|
144
|
+
path: "/"
|
|
145
|
+
};
|
|
146
|
+
var JwtPrismaCookieAuthDriver = class {
|
|
147
|
+
prismaModel;
|
|
148
|
+
identifierField;
|
|
149
|
+
passwordField;
|
|
150
|
+
idField;
|
|
151
|
+
jwtSecret;
|
|
152
|
+
jwtExpiresIn;
|
|
153
|
+
cookieName;
|
|
154
|
+
cookieOptions;
|
|
155
|
+
comparePassword;
|
|
156
|
+
transformUser;
|
|
157
|
+
constructor(options) {
|
|
158
|
+
this.prismaModel = options.prisma[options.modelName];
|
|
159
|
+
if (!this.prismaModel) {
|
|
160
|
+
throw new Error(
|
|
161
|
+
`Model "${options.modelName}" n\xE3o encontrado no PrismaClient.`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
this.identifierField = options.identifierField ?? "email";
|
|
165
|
+
this.passwordField = options.passwordField ?? "password";
|
|
166
|
+
this.idField = options.idField ?? "id";
|
|
167
|
+
this.jwtSecret = options.jwtSecret;
|
|
168
|
+
this.jwtExpiresIn = options.jwtExpiresIn ?? "7d";
|
|
169
|
+
this.cookieName = options.cookieName ?? "auth_token";
|
|
170
|
+
this.cookieOptions = {
|
|
171
|
+
...defaultCookieOptions,
|
|
172
|
+
...options.cookieOptions ?? {}
|
|
173
|
+
};
|
|
174
|
+
this.comparePassword = options.comparePassword ?? ((provided, stored) => String(stored) === provided);
|
|
175
|
+
this.transformUser = options.transformUser ?? ((user) => {
|
|
176
|
+
const clone = { ...user };
|
|
177
|
+
delete clone[this.passwordField];
|
|
178
|
+
return clone;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
async login(payload, _req, res) {
|
|
182
|
+
const identifier = payload[this.identifierField];
|
|
183
|
+
const user = await this.prismaModel.findUnique({
|
|
184
|
+
where: { [this.identifierField]: identifier }
|
|
185
|
+
});
|
|
186
|
+
if (!user) {
|
|
187
|
+
throw new import_common3.UnauthorizedException("Invalid credentials");
|
|
188
|
+
}
|
|
189
|
+
const ok = await this.comparePassword(
|
|
190
|
+
payload[this.passwordField],
|
|
191
|
+
user[this.passwordField]
|
|
192
|
+
);
|
|
193
|
+
if (!ok) {
|
|
194
|
+
throw new import_common3.UnauthorizedException("Invalid credentials");
|
|
195
|
+
}
|
|
196
|
+
const token = (0, import_jsonwebtoken.sign)(
|
|
197
|
+
{ sub: user[this.idField] },
|
|
198
|
+
this.jwtSecret,
|
|
199
|
+
{ expiresIn: this.jwtExpiresIn }
|
|
200
|
+
);
|
|
201
|
+
res.cookie(this.cookieName, token, this.cookieOptions);
|
|
202
|
+
return this.transformUser(user);
|
|
203
|
+
}
|
|
204
|
+
async checkIn(req, res) {
|
|
205
|
+
const token = req.cookies?.[this.cookieName];
|
|
206
|
+
if (!token) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
let payload;
|
|
210
|
+
try {
|
|
211
|
+
payload = (0, import_jsonwebtoken.verify)(token, this.jwtSecret);
|
|
212
|
+
} catch {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
const user = await this.prismaModel.findUnique({
|
|
216
|
+
where: { [this.idField]: payload.sub }
|
|
217
|
+
});
|
|
218
|
+
if (!user) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
res.cookie(this.cookieName, token, this.cookieOptions);
|
|
222
|
+
return this.transformUser(user);
|
|
223
|
+
}
|
|
224
|
+
async logout(_req, res) {
|
|
225
|
+
res.clearCookie(this.cookieName, {
|
|
226
|
+
...this.cookieOptions,
|
|
227
|
+
maxAge: 0
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
232
|
+
0 && (module.exports = {
|
|
233
|
+
AUTH_DRIVER,
|
|
234
|
+
AuthController,
|
|
235
|
+
AuthModule,
|
|
236
|
+
JwtPrismaCookieAuthDriver
|
|
237
|
+
});
|
package/dist/nestjs.mjs
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
12
|
+
|
|
13
|
+
// src/nestjs/token.ts
|
|
14
|
+
var AUTH_DRIVER = Symbol("AUTH_DRIVER");
|
|
15
|
+
|
|
16
|
+
// src/nestjs/AuthController.ts
|
|
17
|
+
import {
|
|
18
|
+
Body,
|
|
19
|
+
Controller,
|
|
20
|
+
HttpCode,
|
|
21
|
+
Inject,
|
|
22
|
+
Post,
|
|
23
|
+
Req,
|
|
24
|
+
Res,
|
|
25
|
+
UnauthorizedException
|
|
26
|
+
} from "@nestjs/common";
|
|
27
|
+
var AuthController = class {
|
|
28
|
+
constructor(driver) {
|
|
29
|
+
this.driver = driver;
|
|
30
|
+
}
|
|
31
|
+
async login(body, request, response) {
|
|
32
|
+
const user = await this.driver.login(body, request, response);
|
|
33
|
+
return { message: "ok", data: user };
|
|
34
|
+
}
|
|
35
|
+
async checkIn(request, response) {
|
|
36
|
+
const user = await this.driver.checkIn(request, response);
|
|
37
|
+
if (!user) {
|
|
38
|
+
throw new UnauthorizedException("Not authenticated");
|
|
39
|
+
}
|
|
40
|
+
return { message: "ok", data: user };
|
|
41
|
+
}
|
|
42
|
+
async logout(request, response) {
|
|
43
|
+
await this.driver.logout(request, response);
|
|
44
|
+
return { message: "ok" };
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
__decorateClass([
|
|
48
|
+
Post("/login"),
|
|
49
|
+
HttpCode(200),
|
|
50
|
+
__decorateParam(0, Body()),
|
|
51
|
+
__decorateParam(1, Req()),
|
|
52
|
+
__decorateParam(2, Res({ passthrough: true }))
|
|
53
|
+
], AuthController.prototype, "login", 1);
|
|
54
|
+
__decorateClass([
|
|
55
|
+
Post("/checkin"),
|
|
56
|
+
HttpCode(200),
|
|
57
|
+
__decorateParam(0, Req()),
|
|
58
|
+
__decorateParam(1, Res({ passthrough: true }))
|
|
59
|
+
], AuthController.prototype, "checkIn", 1);
|
|
60
|
+
__decorateClass([
|
|
61
|
+
Post("/logout"),
|
|
62
|
+
HttpCode(200),
|
|
63
|
+
__decorateParam(0, Req()),
|
|
64
|
+
__decorateParam(1, Res({ passthrough: true }))
|
|
65
|
+
], AuthController.prototype, "logout", 1);
|
|
66
|
+
AuthController = __decorateClass([
|
|
67
|
+
Controller(),
|
|
68
|
+
__decorateParam(0, Inject(AUTH_DRIVER))
|
|
69
|
+
], AuthController);
|
|
70
|
+
|
|
71
|
+
// src/nestjs/AuthModule.ts
|
|
72
|
+
import { Module } from "@nestjs/common";
|
|
73
|
+
var AuthModule = class {
|
|
74
|
+
static register(options) {
|
|
75
|
+
const driverProvider = this.normalizeDriverProvider(options.driver);
|
|
76
|
+
return {
|
|
77
|
+
module: AuthModule,
|
|
78
|
+
controllers: [AuthController],
|
|
79
|
+
providers: [driverProvider],
|
|
80
|
+
exports: [driverProvider]
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
static registerAsync(options) {
|
|
84
|
+
const driverProvider = {
|
|
85
|
+
provide: AUTH_DRIVER,
|
|
86
|
+
useFactory: options.useFactory,
|
|
87
|
+
inject: options.inject ?? []
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
module: AuthModule,
|
|
91
|
+
imports: options.imports ?? [],
|
|
92
|
+
controllers: [AuthController],
|
|
93
|
+
providers: [driverProvider],
|
|
94
|
+
exports: [driverProvider]
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
static normalizeDriverProvider(driver) {
|
|
98
|
+
if (typeof driver === "function") {
|
|
99
|
+
return { provide: AUTH_DRIVER, useClass: driver };
|
|
100
|
+
}
|
|
101
|
+
if ("useClass" in driver) {
|
|
102
|
+
return { provide: AUTH_DRIVER, useClass: driver.useClass };
|
|
103
|
+
}
|
|
104
|
+
if ("useFactory" in driver) {
|
|
105
|
+
return {
|
|
106
|
+
provide: AUTH_DRIVER,
|
|
107
|
+
useFactory: driver.useFactory,
|
|
108
|
+
inject: driver.inject ?? []
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if ("useValue" in driver) {
|
|
112
|
+
return { provide: AUTH_DRIVER, useValue: driver.useValue };
|
|
113
|
+
}
|
|
114
|
+
return { provide: AUTH_DRIVER, useValue: driver };
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
AuthModule = __decorateClass([
|
|
118
|
+
Module({})
|
|
119
|
+
], AuthModule);
|
|
120
|
+
|
|
121
|
+
// src/nestjs/JwtPrismaCookieAuthDriver.ts
|
|
122
|
+
import { UnauthorizedException as UnauthorizedException2 } from "@nestjs/common";
|
|
123
|
+
import { sign, verify } from "jsonwebtoken";
|
|
124
|
+
var defaultCookieOptions = {
|
|
125
|
+
httpOnly: true,
|
|
126
|
+
sameSite: "lax",
|
|
127
|
+
path: "/"
|
|
128
|
+
};
|
|
129
|
+
var JwtPrismaCookieAuthDriver = class {
|
|
130
|
+
prismaModel;
|
|
131
|
+
identifierField;
|
|
132
|
+
passwordField;
|
|
133
|
+
idField;
|
|
134
|
+
jwtSecret;
|
|
135
|
+
jwtExpiresIn;
|
|
136
|
+
cookieName;
|
|
137
|
+
cookieOptions;
|
|
138
|
+
comparePassword;
|
|
139
|
+
transformUser;
|
|
140
|
+
constructor(options) {
|
|
141
|
+
this.prismaModel = options.prisma[options.modelName];
|
|
142
|
+
if (!this.prismaModel) {
|
|
143
|
+
throw new Error(
|
|
144
|
+
`Model "${options.modelName}" n\xE3o encontrado no PrismaClient.`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
this.identifierField = options.identifierField ?? "email";
|
|
148
|
+
this.passwordField = options.passwordField ?? "password";
|
|
149
|
+
this.idField = options.idField ?? "id";
|
|
150
|
+
this.jwtSecret = options.jwtSecret;
|
|
151
|
+
this.jwtExpiresIn = options.jwtExpiresIn ?? "7d";
|
|
152
|
+
this.cookieName = options.cookieName ?? "auth_token";
|
|
153
|
+
this.cookieOptions = {
|
|
154
|
+
...defaultCookieOptions,
|
|
155
|
+
...options.cookieOptions ?? {}
|
|
156
|
+
};
|
|
157
|
+
this.comparePassword = options.comparePassword ?? ((provided, stored) => String(stored) === provided);
|
|
158
|
+
this.transformUser = options.transformUser ?? ((user) => {
|
|
159
|
+
const clone = { ...user };
|
|
160
|
+
delete clone[this.passwordField];
|
|
161
|
+
return clone;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
async login(payload, _req, res) {
|
|
165
|
+
const identifier = payload[this.identifierField];
|
|
166
|
+
const user = await this.prismaModel.findUnique({
|
|
167
|
+
where: { [this.identifierField]: identifier }
|
|
168
|
+
});
|
|
169
|
+
if (!user) {
|
|
170
|
+
throw new UnauthorizedException2("Invalid credentials");
|
|
171
|
+
}
|
|
172
|
+
const ok = await this.comparePassword(
|
|
173
|
+
payload[this.passwordField],
|
|
174
|
+
user[this.passwordField]
|
|
175
|
+
);
|
|
176
|
+
if (!ok) {
|
|
177
|
+
throw new UnauthorizedException2("Invalid credentials");
|
|
178
|
+
}
|
|
179
|
+
const token = sign(
|
|
180
|
+
{ sub: user[this.idField] },
|
|
181
|
+
this.jwtSecret,
|
|
182
|
+
{ expiresIn: this.jwtExpiresIn }
|
|
183
|
+
);
|
|
184
|
+
res.cookie(this.cookieName, token, this.cookieOptions);
|
|
185
|
+
return this.transformUser(user);
|
|
186
|
+
}
|
|
187
|
+
async checkIn(req, res) {
|
|
188
|
+
const token = req.cookies?.[this.cookieName];
|
|
189
|
+
if (!token) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
let payload;
|
|
193
|
+
try {
|
|
194
|
+
payload = verify(token, this.jwtSecret);
|
|
195
|
+
} catch {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
const user = await this.prismaModel.findUnique({
|
|
199
|
+
where: { [this.idField]: payload.sub }
|
|
200
|
+
});
|
|
201
|
+
if (!user) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
res.cookie(this.cookieName, token, this.cookieOptions);
|
|
205
|
+
return this.transformUser(user);
|
|
206
|
+
}
|
|
207
|
+
async logout(_req, res) {
|
|
208
|
+
res.clearCookie(this.cookieName, {
|
|
209
|
+
...this.cookieOptions,
|
|
210
|
+
maxAge: 0
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
export {
|
|
215
|
+
AUTH_DRIVER,
|
|
216
|
+
AuthController,
|
|
217
|
+
AuthModule,
|
|
218
|
+
JwtPrismaCookieAuthDriver
|
|
219
|
+
};
|
package/dist/{Auth.js → vue.js}
RENAMED
|
@@ -17,12 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
|
-
// src/
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
20
|
+
// src/vue/index.ts
|
|
21
|
+
var vue_exports = {};
|
|
22
|
+
__export(vue_exports, {
|
|
23
23
|
Auth: () => Auth
|
|
24
24
|
});
|
|
25
|
-
module.exports = __toCommonJS(
|
|
25
|
+
module.exports = __toCommonJS(vue_exports);
|
|
26
|
+
|
|
27
|
+
// src/vue/VueAuth.ts
|
|
26
28
|
var import_vue = require("vue");
|
|
27
29
|
var Auth = class {
|
|
28
30
|
user = (0, import_vue.ref)(null);
|
package/package.json
CHANGED
|
@@ -1,42 +1,71 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ministerjs/auth",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"dist/*"
|
|
10
|
+
"dist/*",
|
|
11
|
+
"types/*"
|
|
11
12
|
],
|
|
13
|
+
"types": "./types",
|
|
12
14
|
"exports": {
|
|
13
|
-
"./
|
|
14
|
-
"types": "./
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
"./types": {
|
|
16
|
+
"types": "./types/index.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./vue": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.mjs",
|
|
21
|
+
"require": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./nestjs": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"import": "./dist/index.mjs",
|
|
26
|
+
"require": "./dist/index.js"
|
|
17
27
|
}
|
|
18
28
|
},
|
|
19
29
|
"peerDependencies": {
|
|
20
|
-
"vue": "^3.5.12"
|
|
30
|
+
"vue": "^3.5.12",
|
|
31
|
+
"@nestjs/common": "^11.0.11",
|
|
32
|
+
"@prisma/client": "^6.5.0",
|
|
33
|
+
"jsonwebtoken": "^9.0.2"
|
|
34
|
+
},
|
|
35
|
+
"peerDependenciesMeta": {
|
|
36
|
+
"@nestjs/common": {
|
|
37
|
+
"optional": true
|
|
38
|
+
},
|
|
39
|
+
"@prisma/client": {
|
|
40
|
+
"optional": true
|
|
41
|
+
},
|
|
42
|
+
"jsonwebtoken": {
|
|
43
|
+
"optional": true
|
|
44
|
+
}
|
|
21
45
|
},
|
|
22
46
|
"devDependencies": {
|
|
23
47
|
"@ministerjs/build": "^2.1.2",
|
|
24
48
|
"@ministerjs/resource": "1.2.0",
|
|
25
49
|
"@types/node": "^22.13.10",
|
|
50
|
+
"@types/express": "^4.17.21",
|
|
26
51
|
"cross-env": "^7.0.3",
|
|
27
52
|
"eslint": "^9.22.0",
|
|
28
53
|
"globals": "^15.15.0",
|
|
29
54
|
"prettier": "3.5.3",
|
|
30
55
|
"tsup": "^8.4.0",
|
|
31
56
|
"tsx": "^4.19.3",
|
|
32
|
-
"typescript": "
|
|
57
|
+
"typescript": "~5.8.3",
|
|
33
58
|
"vitest": "^3.0.9",
|
|
34
|
-
"vue": "^3.5.13"
|
|
59
|
+
"vue": "^3.5.13",
|
|
60
|
+
"@nestjs/common": "^11.0.11",
|
|
61
|
+
"@types/jsonwebtoken": "^9.0.6",
|
|
62
|
+
"jsonwebtoken": "^9.0.2"
|
|
35
63
|
},
|
|
36
64
|
"scripts": {
|
|
37
65
|
"dev": "tsup --watch",
|
|
38
66
|
"lint": "eslint ./src --fix --config ../../eslint.config.mjs",
|
|
39
67
|
"test": "vitest run --root ../../ --project @ministerjs/auth",
|
|
40
|
-
"build": "
|
|
68
|
+
"build:types": "rimraf types && tsc --project tsconfig.build.json && cpx \"src/**/*.d.ts\" types/",
|
|
69
|
+
"build": "pnpm lint && pnpm test && pnpm build:types && tsup"
|
|
41
70
|
}
|
|
42
71
|
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Request, Response } from "express";
|
|
2
|
+
import type { AuthDriver, AuthPayload, AuthResponse, LogoutResponse } from "./types";
|
|
3
|
+
declare class AuthController<User extends Record<string, any> = Record<string, any>> {
|
|
4
|
+
private readonly driver;
|
|
5
|
+
constructor(driver: AuthDriver<User>);
|
|
6
|
+
login(body: AuthPayload, request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
7
|
+
checkIn(request: Request, response: Response): Promise<AuthResponse<User>>;
|
|
8
|
+
logout(request: Request, response: Response): Promise<LogoutResponse>;
|
|
9
|
+
}
|
|
10
|
+
export { AuthController };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DynamicModule, Type } from "@nestjs/common";
|
|
2
|
+
import type { AuthDriver } from "./types";
|
|
3
|
+
type DriverProvider<User> = AuthDriver<User> | {
|
|
4
|
+
useValue: AuthDriver<User>;
|
|
5
|
+
} | {
|
|
6
|
+
useClass: Type<AuthDriver<User>>;
|
|
7
|
+
} | {
|
|
8
|
+
useFactory: (...args: any[]) => Promise<AuthDriver<User>> | AuthDriver<User>;
|
|
9
|
+
inject?: any[];
|
|
10
|
+
} | Type<AuthDriver<User>>;
|
|
11
|
+
interface AuthModuleOptions<User = any> {
|
|
12
|
+
/**
|
|
13
|
+
* Provider que implementa a interface AuthDriver.
|
|
14
|
+
* Aceita instância direta, classe Nest provider ou useFactory.
|
|
15
|
+
*/
|
|
16
|
+
driver: DriverProvider<User>;
|
|
17
|
+
}
|
|
18
|
+
interface AuthModuleAsyncOptions<User = any> {
|
|
19
|
+
imports?: any[];
|
|
20
|
+
/**
|
|
21
|
+
* Factory que devolve uma instância de AuthDriver.
|
|
22
|
+
*/
|
|
23
|
+
useFactory: (...args: any[]) => Promise<AuthDriver<User>> | AuthDriver<User>;
|
|
24
|
+
inject?: any[];
|
|
25
|
+
}
|
|
26
|
+
declare class AuthModule {
|
|
27
|
+
static register<User = any>(options: AuthModuleOptions<User>): DynamicModule;
|
|
28
|
+
static registerAsync<User = any>(options: AuthModuleAsyncOptions<User>): DynamicModule;
|
|
29
|
+
private static normalizeDriverProvider;
|
|
30
|
+
}
|
|
31
|
+
export type { AuthModuleOptions, AuthModuleAsyncOptions, DriverProvider };
|
|
32
|
+
export { AuthModule };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { CookieOptions, Request, Response } from "express";
|
|
2
|
+
import { type SignOptions } from "jsonwebtoken";
|
|
3
|
+
import type { AuthDriver, AuthPayload } from "./types";
|
|
4
|
+
type PrismaClientLike = Record<string, any>;
|
|
5
|
+
interface JwtPrismaDriverOptions {
|
|
6
|
+
prisma: PrismaClientLike;
|
|
7
|
+
/**
|
|
8
|
+
* Nome do model Prisma (ex.: "user").
|
|
9
|
+
*/
|
|
10
|
+
modelName: string;
|
|
11
|
+
/**
|
|
12
|
+
* Campo usado como identificador de login (ex.: "email").
|
|
13
|
+
*/
|
|
14
|
+
identifierField?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Campo usado como senha (hash) no banco.
|
|
17
|
+
*/
|
|
18
|
+
passwordField?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Campo de ID primário (usado no payload do token).
|
|
21
|
+
*/
|
|
22
|
+
idField?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Segredo para assinar/verificar JWT.
|
|
25
|
+
*/
|
|
26
|
+
jwtSecret: string;
|
|
27
|
+
/**
|
|
28
|
+
* Tempo de expiração (aceita formato jsonwebtoken, ex.: "7d").
|
|
29
|
+
*/
|
|
30
|
+
jwtExpiresIn?: SignOptions["expiresIn"];
|
|
31
|
+
/**
|
|
32
|
+
* Nome do cookie que armazena o token.
|
|
33
|
+
*/
|
|
34
|
+
cookieName?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Opções do cookie (secure, sameSite etc).
|
|
37
|
+
*/
|
|
38
|
+
cookieOptions?: Partial<CookieOptions>;
|
|
39
|
+
/**
|
|
40
|
+
* Função de comparação de senha (p.ex. bcrypt.compare).
|
|
41
|
+
*/
|
|
42
|
+
comparePassword?: (provided: string, stored: unknown) => Promise<boolean> | boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Permite alterar a shape do usuário retornado.
|
|
45
|
+
*/
|
|
46
|
+
transformUser?: <T extends Record<string, any>>(user: T) => any;
|
|
47
|
+
}
|
|
48
|
+
declare class JwtPrismaCookieAuthDriver<User extends Record<string, any>> implements AuthDriver<User> {
|
|
49
|
+
private readonly prismaModel;
|
|
50
|
+
private readonly identifierField;
|
|
51
|
+
private readonly passwordField;
|
|
52
|
+
private readonly idField;
|
|
53
|
+
private readonly jwtSecret;
|
|
54
|
+
private readonly jwtExpiresIn;
|
|
55
|
+
private readonly cookieName;
|
|
56
|
+
private readonly cookieOptions;
|
|
57
|
+
private readonly comparePassword;
|
|
58
|
+
private readonly transformUser;
|
|
59
|
+
constructor(options: JwtPrismaDriverOptions);
|
|
60
|
+
login(payload: AuthPayload, _req: Request, res: Response): Promise<User>;
|
|
61
|
+
checkIn(req: Request, res: Response): Promise<User | null>;
|
|
62
|
+
logout(_req: Request, res: Response): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
export type { JwtPrismaDriverOptions };
|
|
65
|
+
export { JwtPrismaCookieAuthDriver };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Request, Response } from "express";
|
|
2
|
+
export type AuthPayload = Record<string, any>;
|
|
3
|
+
export interface AuthResponse<User> {
|
|
4
|
+
message: string;
|
|
5
|
+
data: User;
|
|
6
|
+
}
|
|
7
|
+
export interface LogoutResponse {
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
export interface AuthDriver<User = any> {
|
|
11
|
+
/**
|
|
12
|
+
* Deve validar o payload recebido e retornar o usuário autenticado.
|
|
13
|
+
*/
|
|
14
|
+
login(payload: AuthPayload, request: Request, response: Response): Promise<User> | User;
|
|
15
|
+
/**
|
|
16
|
+
* Deve recuperar o usuário a partir do contexto (cookies, headers, sessão, etc.).
|
|
17
|
+
* Retorne `null` ou `undefined` quando não houver sessão ativa.
|
|
18
|
+
*/
|
|
19
|
+
checkIn(request: Request, response: Response): Promise<User | null | undefined> | User | null | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Deve encerrar a sessão/tokens do usuário.
|
|
22
|
+
*/
|
|
23
|
+
logout(request: Request, response: Response): Promise<void> | void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Ref } from "vue";
|
|
2
|
+
import type { Fetch, FetchOptions, FetchResponse } from "@ministerjs/resource";
|
|
3
|
+
interface Options<User extends Record<string, any>> {
|
|
4
|
+
fetch: Fetch;
|
|
5
|
+
mapUser?: (user: User) => User;
|
|
6
|
+
routes?: {
|
|
7
|
+
signUp?: string;
|
|
8
|
+
login?: string;
|
|
9
|
+
checkIn?: string;
|
|
10
|
+
logout?: string;
|
|
11
|
+
};
|
|
12
|
+
afterLogout: () => void | Promise<void>;
|
|
13
|
+
afterCheckIn: (result: boolean) => void | Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
declare class Auth<User extends Record<string, any>> {
|
|
16
|
+
user: Ref<Partial<User> | null>;
|
|
17
|
+
on: Ref<boolean, boolean>;
|
|
18
|
+
loading: Ref<boolean, boolean>;
|
|
19
|
+
checkedIn: Ref<boolean, boolean>;
|
|
20
|
+
private fetch;
|
|
21
|
+
private mapUser;
|
|
22
|
+
private afterLogout;
|
|
23
|
+
private afterCheckIn;
|
|
24
|
+
private routes;
|
|
25
|
+
constructor({ fetch, mapUser, routes, afterLogout, afterCheckIn, }: Options<User>);
|
|
26
|
+
login(payload: Record<string, any>): Promise<void>;
|
|
27
|
+
checkIn(): Promise<void>;
|
|
28
|
+
logout(): Promise<void>;
|
|
29
|
+
private setUser;
|
|
30
|
+
}
|
|
31
|
+
export type { Fetch, FetchOptions, FetchResponse };
|
|
32
|
+
export { Auth };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./VueAuth";
|
|
File without changes
|
|
File without changes
|