@ministerjs/auth 1.0.2 → 2.0.0

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 CHANGED
@@ -1,6 +1,12 @@
1
1
  # @ministerjs/auth
2
2
 
3
- Classe para gerenciar autenticação de usuários em aplicações Vue.
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
- ## Importação
12
-
13
- ```ts
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 };
@@ -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
+ });
@@ -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
+ };
@@ -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/Auth.ts
21
- var Auth_exports = {};
22
- __export(Auth_exports, {
20
+ // src/vue/index.ts
21
+ var vue_exports = {};
22
+ __export(vue_exports, {
23
23
  Auth: () => Auth
24
24
  });
25
- module.exports = __toCommonJS(Auth_exports);
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);
@@ -1,4 +1,4 @@
1
- // src/Auth.ts
1
+ // src/vue/VueAuth.ts
2
2
  import { ref } from "vue";
3
3
  var Auth = class {
4
4
  user = ref(null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ministerjs/auth",
3
- "version": "1.0.2",
3
+ "version": "2.0.0",
4
4
  "license": "UNLICENSED",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -10,28 +10,51 @@
10
10
  "dist/*"
11
11
  ],
12
12
  "exports": {
13
- "./Auth": {
14
- "types": "./dist/Auth.d.ts",
15
- "import": "./dist/Auth.mjs",
16
- "require": "./dist/Auth.js"
13
+ "./vue": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.mjs",
16
+ "require": "./dist/index.js"
17
+ },
18
+ "./nestjs": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.mjs",
21
+ "require": "./dist/index.js"
17
22
  }
18
23
  },
19
24
  "peerDependencies": {
20
- "vue": "^3.5.12"
25
+ "vue": "^3.5.12",
26
+ "@nestjs/common": "^11.0.11",
27
+ "@prisma/client": "^6.5.0",
28
+ "jsonwebtoken": "^9.0.2"
29
+ },
30
+ "peerDependenciesMeta": {
31
+ "@nestjs/common": {
32
+ "optional": true
33
+ },
34
+ "@prisma/client": {
35
+ "optional": true
36
+ },
37
+ "jsonwebtoken": {
38
+ "optional": true
39
+ }
21
40
  },
22
41
  "devDependencies": {
23
42
  "@ministerjs/build": "^2.1.2",
24
43
  "@ministerjs/resource": "1.2.0",
25
44
  "@types/node": "^22.13.10",
45
+ "@types/express": "^4.17.21",
26
46
  "cross-env": "^7.0.3",
27
47
  "eslint": "^9.22.0",
28
48
  "globals": "^15.15.0",
29
49
  "prettier": "3.5.3",
30
50
  "tsup": "^8.4.0",
31
51
  "tsx": "^4.19.3",
32
- "typescript": "latest",
52
+ "typescript": "~5.8.3",
33
53
  "vitest": "^3.0.9",
34
- "vue": "^3.5.13"
54
+ "vue": "^3.5.13",
55
+ "@nestjs/common": "^11.0.11",
56
+ "@types/jsonwebtoken": "^9.0.6",
57
+ "jsonwebtoken": "^9.0.2"
35
58
  },
36
59
  "scripts": {
37
60
  "dev": "tsup --watch",
File without changes
File without changes