@jmlq/auth 0.0.1-alpha.8 → 0.0.1-beta.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.
Files changed (162) hide show
  1. package/README.es.md +133 -0
  2. package/README.md +81 -207
  3. package/dist/application/dtos/index.d.ts +1 -1
  4. package/dist/application/dtos/index.js +1 -1
  5. package/dist/application/dtos/request/change-password.request.d.ts +15 -0
  6. package/dist/application/dtos/request/index.d.ts +5 -0
  7. package/dist/application/dtos/request/index.js +5 -0
  8. package/dist/application/dtos/request/logout.request.d.ts +2 -1
  9. package/dist/application/dtos/request/me.request.d.ts +3 -0
  10. package/dist/application/dtos/request/me.request.js +2 -0
  11. package/dist/application/dtos/request/register-user.request.d.ts +2 -1
  12. package/dist/application/dtos/request/request-password-reset.request.d.ts +6 -0
  13. package/dist/application/dtos/request/request-password-reset.request.js +2 -0
  14. package/dist/application/dtos/request/reset-password.request.d.ts +14 -0
  15. package/dist/application/dtos/request/reset-password.request.js +2 -0
  16. package/dist/application/dtos/request/verify-email.request.d.ts +3 -0
  17. package/dist/application/dtos/request/verify-email.request.js +2 -0
  18. package/dist/application/dtos/response/change-password.response.d.ts +7 -0
  19. package/dist/application/dtos/response/change-password.response.js +2 -0
  20. package/dist/application/dtos/response/index.d.ts +5 -0
  21. package/dist/application/dtos/response/index.js +5 -0
  22. package/dist/application/dtos/response/login.response.d.ts +2 -1
  23. package/dist/application/dtos/response/me.response.d.ts +11 -0
  24. package/dist/application/dtos/response/me.response.js +2 -0
  25. package/dist/application/dtos/response/refresh-token.response.d.ts +1 -0
  26. package/dist/application/dtos/response/register-user.response.d.ts +9 -0
  27. package/dist/application/dtos/response/request-password-reset.response.d.ts +15 -0
  28. package/dist/application/dtos/response/request-password-reset.response.js +2 -0
  29. package/dist/application/dtos/response/reset-password.response.d.ts +7 -0
  30. package/dist/application/dtos/response/reset-password.response.js +2 -0
  31. package/dist/application/dtos/response/verify-email.response.d.ts +4 -0
  32. package/dist/application/dtos/response/verify-email.response.js +2 -0
  33. package/dist/application/dtos/types/user-role.type.js +2 -0
  34. package/dist/application/facades/auth.facade.d.ts +33 -0
  35. package/dist/application/facades/auth.facade.js +60 -0
  36. package/dist/application/facades/create-auth-facade.d.ts +22 -0
  37. package/dist/application/facades/create-auth-facade.js +9 -0
  38. package/dist/application/facades/index.d.ts +2 -0
  39. package/dist/application/facades/index.js +18 -0
  40. package/dist/application/factories/auth-service.factory.d.ts +4 -4
  41. package/dist/application/factories/auth-service.factory.js +16 -4
  42. package/dist/application/factories/index.js +1 -0
  43. package/dist/application/types/auth-service-factory-options.type.d.ts +44 -0
  44. package/dist/application/use-cases/change-password.use-case.d.ts +21 -0
  45. package/dist/application/use-cases/change-password.use-case.js +49 -0
  46. package/dist/application/use-cases/index.d.ts +5 -0
  47. package/dist/application/use-cases/index.js +5 -0
  48. package/dist/application/use-cases/internal/index.d.ts +1 -0
  49. package/dist/application/use-cases/internal/index.js +17 -0
  50. package/dist/application/use-cases/internal/password-assertions.d.ts +13 -0
  51. package/dist/application/use-cases/internal/password-assertions.js +26 -0
  52. package/dist/application/use-cases/login-with-password.use-case.js +24 -28
  53. package/dist/application/use-cases/logout.use-case.js +14 -2
  54. package/dist/application/use-cases/me.use-case.d.ts +7 -0
  55. package/dist/application/use-cases/me.use-case.js +28 -0
  56. package/dist/application/use-cases/refresh-token.use-case.d.ts +16 -2
  57. package/dist/application/use-cases/refresh-token.use-case.js +33 -5
  58. package/dist/application/use-cases/register-user.use-case.d.ts +6 -1
  59. package/dist/application/use-cases/register-user.use-case.js +18 -7
  60. package/dist/application/use-cases/request-password-reset.use-case.d.ts +19 -0
  61. package/dist/application/use-cases/request-password-reset.use-case.js +43 -0
  62. package/dist/application/use-cases/reset-password.use-case.d.ts +20 -0
  63. package/dist/application/use-cases/reset-password.use-case.js +59 -0
  64. package/dist/application/use-cases/verify-email.use-case.d.ts +8 -0
  65. package/dist/application/use-cases/verify-email.use-case.js +30 -0
  66. package/dist/domain/entities/credential.entity.d.ts +36 -11
  67. package/dist/domain/entities/credential.entity.js +41 -11
  68. package/dist/domain/entities/user.entity.d.ts +32 -1
  69. package/dist/domain/entities/user.entity.js +54 -1
  70. package/dist/domain/errors/auth-error-code.d.ts +16 -0
  71. package/dist/domain/errors/auth-error-code.js +60 -0
  72. package/dist/domain/errors/auth.errors.d.ts +29 -8
  73. package/dist/domain/errors/auth.errors.js +59 -8
  74. package/dist/domain/errors/general.errors.d.ts +4 -0
  75. package/dist/domain/errors/general.errors.js +10 -0
  76. package/dist/domain/errors/identity.errors.d.ts +17 -12
  77. package/dist/domain/errors/identity.errors.js +29 -25
  78. package/dist/domain/errors/index.d.ts +5 -0
  79. package/dist/domain/errors/index.js +5 -0
  80. package/dist/domain/errors/jwt-payload.error.d.ts +4 -0
  81. package/dist/domain/errors/jwt-payload.error.js +10 -0
  82. package/dist/domain/errors/jwt.errors.d.ts +7 -0
  83. package/dist/domain/errors/jwt.errors.js +16 -0
  84. package/dist/domain/errors/password-reset.errors.d.ts +14 -0
  85. package/dist/domain/errors/password-reset.errors.js +29 -0
  86. package/dist/domain/index.d.ts +1 -0
  87. package/dist/domain/index.js +1 -0
  88. package/dist/domain/ports/auth/email-verification-token.port.d.ts +19 -0
  89. package/dist/domain/ports/auth/email-verification-token.port.js +2 -0
  90. package/dist/domain/ports/auth/index.d.ts +2 -0
  91. package/dist/domain/ports/auth/index.js +2 -0
  92. package/dist/domain/ports/auth/password-reset-token.port.d.ts +36 -0
  93. package/dist/domain/ports/auth/password-reset-token.port.js +2 -0
  94. package/dist/domain/ports/jwt/payload/jwt-payload.port.d.ts +25 -3
  95. package/dist/domain/ports/repository/credential.repository.d.ts +55 -2
  96. package/dist/domain/ports/token/token-session.port.d.ts +2 -0
  97. package/dist/domain/props/entities/credential.props.d.ts +9 -1
  98. package/dist/domain/props/entities/user.props.d.ts +1 -0
  99. package/dist/domain/props/jwt/generate-access-token.props.d.ts +3 -2
  100. package/dist/domain/props/jwt/generate-refresh-token.props.d.ts +3 -2
  101. package/dist/domain/props/jwt/jwt-user.d.ts +11 -2
  102. package/dist/domain/services/helpers/assert-jwt-structure.helper.d.ts +1 -0
  103. package/dist/domain/services/helpers/assert-jwt-structure.helper.js +13 -0
  104. package/dist/domain/services/helpers/index.d.ts +7 -0
  105. package/dist/domain/services/helpers/index.js +23 -0
  106. package/dist/domain/services/helpers/optional-audience.helper.d.ts +14 -0
  107. package/dist/domain/services/helpers/optional-audience.helper.js +49 -0
  108. package/dist/domain/services/helpers/optional-non-empty-string.helper.d.ts +1 -0
  109. package/dist/domain/services/helpers/optional-non-empty-string.helper.js +9 -0
  110. package/dist/domain/services/helpers/optional-record.helper.d.ts +1 -0
  111. package/dist/domain/services/helpers/optional-record.helper.js +15 -0
  112. package/dist/domain/services/helpers/optional-roles.helper.d.ts +3 -0
  113. package/dist/domain/services/helpers/optional-roles.helper.js +32 -0
  114. package/dist/domain/services/helpers/require-finite-number.helper.d.ts +1 -0
  115. package/dist/domain/services/helpers/require-finite-number.helper.js +12 -0
  116. package/dist/domain/services/helpers/require-non-empty-string.helper.d.ts +1 -0
  117. package/dist/domain/services/helpers/require-non-empty-string.helper.js +12 -0
  118. package/dist/domain/services/index.d.ts +1 -0
  119. package/dist/domain/services/index.js +1 -0
  120. package/dist/domain/services/normalize-jwt-payload.service.d.ts +19 -0
  121. package/dist/domain/services/normalize-jwt-payload.service.js +58 -0
  122. package/dist/domain/types/access-snapshot.type.d.ts +15 -0
  123. package/dist/domain/types/access-snapshot.type.js +2 -0
  124. package/dist/domain/types/index.d.ts +1 -0
  125. package/dist/domain/types/index.js +2 -0
  126. package/dist/in-memory/in-memory-credential.repository.d.ts +66 -3
  127. package/dist/in-memory/in-memory-credential.repository.js +174 -46
  128. package/dist/index.d.ts +18 -2
  129. package/dist/index.js +24 -9
  130. package/dist/infrastructure/index.d.ts +3 -0
  131. package/dist/infrastructure/index.js +18 -0
  132. package/dist/infrastructure/security/bcrypt-password-hasher.js +0 -1
  133. package/dist/infrastructure/services/token-session.service.d.ts +163 -8
  134. package/dist/infrastructure/services/token-session.service.js +290 -37
  135. package/dist/infrastructure/types/auth-service-container.d.ts +21 -2
  136. package/dist/shared/index.d.ts +1 -0
  137. package/dist/shared/index.js +1 -0
  138. package/dist/shared/jwt-plugin/create-jwt-id.d.ts +6 -0
  139. package/dist/shared/jwt-plugin/create-jwt-id.js +30 -0
  140. package/dist/shared/jwt-plugin/index.d.ts +9 -0
  141. package/dist/shared/jwt-plugin/index.js +25 -0
  142. package/dist/shared/jwt-plugin/is-retryable-auth-code.d.ts +8 -0
  143. package/dist/shared/jwt-plugin/is-retryable-auth-code.js +15 -0
  144. package/dist/shared/jwt-plugin/normalize-clock-skew-seconds.d.ts +14 -0
  145. package/dist/shared/jwt-plugin/normalize-clock-skew-seconds.js +23 -0
  146. package/dist/shared/jwt-plugin/normalize-default-expires-in.d.ts +16 -0
  147. package/dist/shared/jwt-plugin/normalize-default-expires-in.js +36 -0
  148. package/dist/shared/jwt-plugin/read-custom-claims.d.ts +12 -0
  149. package/dist/shared/jwt-plugin/read-custom-claims.js +21 -0
  150. package/dist/shared/jwt-plugin/read-expires-in.d.ts +12 -0
  151. package/dist/shared/jwt-plugin/read-expires-in.js +20 -0
  152. package/dist/shared/jwt-plugin/read-session-id.d.ts +11 -0
  153. package/dist/shared/jwt-plugin/read-session-id.js +17 -0
  154. package/dist/shared/jwt-plugin/resolve-expires-in.d.ts +14 -0
  155. package/dist/shared/jwt-plugin/resolve-expires-in.js +31 -0
  156. package/dist/shared/jwt-plugin/to-date-from-unix-seconds.d.ts +7 -0
  157. package/dist/shared/jwt-plugin/to-date-from-unix-seconds.js +12 -0
  158. package/package.json +12 -11
  159. /package/dist/application/dtos/{type/user-role.type.js → request/change-password.request.js} +0 -0
  160. /package/dist/application/dtos/{type → types}/index.d.ts +0 -0
  161. /package/dist/application/dtos/{type → types}/index.js +0 -0
  162. /package/dist/application/dtos/{type → types}/user-role.type.d.ts +0 -0
