@neodaten/auth-native 0.0.1-reserva.0 → 0.1.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.
Files changed (104) hide show
  1. package/README.md +1 -1
  2. package/dist/almacen-con-desbloqueo.d.ts +19 -0
  3. package/dist/almacen-con-desbloqueo.js +117 -0
  4. package/dist/almacen-con-desbloqueo.js.map +1 -0
  5. package/dist/almacen-seguro.d.ts +5 -0
  6. package/dist/almacen-seguro.js +2 -0
  7. package/dist/almacen-seguro.js.map +1 -0
  8. package/dist/base64url.d.ts +3 -0
  9. package/dist/base64url.js +40 -0
  10. package/dist/base64url.js.map +1 -0
  11. package/dist/bienvenida/bienvenida-con-ultima-cuenta.d.ts +13 -0
  12. package/dist/bienvenida/bienvenida-con-ultima-cuenta.js +73 -0
  13. package/dist/bienvenida/bienvenida-con-ultima-cuenta.js.map +1 -0
  14. package/dist/bienvenida/estado-de-la-bienvenida.d.ts +14 -0
  15. package/dist/bienvenida/estado-de-la-bienvenida.js +18 -0
  16. package/dist/bienvenida/estado-de-la-bienvenida.js.map +1 -0
  17. package/dist/bienvenida/index.d.ts +5 -0
  18. package/dist/bienvenida/index.js +5 -0
  19. package/dist/bienvenida/index.js.map +1 -0
  20. package/dist/bienvenida/marca-de-la-bienvenida.d.ts +12 -0
  21. package/dist/bienvenida/marca-de-la-bienvenida.js +2 -0
  22. package/dist/bienvenida/marca-de-la-bienvenida.js.map +1 -0
  23. package/dist/bienvenida/textos-de-la-bienvenida.d.ts +9 -0
  24. package/dist/bienvenida/textos-de-la-bienvenida.js +12 -0
  25. package/dist/bienvenida/textos-de-la-bienvenida.js.map +1 -0
  26. package/dist/bienvenida/use-bienvenida.d.ts +13 -0
  27. package/dist/bienvenida/use-bienvenida.js +42 -0
  28. package/dist/bienvenida/use-bienvenida.js.map +1 -0
  29. package/dist/canal-del-canje.d.ts +3 -0
  30. package/dist/canal-del-canje.js +22 -0
  31. package/dist/canal-del-canje.js.map +1 -0
  32. package/dist/cliente-de-identidad-nativa.d.ts +32 -0
  33. package/dist/cliente-de-identidad-nativa.js +179 -0
  34. package/dist/cliente-de-identidad-nativa.js.map +1 -0
  35. package/dist/criptografia.d.ts +15 -0
  36. package/dist/criptografia.js +28 -0
  37. package/dist/criptografia.js.map +1 -0
  38. package/dist/error-de-identidad.d.ts +6 -0
  39. package/dist/error-de-identidad.js +29 -0
  40. package/dist/error-de-identidad.js.map +1 -0
  41. package/dist/expo/crear-almacen-expo.d.ts +17 -0
  42. package/dist/expo/crear-almacen-expo.js +30 -0
  43. package/dist/expo/crear-almacen-expo.js.map +1 -0
  44. package/dist/expo/index.d.ts +1 -0
  45. package/dist/expo/index.js +2 -0
  46. package/dist/expo/index.js.map +1 -0
  47. package/dist/index.d.ts +11 -0
  48. package/dist/index.js +9 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/keychain/crear-almacen-keychain.d.ts +34 -0
  51. package/dist/keychain/crear-almacen-keychain.js +46 -0
  52. package/dist/keychain/crear-almacen-keychain.js.map +1 -0
  53. package/dist/keychain/index.d.ts +1 -0
  54. package/dist/keychain/index.js +2 -0
  55. package/dist/keychain/index.js.map +1 -0
  56. package/dist/llaves-del-emisor.d.ts +4 -0
  57. package/dist/llaves-del-emisor.js +42 -0
  58. package/dist/llaves-del-emisor.js.map +1 -0
  59. package/dist/login-hospedado.d.ts +29 -0
  60. package/dist/login-hospedado.js +123 -0
  61. package/dist/login-hospedado.js.map +1 -0
  62. package/dist/navegacion-del-login.d.ts +20 -0
  63. package/dist/navegacion-del-login.js +27 -0
  64. package/dist/navegacion-del-login.js.map +1 -0
  65. package/dist/pantalla/index.d.ts +2 -0
  66. package/dist/pantalla/index.js +3 -0
  67. package/dist/pantalla/index.js.map +1 -0
  68. package/dist/pantalla/manejador-de-carga.d.ts +11 -0
  69. package/dist/pantalla/manejador-de-carga.js +12 -0
  70. package/dist/pantalla/manejador-de-carga.js.map +1 -0
  71. package/dist/pantalla/pantalla-de-login-hospedado.d.ts +6 -0
  72. package/dist/pantalla/pantalla-de-login-hospedado.js +30 -0
  73. package/dist/pantalla/pantalla-de-login-hospedado.js.map +1 -0
  74. package/dist/passkey-de-la-bienvenida.d.ts +20 -0
  75. package/dist/passkey-de-la-bienvenida.js +50 -0
  76. package/dist/passkey-de-la-bienvenida.js.map +1 -0
  77. package/dist/pkce.d.ts +8 -0
  78. package/dist/pkce.js +13 -0
  79. package/dist/pkce.js.map +1 -0
  80. package/dist/respuesta-del-emisor.d.ts +17 -0
  81. package/dist/respuesta-del-emisor.js +70 -0
  82. package/dist/respuesta-del-emisor.js.map +1 -0
  83. package/dist/sesion-guardada.d.ts +12 -0
  84. package/dist/sesion-guardada.js +44 -0
  85. package/dist/sesion-guardada.js.map +1 -0
  86. package/dist/sha256.d.ts +1 -0
  87. package/dist/sha256.js +84 -0
  88. package/dist/sha256.js.map +1 -0
  89. package/dist/textos-del-desbloqueo.d.ts +7 -0
  90. package/dist/textos-del-desbloqueo.js +7 -0
  91. package/dist/textos-del-desbloqueo.js.map +1 -0
  92. package/dist/ticket-de-atestacion.d.ts +21 -0
  93. package/dist/ticket-de-atestacion.js +33 -0
  94. package/dist/ticket-de-atestacion.js.map +1 -0
  95. package/dist/ultima-cuenta.d.ts +13 -0
  96. package/dist/ultima-cuenta.js +67 -0
  97. package/dist/ultima-cuenta.js.map +1 -0
  98. package/dist/validar-id-token.d.ts +15 -0
  99. package/dist/validar-id-token.js +86 -0
  100. package/dist/validar-id-token.js.map +1 -0
  101. package/dist/vuelo-unico.d.ts +1 -0
  102. package/dist/vuelo-unico.js +10 -0
  103. package/dist/vuelo-unico.js.map +1 -0
  104. package/package.json +37 -46
