@dotrino/identity 0.96.0 → 0.97.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/package.json +1 -1
- package/vault/acta.js +11 -2
- package/vault/core.js +14 -3
- package/vault/session.js +1 -1
package/package.json
CHANGED
package/vault/acta.js
CHANGED
|
@@ -103,7 +103,7 @@ const conCampoSellador = (acta) => Number(acta?.v) < V_SIN_CAMPO_SELLADOR
|
|
|
103
103
|
* el rol de master, que no se delega. Así un dispositivo con `admin` robado hace daño
|
|
104
104
|
* acotado y **reversible** (se le revoca), en vez de poder dejarte fuera de tu cuenta.
|
|
105
105
|
*/
|
|
106
|
-
export const CAPS = Object.freeze(['sign', 'store', 'read', 'secrets', 'admin', 'approve', 'passwords', 'sealer', 'unattended', 'replica'])
|
|
106
|
+
export const CAPS = Object.freeze(['sign', 'store', 'read', 'secrets', 'admin', 'approve', 'passwords', 'passkeys', 'sealer', 'unattended', 'replica'])
|
|
107
107
|
|
|
108
108
|
/** Capacidades de un DISPOSITIVO (sin CN): acceso a todo lo del usuario. */
|
|
109
109
|
/**
|
|
@@ -117,6 +117,15 @@ export const CAPS = Object.freeze(['sign', 'store', 'read', 'secrets', 'admin',
|
|
|
117
117
|
* pedirle algo a la bóveda es exactamente lo que decide el acta — tener dos registros
|
|
118
118
|
* de lo mismo obliga a acordarse de los dos al quitar un aparato.
|
|
119
119
|
*
|
|
120
|
+
* `passkeys` es ABRIR LA PRIVADA DE UNA PASSKEY. Una passkey no se parece a una
|
|
121
|
+
* contraseña: es una llave privada que firma el reto de un sitio, y si se copia sirve
|
|
122
|
+
* **hasta que la borres en cada sitio** donde la registraste — no hay nada que «cambiar».
|
|
123
|
+
* Por eso su envoltura solo se le hace a quien tenga `passwords` **y** esto
|
|
124
|
+
* (`dotrino-passmanager/docs/sealed-passwords.md` §2.8).
|
|
125
|
+
*
|
|
126
|
+
* Sin `passwords` no significa nada: la passkey vive en una entrada de contraseñas. Y una
|
|
127
|
+
* SESIÓN no lo lleva nunca, como `passwords` (`session.js`).
|
|
128
|
+
*
|
|
120
129
|
* `replica` es REPARTIR, NO DECIDIR. Un replicador no tiene maestra: guarda el acta y los
|
|
121
130
|
* sobres —que ya vienen sellados a su destinatario, así que tampoco puede abrirlos— y los
|
|
122
131
|
* entrega cuando la bóveda no está. Firma su respuesta con su propia llave de aparato, y
|
|
@@ -140,7 +149,7 @@ export const CAPS = Object.freeze(['sign', 'store', 'read', 'secrets', 'admin',
|
|
|
140
149
|
* de la cuenta, se ve en la pantalla de permisos como los demás, y se quita quitándolo —
|
|
141
150
|
* sin acordarse de un segundo registro escondido.
|
|
142
151
|
*/
|
|
143
|
-
export const DEVICE_CAPS = Object.freeze(['sign', 'store', 'read', 'admin', 'approve', 'passwords', 'sealer', 'unattended', 'replica'])
|
|
152
|
+
export const DEVICE_CAPS = Object.freeze(['sign', 'store', 'read', 'admin', 'approve', 'passwords', 'passkeys', 'sealer', 'unattended', 'replica'])
|
|
144
153
|
|
|
145
154
|
/**
|
|
146
155
|
* Lo que recibe un dispositivo recién emparejado. `admin` **no está**: no se
|
package/vault/core.js
CHANGED
|
@@ -47,6 +47,17 @@ export const CURRENT_STORAGE = 'dotrino.identity.current' // id del perfil act
|
|
|
47
47
|
const NONCE_TTL_MS = 5 * 60 * 1000
|
|
48
48
|
/** El proxio del ecosistema. No hay otro: quien quiera el suyo lo dice al llamar. */
|
|
49
49
|
const DEFAULT_PROXY = 'wss://proxy.dotrino.com'
|
|
50
|
+
/**
|
|
51
|
+
* EL PILAR DE LA BÓVEDA, EN UNA VARIABLE Y NO ESCRITO EN EL `import`. No es un capricho de
|
|
52
|
+
* estilo: **este archivo lo empaqueta cada app** —`capabilities.js` tira de él— y
|
|
53
|
+
* `@dotrino/vault` no es dependencia de ninguna, ni debe serlo: arrastraría el OPAQUE en
|
|
54
|
+
* WASM (~270 KB) a las treinta. Con el nombre escrito, el empaquetador intenta resolverlo
|
|
55
|
+
* al construir y **el build de la app se cae**, aunque nunca vaya a ejecutar esa línea.
|
|
56
|
+
*
|
|
57
|
+
* Lo que hay detrás solo corre en el iframe de identidad, que lo resuelve con su import map
|
|
58
|
+
* (o en Node, donde el paquete está instalado).
|
|
59
|
+
*/
|
|
60
|
+
const PILAR_VAULT = '@dotrino/vault'
|
|
50
61
|
|
|
51
62
|
// ----- crypto helpers (puros) -----
|
|
52
63
|
|
|
@@ -1123,8 +1134,8 @@ export async function createIdentityCore ({ kv: hostKv, peers, makeSync = null,
|
|
|
1123
1134
|
let client = null
|
|
1124
1135
|
try {
|
|
1125
1136
|
const { WebSocketProxyClient } = await import('@dotrino/proxy-client')
|
|
1126
|
-
const { closeLogin } = await import(
|
|
1127
|
-
const { vaultChannel } = await import(
|
|
1137
|
+
const { closeLogin } = await import(/* @vite-ignore */ `${PILAR_VAULT}/login-client`)
|
|
1138
|
+
const { vaultChannel } = await import(/* @vite-ignore */ `${PILAR_VAULT}/password-logins`)
|
|
1128
1139
|
client = new WebSocketProxyClient({ url: meta.proxy || DEFAULT_PROXY, enableWebRTC: false, autoReconnect: false })
|
|
1129
1140
|
await client.connect()
|
|
1130
1141
|
// El token de la bóveda cambia con cada reconexión suya, así que se vuelve a mirar el
|
|
@@ -2323,7 +2334,7 @@ export async function createIdentityCore ({ kv: hostKv, peers, makeSync = null,
|
|
|
2323
2334
|
async loginWithPassword ({ address, password, remember = false, label = '', proxyUrl = null } = {}) {
|
|
2324
2335
|
const url = proxyUrl || DEFAULT_PROXY
|
|
2325
2336
|
const { WebSocketProxyClient } = await import('@dotrino/proxy-client')
|
|
2326
|
-
const { loginWithPassword: entrar } = await import(
|
|
2337
|
+
const { loginWithPassword: entrar } = await import(/* @vite-ignore */ `${PILAR_VAULT}/login-client`)
|
|
2327
2338
|
const client = new WebSocketProxyClient({ url, enableWebRTC: false, autoReconnect: false })
|
|
2328
2339
|
await client.connect()
|
|
2329
2340
|
let entrada
|
package/vault/session.js
CHANGED
|
@@ -57,7 +57,7 @@ export const SESSION_SCOPES = Object.freeze(['id:whoami', 'vault:store'])
|
|
|
57
57
|
* blanca a propósito: si mañana alguien añade un alcance a `SESSION_SCOPES` sin pensarlo,
|
|
58
58
|
* esto sigue cortando lo que no puede pasar.
|
|
59
59
|
*/
|
|
60
|
-
export const SESSION_FORBIDDEN = Object.freeze(['secrets', 'admin', 'approve', 'sealer', 'passwords', 'unattended', 'replica'])
|
|
60
|
+
export const SESSION_FORBIDDEN = Object.freeze(['secrets', 'admin', 'approve', 'sealer', 'passwords', 'passkeys', 'unattended', 'replica'])
|
|
61
61
|
|
|
62
62
|
/** Qué capacidad del acta hace falta para conceder cada alcance de sesión. */
|
|
63
63
|
const SCOPE_NEEDS = Object.freeze({ 'id:whoami': null, 'vault:store': 'store' })
|