@@ -16,6 +16,7 @@ class User {
16
16
  this._roles = props.roles;
17
17
  this._password = props.password;
18
18
  this._isActive = props.isActive;
19
+ this._isEmailVerified = props.isEmailVerified;
19
20
  this._createdAt = props.createdAt;
20
21
  this._updatedAt = props.updatedAt;
21
22
  }
@@ -50,6 +51,12 @@ class User {
50
51
  get isActive() {
51
52
  return this._isActive;
52
53
  }
54
+ /**
55
+ * Indica si el correo fue verificado.
56
+ */
57
+ get isEmailVerified() {
58
+ return this._isEmailVerified;
59
+ }
53
60
  /**
54
61
  * Obtiene la fecha de creación del usuario
55
62
  */
@@ -79,10 +86,28 @@ class User {
79
86
  }
80
87
  /**
81
88
  * Evalúa si el usuario puede iniciar sesión
89
+ * Política de login:
90
+ * - activo
91
+ * - email verificado
82
92
  * @returns Verdadero si el usuario puede iniciar sesión, falso en caso contrario
83
93
  */
84
94
  canLogin() {
85
- return this._isActive;
95
+ return this._isActive && this._isEmailVerified;
96
+ }
97
+ verifyEmail() {
98
+ if (this._isEmailVerified)
99
+ return;
100
+ this._isEmailVerified = true;
101
+ this._updatedAt = new Date();
102
+ }
103
+ /**
104
+ * Cambia la contraseña del usuario.
105
+ * Responsabilidad: el agregado actualiza su estado de forma consistente.
106
+ * Reglas de policy/validaciones pertenecen al caso de uso (application).
107
+ */
108
+ changePassword(newHashedPassword) {
109
+ this._password = newHashedPassword;
110
+ this._updatedAt = new Date();
86
111
  }
87
112
  /**
88
113
  * Factory method to create a new User
@@ -98,6 +123,7 @@ class User {
98
123
  roles: roles,
99
124
  password: new object_values_1.HashedPassword(hashedPassword),
100
125
  isActive: true,
126
+ isEmailVerified: false,
101
127
  createdAt: new Date(),
102
128
  updatedAt: new Date(),
103
129
  });
@@ -112,5 +138,32 @@ class User {
112
138
  static reconstitute(props) {
113
139
  return new User(props);
114
140
  }
141
+ /**
142
+ * Deriva roles y permissions efectivas desde la entidad.
143
+ *
144
+ * Fuente de datos:
145
+ * - this.roles (Role[])
146
+ * - role.getValue() => { role: string; permissions: string[] }
147
+ *
148
+ * Nota:
149
+ * - Esto NO consulta BDD.
150
+ * - La BDD se consulta en el host (middleware) para autorización “fresca”.
151
+ */
152
+ getAccessSnapshot() {
153
+ const roles = [];
154
+ const permissions = [];
155
+ for (const role of this.roles) {
156
+ const value = role.getValue(); // canónico (incluye permissions)
157
+ roles.push(value.role);
158
+ permissions.push(...value.permissions);
159
+ }
160
+ // Unique + orden determinista (útil para test/debug)
161
+ const uniqSorted = (items) => Array.from(new Set(items)).sort((a, b) => a.localeCompare(b));
162
+ return {
163
+ userId: this.id.getValue(),
164
+ roles: uniqSorted(roles),
165
+ permissions: uniqSorted(permissions),
166
+ };
167
+ }
115
168
  }