@@ -0,0 +1,123 @@
1
+ import { exigirCanalSeguroDelCanje, exigirOrigenDelLogin } from './canal-del-canje';
2
+ import { ErrorDeIdentidad } from './error-de-identidad';
3
+ import { crearLlavesDelEmisor } from './llaves-del-emisor';
4
+ import { decidirNavegacion, esElRegresoDeLaApp, } from './navegacion-del-login';
5
+ import { crearPedidoProtegido } from './pkce';
6
+ import { tokensDe } from './respuesta-del-emisor';
7
+ import { pedirTicketDeAtestacion } from './ticket-de-atestacion';
8
+ import { validarIdToken } from './validar-id-token';
9
+ const PARAMETRO_DEL_TICKET = 'atestacion';
10
+ const ERROR_DE_ACCESO_DENEGADO = 'access_denied';
11
+ const formulario = (campos) => ({
12
+ method: 'POST',
13
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
14
+ body: new URLSearchParams(campos).toString(),
15
+ });
16
+ const ajena = () => new ErrorDeIdentidad('respuesta_ajena');
17
+ const origenesDe = ({ issuer, authorization_endpoint }, origenDelLogin) => [
18
+ ...new Set([
19
+ new URL(issuer).origin,
20
+ new URL(authorization_endpoint).origin,
21
+ exigirOrigenDelLogin(origenDelLogin ?? new URL(issuer).origin, issuer),
22
+ ]),
23
+ ];
24
+ const urlDeAutorizacion = ({ dependencias, metadatos, pedido, ticket, opciones, }) => {
25
+ const url = new URL(metadatos.authorization_endpoint);
26
+ const parametros = {
27
+ client_id: dependencias.clienteId,
28
+ redirect_uri: dependencias.redireccion,
29
+ response_type: 'code',
30
+ scope: dependencias.alcance,
31
+ resource: dependencias.recurso,
32
+ state: pedido.estado,
33
+ nonce: pedido.nonce,
34
+ code_challenge: pedido.reto,
35
+ code_challenge_method: 'S256',
36
+ ...(ticket === null ? {} : { [PARAMETRO_DEL_TICKET]: ticket }),
37
+ ...(opciones.organizacion === undefined ? {} : { organization: opciones.organizacion }),
38
+ ...(opciones.pistaDeIdentificador === undefined
39
+ ? {}
40
+ : { login_hint: opciones.pistaDeIdentificador }),
41
+ };
42
+ for (const [nombre, valor] of Object.entries(parametros))
43
+ url.searchParams.set(nombre, valor);
44
+ return url.toString();
45
+ };
46
+ const codigoDelRegreso = (urlDelRegreso, { dependencias, metadatos, pedido }) => {
47
+ if (!URL.canParse(urlDelRegreso))
48
+ throw ajena();
49
+ const regreso = new URL(urlDelRegreso);
50
+ if (!esElRegresoDeLaApp(regreso, new URL(dependencias.redireccion)))
51
+ throw ajena();
52
+ const parametros = regreso.searchParams;
53
+ if (parametros.get('state') !== pedido.estado)
54
+ throw ajena();
55
+ const emisor = parametros.get('iss');
56
+ if (emisor !== null && emisor !== metadatos.issuer)
57
+ throw ajena();
58
+ const error = parametros.get('error');
59
+ if (error !== null) {
60
+ throw new ErrorDeIdentidad(error === ERROR_DE_ACCESO_DENEGADO ? 'acceso_cancelado' : 'respuesta_invalida');
61
+ }
62
+ const codigo = parametros.get('code');
63
+ if (codigo === null || codigo.length === 0)
64
+ throw new ErrorDeIdentidad('respuesta_invalida');
65
+ return codigo;
66
+ };
67
+ const ticketSiHayProveedor = (dependencias) => dependencias.proveedorDeAtestacion === null
68
+ ? Promise.resolve(null)
69
+ : pedirTicketDeAtestacion({
70
+ coreApiUrl: dependencias.coreApiUrl,
71
+ clienteId: dependencias.clienteId,
72
+ proveedor: dependencias.proveedorDeAtestacion,
73
+ pedir: dependencias.pedir,
74
+ });
75
+ const canjear = async (codigo, { dependencias, metadatos, pedido }) => {
76
+ if (dependencias.cripto.verificarEs256 === null) {
77
+ exigirCanalSeguroDelCanje(metadatos.token_endpoint, metadatos.issuer);
78
+ }
79
+ const tokens = await tokensDe(await dependencias.pedir(metadatos.token_endpoint, formulario({
80
+ grant_type: 'authorization_code',
81
+ client_id: dependencias.clienteId,
82
+ code: codigo,
83
+ redirect_uri: dependencias.redireccion,
84
+ code_verifier: pedido.verificador,
85
+ resource: dependencias.recurso,
86
+ })));
87
+ if (tokens.id_token === undefined)
88
+ throw new ErrorDeIdentidad('identidad_invalida');
89
+ await validarIdToken(tokens.id_token, {
90
+ emisor: metadatos.issuer,
91
+ clienteId: dependencias.clienteId,
92
+ nonce: pedido.nonce,
93
+ ahoraMs: dependencias.ahora(),
94
+ }, {
95
+ llaves: crearLlavesDelEmisor(() => Promise.resolve(metadatos.jwks_uri), dependencias.pedir),
96
+ cripto: dependencias.cripto,
97
+ });
98
+ return tokens;
99
+ };
100
+ export const abrirLoginHospedado = async (dependencias, opciones = {}) => {
101
+ const metadatos = await dependencias.metadatos();
102
+ const reglas = {
103
+ redireccion: dependencias.redireccion,
104
+ origenesPermitidos: origenesDe(metadatos, dependencias.origenDelLogin),
105
+ };
106
+ const pedido = await crearPedidoProtegido(dependencias.cripto);
107
+ const ticket = await ticketSiHayProveedor(dependencias);
108
+ const contexto = { dependencias, metadatos, pedido };
109
+ let completado = false;
110
+ return {
111
+ url: urlDeAutorizacion({ ...contexto, ticket, opciones }),
112
+ reglas,
113
+ decidir: (navegacion) => decidirNavegacion(navegacion, reglas),
114
+ async completar(urlDelRegreso) {
115
+ if (completado)
116
+ throw new ErrorDeIdentidad('login_ya_completado');
117
+ completado = true;
118
+ const codigo = codigoDelRegreso(urlDelRegreso, contexto);
119
+ await dependencias.guardar(await canjear(codigo, contexto));
120
+ },
121
+ };
122
+ };
123
+ //# sourceMappingURL=login-hospedado.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login-hospedado.js","sourceRoot":"","sources":["../src/login-hospedado.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export declare const ORIGEN_DEL_CAPTCHA = "https://challenges.cloudflare.com";
2
+ export type DecisionDeNavegacion = {
3
+ tipo: 'cargar';
4
+ } | {
5
+ tipo: 'callback';
6
+ url: string;
7
+ } | {
8
+ tipo: 'descartar';
9
+ url: string;
10
+ };
11
+ export interface NavegacionPedida {
12
+ url: string;
13
+ esMarcoPrincipal: boolean;
14
+ }
15
+ export interface ReglasDeNavegacion {
16
+ redireccion: string;
17
+ origenesPermitidos: readonly string[];
18
+ }
19
+ export declare const esElRegresoDeLaApp: (url: URL, redireccion: URL) => boolean;
20
+ export declare const decidirNavegacion: ({ url, esMarcoPrincipal }: NavegacionPedida, { redireccion, origenesPermitidos }: ReglasDeNavegacion) => DecisionDeNavegacion;
@@ -0,0 +1,27 @@
1
+ export const ORIGEN_DEL_CAPTCHA = 'https://challenges.cloudflare.com';
2
+ const PROTOCOLOS_WEB = new Set(['https:', 'http:']);
3
+ const MARCOS_INTERNOS = new Set(['about:blank', 'about:srcdoc']);
4
+ const leer = (texto) => (URL.canParse(texto) ? new URL(texto) : null);
5
+ export const esElRegresoDeLaApp = (url, redireccion) => url.protocol === redireccion.protocol &&
6
+ url.host === redireccion.host &&
7
+ url.pathname === redireccion.pathname &&
8
+ url.username === '' &&
9
+ url.password === '';
10
+ const esOrigenPermitido = (url, origenes) => PROTOCOLOS_WEB.has(url.protocol) && origenes.includes(url.origin);
11
+ const esDelMarcoDelCaptcha = (url, esMarcoPrincipal) => !esMarcoPrincipal && url.origin === ORIGEN_DEL_CAPTCHA;
12
+ export const decidirNavegacion = ({ url, esMarcoPrincipal }, { redireccion, origenesPermitidos }) => {
13
+ const descartar = { tipo: 'descartar', url };
14
+ const leida = leer(url);
15
+ const regreso = leer(redireccion);
16
+ if (leida === null || regreso === null)
17
+ return descartar;
18
+ if (esElRegresoDeLaApp(leida, regreso)) {
19
+ return esMarcoPrincipal ? { tipo: 'callback', url } : descartar;
20
+ }
21
+ if (!esMarcoPrincipal && MARCOS_INTERNOS.has(url))
22
+ return { tipo: 'cargar' };
23
+ if (esOrigenPermitido(leida, origenesPermitidos))
24
+ return { tipo: 'cargar' };
25
+ return esDelMarcoDelCaptcha(leida, esMarcoPrincipal) ? { tipo: 'cargar' } : descartar;
26
+ };
27
+ //# sourceMappingURL=navegacion-del-login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navegacion-del-login.js","sourceRoot":"","sources":["../src/navegacion-del-login.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG,mCAAmC,CAAC;AAEtE,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AACzE,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC;AAiBtF,MAAM,IAAI,GAAG,CAAC,KAAa,EAAc,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAE1F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAQ,EAAE,WAAgB,EAAW,EAAE,CACxE,GAAG,CAAC,QAAQ,KAAK,WAAW,CAAC,QAAQ;IACrC,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI;IAC7B,GAAG,CAAC,QAAQ,KAAK,WAAW,CAAC,QAAQ;IACrC,GAAG,CAAC,QAAQ,KAAK,EAAE;IACnB,GAAG,CAAC,QAAQ,KAAK,EAAE,CAAC;AAEtB,MAAM,iBAAiB,GAAG,CAAC,GAAQ,EAAE,QAA2B,EAAW,EAAE,CAC3E,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAEpE,MAAM,oBAAoB,GAAG,CAAC,GAAQ,EAAE,gBAAyB,EAAW,EAAE,CAC5E,CAAC,gBAAgB,IAAI,GAAG,CAAC,MAAM,KAAK,kBAAkB,CAAC;AAEzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,EAAE,GAAG,EAAE,gBAAgB,EAAoB,EAC3C,EAAE,WAAW,EAAE,kBAAkB,EAAsB,EACjC,EAAE;IACxB,MAAM,SAAS,GAAyB,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;IACnE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;IAClC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IACzD,IAAI,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;QACvC,OAAO,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAClE,CAAC;IACD,IAAI,CAAC,gBAAgB,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC7E,IAAI,iBAAiB,CAAC,KAAK,EAAE,kBAAkB,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC5E,OAAO,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACxF,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { crearManejadorDeCarga, type AvisosDelLogin } from './manejador-de-carga';
2
+ export { PantallaDeLoginHospedado, type PropiedadesDelLoginHospedado, } from './pantalla-de-login-hospedado';
@@ -0,0 +1,3 @@
1
+ export { crearManejadorDeCarga } from './manejador-de-carga';
2
+ export { PantallaDeLoginHospedado, } from './pantalla-de-login-hospedado';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pantalla/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAuB,MAAM,sBAAsB,CAAC;AAClF,OAAO,EACL,wBAAwB,GAEzB,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { LoginAbierto } from '../login-hospedado';
2
+ export interface PeticionDeCarga {
3
+ url: string;
4
+ isTopFrame: boolean;
5
+ }
6
+ export interface AvisosDelLogin {
7
+ alEntrar: () => void;
8
+ alFallar: (error: unknown) => void;
9
+ alDescartarEnlace?: (url: string) => void;
10
+ }
11
+ export declare const crearManejadorDeCarga: (login: LoginAbierto, { alEntrar, alFallar, alDescartarEnlace }: AvisosDelLogin) => ({ url, isTopFrame }: PeticionDeCarga) => boolean;
@@ -0,0 +1,12 @@
1
+ export const crearManejadorDeCarga = (login, { alEntrar, alFallar, alDescartarEnlace }) => ({ url, isTopFrame }) => {
2
+ const decision = login.decidir({ url, esMarcoPrincipal: isTopFrame });
3
+ if (decision.tipo === 'cargar')
4
+ return true;
5
+ if (decision.tipo === 'descartar') {
6
+ alDescartarEnlace?.(decision.url);
7
+ return false;
8
+ }
9
+ login.completar(decision.url).then(alEntrar, alFallar);
10
+ return false;
11
+ };
12
+ //# sourceMappingURL=manejador-de-carga.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manejador-de-carga.js","sourceRoot":"","sources":["../../src/pantalla/manejador-de-carga.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,qBAAqB,GAChC,CAAC,KAAmB,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,EAAkB,EAAE,EAAE,CACnF,CAAC,EAAE,GAAG,EAAE,UAAU,EAAmB,EAAW,EAAE;IAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAC;IACtE,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAClC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { LoginAbierto } from '../login-hospedado';
2
+ import { type AvisosDelLogin } from './manejador-de-carga';
3
+ export interface PropiedadesDelLoginHospedado extends AvisosDelLogin {
4
+ login: LoginAbierto;
5
+ }
6
+ export declare function PantallaDeLoginHospedado({ login, alEntrar, alFallar, alDescartarEnlace, }: PropiedadesDelLoginHospedado): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useMemo } from 'react';
3
+ import { WebView } from 'react-native-webview';
4
+ import { crearManejadorDeCarga } from './manejador-de-carga';
5
+ const ORIGENES_QUE_DECIDE_LA_APP = ['*'];
6
+ const SIN_RASTRO = {
7
+ incognito: true,
8
+ cacheEnabled: false,
9
+ cacheMode: 'LOAD_NO_CACHE',
10
+ sharedCookiesEnabled: false,
11
+ thirdPartyCookiesEnabled: false,
12
+ javaScriptCanOpenWindowsAutomatically: false,
13
+ setSupportMultipleWindows: false,
14
+ allowFileAccess: false,
15
+ allowFileAccessFromFileURLs: false,
16
+ allowUniversalAccessFromFileURLs: false,
17
+ allowsLinkPreview: false,
18
+ mediaPlaybackRequiresUserAction: true,
19
+ geolocationEnabled: false,
20
+ webviewDebuggingEnabled: false,
21
+ };
22
+ export function PantallaDeLoginHospedado({ login, alEntrar, alFallar, alDescartarEnlace, }) {
23
+ const decidirCarga = useMemo(() => crearManejadorDeCarga(login, {
24
+ alEntrar,
25
+ alFallar,
26
+ ...(alDescartarEnlace === undefined ? {} : { alDescartarEnlace }),
27
+ }), [login, alEntrar, alFallar, alDescartarEnlace]);
28
+ return (_jsx(WebView, { ...SIN_RASTRO, source: { uri: login.url }, originWhitelist: ORIGENES_QUE_DECIDE_LA_APP, onShouldStartLoadWithRequest: decidirCarga }));
29
+ }
30
+ //# sourceMappingURL=pantalla-de-login-hospedado.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pantalla-de-login-hospedado.js","sourceRoot":"","sources":["../../src/pantalla/pantalla-de-login-hospedado.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,OAAO,EAAqB,MAAM,sBAAsB,CAAC;AAGlE,OAAO,EAAE,qBAAqB,EAAuB,MAAM,sBAAsB,CAAC;AAElF,MAAM,0BAA0B,GAAG,CAAC,GAAG,CAAC,CAAC;AAMzC,MAAM,UAAU,GAA0B;IACxC,SAAS,EAAE,IAAI;IACf,YAAY,EAAE,KAAK;IACnB,SAAS,EAAE,eAAe;IAC1B,oBAAoB,EAAE,KAAK;IAC3B,wBAAwB,EAAE,KAAK;IAC/B,qCAAqC,EAAE,KAAK;IAC5C,yBAAyB,EAAE,KAAK;IAChC,eAAe,EAAE,KAAK;IACtB,2BAA2B,EAAE,KAAK;IAClC,gCAAgC,EAAE,KAAK;IACvC,iBAAiB,EAAE,KAAK;IACxB,+BAA+B,EAAE,IAAI;IACrC,kBAAkB,EAAE,KAAK;IACzB,uBAAuB,EAAE,KAAK;CAC/B,CAAC;AAEF,MAAM,UAAU,wBAAwB,CAAC,EACvC,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,iBAAiB,GACY;IAC7B,MAAM,YAAY,GAAG,OAAO,CAC1B,GAAG,EAAE,CACH,qBAAqB,CAAC,KAAK,EAAE;QAC3B,QAAQ;QACR,QAAQ;QACR,GAAG,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC;KAClE,CAAC,EACJ,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAC/C,CAAC;IAEF,OAAO,CACL,KAAC,OAAO,OACF,UAAU,EACd,MAAM,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,EAC1B,eAAe,EAAE,0BAA0B,EAC3C,4BAA4B,EAAE,YAAY,GAC1C,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { ProveedorDeAtestacion } from './ticket-de-atestacion';
2
+ export declare const GRANT_TYPE_PASSKEY = "urn:neodaten:grant-type:passkey";
3
+ export type BiometriaDelDispositivo = 'rostro' | 'huella' | 'otra';
4
+ export interface ProveedorDePasskey {
5
+ biometria(): Promise<BiometriaDelDispositivo | null>;
6
+ firmar(opcionesJson: string): Promise<string>;
7
+ }
8
+ export interface RetoDePasskey {
9
+ reto: string;
10
+ opcionesJson: string;
11
+ dispositivo: string | null;
12
+ }
13
+ export interface PedidoDeRetoDePasskey {
14
+ coreApiUrl: string;
15
+ emisor: string;
16
+ clienteId: string;
17
+ proveedorDeAtestacion: ProveedorDeAtestacion | null;
18
+ pedir: (url: string, init?: RequestInit) => Promise<Response>;
19
+ }
20
+ export declare const pedirRetoDePasskey: (pedido: PedidoDeRetoDePasskey) => Promise<RetoDePasskey>;
@@ -0,0 +1,50 @@
1
+ import { ErrorDeIdentidad } from './error-de-identidad';
2
+ import { pedirTicketDelDispositivo } from './ticket-de-atestacion';
3
+ export const GRANT_TYPE_PASSKEY = 'urn:neodaten:grant-type:passkey';
4
+ const PREFIJO_DEL_EMISOR = '/p/';
5
+ const ESTADO_DE_ATESTACION_REQUERIDA = 428;
6
+ const slugDelEmisor = (emisor) => {
7
+ const { pathname } = new URL(emisor);
8
+ const indice = pathname.lastIndexOf(PREFIJO_DEL_EMISOR);
9
+ const slug = indice === -1 ? '' : pathname.slice(indice + PREFIJO_DEL_EMISOR.length);
10
+ if (slug.length === 0 || slug.includes('/'))
11
+ throw new ErrorDeIdentidad('respuesta_invalida');
12
+ return slug;
13
+ };
14
+ const esObjeto = (valor) => typeof valor === 'object' && valor !== null;
15
+ const ticketSiHayProveedor = (pedido) => pedido.proveedorDeAtestacion === null
16
+ ? Promise.resolve(null)
17
+ : pedirTicketDelDispositivo({
18
+ coreApiUrl: pedido.coreApiUrl,
19
+ clienteId: pedido.clienteId,
20
+ proveedor: pedido.proveedorDeAtestacion,
21
+ pedir: pedido.pedir,
22
+ });
23
+ const retoDe = async (respuesta) => {
24
+ if (!respuesta.ok) {
25
+ throw new ErrorDeIdentidad(respuesta.status === ESTADO_DE_ATESTACION_REQUERIDA
26
+ ? 'atestacion_fallida'
27
+ : 'servicio_no_disponible');
28
+ }
29
+ const cuerpo = await respuesta.json();
30
+ if (!esObjeto(cuerpo) || typeof cuerpo.reto !== 'string' || !esObjeto(cuerpo.opciones)) {
31
+ throw new ErrorDeIdentidad('respuesta_invalida');
32
+ }
33
+ return { reto: cuerpo.reto, opcionesJson: JSON.stringify(cuerpo.opciones) };
34
+ };
35
+ export const pedirRetoDePasskey = async (pedido) => {
36
+ const atestada = await ticketSiHayProveedor(pedido);
37
+ const respuesta = await pedido.pedir(`${pedido.coreApiUrl}/oidc/${slugDelEmisor(pedido.emisor)}/nativa/passkey/reto`, {
38
+ method: 'POST',
39
+ headers: {
40
+ 'Content-Type': 'application/json',
41
+ ...(atestada === null ? {} : { 'x-dispositivo': atestada.dispositivo }),
42
+ },
43
+ body: JSON.stringify({
44
+ client_id: pedido.clienteId,
45
+ ...(atestada === null ? {} : { atestacion: atestada.ticket }),
46
+ }),
47
+ });
48
+ return { ...(await retoDe(respuesta)), dispositivo: atestada?.dispositivo ?? null };
49
+ };
50
+ //# sourceMappingURL=passkey-de-la-bienvenida.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkey-de-la-bienvenida.js","sourceRoot":"","sources":["../src/passkey-de-la-bienvenida.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAEnE,MAAM,CAAC,MAAM,kBAAkB,GAAG,iCAAiC,CAAC;AAuBpE,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACjC,MAAM,8BAA8B,GAAG,GAAG,CAAC;AAE3C,MAAM,aAAa,GAAG,CAAC,MAAc,EAAU,EAAE;IAC/C,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACrF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;IAC9F,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CACpE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AAE9C,MAAM,oBAAoB,GAAG,CAC3B,MAA6B,EACS,EAAE,CACxC,MAAM,CAAC,qBAAqB,KAAK,IAAI;IACnC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;IACvB,CAAC,CAAC,yBAAyB,CAAC;QACxB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,MAAM,CAAC,qBAAqB;QACvC,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAC;AAET,MAAM,MAAM,GAAG,KAAK,EAAE,SAAmB,EAA+C,EAAE;IACxF,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,gBAAgB,CACxB,SAAS,CAAC,MAAM,KAAK,8BAA8B;YACjD,CAAC,CAAC,oBAAoB;YACtB,CAAC,CAAC,wBAAwB,CAC7B,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAY,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;IAC/C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvF,MAAM,IAAI,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;AAC9E,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EAAE,MAA6B,EAA0B,EAAE;IAChG,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,KAAK,CAClC,GAAG,MAAM,CAAC,UAAU,SAAS,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,sBAAsB,EAC/E;QACE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC;SACxE;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;SAC9D,CAAC;KACH,CACF,CAAC;IACF,OAAO,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,IAAI,IAAI,EAAE,CAAC;AACtF,CAAC,CAAC"}
package/dist/pkce.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { Criptografia } from './criptografia';
2
+ export interface PedidoProtegido {
3
+ verificador: string;
4
+ reto: string;
5
+ estado: string;
6
+ nonce: string;
7
+ }
8
+ export declare const crearPedidoProtegido: (cripto: Criptografia) => Promise<PedidoProtegido>;
package/dist/pkce.js ADDED
@@ -0,0 +1,13 @@
1
+ import { aBase64url, textoABytes } from './base64url';
2
+ const BYTES_DEL_VERIFICADOR = 32;
3
+ const BYTES_DEL_ESTADO = 16;
4
+ export const crearPedidoProtegido = async (cripto) => {
5
+ const verificador = aBase64url(cripto.bytesAleatorios(BYTES_DEL_VERIFICADOR));
6
+ return {
7
+ verificador,
8
+ reto: aBase64url(await cripto.sha256(textoABytes(verificador))),
9
+ estado: aBase64url(cripto.bytesAleatorios(BYTES_DEL_ESTADO)),
10
+ nonce: aBase64url(cripto.bytesAleatorios(BYTES_DEL_ESTADO)),
11
+ };
12
+ };
13
+ //# sourceMappingURL=pkce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../src/pkce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGtD,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACjC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAS5B,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,MAAoB,EAA4B,EAAE;IAC3F,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC9E,OAAO;QACL,WAAW;QACX,IAAI,EAAE,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;QAC/D,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC;QAC5D,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC;KAC5D,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { ErrorDeIdentidad } from './error-de-identidad';
2
+ export interface TokensEmitidos {
3
+ access_token: string;
4
+ expires_in: number;
5
+ refresh_token: string;
6
+ id_token?: string;
7
+ }
8
+ export interface MetadatosDelEmisor {
9
+ issuer: string;
10
+ authorization_endpoint: string;
11
+ token_endpoint: string;
12
+ jwks_uri: string;
13
+ revocation_endpoint?: string;
14
+ }
15
+ export declare function sinConexion(error: unknown): ErrorDeIdentidad;
16
+ export declare function tokensDe(respuesta: Response): Promise<TokensEmitidos>;
17
+ export declare function metadatosDe(respuesta: Response, emisorEsperado: string): Promise<MetadatosDelEmisor>;
@@ -0,0 +1,70 @@
1
+ import { ErrorDeIdentidad } from './error-de-identidad';
2
+ const CAMPOS_OBLIGATORIOS_DEL_EMISOR = [
3
+ 'issuer',
4
+ 'authorization_endpoint',
5
+ 'token_endpoint',
6
+ 'jwks_uri',
7
+ ];
8
+ const PRIMER_ESTADO_DE_ERROR_DEL_SERVIDOR = 500;
9
+ const ERRORES_DE_CREDENCIAL = new Set(['invalid_grant']);
10
+ const esObjeto = (valor) => typeof valor === 'object' && valor !== null;
11
+ const interpretarJson = async (respuesta) => {
12
+ try {
13
+ const valor = await respuesta.json();
14
+ return valor;
15
+ }
16
+ catch (error) {
17
+ if (error instanceof SyntaxError)
18
+ return null;
19
+ throw error;
20
+ }
21
+ };
22
+ export function sinConexion(error) {
23
+ return error instanceof ErrorDeIdentidad
24
+ ? error
25
+ : new ErrorDeIdentidad('sin_conexion', { cause: error });
26
+ }
27
+ export async function tokensDe(respuesta) {
28
+ const cuerpo = await interpretarJson(respuesta);
29
+ if (!respuesta.ok) {
30
+ const error = esObjeto(cuerpo) ? cuerpo.error : undefined;
31
+ if (typeof error === 'string' && ERRORES_DE_CREDENCIAL.has(error)) {
32
+ throw new ErrorDeIdentidad('codigo_invalido');
33
+ }
34
+ throw new ErrorDeIdentidad(respuesta.status >= PRIMER_ESTADO_DE_ERROR_DEL_SERVIDOR || error === 'temporarily_unavailable'
35
+ ? 'servicio_no_disponible'
36
+ : 'respuesta_invalida');
37
+ }
38
+ if (!esObjeto(cuerpo) ||
39
+ typeof cuerpo.access_token !== 'string' ||
40
+ typeof cuerpo.expires_in !== 'number' ||
41
+ typeof cuerpo.refresh_token !== 'string') {
42
+ throw new ErrorDeIdentidad('respuesta_invalida');
43
+ }
44
+ return {
45
+ access_token: cuerpo.access_token,
46
+ expires_in: cuerpo.expires_in,
47
+ refresh_token: cuerpo.refresh_token,
48
+ ...(typeof cuerpo.id_token === 'string' ? { id_token: cuerpo.id_token } : {}),
49
+ };
50
+ }
51
+ const tieneLosCamposDelEmisor = (cuerpo) => esObjeto(cuerpo) &&
52
+ CAMPOS_OBLIGATORIOS_DEL_EMISOR.every((campo) => typeof cuerpo[campo] === 'string');
53
+ export async function metadatosDe(respuesta, emisorEsperado) {
54
+ const cuerpo = await interpretarJson(respuesta);
55
+ if (!respuesta.ok || !tieneLosCamposDelEmisor(cuerpo)) {
56
+ throw new ErrorDeIdentidad('servicio_no_disponible');
57
+ }
58
+ if (cuerpo.issuer !== emisorEsperado)
59
+ throw new ErrorDeIdentidad('respuesta_ajena');
60
+ return {
61
+ issuer: cuerpo.issuer,
62
+ authorization_endpoint: cuerpo.authorization_endpoint,
63
+ token_endpoint: cuerpo.token_endpoint,
64
+ jwks_uri: cuerpo.jwks_uri,
65
+ ...(typeof cuerpo.revocation_endpoint === 'string'
66
+ ? { revocation_endpoint: cuerpo.revocation_endpoint }
67
+ : {}),
68
+ };
69
+ }
70
+ //# sourceMappingURL=respuesta-del-emisor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"respuesta-del-emisor.js","sourceRoot":"","sources":["../src/respuesta-del-emisor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { AlmacenSeguro } from './almacen-seguro';
2
+ export declare const LLAVE_DE_LA_SESION = "neodaten.sesion";
3
+ export declare const LLAVE_DEL_REFRESCO = "neodaten.sesion.refresco";
4
+ export interface SesionGuardada {
5
+ acceso: string;
6
+ venceEn: number;
7
+ refresco: string;
8
+ identidad: string | null;
9
+ }
10
+ export declare function borrarSesion(almacen: AlmacenSeguro): Promise<void>;
11
+ export declare function leerSesion(almacen: AlmacenSeguro): Promise<SesionGuardada | null>;
12
+ export declare function guardarSesion(almacen: AlmacenSeguro, { refresco, ...datos }: SesionGuardada): Promise<void>;
@@ -0,0 +1,44 @@
1
+ export const LLAVE_DE_LA_SESION = 'neodaten.sesion';
2
+ export const LLAVE_DEL_REFRESCO = 'neodaten.sesion.refresco';
3
+ const esTexto = (valor) => typeof valor === 'string' && valor.length > 0;
4
+ const esDatosDeLaSesion = (valor) => {
5
+ if (typeof valor !== 'object' || valor === null)
6
+ return false;
7
+ if (!('acceso' in valor) || !('venceEn' in valor) || !('identidad' in valor))
8
+ return false;
9
+ return (esTexto(valor.acceso) &&
10
+ typeof valor.venceEn === 'number' &&
11
+ (valor.identidad === null || esTexto(valor.identidad)));
12
+ };
13
+ const interpretarJson = (texto) => {
14
+ try {
15
+ const valor = JSON.parse(texto);
16
+ return valor;
17
+ }
18
+ catch (error) {
19
+ if (error instanceof SyntaxError)
20
+ return null;
21
+ throw error;
22
+ }
23
+ };
24
+ export async function borrarSesion(almacen) {
25
+ await almacen.borrar(LLAVE_DE_LA_SESION);
26
+ await almacen.borrar(LLAVE_DEL_REFRESCO);
27
+ }
28
+ export async function leerSesion(almacen) {
29
+ const texto = await almacen.obtener(LLAVE_DE_LA_SESION);
30
+ if (texto === null)
31
+ return null;
32
+ const datos = interpretarJson(texto);
33
+ const refresco = await almacen.obtener(LLAVE_DEL_REFRESCO);
34
+ if (esDatosDeLaSesion(datos) && esTexto(refresco)) {
35
+ return { acceso: datos.acceso, venceEn: datos.venceEn, identidad: datos.identidad, refresco };
36
+ }
37
+ await borrarSesion(almacen);
38
+ return null;
39
+ }
40
+ export async function guardarSesion(almacen, { refresco, ...datos }) {
41
+ await almacen.guardar(LLAVE_DEL_REFRESCO, refresco);
42
+ await almacen.guardar(LLAVE_DE_LA_SESION, JSON.stringify(datos));
43
+ }
44
+ //# sourceMappingURL=sesion-guardada.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sesion-guardada.js","sourceRoot":"","sources":["../src/sesion-guardada.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AACpD,MAAM,CAAC,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAW7D,MAAM,OAAO,GAAG,CAAC,KAAc,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAEnG,MAAM,iBAAiB,GAAG,CAAC,KAAc,EAA4B,EAAE;IACrE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,IAAI,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3F,OAAO,CACL,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;QACrB,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,CAAC,KAAK,CAAC,SAAS,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CACvD,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,KAAa,EAAW,EAAE;IACjD,IAAI,CAAC;QACH,MAAM,KAAK,GAAY,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,WAAW;YAAE,OAAO,IAAI,CAAC;QAC9C,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAsB;IACvD,MAAM,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACzC,MAAM,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAsB;IACrD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACxD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC3D,IAAI,iBAAiB,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClD,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;IAChG,CAAC;IACD,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAsB,EACtB,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAkB;IAEtC,MAAM,OAAO,CAAC,OAAO,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;IACpD,MAAM,OAAO,CAAC,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const sha256: (datos: Uint8Array) => Uint8Array;
package/dist/sha256.js ADDED
@@ -0,0 +1,84 @@
1
+ const CONSTANTES_DE_RONDA = new Uint32Array([
2
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
3
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
4
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
5
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
6
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
7
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
8
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
9
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
10
+ ]);
11
+ const ESTADO_INICIAL = [
12
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
13
+ ];
14
+ const BYTES_POR_BLOQUE = 64;
15
+ const PALABRAS_DEL_BLOQUE = 16;
16
+ const BYTES_POR_PALABRA = 4;
17
+ const BYTES_DEL_RESUMEN = 32;
18
+ const BITS_POR_PALABRA = 32;
19
+ const BYTES_DEL_LARGO = 8;
20
+ const PALABRAS_DEL_HORARIO = 64;
21
+ const MARCA_DE_FIN = 0x80;
22
+ const BITS_POR_BYTE = 8;
23
+ const DIVISOR_DE_32_BITS = 0x1_0000_0000;
24
+ const rotar = (valor, bits) => (valor >>> bits) | (valor << (BITS_POR_PALABRA - bits));
25
+ const conRelleno = (datos) => {
26
+ const largo = Math.ceil((datos.length + 1 + BYTES_DEL_LARGO) / BYTES_POR_BLOQUE) * BYTES_POR_BLOQUE;
27
+ const rellenado = new Uint8Array(largo);
28
+ rellenado.set(datos);
29
+ rellenado[datos.length] = MARCA_DE_FIN;
30
+ const vista = new DataView(rellenado.buffer);
31
+ const bits = datos.length * BITS_POR_BYTE;
32
+ vista.setUint32(largo - BYTES_DEL_LARGO, Math.floor(bits / DIVISOR_DE_32_BITS));
33
+ vista.setUint32(largo - BYTES_DEL_LARGO / 2, bits >>> 0);
34
+ return rellenado;
35
+ };
36
+ const horarioDelBloque = (vista, inicio) => {
37
+ const horario = new Uint32Array(PALABRAS_DEL_HORARIO);
38
+ for (let indice = 0; indice < PALABRAS_DEL_BLOQUE; indice += 1) {
39
+ horario[indice] = vista.getUint32(inicio + indice * BYTES_POR_PALABRA);
40
+ }
41
+ for (let indice = PALABRAS_DEL_BLOQUE; indice < PALABRAS_DEL_HORARIO; indice += 1) {
42
+ const anterior15 = horario[indice - 15] ?? 0;
43
+ const anterior2 = horario[indice - 2] ?? 0;
44
+ const s0 = rotar(anterior15, 7) ^ rotar(anterior15, 18) ^ (anterior15 >>> 3);
45
+ const s1 = rotar(anterior2, 17) ^ rotar(anterior2, 19) ^ (anterior2 >>> 10);
46
+ horario[indice] = (horario[indice - 16] ?? 0) + s0 + (horario[indice - 7] ?? 0) + s1;
47
+ }
48
+ return horario;
49
+ };
50
+ const comprimir = (estado, horario) => {
51
+ let [a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0] = estado;
52
+ for (let indice = 0; indice < PALABRAS_DEL_HORARIO; indice += 1) {
53
+ const s1 = rotar(e, 6) ^ rotar(e, 11) ^ rotar(e, 25);
54
+ const eleccion = (e & f) ^ (~e & g);
55
+ const temporal1 = (h + s1 + eleccion + (CONSTANTES_DE_RONDA[indice] ?? 0) + (horario[indice] ?? 0)) >>> 0;
56
+ const s0 = rotar(a, 2) ^ rotar(a, 13) ^ rotar(a, 22);
57
+ const mayoria = (a & b) ^ (a & c) ^ (b & c);
58
+ const temporal2 = (s0 + mayoria) >>> 0;
59
+ [h, g, f, e, d, c, b, a] = [
60
+ g,
61
+ f,
62
+ e,
63
+ (d + temporal1) >>> 0,
64
+ c,
65
+ b,
66
+ a,
67
+ (temporal1 + temporal2) >>> 0,
68
+ ];
69
+ }
70
+ return [a, b, c, d, e, f, g, h].map((valor, indice) => (valor + (estado[indice] ?? 0)) >>> 0);
71
+ };
72
+ export const sha256 = (datos) => {
73
+ const rellenado = conRelleno(datos);
74
+ const vista = new DataView(rellenado.buffer);
75
+ let estado = [...ESTADO_INICIAL];
76
+ for (let inicio = 0; inicio < rellenado.length; inicio += BYTES_POR_BLOQUE) {
77
+ estado = comprimir(estado, horarioDelBloque(vista, inicio));
78
+ }
79
+ const resumen = new Uint8Array(BYTES_DEL_RESUMEN);
80
+ const salida = new DataView(resumen.buffer);
81
+ estado.forEach((valor, indice) => salida.setUint32(indice * BYTES_POR_PALABRA, valor));
82
+ return resumen;
83
+ };
84
+ //# sourceMappingURL=sha256.js.map