@dacyti-gsi/auth 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/types.ts ADDED
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Configuración del cliente.
3
+ *
4
+ * Todo tiene valor por defecto: lo que no se pasa se lee del entorno
5
+ * (`SSO_ISSUER`, `SSO_CLIENT_ID`, `SSO_CLIENT_SECRET`, `SSO_SECRET`,
6
+ * `APP_URL`, `SSO_POST_LOGOUT_URI`). Cada opción que hay que rellenar para
7
+ * empezar es una decisión que se le pide a alguien que todavía no conoce el
8
+ * sistema; las variables de entorno ya son el idioma de despliegue.
9
+ *
10
+ * ```ts
11
+ * export const sso = defineNextSSO({ permissions: ["documentos:anular"] });
12
+ * ```
13
+ */
14
+ export type SSOClientOptions<Permission extends string = string> = {
15
+ /**
16
+ * URL del emisor, tal cual la publica el portal. Ej: `https://sso.ejemplo.com/api/auth`.
17
+ * Por defecto `SSO_ISSUER`.
18
+ */
19
+ issuer?: string;
20
+ /** Por defecto `SSO_CLIENT_ID`. */
21
+ clientId?: string;
22
+ /** Por defecto `SSO_CLIENT_SECRET`. */
23
+ clientSecret?: string;
24
+
25
+ /**
26
+ * Clave para cifrar la cookie de sesión. Mínimo 32 caracteres.
27
+ * Por defecto `SSO_SECRET`.
28
+ *
29
+ * La cookie guarda el access token. Cifrarla evita que acabe legible en un
30
+ * volcado de memoria, en un log de proxy o en una copia de seguridad del
31
+ * navegador.
32
+ */
33
+ secret?: string;
34
+
35
+ /**
36
+ * Espejo del catálogo que el portal declara para esta aplicación.
37
+ *
38
+ * El portal define los permisos (cadenas opacas: las almacena, las agrupa en
39
+ * roles y las emite como claim) y la aplicación les da significado al
40
+ * exigirlos con `can()`, `protectPage()`, `action()` o `<Protect>`. Esta
41
+ * lista no declara nada: si se pasa como tupla `as const`, `can()`
42
+ * autocompleta y un permiso mal escrito es un error de compilación en lugar
43
+ * de un `false` silencioso en producción.
44
+ *
45
+ * Declara primero en la consola del portal; lo que llegue sin declarar,
46
+ * simplemente nunca aparece en la sesión.
47
+ */
48
+ permissions?: readonly Permission[];
49
+
50
+ /** Ruta donde se montan los handlers. Por defecto `/api/sso`. */
51
+ basePath?: string;
52
+
53
+ /**
54
+ * URL pública de la aplicación consumidora. Solo explícita, nunca del
55
+ * entorno: el `redirect_uri` debe coincidir EXACTAMENTE con el registrado en
56
+ * el portal, y adivinarlo desde una variable global es como se acaba
57
+ * enviando el puerto equivocado.
58
+ *
59
+ * Opcional: se deduce de la petición entrante. Indícala si la aplicación vive
60
+ * detrás de un proxy que no reescribe `X-Forwarded-Host`, o si necesitas
61
+ * construir enlaces fuera del ciclo de una petición.
62
+ */
63
+ appUrl?: string;
64
+
65
+ /**
66
+ * A dónde vuelve el navegador tras cerrar la sesión en el portal.
67
+ * Por defecto `SSO_POST_LOGOUT_URI`.
68
+ *
69
+ * Por defecto, la raíz de la aplicación. **Tiene que estar registrada en el
70
+ * portal como URI de cierre de sesión** y coincidir exactamente: el endpoint
71
+ * de cierre solo redirige a URIs que un administrador dio de alta.
72
+ */
73
+ postLogoutRedirectUri?: string;
74
+
75
+ /** Por defecto `["openid", "profile", "email"]`. */
76
+ scopes?: string[];
77
+
78
+ /** Nombre de la cookie de sesión. Por defecto `__Host-sso_session`. */
79
+ cookieName?: string;
80
+
81
+ /** Duración de la sesión local, en segundos. Por defecto 7 días. */
82
+ sessionMaxAge?: number;
83
+ };
84
+
85
+ /** Métodos de autenticación, con los valores del RFC 8176. */
86
+ export type AuthMethod = "pwd" | "otp" | "swk" | "mfa" | (string & {});
87
+
88
+ export type SSOUser = {
89
+ /** Identificador estable. Úsalo como clave, no el correo. */
90
+ id: string;
91
+ email: string;
92
+ emailVerified: boolean;
93
+ name: string | null;
94
+ image: string | null;
95
+ };
96
+
97
+ export type SSOSession<Permission extends string = string> = {
98
+ user: SSOUser;
99
+
100
+ roles: string[];
101
+ permissions: Permission[];
102
+
103
+ /** Con qué se autenticó esta sesión. */
104
+ amr: AuthMethod[];
105
+
106
+ accessToken: string;
107
+ /** Marca de tiempo Unix en la que caduca el acceso. */
108
+ expiresAt: number;
109
+
110
+ /**
111
+ * Si el `access_token` ya caducó.
112
+ *
113
+ * Dura 15 minutos, muy poco frente a la vida de la cookie. Llamar a una API
114
+ * con un token caducado da 401, así que conviene consultarlo antes —o dejar
115
+ * que `session({ revalidate: true })` o `action()` lo renueven.
116
+ */
117
+ isExpired(): boolean;
118
+
119
+ /** Si la sesión tiene el permiso indicado. */
120
+ can(permission: Permission): boolean;
121
+ /** Si los tiene todos. */
122
+ canAll(...permissions: Permission[]): boolean;
123
+ /** Si tiene al menos uno. */
124
+ canAny(...permissions: Permission[]): boolean;
125
+
126
+ /** Lanza `SSOForbiddenError` si falta el permiso. */
127
+ requires(permission: Permission): void;
128
+
129
+ /** Si la autenticación usó más de un factor. */
130
+ usedSecondFactor(): boolean;
131
+ };
132
+
133
+ /** Documento de descubrimiento OIDC, con los campos que usa el cliente. */
134
+ export type DiscoveryDocument = {
135
+ issuer: string;
136
+ authorization_endpoint: string;
137
+ token_endpoint: string;
138
+ userinfo_endpoint: string;
139
+ jwks_uri: string;
140
+ end_session_endpoint?: string;
141
+ revocation_endpoint?: string;
142
+ introspection_endpoint?: string;
143
+ };