@enbox/auth 0.6.19 → 0.6.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/esm/auth-manager.js +204 -6
- package/dist/esm/auth-manager.js.map +1 -1
- package/dist/esm/connect/lifecycle.js +62 -5
- package/dist/esm/connect/lifecycle.js.map +1 -1
- package/dist/esm/connect/restore.js +321 -12
- package/dist/esm/connect/restore.js.map +1 -1
- package/dist/esm/connect/wallet.js +3 -1
- package/dist/esm/connect/wallet.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types.js +31 -0
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/wallet-connect-client.js +4 -0
- package/dist/esm/wallet-connect-client.js.map +1 -1
- package/dist/types/auth-manager.d.ts.map +1 -1
- package/dist/types/connect/lifecycle.d.ts +8 -1
- package/dist/types/connect/lifecycle.d.ts.map +1 -1
- package/dist/types/connect/restore.d.ts +16 -0
- package/dist/types/connect/restore.d.ts.map +1 -1
- package/dist/types/connect/wallet.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types.d.ts +56 -2
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/wallet-connect-client.d.ts +4 -0
- package/dist/types/wallet-connect-client.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/auth-manager.ts +198 -4
- package/src/connect/lifecycle.ts +77 -6
- package/src/connect/restore.ts +348 -13
- package/src/connect/wallet.ts +6 -1
- package/src/index.ts +6 -0
- package/src/types.ts +62 -2
- package/src/wallet-connect-client.ts +11 -3
|
@@ -8,11 +8,27 @@
|
|
|
8
8
|
import type { AuthSession } from '../identity-session.js';
|
|
9
9
|
import type { FlowContext } from './lifecycle.js';
|
|
10
10
|
import type { RestoreSessionOptions } from '../types.js';
|
|
11
|
+
import type { StorageAdapter } from '../types.js';
|
|
12
|
+
import type { EnboxUserAgent } from '@enbox/agent';
|
|
11
13
|
/**
|
|
12
14
|
* Attempt to restore a previous session.
|
|
13
15
|
*
|
|
14
16
|
* Returns `undefined` if no previous session exists.
|
|
15
17
|
* Returns an `AuthSession` if the session was successfully restored.
|
|
18
|
+
*
|
|
19
|
+
* Two independent concerns are handled here:
|
|
20
|
+
* 1. Revocation retry maintenance (from a previous partial disconnect)
|
|
21
|
+
* 2. Normal session restore
|
|
22
|
+
* They do NOT depend on each other. Both can run in the same call.
|
|
16
23
|
*/
|
|
17
24
|
export declare function restoreSession(ctx: FlowContext, options?: RestoreSessionOptions): Promise<AuthSession | undefined>;
|
|
25
|
+
/**
|
|
26
|
+
* Retry grant revocations that were not confirmed by the owner's remote
|
|
27
|
+
* DWN during a previous disconnect. Called from `restoreSession()` AFTER
|
|
28
|
+
* sync is started and only when `REVOCATION_RETRY_CONTEXT` exists.
|
|
29
|
+
*
|
|
30
|
+
* This function does NOT restore a session — the user explicitly
|
|
31
|
+
* disconnected and the retry is purely a background cleanup.
|
|
32
|
+
*/
|
|
33
|
+
export declare function retryOrphanedRevocations(userAgent: EnboxUserAgent, storage: StorageAdapter): Promise<void>;
|
|
18
34
|
//# sourceMappingURL=restore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../../../src/connect/restore.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../../../src/connect/restore.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAUnD;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,WAAW,EAChB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAyLlC;AA4LD;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC,CA6Cf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../../src/connect/wallet.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAQxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAExD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../../src/connect/wallet.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAQxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAExD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,WAAW,CAAC,CAuDtB"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -39,5 +39,7 @@ export type { ProtocolPermissionOptions, WalletConnectClientOptions } from './wa
|
|
|
39
39
|
export { loadTokensFromStorage, saveTokensToStorage } from './registration.js';
|
|
40
40
|
export { applyLocalDwnDiscovery, checkUrlForDwnDiscoveryPayload, clearLocalDwnEndpoint, discoverLocalDwn, persistLocalDwnEndpoint, requestLocalDwnDiscovery, restoreLocalDwnEndpoint, } from './discovery.js';
|
|
41
41
|
export { BrowserStorage, LevelStorage, MemoryStorage, createDefaultStorage } from './storage/storage.js';
|
|
42
|
+
export { retryOrphanedRevocations } from './connect/restore.js';
|
|
43
|
+
export { STORAGE_KEYS } from './types.js';
|
|
42
44
|
export type { AuthEvent, AuthEventHandler, AuthEventMap, AuthManagerOptions, AuthSessionInfo, AuthState, ConnectHandler, ConnectOptions, ConnectPermissionRequest, ConnectResult, DisconnectOptions, HandlerConnectOptions, HeadlessConnectOptions, IdentityInfo, IdentityVaultBackup, ImportFromPhraseOptions, ImportFromPortableOptions, LocalConnectOptions, LocalDwnStrategy, Permission, PortableIdentity, ProtocolRequest, ProviderAuthParams, ProviderAuthResult, RegistrationOptions, RegistrationTokenData, RestoreSessionOptions, ShutdownOptions, StorageAdapter, SyncOption, WalletConnectOptions, } from './types.js';
|
|
43
45
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAI9D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,YAAY,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAGxG,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG/E,OAAO,EACL,sBAAsB,EACtB,8BAA8B,EAC9B,qBAAqB,EACrB,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGzG,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,SAAS,EACT,cAAc,EACd,cAAc,EACd,wBAAwB,EACxB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,mBAAmB,EACnB,uBAAuB,EACvB,yBAAyB,EACzB,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,UAAU,EACV,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAI9D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,YAAY,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAGxG,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG/E,OAAO,EACL,sBAAsB,EACtB,8BAA8B,EAC9B,qBAAqB,EACrB,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGzG,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAGhE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,SAAS,EACT,cAAc,EACd,cAAc,EACd,wBAAwB,EACxB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,mBAAmB,EACnB,uBAAuB,EACvB,yBAAyB,EACzB,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,UAAU,EACV,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
|
package/dist/types/types.d.ts
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* Public types for the authentication and identity management SDK.
|
|
4
4
|
*/
|
|
5
5
|
import type { PortableDid } from '@enbox/dids';
|
|
6
|
-
import type { ConnectPermissionRequest, DwnDataEncodedRecordsWriteMessage, DwnProtocolDefinition, EnboxUserAgent, HdIdentityVault, LocalDwnStrategy, PortableIdentity } from '@enbox/agent';
|
|
6
|
+
import type { ConnectPermissionRequest, DelegateContextKey, DelegateDecryptionKey, DwnDataEncodedRecordsWriteMessage, DwnProtocolDefinition, EnboxUserAgent, HdIdentityVault, LocalDwnStrategy, PortableIdentity } from '@enbox/agent';
|
|
7
7
|
import type { PasswordProvider } from './password-provider.js';
|
|
8
|
-
export type { ConnectPermissionRequest, HdIdentityVault, IdentityVaultBackup, LocalDwnStrategy, PortableIdentity } from '@enbox/agent';
|
|
8
|
+
export type { ConnectPermissionRequest, DelegateContextKey, DelegateDecryptionKey, HdIdentityVault, IdentityVaultBackup, LocalDwnStrategy, PortableIdentity } from '@enbox/agent';
|
|
9
9
|
export type { EnboxUserAgent } from '@enbox/agent';
|
|
10
10
|
/**
|
|
11
11
|
* Controls DWN synchronisation behaviour.
|
|
@@ -187,6 +187,29 @@ export interface ConnectResult {
|
|
|
187
187
|
delegateGrants: DwnDataEncodedRecordsWriteMessage[];
|
|
188
188
|
/** The DID of the identity the user approved (the wallet owner's DID). */
|
|
189
189
|
connectedDid: string;
|
|
190
|
+
/**
|
|
191
|
+
* Scope-aware decryption keys for encrypted protocols.
|
|
192
|
+
*
|
|
193
|
+
* Derived only for read-like permission scopes (Read/Query/Subscribe) on
|
|
194
|
+
* protocols with `encryptionRequired: true` types. Write-only delegates
|
|
195
|
+
* receive no decryption keys.
|
|
196
|
+
*/
|
|
197
|
+
delegateDecryptionKeys?: DelegateDecryptionKey[];
|
|
198
|
+
/**
|
|
199
|
+
* Context-scoped decryption keys for multi-party encrypted protocols.
|
|
200
|
+
* Each key unlocks one rootContextId for records using ProtocolContext encryption.
|
|
201
|
+
*/
|
|
202
|
+
delegateContextKeys?: DelegateContextKey[];
|
|
203
|
+
/**
|
|
204
|
+
* Protocol URIs that have multi-party encrypted access patterns.
|
|
205
|
+
* Delivered even when no contexts exist yet (cold-start).
|
|
206
|
+
*/
|
|
207
|
+
delegateMultiPartyProtocols?: string[];
|
|
208
|
+
/** Per-grant revocation mappings for session-bound self-revocation on disconnect. */
|
|
209
|
+
sessionRevocations?: {
|
|
210
|
+
grantId: string;
|
|
211
|
+
revocationGrantId: string;
|
|
212
|
+
}[];
|
|
190
213
|
}
|
|
191
214
|
/**
|
|
192
215
|
* A connect handler obtains delegated credentials from a wallet.
|
|
@@ -547,6 +570,23 @@ export declare const STORAGE_KEYS: {
|
|
|
547
570
|
readonly DELEGATE_DID: "enbox:auth:delegateDid";
|
|
548
571
|
/** The connected DID (for wallet-connected sessions). */
|
|
549
572
|
readonly CONNECTED_DID: "enbox:auth:connectedDid";
|
|
573
|
+
/**
|
|
574
|
+
* JSON-serialised `DelegateDecryptionKey[]` for delegate decryption of
|
|
575
|
+
* encrypted protocol records. Persisted so session restore can re-populate
|
|
576
|
+
* the delegate decryption key cache without requiring a new connect flow.
|
|
577
|
+
*/
|
|
578
|
+
readonly DELEGATE_DECRYPTION_KEYS: "enbox:auth:delegateDecryptionKeys";
|
|
579
|
+
/**
|
|
580
|
+
* JSON-serialised `DelegateContextKey[]` for multi-party encrypted protocol
|
|
581
|
+
* records. Persisted for session restore.
|
|
582
|
+
*/
|
|
583
|
+
readonly DELEGATE_CONTEXT_KEYS: "enbox:auth:delegateContextKeys";
|
|
584
|
+
/**
|
|
585
|
+
* JSON-serialised `string[]` of multi-party protocol URIs for delegate
|
|
586
|
+
* context key eligibility. Persisted for session restore so cold-start
|
|
587
|
+
* delegates (who connected with zero contexts) still receive future keys.
|
|
588
|
+
*/
|
|
589
|
+
readonly DELEGATE_MULTI_PARTY_PROTOCOLS: "enbox:auth:delegateMultiPartyProtocols";
|
|
550
590
|
/**
|
|
551
591
|
* The base URL of the local DWN server discovered via the `dwn://connect`
|
|
552
592
|
* browser redirect flow. Persisted so subsequent page loads can skip the
|
|
@@ -563,5 +603,19 @@ export declare const STORAGE_KEYS: {
|
|
|
563
603
|
* @see https://github.com/enboxorg/enbox/issues/690
|
|
564
604
|
*/
|
|
565
605
|
readonly REGISTRATION_TOKENS: "enbox:auth:registrationTokens";
|
|
606
|
+
/**
|
|
607
|
+
* JSON-serialised `SessionRevocationEntry[]` mapping session grant IDs to
|
|
608
|
+
* their corresponding revocation grant IDs for disconnect.
|
|
609
|
+
*/
|
|
610
|
+
readonly SESSION_REVOCATIONS: "enbox:auth:sessionRevocations";
|
|
611
|
+
/**
|
|
612
|
+
* Self-contained collection of revocation retry entries from previous
|
|
613
|
+
* partial disconnects. JSON-serialised array of
|
|
614
|
+
* `{ delegateDid, connectedDid, revocations }` entries, one per
|
|
615
|
+
* session. Keyed by `delegateDid` (unique per session).
|
|
616
|
+
*
|
|
617
|
+
* Completely independent from active session state.
|
|
618
|
+
*/
|
|
619
|
+
readonly REVOCATION_RETRY_CONTEXT: "enbox:auth:revocationRetryContext";
|
|
566
620
|
};
|
|
567
621
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,wBAAwB,EAAE,iCAAiC,EAAE,qBAAqB,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -70,6 +70,10 @@ declare function initClient({ displayName, connectServerUrl, walletUri, permissi
|
|
|
70
70
|
delegateGrants: EnboxConnectResponse['delegateGrants'];
|
|
71
71
|
delegatePortableDid: EnboxConnectResponse['delegatePortableDid'];
|
|
72
72
|
connectedDid: string;
|
|
73
|
+
delegateDecryptionKeys?: EnboxConnectResponse['delegateDecryptionKeys'];
|
|
74
|
+
delegateContextKeys?: EnboxConnectResponse['delegateContextKeys'];
|
|
75
|
+
delegateMultiPartyProtocols?: EnboxConnectResponse['delegateMultiPartyProtocols'];
|
|
76
|
+
sessionRevocations?: EnboxConnectResponse['sessionRevocations'];
|
|
73
77
|
} | undefined>;
|
|
74
78
|
/**
|
|
75
79
|
* Creates a set of Dwn Permission Scopes to request for a given protocol.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wallet-connect-client.d.ts","sourceRoot":"","sources":["../../src/wallet-connect-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAsB,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACxG,OAAO,KAAK,EAAyB,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAQhF;;;;;;GAMG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;IAEpB,sFAAsF;IACtF,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,kBAAkB,EAAE,wBAAwB,EAAE,CAAC;IAE/C;;;;;OAKG;IACH,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC;;;;;OAKG;IACH,WAAW,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACpC,CAAC;AAEF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,+DAA+D;IAC/D,UAAU,EAAE,qBAAqB,CAAC;IAElC,uDAAuD;IACvD,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,CAAC;AAEF;;;GAGG;AACH,iBAAe,UAAU,CAAC,EACxB,WAAW,EACX,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,gBAAgB,EAChB,WAAW,GACZ,EAAE,0BAA0B,GAAG,OAAO,CAAC;IACtC,cAAc,EAAE,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IACvD,mBAAmB,EAAE,oBAAoB,CAAC,qBAAqB,CAAC,CAAC;IACjE,YAAY,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"wallet-connect-client.d.ts","sourceRoot":"","sources":["../../src/wallet-connect-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAsB,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACxG,OAAO,KAAK,EAAyB,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAQhF;;;;;;GAMG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;IAEpB,sFAAsF;IACtF,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,kBAAkB,EAAE,wBAAwB,EAAE,CAAC;IAE/C;;;;;OAKG;IACH,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC;;;;;OAKG;IACH,WAAW,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACpC,CAAC;AAEF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,+DAA+D;IAC/D,UAAU,EAAE,qBAAqB,CAAC;IAElC,uDAAuD;IACvD,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,CAAC;AAEF;;;GAGG;AACH,iBAAe,UAAU,CAAC,EACxB,WAAW,EACX,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,gBAAgB,EAChB,WAAW,GACZ,EAAE,0BAA0B,GAAG,OAAO,CAAC;IACtC,cAAc,EAAE,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IACvD,mBAAmB,EAAE,oBAAoB,CAAC,qBAAqB,CAAC,CAAC;IACjE,YAAY,EAAE,MAAM,CAAC;IACrB,sBAAsB,CAAC,EAAE,oBAAoB,CAAC,wBAAwB,CAAC,CAAC;IACxE,mBAAmB,CAAC,EAAE,oBAAoB,CAAC,qBAAqB,CAAC,CAAC;IAClE,2BAA2B,CAAC,EAAE,oBAAoB,CAAC,6BAA6B,CAAC,CAAC;IAClF,kBAAkB,CAAC,EAAE,oBAAoB,CAAC,oBAAoB,CAAC,CAAC;CACjE,GAAG,SAAS,CAAC,CAsGb;AAED;;;;;;;GAOG;AACH,iBAAS,kCAAkC,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,yBAAyB,GAAG,wBAAwB,CAsE5H;AAED,eAAO,MAAM,aAAa;;;CAAqD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enbox/auth",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.21",
|
|
4
4
|
"description": "Headless authentication and identity management SDK for Enbox",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/esm/index.js",
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
"bun": ">=1.0.0"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@enbox/agent": "0.
|
|
59
|
+
"@enbox/agent": "0.6.1",
|
|
60
60
|
"@enbox/common": "0.1.0",
|
|
61
61
|
"@enbox/crypto": "0.1.0",
|
|
62
62
|
"@enbox/dids": "0.1.0",
|
|
63
|
-
"@enbox/dwn-clients": "0.
|
|
63
|
+
"@enbox/dwn-clients": "0.3.0",
|
|
64
64
|
"@enbox/dwn-sdk-js": "0.3.2",
|
|
65
65
|
"level": "8.0.1"
|
|
66
66
|
},
|
package/src/auth-manager.ts
CHANGED
|
@@ -32,7 +32,9 @@ import type {
|
|
|
32
32
|
WalletConnectOptions,
|
|
33
33
|
} from './types.js';
|
|
34
34
|
|
|
35
|
-
import {
|
|
35
|
+
import { Convert } from '@enbox/common';
|
|
36
|
+
import { DataStream } from '@enbox/dwn-sdk-js';
|
|
37
|
+
import { DwnInterface, DwnPermissionGrant, EnboxUserAgent } from '@enbox/agent';
|
|
36
38
|
|
|
37
39
|
import { AuthEventEmitter } from './events.js';
|
|
38
40
|
import { AuthSession } from './identity-session.js';
|
|
@@ -457,13 +459,145 @@ export class AuthManager {
|
|
|
457
459
|
const { clearStorage = false, timeout = 2000 } = options;
|
|
458
460
|
const did = this._session?.did;
|
|
459
461
|
|
|
460
|
-
//
|
|
462
|
+
// Revoke delegated session grants BEFORE stopping sync so the
|
|
463
|
+
// revocations can be sent to the owner's remote DWN endpoints.
|
|
464
|
+
// Each revocation grant is contextId-scoped to the specific
|
|
465
|
+
// session grant it can revoke.
|
|
466
|
+
const delegateDid = this._session?.delegateDid;
|
|
467
|
+
const connectedDid = this._session?.did;
|
|
468
|
+
let failedRevocations: { grantId: string; revocationGrantId: string }[] = [];
|
|
469
|
+
|
|
470
|
+
if (delegateDid && connectedDid) {
|
|
471
|
+
try {
|
|
472
|
+
const revocationsJson = await this._storage.get(STORAGE_KEYS.SESSION_REVOCATIONS);
|
|
473
|
+
if (revocationsJson) {
|
|
474
|
+
const revocations: { grantId: string; revocationGrantId: string }[] = JSON.parse(revocationsJson);
|
|
475
|
+
|
|
476
|
+
// Resolve the owner's DWN endpoints for remote delivery.
|
|
477
|
+
// Resolve REMOTE owner DWN endpoints (from DID document, not local
|
|
478
|
+
// discovery). Only remote endpoints count for revocation success.
|
|
479
|
+
let remoteDwnUrls: string[] = [];
|
|
480
|
+
try {
|
|
481
|
+
remoteDwnUrls = await this._userAgent.dwn.getRemoteDwnEndpointUrls(connectedDid);
|
|
482
|
+
} catch {
|
|
483
|
+
// Endpoint resolution failure — revocations will be local-only.
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
const succeeded: string[] = [];
|
|
487
|
+
for (const { grantId, revocationGrantId } of revocations) {
|
|
488
|
+
try {
|
|
489
|
+
// Read the specific grant by recordId. Use the delegate DID
|
|
490
|
+
// as author since the delegate agent may not have the owner's
|
|
491
|
+
// signing key. The delegate is the grant's recipient, so the
|
|
492
|
+
// permissions protocol authorizes the read.
|
|
493
|
+
const { reply: readReply } = await this._userAgent.dwn.processRequest({
|
|
494
|
+
author : delegateDid,
|
|
495
|
+
target : connectedDid,
|
|
496
|
+
messageType : DwnInterface.RecordsRead,
|
|
497
|
+
messageParams : { filter: { recordId: grantId } },
|
|
498
|
+
});
|
|
499
|
+
if (readReply.status.code !== 200 || !readReply.entry) { continue; }
|
|
500
|
+
// Reconstruct DwnDataEncodedRecordsWriteMessage: RecordsRead returns
|
|
501
|
+
// data as a stream, but PermissionGrant.parse needs encodedData.
|
|
502
|
+
const grantDataBytes = readReply.entry.data
|
|
503
|
+
? await DataStream.toBytes(readReply.entry.data)
|
|
504
|
+
: new Uint8Array(0);
|
|
505
|
+
const grantMsgWithData = {
|
|
506
|
+
...readReply.entry.recordsWrite,
|
|
507
|
+
encodedData: Convert.uint8Array(grantDataBytes).toBase64Url(),
|
|
508
|
+
};
|
|
509
|
+
const grant = DwnPermissionGrant.parse(grantMsgWithData as any);
|
|
510
|
+
|
|
511
|
+
// Self-healing: ensure the revocation grant is on the remote
|
|
512
|
+
// DWN. The best-effort fanout at connect time may have failed.
|
|
513
|
+
if (remoteDwnUrls.length > 0) {
|
|
514
|
+
try {
|
|
515
|
+
const { reply: revGrantReply } = await this._userAgent.dwn.processRequest({
|
|
516
|
+
author : delegateDid,
|
|
517
|
+
target : connectedDid,
|
|
518
|
+
messageType : DwnInterface.RecordsRead,
|
|
519
|
+
messageParams : { filter: { recordId: revocationGrantId } },
|
|
520
|
+
});
|
|
521
|
+
if (revGrantReply.status.code === 200 && revGrantReply.entry?.recordsWrite) {
|
|
522
|
+
const { encodedData: revGrantEncoded, ...revGrantRaw } = revGrantReply.entry.recordsWrite as any;
|
|
523
|
+
const revGrantData = revGrantReply.entry.data
|
|
524
|
+
? new Blob([await DataStream.toBytes(revGrantReply.entry.data) as BlobPart])
|
|
525
|
+
: undefined;
|
|
526
|
+
for (const dwnUrl of remoteDwnUrls) {
|
|
527
|
+
try {
|
|
528
|
+
await this._userAgent.rpc.sendDwnRequest({
|
|
529
|
+
dwnUrl,
|
|
530
|
+
targetDid : connectedDid,
|
|
531
|
+
message : revGrantRaw,
|
|
532
|
+
data : revGrantData,
|
|
533
|
+
});
|
|
534
|
+
} catch { /* per-endpoint failure */ }
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
} catch { /* best-effort */ }
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// Create the revocation locally.
|
|
541
|
+
const { message: revocationMessage } = await this._userAgent.permissions.createRevocation({
|
|
542
|
+
author : connectedDid,
|
|
543
|
+
store : true,
|
|
544
|
+
grant,
|
|
545
|
+
granteeDid : delegateDid,
|
|
546
|
+
permissionGrantId : revocationGrantId,
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
// Send the revocation to the owner's remote DWN endpoints.
|
|
550
|
+
// A revocation is only considered successful if at least one
|
|
551
|
+
// remote endpoint confirms it (202/409). Without remote
|
|
552
|
+
// delivery, the owner-side authority source won't see it.
|
|
553
|
+
let remoteDelivered = false;
|
|
554
|
+
if (revocationMessage && remoteDwnUrls.length > 0) {
|
|
555
|
+
const { encodedData, ...rawMessage } = revocationMessage as any;
|
|
556
|
+
const data = encodedData
|
|
557
|
+
? new Blob([Convert.base64Url(encodedData).toUint8Array() as BlobPart])
|
|
558
|
+
: undefined;
|
|
559
|
+
for (const dwnUrl of remoteDwnUrls) {
|
|
560
|
+
try {
|
|
561
|
+
const sendReply = await this._userAgent.rpc.sendDwnRequest({
|
|
562
|
+
dwnUrl,
|
|
563
|
+
targetDid : connectedDid,
|
|
564
|
+
message : rawMessage as any,
|
|
565
|
+
data,
|
|
566
|
+
});
|
|
567
|
+
if (sendReply?.status?.code === 202 || sendReply?.status?.code === 409) {
|
|
568
|
+
remoteDelivered = true;
|
|
569
|
+
}
|
|
570
|
+
} catch {
|
|
571
|
+
// Per-endpoint failure — try the next one.
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
if (remoteDelivered) {
|
|
577
|
+
succeeded.push(grantId);
|
|
578
|
+
}
|
|
579
|
+
} catch {
|
|
580
|
+
// Individual revocation failure.
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
failedRevocations = revocations.filter((r) => !succeeded.includes(r.grantId));
|
|
585
|
+
}
|
|
586
|
+
} catch (error: any) {
|
|
587
|
+
console.warn(`AuthManager: Grant revocation on disconnect failed: ${error.message}`);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Stop sync AFTER revocations are sent to remote endpoints.
|
|
461
592
|
if (this._session) {
|
|
462
593
|
await this._userAgent.sync.stopSync(timeout);
|
|
463
594
|
}
|
|
464
595
|
|
|
465
596
|
this._session = undefined;
|
|
466
597
|
|
|
598
|
+
// Always clear the in-memory delegate decryption key cache on disconnect.
|
|
599
|
+
this._userAgent.dwn.clearDelegateDecryptionKeys();
|
|
600
|
+
|
|
467
601
|
if (clearStorage) {
|
|
468
602
|
// Nuclear wipe: clear all persisted auth data.
|
|
469
603
|
await this._storage.clear();
|
|
@@ -485,11 +619,66 @@ export class AuthManager {
|
|
|
485
619
|
}
|
|
486
620
|
}
|
|
487
621
|
} else {
|
|
488
|
-
// Clean disconnect:
|
|
622
|
+
// Clean disconnect: ALWAYS clear all session markers regardless
|
|
623
|
+
// of revocation outcome. Retry context is independent (step below).
|
|
489
624
|
await this._storage.remove(STORAGE_KEYS.PREVIOUSLY_CONNECTED);
|
|
490
625
|
await this._storage.remove(STORAGE_KEYS.ACTIVE_IDENTITY);
|
|
491
626
|
await this._storage.remove(STORAGE_KEYS.DELEGATE_DID);
|
|
492
627
|
await this._storage.remove(STORAGE_KEYS.CONNECTED_DID);
|
|
628
|
+
await this._storage.remove(STORAGE_KEYS.DELEGATE_DECRYPTION_KEYS);
|
|
629
|
+
await this._storage.remove(STORAGE_KEYS.DELEGATE_CONTEXT_KEYS);
|
|
630
|
+
await this._storage.remove(STORAGE_KEYS.DELEGATE_MULTI_PARTY_PROTOCOLS);
|
|
631
|
+
await this._storage.remove(STORAGE_KEYS.SESSION_REVOCATIONS);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// Update retry context — but NOT after a nuclear wipe.
|
|
635
|
+
// On failure: merge into existing collection.
|
|
636
|
+
// On success: prune any stale retry entry for this delegate.
|
|
637
|
+
if (!clearStorage && delegateDid && failedRevocations.length > 0 && connectedDid) {
|
|
638
|
+
let entries: { delegateDid: string; connectedDid: string; revocations: { grantId: string; revocationGrantId: string }[] }[] = [];
|
|
639
|
+
try {
|
|
640
|
+
const existing = await this._storage.get(STORAGE_KEYS.REVOCATION_RETRY_CONTEXT);
|
|
641
|
+
if (existing) {
|
|
642
|
+
const parsed = JSON.parse(existing);
|
|
643
|
+
if (Array.isArray(parsed)) {
|
|
644
|
+
entries = parsed;
|
|
645
|
+
} else if (parsed?.delegateDid && parsed?.connectedDid && Array.isArray(parsed?.revocations)) {
|
|
646
|
+
// Legacy single-object format — migrate to array.
|
|
647
|
+
entries = [parsed];
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
} catch { /* ignore corrupt data — start fresh */ }
|
|
651
|
+
|
|
652
|
+
// Replace or append this session's entry (keyed by delegateDid).
|
|
653
|
+
const idx = entries.findIndex((e) => e.delegateDid === delegateDid);
|
|
654
|
+
const newEntry = { delegateDid, connectedDid, revocations: failedRevocations };
|
|
655
|
+
if (idx >= 0) {
|
|
656
|
+
entries[idx] = newEntry;
|
|
657
|
+
} else {
|
|
658
|
+
entries.push(newEntry);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
await this._storage.set(STORAGE_KEYS.REVOCATION_RETRY_CONTEXT, JSON.stringify(entries));
|
|
662
|
+
console.warn(
|
|
663
|
+
`AuthManager: ${failedRevocations.length} grant revocation(s) failed. ` +
|
|
664
|
+
`Retry context persisted in REVOCATION_RETRY_CONTEXT.`
|
|
665
|
+
);
|
|
666
|
+
} else if (!clearStorage && delegateDid && failedRevocations.length === 0) {
|
|
667
|
+
// All revocations succeeded — prune any stale retry entry for this
|
|
668
|
+
// delegate from a previous partial disconnect.
|
|
669
|
+
try {
|
|
670
|
+
const existing = await this._storage.get(STORAGE_KEYS.REVOCATION_RETRY_CONTEXT);
|
|
671
|
+
if (existing) {
|
|
672
|
+
const parsed = JSON.parse(existing);
|
|
673
|
+
const arr = Array.isArray(parsed) ? parsed : [];
|
|
674
|
+
const pruned = arr.filter((e: any) => e.delegateDid !== delegateDid);
|
|
675
|
+
if (pruned.length === 0) {
|
|
676
|
+
await this._storage.remove(STORAGE_KEYS.REVOCATION_RETRY_CONTEXT);
|
|
677
|
+
} else if (pruned.length < arr.length) {
|
|
678
|
+
await this._storage.set(STORAGE_KEYS.REVOCATION_RETRY_CONTEXT, JSON.stringify(pruned));
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
} catch { /* best effort */ }
|
|
493
682
|
}
|
|
494
683
|
|
|
495
684
|
this._setState('unlocked');
|
|
@@ -834,9 +1023,14 @@ export class AuthManager {
|
|
|
834
1023
|
}
|
|
835
1024
|
|
|
836
1025
|
// 5. Import delegate DID, process grants, set up sync.
|
|
837
|
-
const {
|
|
1026
|
+
const {
|
|
1027
|
+
delegatePortableDid, connectedDid, delegateGrants, delegateDecryptionKeys,
|
|
1028
|
+
delegateContextKeys, delegateMultiPartyProtocols, sessionRevocations,
|
|
1029
|
+
} = result;
|
|
838
1030
|
const identity = await importDelegateAndSetupSync({
|
|
839
1031
|
userAgent, delegatePortableDid, connectedDid, delegateGrants,
|
|
1032
|
+
delegateDecryptionKeys, delegateContextKeys, delegateMultiPartyProtocols,
|
|
1033
|
+
sessionRevocations,
|
|
840
1034
|
flowName: 'Connect',
|
|
841
1035
|
});
|
|
842
1036
|
|
package/src/connect/lifecycle.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import type { PortableDid } from '@enbox/dids';
|
|
18
|
-
import type { BearerIdentity, DwnDataEncodedRecordsWriteMessage, DwnMessagesPermissionScope, DwnRecordsPermissionScope, EnboxUserAgent } from '@enbox/agent';
|
|
18
|
+
import type { BearerIdentity, DelegateContextKey, DelegateDecryptionKey, DwnDataEncodedRecordsWriteMessage, DwnMessagesPermissionScope, DwnRecordsPermissionScope, EnboxUserAgent } from '@enbox/agent';
|
|
19
19
|
|
|
20
20
|
import type { AuthEventEmitter } from '../events.js';
|
|
21
21
|
import type { PasswordProvider } from '../password-provider.js';
|
|
@@ -337,9 +337,17 @@ export async function importDelegateAndSetupSync(params: {
|
|
|
337
337
|
delegatePortableDid: PortableDid;
|
|
338
338
|
connectedDid: string;
|
|
339
339
|
delegateGrants: DwnDataEncodedRecordsWriteMessage[];
|
|
340
|
+
delegateDecryptionKeys?: DelegateDecryptionKey[];
|
|
341
|
+
delegateContextKeys?: DelegateContextKey[];
|
|
342
|
+
delegateMultiPartyProtocols?: string[];
|
|
343
|
+
sessionRevocations?: { grantId: string; revocationGrantId: string }[];
|
|
340
344
|
flowName: string;
|
|
341
345
|
}): Promise<BearerIdentity> {
|
|
342
|
-
const {
|
|
346
|
+
const {
|
|
347
|
+
userAgent, delegatePortableDid, connectedDid, delegateGrants,
|
|
348
|
+
delegateDecryptionKeys, delegateContextKeys, delegateMultiPartyProtocols,
|
|
349
|
+
sessionRevocations, flowName,
|
|
350
|
+
} = params;
|
|
343
351
|
|
|
344
352
|
let identity: BearerIdentity | undefined;
|
|
345
353
|
try {
|
|
@@ -362,6 +370,24 @@ export async function importDelegateAndSetupSync(params: {
|
|
|
362
370
|
grants : delegateGrants,
|
|
363
371
|
});
|
|
364
372
|
|
|
373
|
+
// Import delegate protocol path decryption keys if the wallet provided
|
|
374
|
+
// them. These enable the delegate to decrypt ProtocolPath-encrypted
|
|
375
|
+
// records without possessing the owner's root X25519 private key.
|
|
376
|
+
if (delegateDecryptionKeys && delegateDecryptionKeys.length > 0) {
|
|
377
|
+
userAgent.dwn.importDelegateDecryptionKeys(delegatePortableDid.uri, delegateDecryptionKeys);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Import context-scoped decryption keys for multi-party encrypted protocols.
|
|
381
|
+
// Always register multi-party protocols (even with zero keys) so the
|
|
382
|
+
// agent can deliver context keys for contexts created after connect.
|
|
383
|
+
if ((delegateContextKeys && delegateContextKeys.length > 0) || (delegateMultiPartyProtocols && delegateMultiPartyProtocols.length > 0)) {
|
|
384
|
+
userAgent.dwn.importDelegateContextKeys(
|
|
385
|
+
delegatePortableDid.uri,
|
|
386
|
+
delegateContextKeys ?? [],
|
|
387
|
+
delegateMultiPartyProtocols,
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
|
|
365
391
|
await userAgent.sync.registerIdentity({
|
|
366
392
|
did : connectedDid,
|
|
367
393
|
options : {
|
|
@@ -375,6 +401,20 @@ export async function importDelegateAndSetupSync(params: {
|
|
|
375
401
|
// Doing a manual pull first would double the startup burst and can
|
|
376
402
|
// trigger rate limits on the remote DWN.
|
|
377
403
|
|
|
404
|
+
// Store protocol keys on the identity for finalize to persist.
|
|
405
|
+
if (delegateDecryptionKeys && delegateDecryptionKeys.length > 0) {
|
|
406
|
+
(identity as any)._delegateDecryptionKeys = delegateDecryptionKeys;
|
|
407
|
+
}
|
|
408
|
+
if (delegateContextKeys && delegateContextKeys.length > 0) {
|
|
409
|
+
(identity as any)._delegateContextKeys = delegateContextKeys;
|
|
410
|
+
}
|
|
411
|
+
if (delegateMultiPartyProtocols && delegateMultiPartyProtocols.length > 0) {
|
|
412
|
+
(identity as any)._delegateMultiPartyProtocols = delegateMultiPartyProtocols;
|
|
413
|
+
}
|
|
414
|
+
if (sessionRevocations && sessionRevocations.length > 0) {
|
|
415
|
+
(identity as any)._sessionRevocations = sessionRevocations;
|
|
416
|
+
}
|
|
417
|
+
|
|
378
418
|
return identity;
|
|
379
419
|
} catch (error: unknown) {
|
|
380
420
|
if (identity) {
|
|
@@ -418,6 +458,40 @@ export async function finalizeDelegateSession(params: {
|
|
|
418
458
|
|
|
419
459
|
await startSyncIfEnabled(userAgent, sync);
|
|
420
460
|
|
|
461
|
+
// Persist protocol path keys alongside the delegate session markers
|
|
462
|
+
// so they survive agent restarts.
|
|
463
|
+
const delegateDecryptionKeys = (identity as any)._delegateDecryptionKeys as DelegateDecryptionKey[] | undefined;
|
|
464
|
+
const extraStorageKeys: Record<string, string> = {
|
|
465
|
+
[STORAGE_KEYS.DELEGATE_DID] : delegateDid,
|
|
466
|
+
[STORAGE_KEYS.CONNECTED_DID] : connectedDid,
|
|
467
|
+
};
|
|
468
|
+
if (delegateDecryptionKeys && delegateDecryptionKeys.length > 0) {
|
|
469
|
+
extraStorageKeys[STORAGE_KEYS.DELEGATE_DECRYPTION_KEYS] = JSON.stringify(delegateDecryptionKeys);
|
|
470
|
+
}
|
|
471
|
+
const delegateContextKeys = (identity as any)._delegateContextKeys as DelegateContextKey[] | undefined;
|
|
472
|
+
if (delegateContextKeys && delegateContextKeys.length > 0) {
|
|
473
|
+
extraStorageKeys[STORAGE_KEYS.DELEGATE_CONTEXT_KEYS] = JSON.stringify(delegateContextKeys);
|
|
474
|
+
}
|
|
475
|
+
const delegateMultiPartyProtocols = (identity as any)._delegateMultiPartyProtocols as string[] | undefined;
|
|
476
|
+
if (delegateMultiPartyProtocols && delegateMultiPartyProtocols.length > 0) {
|
|
477
|
+
extraStorageKeys[STORAGE_KEYS.DELEGATE_MULTI_PARTY_PROTOCOLS] = JSON.stringify(delegateMultiPartyProtocols);
|
|
478
|
+
}
|
|
479
|
+
const sessionRevocations = (identity as any)._sessionRevocations as { grantId: string; revocationGrantId: string }[] | undefined;
|
|
480
|
+
if (sessionRevocations && sessionRevocations.length > 0) {
|
|
481
|
+
extraStorageKeys[STORAGE_KEYS.SESSION_REVOCATIONS] = JSON.stringify(sessionRevocations);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Wire post-connect context key persistence: when the owner creates a
|
|
485
|
+
// new multi-party context, the agent injects the key into the delegate
|
|
486
|
+
// cache and fires this callback so we persist the updated keys.
|
|
487
|
+
userAgent.dwn.onDelegateContextKeysChanged = async (changedDelegateDid: string): Promise<void> => {
|
|
488
|
+
if (changedDelegateDid !== delegateDid) { return; }
|
|
489
|
+
try {
|
|
490
|
+
const keys = userAgent.dwn.exportDelegateContextKeys(delegateDid);
|
|
491
|
+
await storage.set(STORAGE_KEYS.DELEGATE_CONTEXT_KEYS, JSON.stringify(keys));
|
|
492
|
+
} catch { /* best effort — keys will be re-derived on next connect */ }
|
|
493
|
+
};
|
|
494
|
+
|
|
421
495
|
return finalizeSession({
|
|
422
496
|
userAgent,
|
|
423
497
|
emitter,
|
|
@@ -426,10 +500,7 @@ export async function finalizeDelegateSession(params: {
|
|
|
426
500
|
delegateDid,
|
|
427
501
|
identityName : identity.metadata.name,
|
|
428
502
|
identityConnectedDid : identity.metadata.connectedDid,
|
|
429
|
-
extraStorageKeys
|
|
430
|
-
[STORAGE_KEYS.DELEGATE_DID] : delegateDid,
|
|
431
|
-
[STORAGE_KEYS.CONNECTED_DID] : connectedDid,
|
|
432
|
-
},
|
|
503
|
+
extraStorageKeys,
|
|
433
504
|
});
|
|
434
505
|
}
|
|
435
506
|
|