@enbox/auth 0.5.0 → 0.6.1
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 +240 -171
- package/dist/esm/auth-manager.js.map +1 -1
- package/dist/esm/connect/import.js +131 -0
- package/dist/esm/connect/import.js.map +1 -0
- package/dist/esm/connect/lifecycle.js +378 -0
- package/dist/esm/connect/lifecycle.js.map +1 -0
- package/dist/esm/connect/local.js +105 -0
- package/dist/esm/connect/local.js.map +1 -0
- package/dist/esm/connect/restore.js +117 -0
- package/dist/esm/connect/restore.js.map +1 -0
- package/dist/esm/connect/wallet.js +80 -0
- package/dist/esm/connect/wallet.js.map +1 -0
- package/dist/esm/{flows/dwn-discovery.js → discovery.js} +2 -2
- package/dist/esm/discovery.js.map +1 -0
- package/dist/esm/index.js +13 -19
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/permissions.js +41 -0
- package/dist/esm/permissions.js.map +1 -0
- package/dist/esm/{flows/dwn-registration.js → registration.js} +2 -2
- package/dist/esm/registration.js.map +1 -0
- package/dist/esm/types.js +4 -0
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/wallet-connect-client.js +188 -0
- package/dist/esm/wallet-connect-client.js.map +1 -0
- package/dist/types/auth-manager.d.ts +89 -11
- package/dist/types/auth-manager.d.ts.map +1 -1
- package/dist/types/connect/import.d.ts +25 -0
- package/dist/types/connect/import.d.ts.map +1 -0
- package/dist/types/connect/lifecycle.d.ts +199 -0
- package/dist/types/connect/lifecycle.d.ts.map +1 -0
- package/dist/types/connect/local.d.ts +23 -0
- package/dist/types/connect/local.d.ts.map +1 -0
- package/dist/types/connect/restore.d.ts +18 -0
- package/dist/types/connect/restore.d.ts.map +1 -0
- package/dist/types/connect/wallet.d.ts +21 -0
- package/dist/types/connect/wallet.d.ts.map +1 -0
- package/dist/types/{flows/dwn-discovery.d.ts → discovery.d.ts} +3 -3
- package/dist/types/discovery.d.ts.map +1 -0
- package/dist/types/index.d.ts +14 -19
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/permissions.d.ts +18 -0
- package/dist/types/permissions.d.ts.map +1 -0
- package/dist/types/{flows/dwn-registration.d.ts → registration.d.ts} +2 -2
- package/dist/types/registration.d.ts.map +1 -0
- package/dist/types/types.d.ts +154 -4
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/wallet-connect-client.d.ts +86 -0
- package/dist/types/wallet-connect-client.d.ts.map +1 -0
- package/package.json +9 -5
- package/src/auth-manager.ts +258 -191
- package/src/connect/import.ts +148 -0
- package/src/connect/lifecycle.ts +487 -0
- package/src/connect/local.ts +116 -0
- package/src/connect/restore.ts +133 -0
- package/src/connect/wallet.ts +89 -0
- package/src/{flows/dwn-discovery.ts → discovery.ts} +4 -3
- package/src/index.ts +20 -19
- package/src/permissions.ts +48 -0
- package/src/{flows/dwn-registration.ts → registration.ts} +2 -2
- package/src/types.ts +171 -4
- package/src/wallet-connect-client.ts +275 -0
- package/dist/esm/flows/dwn-discovery.js.map +0 -1
- package/dist/esm/flows/dwn-registration.js.map +0 -1
- package/dist/esm/flows/import-identity.js +0 -177
- package/dist/esm/flows/import-identity.js.map +0 -1
- package/dist/esm/flows/local-connect.js +0 -158
- package/dist/esm/flows/local-connect.js.map +0 -1
- package/dist/esm/flows/session-restore.js +0 -125
- package/dist/esm/flows/session-restore.js.map +0 -1
- package/dist/esm/flows/wallet-connect.js +0 -200
- package/dist/esm/flows/wallet-connect.js.map +0 -1
- package/dist/esm/vault/vault-manager.js +0 -95
- package/dist/esm/vault/vault-manager.js.map +0 -1
- package/dist/types/flows/dwn-discovery.d.ts.map +0 -1
- package/dist/types/flows/dwn-registration.d.ts.map +0 -1
- package/dist/types/flows/import-identity.d.ts +0 -35
- package/dist/types/flows/import-identity.d.ts.map +0 -1
- package/dist/types/flows/local-connect.d.ts +0 -31
- package/dist/types/flows/local-connect.d.ts.map +0 -1
- package/dist/types/flows/session-restore.d.ts +0 -29
- package/dist/types/flows/session-restore.d.ts.map +0 -1
- package/dist/types/flows/wallet-connect.d.ts +0 -44
- package/dist/types/flows/wallet-connect.d.ts.map +0 -1
- package/dist/types/vault/vault-manager.d.ts +0 -57
- package/dist/types/vault/vault-manager.d.ts.map +0 -1
- package/src/flows/import-identity.ts +0 -219
- package/src/flows/local-connect.ts +0 -192
- package/src/flows/session-restore.ts +0 -155
- package/src/flows/wallet-connect.ts +0 -226
- package/src/vault/vault-manager.ts +0 -89
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session restore flow.
|
|
3
|
-
*
|
|
4
|
-
* Restores a previously established session from persisted storage,
|
|
5
|
-
* replacing the "previouslyConnected" pattern in apps.
|
|
6
|
-
* @module
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { EnboxUserAgent } from '@enbox/agent';
|
|
10
|
-
|
|
11
|
-
import type { AuthEventEmitter } from '../events.js';
|
|
12
|
-
import type { PasswordProvider } from '../password-provider.js';
|
|
13
|
-
import type { RestoreSessionOptions, StorageAdapter, SyncOption } from '../types.js';
|
|
14
|
-
|
|
15
|
-
import { applyLocalDwnDiscovery } from './dwn-discovery.js';
|
|
16
|
-
import { AuthSession } from '../identity-session.js';
|
|
17
|
-
import { INSECURE_DEFAULT_PASSWORD, STORAGE_KEYS } from '../types.js';
|
|
18
|
-
|
|
19
|
-
/** @internal */
|
|
20
|
-
export interface SessionRestoreContext {
|
|
21
|
-
userAgent: EnboxUserAgent;
|
|
22
|
-
emitter: AuthEventEmitter;
|
|
23
|
-
storage: StorageAdapter;
|
|
24
|
-
defaultPassword?: string;
|
|
25
|
-
passwordProvider?: PasswordProvider;
|
|
26
|
-
defaultSync?: SyncOption;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Attempt to restore a previous session.
|
|
31
|
-
*
|
|
32
|
-
* Returns `undefined` if no previous session exists.
|
|
33
|
-
* Returns an `AuthSession` if the session was successfully restored.
|
|
34
|
-
*/
|
|
35
|
-
export async function restoreSession(
|
|
36
|
-
ctx: SessionRestoreContext,
|
|
37
|
-
options: RestoreSessionOptions = {},
|
|
38
|
-
): Promise<AuthSession | undefined> {
|
|
39
|
-
const { userAgent, emitter, storage } = ctx;
|
|
40
|
-
|
|
41
|
-
// Check if there was a previous session.
|
|
42
|
-
const previouslyConnected = await storage.get(STORAGE_KEYS.PREVIOUSLY_CONNECTED);
|
|
43
|
-
if (previouslyConnected !== 'true') {
|
|
44
|
-
return undefined;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Resolve password: explicit option → callback → provider → manager default → insecure fallback.
|
|
48
|
-
let password = options.password ?? ctx.defaultPassword;
|
|
49
|
-
|
|
50
|
-
if (!password && options.onPasswordRequired) {
|
|
51
|
-
password = await options.onPasswordRequired();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (!password && ctx.passwordProvider) {
|
|
55
|
-
try {
|
|
56
|
-
password = await ctx.passwordProvider.getPassword({ reason: 'unlock' });
|
|
57
|
-
} catch {
|
|
58
|
-
// Provider failed — fall through to insecure default.
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
password ??= INSECURE_DEFAULT_PASSWORD;
|
|
63
|
-
|
|
64
|
-
// Warn if using insecure default.
|
|
65
|
-
if (password === INSECURE_DEFAULT_PASSWORD) {
|
|
66
|
-
console.warn(
|
|
67
|
-
'[@enbox/auth] SECURITY WARNING: No password set. Using insecure default. ' +
|
|
68
|
-
'Set a password to protect your identity vault.'
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Start the agent (initializes + unlocks vault).
|
|
73
|
-
if (await userAgent.firstLaunch()) {
|
|
74
|
-
// Vault doesn't exist yet — this shouldn't happen if previouslyConnected is true.
|
|
75
|
-
// Clean up the stale flag and return undefined.
|
|
76
|
-
await storage.remove(STORAGE_KEYS.PREVIOUSLY_CONNECTED);
|
|
77
|
-
return undefined;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
await userAgent.start({ password });
|
|
81
|
-
emitter.emit('vault-unlocked', {});
|
|
82
|
-
|
|
83
|
-
// Apply local DWN discovery (browser redirect payload or persisted endpoint).
|
|
84
|
-
// In remote mode, discovery already ran before agent creation — skip.
|
|
85
|
-
if (!userAgent.dwn.isRemoteMode) {
|
|
86
|
-
await applyLocalDwnDiscovery(userAgent, storage, emitter);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Determine which identity to reconnect.
|
|
90
|
-
const activeIdentityDid = await storage.get(STORAGE_KEYS.ACTIVE_IDENTITY);
|
|
91
|
-
const storedDelegateDid = await storage.get(STORAGE_KEYS.DELEGATE_DID);
|
|
92
|
-
|
|
93
|
-
// First try the connected identity (wallet-connected sessions).
|
|
94
|
-
let identity = await userAgent.identity.connectedIdentity();
|
|
95
|
-
|
|
96
|
-
if (!identity) {
|
|
97
|
-
// Try to find the specific active identity.
|
|
98
|
-
if (activeIdentityDid) {
|
|
99
|
-
identity = await userAgent.identity.get({ didUri: activeIdentityDid });
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Fall back to the first available identity.
|
|
103
|
-
if (!identity) {
|
|
104
|
-
const identities = await userAgent.identity.list();
|
|
105
|
-
identity = identities[0];
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (!identity) {
|
|
110
|
-
// No identity found — clean up stale session data.
|
|
111
|
-
await storage.remove(STORAGE_KEYS.PREVIOUSLY_CONNECTED);
|
|
112
|
-
await storage.remove(STORAGE_KEYS.ACTIVE_IDENTITY);
|
|
113
|
-
await storage.remove(STORAGE_KEYS.DELEGATE_DID);
|
|
114
|
-
await storage.remove(STORAGE_KEYS.CONNECTED_DID);
|
|
115
|
-
return undefined;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const connectedDid = identity.metadata.connectedDid ?? identity.did.uri;
|
|
119
|
-
const delegateDid = identity.metadata.connectedDid
|
|
120
|
-
? identity.did.uri
|
|
121
|
-
: (storedDelegateDid ?? undefined);
|
|
122
|
-
|
|
123
|
-
// Start sync.
|
|
124
|
-
const sync = ctx.defaultSync;
|
|
125
|
-
if (sync !== 'off') {
|
|
126
|
-
const syncMode = sync === undefined ? 'live' : 'poll';
|
|
127
|
-
const syncInterval = sync ?? (syncMode === 'live' ? '5m' : '2m');
|
|
128
|
-
userAgent.sync.startSync({ mode: syncMode, interval: syncInterval })
|
|
129
|
-
.catch((err: unknown) => {
|
|
130
|
-
console.error('[@enbox/auth] Sync failed:', err);
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Update persisted session info.
|
|
135
|
-
await storage.set(STORAGE_KEYS.ACTIVE_IDENTITY, connectedDid);
|
|
136
|
-
|
|
137
|
-
const identityInfo = {
|
|
138
|
-
didUri : connectedDid,
|
|
139
|
-
name : identity.metadata.name,
|
|
140
|
-
connectedDid : identity.metadata.connectedDid,
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const session = new AuthSession({
|
|
144
|
-
agent : userAgent,
|
|
145
|
-
did : connectedDid,
|
|
146
|
-
delegateDid,
|
|
147
|
-
identity : identityInfo,
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
emitter.emit('session-start', {
|
|
151
|
-
session: { did: connectedDid, delegateDid, identity: identityInfo },
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
return session;
|
|
155
|
-
}
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wallet connect (Enbox Connect relay) flow.
|
|
3
|
-
*
|
|
4
|
-
* Connects to an external wallet via the Enbox Connect relay protocol,
|
|
5
|
-
* importing a delegated DID with permission grants.
|
|
6
|
-
* This replaces the "Mode B/C" paths in Enbox.connect().
|
|
7
|
-
* @module
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { Convert } from '@enbox/common';
|
|
11
|
-
import { WalletConnect } from '@enbox/agent';
|
|
12
|
-
import type { DwnDataEncodedRecordsWriteMessage, DwnMessagesPermissionScope, DwnRecordsPermissionScope, EnboxUserAgent } from '@enbox/agent';
|
|
13
|
-
import { DwnInterface, DwnPermissionGrant } from '@enbox/agent';
|
|
14
|
-
|
|
15
|
-
import type { AuthEventEmitter } from '../events.js';
|
|
16
|
-
import { AuthSession } from '../identity-session.js';
|
|
17
|
-
import { registerWithDwnEndpoints } from './dwn-registration.js';
|
|
18
|
-
import { STORAGE_KEYS } from '../types.js';
|
|
19
|
-
import type { RegistrationOptions, StorageAdapter, SyncOption, WalletConnectOptions } from '../types.js';
|
|
20
|
-
|
|
21
|
-
/** @internal */
|
|
22
|
-
export interface WalletConnectContext {
|
|
23
|
-
userAgent: EnboxUserAgent;
|
|
24
|
-
emitter: AuthEventEmitter;
|
|
25
|
-
storage: StorageAdapter;
|
|
26
|
-
defaultSync?: SyncOption;
|
|
27
|
-
defaultDwnEndpoints?: string[];
|
|
28
|
-
registration?: RegistrationOptions;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Process connected grants by storing them in the local DWN as the owner.
|
|
33
|
-
*
|
|
34
|
-
* This is the agent-level equivalent of `Enbox.processConnectedGrants()`.
|
|
35
|
-
* It stores each grant, signed as owner, and returns the deduplicated
|
|
36
|
-
* list of protocol URIs represented by the grants.
|
|
37
|
-
*
|
|
38
|
-
* @internal
|
|
39
|
-
*/
|
|
40
|
-
export async function processConnectedGrants(params: {
|
|
41
|
-
agent: EnboxUserAgent;
|
|
42
|
-
delegateDid: string;
|
|
43
|
-
grants: DwnDataEncodedRecordsWriteMessage[];
|
|
44
|
-
}): Promise<string[]> {
|
|
45
|
-
const { agent, delegateDid, grants } = params;
|
|
46
|
-
const connectedProtocols = new Set<string>();
|
|
47
|
-
|
|
48
|
-
for (const grantMessage of grants) {
|
|
49
|
-
const grant = DwnPermissionGrant.parse(grantMessage);
|
|
50
|
-
|
|
51
|
-
// Store the grant as the owner of the DWN so the delegateDid
|
|
52
|
-
// can use it when impersonating the connectedDid.
|
|
53
|
-
const { encodedData, ...rawMessage } = grantMessage;
|
|
54
|
-
const dataStream = new Blob([Convert.base64Url(encodedData).toUint8Array() as BlobPart]);
|
|
55
|
-
|
|
56
|
-
const { reply } = await agent.processDwnRequest({
|
|
57
|
-
store : true,
|
|
58
|
-
author : delegateDid,
|
|
59
|
-
target : delegateDid,
|
|
60
|
-
messageType : DwnInterface.RecordsWrite,
|
|
61
|
-
signAsOwner : true,
|
|
62
|
-
rawMessage,
|
|
63
|
-
dataStream,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
if (reply.status.code !== 202) {
|
|
67
|
-
throw new Error(
|
|
68
|
-
`[@enbox/auth] Failed to process connected grant: ${reply.status.detail}`
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const protocol = (grant.scope as DwnMessagesPermissionScope | DwnRecordsPermissionScope).protocol;
|
|
73
|
-
if (protocol) {
|
|
74
|
-
connectedProtocols.add(protocol);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return [...connectedProtocols];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Execute the wallet connect flow.
|
|
83
|
-
*
|
|
84
|
-
* 1. Passes the permission requests directly to `WalletConnect.initClient()`.
|
|
85
|
-
* 2. Imports the delegate DID and processes grants.
|
|
86
|
-
* 3. Sets up sync and returns an AuthSession.
|
|
87
|
-
*/
|
|
88
|
-
export async function walletConnect(
|
|
89
|
-
ctx: WalletConnectContext,
|
|
90
|
-
options: WalletConnectOptions,
|
|
91
|
-
): Promise<AuthSession> {
|
|
92
|
-
const { userAgent, emitter, storage } = ctx;
|
|
93
|
-
const sync = options.sync ?? ctx.defaultSync;
|
|
94
|
-
|
|
95
|
-
if (sync === 'off') {
|
|
96
|
-
throw new Error(
|
|
97
|
-
'[@enbox/auth] Sync must be enabled when using wallet connect. ' +
|
|
98
|
-
'Remove sync: "off" or set an interval like "15s".'
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Run the Enbox Connect relay flow.
|
|
103
|
-
// permissionRequests are already agent-level ConnectPermissionRequest objects.
|
|
104
|
-
const result = await WalletConnect.initClient({
|
|
105
|
-
displayName : options.displayName,
|
|
106
|
-
connectServerUrl : options.connectServerUrl,
|
|
107
|
-
walletUri : options.walletUri ?? 'enbox://connect',
|
|
108
|
-
permissionRequests : options.permissionRequests,
|
|
109
|
-
onWalletUriReady : options.onWalletUriReady,
|
|
110
|
-
validatePin : options.validatePin,
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
if (!result) {
|
|
114
|
-
throw new Error('[@enbox/auth] Wallet connect flow was cancelled or returned no result.');
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const { delegatePortableDid, connectedDid, delegateGrants } = result;
|
|
118
|
-
|
|
119
|
-
// Import the delegated DID as an Identity.
|
|
120
|
-
let identity;
|
|
121
|
-
try {
|
|
122
|
-
identity = await userAgent.identity.import({
|
|
123
|
-
portableIdentity: {
|
|
124
|
-
portableDid : delegatePortableDid,
|
|
125
|
-
metadata : {
|
|
126
|
-
connectedDid,
|
|
127
|
-
name : 'Default',
|
|
128
|
-
uri : delegatePortableDid.uri,
|
|
129
|
-
tenant : userAgent.agentDid.uri,
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
// Process the connected grants using agent primitives.
|
|
135
|
-
const connectedProtocols = await processConnectedGrants({
|
|
136
|
-
agent : userAgent,
|
|
137
|
-
delegateDid : delegatePortableDid.uri,
|
|
138
|
-
grants : delegateGrants,
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// Register with DWN endpoints (if registration options are provided).
|
|
142
|
-
if (ctx.registration) {
|
|
143
|
-
const dwnEndpoints = ctx.defaultDwnEndpoints ?? ['https://enbox-dwn.fly.dev'];
|
|
144
|
-
await registerWithDwnEndpoints(
|
|
145
|
-
{
|
|
146
|
-
userAgent : userAgent,
|
|
147
|
-
dwnEndpoints,
|
|
148
|
-
agentDid : userAgent.agentDid.uri,
|
|
149
|
-
connectedDid,
|
|
150
|
-
storage : storage,
|
|
151
|
-
},
|
|
152
|
-
ctx.registration,
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Register sync for the connected identity.
|
|
157
|
-
await userAgent.sync.registerIdentity({
|
|
158
|
-
did : connectedDid,
|
|
159
|
-
options : {
|
|
160
|
-
delegateDid : delegatePortableDid.uri,
|
|
161
|
-
protocols : connectedProtocols,
|
|
162
|
-
},
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
// Pull down existing messages from the connected DID's DWN.
|
|
166
|
-
await userAgent.sync.sync('pull');
|
|
167
|
-
} catch (error: unknown) {
|
|
168
|
-
// Clean up on failure.
|
|
169
|
-
if (identity) {
|
|
170
|
-
try {
|
|
171
|
-
await userAgent.did.delete({
|
|
172
|
-
didUri : identity.did.uri,
|
|
173
|
-
tenant : identity.metadata.tenant,
|
|
174
|
-
deleteKey : true,
|
|
175
|
-
});
|
|
176
|
-
} catch { /* best effort */ }
|
|
177
|
-
|
|
178
|
-
try {
|
|
179
|
-
await userAgent.identity.delete({ didUri: identity.did.uri });
|
|
180
|
-
} catch { /* best effort */ }
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
184
|
-
throw new Error(`[@enbox/auth] Wallet connect failed: ${message}`);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Start sync.
|
|
188
|
-
const syncMode = sync === undefined ? 'live' : 'poll';
|
|
189
|
-
const syncInterval = sync ?? (syncMode === 'live' ? '5m' : '2m');
|
|
190
|
-
userAgent.sync.startSync({ mode: syncMode, interval: syncInterval })
|
|
191
|
-
.catch((err: unknown) => {
|
|
192
|
-
console.error('[@enbox/auth] Sync failed:', err);
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
const delegateDid = delegatePortableDid.uri;
|
|
196
|
-
|
|
197
|
-
// Persist session info.
|
|
198
|
-
await storage.set(STORAGE_KEYS.PREVIOUSLY_CONNECTED, 'true');
|
|
199
|
-
await storage.set(STORAGE_KEYS.ACTIVE_IDENTITY, connectedDid);
|
|
200
|
-
await storage.set(STORAGE_KEYS.DELEGATE_DID, delegateDid);
|
|
201
|
-
await storage.set(STORAGE_KEYS.CONNECTED_DID, connectedDid);
|
|
202
|
-
|
|
203
|
-
const identityInfo = {
|
|
204
|
-
didUri : connectedDid,
|
|
205
|
-
name : identity.metadata.name,
|
|
206
|
-
connectedDid : identity.metadata.connectedDid,
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
const session = new AuthSession({
|
|
210
|
-
agent : userAgent,
|
|
211
|
-
did : connectedDid,
|
|
212
|
-
delegateDid,
|
|
213
|
-
identity : identityInfo,
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
emitter.emit('identity-added', { identity: identityInfo });
|
|
217
|
-
emitter.emit('session-start', {
|
|
218
|
-
session: {
|
|
219
|
-
did : session.did,
|
|
220
|
-
delegateDid,
|
|
221
|
-
identity : identityInfo,
|
|
222
|
-
},
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
return session;
|
|
226
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* VaultManager wraps {@link HdIdentityVault} with a high-level API
|
|
3
|
-
* and emits events on lock/unlock.
|
|
4
|
-
* @module
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { HdIdentityVault, IdentityVaultBackup } from '@enbox/agent';
|
|
8
|
-
|
|
9
|
-
import type { AuthEventEmitter } from '../events.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Manages the encrypted identity vault lifecycle.
|
|
13
|
-
*
|
|
14
|
-
* The vault stores the agent's DID and content encryption key (CEK),
|
|
15
|
-
* protected by a user password using PBES2-HS512+A256KW with a 210K
|
|
16
|
-
* iteration work factor. The vault supports HD key derivation from
|
|
17
|
-
* a BIP-39 mnemonic for recovery.
|
|
18
|
-
*/
|
|
19
|
-
export class VaultManager {
|
|
20
|
-
private readonly _vault: HdIdentityVault;
|
|
21
|
-
private readonly _emitter: AuthEventEmitter;
|
|
22
|
-
|
|
23
|
-
constructor(vault: HdIdentityVault, emitter: AuthEventEmitter) {
|
|
24
|
-
this._vault = vault;
|
|
25
|
-
this._emitter = emitter;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** The underlying vault instance (for advanced usage). */
|
|
29
|
-
get raw(): HdIdentityVault {
|
|
30
|
-
return this._vault;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** Whether the vault has been initialized (has encrypted data). */
|
|
34
|
-
async isInitialized(): Promise<boolean> {
|
|
35
|
-
return this._vault.isInitialized();
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Whether the vault is currently locked (synchronous check). */
|
|
39
|
-
get isLocked(): boolean {
|
|
40
|
-
return this._vault.isLocked();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Unlock the vault with the given password.
|
|
45
|
-
* Decrypts the CEK into memory so the agent DID can be retrieved.
|
|
46
|
-
*
|
|
47
|
-
* @throws If the password is incorrect or vault is not initialized.
|
|
48
|
-
*/
|
|
49
|
-
async unlock(password: string): Promise<void> {
|
|
50
|
-
await this._vault.unlock({ password });
|
|
51
|
-
this._emitter.emit('vault-unlocked', {});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Lock the vault, clearing the CEK from memory.
|
|
56
|
-
* After locking, the password must be provided again to unlock.
|
|
57
|
-
*/
|
|
58
|
-
async lock(): Promise<void> {
|
|
59
|
-
await this._vault.lock();
|
|
60
|
-
this._emitter.emit('vault-locked', {});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Change the vault password. Re-encrypts the CEK with the new password.
|
|
65
|
-
*
|
|
66
|
-
* @throws If the old password is incorrect or vault is locked.
|
|
67
|
-
*/
|
|
68
|
-
async changePassword(oldPassword: string, newPassword: string): Promise<void> {
|
|
69
|
-
await this._vault.changePassword({ oldPassword, newPassword });
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Create a backup of the vault.
|
|
74
|
-
*
|
|
75
|
-
* @throws If the vault is not initialized or is locked.
|
|
76
|
-
*/
|
|
77
|
-
async backup(): Promise<IdentityVaultBackup> {
|
|
78
|
-
return this._vault.backup();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Restore the vault from a backup.
|
|
83
|
-
*
|
|
84
|
-
* @throws If the password doesn't match the backup's encryption.
|
|
85
|
-
*/
|
|
86
|
-
async restore(backup: IdentityVaultBackup, password: string): Promise<void> {
|
|
87
|
-
await this._vault.restore({ backup, password });
|
|
88
|
-
}
|
|
89
|
-
}
|