116
169
  exports.User = User;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Códigos canónicos de error del dominio de Auth.
3
+ *
4
+ * Objetivo:
5
+ * - Host / plugins NO deben depender de `error.name` o `message`.
6
+ * - Solo deben mapear por `code`.
7
+ *
8
+ * Nota:
9
+ * - Mantén este catálogo pequeño y estable.
10
+ * - Si agregas un error nuevo, agrega aquí su código.
11
+ */
12
+ /**
13
+ * ÚNICA fuente de verdad de los códigos.
14
+ */
15
+ export declare const AUTH_ERROR_CODES: readonly ["TOKEN_INVALID", "TOKEN_EXPIRED", "TOKEN_MALFORMED", "SIGNATURE_INVALID", "AUTHENTICATION_FAILED", "JWT_ERROR", "KEY_MISMATCH", "KEY_NOT_FOUND", "KEY_MISMATCH", "CLAIMS_VALIDATION_ERROR", "JWT_PAYLOAD_INVALID", "TOKEN_NOT_YET_VALID", "JWT_EMPTY", "JWT_MALFORMED", "ALGORITHM_UNSUPPORTED", "KEY_MISMATCH", "KEY_NOT_FOUND", "INVALID_EMAIL", "INVALID_HASHED_PASSWORD", "PASSWORD_POLICY_VIOLATION", "PASSWORD_MISMATCH", "USER_NOT_FOUND", "USER_DISABLED", "EMAIL_ALREADY_IN_USE", "INVALID_PERMISSION", "INVALID_ROLE", "INVALID_ID", "LOGOUT_FAILED", "EMAIL_NOT_VERIFIED", "PASSWORD_RESET_TOKEN_INVALID", "PASSWORD_RESET_TOKEN_EXPIRED", "PASSWORD_RESET_TOKEN_ALREADY_USED", "EMAIL_VERIFICATION_TOKEN_INVALID", "EMAIL_VERIFICATION_TOKEN_EXPIRED", "EMAIL_VERIFICATION_TOKEN_ALREADY_USED", "INVALID_INPUT"];
16
+ export type AuthErrorCode = (typeof AUTH_ERROR_CODES)[number];
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AUTH_ERROR_CODES = void 0;
4
+ /**
5
+ * Códigos canónicos de error del dominio de Auth.
6
+ *
7
+ * Objetivo:
8
+ * - Host / plugins NO deben depender de `error.name` o `message`.
9
+ * - Solo deben mapear por `code`.
10
+ *
11
+ * Nota:
12
+ * - Mantén este catálogo pequeño y estable.
13
+ * - Si agregas un error nuevo, agrega aquí su código.
14
+ */
15
+ /**
16
+ * ÚNICA fuente de verdad de los códigos.
17
+ */
18
+ exports.AUTH_ERROR_CODES = [
19
+ // JWT / sesión
20
+ "TOKEN_INVALID",
21
+ "TOKEN_EXPIRED",
22
+ "TOKEN_MALFORMED", // formato invalido (no header.payload.signature),
23
+ "SIGNATURE_INVALID",
24
+ "AUTHENTICATION_FAILED", // catch-all de autenticación,
25
+ "JWT_ERROR",
26
+ "KEY_MISMATCH",
27
+ "KEY_NOT_FOUND",
28
+ "KEY_MISMATCH",
29
+ "CLAIMS_VALIDATION_ERROR",
30
+ "JWT_PAYLOAD_INVALID",
31
+ "TOKEN_NOT_YET_VALID",
32
+ "JWT_EMPTY",
33
+ "JWT_MALFORMED",
34
+ // Refresh Token
35
+ "ALGORITHM_UNSUPPORTED",
36
+ "KEY_MISMATCH",
37
+ "KEY_NOT_FOUND",
38
+ // Identidad / login
39
+ "INVALID_EMAIL",
40
+ "INVALID_HASHED_PASSWORD",
41
+ "PASSWORD_POLICY_VIOLATION",
42
+ "PASSWORD_MISMATCH",
43
+ "USER_NOT_FOUND",
44
+ "USER_DISABLED",
45
+ "EMAIL_ALREADY_IN_USE",
46
+ "INVALID_PERMISSION",
47
+ "INVALID_ROLE",
48
+ "INVALID_ID",
49
+ "LOGOUT_FAILED",
50
+ "EMAIL_NOT_VERIFIED",
51
+ // Password reset
52
+ "PASSWORD_RESET_TOKEN_INVALID",
53
+ "PASSWORD_RESET_TOKEN_EXPIRED",
54
+ "PASSWORD_RESET_TOKEN_ALREADY_USED",
55
+ "EMAIL_VERIFICATION_TOKEN_INVALID",
56
+ "EMAIL_VERIFICATION_TOKEN_EXPIRED",
57
+ "EMAIL_VERIFICATION_TOKEN_ALREADY_USED",
58
+ //General
59
+ "INVALID_INPUT",
60
+ ];
@@ -1,8 +1,9 @@
1
- export type AuthErrorCode = "TOKEN_EXPIRED" | "TOKEN_MALFORMED" | "SIGNATURE_INVALID" | "AUTHENTICATION_FAILED";
1
+ import { AuthErrorCode } from "./auth-error-code";
2
2
  export interface ClaimsIssue {
3
3
  path: string;
4
4
  message: string;
5
5
  }
