@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.
- package/README.es.md +133 -0
- package/README.md +81 -207
- package/dist/application/dtos/index.d.ts +1 -1
- package/dist/application/dtos/index.js +1 -1
- package/dist/application/dtos/request/change-password.request.d.ts +15 -0
- package/dist/application/dtos/request/index.d.ts +5 -0
- package/dist/application/dtos/request/index.js +5 -0
- package/dist/application/dtos/request/logout.request.d.ts +2 -1
- package/dist/application/dtos/request/me.request.d.ts +3 -0
- package/dist/application/dtos/request/me.request.js +2 -0
- package/dist/application/dtos/request/register-user.request.d.ts +2 -1
- package/dist/application/dtos/request/request-password-reset.request.d.ts +6 -0
- package/dist/application/dtos/request/request-password-reset.request.js +2 -0
- package/dist/application/dtos/request/reset-password.request.d.ts +14 -0
- package/dist/application/dtos/request/reset-password.request.js +2 -0
- package/dist/application/dtos/request/verify-email.request.d.ts +3 -0
- package/dist/application/dtos/request/verify-email.request.js +2 -0
- package/dist/application/dtos/response/change-password.response.d.ts +7 -0
- package/dist/application/dtos/response/change-password.response.js +2 -0
- package/dist/application/dtos/response/index.d.ts +5 -0
- package/dist/application/dtos/response/index.js +5 -0
- package/dist/application/dtos/response/login.response.d.ts +2 -1
- package/dist/application/dtos/response/me.response.d.ts +11 -0
- package/dist/application/dtos/response/me.response.js +2 -0
- package/dist/application/dtos/response/refresh-token.response.d.ts +1 -0
- package/dist/application/dtos/response/register-user.response.d.ts +9 -0
- package/dist/application/dtos/response/request-password-reset.response.d.ts +15 -0
- package/dist/application/dtos/response/request-password-reset.response.js +2 -0
- package/dist/application/dtos/response/reset-password.response.d.ts +7 -0
- package/dist/application/dtos/response/reset-password.response.js +2 -0
- package/dist/application/dtos/response/verify-email.response.d.ts +4 -0
- package/dist/application/dtos/response/verify-email.response.js +2 -0
- package/dist/application/dtos/types/user-role.type.js +2 -0
- package/dist/application/facades/auth.facade.d.ts +33 -0
- package/dist/application/facades/auth.facade.js +60 -0
- package/dist/application/facades/create-auth-facade.d.ts +22 -0
- package/dist/application/facades/create-auth-facade.js +9 -0
- package/dist/application/facades/index.d.ts +2 -0
- package/dist/application/facades/index.js +18 -0
- package/dist/application/factories/auth-service.factory.d.ts +4 -4
- package/dist/application/factories/auth-service.factory.js +16 -4
- package/dist/application/factories/index.js +1 -0
- package/dist/application/types/auth-service-factory-options.type.d.ts +44 -0
- package/dist/application/use-cases/change-password.use-case.d.ts +21 -0
- package/dist/application/use-cases/change-password.use-case.js +49 -0
- package/dist/application/use-cases/index.d.ts +5 -0
- package/dist/application/use-cases/index.js +5 -0
- package/dist/application/use-cases/internal/index.d.ts +1 -0
- package/dist/application/use-cases/internal/index.js +17 -0
- package/dist/application/use-cases/internal/password-assertions.d.ts +13 -0
- package/dist/application/use-cases/internal/password-assertions.js +26 -0
- package/dist/application/use-cases/login-with-password.use-case.js +24 -28
- package/dist/application/use-cases/logout.use-case.js +14 -2
- package/dist/application/use-cases/me.use-case.d.ts +7 -0
- package/dist/application/use-cases/me.use-case.js +28 -0
- package/dist/application/use-cases/refresh-token.use-case.d.ts +16 -2
- package/dist/application/use-cases/refresh-token.use-case.js +33 -5
- package/dist/application/use-cases/register-user.use-case.d.ts +6 -1
- package/dist/application/use-cases/register-user.use-case.js +18 -7
- package/dist/application/use-cases/request-password-reset.use-case.d.ts +19 -0
- package/dist/application/use-cases/request-password-reset.use-case.js +43 -0
- package/dist/application/use-cases/reset-password.use-case.d.ts +20 -0
- package/dist/application/use-cases/reset-password.use-case.js +59 -0
- package/dist/application/use-cases/verify-email.use-case.d.ts +8 -0
- package/dist/application/use-cases/verify-email.use-case.js +30 -0
- package/dist/domain/entities/credential.entity.d.ts +36 -11
- package/dist/domain/entities/credential.entity.js +41 -11
- package/dist/domain/entities/user.entity.d.ts +32 -1
- package/dist/domain/entities/user.entity.js +54 -1
- package/dist/domain/errors/auth-error-code.d.ts +16 -0
- package/dist/domain/errors/auth-error-code.js +60 -0
- package/dist/domain/errors/auth.errors.d.ts +29 -8
- package/dist/domain/errors/auth.errors.js +59 -8
- package/dist/domain/errors/general.errors.d.ts +4 -0
- package/dist/domain/errors/general.errors.js +10 -0
- package/dist/domain/errors/identity.errors.d.ts +17 -12
- package/dist/domain/errors/identity.errors.js +29 -25
- package/dist/domain/errors/index.d.ts +5 -0
- package/dist/domain/errors/index.js +5 -0
- package/dist/domain/errors/jwt-payload.error.d.ts +4 -0
- package/dist/domain/errors/jwt-payload.error.js +10 -0
- package/dist/domain/errors/jwt.errors.d.ts +7 -0
- package/dist/domain/errors/jwt.errors.js +16 -0
- package/dist/domain/errors/password-reset.errors.d.ts +14 -0
- package/dist/domain/errors/password-reset.errors.js +29 -0
- package/dist/domain/index.d.ts +1 -0
- package/dist/domain/index.js +1 -0
- package/dist/domain/ports/auth/email-verification-token.port.d.ts +19 -0
- package/dist/domain/ports/auth/email-verification-token.port.js +2 -0
- package/dist/domain/ports/auth/index.d.ts +2 -0
- package/dist/domain/ports/auth/index.js +2 -0
- package/dist/domain/ports/auth/password-reset-token.port.d.ts +36 -0
- package/dist/domain/ports/auth/password-reset-token.port.js +2 -0
- package/dist/domain/ports/jwt/payload/jwt-payload.port.d.ts +25 -3
- package/dist/domain/ports/repository/credential.repository.d.ts +55 -2
- package/dist/domain/ports/token/token-session.port.d.ts +2 -0
- package/dist/domain/props/entities/credential.props.d.ts +9 -1
- package/dist/domain/props/entities/user.props.d.ts +1 -0
- package/dist/domain/props/jwt/generate-access-token.props.d.ts +3 -2
- package/dist/domain/props/jwt/generate-refresh-token.props.d.ts +3 -2
- package/dist/domain/props/jwt/jwt-user.d.ts +11 -2
- package/dist/domain/services/helpers/assert-jwt-structure.helper.d.ts +1 -0
- package/dist/domain/services/helpers/assert-jwt-structure.helper.js +13 -0
- package/dist/domain/services/helpers/index.d.ts +7 -0
- package/dist/domain/services/helpers/index.js +23 -0
- package/dist/domain/services/helpers/optional-audience.helper.d.ts +14 -0
- package/dist/domain/services/helpers/optional-audience.helper.js +49 -0
- package/dist/domain/services/helpers/optional-non-empty-string.helper.d.ts +1 -0
- package/dist/domain/services/helpers/optional-non-empty-string.helper.js +9 -0
- package/dist/domain/services/helpers/optional-record.helper.d.ts +1 -0
- package/dist/domain/services/helpers/optional-record.helper.js +15 -0
- package/dist/domain/services/helpers/optional-roles.helper.d.ts +3 -0
- package/dist/domain/services/helpers/optional-roles.helper.js +32 -0
- package/dist/domain/services/helpers/require-finite-number.helper.d.ts +1 -0
- package/dist/domain/services/helpers/require-finite-number.helper.js +12 -0
- package/dist/domain/services/helpers/require-non-empty-string.helper.d.ts +1 -0
- package/dist/domain/services/helpers/require-non-empty-string.helper.js +12 -0
- package/dist/domain/services/index.d.ts +1 -0
- package/dist/domain/services/index.js +1 -0
- package/dist/domain/services/normalize-jwt-payload.service.d.ts +19 -0
- package/dist/domain/services/normalize-jwt-payload.service.js +58 -0
- package/dist/domain/types/access-snapshot.type.d.ts +15 -0
- package/dist/domain/types/access-snapshot.type.js +2 -0
- package/dist/domain/types/index.d.ts +1 -0
- package/dist/domain/types/index.js +2 -0
- package/dist/in-memory/in-memory-credential.repository.d.ts +66 -3
- package/dist/in-memory/in-memory-credential.repository.js +174 -46
- package/dist/index.d.ts +18 -2
- package/dist/index.js +24 -9
- package/dist/infrastructure/index.d.ts +3 -0
- package/dist/infrastructure/index.js +18 -0
- package/dist/infrastructure/security/bcrypt-password-hasher.js +0 -1
- package/dist/infrastructure/services/token-session.service.d.ts +163 -8
- package/dist/infrastructure/services/token-session.service.js +290 -37
- package/dist/infrastructure/types/auth-service-container.d.ts +21 -2
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/shared/jwt-plugin/create-jwt-id.d.ts +6 -0
- package/dist/shared/jwt-plugin/create-jwt-id.js +30 -0
- package/dist/shared/jwt-plugin/index.d.ts +9 -0
- package/dist/shared/jwt-plugin/index.js +25 -0
- package/dist/shared/jwt-plugin/is-retryable-auth-code.d.ts +8 -0
- package/dist/shared/jwt-plugin/is-retryable-auth-code.js +15 -0
- package/dist/shared/jwt-plugin/normalize-clock-skew-seconds.d.ts +14 -0
- package/dist/shared/jwt-plugin/normalize-clock-skew-seconds.js +23 -0
- package/dist/shared/jwt-plugin/normalize-default-expires-in.d.ts +16 -0
- package/dist/shared/jwt-plugin/normalize-default-expires-in.js +36 -0
- package/dist/shared/jwt-plugin/read-custom-claims.d.ts +12 -0
- package/dist/shared/jwt-plugin/read-custom-claims.js +21 -0
- package/dist/shared/jwt-plugin/read-expires-in.d.ts +12 -0
- package/dist/shared/jwt-plugin/read-expires-in.js +20 -0
- package/dist/shared/jwt-plugin/read-session-id.d.ts +11 -0
- package/dist/shared/jwt-plugin/read-session-id.js +17 -0
- package/dist/shared/jwt-plugin/resolve-expires-in.d.ts +14 -0
- package/dist/shared/jwt-plugin/resolve-expires-in.js +31 -0
- package/dist/shared/jwt-plugin/to-date-from-unix-seconds.d.ts +7 -0
- package/dist/shared/jwt-plugin/to-date-from-unix-seconds.js +12 -0
- package/package.json +12 -11
- /package/dist/application/dtos/{type/user-role.type.js → request/change-password.request.js} +0 -0
- /package/dist/application/dtos/{type → types}/index.d.ts +0 -0
- /package/dist/application/dtos/{type → types}/index.js +0 -0
- /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
|
-
|
|
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:
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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.
|
|
113
|
+
exports.EmailVerificationTokenExpiredError = EmailVerificationTokenExpiredError;
|
|
@@ -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
|
-
|
|
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
|
|
9
|
+
export declare class InvalidHashedPasswordError extends AuthDomainError {
|
|
5
10
|
constructor(msg?: string);
|
|
6
11
|
}
|
|
7
|
-
export declare class PasswordPolicyViolationError extends
|
|
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
|
|
16
|
+
export declare class PasswordMismatchError extends AuthDomainError {
|
|
12
17
|
constructor(msg?: string);
|
|
13
18
|
}
|
|
14
|
-
export declare class UserNotFoundError extends
|
|
19
|
+
export declare class UserNotFoundError extends AuthDomainError {
|
|
15
20
|
constructor(msg?: string);
|
|
16
21
|
}
|
|
17
|
-
export declare class UserDisabledError extends
|
|
22
|
+
export declare class UserDisabledError extends AuthDomainError {
|
|
18
23
|
constructor(msg?: string);
|
|
19
24
|
}
|
|
20
|
-
export declare class EmailAlreadyInUseError extends
|
|
25
|
+
export declare class EmailAlreadyInUseError extends AuthDomainError {
|
|
21
26
|
constructor(msg?: string);
|
|
22
27
|
}
|
|
23
|
-
export declare class InvalidPermissionError extends
|
|
28
|
+
export declare class InvalidPermissionError extends AuthDomainError {
|
|
24
29
|
constructor(message: string);
|
|
25
30
|
}
|
|
26
|
-
export declare class InvalidRoleError extends
|
|
31
|
+
export declare class InvalidRoleError extends AuthDomainError {
|
|
27
32
|
constructor(message: string);
|
|
28
33
|
}
|
|
29
|
-
export declare class InvalidIdError extends
|
|
34
|
+
export declare class InvalidIdError extends AuthDomainError {
|
|
30
35
|
constructor(message: string);
|
|
31
36
|
}
|
|
32
|
-
export declare class LogoutError extends
|
|
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
|
-
|
|
5
|
-
class InvalidEmailError extends
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
}
|
|
@@ -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,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;
|
package/dist/domain/index.d.ts
CHANGED
package/dist/domain/index.js
CHANGED
|
@@ -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
|
+
}
|