@dotrino/vaultd 0.159.0 → 0.160.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/lib/src/core/libVersion.js +1 -1
- package/lib/src/core/passwords.js +0 -1
- package/lib/src/core/vault.js +4 -4
- package/package.json +4 -4
- package/src/ctl.js +4 -7
- package/src/service.js +10 -0
- package/src/tui/app.js +3 -2
- package/src/tui/i18n.js +0 -4
package/lib/src/core/vault.js
CHANGED
|
@@ -311,14 +311,14 @@ export async function startVault ({ platform, proxyUrl, log = console.log, onEnr
|
|
|
311
311
|
* eso se filtran explícitamente aquí, que es donde se construye la lista, y no en quien la
|
|
312
312
|
* consume (`sealed-passwords.md` §2.1).
|
|
313
313
|
*
|
|
314
|
-
* `main`
|
|
315
|
-
*
|
|
314
|
+
* `main` y `passkeys` (la generación aparte de la privada de una passkey) son los MISMOS:
|
|
315
|
+
* los aparatos con `contraseñas`. Hubo un permiso `passkeys` aparte y se fusionó en ese
|
|
316
|
+
* (dueño, 2026-10-16: «realmente deberían ser uno solo»); `kind` se queda por el formato. Un miembro sin llave de cifrado no puede recibir nada: se
|
|
316
317
|
* queda fuera y se ve en `incompleteMembers`.
|
|
317
318
|
*/
|
|
318
319
|
const noEsLaBoveda = (pub) => pub !== master && pub !== commKey.pub()
|
|
319
|
-
const passwordRecipients = (
|
|
320
|
+
const passwordRecipients = (_kind = 'main') => (actaCache?.members || [])
|
|
320
321
|
.filter((m) => m.encPub && noEsLaBoveda(m.pub) && Acta.memberCan(actaCache, m.pub, 'passwords'))
|
|
321
|
-
.filter((m) => kind !== 'passkeys' || Acta.memberCan(actaCache, m.pub, 'passkeys'))
|
|
322
322
|
.map((m) => ({ pub: m.pub, encPub: m.encPub }))
|
|
323
323
|
|
|
324
324
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dotrino/vaultd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.160.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Certificador personal de Dotrino: daemon headless que custodia la clave maestra y delega capacidades a tus dispositivos por el proxy. Tu CA propia.",
|
|
6
6
|
"bin": {
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@dotrino/compat": "0.4.0",
|
|
25
|
-
"@dotrino/identity": "^0.
|
|
25
|
+
"@dotrino/identity": "^0.118.0",
|
|
26
26
|
"@dotrino/opaque": "0.1.0",
|
|
27
|
-
"@dotrino/passmanager": "0.
|
|
27
|
+
"@dotrino/passmanager": "0.18.1",
|
|
28
28
|
"@dotrino/proxy-client": "^0.36.1",
|
|
29
|
-
"@dotrino/roadmap": "0.4.
|
|
29
|
+
"@dotrino/roadmap": "0.4.20",
|
|
30
30
|
"@dotrino/store": "0.11.0",
|
|
31
31
|
"@dotrino/update": "0.9.0",
|
|
32
32
|
"sigstore": "5.0.0",
|
package/src/ctl.js
CHANGED
|
@@ -785,12 +785,9 @@ const CAP_BY_WORD = {
|
|
|
785
785
|
// `contraseñas`: el gestor (la extensión, la app del teléfono) puede PEDIR
|
|
786
786
|
// credenciales de a una. Se acepta con y sin tilde: nadie escribe la ñ en una CLI.
|
|
787
787
|
contrasenas: 'passwords', 'contraseñas': 'passwords',
|
|
788
|
-
// `
|
|
789
|
-
//
|
|
790
|
-
|
|
791
|
-
// (`dotrino-passmanager/docs/sealed-passwords.md` §2.8). Sin `contraseñas` no
|
|
792
|
-
// significa nada: la passkey vive en una entrada de contraseñas.
|
|
793
|
-
passkeys: 'passkeys', llaves: 'passkeys',
|
|
788
|
+
// `contraseñas` cubre también las PASSKEYS: hubo un `passkeys` aparte y se fusionó en este
|
|
789
|
+
// (dueño, 2026-10-16). Quien escriba la palabra vieja recibe lo que hoy significa.
|
|
790
|
+
passkeys: 'passwords',
|
|
794
791
|
// `desatendido`: RECIBE CLAVES PRIVADAS SIN QUE NADIE APRUEBE. Sin él, la bóveda no
|
|
795
792
|
// entrega nada hasta que un aparato con `aprueba` lo firme (una vez por arranque).
|
|
796
793
|
//
|
|
@@ -2340,7 +2337,7 @@ function help () {
|
|
|
2340
2337
|
pair --quiet escupe SOLO la invitación (una línea) y termina: sin QR y sin
|
|
2341
2338
|
esperar. Para desplegar (un contenedor no mira un QR en pantalla)
|
|
2342
2339
|
pair --scope <lista> los PERMISOS con los que entra, cualquiera de los de caps (firma,lee,guarda,administra,
|
|
2343
|
-
aprueba,contrasenas,
|
|
2340
|
+
aprueba,contrasenas,sella,desatendido,replica) y secrets:<ns>. Sin esto: firma,lee,guarda.
|
|
2344
2341
|
Entra al acta ya con ellos. Se combina con --service: --service eco --scope firma
|
|
2345
2342
|
secret set <ns> <CLAVE> <valor> variable del scope <ns>: la comparten TODOS los
|
|
2346
2343
|
aparatos del perfil que sirven ese namespace
|
package/src/service.js
CHANGED
|
@@ -40,6 +40,16 @@ export function daemonCommand () {
|
|
|
40
40
|
return { cmd: process.execPath, args: [path.join(here, '..', 'bin', 'dotrino-vaultd.js')] }
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* La orden para volver a correr ESTA misma invocación (la TUI tras actualizar). En el binario
|
|
45
|
+
* (SEA) `process.argv[1]` es otra vez el ejecutable, así que `argv.slice(1)` le pasaba su
|
|
46
|
+
* propia ruta como primer argumento: `sea-entry.js` no lo reconocía y arrancaba el DAEMON en
|
|
47
|
+
* la terminal en vez de la TUI (2026-10-16, al pasar a 0.159.0).
|
|
48
|
+
*/
|
|
49
|
+
export function selfCommand (argv = process.argv, sea = !!globalThis.__DOTRINO_SEA__) {
|
|
50
|
+
return { cmd: process.execPath, args: argv.slice(sea ? 2 : 1) }
|
|
51
|
+
}
|
|
52
|
+
|
|
43
53
|
/** Dónde escribe el daemon suelto lo que diría por consola. */
|
|
44
54
|
export const daemonLogFile = () => path.join(dataDir(), 'daemon.log')
|
|
45
55
|
|
package/src/tui/app.js
CHANGED
|
@@ -647,7 +647,7 @@ function pairModeRows (st, t) {
|
|
|
647
647
|
* esté nombrado se añade al final: un permiso puede salir en mal sitio, nunca desaparecer.
|
|
648
648
|
* `test/tui-permisos.test.mjs` exige además que todos tengan nombre en los dos idiomas.
|
|
649
649
|
*/
|
|
650
|
-
const ORDEN = ['sign', 'store', 'read', 'admin', 'approve', 'passwords', '
|
|
650
|
+
const ORDEN = ['sign', 'store', 'read', 'admin', 'approve', 'passwords', 'sealer', 'unattended', 'replica']
|
|
651
651
|
const CAPS_ORDER = [...ORDEN.filter((c) => DEVICE_CAPS.includes(c)),
|
|
652
652
|
...DEVICE_CAPS.filter((c) => !ORDEN.includes(c))]
|
|
653
653
|
|
|
@@ -3006,7 +3006,8 @@ export async function runTui () {
|
|
|
3006
3006
|
// TRAS ACTUALIZAR Y REINICIAR, esta pantalla también se vuelve a abrir: es el binario
|
|
3007
3007
|
// anterior el que sigue en memoria. Se lanza el nuevo en esta misma terminal.
|
|
3008
3008
|
if (st.relaunch) {
|
|
3009
|
-
const
|
|
3009
|
+
const { cmd, args } = service.selfCommand()
|
|
3010
|
+
const r = spawnSync(cmd, args, { stdio: 'inherit' })
|
|
3010
3011
|
process.exit(r.status ?? 0)
|
|
3011
3012
|
}
|
|
3012
3013
|
}
|
package/src/tui/i18n.js
CHANGED
|
@@ -123,7 +123,6 @@ const es = {
|
|
|
123
123
|
read: 'lee',
|
|
124
124
|
admin: 'administra',
|
|
125
125
|
passwords: 'contrasenas',
|
|
126
|
-
passkeys: 'passkeys',
|
|
127
126
|
approve: 'aprueba',
|
|
128
127
|
sealer: 'sella',
|
|
129
128
|
unattended: 'desatendido',
|
|
@@ -140,7 +139,6 @@ const es = {
|
|
|
140
139
|
passwords: 'pedir una contraseña por sitio, nunca la lista entera',
|
|
141
140
|
// Una passkey copiada sirve hasta que la borres en cada sitio: de una contraseña, al
|
|
142
141
|
// menos, se puede cambiar. Por eso es una decisión aparte.
|
|
143
|
-
passkeys: 'abrir además las passkeys guardadas, que son llaves y no se pueden cambiar. Sin «contrasenas» no hace nada',
|
|
144
142
|
approve: 'dar el visto bueno cuando otro aparato pide claves privadas',
|
|
145
143
|
// Sellar solo significa algo en un aparato que HAGA de bóveda (otra máquina con el
|
|
146
144
|
// daemon, o un navegador que se puso de bóveda). En un teléfono normal se concede y no
|
|
@@ -619,7 +617,6 @@ const en = {
|
|
|
619
617
|
read: 'read',
|
|
620
618
|
admin: 'admin',
|
|
621
619
|
passwords: 'passwords',
|
|
622
|
-
passkeys: 'passkeys',
|
|
623
620
|
approve: 'approve',
|
|
624
621
|
sealer: 'sealer',
|
|
625
622
|
unattended: 'unattended',
|
|
@@ -632,7 +629,6 @@ const en = {
|
|
|
632
629
|
read: 'see what you saved',
|
|
633
630
|
admin: 'connect and remove devices from there, without coming here. It cannot change permissions',
|
|
634
631
|
passwords: 'ask for one password per site, never the whole list',
|
|
635
|
-
passkeys: 'also open saved passkeys, which are keys and cannot be changed. Without «passwords» it does nothing',
|
|
636
632
|
approve: 'give the go-ahead when another device asks for private keys',
|
|
637
633
|
sealer: 'admit devices and change permissions on its own when this vault is away. Only useful on another VAULT',
|
|
638
634
|
unattended: 'take private keys without asking you. Off, it must be approved from a device with «approve» every time it starts',
|