@jmlq/auth-plugin-jose 0.0.1-alpha.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 (64) hide show
  1. package/README.md +228 -0
  2. package/dist/application/factories/create-jose-token-service.d.ts +28 -0
  3. package/dist/application/factories/create-jose-token-service.js +76 -0
  4. package/dist/application/factories/index.d.ts +1 -0
  5. package/dist/application/factories/index.js +17 -0
  6. package/dist/application/factories/internal/assert.util.d.ts +9 -0
  7. package/dist/application/factories/internal/assert.util.js +16 -0
  8. package/dist/application/factories/internal/clock-skew-normalizer.util.d.ts +14 -0
  9. package/dist/application/factories/internal/clock-skew-normalizer.util.js +24 -0
  10. package/dist/application/factories/internal/expires-in.util.d.ts +21 -0
  11. package/dist/application/factories/internal/expires-in.util.js +31 -0
  12. package/dist/application/factories/internal/index.d.ts +5 -0
  13. package/dist/application/factories/internal/index.js +21 -0
  14. package/dist/application/factories/internal/key-material.validator.d.ts +15 -0
  15. package/dist/application/factories/internal/key-material.validator.js +26 -0
  16. package/dist/application/factories/internal/string-normalizers.util.d.ts +18 -0
  17. package/dist/application/factories/internal/string-normalizers.util.js +31 -0
  18. package/dist/application/types/expires-in.types.d.ts +33 -0
  19. package/dist/application/types/expires-in.types.js +3 -0
  20. package/dist/application/types/index.d.ts +2 -0
  21. package/dist/application/types/index.js +18 -0
  22. package/dist/application/types/jose-token-service.options.d.ts +81 -0
  23. package/dist/application/types/jose-token-service.options.js +9 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.js +9 -0
  26. package/dist/infrastructure/mappers/index.d.ts +1 -0
  27. package/dist/infrastructure/mappers/index.js +17 -0
  28. package/dist/infrastructure/mappers/jose-error.mapper.d.ts +35 -0
  29. package/dist/infrastructure/mappers/jose-error.mapper.js +219 -0
  30. package/dist/infrastructure/mappers/types/index.d.ts +4 -0
  31. package/dist/infrastructure/mappers/types/index.js +20 -0
  32. package/dist/infrastructure/mappers/types/jose-error-context.type.d.ts +32 -0
  33. package/dist/infrastructure/mappers/types/jose-error-context.type.js +3 -0
  34. package/dist/infrastructure/mappers/types/mapped-auth-error.type.d.ts +24 -0
  35. package/dist/infrastructure/mappers/types/mapped-auth-error.type.js +3 -0
  36. package/dist/infrastructure/mappers/types/token-kind.type.d.ts +7 -0
  37. package/dist/infrastructure/mappers/types/token-kind.type.js +3 -0
  38. package/dist/infrastructure/mappers/types/token-operation.type.d.ts +7 -0
  39. package/dist/infrastructure/mappers/types/token-operation.type.js +3 -0
  40. package/dist/infrastructure/services/index.d.ts +1 -0
  41. package/dist/infrastructure/services/index.js +17 -0
  42. package/dist/infrastructure/services/internal/expires-in.util.d.ts +21 -0
  43. package/dist/infrastructure/services/internal/expires-in.util.js +35 -0
  44. package/dist/infrastructure/services/internal/index.d.ts +7 -0
  45. package/dist/infrastructure/services/internal/index.js +23 -0
  46. package/dist/infrastructure/services/internal/jose-context.util.d.ts +35 -0
  47. package/dist/infrastructure/services/internal/jose-context.util.js +51 -0
  48. package/dist/infrastructure/services/internal/jose-error.util.d.ts +16 -0
  49. package/dist/infrastructure/services/internal/jose-error.util.js +27 -0
  50. package/dist/infrastructure/services/internal/jose-keys.normalizer.d.ts +25 -0
  51. package/dist/infrastructure/services/internal/jose-keys.normalizer.js +35 -0
  52. package/dist/infrastructure/services/internal/jti.util.d.ts +8 -0
  53. package/dist/infrastructure/services/internal/jti.util.js +25 -0
  54. package/dist/infrastructure/services/internal/jwt-expiration-reader.d.ts +9 -0
  55. package/dist/infrastructure/services/internal/jwt-expiration-reader.js +23 -0
  56. package/dist/infrastructure/services/internal/jwt-payload.normalizer.d.ts +11 -0
  57. package/dist/infrastructure/services/internal/jwt-payload.normalizer.js +56 -0
  58. package/dist/infrastructure/services/jose-token.service.d.ts +192 -0
  59. package/dist/infrastructure/services/jose-token.service.js +309 -0
  60. package/dist/infrastructure/services/types/create-auth-error-fn.type.d.ts +27 -0
  61. package/dist/infrastructure/services/types/create-auth-error-fn.type.js +2 -0
  62. package/dist/infrastructure/services/types/index.d.ts +1 -0
  63. package/dist/infrastructure/services/types/index.js +17 -0
  64. package/package.json +48 -0
