@tgoliveira/vault-core 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 (138) hide show
  1. package/API_REFERENCE.md +36 -0
  2. package/ARCHITECTURE.md +32 -0
  3. package/LICENSE +21 -0
  4. package/MIGRATION_FROM_LIQSENSE.md +42 -0
  5. package/PASSKEY_PRF_ENVELOPES.md +9 -0
  6. package/PASSWORD_ENVELOPES.md +7 -0
  7. package/README.md +78 -0
  8. package/RECOVERY_PHRASE.md +9 -0
  9. package/SECURITY.md +31 -0
  10. package/dist/browser.d.ts +11 -0
  11. package/dist/browser.d.ts.map +1 -0
  12. package/dist/browser.js +71 -0
  13. package/dist/browser.js.map +1 -0
  14. package/dist/constants.d.ts +5 -0
  15. package/dist/constants.d.ts.map +1 -0
  16. package/dist/constants.js +5 -0
  17. package/dist/constants.js.map +1 -0
  18. package/dist/crypto/aad.d.ts +4 -0
  19. package/dist/crypto/aad.d.ts.map +1 -0
  20. package/dist/crypto/aad.js +23 -0
  21. package/dist/crypto/aad.js.map +1 -0
  22. package/dist/crypto/aes-gcm.d.ts +9 -0
  23. package/dist/crypto/aes-gcm.d.ts.map +1 -0
  24. package/dist/crypto/aes-gcm.js +58 -0
  25. package/dist/crypto/aes-gcm.js.map +1 -0
  26. package/dist/crypto/encoding.d.ts +6 -0
  27. package/dist/crypto/encoding.d.ts.map +1 -0
  28. package/dist/crypto/encoding.js +27 -0
  29. package/dist/crypto/encoding.js.map +1 -0
  30. package/dist/crypto/random.d.ts +2 -0
  31. package/dist/crypto/random.d.ts.map +1 -0
  32. package/dist/crypto/random.js +4 -0
  33. package/dist/crypto/random.js.map +1 -0
  34. package/dist/crypto/serialization.d.ts +3 -0
  35. package/dist/crypto/serialization.d.ts.map +1 -0
  36. package/dist/crypto/serialization.js +7 -0
  37. package/dist/crypto/serialization.js.map +1 -0
  38. package/dist/envelopes/passkey-prf.d.ts +21 -0
  39. package/dist/envelopes/passkey-prf.d.ts.map +1 -0
  40. package/dist/envelopes/passkey-prf.js +78 -0
  41. package/dist/envelopes/passkey-prf.js.map +1 -0
  42. package/dist/envelopes/password.d.ts +20 -0
  43. package/dist/envelopes/password.d.ts.map +1 -0
  44. package/dist/envelopes/password.js +41 -0
  45. package/dist/envelopes/password.js.map +1 -0
  46. package/dist/envelopes/recovery.d.ts +46 -0
  47. package/dist/envelopes/recovery.d.ts.map +1 -0
  48. package/dist/envelopes/recovery.js +167 -0
  49. package/dist/envelopes/recovery.js.map +1 -0
  50. package/dist/errors/vault-errors.d.ts +20 -0
  51. package/dist/errors/vault-errors.d.ts.map +1 -0
  52. package/dist/errors/vault-errors.js +37 -0
  53. package/dist/errors/vault-errors.js.map +1 -0
  54. package/dist/index.d.ts +21 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +20 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/kdf/argon2id.d.ts +24 -0
  59. package/dist/kdf/argon2id.d.ts.map +1 -0
  60. package/dist/kdf/argon2id.js +57 -0
  61. package/dist/kdf/argon2id.js.map +1 -0
  62. package/dist/kdf/params.d.ts +9 -0
  63. package/dist/kdf/params.d.ts.map +1 -0
  64. package/dist/kdf/params.js +8 -0
  65. package/dist/kdf/params.js.map +1 -0
  66. package/dist/keys/user-vault-key.d.ts +7 -0
  67. package/dist/keys/user-vault-key.d.ts.map +1 -0
  68. package/dist/keys/user-vault-key.js +15 -0
  69. package/dist/keys/user-vault-key.js.map +1 -0
  70. package/dist/payload/encrypted-payload.d.ts +5 -0
  71. package/dist/payload/encrypted-payload.d.ts.map +1 -0
  72. package/dist/payload/encrypted-payload.js +14 -0
  73. package/dist/payload/encrypted-payload.js.map +1 -0
  74. package/dist/profile.d.ts +21 -0
  75. package/dist/profile.d.ts.map +1 -0
  76. package/dist/profile.js +9 -0
  77. package/dist/profile.js.map +1 -0
  78. package/dist/react/index.d.ts +6 -0
  79. package/dist/react/index.d.ts.map +1 -0
  80. package/dist/react/index.js +6 -0
  81. package/dist/react/index.js.map +1 -0
  82. package/dist/react/session/use-vault-session.d.ts +11 -0
  83. package/dist/react/session/use-vault-session.d.ts.map +1 -0
  84. package/dist/react/session/use-vault-session.js +29 -0
  85. package/dist/react/session/use-vault-session.js.map +1 -0
  86. package/dist/react/session/use-vault-unlocked.d.ts +3 -0
  87. package/dist/react/session/use-vault-unlocked.d.ts.map +1 -0
  88. package/dist/react/session/use-vault-unlocked.js +9 -0
  89. package/dist/react/session/use-vault-unlocked.js.map +1 -0
  90. package/dist/react/session/vault-session-provider.d.ts +9 -0
  91. package/dist/react/session/vault-session-provider.d.ts.map +1 -0
  92. package/dist/react/session/vault-session-provider.js +16 -0
  93. package/dist/react/session/vault-session-provider.js.map +1 -0
  94. package/dist/react/status/resolve-vault-client-status.d.ts +8 -0
  95. package/dist/react/status/resolve-vault-client-status.d.ts.map +1 -0
  96. package/dist/react/status/resolve-vault-client-status.js +13 -0
  97. package/dist/react/status/resolve-vault-client-status.js.map +1 -0
  98. package/dist/react/status/use-vault-client-status.d.ts +3 -0
  99. package/dist/react/status/use-vault-client-status.d.ts.map +1 -0
  100. package/dist/react/status/use-vault-client-status.js +8 -0
  101. package/dist/react/status/use-vault-client-status.js.map +1 -0
  102. package/dist/recovery/kit.d.ts +16 -0
  103. package/dist/recovery/kit.d.ts.map +1 -0
  104. package/dist/recovery/kit.js +33 -0
  105. package/dist/recovery/kit.js.map +1 -0
  106. package/dist/session/auto-lock.d.ts +18 -0
  107. package/dist/session/auto-lock.d.ts.map +1 -0
  108. package/dist/session/auto-lock.js +86 -0
  109. package/dist/session/auto-lock.js.map +1 -0
  110. package/dist/session/memory-session.d.ts +8 -0
  111. package/dist/session/memory-session.d.ts.map +1 -0
  112. package/dist/session/memory-session.js +20 -0
  113. package/dist/session/memory-session.js.map +1 -0
  114. package/dist/testing/fixtures/liqsense-compat.d.ts +32 -0
  115. package/dist/testing/fixtures/liqsense-compat.d.ts.map +1 -0
  116. package/dist/testing/fixtures/liqsense-compat.js +31 -0
  117. package/dist/testing/fixtures/liqsense-compat.js.map +1 -0
  118. package/dist/testing/no-plaintext.d.ts +2 -0
  119. package/dist/testing/no-plaintext.d.ts.map +1 -0
  120. package/dist/testing/no-plaintext.js +2 -0
  121. package/dist/testing/no-plaintext.js.map +1 -0
  122. package/dist/testing.d.ts +2 -0
  123. package/dist/testing.d.ts.map +1 -0
  124. package/dist/testing.js +2 -0
  125. package/dist/testing.js.map +1 -0
  126. package/dist/validation/aad-assert.d.ts +5 -0
  127. package/dist/validation/aad-assert.d.ts.map +1 -0
  128. package/dist/validation/aad-assert.js +29 -0
  129. package/dist/validation/aad-assert.js.map +1 -0
  130. package/dist/validation/plaintext-reject.d.ts +23 -0
  131. package/dist/validation/plaintext-reject.d.ts.map +1 -0
  132. package/dist/validation/plaintext-reject.js +75 -0
  133. package/dist/validation/plaintext-reject.js.map +1 -0
  134. package/dist/validation/schemas.d.ts +203 -0
  135. package/dist/validation/schemas.d.ts.map +1 -0
  136. package/dist/validation/schemas.js +39 -0
  137. package/dist/validation/schemas.js.map +1 -0
  138. package/package.json +100 -0
