@swal/vault 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.
@@ -0,0 +1,109 @@
1
+ import { assertCloudSharesSafe, packWithoutShares, verifySealedPackHash } from './sealedPack.js';
2
+ export class R2StorageClient {
3
+ bucketName;
4
+ endpointUrl;
5
+ r2Binding;
6
+ appId;
7
+ instanceId;
8
+ memoryStore = new Map();
9
+ constructor(config = {}) {
10
+ this.bucketName = config.bucketName || `swal-${config.appId || 'app'}-vault`;
11
+ this.endpointUrl = config.endpointUrl || 'https://r2.swal.dev';
12
+ this.r2Binding = config.r2Binding ?? null;
13
+ this.appId = config.appId || 'my-app';
14
+ this.instanceId = config.instanceId || 'default';
15
+ }
16
+ getBucketName() { return this.bucketName; }
17
+ isCloudEnabled() { return !!this.r2Binding; }
18
+ r2KeyForPack(pack) {
19
+ const m = pack.metadata;
20
+ const app = m.appId || this.appId;
21
+ const inst = m.instanceId || this.instanceId;
22
+ const entity = m.entity || 'generic';
23
+ return `packs/${app}/${inst}/${entity}/${pack.content_hash}.json`;
24
+ }
25
+ /**
26
+ * Sube el pack SIN shares (frontera E2EE). Lanza si el pack trae >=2 shares: el llamador debe
27
+ * quitar los shares 1 y 2 y guardar el 3 aparte (ver `CloudShareStore`).
28
+ */
29
+ async uploadSealedPack(input) {
30
+ if (!input?.content_hash)
31
+ throw new Error('SealedPack sin content_hash');
32
+ assertCloudSharesSafe(input.shares?.length ?? 0);
33
+ const pack = packWithoutShares(input);
34
+ const ok = await verifySealedPackHash(pack);
35
+ if (!ok)
36
+ throw new Error('SealedPack content_hash mismatch');
37
+ const key = this.r2KeyForPack(pack);
38
+ // Cloud real si hay binding
39
+ if (this.r2Binding?.put) {
40
+ await this.r2Binding.put(key, JSON.stringify(pack), { httpMetadata: { contentType: 'application/json' } });
41
+ }
42
+ // Siempre memory replica (mesh fallback)
43
+ this.memoryStore.set(key, JSON.parse(JSON.stringify(pack)));
44
+ this.memoryStore.set(pack.content_hash, JSON.parse(JSON.stringify(pack)));
45
+ const url = `${this.endpointUrl}/${this.bucketName}/${key}`;
46
+ return { url, contentHash: pack.content_hash, key };
47
+ }
48
+ async getSealedPack(keyOrHash) {
49
+ // Intenta R2 real primero
50
+ if (this.r2Binding?.get) {
51
+ try {
52
+ const obj = await this.r2Binding.get(keyOrHash);
53
+ if (obj)
54
+ return JSON.parse(await obj.text());
55
+ // intenta como hash -> busca key generica
56
+ }
57
+ catch { }
58
+ }
59
+ const p = this.memoryStore.get(keyOrHash);
60
+ return p ? JSON.parse(JSON.stringify(p)) : null;
61
+ }
62
+ async deleteSealedPack(keyOrHash) {
63
+ if (this.r2Binding?.delete)
64
+ try {
65
+ await this.r2Binding.delete(keyOrHash);
66
+ }
67
+ catch { }
68
+ const pack = this.memoryStore.get(keyOrHash);
69
+ if (!pack)
70
+ return false;
71
+ this.memoryStore.delete(keyOrHash);
72
+ this.memoryStore.delete(pack.content_hash);
73
+ this.memoryStore.delete(this.r2KeyForPack(pack));
74
+ return true;
75
+ }
76
+ async verifyR2PackIntegrity(keyOrHash) {
77
+ const p = await this.getSealedPack(keyOrHash);
78
+ if (!p)
79
+ return false;
80
+ return verifySealedPackHash(p);
81
+ }
82
+ async listSealedPacks(prefix) {
83
+ if (this.r2Binding?.list) {
84
+ try {
85
+ const listed = await this.r2Binding.list({ prefix: prefix ?? `packs/${this.appId}/` });
86
+ return (listed.objects ?? []).map((o) => o.key);
87
+ }
88
+ catch { }
89
+ }
90
+ const keys = new Set();
91
+ for (const k of this.memoryStore.keys())
92
+ if (k.startsWith('packs/'))
93
+ keys.add(k);
94
+ const pref = prefix ?? `packs/${this.appId}/`;
95
+ return [...keys].filter((k) => k.startsWith(pref));
96
+ }
97
+ // Helper pay-per-use: calcula bytes para metering
98
+ async estimateStoredBytes() {
99
+ const keys = await this.listSealedPacks();
100
+ let total = 0;
101
+ for (const k of keys) {
102
+ const p = await this.getSealedPack(k);
103
+ if (p)
104
+ total += JSON.stringify(p).length;
105
+ }
106
+ return total;
107
+ }
108
+ }
109
+ //# sourceMappingURL=r2Client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"r2Client.js","sourceRoot":"","sources":["../src/r2Client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /** Version de formato del pack. Ausente = legado (sin AAD). 2 = metadatos ligados como AAD de AES-GCM. */
2
+ export declare const PACK_VERSION = 2;
3
+ /**
4
+ * Lista blanca de metadatos que pueden viajar EN CLARO junto al pack. Todo lo que no este aqui
5
+ * se rechaza al sellar (salvo `extraClearKeys` explicito): los metadatos no van cifrados.
6
+ */
7
+ export declare const CLEAR_METADATA_KEYS: readonly string[];
8
+ export interface DEKShare {
9
+ index: number;
10
+ value: string;
11
+ }
12
+ export interface SealedPackMetadata {
13
+ vehicleId?: string;
14
+ entityId?: string;
15
+ entity?: string;
16
+ appId?: string;
17
+ instanceId?: string;
18
+ timestamp: number;
19
+ recordCount?: number;
20
+ deviceId?: string;
21
+ [k: string]: unknown;
22
+ }
23
+ export interface SealedPack {
24
+ /** Version de formato. Ausente = legado sin AAD. */
25
+ v?: number;
26
+ id: string;
27
+ content_hash: string;
28
+ ciphertext: string;
29
+ iv: string;
30
+ tag: string;
31
+ shares: DEKShare[];
32
+ signature: string;
33
+ publicKey: string;
34
+ metadata: SealedPackMetadata;
35
+ chain: string;
36
+ chainId: number;
37
+ }
38
+ export declare function splitDEK(dek: Uint8Array): DEKShare[];
39
+ export declare function reconstructDEK(shares: DEKShare[]): Uint8Array;
40
+ /**
41
+ * @deprecated Usa `computeContentHashAsync` (WebCrypto). Se mantiene sincrono (SHA-256 JS puro)
42
+ * solo por compatibilidad; produce el mismo resultado.
43
+ */
44
+ export declare function computeContentHash(ciphertext: Uint8Array, metadata: SealedPackMetadata): string;
45
+ export declare function computeContentHashAsync(ciphertext: Uint8Array, metadata: SealedPackMetadata): Promise<string>;
46
+ /** Umbral de Shamir: shares necesarias para reconstruir. */
47
+ export declare const SHAMIR_THRESHOLD = 2;
48
+ /** Indice del unico share que puede residir en la nube. */
49
+ export declare const CLOUD_SHARE_INDEX = 3;
50
+ /** Devuelve una copia del pack SIN shares, apta para almacenar en la nube. */
51
+ export declare function packWithoutShares(pack: SealedPack): SealedPack;
52
+ /** El share que puede subirse a KV (x=3). `null` si no existe. */
53
+ export declare function cloudBoundShare(shares: DEKShare[]): DEKShare | null;
54
+ /**
55
+ * Guarda de la frontera: lanza si la nube acumularia el umbral o mas shares.
56
+ * Se usa antes de subir nada, para fallar cerrado en vez de filtrar la clave.
57
+ */
58
+ export declare function assertCloudSharesSafe(cloudShareCount: number): void;
59
+ /**
60
+ * Par de claves Ed25519. Acepta CryptoKeyPair (WebCrypto) o, por compat, el par de
61
+ * `KeyObject` de node (se detecta por duck-typing, sin depender de modulos de node).
62
+ */
63
+ export type SealedPackKeyPair = CryptoKeyPair | {
64
+ privateKey: {
65
+ export(o: {
66
+ type: 'pkcs8';
67
+ format: 'der';
68
+ }): Uint8Array;
69
+ };
70
+ publicKey: {
71
+ export(o: {
72
+ type: 'spki';
73
+ format: 'der';
74
+ }): Uint8Array;
75
+ };
76
+ };
77
+ export declare function createSealedPack(payload: Uint8Array, metadata: SealedPackMetadata, keyPair?: SealedPackKeyPair, options?: {
78
+ extraClearKeys?: string[];
79
+ }): Promise<SealedPack>;
80
+ export declare function unpackSealedPack(pack: SealedPack, shares: DEKShare[]): Promise<Uint8Array>;
81
+ export declare function verifySealedPackHash(pack: SealedPack): Promise<boolean>;
82
+ /** Verifica la firma Ed25519 del content_hash con la publicKey del pack. */
83
+ export declare function verifySealedPackSignature(pack: SealedPack): Promise<boolean>;
84
+ export declare function packMetadataForEntity(entity: string, id: string, appId: string, instanceId: string): SealedPackMetadata;
85
+ /**
86
+ * @deprecated Eliminado: la version anterior fabricaba un `walletAddress` falso (0x + prefijo de la
87
+ * publicKey) y emitia eventos con el. El anclaje real en Polygon aun no esta implementado.
88
+ */
89
+ export declare function registerOnPolygon(_pack: SealedPack, _bus?: unknown): never;
90
+ //# sourceMappingURL=sealedPack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sealedPack.d.ts","sourceRoot":"","sources":["../src/sealedPack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,233 @@
1
+ // sealedPack.ts — core reusable vault (antes en gara-g app-pwa)
2
+ // Extraído a cores/swal-vault para reuso en gara-g, hosteler-ia, flota, cualquier app SWAL.
3
+ // 100% cifrado: AES-256-GCM + Shamir 2-of-3 sobre DEK + SHA256 content_hash + Ed25519.
4
+ // Cloudflare nunca ve plaintext, solo ciphertext+shares+hash.
5
+ // Pay-per-use: costo solo si se sube a R2; mesh-only gratis (replica P2P en otros nodos gara-g).
6
+ import { bs, concatBytes, fromBase64, fromHex, randomBytes, randomInt, sha256, sha256Sync, toBase64, toHex, utf8, } from './bytes.js';
7
+ const subtle = () => globalThis.crypto.subtle;
8
+ // Cadena de anclaje por defecto (sin dependencia de @swal/econ-sdk; el vault es puro).
9
+ const _econChain = 'polygon';
10
+ const _econChainId = 137;
11
+ /** Version de formato del pack. Ausente = legado (sin AAD). 2 = metadatos ligados como AAD de AES-GCM. */
12
+ export const PACK_VERSION = 2;
13
+ /**
14
+ * Lista blanca de metadatos que pueden viajar EN CLARO junto al pack. Todo lo que no este aqui
15
+ * se rechaza al sellar (salvo `extraClearKeys` explicito): los metadatos no van cifrados.
16
+ */
17
+ export const CLEAR_METADATA_KEYS = [
18
+ 'vehicleId', 'entityId', 'entity', 'appId', 'instanceId', 'timestamp', 'recordCount', 'deviceId',
19
+ ];
20
+ function mod257(n) {
21
+ const r = n % 257;
22
+ return r < 0 ? r + 257 : r;
23
+ }
24
+ function modInverse257(n) {
25
+ const a = mod257(n);
26
+ if (a === 0)
27
+ throw new Error('Division by zero GF257');
28
+ let res = 1;
29
+ let base = a;
30
+ let exp = 255;
31
+ while (exp > 0) {
32
+ if (exp % 2 === 1)
33
+ res = (res * base) % 257;
34
+ base = (base * base) % 257;
35
+ exp = Math.floor(exp / 2);
36
+ }
37
+ return res;
38
+ }
39
+ export function splitDEK(dek) {
40
+ if (dek.length !== 32)
41
+ throw new Error('DEK 32 bytes');
42
+ const s1 = new Uint8Array(32);
43
+ const s2 = new Uint8Array(32);
44
+ const s3 = new Uint8Array(32);
45
+ for (let i = 0; i < 32; i++) {
46
+ const secret = dek[i];
47
+ let a1, y1, y2, y3;
48
+ do {
49
+ a1 = randomInt(1, 257);
50
+ y1 = mod257(secret + a1 * 1);
51
+ y2 = mod257(secret + a1 * 2);
52
+ y3 = mod257(secret + a1 * 3);
53
+ } while (y1 === 256 || y2 === 256 || y3 === 256);
54
+ s1[i] = y1;
55
+ s2[i] = y2;
56
+ s3[i] = y3;
57
+ }
58
+ return [
59
+ { index: 1, value: toBase64(s1) },
60
+ { index: 2, value: toBase64(s2) },
61
+ { index: 3, value: toBase64(s3) },
62
+ ];
63
+ }
64
+ export function reconstructDEK(shares) {
65
+ if (shares.length < 2)
66
+ throw new Error('At least 2 shares are required to reconstruct DEK');
67
+ const s1 = shares[0], s2 = shares[1];
68
+ const x1 = s1.index, x2 = s2.index;
69
+ if (x1 === x2)
70
+ throw new Error('shares duplicate x');
71
+ const y1 = fromBase64(s1.value);
72
+ const y2 = fromBase64(s2.value);
73
+ if (y1.length !== 32 || y2.length !== 32)
74
+ throw new Error('share length 32');
75
+ const num1 = mod257(-x2), den1 = mod257(x1 - x2), L1 = mod257(num1 * modInverse257(den1));
76
+ const num2 = mod257(-x1), den2 = mod257(x2 - x1), L2 = mod257(num2 * modInverse257(den2));
77
+ const dek = new Uint8Array(32);
78
+ for (let i = 0; i < 32; i++)
79
+ dek[i] = mod257(y1[i] * L1 + y2[i] * L2);
80
+ return dek;
81
+ }
82
+ function canonicalJson(v) {
83
+ if (Array.isArray(v))
84
+ return `[${v.map(canonicalJson).join(',')}]`;
85
+ if (v && typeof v === 'object') {
86
+ const o = v;
87
+ return `{${Object.keys(o).sort().filter((k) => o[k] !== undefined)
88
+ .map((k) => `${JSON.stringify(k)}:${canonicalJson(o[k])}`).join(',')}}`;
89
+ }
90
+ return JSON.stringify(v) ?? 'null';
91
+ }
92
+ /** AAD de AES-GCM (v2): los metadatos quedan autenticados; alterarlos rompe el descifrado. */
93
+ function metadataAad(metadata) {
94
+ return utf8(`swal-vault/v${PACK_VERSION}|${canonicalJson(metadata)}`);
95
+ }
96
+ function assertMetadataWhitelisted(metadata, extra) {
97
+ const allowed = new Set([...CLEAR_METADATA_KEYS, ...extra]);
98
+ for (const k of Object.keys(metadata)) {
99
+ if (!allowed.has(k)) {
100
+ throw new Error(`Metadato "${k}" no esta en la lista blanca de metadatos en claro (usa extraClearKeys si es intencional)`);
101
+ }
102
+ }
103
+ }
104
+ function contentHashInput(ciphertext, metadata) {
105
+ return concatBytes(ciphertext, utf8(JSON.stringify(metadata, Object.keys(metadata).sort())));
106
+ }
107
+ /**
108
+ * @deprecated Usa `computeContentHashAsync` (WebCrypto). Se mantiene sincrono (SHA-256 JS puro)
109
+ * solo por compatibilidad; produce el mismo resultado.
110
+ */
111
+ export function computeContentHash(ciphertext, metadata) {
112
+ return '0x' + toHex(sha256Sync(contentHashInput(ciphertext, metadata)));
113
+ }
114
+ export async function computeContentHashAsync(ciphertext, metadata) {
115
+ return '0x' + toHex(await sha256(contentHashInput(ciphertext, metadata)));
116
+ }
117
+ // ── Frontera de confianza: qué NO puede vivir en la nube ─────────────────────────
118
+ //
119
+ // El reparto es Shamir 2-de-3: con DOS shares cualquiera se reconstruye la DEK. Por tanto la nube
120
+ // (R2 + D1 + KV) **nunca** puede acumular 2 shares, o el operador podria leer los datos y la
121
+ // promesa "el operador no puede leer" seria falsa.
122
+ //
123
+ // Reparto correcto:
124
+ // * share x=1 -> DISPOSITIVO (nunca se sube)
125
+ // * share x=2 -> RECUPERACION (nunca se sube; se entrega al usuario en el alta)
126
+ // * share x=3 -> KV (unico share que la nube puede tener)
127
+ //
128
+ // Asi R2+D1+KV juntos suman 1 share y no alcanzan el umbral.
129
+ /** Umbral de Shamir: shares necesarias para reconstruir. */
130
+ export const SHAMIR_THRESHOLD = 2;
131
+ /** Indice del unico share que puede residir en la nube. */
132
+ export const CLOUD_SHARE_INDEX = 3;
133
+ /** Devuelve una copia del pack SIN shares, apta para almacenar en la nube. */
134
+ export function packWithoutShares(pack) {
135
+ return { ...pack, shares: [] };
136
+ }
137
+ /** El share que puede subirse a KV (x=3). `null` si no existe. */
138
+ export function cloudBoundShare(shares) {
139
+ return shares.find((s) => s.index === CLOUD_SHARE_INDEX) ?? null;
140
+ }
141
+ /**
142
+ * Guarda de la frontera: lanza si la nube acumularia el umbral o mas shares.
143
+ * Se usa antes de subir nada, para fallar cerrado en vez de filtrar la clave.
144
+ */
145
+ export function assertCloudSharesSafe(cloudShareCount) {
146
+ if (cloudShareCount >= SHAMIR_THRESHOLD) {
147
+ throw new Error(`E2EE: la nube no puede acumular ${cloudShareCount} shares (umbral ${SHAMIR_THRESHOLD}). ` +
148
+ 'Deja en el dispositivo los shares 1 y 2 y sube solo el 3.');
149
+ }
150
+ }
151
+ async function resolveKeyPair(kp) {
152
+ if (!kp) {
153
+ const pair = (await subtle().generateKey({ name: 'Ed25519' }, true, ['sign', 'verify']));
154
+ return { priv: pair.privateKey, pubSpki: new Uint8Array(await subtle().exportKey('spki', pair.publicKey)) };
155
+ }
156
+ const priv = kp.privateKey;
157
+ if (typeof priv.export === 'function') {
158
+ const pkcs8 = new Uint8Array(priv.export({ type: 'pkcs8', format: 'der' }));
159
+ const pubSpki = new Uint8Array(kp.publicKey.export({ type: 'spki', format: 'der' }));
160
+ return { priv: await subtle().importKey('pkcs8', bs(pkcs8), { name: 'Ed25519' }, false, ['sign']), pubSpki };
161
+ }
162
+ return { priv: priv, pubSpki: new Uint8Array(await subtle().exportKey('spki', kp.publicKey)) };
163
+ }
164
+ async function aesKey(dek, usage) {
165
+ return subtle().importKey('raw', bs(dek), { name: 'AES-GCM' }, false, [usage]);
166
+ }
167
+ export async function createSealedPack(payload, metadata, keyPair, options = {}) {
168
+ assertMetadataWhitelisted(metadata, options.extraClearKeys ?? []);
169
+ const dek = randomBytes(32);
170
+ const iv = randomBytes(12);
171
+ // WebCrypto devuelve ciphertext||tag(16); se separan para mantener el formato del pack.
172
+ const sealed = new Uint8Array(await subtle().encrypt({ name: 'AES-GCM', iv: bs(iv), tagLength: 128, additionalData: bs(metadataAad(metadata)) }, await aesKey(dek, 'encrypt'), bs(payload)));
173
+ const ct = sealed.subarray(0, sealed.length - 16);
174
+ const tag = sealed.subarray(sealed.length - 16);
175
+ const shares = splitDEK(dek);
176
+ const contentHash = await computeContentHashAsync(ct, metadata);
177
+ const { priv, pubSpki } = await resolveKeyPair(keyPair);
178
+ const sig = new Uint8Array(await subtle().sign({ name: 'Ed25519' }, priv, bs(utf8(contentHash))));
179
+ return {
180
+ v: PACK_VERSION,
181
+ id: `pack-${globalThis.crypto.randomUUID()}`,
182
+ content_hash: contentHash,
183
+ ciphertext: toBase64(ct),
184
+ iv: toBase64(iv),
185
+ tag: toBase64(tag),
186
+ shares,
187
+ signature: toHex(sig),
188
+ publicKey: toHex(pubSpki),
189
+ metadata,
190
+ chain: _econChain,
191
+ chainId: _econChainId,
192
+ };
193
+ }
194
+ export async function unpackSealedPack(pack, shares) {
195
+ const dek = reconstructDEK(shares);
196
+ const ct = fromBase64(pack.ciphertext);
197
+ const iv = fromBase64(pack.iv);
198
+ const tag = fromBase64(pack.tag);
199
+ if (pack.v !== undefined && pack.v !== PACK_VERSION)
200
+ throw new Error(`Version de pack no soportada: ${pack.v}`);
201
+ // Legado (sin `v`): sin AAD. Un pack v2 al que se le quita `v` falla por tag al no coincidir el AAD.
202
+ const params = { name: 'AES-GCM', iv: bs(iv), tagLength: 128 };
203
+ if (pack.v === PACK_VERSION)
204
+ params.additionalData = bs(metadataAad(pack.metadata));
205
+ const dec = await subtle().decrypt(params, await aesKey(dek, 'decrypt'), bs(concatBytes(ct, tag)));
206
+ return new Uint8Array(dec);
207
+ }
208
+ export async function verifySealedPackHash(pack) {
209
+ const exp = await computeContentHashAsync(fromBase64(pack.ciphertext), pack.metadata);
210
+ return exp.toLowerCase() === pack.content_hash.toLowerCase();
211
+ }
212
+ /** Verifica la firma Ed25519 del content_hash con la publicKey del pack. */
213
+ export async function verifySealedPackSignature(pack) {
214
+ try {
215
+ const key = await subtle().importKey('spki', bs(fromHex(pack.publicKey)), { name: 'Ed25519' }, false, ['verify']);
216
+ return await subtle().verify({ name: 'Ed25519' }, key, bs(fromHex(pack.signature)), bs(utf8(pack.content_hash)));
217
+ }
218
+ catch {
219
+ return false;
220
+ }
221
+ }
222
+ // Helper generico para cualquier entity (no solo vehicle)
223
+ export function packMetadataForEntity(entity, id, appId, instanceId) {
224
+ return { entity, entityId: id, appId, instanceId, timestamp: Date.now() };
225
+ }
226
+ /**
227
+ * @deprecated Eliminado: la version anterior fabricaba un `walletAddress` falso (0x + prefijo de la
228
+ * publicKey) y emitia eventos con el. El anclaje real en Polygon aun no esta implementado.
229
+ */
230
+ export function registerOnPolygon(_pack, _bus) {
231
+ throw new Error('registerOnPolygon: not implemented');
232
+ }
233
+ //# sourceMappingURL=sealedPack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sealedPack.js","sourceRoot":"","sources":["../src/sealedPack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { type DEKShare } from '../sealedPack.js';
2
+ export declare const MIN_PBKDF2_ITERATIONS = 310000;
3
+ export declare const DEFAULT_PBKDF2_ITERATIONS = 600000;
4
+ export declare class VaultError extends Error {
5
+ code: 'LOCKED' | 'BAD_KEY' | 'BAD_FORMAT' | 'NO_PASSKEY' | 'SHARE_ALREADY_SHOWN' | 'NO_MESH_KEY' | 'BAD_PARAMS';
6
+ constructor(code: 'LOCKED' | 'BAD_KEY' | 'BAD_FORMAT' | 'NO_PASSKEY' | 'SHARE_ALREADY_SHOWN' | 'NO_MESH_KEY' | 'BAD_PARAMS', message: string);
7
+ }
8
+ /** Proveedor de salida PRF de un passkey (inyectable; por defecto usa WebAuthn). */
9
+ export interface PasskeyPrfProvider {
10
+ /** Devuelve >=32 bytes deterministas para `salt`, o lanza si el autenticador no soporta PRF. */
11
+ getPrfOutput(salt: Uint8Array): Promise<Uint8Array>;
12
+ }
13
+ export interface VaultClientOptions {
14
+ storage: 'idb';
15
+ dbName?: string;
16
+ pbkdf2Iterations?: number;
17
+ passkey?: PasskeyPrfProvider;
18
+ /** Para WebAuthn por defecto. */
19
+ rpId?: string;
20
+ }
21
+ export interface DeviceIdentity {
22
+ deviceId: string;
23
+ /** SPKI en base64url. */
24
+ publicKey: string;
25
+ publicKeyJwk: JsonWebKey;
26
+ }
27
+ export type UnlockOptions = {
28
+ passphrase: string;
29
+ } | {
30
+ passkey: true;
31
+ };
32
+ export interface MeshKey {
33
+ /** Bytes crudos (32). Evita retenerlos mas de lo necesario. */
34
+ raw: Uint8Array;
35
+ /** CryptoKey AES-GCM no extraible, derivada de los mismos bytes. */
36
+ key: CryptoKey;
37
+ }
38
+ export interface VaultClient {
39
+ getDeviceIdentity(): Promise<DeviceIdentity>;
40
+ sign(data: Uint8Array): Promise<Uint8Array>;
41
+ verify(publicKeyJwk: JsonWebKey, data: Uint8Array, signature: Uint8Array): Promise<boolean>;
42
+ /** Disponibilidad probable de passkeys (la confirmacion de PRF solo ocurre al usarlo). */
43
+ isPasskeyPrfAvailable(): boolean;
44
+ /** Deriva la KEK (passphrase o passkey PRF) y la mantiene en memoria. */
45
+ unlock(opts: UnlockOptions): Promise<void>;
46
+ /** Como unlock, pero con passkey si hay soporte; si no, usa passphrase. */
47
+ unlockPreferPasskey(passphrase: string): Promise<'passkey' | 'passphrase'>;
48
+ lock(): void;
49
+ isUnlocked(): boolean;
50
+ wrapKey(raw32: Uint8Array, kek?: CryptoKey): Promise<string>;
51
+ unwrapKey(wrapped: string, kek?: CryptoKey): Promise<Uint8Array>;
52
+ getOrCreateMeshKey(): Promise<MeshKey>;
53
+ /** Devuelve el share de recuperacion (x=2) UNA sola vez; luego lanza SHARE_ALREADY_SHOWN. */
54
+ exportRecoveryShare(): Promise<{
55
+ recoveryShare: DEKShare;
56
+ cloudShare: DEKShare;
57
+ }>;
58
+ /** Reconstruye la meshKey con el share de recuperacion + el share del dispositivo. */
59
+ recoverMeshKey(recoveryShare: DEKShare): Promise<Uint8Array>;
60
+ /** Recupera la meshKey y la re-envuelve con una nueva passphrase. */
61
+ resetPassphrase(recoveryShare: DEKShare, newPassphrase: string): Promise<void>;
62
+ }
63
+ export declare function createVaultClient(opts: VaultClientOptions): VaultClient;
64
+ //# sourceMappingURL=vault-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault-client.d.ts","sourceRoot":"","sources":["../../src/web/vault-client.ts"],"names":[],"mappings":"AAYA,OAAO,EAA4B,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE3E,eAAO,MAAM,qBAAqB,SAAU,CAAC;AAC7C,eAAO,MAAM,yBAAyB,SAAU,CAAC;AAEjD,qBAAa,UAAW,SAAQ,KAAK;IAE1B,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,YAAY,GAAG,YAAY,GAAG,qBAAqB,GAAG,aAAa,GAAG,YAAY;IADxH,YACS,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,YAAY,GAAG,YAAY,GAAG,qBAAqB,GAAG,aAAa,GAAG,YAAY,EACtH,OAAO,EAAE,MAAM,EAIhB;CACF;AAED,oFAAoF;AACpF,MAAM,WAAW,kBAAkB;IACjC,gGAAgG;IAChG,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,UAAU,CAAC;CAC1B;AAED,MAAM,MAAM,aAAa,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,CAAC;AAEvE,MAAM,WAAW,OAAO;IACtB,+DAA+D;IAC/D,GAAG,EAAE,UAAU,CAAC;IAChB,oEAAoE;IACpE,GAAG,EAAE,SAAS,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7C,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5C,MAAM,CAAC,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE5F,0FAA0F;IAC1F,qBAAqB,IAAI,OAAO,CAAC;IACjC,yEAAyE;IACzE,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,2EAA2E;IAC3E,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC,CAAC;IAC3E,IAAI,IAAI,IAAI,CAAC;IACb,UAAU,IAAI,OAAO,CAAC;IAEtB,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAEjE,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,6FAA6F;IAC7F,mBAAmB,IAAI,OAAO,CAAC;QAAE,aAAa,EAAE,QAAQ,CAAC;QAAC,UAAU,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC;IAClF,sFAAsF;IACtF,cAAc,CAAC,aAAa,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7D,qEAAqE;IACrE,eAAe,CAAC,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChF;AAyHD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,WAAW,CAgJvE"}