@learncard/sss-key-manager 0.1.20 → 0.1.21
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/dist/api-client.d.ts +49 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/atomic-operations.d.ts +101 -0
- package/dist/atomic-operations.d.ts.map +1 -0
- package/dist/auth-coordinator.d.ts +10 -0
- package/dist/auth-coordinator.d.ts.map +1 -0
- package/dist/crypto.d.ts +31 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/key-manager.d.ts +30 -0
- package/dist/key-manager.d.ts.map +1 -0
- package/dist/passkey.d.ts +23 -0
- package/dist/passkey.d.ts.map +1 -0
- package/dist/qr-crypto.d.ts +56 -0
- package/dist/qr-crypto.d.ts.map +1 -0
- package/dist/qr-login.d.ts +122 -0
- package/dist/qr-login.d.ts.map +1 -0
- package/dist/recovery-phrase.d.ts +14 -0
- package/dist/recovery-phrase.d.ts.map +1 -0
- package/dist/sss-key-manager.cjs.development.js +3 -2
- package/dist/sss-key-manager.cjs.development.js.map +2 -2
- package/dist/sss-key-manager.cjs.production.min.js +6 -6
- package/dist/sss-key-manager.cjs.production.min.js.map +3 -3
- package/dist/sss-key-manager.esm.js +3 -2
- package/dist/sss-key-manager.esm.js.map +2 -2
- package/dist/sss-strategy.d.ts +82 -0
- package/dist/sss-strategy.d.ts.map +1 -0
- package/dist/sss.d.ts +15 -0
- package/dist/sss.d.ts.map +1 -0
- package/dist/storage.d.ts +46 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/types.d.ts +155 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +5 -6
- package/src/crypto.ts +9 -14
- package/src/recovery-phrase.ts +7 -4
- package/dist/sss-key-manager.d.ts +0 -898
|
@@ -1,898 +0,0 @@
|
|
|
1
|
-
// Generated by dts-bundle-generator v6.13.0
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Provider-agnostic interfaces for authentication and key derivation.
|
|
5
|
-
*
|
|
6
|
-
* Both @learncard/sss-key-manager and learn-card-base import from here,
|
|
7
|
-
* ensuring a single canonical source for abstract interfaces without
|
|
8
|
-
* coupling consumers to any specific implementation.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Typed error for auth session issues.
|
|
12
|
-
* Auth providers should throw this (instead of generic Error) when the
|
|
13
|
-
* session is expired, revoked, or missing so the coordinator can
|
|
14
|
-
* distinguish "not logged in" from "unexpected failure".
|
|
15
|
-
*/
|
|
16
|
-
export declare class AuthSessionError extends Error {
|
|
17
|
-
readonly reason: "expired" | "no_session" | "revoked" | "network";
|
|
18
|
-
constructor(message: string, reason: "expired" | "no_session" | "revoked" | "network");
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Auth provider identifier. Known values: 'firebase', 'supertokens', 'keycloak', 'oidc'.
|
|
22
|
-
* Use any string to support custom auth providers without modifying this type.
|
|
23
|
-
*/
|
|
24
|
-
export type AuthProviderType = string;
|
|
25
|
-
export interface AuthUser {
|
|
26
|
-
id: string;
|
|
27
|
-
email?: string;
|
|
28
|
-
phone?: string;
|
|
29
|
-
displayName?: string;
|
|
30
|
-
photoUrl?: string;
|
|
31
|
-
providerType: AuthProviderType;
|
|
32
|
-
/** Account creation timestamp (when available from the auth provider) */
|
|
33
|
-
createdAt?: Date;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Abstract auth provider interface.
|
|
37
|
-
* Implementations wrap a specific auth SDK (Firebase, Supertokens, etc.)
|
|
38
|
-
* and expose a uniform API to the coordinator.
|
|
39
|
-
*/
|
|
40
|
-
export interface AuthProvider {
|
|
41
|
-
getIdToken(forceRefresh?: boolean): Promise<string>;
|
|
42
|
-
getCurrentUser(): Promise<AuthUser | null>;
|
|
43
|
-
getProviderType(): AuthProviderType;
|
|
44
|
-
signOut(): Promise<void>;
|
|
45
|
-
/**
|
|
46
|
-
* Attempt to silently refresh the auth session (e.g., force-refresh
|
|
47
|
-
* the JWT using the underlying refresh token).
|
|
48
|
-
*
|
|
49
|
-
* Returns `true` if the session was successfully refreshed.
|
|
50
|
-
* Returns `false` if a full re-authentication is required.
|
|
51
|
-
*
|
|
52
|
-
* Optional — providers that don't implement this will require full
|
|
53
|
-
* re-auth whenever the session expires.
|
|
54
|
-
*/
|
|
55
|
-
refreshSession?(): Promise<boolean>;
|
|
56
|
-
/**
|
|
57
|
-
* Re-authenticate with a server-issued token (e.g., a Firebase custom
|
|
58
|
-
* token returned after a server-side account change that invalidates
|
|
59
|
-
* the current session).
|
|
60
|
-
*
|
|
61
|
-
* Returns the refreshed AuthUser read directly from the auth SDK
|
|
62
|
-
* (not from the app store, which may be stale).
|
|
63
|
-
*
|
|
64
|
-
* Optional — only needed by providers whose server-side account
|
|
65
|
-
* mutations invalidate the client session.
|
|
66
|
-
*/
|
|
67
|
-
reauthenticateWithToken?(token: string): Promise<AuthUser | null>;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Recovery method metadata returned by the server.
|
|
71
|
-
* The `type` is a string so strategies can define their own method types
|
|
72
|
-
* without modifying this interface.
|
|
73
|
-
*/
|
|
74
|
-
export interface RecoveryMethodInfo {
|
|
75
|
-
type: string;
|
|
76
|
-
createdAt: Date;
|
|
77
|
-
credentialId?: string;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Generic result of a successful recovery execution.
|
|
81
|
-
* All strategies must produce a private key + DID.
|
|
82
|
-
*/
|
|
83
|
-
export interface RecoveryResult {
|
|
84
|
-
privateKey: string;
|
|
85
|
-
did: string;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Server key status returned by the strategy's fetchServerKeyStatus.
|
|
89
|
-
* The strategy owns the server shape — different strategies may
|
|
90
|
-
* have fundamentally different server payloads.
|
|
91
|
-
*/
|
|
92
|
-
export interface ServerKeyStatus {
|
|
93
|
-
exists: boolean;
|
|
94
|
-
needsMigration: boolean;
|
|
95
|
-
primaryDid: string | null;
|
|
96
|
-
recoveryMethods: RecoveryMethodInfo[];
|
|
97
|
-
authShare: string | null;
|
|
98
|
-
shareVersion: number | null;
|
|
99
|
-
maskedRecoveryEmail?: string | null;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Declarative capability flags for a key derivation strategy.
|
|
103
|
-
*
|
|
104
|
-
* UI components read these to decide which features to show.
|
|
105
|
-
* Each strategy declares its own capabilities — no strategy-specific
|
|
106
|
-
* checks needed in the UI layer.
|
|
107
|
-
*
|
|
108
|
-
* All flags default to `false` when absent.
|
|
109
|
-
*
|
|
110
|
-
* @example
|
|
111
|
-
* ```ts
|
|
112
|
-
* // SSS declares full capabilities:
|
|
113
|
-
* capabilities: { recovery: true, deviceLinking: true, localKeyPersistence: true }
|
|
114
|
-
*
|
|
115
|
-
* // Web3Auth derives keys on-demand, nothing local to manage:
|
|
116
|
-
* capabilities: { recovery: false, deviceLinking: false, localKeyPersistence: false }
|
|
117
|
-
* ```
|
|
118
|
-
*/
|
|
119
|
-
export interface KeyDerivationCapabilities {
|
|
120
|
-
/** Strategy supports user-facing recovery methods (setup + execution) */
|
|
121
|
-
recovery: boolean;
|
|
122
|
-
/** Strategy supports cross-device key transfer (e.g., QR-based device linking) */
|
|
123
|
-
deviceLinking: boolean;
|
|
124
|
-
/**
|
|
125
|
-
* Strategy persists key material locally (e.g., device share in IndexedDB).
|
|
126
|
-
* When true, "public computer" / "forget device" features are relevant.
|
|
127
|
-
*/
|
|
128
|
-
localKeyPersistence: boolean;
|
|
129
|
-
/**
|
|
130
|
-
* Strategy supports upgrading the user's contact method (e.g., phone → email).
|
|
131
|
-
* When true, the `upgradeContactMethod` method is available and the
|
|
132
|
-
* email-linking gate can be shown for phone-only users.
|
|
133
|
-
*/
|
|
134
|
-
contactMethodUpgrade: boolean;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Key Derivation Strategy
|
|
138
|
-
*
|
|
139
|
-
* Abstract interface for different key derivation implementations.
|
|
140
|
-
* Used by AuthCoordinator to delegate key operations.
|
|
141
|
-
*
|
|
142
|
-
* The strategy owns:
|
|
143
|
-
* - Local key storage
|
|
144
|
-
* - Key splitting and reconstruction
|
|
145
|
-
* - Server communication for remote key components
|
|
146
|
-
* - Recovery method execution and setup
|
|
147
|
-
* - Storage cleanup knowledge
|
|
148
|
-
*
|
|
149
|
-
* Type parameters allow each strategy to define its own recovery shapes:
|
|
150
|
-
* - TRecoveryInput: what the user provides to recover (e.g., password, passkey)
|
|
151
|
-
* - TRecoverySetupInput: what the user provides to set up a recovery method
|
|
152
|
-
* - TRecoverySetupResult: what setup returns (e.g., generated phrase, credential ID)
|
|
153
|
-
*
|
|
154
|
-
* @example
|
|
155
|
-
* // SSS strategy with specific recovery types:
|
|
156
|
-
* type SSSStrategy = KeyDerivationStrategy<SSSRecoveryInput, SSSRecoverySetupInput, SSSRecoverySetupResult>;
|
|
157
|
-
*
|
|
158
|
-
* // Simple strategy with no recovery:
|
|
159
|
-
* type SimpleStrategy = KeyDerivationStrategy<never, never, never>;
|
|
160
|
-
*/
|
|
161
|
-
export interface KeyDerivationStrategy<TRecoveryInput = unknown, TRecoverySetupInput = unknown, TRecoverySetupResult = unknown> {
|
|
162
|
-
readonly name: string;
|
|
163
|
-
/** Declarative feature flags — UI reads these to gate features */
|
|
164
|
-
readonly capabilities: KeyDerivationCapabilities;
|
|
165
|
-
/** Check if there's a local key component (e.g., device share) */
|
|
166
|
-
hasLocalKey(): Promise<boolean>;
|
|
167
|
-
/** Get the local key component */
|
|
168
|
-
getLocalKey(): Promise<string | null>;
|
|
169
|
-
/** Store a local key component */
|
|
170
|
-
storeLocalKey(key: string): Promise<void>;
|
|
171
|
-
/** Clear all local key data */
|
|
172
|
-
clearLocalKeys(): Promise<void>;
|
|
173
|
-
/** Split a private key into shares/components */
|
|
174
|
-
splitKey(privateKey: string): Promise<{
|
|
175
|
-
localKey: string;
|
|
176
|
-
remoteKey: string;
|
|
177
|
-
}>;
|
|
178
|
-
/** Reconstruct private key from components */
|
|
179
|
-
reconstructKey(localKey: string, remoteKey: string): Promise<string>;
|
|
180
|
-
/** Verify that stored keys can reconstruct the expected DID */
|
|
181
|
-
verifyKeys?(localKey: string, remoteKey: string, expectedDid: string, didFromPrivateKey: (pk: string) => Promise<string>): Promise<boolean>;
|
|
182
|
-
/** Fetch the server-side key status for the authenticated user */
|
|
183
|
-
fetchServerKeyStatus(token: string, providerType: AuthProviderType): Promise<ServerKeyStatus>;
|
|
184
|
-
/** Store the remote key component on the server */
|
|
185
|
-
storeAuthShare(token: string, providerType: AuthProviderType, remoteKey: string, did: string, didAuthVp?: string): Promise<void>;
|
|
186
|
-
/** Mark migration complete on the server (optional — only needed for migration-capable strategies) */
|
|
187
|
-
markMigrated?(token: string, providerType: AuthProviderType, didAuthVp?: string): Promise<void>;
|
|
188
|
-
/** Execute a recovery flow and return the recovered private key + DID */
|
|
189
|
-
executeRecovery(params: {
|
|
190
|
-
token: string;
|
|
191
|
-
providerType: AuthProviderType;
|
|
192
|
-
input: TRecoveryInput;
|
|
193
|
-
/** Optional: validate the reconstructed key's DID before rotating shares */
|
|
194
|
-
didFromPrivateKey?: (privateKey: string) => Promise<string>;
|
|
195
|
-
}): Promise<RecoveryResult>;
|
|
196
|
-
/** Set up a new recovery method */
|
|
197
|
-
setupRecoveryMethod?(params: {
|
|
198
|
-
token: string;
|
|
199
|
-
providerType: AuthProviderType;
|
|
200
|
-
privateKey: string;
|
|
201
|
-
input: TRecoverySetupInput;
|
|
202
|
-
authUser?: AuthUser;
|
|
203
|
-
/** Optional: sign a DID-Auth VP JWT for server write operations */
|
|
204
|
-
signDidAuthVp?: (privateKey: string) => Promise<string>;
|
|
205
|
-
}): Promise<TRecoverySetupResult>;
|
|
206
|
-
/** Get configured recovery methods for the authenticated user */
|
|
207
|
-
getAvailableRecoveryMethods?(token: string, providerType: AuthProviderType): Promise<RecoveryMethodInfo[]>;
|
|
208
|
-
/**
|
|
209
|
-
* Verify email ownership and upgrade the user's contact method on the
|
|
210
|
-
* server (e.g., phone → email). The server verifies the OTP code, links
|
|
211
|
-
* the email to the auth account (passwordless), and atomically updates
|
|
212
|
-
* the UserKey contact method.
|
|
213
|
-
*
|
|
214
|
-
* Strategies that don't manage server-side contact methods can omit this.
|
|
215
|
-
*
|
|
216
|
-
* @param token - Auth token for the current session
|
|
217
|
-
* @param providerType - Auth provider type
|
|
218
|
-
* @param previousPhone - The phone number being replaced
|
|
219
|
-
* @param email - The new email address (already OTP-verified client-side)
|
|
220
|
-
* @param code - The 6-digit verification code
|
|
221
|
-
*/
|
|
222
|
-
upgradeContactMethod?(token: string, providerType: AuthProviderType, previousPhone: string, email: string, code: string): Promise<{
|
|
223
|
-
customToken?: string;
|
|
224
|
-
} | void>;
|
|
225
|
-
/**
|
|
226
|
-
* Send a backup share to the user's email for fail-safe recovery.
|
|
227
|
-
* Called by the coordinator after key setup or migration.
|
|
228
|
-
* Implementation should be fire-and-forget (non-fatal on failure).
|
|
229
|
-
*
|
|
230
|
-
* @param token - Auth token for server communication
|
|
231
|
-
* @param providerType - Auth provider type
|
|
232
|
-
* @param privateKey - The private key to derive the email share from
|
|
233
|
-
* @param email - Destination email address
|
|
234
|
-
*/
|
|
235
|
-
sendEmailBackupShare?(token: string, providerType: AuthProviderType, privateKey: string, email: string): Promise<void>;
|
|
236
|
-
/**
|
|
237
|
-
* Get the share version associated with the local device share.
|
|
238
|
-
* Used to request the matching auth share from the server and to
|
|
239
|
-
* include in QR cross-device transfers.
|
|
240
|
-
*
|
|
241
|
-
* Returns null for legacy shares with no stored version.
|
|
242
|
-
*/
|
|
243
|
-
getLocalShareVersion?(): Promise<number | null>;
|
|
244
|
-
/**
|
|
245
|
-
* Store the share version for the local device share.
|
|
246
|
-
* Called after receiving a device share + version via QR transfer.
|
|
247
|
-
*/
|
|
248
|
-
storeLocalShareVersion?(version: number): Promise<void>;
|
|
249
|
-
/**
|
|
250
|
-
* Inform the strategy which user is active so it can scope local storage
|
|
251
|
-
* (e.g., device shares) per-user. Called by the coordinator after
|
|
252
|
-
* authentication, before any local-key operations.
|
|
253
|
-
*
|
|
254
|
-
* Strategies that don't need per-user scoping can omit this method.
|
|
255
|
-
*
|
|
256
|
-
* @param userId - Stable, unique identifier for the authenticated user
|
|
257
|
-
* (e.g., Firebase UID). Must NOT change across sessions.
|
|
258
|
-
*/
|
|
259
|
-
setActiveUser?(userId: string): void;
|
|
260
|
-
/** Return storage keys (e.g., IndexedDB database names) that should be preserved during logout */
|
|
261
|
-
getPreservedStorageKeys(): string[];
|
|
262
|
-
/** Strategy-specific cleanup beyond clearLocalKeys (optional) */
|
|
263
|
-
cleanup?(): Promise<void>;
|
|
264
|
-
}
|
|
265
|
-
export type ContactMethodType = "email" | "phone";
|
|
266
|
-
export interface ContactMethod {
|
|
267
|
-
type: ContactMethodType;
|
|
268
|
-
value: string;
|
|
269
|
-
}
|
|
270
|
-
export interface AuthProviderMapping {
|
|
271
|
-
type: AuthProviderType;
|
|
272
|
-
id: string;
|
|
273
|
-
}
|
|
274
|
-
export type SecurityLevel = "basic" | "enhanced" | "advanced";
|
|
275
|
-
/**
|
|
276
|
-
* SSS recovery method type identifiers.
|
|
277
|
-
* These are the specific recovery methods supported by the SSS strategy.
|
|
278
|
-
*/
|
|
279
|
-
export type RecoveryMethodType = "passkey" | "backup" | "phrase" | "email";
|
|
280
|
-
export interface PasskeyRecoveryMethod {
|
|
281
|
-
type: "passkey";
|
|
282
|
-
credentialId?: string;
|
|
283
|
-
}
|
|
284
|
-
export interface BackupFileRecoveryMethod {
|
|
285
|
-
type: "backup";
|
|
286
|
-
fileContents: string;
|
|
287
|
-
password: string;
|
|
288
|
-
}
|
|
289
|
-
export interface RecoveryPhraseRecoveryMethod {
|
|
290
|
-
type: "phrase";
|
|
291
|
-
phrase: string;
|
|
292
|
-
}
|
|
293
|
-
/** @deprecated Use RecoveryInput instead. Kept for legacy SSSKeyManager class. */
|
|
294
|
-
export type RecoveryMethod = PasskeyRecoveryMethod | BackupFileRecoveryMethod | RecoveryPhraseRecoveryMethod;
|
|
295
|
-
/**
|
|
296
|
-
* SSS-specific recovery input — what the user provides to recover their key.
|
|
297
|
-
*/
|
|
298
|
-
export type RecoveryInput = {
|
|
299
|
-
method: "passkey";
|
|
300
|
-
credentialId: string;
|
|
301
|
-
} | {
|
|
302
|
-
method: "phrase";
|
|
303
|
-
phrase: string;
|
|
304
|
-
} | {
|
|
305
|
-
method: "backup";
|
|
306
|
-
fileContents: string;
|
|
307
|
-
password: string;
|
|
308
|
-
} | {
|
|
309
|
-
method: "email";
|
|
310
|
-
emailShare: string;
|
|
311
|
-
};
|
|
312
|
-
/**
|
|
313
|
-
* SSS-specific recovery setup input — what the user provides to set up a method.
|
|
314
|
-
*/
|
|
315
|
-
export type RecoverySetupInput = {
|
|
316
|
-
method: "passkey";
|
|
317
|
-
} | {
|
|
318
|
-
method: "phrase";
|
|
319
|
-
} | {
|
|
320
|
-
method: "backup";
|
|
321
|
-
password: string;
|
|
322
|
-
did: string;
|
|
323
|
-
} | {
|
|
324
|
-
method: "email";
|
|
325
|
-
};
|
|
326
|
-
/**
|
|
327
|
-
* SSS-specific recovery setup result.
|
|
328
|
-
*/
|
|
329
|
-
export type RecoverySetupResult = {
|
|
330
|
-
method: "passkey";
|
|
331
|
-
credentialId: string;
|
|
332
|
-
} | {
|
|
333
|
-
method: "phrase";
|
|
334
|
-
phrase: string;
|
|
335
|
-
} | {
|
|
336
|
-
method: "backup";
|
|
337
|
-
backupFile: BackupFile;
|
|
338
|
-
} | {
|
|
339
|
-
method: "email";
|
|
340
|
-
};
|
|
341
|
-
export interface EncryptedShare {
|
|
342
|
-
encryptedData: string;
|
|
343
|
-
iv: string;
|
|
344
|
-
salt?: string;
|
|
345
|
-
}
|
|
346
|
-
export interface ServerEncryptedShare {
|
|
347
|
-
encryptedData: string;
|
|
348
|
-
encryptedDek: string;
|
|
349
|
-
iv: string;
|
|
350
|
-
}
|
|
351
|
-
export interface UserKeyRecord {
|
|
352
|
-
contactMethod: ContactMethod;
|
|
353
|
-
authProviders: AuthProviderMapping[];
|
|
354
|
-
primaryDid: string;
|
|
355
|
-
linkedDids: string[];
|
|
356
|
-
keyProvider: "web3auth" | "sss";
|
|
357
|
-
authShare?: ServerEncryptedShare;
|
|
358
|
-
securityLevel: SecurityLevel;
|
|
359
|
-
recoveryMethods: RecoveryMethodInfo[];
|
|
360
|
-
migratedFromWeb3Auth: boolean;
|
|
361
|
-
migratedAt?: Date;
|
|
362
|
-
createdAt: Date;
|
|
363
|
-
updatedAt: Date;
|
|
364
|
-
}
|
|
365
|
-
export interface BackupFile {
|
|
366
|
-
version: 1;
|
|
367
|
-
createdAt: string;
|
|
368
|
-
primaryDid: string;
|
|
369
|
-
shareVersion?: number;
|
|
370
|
-
encryptedShare: {
|
|
371
|
-
ciphertext: string;
|
|
372
|
-
iv: string;
|
|
373
|
-
salt: string;
|
|
374
|
-
kdfParams: {
|
|
375
|
-
algorithm: "argon2id";
|
|
376
|
-
timeCost: number;
|
|
377
|
-
memoryCost: number;
|
|
378
|
-
parallelism: number;
|
|
379
|
-
};
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
export interface SSSKeyManagerConfig {
|
|
383
|
-
serverUrl: string;
|
|
384
|
-
authProvider: AuthProvider;
|
|
385
|
-
deviceStorageKey?: string;
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* The SSS key derivation strategy — a KeyDerivationStrategy narrowed
|
|
389
|
-
* with SSS-specific recovery input/output types.
|
|
390
|
-
*/
|
|
391
|
-
export type SSSKeyDerivationStrategy = KeyDerivationStrategy<RecoveryInput, RecoverySetupInput, RecoverySetupResult>;
|
|
392
|
-
/** @deprecated Use KeyDerivationStrategy instead. Kept for legacy SSSKeyManager class. */
|
|
393
|
-
export interface KeyDerivationProvider {
|
|
394
|
-
readonly name: string;
|
|
395
|
-
connect(): Promise<string>;
|
|
396
|
-
disconnect(): Promise<void>;
|
|
397
|
-
isInitialized(): boolean;
|
|
398
|
-
hasLocalKey(): Promise<boolean>;
|
|
399
|
-
canMigrate?(): Promise<boolean>;
|
|
400
|
-
migrate?(privateKey: string): Promise<void>;
|
|
401
|
-
}
|
|
402
|
-
/** @deprecated Use KeyDerivationStrategy instead. Kept for legacy SSSKeyManager class. */
|
|
403
|
-
export interface SSSKeyDerivationProvider extends KeyDerivationProvider {
|
|
404
|
-
addRecoveryMethod(method: RecoveryMethod): Promise<void>;
|
|
405
|
-
getRecoveryMethods(): Promise<RecoveryMethodInfo[]>;
|
|
406
|
-
recover(method: RecoveryMethod): Promise<string>;
|
|
407
|
-
getSecurityLevel(): Promise<SecurityLevel>;
|
|
408
|
-
exportBackup(password: string): Promise<BackupFile>;
|
|
409
|
-
}
|
|
410
|
-
export declare class SSSKeyManager implements SSSKeyDerivationProvider {
|
|
411
|
-
readonly name = "sss";
|
|
412
|
-
private config;
|
|
413
|
-
private apiClient;
|
|
414
|
-
private initialized;
|
|
415
|
-
private currentPrivateKey;
|
|
416
|
-
constructor(config: SSSKeyManagerConfig);
|
|
417
|
-
isInitialized(): boolean;
|
|
418
|
-
hasLocalKey(): Promise<boolean>;
|
|
419
|
-
connect(): Promise<string>;
|
|
420
|
-
disconnect(): Promise<void>;
|
|
421
|
-
setupNewKey(): Promise<string>;
|
|
422
|
-
setupWithKey(privateKey: string, primaryDid?: string): Promise<void>;
|
|
423
|
-
migrate(privateKey: string): Promise<void>;
|
|
424
|
-
canMigrate(): Promise<boolean>;
|
|
425
|
-
addRecoveryMethod(method: RecoveryMethod): Promise<void>;
|
|
426
|
-
generateRecoveryPhrase(): Promise<string>;
|
|
427
|
-
getRecoveryMethods(): Promise<RecoveryMethodInfo[]>;
|
|
428
|
-
recover(method: RecoveryMethod): Promise<string>;
|
|
429
|
-
getSecurityLevel(): Promise<SecurityLevel>;
|
|
430
|
-
exportBackup(password: string): Promise<BackupFile>;
|
|
431
|
-
clearLocalData(): Promise<void>;
|
|
432
|
-
deleteAccount(): Promise<void>;
|
|
433
|
-
}
|
|
434
|
-
export declare function createSSSKeyManager(config: SSSKeyManagerConfig): SSSKeyManager;
|
|
435
|
-
export interface GetAuthShareResponse {
|
|
436
|
-
authShare: ServerEncryptedShare | null;
|
|
437
|
-
primaryDid: string | null;
|
|
438
|
-
securityLevel: SecurityLevel;
|
|
439
|
-
recoveryMethods: RecoveryMethodInfo[];
|
|
440
|
-
keyProvider: "web3auth" | "sss";
|
|
441
|
-
maskedRecoveryEmail?: string | null;
|
|
442
|
-
}
|
|
443
|
-
export interface StoreAuthShareInput {
|
|
444
|
-
authShare: ServerEncryptedShare;
|
|
445
|
-
primaryDid: string;
|
|
446
|
-
securityLevel?: SecurityLevel;
|
|
447
|
-
}
|
|
448
|
-
export interface StoreRecoveryShareInput {
|
|
449
|
-
type: "passkey" | "backup" | "phrase" | "email";
|
|
450
|
-
encryptedShare?: EncryptedShare;
|
|
451
|
-
credentialId?: string;
|
|
452
|
-
shareVersion?: number;
|
|
453
|
-
}
|
|
454
|
-
export interface ApiClientConfig {
|
|
455
|
-
serverUrl: string;
|
|
456
|
-
authProvider: AuthProvider;
|
|
457
|
-
}
|
|
458
|
-
export declare class SSSApiClient {
|
|
459
|
-
private serverUrl;
|
|
460
|
-
private authProvider;
|
|
461
|
-
constructor(config: ApiClientConfig);
|
|
462
|
-
private getAuthHeaders;
|
|
463
|
-
private getContactMethodFromUser;
|
|
464
|
-
getAuthShare(): Promise<GetAuthShareResponse | null>;
|
|
465
|
-
storeAuthShare(input: StoreAuthShareInput): Promise<void>;
|
|
466
|
-
addRecoveryMethod(input: StoreRecoveryShareInput): Promise<void>;
|
|
467
|
-
getRecoveryShare(type: "passkey" | "backup" | "phrase" | "email", credentialId?: string): Promise<{
|
|
468
|
-
encryptedShare?: EncryptedShare;
|
|
469
|
-
shareVersion?: number;
|
|
470
|
-
} | null>;
|
|
471
|
-
markMigrated(): Promise<void>;
|
|
472
|
-
sendEmailBackupShare(emailShare: string, overrideEmail?: string): Promise<void>;
|
|
473
|
-
addRecoveryEmail(email: string): Promise<void>;
|
|
474
|
-
verifyRecoveryEmail(code: string): Promise<{
|
|
475
|
-
maskedEmail: string;
|
|
476
|
-
}>;
|
|
477
|
-
deleteUserKey(): Promise<void>;
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* Shamir Secret Sharing operations
|
|
481
|
-
*/
|
|
482
|
-
export declare const SSS_TOTAL_SHARES = 4;
|
|
483
|
-
export declare const SSS_THRESHOLD = 2;
|
|
484
|
-
export interface SSSShares {
|
|
485
|
-
deviceShare: string;
|
|
486
|
-
authShare: string;
|
|
487
|
-
recoveryShare: string;
|
|
488
|
-
emailShare: string;
|
|
489
|
-
}
|
|
490
|
-
export declare function splitPrivateKey(privateKeyHex: string): Promise<SSSShares>;
|
|
491
|
-
export declare function reconstructPrivateKey(share1Hex: string, share2Hex: string): Promise<string>;
|
|
492
|
-
export declare function reconstructFromShares(shares: string[]): Promise<string>;
|
|
493
|
-
/**
|
|
494
|
-
* Device-side storage for SSS shares
|
|
495
|
-
* Reuses patterns from webSecureStorage but specialized for SSS
|
|
496
|
-
*/
|
|
497
|
-
export declare function storeDeviceShare(share: string, id?: string): Promise<void>;
|
|
498
|
-
/**
|
|
499
|
-
* Store the share version alongside a device share.
|
|
500
|
-
* Stored as a separate key `{id}:version` to avoid changing the encryption format.
|
|
501
|
-
*/
|
|
502
|
-
export declare function storeShareVersion(version: number, id?: string): Promise<void>;
|
|
503
|
-
/**
|
|
504
|
-
* Retrieve the share version for a device share.
|
|
505
|
-
* Returns null if no version is stored (legacy shares).
|
|
506
|
-
*/
|
|
507
|
-
export declare function getShareVersion(id?: string): Promise<number | null>;
|
|
508
|
-
export declare function getDeviceShare(id?: string): Promise<string | null>;
|
|
509
|
-
export declare function hasDeviceShare(id?: string): Promise<boolean>;
|
|
510
|
-
export declare function deleteDeviceShare(id?: string): Promise<void>;
|
|
511
|
-
export interface DeviceShareEntry {
|
|
512
|
-
id: string;
|
|
513
|
-
preview: string;
|
|
514
|
-
shareVersion?: number;
|
|
515
|
-
}
|
|
516
|
-
/**
|
|
517
|
-
* List all device shares stored in IndexedDB.
|
|
518
|
-
* Returns the storage key and a truncated preview for each share.
|
|
519
|
-
* Useful for debugging multi-account storage.
|
|
520
|
-
*/
|
|
521
|
-
export declare function listAllDeviceShares(): Promise<DeviceShareEntry[]>;
|
|
522
|
-
export declare function isPublicComputerMode(): boolean;
|
|
523
|
-
export declare function setPublicComputerMode(enabled: boolean): void;
|
|
524
|
-
/**
|
|
525
|
-
* Create storage functions that dynamically route to sessionStorage (public
|
|
526
|
-
* computer mode) or IndexedDB (normal mode) based on the `lc-session-mode`
|
|
527
|
-
* flag in sessionStorage. Checked at call time, not at creation time.
|
|
528
|
-
*/
|
|
529
|
-
export declare function createAdaptiveStorage(): {
|
|
530
|
-
storeDeviceShare: (share: string, id?: string) => Promise<void>;
|
|
531
|
-
getDeviceShare: (id?: string) => Promise<string | null>;
|
|
532
|
-
hasDeviceShare: (id?: string) => Promise<boolean>;
|
|
533
|
-
clearAllShares: (id?: string) => Promise<void>;
|
|
534
|
-
storeShareVersion: (version: number, id?: string) => Promise<void>;
|
|
535
|
-
getShareVersion: (id?: string) => Promise<number | null>;
|
|
536
|
-
};
|
|
537
|
-
export declare function clearAllShares(id?: string): Promise<void>;
|
|
538
|
-
/**
|
|
539
|
-
* Cryptographic utilities for SSS Key Manager
|
|
540
|
-
*/
|
|
541
|
-
export interface KdfParams {
|
|
542
|
-
algorithm: "argon2id";
|
|
543
|
-
timeCost: number;
|
|
544
|
-
memoryCost: number;
|
|
545
|
-
parallelism: number;
|
|
546
|
-
}
|
|
547
|
-
export declare const DEFAULT_KDF_PARAMS: KdfParams;
|
|
548
|
-
export declare function bufferToBase64(buf: ArrayBuffer): string;
|
|
549
|
-
export declare function base64ToBuffer(b64: string): Uint8Array;
|
|
550
|
-
export declare function hexToBytes(hex: string): Uint8Array;
|
|
551
|
-
export declare function bytesToHex(bytes: Uint8Array): string;
|
|
552
|
-
export declare function deriveKeyFromPassword(password: string, salt: Uint8Array, params?: KdfParams): Promise<Uint8Array>;
|
|
553
|
-
export declare function encryptWithPassword(plaintext: string, password: string): Promise<{
|
|
554
|
-
ciphertext: string;
|
|
555
|
-
iv: string;
|
|
556
|
-
salt: string;
|
|
557
|
-
kdfParams: KdfParams;
|
|
558
|
-
}>;
|
|
559
|
-
export declare function decryptWithPassword(ciphertext: string, iv: string, salt: string, password: string, params?: KdfParams): Promise<string>;
|
|
560
|
-
export declare function generateEd25519PrivateKey(): Promise<string>;
|
|
561
|
-
/**
|
|
562
|
-
* WebAuthn Passkey utilities for SSS recovery
|
|
563
|
-
* Uses the PRF (Pseudo-Random Function) extension to derive encryption keys
|
|
564
|
-
*/
|
|
565
|
-
export interface PasskeyCredential {
|
|
566
|
-
credentialId: string;
|
|
567
|
-
publicKey: string;
|
|
568
|
-
transports?: AuthenticatorTransport[];
|
|
569
|
-
}
|
|
570
|
-
export interface PasskeyEncryptedShare {
|
|
571
|
-
encryptedData: string;
|
|
572
|
-
iv: string;
|
|
573
|
-
credentialId: string;
|
|
574
|
-
}
|
|
575
|
-
export declare function isWebAuthnSupported(): boolean;
|
|
576
|
-
export declare function isPRFSupported(): Promise<boolean>;
|
|
577
|
-
export declare function createPasskeyCredential(userId: string, userName: string): Promise<PasskeyCredential>;
|
|
578
|
-
export declare function deriveKeyFromPasskey(credentialId: string): Promise<CryptoKey>;
|
|
579
|
-
export declare function encryptShareWithPasskey(share: string, credentialId: string): Promise<PasskeyEncryptedShare>;
|
|
580
|
-
export declare function decryptShareWithPasskey(encryptedShare: PasskeyEncryptedShare): Promise<string>;
|
|
581
|
-
/**
|
|
582
|
-
* BIP39 Recovery Phrase utilities for SSS recovery
|
|
583
|
-
* The recovery phrase directly encodes a share (not encryption)
|
|
584
|
-
*/
|
|
585
|
-
export interface RecoveryPhraseData {
|
|
586
|
-
phrase: string;
|
|
587
|
-
shareHex: string;
|
|
588
|
-
}
|
|
589
|
-
export declare function shareToRecoveryPhrase(shareHex: string): Promise<string>;
|
|
590
|
-
export declare function recoveryPhraseToShare(phrase: string): Promise<string>;
|
|
591
|
-
export declare function generateRecoveryPhrase(shareHex: string): Promise<RecoveryPhraseData>;
|
|
592
|
-
export declare function validateRecoveryPhrase(phrase: string): Promise<boolean>;
|
|
593
|
-
export declare function countWords(phrase: string): number;
|
|
594
|
-
export interface AtomicSplitResult {
|
|
595
|
-
privateKey: string;
|
|
596
|
-
shares: SSSShares;
|
|
597
|
-
verified: boolean;
|
|
598
|
-
}
|
|
599
|
-
export interface AtomicUpdateOptions {
|
|
600
|
-
previousDeviceShare?: string;
|
|
601
|
-
previousAuthShare?: string;
|
|
602
|
-
onRollback?: (reason: string) => void;
|
|
603
|
-
}
|
|
604
|
-
export interface StorageOperations {
|
|
605
|
-
storeDevice: (share: string) => Promise<void>;
|
|
606
|
-
storeAuth: (share: string) => Promise<void>;
|
|
607
|
-
getDevice?: () => Promise<string | null>;
|
|
608
|
-
getAuth?: () => Promise<string | null>;
|
|
609
|
-
}
|
|
610
|
-
export declare class ShareVerificationError extends Error {
|
|
611
|
-
readonly combination: string;
|
|
612
|
-
readonly expected: string;
|
|
613
|
-
readonly got: string;
|
|
614
|
-
constructor(message: string, combination: string, expected: string, got: string);
|
|
615
|
-
}
|
|
616
|
-
export declare class AtomicUpdateError extends Error {
|
|
617
|
-
readonly phase: "split" | "verify" | "store_device" | "store_auth" | "verify_stored";
|
|
618
|
-
readonly rolledBack: boolean;
|
|
619
|
-
readonly cause?: Error | undefined;
|
|
620
|
-
constructor(message: string, phase: "split" | "verify" | "store_device" | "store_auth" | "verify_stored", rolledBack: boolean, cause?: Error | undefined);
|
|
621
|
-
}
|
|
622
|
-
/**
|
|
623
|
-
* Split a private key into shares and verify ALL combinations reconstruct correctly.
|
|
624
|
-
*
|
|
625
|
-
* This function will NOT return until verification passes. If verification fails,
|
|
626
|
-
* it throws an error - no shares are ever returned that don't reconstruct the key.
|
|
627
|
-
*
|
|
628
|
-
* @param privateKey - The private key to split (hex string)
|
|
629
|
-
* @returns Verified shares that are guaranteed to reconstruct the key
|
|
630
|
-
* @throws ShareVerificationError if any share combination fails verification
|
|
631
|
-
*/
|
|
632
|
-
export declare function splitAndVerify(privateKey: string): Promise<AtomicSplitResult>;
|
|
633
|
-
/**
|
|
634
|
-
* Atomically update shares with rollback on failure.
|
|
635
|
-
*
|
|
636
|
-
* This function ensures that either:
|
|
637
|
-
* 1. Both device and auth shares are updated successfully, OR
|
|
638
|
-
* 2. The previous state is restored (rollback)
|
|
639
|
-
*
|
|
640
|
-
* The operation flow:
|
|
641
|
-
* 1. Generate and verify new shares
|
|
642
|
-
* 2. Store device share locally
|
|
643
|
-
* 3. Store auth share on server
|
|
644
|
-
* 4. If step 3 fails, rollback step 2
|
|
645
|
-
*
|
|
646
|
-
* @param privateKey - The private key to split
|
|
647
|
-
* @param storage - Storage operations for device and auth shares
|
|
648
|
-
* @param options - Options including previous shares for rollback
|
|
649
|
-
* @returns The new verified shares
|
|
650
|
-
* @throws AtomicUpdateError with rollback status
|
|
651
|
-
*/
|
|
652
|
-
export declare function atomicShareUpdate(privateKey: string, storage: StorageOperations, options?: AtomicUpdateOptions): Promise<SSSShares>;
|
|
653
|
-
/**
|
|
654
|
-
* Verify that stored shares can reconstruct the expected private key.
|
|
655
|
-
*
|
|
656
|
-
* This is a health check that should be run after recovery or on login
|
|
657
|
-
* to ensure the user's shares are in a consistent state.
|
|
658
|
-
*
|
|
659
|
-
* @param storage - Storage operations to retrieve shares
|
|
660
|
-
* @param expectedDid - The expected DID (used to verify the reconstructed key)
|
|
661
|
-
* @param didFromPrivateKey - Function to derive DID from private key
|
|
662
|
-
* @returns Object with health status and details
|
|
663
|
-
*/
|
|
664
|
-
export declare function verifyStoredShares(storage: Pick<StorageOperations, "getDevice" | "getAuth">, expectedDid: string, didFromPrivateKey: (privateKey: string) => Promise<string>): Promise<{
|
|
665
|
-
healthy: boolean;
|
|
666
|
-
hasDeviceShare: boolean;
|
|
667
|
-
hasAuthShare: boolean;
|
|
668
|
-
didMatches: boolean;
|
|
669
|
-
error?: string;
|
|
670
|
-
}>;
|
|
671
|
-
/**
|
|
672
|
-
* Create a recovery operation that atomically updates all shares.
|
|
673
|
-
*
|
|
674
|
-
* This is used during recovery when we reconstruct from recovery+auth shares
|
|
675
|
-
* and need to generate a new device share.
|
|
676
|
-
*
|
|
677
|
-
* @param recoveryShare - The decrypted recovery share
|
|
678
|
-
* @param authShareData - The auth share from server
|
|
679
|
-
* @param storage - Storage operations
|
|
680
|
-
* @param options - Atomic update options
|
|
681
|
-
* @returns The reconstructed private key and new shares
|
|
682
|
-
*/
|
|
683
|
-
export declare function atomicRecovery(recoveryShare: string, authShareData: string, storage: StorageOperations, options?: AtomicUpdateOptions): Promise<{
|
|
684
|
-
privateKey: string;
|
|
685
|
-
newShares: SSSShares;
|
|
686
|
-
}>;
|
|
687
|
-
export interface SSSStorageFunctions {
|
|
688
|
-
storeDeviceShare: (share: string, id?: string) => Promise<void>;
|
|
689
|
-
getDeviceShare: (id?: string) => Promise<string | null>;
|
|
690
|
-
hasDeviceShare: (id?: string) => Promise<boolean>;
|
|
691
|
-
clearAllShares: (id?: string) => Promise<void>;
|
|
692
|
-
storeShareVersion: (version: number, id?: string) => Promise<void>;
|
|
693
|
-
getShareVersion: (id?: string) => Promise<number | null>;
|
|
694
|
-
}
|
|
695
|
-
export interface SSSStrategyConfig {
|
|
696
|
-
/** Server URL for key share operations */
|
|
697
|
-
serverUrl: string;
|
|
698
|
-
/** Custom storage functions (defaults to IndexedDB) */
|
|
699
|
-
storage?: SSSStorageFunctions;
|
|
700
|
-
/**
|
|
701
|
-
* Whether to automatically send a backup share to the user's email
|
|
702
|
-
* during key setup and recovery. The share is relayed through the server
|
|
703
|
-
* but never persisted — fire-and-forget.
|
|
704
|
-
*
|
|
705
|
-
* Defaults to false. Controlled by VITE_ENABLE_EMAIL_BACKUP_SHARE env var.
|
|
706
|
-
*/
|
|
707
|
-
enableEmailBackupShare?: boolean;
|
|
708
|
-
/**
|
|
709
|
-
* Tenant identifier forwarded as `X-Tenant-Id` on every server request.
|
|
710
|
-
* The lca-api uses this to brand recovery / OTP emails for the active
|
|
711
|
-
* tenant. Defaults to the server's fallback tenant (learncard) when unset.
|
|
712
|
-
*/
|
|
713
|
-
tenantId?: string;
|
|
714
|
-
}
|
|
715
|
-
/**
|
|
716
|
-
* Create an SSS key derivation strategy.
|
|
717
|
-
*
|
|
718
|
-
* @example
|
|
719
|
-
* ```ts
|
|
720
|
-
* const sssStrategy = createSSSStrategy({
|
|
721
|
-
* serverUrl: 'https://api.learncard.com',
|
|
722
|
-
* });
|
|
723
|
-
*
|
|
724
|
-
* // Use with AuthCoordinator
|
|
725
|
-
* const coordinator = createAuthCoordinator({
|
|
726
|
-
* authProvider,
|
|
727
|
-
* keyDerivation: sssStrategy,
|
|
728
|
-
* });
|
|
729
|
-
* ```
|
|
730
|
-
*/
|
|
731
|
-
export declare function createSSSStrategy(config: SSSStrategyConfig): SSSKeyDerivationStrategy;
|
|
732
|
-
/**
|
|
733
|
-
* QR Login Crypto Helpers
|
|
734
|
-
*
|
|
735
|
-
* X25519 ECDH key exchange + AES-256-GCM encryption for cross-device
|
|
736
|
-
* share transfer. Uses the Web Crypto API exclusively — no external deps.
|
|
737
|
-
*
|
|
738
|
-
* Flow:
|
|
739
|
-
* Device B generates an ephemeral X25519 keypair, shares the public key.
|
|
740
|
-
* Device A derives a shared secret via ECDH, encrypts the device share
|
|
741
|
-
* with AES-256-GCM, and sends the ciphertext.
|
|
742
|
-
* Device B decrypts with the same derived shared secret.
|
|
743
|
-
*/
|
|
744
|
-
export interface EphemeralKeypair {
|
|
745
|
-
/** Base64-encoded X25519 public key (sent to server / encoded in QR) */
|
|
746
|
-
publicKey: string;
|
|
747
|
-
/** Raw CryptoKey — kept in memory on Device B, never leaves the device */
|
|
748
|
-
privateKey: CryptoKey;
|
|
749
|
-
}
|
|
750
|
-
export interface EncryptedSharePayload {
|
|
751
|
-
/** Base64-encoded AES-256-GCM ciphertext */
|
|
752
|
-
ciphertext: string;
|
|
753
|
-
/** Base64-encoded 12-byte IV */
|
|
754
|
-
iv: string;
|
|
755
|
-
/** Base64-encoded ephemeral public key of the *sender* (Device A) */
|
|
756
|
-
senderPublicKey: string;
|
|
757
|
-
}
|
|
758
|
-
/**
|
|
759
|
-
* Generate an ephemeral X25519 keypair for the new device (Device B).
|
|
760
|
-
* The public key is shared via QR / short code; the private key stays in memory.
|
|
761
|
-
*/
|
|
762
|
-
export declare const generateEphemeralKeypair: () => Promise<EphemeralKeypair>;
|
|
763
|
-
/**
|
|
764
|
-
* Encrypt a device share for transfer to Device B.
|
|
765
|
-
*
|
|
766
|
-
* Called by Device A (the logged-in device):
|
|
767
|
-
* 1. Generates its own ephemeral X25519 keypair
|
|
768
|
-
* 2. Derives a shared secret from its private key + Device B's public key
|
|
769
|
-
* 3. Encrypts the share with AES-256-GCM
|
|
770
|
-
* 4. Returns the ciphertext + IV + Device A's ephemeral public key
|
|
771
|
-
*
|
|
772
|
-
* @param deviceShare - Plaintext device share to encrypt
|
|
773
|
-
* @param recipientPublicKey - Base64-encoded X25519 public key from Device B
|
|
774
|
-
*/
|
|
775
|
-
export declare const encryptShareForTransfer: (deviceShare: string, recipientPublicKey: string) => Promise<EncryptedSharePayload>;
|
|
776
|
-
/**
|
|
777
|
-
* Decrypt a device share received from Device A.
|
|
778
|
-
*
|
|
779
|
-
* Called by Device B (the new device):
|
|
780
|
-
* 1. Derives the shared secret from its private key + Device A's public key
|
|
781
|
-
* 2. Decrypts the ciphertext with AES-256-GCM
|
|
782
|
-
*
|
|
783
|
-
* @param payload - The encrypted payload from Device A
|
|
784
|
-
* @param recipientPrivateKey - Device B's ephemeral private CryptoKey
|
|
785
|
-
*/
|
|
786
|
-
export declare const decryptShareFromTransfer: (payload: EncryptedSharePayload, recipientPrivateKey: CryptoKey) => Promise<string>;
|
|
787
|
-
export interface QrLoginSession {
|
|
788
|
-
sessionId: string;
|
|
789
|
-
shortCode: string;
|
|
790
|
-
expiresInSeconds: number;
|
|
791
|
-
}
|
|
792
|
-
export interface QrLoginSessionInfo {
|
|
793
|
-
sessionId: string;
|
|
794
|
-
publicKey: string;
|
|
795
|
-
status: "pending" | "approved";
|
|
796
|
-
encryptedPayload?: string;
|
|
797
|
-
approverDid?: string;
|
|
798
|
-
}
|
|
799
|
-
export interface QrLoginClientConfig {
|
|
800
|
-
serverUrl: string;
|
|
801
|
-
}
|
|
802
|
-
export interface QrPayload {
|
|
803
|
-
/** Session ID for the relay */
|
|
804
|
-
sessionId: string;
|
|
805
|
-
/** Base64-encoded ephemeral X25519 public key */
|
|
806
|
-
publicKey: string;
|
|
807
|
-
/** Server URL for the relay */
|
|
808
|
-
serverUrl: string;
|
|
809
|
-
}
|
|
810
|
-
/** Result of polling — either still waiting or the device share is ready */
|
|
811
|
-
export type PollResult = {
|
|
812
|
-
status: "pending";
|
|
813
|
-
} | {
|
|
814
|
-
status: "approved";
|
|
815
|
-
deviceShare: string;
|
|
816
|
-
approverDid: string;
|
|
817
|
-
accountHint?: string;
|
|
818
|
-
shareVersion?: number;
|
|
819
|
-
};
|
|
820
|
-
/**
|
|
821
|
-
* Create a QR login session and generate the ephemeral keypair.
|
|
822
|
-
*
|
|
823
|
-
* Returns everything Device B needs to display a QR and start polling.
|
|
824
|
-
* The ephemeral private key is kept in memory — never serialized.
|
|
825
|
-
*/
|
|
826
|
-
export declare const createQrLoginSession: (config: QrLoginClientConfig) => Promise<{
|
|
827
|
-
session: QrLoginSession;
|
|
828
|
-
ephemeralKeypair: EphemeralKeypair;
|
|
829
|
-
qrPayload: QrPayload;
|
|
830
|
-
}>;
|
|
831
|
-
/**
|
|
832
|
-
* Poll a QR login session for approval.
|
|
833
|
-
*
|
|
834
|
-
* When Device A approves, this returns the decrypted device share.
|
|
835
|
-
*
|
|
836
|
-
* @param config - Server config
|
|
837
|
-
* @param sessionId - The session to poll
|
|
838
|
-
* @param ephemeralPrivateKey - Device B's ephemeral private key (for decryption)
|
|
839
|
-
*/
|
|
840
|
-
export declare const pollQrLoginSession: (config: QrLoginClientConfig, sessionId: string, ephemeralPrivateKey: CryptoKey) => Promise<PollResult>;
|
|
841
|
-
/**
|
|
842
|
-
* Convenience: poll in a loop until approved or timeout.
|
|
843
|
-
*
|
|
844
|
-
* @param config - Server config
|
|
845
|
-
* @param sessionId - The session to poll
|
|
846
|
-
* @param ephemeralPrivateKey - Device B's ephemeral private key
|
|
847
|
-
* @param intervalMs - Polling interval (default 2000ms)
|
|
848
|
-
* @param timeoutMs - Total timeout (default 120000ms)
|
|
849
|
-
* @param onPoll - Optional callback on each poll (for UI updates)
|
|
850
|
-
*/
|
|
851
|
-
export declare const pollUntilApproved: (config: QrLoginClientConfig, sessionId: string, ephemeralPrivateKey: CryptoKey, options?: {
|
|
852
|
-
intervalMs?: number;
|
|
853
|
-
timeoutMs?: number;
|
|
854
|
-
onPoll?: (attempt: number) => void;
|
|
855
|
-
signal?: AbortSignal;
|
|
856
|
-
}) => Promise<{
|
|
857
|
-
deviceShare: string;
|
|
858
|
-
approverDid: string;
|
|
859
|
-
accountHint?: string;
|
|
860
|
-
shareVersion?: number;
|
|
861
|
-
}>;
|
|
862
|
-
/**
|
|
863
|
-
* Fetch a QR login session's public key (for Device A to encrypt against).
|
|
864
|
-
*
|
|
865
|
-
* @param config - Server config
|
|
866
|
-
* @param lookup - Session ID or 6-digit short code
|
|
867
|
-
*/
|
|
868
|
-
export declare const getQrLoginSessionInfo: (config: QrLoginClientConfig, lookup: string) => Promise<QrLoginSessionInfo>;
|
|
869
|
-
/**
|
|
870
|
-
* Approve a QR login session by encrypting and pushing the device share.
|
|
871
|
-
*
|
|
872
|
-
* Called by Device A (the logged-in device).
|
|
873
|
-
*
|
|
874
|
-
* @param config - Server config
|
|
875
|
-
* @param sessionId - The session to approve
|
|
876
|
-
* @param deviceShare - Plaintext device share from Device A's local storage
|
|
877
|
-
* @param approverDid - DID of the approving device
|
|
878
|
-
* @param recipientPublicKey - Base64 X25519 public key from the session
|
|
879
|
-
* @param accountHint - Optional email or phone of the approver's account (sent to Device B as a login hint)
|
|
880
|
-
* @param shareVersion - Optional share version so Device B can fetch the matching auth share
|
|
881
|
-
*/
|
|
882
|
-
export declare const approveQrLoginSession: (config: QrLoginClientConfig, sessionId: string, deviceShare: string, approverDid: string, recipientPublicKey: string, accountHint?: string, shareVersion?: number) => Promise<void>;
|
|
883
|
-
export interface NotifyDevicesResult {
|
|
884
|
-
sent: boolean;
|
|
885
|
-
deviceCount: number;
|
|
886
|
-
}
|
|
887
|
-
/**
|
|
888
|
-
* Send a push notification to the authenticated user's other devices,
|
|
889
|
-
* prompting them to open the approver flow for the given QR session.
|
|
890
|
-
*
|
|
891
|
-
* Called by Device B (in needs_recovery) after creating a session.
|
|
892
|
-
* Requires the user's Firebase (or other auth provider) token.
|
|
893
|
-
*
|
|
894
|
-
* This is fire-and-forget — failure does not block the QR login flow.
|
|
895
|
-
*/
|
|
896
|
-
export declare const notifyDevicesForQrSession: (config: QrLoginClientConfig, sessionId: string, shortCode: string, authToken: string, providerType?: string) => Promise<NotifyDevicesResult>;
|
|
897
|
-
|
|
898
|
-
export {};
|