@@ -0,0 +1,36 @@
1
+ # API Reference
2
+
3
+ See TypeScript exports from:
4
+
5
+ - `@tgoliveira/vault-core`
6
+ - `@tgoliveira/vault-core/browser`
7
+ - `@tgoliveira/vault-core/testing`
8
+ - `@tgoliveira/vault-core/react`
9
+
10
+ ## Core types
11
+
12
+ - `VaultCryptoProfile`, `VaultCryptoVersion`
13
+ - `EncryptedVaultPayload`, `VaultEnvelope`, `PasswordEnvelope`, `RecoveryPhraseEnvelope`, `PasskeyPrfEnvelope`
14
+ - `RecoveryPhraseWordCount` (`12 | 24`)
15
+ - `VaultUnlockResult<TPayload>`, `VaultCoreError`
16
+
17
+ ## Core functions
18
+
19
+ - `createUserVaultKey()`
20
+ - `encryptVaultPayload<T>(payload, key, scope, profile)`
21
+ - `decryptVaultPayload<T>(encrypted, key)`
22
+ - `createPasswordEnvelope` / `unlockWithPasswordEnvelope`
23
+ - `createRecoveryPhrase` / `createRecoveryEnvelope` / `unlockWithRecoveryEnvelope`
24
+ - `createPasskeyPrfEnvelope` / `unlockWithPasskeyPrfEnvelope`
25
+ - `createRecoveryKitText(...)`
26
+ - `assertVaultKeyAad` / `assertVaultPayloadAad`
27
+ - `assertNoVaultPlaintextFields` / `validateNoPlaintextLeak`
28
+
29
+ Deprecated aliases (`wrapVaultKeyForPassword`, etc.) remain for migration.
30
+
31
+ ## React entry (`@tgoliveira/vault-core/react`)
32
+
33
+ - `useVaultUnlocked()`, `useVaultLockState()`
34
+ - `useVaultSession()`, `VaultSessionProvider`
35
+ - `resolveVaultClientStatus()`, `useVaultClientStatus()`
36
+ - `VaultClientStatus`, `VaultServerStatusSnapshot`
@@ -0,0 +1,32 @@
1
+ # Vault Core Architecture
2
+
3
+ ## User Vault Key (UVK)
4
+
5
+ 256-bit AES-GCM key generated client-side. Wrapped by envelopes; encrypts app payload JSON.
6
+
7
+ ## Envelopes
8
+
9
+ | Method | KDF | Wraps |
10
+ | --- | --- | --- |
11
+ | Password | Argon2id | UVK |
12
+ | Recovery phrase | Argon2id (BIP39 normalized phrase) | UVK |
13
+ | Passkey PRF | PRF output → AES key | UVK |
14
+
15
+ Envelope AAD field: `vault_key` with app `aadContextEnvelope`.
16
+
17
+ ## Encrypted payload
18
+
19
+ Generic JSON encrypted under UVK. AAD field: `vault_payload` with app `aadContextVault`.
20
+
21
+ Format: `enc-v1` / `AES-GCM` / `kdf-v1`.
22
+
23
+ ## Package layers
24
+
25
+ ```
26
+ @tgoliveira/vault-core crypto + envelopes + payload + validation
27
+ @tgoliveira/vault-core/browser session + auto-lock + PRF salt + kit DOM
28
+ @tgoliveira/vault-core/testing sentinels + scan helpers
29
+ @tgoliveira/vault-core/react headless React session/status hooks
30
+ ```
31
+
32
+ Apps own: persistence, routes, product UI, product payload schema, WebAuthn ceremony.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Thiago Oliveira
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,42 @@
1
+ # Migration from LiqSense
2
+
3
+ ## LiqSense profile (frozen)
4
+
5
+ ```ts
6
+ export const LIQSENSE_VAULT_PROFILE = {
7
+ cryptoVersion: "vault-v1",
8
+ aadContextVault: "liqsense:vault:v1",
9
+ aadContextEnvelope: "liqsense:vault-envelope:v1",
10
+ };
11
+ export const LIQSENSE_PRF_SALT_PREFIX = "liqsense-passkey-prf-v1:";
12
+ ```
13
+
14
+ ## Import mapping
15
+
16
+ | LiqSense (legacy) | vault-core |
17
+ | --- | --- |
18
+ | `generateUserVaultKey` | `createUserVaultKey` |
19
+ | `wrapVaultKeyForPassword` | `createPasswordEnvelope` + profile |
20
+ | `unwrapVaultKeyFromPassword` | `unlockWithPasswordEnvelope` |
21
+ | `wrapVaultKeyForRecoveryPhrase` | `createRecoveryEnvelope` + profile |
22
+ | `generateRecoveryPhrase` | `createRecoveryPhrase` |
23
+
24
+ LiqSense keeps thin wrappers in `src/modules/vault/core/` binding `LIQSENSE_VAULT_PROFILE`.
25
+
26
+ ## Local dev
27
+
28
+ ```json
29
+ "@tgoliveira/vault-core": "file:../vault-core"
30
+ ```
31
+
32
+ Build vault-core first. LiqSense uses `next build --webpack` for local package resolution.
33
+
34
+ ## React hooks
35
+
36
+ Import from `@tgoliveira/vault-core/react` (not a separate package):
37
+
38
+ ```ts
39
+ import { useVaultUnlocked, resolveVaultClientStatus } from "@tgoliveira/vault-core/react";
40
+ ```
41
+
42
+ The standalone `@tgoliveira/vault-react` package is deprecated.
@@ -0,0 +1,9 @@
1
+ # Passkey PRF Envelopes
2
+
3
+ - Separate from account passkey login
4
+ - App provides PRF output bytes (≥ 32 bytes) from WebAuthn ceremony
5
+ - Package wraps UVK with PRF-derived AES key
6
+ - API: `createPasskeyPrfEnvelope` / `unlockWithPasskeyPrfEnvelope`
7
+ - Browser helpers: `buildPrfSaltBytes(prefix, userId)`, capability probes
8
+
9
+ PRF output never sent to server. WebAuthn ceremony stays in the app.
@@ -0,0 +1,7 @@
1
+ # Password Envelopes
2
+
3
+ - Vault password normalized with NFKC before Argon2id
4
+ - Default params: memory 65536 KiB, iterations 3, parallelism 1, 32-byte hash, 16-byte salt
5
+ - API: `createPasswordEnvelope` / `unlockWithPasswordEnvelope`
6
+
7
+ Vault password never sent to server.
package/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # @tgoliveira/vault-core
2
+
3
+ Framework-independent vault crypto primitives extracted from LiqSense.
4
+
5
+ ## Scope
6
+
7
+ - User Vault Key (UVK) generation
8
+ - AES-GCM encrypted payloads with canonical AAD
9
+ - Argon2id password and recovery phrase envelopes
10
+ - Passkey PRF envelope wrap/unwrap (PRF bytes only — no WebAuthn ceremony)
11
+ - BIP39 12/24-word recovery phrases
12
+ - No-plaintext validation helpers
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install @tgoliveira/vault-core
18
+ ```
19
+
20
+ Local development with LiqSense:
21
+
22
+ ```json
23
+ "@tgoliveira/vault-core": "file:../vault-core"
24
+ ```
25
+
26
+ Build vault-core before consuming:
27
+
28
+ ```bash
29
+ cd ../vault-core && npm run validate
30
+ ```
31
+
32
+ ## Quick start
33
+
34
+ ```ts
35
+ import {
36
+ createUserVaultKey,
37
+ createPasswordEnvelope,
38
+ unlockWithPasswordEnvelope,
39
+ encryptVaultPayload,
40
+ decryptVaultPayload,
41
+ type VaultCryptoProfile,
42
+ } from "@tgoliveira/vault-core";
43
+
44
+ const profile: VaultCryptoProfile = {
45
+ cryptoVersion: "vault-v1",
46
+ aadContextVault: "myapp:vault:v1",
47
+ aadContextEnvelope: "myapp:vault-envelope:v1",
48
+ };
49
+
50
+ const userId = "00000000-0000-4000-8000-000000000001";
51
+ const scope = { userId, resourceId: userId };
52
+ const vaultKey = await createUserVaultKey();
53
+
54
+ const { envelope } = await createPasswordEnvelope(
55
+ vaultKey,
56
+ userVaultPassword,
57
+ scope,
58
+ profile
59
+ );
60
+ ```
61
+
62
+ ## Exports
63
+
64
+ | Entry | Purpose |
65
+ | --- | --- |
66
+ | `@tgoliveira/vault-core` | Core crypto, envelopes, payload, validation |
67
+ | `@tgoliveira/vault-core/browser` | In-memory session, auto-lock, PRF salt, recovery kit DOM helpers |
68
+ | `@tgoliveira/vault-core/testing` | Sentinels and plaintext scan helpers |
69
+ | `@tgoliveira/vault-core/react` | Headless React session/status hooks (optional peer: `react`) |
70
+
71
+ ## Boundaries
72
+
73
+ - Does **not** include account authentication
74
+ - Does **not** require React, Next.js, or product payload schemas on the default entry
75
+ - `./react` is optional and requires `react >= 18`
76
+ - Vault password, recovery phrase, UVK, PRF output, and decrypted payload must stay client-side
77
+
78
+ See `SECURITY.md`, `ARCHITECTURE.md`, and `MIGRATION_FROM_LIQSENSE.md`.
@@ -0,0 +1,9 @@
1
+ # Recovery Phrase
2
+
3
+ - BIP39 English wordlist via `@scure/bip39`
4
+ - Supported lengths: **12 words** (128-bit) and **24 words** (256-bit, default)
5
+ - Normalization: trim, lowercase, single-space separated
6
+ - Confirmation helpers: deterministic word indices (3 for 12 words, 4 for 24)
7
+ - Recovery kit text via `createRecoveryKitText({ productName, ... })`
8
+
9
+ Recovery phrase never sent to server.
package/SECURITY.md ADDED
@@ -0,0 +1,31 @@
1
+ # Vault Core Security Model
2
+
3
+ ## Separation from account auth
4
+
5
+ Account login, password reset, TOTP, OAuth, and passkey **login** must not unlock the vault.
6
+
7
+ Vault unlock requires a separate vault password, recovery phrase, or passkey PRF envelope.
8
+
9
+ ## Server must never receive
10
+
11
+ - Vault password
12
+ - Recovery phrase (plaintext)
13
+ - User Vault Key
14
+ - PRF output
15
+ - Decrypted vault payload
16
+
17
+ Use `assertNoVaultPlaintextFields()` on API request bodies.
18
+
19
+ ## Client must never persist
20
+
21
+ - Decrypted vault payload in localStorage or IndexedDB
22
+
23
+ Browser session helpers clear UVK on lock and `pagehide`.
24
+
25
+ ## Crypto constants (per app profile)
26
+
27
+ Apps define `VaultCryptoProfile` with stable AAD contexts. Existing ciphertext breaks if contexts change.
28
+
29
+ ## Logging
30
+
31
+ Never log vault secrets, request bodies containing envelopes, or decrypted payloads.
@@ -0,0 +1,11 @@
1
+ import { extractPasskeyPrfOutput, isPasskeySupported, isPrfExtensionSupported } from "./envelopes/passkey-prf.js";
2
+ export declare function buildPrfSaltBytes(prefix: string, userId: string): Promise<ArrayBuffer>;
3
+ export declare function createRecoveryKitDownload(content: string, filename: string): void;
4
+ export declare function printRecoveryKitContent(content: string): void;
5
+ export declare function assertNoDecryptedVaultInLocalStorage(storagePrefix: string): boolean;
6
+ export declare function assertNoDecryptedVaultInIndexedDB(storagePrefix: string): Promise<boolean>;
7
+ export declare function persistVaultRecordLocally(): never;
8
+ export { extractPasskeyPrfOutput, isPasskeySupported, isPrfExtensionSupported, };
9
+ export { configureVaultSession, subscribeVaultSession, isVaultManuallyLocked, clearVaultAutoLockTimer, scheduleVaultAutoLock, touchVaultSession, unlockVaultSession, lockVaultSession, lockVaultSessionManually, resetVaultSessionLockState, registerVaultUnloadGuard, getVaultAutoLockRemainingMs, getSessionVaultKey, setSessionVaultKey, lockVault, isVaultUnlocked, clearVaultClientState, type VaultSessionConfig, } from "./session/auto-lock.js";
10
+ export { createRecoveryKitText, buildRecoveryKitContent } from "./recovery/kit.js";
11
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AACA,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;AAEpC,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAG5F;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,IAAI,CASN;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAU7D;AASD,wBAAgB,oCAAoC,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAWnF;AAED,wBAAsB,iCAAiC,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgB/F;AAED,wBAAgB,yBAAyB,IAAI,KAAK,CAEjD;AAED,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,GACxB,CAAC;AAEF,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EACxB,2BAA2B,EAC3B,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,EACT,eAAe,EACf,qBAAqB,EACrB,KAAK,kBAAkB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,71 @@
1
+ import { stringToBytes, toBufferSource } from "./crypto/encoding.js";
2
+ import { extractPasskeyPrfOutput, isPasskeySupported, isPrfExtensionSupported, } from "./envelopes/passkey-prf.js";
3
+ export async function buildPrfSaltBytes(prefix, userId) {
4
+ const input = toBufferSource(stringToBytes(`${prefix}${userId}`));
5
+ return crypto.subtle.digest("SHA-256", input);
6
+ }
7
+ export function createRecoveryKitDownload(content, filename) {
8
+ if (typeof window === "undefined")
9
+ return;
10
+ const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
11
+ const url = URL.createObjectURL(blob);
12
+ const anchor = document.createElement("a");
13
+ anchor.href = url;
14
+ anchor.download = filename;
15
+ anchor.click();
16
+ URL.revokeObjectURL(url);
17
+ }
18
+ export function printRecoveryKitContent(content) {
19
+ if (typeof window === "undefined")
20
+ return;
21
+ const printWindow = window.open("", "_blank", "noopener,noreferrer,width=640,height=720");
22
+ if (!printWindow)
23
+ return;
24
+ printWindow.document.write(`<pre style="font-family:monospace;white-space:pre-wrap;padding:24px;">${escapeHtml(content)}</pre>`);
25
+ printWindow.document.close();
26
+ printWindow.focus();
27
+ printWindow.print();
28
+ }
29
+ function escapeHtml(value) {
30
+ return value
31
+ .replace(/&/g, "&amp;")
32
+ .replace(/</g, "&lt;")
33
+ .replace(/>/g, "&gt;");
34
+ }
35
+ export function assertNoDecryptedVaultInLocalStorage(storagePrefix) {
36
+ if (typeof window === "undefined")
37
+ return true;
38
+ for (let i = 0; i < localStorage.length; i++) {
39
+ const key = localStorage.key(i);
40
+ if (!key)
41
+ continue;
42
+ if (key.startsWith(storagePrefix)) {
43
+ return false;
44
+ }
45
+ }
46
+ return true;
47
+ }
48
+ export async function assertNoDecryptedVaultInIndexedDB(storagePrefix) {
49
+ if (typeof window === "undefined" || typeof indexedDB === "undefined")
50
+ return true;
51
+ return new Promise((resolve) => {
52
+ const request = indexedDB.databases?.();
53
+ if (!request) {
54
+ resolve(true);
55
+ return;
56
+ }
57
+ void request
58
+ .then((databases) => {
59
+ const hasVaultDb = databases.some((db) => db.name?.startsWith(storagePrefix));
60
+ resolve(!hasVaultDb);
61
+ })
62
+ .catch(() => resolve(true));
63
+ });
64
+ }
65
+ export function persistVaultRecordLocally() {
66
+ throw new Error("Decrypted vault state must not be persisted to localStorage or IndexedDB");
67
+ }
68
+ export { extractPasskeyPrfOutput, isPasskeySupported, isPrfExtensionSupported, };
69
+ export { configureVaultSession, subscribeVaultSession, isVaultManuallyLocked, clearVaultAutoLockTimer, scheduleVaultAutoLock, touchVaultSession, unlockVaultSession, lockVaultSession, lockVaultSessionManually, resetVaultSessionLockState, registerVaultUnloadGuard, getVaultAutoLockRemainingMs, getSessionVaultKey, setSessionVaultKey, lockVault, isVaultUnlocked, clearVaultClientState, } from "./session/auto-lock.js";
70
+ export { createRecoveryKitText, buildRecoveryKitContent } from "./recovery/kit.js";
71
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare const ENCRYPTION_VERSION: "enc-v1";
2
+ export declare const ENCRYPTION_ALG: "AES-GCM";
3
+ export declare const VAULT_CRYPTO_VERSION: "vault-v1";
4
+ export declare const DEFAULT_VAULT_AUTO_LOCK_MINUTES = 15;
5
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,EAAG,QAAiB,CAAC;AACpD,eAAO,MAAM,cAAc,EAAG,SAAkB,CAAC;AACjD,eAAO,MAAM,oBAAoB,EAAG,UAAmB,CAAC;AACxD,eAAO,MAAM,+BAA+B,KAAK,CAAC"}
@@ -0,0 +1,5 @@
1
+ export const ENCRYPTION_VERSION = "enc-v1";
2
+ export const ENCRYPTION_ALG = "AES-GCM";
3
+ export const VAULT_CRYPTO_VERSION = "vault-v1";
4
+ export const DEFAULT_VAULT_AUTO_LOCK_MINUTES = 15;
5
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAiB,CAAC;AACpD,MAAM,CAAC,MAAM,cAAc,GAAG,SAAkB,CAAC;AACjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAmB,CAAC;AACxD,MAAM,CAAC,MAAM,+BAA+B,GAAG,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { EncryptedVaultPayload } from "../validation/schemas.js";
2
+ export declare function canonicalAadString(aad: EncryptedVaultPayload["aad"]): string;
3
+ export declare function aadByteCandidates(aad: EncryptedVaultPayload["aad"]): Uint8Array[];
4
+ //# sourceMappingURL=aad.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aad.d.ts","sourceRoot":"","sources":["../../src/crypto/aad.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGtE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,qBAAqB,CAAC,KAAK,CAAC,GAAG,MAAM,CAO5E;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,qBAAqB,CAAC,KAAK,CAAC,GAAG,UAAU,EAAE,CAajF"}
@@ -0,0 +1,23 @@
1
+ import { stringToBytes } from "./encoding.js";
2
+ export function canonicalAadString(aad) {
3
+ return JSON.stringify({
4
+ context: aad.context,
5
+ field: aad.field,
6
+ resourceId: aad.resourceId,
7
+ userId: aad.userId,
8
+ });
9
+ }
10
+ export function aadByteCandidates(aad) {
11
+ const variants = new Set([
12
+ canonicalAadString(aad),
13
+ JSON.stringify({
14
+ userId: aad.userId,
15
+ resourceId: aad.resourceId,
16
+ field: aad.field,
17
+ context: aad.context,
18
+ }),
19
+ JSON.stringify(aad),
20
+ ]);
21
+ return Array.from(variants).map((value) => stringToBytes(value));
22
+ }
23
+ //# sourceMappingURL=aad.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aad.js","sourceRoot":"","sources":["../../src/crypto/aad.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,UAAU,kBAAkB,CAAC,GAAiC;IAClE,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,MAAM,EAAE,GAAG,CAAC,MAAM;KACnB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAiC;IACjE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS;QAC/B,kBAAkB,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,SAAS,CAAC;YACb,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,OAAO,EAAE,GAAG,CAAC,OAAO;SACrB,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;KACpB,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { VaultCryptoProfile, VaultAadScope } from "../profile.js";
2
+ import type { EncryptedVaultPayload } from "../validation/schemas.js";
3
+ export declare function generateAesKey(): Promise<CryptoKey>;
4
+ export declare function importAesKey(rawKey: Uint8Array): Promise<CryptoKey>;
5
+ export declare function exportAesKey(key: CryptoKey): Promise<Uint8Array>;
6
+ export type EncryptFieldAad = VaultAadScope;
7
+ export declare function encryptField(plaintext: string, key: CryptoKey, aad: EncryptFieldAad, profile: VaultCryptoProfile): Promise<EncryptedVaultPayload>;
8
+ export declare function decryptField(payload: EncryptedVaultPayload, key: CryptoKey): Promise<string>;
9
+ //# sourceMappingURL=aes-gcm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aes-gcm.d.ts","sourceRoot":"","sources":["../../src/crypto/aes-gcm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEvE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAYtE,wBAAsB,cAAc,IAAI,OAAO,CAAC,SAAS,CAAC,CAKzD;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAQzE;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAGtE;AAED,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC;AAE5C,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,SAAS,EACd,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,qBAAqB,CAAC,CAyBhC;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,EAC9B,GAAG,EAAE,SAAS,GACb,OAAO,CAAC,MAAM,CAAC,CAuBjB"}
@@ -0,0 +1,58 @@
1
+ import { ENCRYPTION_ALG, ENCRYPTION_VERSION } from "../constants.js";
2
+ import { resolveAadContext } from "../profile.js";
3
+ import { canonicalAadString, aadByteCandidates } from "./aad.js";
4
+ import { bytesToBase64Url, base64UrlToBytes, stringToBytes, bytesToString, toBufferSource, } from "./encoding.js";
5
+ const IV_LENGTH = 12;
6
+ export async function generateAesKey() {
7
+ return crypto.subtle.generateKey({ name: ENCRYPTION_ALG, length: 256 }, true, [
8
+ "encrypt",
9
+ "decrypt",
10
+ ]);
11
+ }
12
+ export async function importAesKey(rawKey) {
13
+ return crypto.subtle.importKey("raw", toBufferSource(rawKey), { name: ENCRYPTION_ALG, length: 256 }, true, ["encrypt", "decrypt"]);
14
+ }
15
+ export async function exportAesKey(key) {
16
+ const raw = await crypto.subtle.exportKey("raw", key);
17
+ return new Uint8Array(raw);
18
+ }
19
+ export async function encryptField(plaintext, key, aad, profile) {
20
+ const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));
21
+ const aadWithContext = {
22
+ ...aad,
23
+ context: resolveAadContext(aad, profile),
24
+ };
25
+ const aadBytes = stringToBytes(canonicalAadString(aadWithContext));
26
+ const ciphertextBuffer = await crypto.subtle.encrypt({
27
+ name: ENCRYPTION_ALG,
28
+ iv: toBufferSource(iv),
29
+ additionalData: toBufferSource(aadBytes),
30
+ }, key, toBufferSource(stringToBytes(plaintext)));
31
+ return {
32
+ version: ENCRYPTION_VERSION,
33
+ alg: ENCRYPTION_ALG,
34
+ iv: bytesToBase64Url(iv),
35
+ ciphertext: bytesToBase64Url(new Uint8Array(ciphertextBuffer)),
36
+ aad: aadWithContext,
37
+ };
38
+ }
39
+ export async function decryptField(payload, key) {
40
+ const iv = base64UrlToBytes(payload.iv);
41
+ const ciphertext = base64UrlToBytes(payload.ciphertext);
42
+ let lastError;
43
+ for (const aadBytes of aadByteCandidates(payload.aad)) {
44
+ try {
45
+ const plaintextBuffer = await crypto.subtle.decrypt({
46
+ name: ENCRYPTION_ALG,
47
+ iv: toBufferSource(iv),
48
+ additionalData: toBufferSource(aadBytes),
49
+ }, key, toBufferSource(ciphertext));
50
+ return bytesToString(new Uint8Array(plaintextBuffer));
51
+ }
52
+ catch (error) {
53
+ lastError = error;
54
+ }
55
+ }
56
+ throw lastError instanceof Error ? lastError : new Error("Decryption failed");
57
+ }
58
+ //# sourceMappingURL=aes-gcm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aes-gcm.js","sourceRoot":"","sources":["../../src/crypto/aes-gcm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function bytesToBase64Url(bytes: Uint8Array): string;
2
+ export declare function base64UrlToBytes(base64url: string): Uint8Array;
3
+ export declare function stringToBytes(str: string): Uint8Array;
4
+ export declare function toBufferSource(bytes: Uint8Array): Uint8Array<ArrayBuffer>;
5
+ export declare function bytesToString(bytes: Uint8Array): string;
6
+ //# sourceMappingURL=encoding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/crypto/encoding.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAM1D;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAS9D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAErD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,CAEzE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEvD"}
@@ -0,0 +1,27 @@
1
+ export function bytesToBase64Url(bytes) {
2
+ let binary = "";
3
+ for (const byte of bytes) {
4
+ binary += String.fromCharCode(byte);
5
+ }
6
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
7
+ }
8
+ export function base64UrlToBytes(base64url) {
9
+ const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
10
+ const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
11
+ const binary = atob(padded);
12
+ const bytes = new Uint8Array(binary.length);
13
+ for (let i = 0; i < binary.length; i++) {
14
+ bytes[i] = binary.charCodeAt(i);
15
+ }
16
+ return bytes;
17
+ }
18
+ export function stringToBytes(str) {
19
+ return new TextEncoder().encode(str);
20
+ }
21
+ export function toBufferSource(bytes) {
22
+ return new Uint8Array(bytes);
23
+ }
24
+ export function bytesToString(bytes) {
25
+ return new TextDecoder().decode(bytes);
26
+ }
27
+ //# sourceMappingURL=encoding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../src/crypto/encoding.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAAC,KAAiB;IAChD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAiB;IAC9C,OAAO,IAAI,UAAU,CAAC,KAAK,CAA4B,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAiB;IAC7C,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function randomBytes(length: number): Uint8Array;
2
+ //# sourceMappingURL=random.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../../src/crypto/random.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAEtD"}
@@ -0,0 +1,4 @@
1
+ export function randomBytes(length) {
2
+ return crypto.getRandomValues(new Uint8Array(length));
3
+ }
4
+ //# sourceMappingURL=random.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random.js","sourceRoot":"","sources":["../../src/crypto/random.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,OAAO,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function serializeVaultPayload(payload: unknown): string;
2
+ export declare function parseVaultPayload<T>(json: string): T;
3
+ //# sourceMappingURL=serialization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../src/crypto/serialization.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAE9D;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAEpD"}
@@ -0,0 +1,7 @@
1
+ export function serializeVaultPayload(payload) {
2
+ return JSON.stringify(payload);
3
+ }
4
+ export function parseVaultPayload(json) {
5
+ return JSON.parse(json);
6
+ }
7
+ //# sourceMappingURL=serialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialization.js","sourceRoot":"","sources":["../../src/crypto/serialization.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAI,IAAY;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { EncryptedVaultPayload, PasskeyPrfEnvelope } from "../validation/schemas.js";
2
+ import type { VaultCryptoProfile, VaultAadScope } from "../profile.js";
3
+ export declare function isPasskeySupported(): boolean;
4
+ export declare function isPrfExtensionSupported(): boolean;
5
+ export declare function extractPasskeyPrfOutput(clientExtensionResults: Record<string, unknown>): Uint8Array | null;
6
+ type WrapScope = Pick<VaultAadScope, "userId" | "resourceId">;
7
+ export declare function createPasskeyPrfEnvelope(vaultKey: CryptoKey, prfOutput: Uint8Array, scope: WrapScope, profile: VaultCryptoProfile, publicMetadata?: Record<string, unknown>): Promise<PasskeyPrfEnvelope>;
8
+ export declare function unwrapVaultKeyFromPasskey(encryptedVaultKey: EncryptedVaultPayload, prfOutput: Uint8Array): Promise<CryptoKey>;
9
+ export declare function unlockWithPasskeyPrfEnvelope(envelope: PasskeyPrfEnvelope | {
10
+ encryptedVaultKey: EncryptedVaultPayload;
11
+ }, prfOutput: Uint8Array | null, options?: {
12
+ prfRequired?: boolean;
13
+ }): Promise<CryptoKey>;
14
+ /** @deprecated Use unlockWithPasskeyPrfEnvelope */
15
+ export declare function unlockVaultFromPasskeyEnvelope(encryptedVaultKeyOrEnvelope: EncryptedVaultPayload | PasskeyPrfEnvelope, prfOutput: Uint8Array | null, options?: {
16
+ prfRequired?: boolean;
17
+ }): Promise<CryptoKey>;
18
+ /** @deprecated Use createPasskeyPrfEnvelope */
19
+ export declare function wrapVaultKeyForPasskey(vaultKey: CryptoKey, prfOutput: Uint8Array, userId: string, resourceId: string, profile: VaultCryptoProfile, publicMetadata?: Record<string, unknown>): Promise<EncryptedVaultPayload>;
20
+ export { PasskeyPrfRequiredError, PasskeyUnlockError } from "../errors/vault-errors.js";
21
+ //# sourceMappingURL=passkey-prf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkey-prf.d.ts","sourceRoot":"","sources":["../../src/envelopes/passkey-prf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAavE,wBAAgB,kBAAkB,IAAI,OAAO,CAG5C;AAED,wBAAgB,uBAAuB,IAAI,OAAO,CAIjD;AAED,wBAAgB,uBAAuB,CACrC,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9C,UAAU,GAAG,IAAI,CAKnB;AAaD,KAAK,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,YAAY,CAAC,CAAC;AAE9D,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,SAAS,EACnB,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,kBAAkB,EAC3B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvC,OAAO,CAAC,kBAAkB,CAAC,CAqB7B;AAED,wBAAsB,yBAAyB,CAC7C,iBAAiB,EAAE,qBAAqB,EACxC,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,SAAS,CAAC,CAOpB;AAED,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,kBAAkB,GAAG;IAAE,iBAAiB,EAAE,qBAAqB,CAAA;CAAE,EAC3E,SAAS,EAAE,UAAU,GAAG,IAAI,EAC5B,OAAO,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAClC,OAAO,CAAC,SAAS,CAAC,CAsBpB;AAED,mDAAmD;AACnD,wBAAsB,8BAA8B,CAClD,2BAA2B,EAAE,qBAAqB,GAAG,kBAAkB,EACvE,SAAS,EAAE,UAAU,GAAG,IAAI,EAC5B,OAAO,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAClC,OAAO,CAAC,SAAS,CAAC,CAMpB;AAED,+CAA+C;AAC/C,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,SAAS,EACnB,SAAS,EAAE,UAAU,EACrB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,kBAAkB,EAC3B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvC,OAAO,CAAC,qBAAqB,CAAC,CAShC;AAED,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}