rl-core-api 0.11.3 → 0.12.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.
@@ -30,6 +30,7 @@ export declare const envSchema: z.ZodObject<{
30
30
  JWT_ACCESS_EXPIRES: z.ZodDefault<z.ZodString>;
31
31
  JWT_PENDING_EXPIRES: z.ZodDefault<z.ZodString>;
32
32
  JWT_REFRESH_EXPIRES_MINUTES: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
33
+ JWT_REFRESH_MOBILE_EXPIRES_MINUTES: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
33
34
  TOTP_ENC_KEY: z.ZodString;
34
35
  COOKIE_SECURE: z.ZodDefault<z.ZodPipe<z.ZodEnum<{
35
36
  true: "true";
@@ -37,6 +37,11 @@ exports.envSchema = zod_1.z
37
37
  .int()
38
38
  .positive()
39
39
  .default(360),
40
+ JWT_REFRESH_MOBILE_EXPIRES_MINUTES: zod_1.z.coerce
41
+ .number()
42
+ .int()
43
+ .positive()
44
+ .default(43_200),
40
45
  TOTP_ENC_KEY: zod_1.z
41
46
  .string()
42
47
  .length(64, "TOTP_ENC_KEY deve ter 64 chars hex (32 bytes)"),
@@ -4,6 +4,7 @@ import { EnvService } from "../../../core/config/env.service";
4
4
  import { MailerService } from "../../../core/mailer/mailer.service";
5
5
  import { PasswordTokenPurpose, PasswordTokenStatus, TokenService } from "./token.service";
6
6
  import { TotpSetup, TwoFactorService } from "./twoFactor.service";
7
+ import { ClientType } from "../presentation/commands/clientType.enum";
7
8
  import { LoginCommand } from "../presentation/commands/login.command";
8
9
  import { VerifyTwoFactorCommand } from "../presentation/commands/twoFactor.command";
9
10
  import { RbacService } from "../../rbac/domain/rbac.service";
@@ -54,7 +55,7 @@ export declare class AuthService {
54
55
  }>;
55
56
  verifyTwoFactor(dto: VerifyTwoFactorCommand, ctx: RequestCtx): Promise<VerifiedSession>;
56
57
  regenerateBackupCodes(userId: string, code: string): Promise<string[]>;
57
- refresh(rawToken: string | undefined, ctx: RequestCtx): Promise<RefreshedTokens>;
58
+ refresh(rawToken: string | undefined, ctx: RequestCtx, client?: ClientType): Promise<RefreshedTokens>;
58
59
  logout(rawRefreshToken?: string): Promise<void>;
59
60
  forgotPassword(email: string): Promise<void>;
60
61
  inspectPasswordToken(token: string): Promise<PasswordTokenCheck>;
@@ -20,6 +20,7 @@ const codedError_util_1 = require("../../../core/utils/codedError.util");
20
20
  const hash_util_1 = require("../../../core/utils/hash.util");
21
21
  const token_service_1 = require("./token.service");
22
22
  const twoFactor_service_1 = require("./twoFactor.service");
23
+ const clientType_enum_1 = require("../presentation/commands/clientType.enum");
23
24
  const rbac_service_1 = require("../../rbac/domain/rbac.service");
24
25
  const users_service_1 = require("../../users/domain/users.service");
25
26
  const BACKUP_FORMAT = /^[A-Za-z0-9]{4}-[A-Za-z0-9]{4}$/;
@@ -150,7 +151,7 @@ let AuthService = class AuthService {
150
151
  user.backupCodes = remainingBackup;
151
152
  }
152
153
  await this.users.save(user);
153
- const tokens = await this.finalizeLogin(user, ctx);
154
+ const tokens = await this.finalizeLogin(user, ctx, dto.client ?? clientType_enum_1.ClientType.WEB);
154
155
  return { ...tokens, backupCodes };
155
156
  }
156
157
  async regenerateBackupCodes(userId, code) {
@@ -170,11 +171,11 @@ let AuthService = class AuthService {
170
171
  await this.users.save(user);
171
172
  return generated.plain;
172
173
  }
173
- async refresh(rawToken, ctx) {
174
+ async refresh(rawToken, ctx, client = clientType_enum_1.ClientType.WEB) {
174
175
  if (!rawToken) {
175
176
  throw new common_1.UnauthorizedException("Refresh token ausente");
176
177
  }
177
- const { userId, rawToken: newRefresh } = await this.tokens.rotateRefreshToken(rawToken, ctx);
178
+ const { userId, rawToken: newRefresh } = await this.tokens.rotateRefreshToken(rawToken, ctx, client);
178
179
  const user = await this.users.findById(userId);
179
180
  if (!user.isActive) {
180
181
  throw accountInactive();
@@ -284,9 +285,9 @@ let AuthService = class AuthService {
284
285
  mustChangePassword: user.mustChangePassword,
285
286
  };
286
287
  }
287
- async finalizeLogin(user, ctx) {
288
+ async finalizeLogin(user, ctx, client) {
288
289
  const accessToken = await this.signAccessToken(user);
289
- const { rawToken } = await this.tokens.issueRefreshToken(user.id, undefined, ctx);
290
+ const { rawToken } = await this.tokens.issueRefreshToken(user.id, undefined, ctx, client);
290
291
  return {
291
292
  accessToken,
292
293
  refreshToken: rawToken,
@@ -1,6 +1,7 @@
1
1
  import { EnvService } from "../../../core/config/env.service";
2
2
  import { AuthTokenRepository } from "../infra/repositories/authToken.repository";
3
3
  import { TokenType } from "../infra/schema/authToken.schema";
4
+ import { ClientType } from "../presentation/commands/clientType.enum";
4
5
  export interface RotationResult {
5
6
  userId: string;
6
7
  rawToken: string;
@@ -29,17 +30,18 @@ export declare class TokenService {
29
30
  constructor(repo: AuthTokenRepository, env: EnvService);
30
31
  private persist;
31
32
  private minutesFromNow;
33
+ private refreshMinutes;
32
34
  issueRefreshToken(userId: string, family?: string, ctx?: {
33
35
  ipAddress?: string;
34
36
  userAgent?: string;
35
- }): Promise<{
37
+ }, client?: ClientType): Promise<{
36
38
  rawToken: string;
37
39
  family: string;
38
40
  }>;
39
41
  rotateRefreshToken(rawToken: string, ctx?: {
40
42
  ipAddress?: string;
41
43
  userAgent?: string;
42
- }): Promise<RotationResult>;
44
+ }, client?: ClientType): Promise<RotationResult>;
43
45
  revokeFamily(family: string): Promise<void>;
44
46
  revokeAllRefresh(userId: string): Promise<void>;
45
47
  revokeByRawToken(rawToken: string): Promise<void>;
@@ -18,6 +18,7 @@ const env_service_1 = require("../../../core/config/env.service");
18
18
  const hash_util_1 = require("../../../core/utils/hash.util");
19
19
  const authToken_repository_1 = require("../infra/repositories/authToken.repository");
20
20
  const authToken_schema_1 = require("../infra/schema/authToken.schema");
21
+ const clientType_enum_1 = require("../presentation/commands/clientType.enum");
21
22
  var PasswordTokenStatus;
22
23
  (function (PasswordTokenStatus) {
23
24
  PasswordTokenStatus["VALID"] = "valid";
@@ -49,7 +50,12 @@ let TokenService = TokenService_1 = class TokenService {
49
50
  minutesFromNow(minutes) {
50
51
  return new Date(Date.now() + minutes * 60_000);
51
52
  }
52
- async issueRefreshToken(userId, family, ctx) {
53
+ refreshMinutes(client) {
54
+ return client === clientType_enum_1.ClientType.MOBILE
55
+ ? this.env.get("JWT_REFRESH_MOBILE_EXPIRES_MINUTES")
56
+ : this.env.get("JWT_REFRESH_EXPIRES_MINUTES");
57
+ }
58
+ async issueRefreshToken(userId, family, ctx, client = clientType_enum_1.ClientType.WEB) {
53
59
  const rawToken = (0, hash_util_1.randomToken)(48);
54
60
  const fam = family ?? (0, uuid_1.v7)();
55
61
  await this.persist({
@@ -57,13 +63,13 @@ let TokenService = TokenService_1 = class TokenService {
57
63
  rawToken,
58
64
  type: authToken_schema_1.TokenType.REFRESH_TOKEN,
59
65
  family: fam,
60
- expiresAt: this.minutesFromNow(this.env.get("JWT_REFRESH_EXPIRES_MINUTES")),
66
+ expiresAt: this.minutesFromNow(this.refreshMinutes(client)),
61
67
  ipAddress: ctx?.ipAddress,
62
68
  userAgent: ctx?.userAgent,
63
69
  });
64
70
  return { rawToken, family: fam };
65
71
  }
66
- async rotateRefreshToken(rawToken, ctx) {
72
+ async rotateRefreshToken(rawToken, ctx, client = clientType_enum_1.ClientType.WEB) {
67
73
  const tokenHash = (0, hash_util_1.sha256)(rawToken);
68
74
  const stored = await this.repo.findOne({
69
75
  where: { tokenHash, type: authToken_schema_1.TokenType.REFRESH_TOKEN },
@@ -83,7 +89,7 @@ let TokenService = TokenService_1 = class TokenService {
83
89
  }
84
90
  stored.used = true;
85
91
  await this.repo.save(stored);
86
- const { rawToken: newRaw, family } = await this.issueRefreshToken(stored.userId, stored.family ?? undefined, ctx);
92
+ const { rawToken: newRaw, family } = await this.issueRefreshToken(stored.userId, stored.family ?? undefined, ctx, client);
87
93
  return { userId: stored.userId, rawToken: newRaw, family };
88
94
  }
89
95
  async revokeFamily(family) {
@@ -63,7 +63,8 @@ let AuthController = class AuthController {
63
63
  async refresh(dto, req, res) {
64
64
  const cookies = req.cookies;
65
65
  const raw = dto.refreshToken ?? cookies?.[cookie_util_1.REFRESH_COOKIE];
66
- const tokens = await this.auth.refresh(raw, ctxFrom(req));
66
+ const client = dto.refreshToken ? clientType_enum_1.ClientType.MOBILE : clientType_enum_1.ClientType.WEB;
67
+ const tokens = await this.auth.refresh(raw, ctxFrom(req), client);
67
68
  if (dto.refreshToken) {
68
69
  return { ok: true, ...tokens };
69
70
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rl-core-api",
3
- "version": "0.11.3",
3
+ "version": "0.12.0",
4
4
  "description": "Core NestJS: autenticação com 2FA, RBAC, auditoria, notificações e listagens com filtro dinâmico",
5
5
  "author": "Rodrigo Liberti",
6
6
  "license": "MIT",