6
+ export declare function isAuthErrorCode(value: unknown): value is AuthErrorCode;
6
7
  export declare abstract class AuthDomainError extends Error {
7
8
  readonly code: AuthErrorCode;
8
9
  readonly details?: unknown;
@@ -10,9 +11,21 @@ export declare abstract class AuthDomainError extends Error {
10
11
  toJSON(): {
11
12
  name: string;
12
13
  message: string;
13
- code: AuthErrorCode;
14
+ code: "TOKEN_INVALID" | "TOKEN_EXPIRED" | "TOKEN_MALFORMED" | "SIGNATURE_INVALID" | "AUTHENTICATION_FAILED" | "JWT_ERROR" | "KEY_MISMATCH" | "KEY_NOT_FOUND" | "CLAIMS_VALIDATION_ERROR" | "JWT_PAYLOAD_INVALID" | "TOKEN_NOT_YET_VALID" | "JWT_EMPTY" | "JWT_MALFORMED" | "ALGORITHM_UNSUPPORTED" | "INVALID_EMAIL" | "INVALID_HASHED_PASSWORD" | "PASSWORD_POLICY_VIOLATION" | "PASSWORD_MISMATCH" | "USER_NOT_FOUND" | "USER_DISABLED" | "EMAIL_ALREADY_IN_USE" | "INVALID_PERMISSION" | "INVALID_ROLE" | "INVALID_ID" | "LOGOUT_FAILED" | "EMAIL_NOT_VERIFIED" | "PASSWORD_RESET_TOKEN_INVALID" | "PASSWORD_RESET_TOKEN_EXPIRED" | "PASSWORD_RESET_TOKEN_ALREADY_USED" | "EMAIL_VERIFICATION_TOKEN_INVALID" | "EMAIL_VERIFICATION_TOKEN_EXPIRED" | "EMAIL_VERIFICATION_TOKEN_ALREADY_USED" | "INVALID_INPUT";
14
15
  details: unknown;
15
16
  };
17
+ /**
18
+ * Guard estable para errores del core.
19
+ *
20
+ * - `instanceof` es el camino ideal, pero puede fallar si hay:
21
+ * - múltiples copias del paquete en runtime (resolución/hoisting),
22
+ * - bundles,
23
+ * - errores creados por hosts que replican forma (code/message).
24
+ *
25
+ * Regla:
26
+ * - Si tiene forma mínima { code: string, message: string }, lo tratamos como AuthDomainError.
27
+ * - El core sigue siendo el “owner” de los códigos y su significado.
28
+ */
16
29
  static isAuthError(e: unknown): e is AuthDomainError;
17
30
  }
18
31
  /** El token ya no es válido por exp (exp < now) */
@@ -34,10 +47,18 @@ export declare class InvalidSignatureError extends AuthDomainError {
34
47
  export declare class AuthenticationError extends AuthDomainError {
35
48
  constructor(message?: string, details?: unknown);
36
49
  }
37
- /** Alias histórico si lo usabas antes */
38
- export declare class InvalidOrExpiredRefreshTokenError extends AuthDomainError {
39
- constructor(details?: {
40
- exp?: number;
41
- now?: number;
42
- });
50
+ export declare class SessionAuthError extends AuthDomainError {
51
+ constructor(message?: string, details?: unknown);
52
+ }
53
+ export declare class EmailNotVerifiedError extends AuthDomainError {
54
+ constructor(message?: string, details?: unknown);
55
+ }
56
+ export declare class EmailVerificationTokenAlreadyUsedError extends AuthDomainError {
57
+ constructor(message?: string, details?: unknown);
58
+ }
59
+ export declare class EmailVerificationTokenInvalidError extends AuthDomainError {
60
+ constructor(message?: string, details?: unknown);
61
+ }
62
+ export declare class EmailVerificationTokenExpiredError extends AuthDomainError {
63
+ constructor(message?: string, details?: unknown);
43
64
  }
@@ -1,6 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InvalidOrExpiredRefreshTokenError = exports.AuthenticationError = exports.InvalidSignatureError = exports.InvalidTokenFormatError = exports.TokenExpiredError = exports.AuthDomainError = void 0;
3
+ exports.EmailVerificationTokenExpiredError = exports.EmailVerificationTokenInvalidError = exports.EmailVerificationTokenAlreadyUsedError = exports.EmailNotVerifiedError = exports.SessionAuthError = exports.AuthenticationError = exports.InvalidSignatureError = exports.InvalidTokenFormatError = exports.TokenExpiredError = exports.AuthDomainError = void 0;
4
+ exports.isAuthErrorCode = isAuthErrorCode;
5
+ const auth_error_code_1 = require("./auth-error-code");
6
+ function asAuthErrorLike(value) {
7
+ if (value && typeof value === "object")
8
+ return value;
9
+ return {};
10
+ }
11
+ const AUTH_ERROR_CODE_SET = new Set(auth_error_code_1.AUTH_ERROR_CODES);
12
+ function isAuthErrorCode(value) {
13
+ return typeof value === "string" && AUTH_ERROR_CODE_SET.has(value);
14
+ }
4
15
  class AuthDomainError extends Error {
5
16
  constructor(message, code, details) {
6
17
  super(message);
@@ -8,7 +19,8 @@ class AuthDomainError extends Error {
8
19
  this.details = details;
9
20
  this.name = new.target.name;
10
21
  // Compatible con V8; ignora silenciosamente en otros engines
11
- if (typeof Error.captureStackTrace === "function") {
22
+ if (typeof Error
23
+ .captureStackTrace === "function") {
12
24
  Error.captureStackTrace(this, new.target);
13
25
  }
14
26
  }
@@ -20,8 +32,24 @@ class AuthDomainError extends Error {
20
32
  details: this.details,
21
33
  };
22
34
  }
35
+ /**
36
+ * Guard estable para errores del core.
37
+ *
38
+ * - `instanceof` es el camino ideal, pero puede fallar si hay:
39
+ * - múltiples copias del paquete en runtime (resolución/hoisting),
40
+ * - bundles,
41
+ * - errores creados por hosts que replican forma (code/message).
42
+ *
43
+ * Regla:
44
+ * - Si tiene forma mínima { code: string, message: string }, lo tratamos como AuthDomainError.
45
+ * - El core sigue siendo el “owner” de los códigos y su significado.
46
+ */
23
47
  static isAuthError(e) {
24
- return e instanceof AuthDomainError;
48
+ if (e instanceof AuthDomainError)
49
+ return true;
50
+ const like = asAuthErrorLike(e);
51
+ // Exigir que code sea uno de los canónicos del core
52
+ return isAuthErrorCode(like.code);
25
53
  }
26
54
  }
27
55
  exports.AuthDomainError = AuthDomainError;
@@ -53,10 +81,33 @@ class AuthenticationError extends AuthDomainError {
53
81
  }
54
82
  }
55
83
  exports.AuthenticationError = AuthenticationError;
56
- /** Alias histórico si lo usabas antes */
57
- class InvalidOrExpiredRefreshTokenError extends AuthDomainError {
58
- constructor(details) {
59
- super("Invalid or expired refresh token", "TOKEN_EXPIRED", details);
84
+ class SessionAuthError extends AuthDomainError {
85
+ constructor(message = "Session Authentication failed", details) {
86
+ super(message, "AUTHENTICATION_FAILED", details);
87
+ }
88
+ }
89
+ exports.SessionAuthError = SessionAuthError;
90
+ class EmailNotVerifiedError extends AuthDomainError {
91
+ constructor(message = "Email is not verified", details) {
92
+ super(message, "EMAIL_NOT_VERIFIED", details);
93
+ }
94
+ }
95
+ exports.EmailNotVerifiedError = EmailNotVerifiedError;
96
+ class EmailVerificationTokenAlreadyUsedError extends AuthDomainError {
97
+ constructor(message = "Email verification token already used", details) {
98
+ super(message, "EMAIL_VERIFICATION_TOKEN_ALREADY_USED", details);
99
+ }
100
+ }
101
+ exports.EmailVerificationTokenAlreadyUsedError = EmailVerificationTokenAlreadyUsedError;
102
+ class EmailVerificationTokenInvalidError extends AuthDomainError {
103
+ constructor(message = "Email verification token is invalid", details) {
104
+ super(message, "EMAIL_VERIFICATION_TOKEN_INVALID", details);
105
+ }
106
+ }
107
+ exports.EmailVerificationTokenInvalidError = EmailVerificationTokenInvalidError;
108
+ class EmailVerificationTokenExpiredError extends AuthDomainError {
109
+ constructor(message = "Email verification token has expired", details) {
110
+ super(message, "EMAIL_VERIFICATION_TOKEN_EXPIRED", details);
60
111
  }
61
112
  }
62
- exports.InvalidOrExpiredRefreshTokenError = InvalidOrExpiredRefreshTokenError;
113
+ exports.EmailVerificationTokenExpiredError = EmailVerificationTokenExpiredError;
@@ -0,0 +1,4 @@
1
+ import { AuthDomainError } from "./auth.errors";
2
+ export declare class InvalidInputError extends AuthDomainError {
3
+ constructor(message?: string, details?: unknown);
4
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvalidInputError = void 0;
4
+ const auth_errors_1 = require("./auth.errors");
5
+ class InvalidInputError extends auth_errors_1.AuthDomainError {
6
+ constructor(message = "Email verification token is required", details) {
7
+ super(message, "INVALID_INPUT", details);
8
+ }
9
+ }
10
+ exports.InvalidInputError = InvalidInputError;
@@ -1,34 +1,39 @@
1
- export declare class InvalidEmailError extends Error {
1
+ /**
2
+ * Errores del dominio relacionados a identidad/credenciales.
3
+ * Ahora incluyen `code` canónico para que host/plugins mapeen por `code`.
4
+ */
5
+ import { AuthDomainError } from "./auth.errors";
6
+ export declare class InvalidEmailError extends AuthDomainError {
2
7
  constructor(value: string);
3
8
  }
4
- export declare class InvalidHashedPasswordError extends Error {
9
+ export declare class InvalidHashedPasswordError extends AuthDomainError {
5
10
  constructor(msg?: string);
6
11
  }
7
- export declare class PasswordPolicyViolationError extends Error {
12
+ export declare class PasswordPolicyViolationError extends AuthDomainError {
8
13
  readonly issues: string[];
9
14
  constructor(issues: string[], msg?: string);
10
15
  }
11
- export declare class PasswordMismatchError extends Error {
16
+ export declare class PasswordMismatchError extends AuthDomainError {
12
17
  constructor(msg?: string);
13
18
  }
14
- export declare class UserNotFoundError extends Error {
19
+ export declare class UserNotFoundError extends AuthDomainError {
15
20
  constructor(msg?: string);
16
21
  }
17
- export declare class UserDisabledError extends Error {
22
+ export declare class UserDisabledError extends AuthDomainError {
18
23
  constructor(msg?: string);
19
24
  }
20
- export declare class EmailAlreadyInUseError extends Error {
25
+ export declare class EmailAlreadyInUseError extends AuthDomainError {
21
26
  constructor(msg?: string);
22
27
  }
23
- export declare class InvalidPermissionError extends Error {
28
+ export declare class InvalidPermissionError extends AuthDomainError {
24
29
  constructor(message: string);
25
30
  }
26
- export declare class InvalidRoleError extends Error {
31
+ export declare class InvalidRoleError extends AuthDomainError {
27
32
  constructor(message: string);
28
33
  }
29
- export declare class InvalidIdError extends Error {
34
+ export declare class InvalidIdError extends AuthDomainError {
30
35
  constructor(message: string);
31
36
  }
32
- export declare class LogoutError extends Error {
33
- constructor(message: string);
37
+ export declare class LogoutError extends AuthDomainError {
38
+ constructor(message: string, details?: unknown);
34
39
  }
@@ -1,81 +1,85 @@
1
1
  "use strict";
2
+ /**
3
+ * Errores del dominio relacionados a identidad/credenciales.
4
+ * Ahora incluyen `code` canónico para que host/plugins mapeen por `code`.
5
+ */
2
6
  Object.defineProperty(exports, "__esModule", { value: true });
3
7
  exports.LogoutError = exports.InvalidIdError = exports.InvalidRoleError = exports.InvalidPermissionError = exports.EmailAlreadyInUseError = exports.UserDisabledError = exports.UserNotFoundError = exports.PasswordMismatchError = exports.PasswordPolicyViolationError = exports.InvalidHashedPasswordError = exports.InvalidEmailError = void 0;
4
- // Object Types
5
- class InvalidEmailError extends Error {
8
+ const auth_errors_1 = require("./auth.errors");
9
+ class InvalidEmailError extends auth_errors_1.AuthDomainError {
6
10
  constructor(value) {
7
- super(`Invalid email format: "${value}"`);
11
+ super(`Invalid email format: "${value}"`, "INVALID_EMAIL");
8
12
  this.name = "InvalidEmailError";
9
13
  }
10
14
  }
11
15
  exports.InvalidEmailError = InvalidEmailError;
12
- class InvalidHashedPasswordError extends Error {
16
+ class InvalidHashedPasswordError extends auth_errors_1.AuthDomainError {
13
17
  constructor(msg = "Invalid bcrypt hash format") {
14
- super(msg);
18
+ super(msg, "INVALID_HASHED_PASSWORD");
15
19
  this.name = "InvalidHashedPasswordError";
16
20
  }
17
21
  }
18
22
  exports.InvalidHashedPasswordError = InvalidHashedPasswordError;
19
- class PasswordPolicyViolationError extends Error {
23
+ class PasswordPolicyViolationError extends auth_errors_1.AuthDomainError {
20
24
  constructor(issues, msg = "Password policy violation") {
21
- super(msg);
22
- this.issues = issues;
25
+ super(msg, "PASSWORD_POLICY_VIOLATION", { issues: issues.join(",") });
23
26
  this.name = "PasswordPolicyViolationError";
27
+ this.issues = issues;
24
28
  }
25
29
  }
26
30
  exports.PasswordPolicyViolationError = PasswordPolicyViolationError;
27
- class PasswordMismatchError extends Error {
31
+ class PasswordMismatchError extends auth_errors_1.AuthDomainError {
28
32
  constructor(msg = "Password does not match") {
29
- super(msg);
33
+ super(msg, "PASSWORD_MISMATCH");
30
34
  this.name = "PasswordMismatchError";
31
35
  }
32
36
  }
33
37
  exports.PasswordMismatchError = PasswordMismatchError;
34
- class UserNotFoundError extends Error {
38
+ class UserNotFoundError extends auth_errors_1.AuthDomainError {
35
39
  constructor(msg = "User not found") {
36
- super(msg);
40
+ super(msg, "USER_NOT_FOUND");
37
41
  this.name = "UserNotFoundError";
38
42
  }
39
43
  }
40
44
  exports.UserNotFoundError = UserNotFoundError;
41
- class UserDisabledError extends Error {
45
+ class UserDisabledError extends auth_errors_1.AuthDomainError {
42
46
  constructor(msg = "User is disabled") {
43
- super(msg);
47
+ super(msg, "USER_DISABLED");
44
48
  this.name = "UserDisabledError";
45
49
  }
46
50
  }
47
51
  exports.UserDisabledError = UserDisabledError;
48
- class EmailAlreadyInUseError extends Error {
52
+ class EmailAlreadyInUseError extends auth_errors_1.AuthDomainError {
49
53
  constructor(msg = "Email already in use") {
50
- super(msg);
54
+ super(msg, "EMAIL_ALREADY_IN_USE");
51
55
  this.name = "EmailAlreadyInUseError";
52
56
  }
53
57
  }
54
58
  exports.EmailAlreadyInUseError = EmailAlreadyInUseError;
55
- class InvalidPermissionError extends Error {
59
+ class InvalidPermissionError extends auth_errors_1.AuthDomainError {
56
60
  constructor(message) {
57
- super(message);
61
+ super(message, "INVALID_PERMISSION");
58
62
  this.name = "InvalidPermissionError";
59
63
  }
60
64
  }
61
65
  exports.InvalidPermissionError = InvalidPermissionError;
62
- class InvalidRoleError extends Error {
66
+ class InvalidRoleError extends auth_errors_1.AuthDomainError {
63
67
  constructor(message) {
64
- super(message);
68
+ super(message, "INVALID_ROLE");
65
69
  this.name = "InvalidRoleError";
66
70
  }
67
71
  }
68
72
  exports.InvalidRoleError = InvalidRoleError;
69
- class InvalidIdError extends Error {
73
+ class InvalidIdError extends auth_errors_1.AuthDomainError {
70
74
  constructor(message) {
71
- super(message);
75
+ super(message, "INVALID_ID");
72
76
  this.name = "InvalidIdError";
73
77
  }
74
78
  }
75
79
  exports.InvalidIdError = InvalidIdError;
76
- class LogoutError extends Error {
77
- constructor(message) {
78
- super(message);
80
+ class LogoutError extends auth_errors_1.AuthDomainError {
81
+ constructor(message, details) {
82
+ super(message, "LOGOUT_FAILED", details);
79
83
  this.name = "LogoutError";
80
84
  }
81
85
  }
@@ -1,2 +1,7 @@
1
1
  export * from "./auth.errors";
2
2
  export * from "./identity.errors";
3
+ export * from "./password-reset.errors";
4
+ export * from "./jwt-payload.error";
5
+ export * from "./auth-error-code";
6
+ export * from "./jwt.errors";
7
+ export * from "./general.errors";
@@ -16,3 +16,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./auth.errors"), exports);
18
18
  __exportStar(require("./identity.errors"), exports);
19
+ __exportStar(require("./password-reset.errors"), exports);
20
+ __exportStar(require("./jwt-payload.error"), exports);
21
+ __exportStar(require("./auth-error-code"), exports);
22
+ __exportStar(require("./jwt.errors"), exports);
23
+ __exportStar(require("./general.errors"), exports);
@@ -0,0 +1,4 @@
1
+ import { AuthDomainError } from "./auth.errors";
2
+ export declare class InvalidJwtPayloadError extends AuthDomainError {
3
+ constructor(message?: string, details?: unknown);
4
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvalidJwtPayloadError = void 0;
4
+ const auth_errors_1 = require("./auth.errors");
5
+ class InvalidJwtPayloadError extends auth_errors_1.AuthDomainError {
6
+ constructor(message = "Invalid JWT payload", details) {
7
+ super(message, "JWT_PAYLOAD_INVALID", details);
8
+ }
9
+ }
10
+ exports.InvalidJwtPayloadError = InvalidJwtPayloadError;
@@ -0,0 +1,7 @@
1
+ import { AuthDomainError } from "./auth.errors";
2
+ export declare class InvalidJwtEmptyError extends AuthDomainError {
3
+ constructor(message?: string, details?: unknown);
4
+ }
5
+ export declare class InvalidJwtMalformedError extends AuthDomainError {
6
+ constructor(message?: string, details?: unknown);
7
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvalidJwtMalformedError = exports.InvalidJwtEmptyError = void 0;
4
+ const auth_errors_1 = require("./auth.errors");
5
+ class InvalidJwtEmptyError extends auth_errors_1.AuthDomainError {
6
+ constructor(message = "Invalid Empty JWT", details) {
7
+ super(message, "JWT_EMPTY", details);
8
+ }
9
+ }
10
+ exports.InvalidJwtEmptyError = InvalidJwtEmptyError;
11
+ class InvalidJwtMalformedError extends auth_errors_1.AuthDomainError {
12
+ constructor(message = "Invalid Malformed JWT", details) {
13
+ super(message, "JWT_MALFORMED", details);
14
+ }
15
+ }
16
+ exports.InvalidJwtMalformedError = InvalidJwtMalformedError;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Errores específicos del flujo de reseteo de contraseña.
3
+ * Responsabilidad: representar fallos esperados y mapeables a HTTP.
4
+ */
5
+ import { AuthDomainError } from "./auth.errors";
6
+ export declare class PasswordResetTokenInvalidError extends AuthDomainError {
7
+ constructor(msg?: string);
8
+ }
9
+ export declare class PasswordResetTokenExpiredError extends AuthDomainError {
10
+ constructor(msg?: string);
11
+ }
12
+ export declare class PasswordResetTokenAlreadyUsedError extends AuthDomainError {
13
+ constructor(msg?: string);
14
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * Errores específicos del flujo de reseteo de contraseña.
4
+ * Responsabilidad: representar fallos esperados y mapeables a HTTP.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PasswordResetTokenAlreadyUsedError = exports.PasswordResetTokenExpiredError = exports.PasswordResetTokenInvalidError = void 0;
8
+ const auth_errors_1 = require("./auth.errors");
9
+ class PasswordResetTokenInvalidError extends auth_errors_1.AuthDomainError {
10
+ constructor(msg = "Password reset token is invalid") {
11
+ super(msg, "PASSWORD_RESET_TOKEN_INVALID");
12
+ this.name = "PasswordResetTokenInvalidError";
13
+ }
14
+ }
15
+ exports.PasswordResetTokenInvalidError = PasswordResetTokenInvalidError;
16
+ class PasswordResetTokenExpiredError extends auth_errors_1.AuthDomainError {
17
+ constructor(msg = "Password reset token has expired") {
18
+ super(msg, "PASSWORD_RESET_TOKEN_EXPIRED");
19
+ this.name = "PasswordResetTokenExpiredError";
20
+ }
21
+ }
22
+ exports.PasswordResetTokenExpiredError = PasswordResetTokenExpiredError;
23
+ class PasswordResetTokenAlreadyUsedError extends auth_errors_1.AuthDomainError {
24
+ constructor(msg = "Password reset token has already been used") {
25
+ super(msg, "PASSWORD_RESET_TOKEN_ALREADY_USED");
26
+ this.name = "PasswordResetTokenAlreadyUsedError";
27
+ }
28
+ }
29
+ exports.PasswordResetTokenAlreadyUsedError = PasswordResetTokenAlreadyUsedError;
@@ -3,3 +3,4 @@ export * from "./errors";
3
3
  export * from "./object-values";
4
4
  export * from "./ports";
5
5
  export * from "./props";
6
+ export * from "./types";
@@ -19,3 +19,4 @@ __exportStar(require("./errors"), exports);
19
19
  __exportStar(require("./object-values"), exports);
20
20
  __exportStar(require("./ports"), exports);
21
21
  __exportStar(require("./props"), exports);
22
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,19 @@
1
+ import type { Id } from "../../object-values";
2
+ /**
3
+ * Token de verificación de email (single-use, TTL).
4
+ * Implementación fuera del core (DB/Redis).
5
+ */
6
+ export interface IEmailVerificationTokenPort {
7
+ issue(userId: Id, ttlMs: number): Promise<{
8
+ token: string;
9
+ expiresAt: Date;
10
+ }>;
11
+ verify(token: string): Promise<{
12
+ userId: Id;
13
+ expiresAt: Date;
14
+ }>;
15
+ consume(token: string): Promise<{
16
+ userId: Id;
17
+ expiresAt: Date;
18
+ }>;
19
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,2 +1,4 @@
1
1
  export * from "./password-hasher.port";
2
2
  export * from "./password-policy.port";
3
+ export * from "./password-reset-token.port";
4
+ export * from "./email-verification-token.port";