package/README.md ADDED
@@ -0,0 +1,228 @@
1
+ # @jmlq/auth-plugin-jose
2
+
3
+ ## Introducción técnica
4
+
5
+ Plugin de **infraestructura JWT** basado en la librería [`jose`](https://github.com/panva/jose) para el core de autenticación [`@jmlq/auth`](https://www.npmjs.com/package/@jmlq/auth).
6
+
7
+ Este paquete **NO contiene lógica de negocio**.
8
+ Su única responsabilidad es **implementar los ports de tokens definidos por el core** y traducir detalles técnicos de `jose` a contratos estables del dominio.
9
+
10
+ El plugin se encarga de:
11
+
12
+ - Generación y verificación de JWT
13
+ - Soporte para algoritmos HS256, RS256 y ES256
14
+ - Normalización y validación de claims estándar (`iss`, `aud`, `exp`, `nbf`, `iat`, `sub`, `jti`)
15
+ - Validación de expiración y clock skew
16
+ - Manejo de claves simétricas y asimétricas
17
+ - Traducción de errores técnicos de `jose` a errores del core
18
+
19
+ ---
20
+
21
+ ## Relación con @jmlq/auth
22
+
23
+ - **@jmlq/auth**
24
+ Core de autenticación (domain + application).
25
+ Define contratos, errores y casos de uso.
26
+
27
+ - **@jmlq/auth-plugin-jose**
28
+ Plugin de **infraestructura**.
29
+ Depende del core e implementa estrictamente sus ports.
30
+
31
+ > ⚠️ Bajo ninguna circunstancia el core depende de este plugin.
32
+
33
+ ---
34
+
35
+ ## Componentes principales expuestos
36
+
37
+ ### Factory
38
+
39
+ - **createJoseTokenService**
40
+ Factory de alto nivel que construye una implementación de `ITokenServicePort`
41
+ compatible con `@jmlq/auth`.
42
+
43
+ Responsabilidades:
44
+
45
+ - Validar configuración técnica mínima (keys, algoritmo, opciones)
46
+ - Normalizar issuer, audience, expiración y clock skew
47
+ - Garantizar una política de expiración consistente
48
+ - Encapsular completamente el uso de `jose`
49
+
50
+ > Es el **único punto recomendado de entrada** para consumidores del plugin.
51
+
52
+ ---
53
+
54
+ ### Tipos de configuración
55
+
56
+ - **JoseTokenServiceOptions**
57
+ Define la configuración necesaria para construir el servicio de tokens:
58
+ - `algorithm`: Algoritmo JWT (`HS256`, `RS256`, `ES256`)
59
+ - `keys`: Material criptográfico (secret o key pair)
60
+ - `issuer`: Emisor esperado (`iss`)
61
+ - `audience`: Audiencia permitida (`aud`)
62
+ - `defaultExpiresIn`: Expiración por defecto (ej: `"15m"`)
63
+ - `clockSkewSeconds`: Tolerancia de desajuste de reloj
64
+
65
+ Estos tipos existen para **configuración explícita y tipada**, sin estado global.
66
+
67
+ ---
68
+
69
+ ## Estrategia de errores (OBLIGATORIA)
70
+
71
+ - El plugin **NO expone errores propios**
72
+
73
+ Reglas:
74
+
75
+ - Todos los errores de `jose` se traducen a `AuthDomainError`
76
+ - No se definen nuevos códigos de error
77
+ - El error original se conserva como `cause` o `meta`
78
+ - La aplicación **solo maneja errores del core**
79
+
80
+ Ejemplos de mapeo:
81
+
82
+ | Error `jose` | Error del core |
83
+ | ---------------------- | ------------------------- |
84
+ | Token expirado | `TOKEN_EXPIRED` |
85
+ | Firma inválida | `SIGNATURE_INVALID` |
86
+ | Token malformado | `TOKEN_MALFORMED` |
87
+ | Algoritmo no soportado | `ALGORITHM_UNSUPPORTED` |
88
+ | Claims inválidos | `CLAIMS_VALIDATION_ERROR` |
89
+
90
+ ---
91
+
92
+ ## 📦 Instalación
93
+
94
+ ```bash
95
+ npm install @jmlq/auth @jmlq/auth-plugin-jose
96
+ ```
97
+
98
+ Versiones recomendadas:
99
+
100
+ - `@jmlq/auth` >= `0.1.0-alpha`
101
+ - `jose` >= `5.x`
102
+
103
+ ---
104
+
105
+ ## Uso básico
106
+
107
+ ### Crear el servicio de tokens
108
+
109
+ ```ts
110
+ import { createJoseTokenService } from "@jmlq/auth-plugin-jose";
111
+
112
+ const tokenService = createJoseTokenService({
113
+ algorithm: "HS256",
114
+ keys: { secret: "super-secret" },
115
+ issuer: "my-api",
116
+ audience: "my-clients",
117
+ defaultExpiresIn: "15m",
118
+ clockSkewSeconds: 5,
119
+ });
120
+ ```
121
+
122
+ ---
123
+
124
+ ### Generar un access token
125
+
126
+ ```ts
127
+ const token = await tokenService.generateAccessToken({
128
+ subject: "user-123",
129
+ payload: {
130
+ scope: ["user"],
131
+ },
132
+ });
133
+ ```
134
+
135
+ ---
136
+
137
+ ### Verificar un token
138
+
139
+ ```ts
140
+ const result = await tokenService.verifyAccessToken(token);
141
+
142
+ console.log(result.payload.sub); // "user-123"
143
+ ```
144
+
145
+ Si ocurre un error:
146
+
147
+ - Se lanza un `AuthDomainError`
148
+ - Nunca se lanza un error de `jose`
149
+
150
+ ---
151
+
152
+ ### Ejemplo de integración en una API (Express)
153
+
154
+ Se recomienda realizar esta integración en la **capa infrastructure** de la API.
155
+
156
+ ```ts
157
+ // src/infrastructure/auth/token-service.ts
158
+
159
+ import { createJoseTokenService } from "@jmlq/auth-plugin-jose";
160
+
161
+ export const tokenService = createJoseTokenService({
162
+ algorithm: "RS256",
163
+ keys: {
164
+ publicKey: process.env.JWT_PUBLIC_KEY!,
165
+ privateKey: process.env.JWT_PRIVATE_KEY!,
166
+ },
167
+ issuer: "auth-api",
168
+ audience: "web-app",
169
+ defaultExpiresIn: "15m",
170
+ });
171
+ ```
172
+
173
+ ## Este servicio se inyecta luego en los casos de uso del core (`@jmlq/auth`).
174
+
175
+ ---
176
+
177
+ ## Variables de entorno (recomendadas)
178
+
179
+ El plugin **No lee variables de entorno directamente**, pero una API típica puede definir::
180
+
181
+ ```ini
182
+ JWT_ALGORITHM=RS256
183
+ JWT_ISSUER=auth-api
184
+ JWT_AUDIENCE=web-app
185
+ JWT_DEFAULT_EXPIRES_IN=15m
186
+ JWT_CLOCK_SKEW_SECONDS=5
187
+
188
+ JWT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----..."
189
+ JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----..."
190
+
191
+ ```
192
+
193
+ La lectura y validación de estas variables es responsabilidad de la aplicación.
194
+
195
+ ---
196
+
197
+ ## Estructura del proyecto
198
+
199
+ ```
200
+ src/
201
+ ├─ application/
202
+ │ ├─ factories/
203
+ │ │ └─ create-jose-token-service.ts
204
+ │ ├─ types/
205
+ │ │ └─ jose-token-service.options.ts
206
+ │ └─ internal/
207
+ │ └─ *.util.ts
208
+
209
+ ├─ infrastructure/
210
+ │ ├─ services/
211
+ │ │ └─ jose-token.service.ts
212
+ │ └─ mappers/
213
+ │ └─ jose-error.mapper.ts
214
+
215
+ └─ index.ts
216
+
217
+ ```
218
+
219
+ ---
220
+
221
+ ## 📄 Más información
222
+
223
+ - **[🏗️ Documentación de Arquitectura](./architecture.md)** - Clean Architecture, capas y patrones
224
+ - **[📚 Ejemplos de Código](./examples/)** - Casos de uso reales y implementaciones
225
+
226
+ ## 📄 Licencia
227
+
228
+ MIT © Mauricio Lahuasi
@@ -0,0 +1,28 @@
1
+ import type { ITokenServicePort } from "@jmlq/auth";
2
+ import type { JoseTokenServiceOptions } from "../types";
3
+ import type { CreateAuthErrorFn } from "../../infrastructure/services/types";
4
+ /**
5
+ * Factory para construir un `ITokenServicePort` basado en `jose`.
6
+ *
7
+ * Responsabilidades de esta factory:
8
+ * - Validar configuración mínima (keys, defaults requeridos).
9
+ * - Normalizar opciones (issuer/audience/clockSkew/defaultExpiresIn).
10
+ * - Garantizar política acordada: getExpirationPolicy = "verify-first".
11
+ *
12
+ * No hace:
13
+ * - importación de keys
14
+ * - operaciones JWT
15
+ * (eso es responsabilidad del adapter `JoseTokenService`).
16
+ *
17
+ * @template TAuthError Tipo de error del core que se construye mediante createAuthError.
18
+ *
19
+ * @param args Argumentos del factory.
20
+ * @param args.options Opciones del plugin (keys, issuer/audience, defaults, etc.).
21
+ * @param args.createAuthError Función para construir errores del core (no errores del plugin).
22
+ *
23
+ * @returns Instancia que cumple `ITokenServicePort`.
24
+ */
25
+ export declare function createJoseTokenService<TAuthError extends Error>(args: {
26
+ options: JoseTokenServiceOptions;
27
+ createAuthError: CreateAuthErrorFn<TAuthError>;
28
+ }): ITokenServicePort;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ // src/application/factories/create-jose-token-service.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.createJoseTokenService = createJoseTokenService;
5
+ const types_1 = require("../types");
6
+ const services_1 = require("../../infrastructure/services");
7
+ const internal_1 = require("./internal");
8
+ /**
9
+ * Factory para construir un `ITokenServicePort` basado en `jose`.
10
+ *
11
+ * Responsabilidades de esta factory:
12
+ * - Validar configuración mínima (keys, defaults requeridos).
13
+ * - Normalizar opciones (issuer/audience/clockSkew/defaultExpiresIn).
14
+ * - Garantizar política acordada: getExpirationPolicy = "verify-first".
15
+ *
16
+ * No hace:
17
+ * - importación de keys
18
+ * - operaciones JWT
19
+ * (eso es responsabilidad del adapter `JoseTokenService`).
20
+ *
21
+ * @template TAuthError Tipo de error del core que se construye mediante createAuthError.
22
+ *
23
+ * @param args Argumentos del factory.
24
+ * @param args.options Opciones del plugin (keys, issuer/audience, defaults, etc.).
25
+ * @param args.createAuthError Función para construir errores del core (no errores del plugin).
26
+ *
27
+ * @returns Instancia que cumple `ITokenServicePort`.
28
+ */
29
+ function createJoseTokenService(args) {
30
+ const { options, createAuthError } = args;
31
+ // ---------------------------------------------------------------------------
32
+ // Validación mínima (fail-fast)
33
+ // ---------------------------------------------------------------------------
34
+ (0, internal_1.assert)(!!options, "options is required");
35
+ (0, internal_1.assert)(!!options.access, "options.access is required");
36
+ (0, internal_1.assert)(!!options.refresh, "options.refresh is required");
37
+ (0, internal_1.validateKeyMaterial)("access", options.access.keys);
38
+ (0, internal_1.validateKeyMaterial)("refresh", options.refresh.keys);
39
+ // Exigir defaults de expiración (props.expiresIn es opcional)
40
+ const accessDefaultExpiresIn = (0, internal_1.normalizeDefaultExpiresIn)("access", options.access.defaultExpiresIn);
41
+ const refreshDefaultExpiresIn = (0, internal_1.normalizeDefaultExpiresIn)("refresh", options.refresh.defaultExpiresIn);
42
+ // ---------------------------------------------------------------------------
43
+ // Normalización de opciones comunes
44
+ // ---------------------------------------------------------------------------
45
+ const commonIssuer = (0, internal_1.normalizeIssuer)(options.issuer);
46
+ const commonAudience = (0, internal_1.normalizeAudience)(options.audience);
47
+ const commonClockSkewSeconds = (0, internal_1.normalizeClockSkewSeconds)(options.clockSkewSeconds);
48
+ // Política acordada: solo verify-first
49
+ const getExpirationPolicy = options.getExpirationPolicy ?? types_1.DEFAULT_GET_EXPIRATION_POLICY;
50
+ (0, internal_1.assert)(getExpirationPolicy === "verify-first", `getExpirationPolicy must be "verify-first"`);
51
+ // ---------------------------------------------------------------------------
52
+ // Construcción final de options (con defaults aplicados)
53
+ // ---------------------------------------------------------------------------
54
+ const normalizedOptions = {
55
+ issuer: commonIssuer,
56
+ audience: commonAudience,
57
+ clockSkewSeconds: commonClockSkewSeconds,
58
+ getExpirationPolicy,
59
+ access: {
60
+ ...options.access,
61
+ issuer: (0, internal_1.normalizeIssuer)(options.access.issuer) ?? commonIssuer,
62
+ audience: (0, internal_1.normalizeAudience)(options.access.audience) ?? commonAudience,
63
+ clockSkewSeconds: (0, internal_1.normalizeClockSkewSeconds)(options.access.clockSkewSeconds ?? commonClockSkewSeconds),
64
+ defaultExpiresIn: accessDefaultExpiresIn,
65
+ },
66
+ refresh: {
67
+ ...options.refresh,
68
+ issuer: (0, internal_1.normalizeIssuer)(options.refresh.issuer) ?? commonIssuer,
69
+ audience: (0, internal_1.normalizeAudience)(options.refresh.audience) ?? commonAudience,
70
+ clockSkewSeconds: (0, internal_1.normalizeClockSkewSeconds)(options.refresh.clockSkewSeconds ?? commonClockSkewSeconds),
71
+ defaultExpiresIn: refreshDefaultExpiresIn,
72
+ },
73
+ };
74
+ // La instancia real (JWT ops) vive en infraestructura.
75
+ return new services_1.JoseTokenService(normalizedOptions, createAuthError);
76
+ }
@@ -0,0 +1 @@
1
+ export * from "./create-jose-token-service";
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./create-jose-token-service"), exports);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Assert minimalista para validar precondiciones.
3
+ * Si la condición no se cumple, lanza un Error con prefijo del factory
4
+ * para rastrear rápidamente el origen.
5
+ *
6
+ * @param condition Expresión booleana que debe cumplirse.
7
+ * @param message Mensaje técnico simple (sin datos sensibles).
8
+ */
9
+ export declare function assert(condition: any, message: string): asserts condition;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ // src/application/factories/internal/assert.util.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.assert = assert;
5
+ /**
6
+ * Assert minimalista para validar precondiciones.
7
+ * Si la condición no se cumple, lanza un Error con prefijo del factory
8
+ * para rastrear rápidamente el origen.
9
+ *
10
+ * @param condition Expresión booleana que debe cumplirse.
11
+ * @param message Mensaje técnico simple (sin datos sensibles).
12
+ */
13
+ function assert(condition, message) {
14
+ if (!condition)
15
+ throw new Error(`[createJoseTokenService] ${message}`);
16
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Normaliza el clock skew (tolerancia de reloj) en segundos.
3
+ *
4
+ * ¿Para qué sirve?
5
+ * En sistemas distribuidos, el reloj del servidor puede diferir unos segundos.
6
+ * `clockSkewSeconds` permite tolerar esa diferencia al validar tokens.
7
+ *
8
+ * Reglas:
9
+ * - si no es número finito o es negativo -> usa default.
10
+ *
11
+ * @param value Valor recibido desde options.
12
+ * @returns clockSkewSeconds normalizado.
13
+ */
14
+ export declare function normalizeClockSkewSeconds(value: unknown): number;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ // src/application/factories/internal/clock-skew-normalizer.util.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.normalizeClockSkewSeconds = normalizeClockSkewSeconds;
5
+ const types_1 = require("../../types");
6
+ /**
7
+ * Normaliza el clock skew (tolerancia de reloj) en segundos.
8
+ *
9
+ * ¿Para qué sirve?
10
+ * En sistemas distribuidos, el reloj del servidor puede diferir unos segundos.
11
+ * `clockSkewSeconds` permite tolerar esa diferencia al validar tokens.
12
+ *
13
+ * Reglas:
14
+ * - si no es número finito o es negativo -> usa default.
15
+ *
16
+ * @param value Valor recibido desde options.
17
+ * @returns clockSkewSeconds normalizado.
18
+ */
19
+ function normalizeClockSkewSeconds(value) {
20
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
21
+ return types_1.DEFAULT_CLOCK_SKEW_SECONDS;
22
+ }
23
+ return value;
24
+ }
@@ -0,0 +1,21 @@
1
+ import type { ExpiresInString } from "../../types/expires-in.types";
2
+ /**
3
+ * Verifica si un valor cumple el formato ExpiresInString.
4
+ *
5
+ * Formato aceptado:
6
+ * - número + unidad: s (seconds), m (minutes), h (hours), d (days)
7
+ * Ejemplos: "15m", "7d", "3600s", "12h".
8
+ *
9
+ * @param value Valor desconocido a validar.
10
+ * @returns true si es ExpiresInString.
11
+ */
12
+ export declare function isExpiresInString(value: unknown): value is ExpiresInString;
13
+ /**
14
+ * Normaliza y exige `defaultExpiresIn` porque `props.expiresIn` es opcional.
15
+ * Si el valor no existe o no cumple el formato, lanza Error.
16
+ *
17
+ * @param kind Tipo de token (access/refresh) para mensajes claros.
18
+ * @param value Valor recibido desde options.
19
+ * @returns ExpiresInString válido.
20
+ */
21
+ export declare function normalizeDefaultExpiresIn(kind: "access" | "refresh", value: unknown): ExpiresInString;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ // src/application/factories/internal/expires-in.util.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.isExpiresInString = isExpiresInString;
5
+ exports.normalizeDefaultExpiresIn = normalizeDefaultExpiresIn;
6
+ const assert_util_1 = require("./assert.util");
7
+ /**
8
+ * Verifica si un valor cumple el formato ExpiresInString.
9
+ *
10
+ * Formato aceptado:
11
+ * - número + unidad: s (seconds), m (minutes), h (hours), d (days)
12
+ * Ejemplos: "15m", "7d", "3600s", "12h".
13
+ *
14
+ * @param value Valor desconocido a validar.
15
+ * @returns true si es ExpiresInString.
16
+ */
17
+ function isExpiresInString(value) {
18
+ return typeof value === "string" && /^[0-9]+[smhd]$/.test(value);
19
+ }
20
+ /**
21
+ * Normaliza y exige `defaultExpiresIn` porque `props.expiresIn` es opcional.
22
+ * Si el valor no existe o no cumple el formato, lanza Error.
23
+ *
24
+ * @param kind Tipo de token (access/refresh) para mensajes claros.
25
+ * @param value Valor recibido desde options.
26
+ * @returns ExpiresInString válido.
27
+ */
28
+ function normalizeDefaultExpiresIn(kind, value) {
29
+ (0, assert_util_1.assert)(isExpiresInString(value), `${kind}.defaultExpiresIn is required and must match format like "15m", "7d", "3600s"`);
30
+ return value;
31
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./assert.util";
2
+ export * from "./clock-skew-normalizer.util";
3
+ export * from "./expires-in.util";
4
+ export * from "./key-material.validator";
5
+ export * from "./string-normalizers.util";
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./assert.util"), exports);
18
+ __exportStar(require("./clock-skew-normalizer.util"), exports);
19
+ __exportStar(require("./expires-in.util"), exports);
20
+ __exportStar(require("./key-material.validator"), exports);
21
+ __exportStar(require("./string-normalizers.util"), exports);
@@ -0,0 +1,15 @@
1
+ import type { JoseKeyMaterial } from "../../types";
2
+ /**
3
+ * Valida que el material de claves requerido exista según el algoritmo.
4
+ *
5
+ * Reglas simples:
6
+ * - HS256: requiere `secret` (string o Uint8Array).
7
+ * - RS256/ES256: requiere `privateKey` y `publicKey` (PEM string o KeyLike).
8
+ *
9
+ * Nota: esta validación NO importa/parsea keys.
10
+ * Solo valida presencia y tipo básico para fallar rápido.
11
+ *
12
+ * @param kind Tipo de token (access/refresh) para errores claros.
13
+ * @param keys Configuración de claves para ese token.
14
+ */
15
+ export declare function validateKeyMaterial(kind: "access" | "refresh", keys: JoseKeyMaterial): void;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ // src/application/factories/internal/key-material.validator.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.validateKeyMaterial = validateKeyMaterial;
5
+ const assert_util_1 = require("./assert.util");
6
+ /**
7
+ * Valida que el material de claves requerido exista según el algoritmo.
8
+ *
9
+ * Reglas simples:
10
+ * - HS256: requiere `secret` (string o Uint8Array).
11
+ * - RS256/ES256: requiere `privateKey` y `publicKey` (PEM string o KeyLike).
12
+ *
13
+ * Nota: esta validación NO importa/parsea keys.
14
+ * Solo valida presencia y tipo básico para fallar rápido.
15
+ *
16
+ * @param kind Tipo de token (access/refresh) para errores claros.
17
+ * @param keys Configuración de claves para ese token.
18
+ */
19
+ function validateKeyMaterial(kind, keys) {
20
+ if (keys.alg === "HS256") {
21
+ (0, assert_util_1.assert)(typeof keys.secret === "string" || keys.secret instanceof Uint8Array, `${kind}.keys.secret must be string or Uint8Array for HS256`);
22
+ return;
23
+ }
24
+ (0, assert_util_1.assert)(keys.privateKey != null, `${kind}.keys.privateKey is required for ${keys.alg}`);
25
+ (0, assert_util_1.assert)(keys.publicKey != null, `${kind}.keys.publicKey is required for ${keys.alg}`);
26
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Normaliza issuer:
3
+ * - si es string no vacío: trim()
4
+ * - si no: undefined
5
+ *
6
+ * @param value Valor recibido desde options.
7
+ * @returns issuer normalizado.
8
+ */
9
+ export declare function normalizeIssuer(value: unknown): string | undefined;
10
+ /**
11
+ * Normaliza audience:
12
+ * - si es string no vacío: trim()
13
+ * - si no: undefined
14
+ *
15
+ * @param value Valor recibido desde options.
16
+ * @returns audience normalizado.
17
+ */
18
+ export declare function normalizeAudience(value: unknown): string | undefined;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ // src/application/factories/internal/string-normalizers.util.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.normalizeIssuer = normalizeIssuer;
5
+ exports.normalizeAudience = normalizeAudience;
6
+ /**
7
+ * Normaliza issuer:
8
+ * - si es string no vacío: trim()
9
+ * - si no: undefined
10
+ *
11
+ * @param value Valor recibido desde options.
12
+ * @returns issuer normalizado.
13
+ */
14
+ function normalizeIssuer(value) {
15
+ return typeof value === "string" && value.trim().length > 0
16
+ ? value.trim()
17
+ : undefined;
18
+ }
19
+ /**
20
+ * Normaliza audience:
21
+ * - si es string no vacío: trim()
22
+ * - si no: undefined
23
+ *
24
+ * @param value Valor recibido desde options.
25
+ * @returns audience normalizado.
26
+ */
27
+ function normalizeAudience(value) {
28
+ return typeof value === "string" && value.trim().length > 0
29
+ ? value.trim()
30
+ : undefined;
31
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Representa un valor de expiración humano para JWT.
3
+ *
4
+ * Convenciones aceptadas (a definir por el parser del plugin):
5
+ * - Segundos: "3600s"
6
+ * - Minutos: "15m"
7
+ * - Horas: "1h"
8
+ * - Días: "7d"
9
+ *
10
+ * NOTA:
11
+ * - Este tipo NO implementa parsing.
12
+ * - La conversión a segundos/Date se hace en la capa infrastructure.
13
+ * - El core (@jmlq/auth) ya usa string para expiresIn; este archivo
14
+ * solo documenta y formaliza el contrato esperado por el plugin.
15
+ */
16
+ /**
17
+ * Unidades de tiempo soportadas para expiresIn.
18
+ */
19
+ export type ExpiresInUnit = "s" | "m" | "h" | "d";
20
+ /**
21
+ * Formato string esperado para expiresIn.
22
+ *
23
+ * Ejemplos válidos:
24
+ * - "3600s"
25
+ * - "15m"
26
+ * - "1h"
27
+ * - "7d"
28
+ */
29
+ export type ExpiresInString = `${number}${ExpiresInUnit}`;
30
+ /**
31
+ * Alias semántico para mayor claridad en options y props.
32
+ */
33
+ export type ExpiresIn = ExpiresInString;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ // src/application/types/expires-in.types.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export * from "./expires-in.types";
2
+ export * from "./jose-token-service.options";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./expires-in.types"), exports);
18
+ __exportStar(require("./jose-token-service.options"), exports);