@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
package/dist/esm/auth-manager.js
CHANGED
|
@@ -18,13 +18,14 @@ import { EnboxUserAgent } from '@enbox/agent';
|
|
|
18
18
|
import { AuthEventEmitter } from './events.js';
|
|
19
19
|
import { AuthSession } from './identity-session.js';
|
|
20
20
|
import { createDefaultStorage } from './storage/storage.js';
|
|
21
|
-
import { discoverLocalDwn } from './
|
|
22
|
-
import { localConnect } from './
|
|
23
|
-
import {
|
|
21
|
+
import { discoverLocalDwn } from './discovery.js';
|
|
22
|
+
import { localConnect } from './connect/local.js';
|
|
23
|
+
import { normalizeProtocolRequests } from './permissions.js';
|
|
24
|
+
import { restoreSession } from './connect/restore.js';
|
|
24
25
|
import { STORAGE_KEYS } from './types.js';
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { importFromPhrase, importFromPortable } from './
|
|
26
|
+
import { walletConnect } from './connect/wallet.js';
|
|
27
|
+
import { ensureVaultReady, finalizeDelegateSession, importDelegateAndSetupSync, resolveIdentityDids, resolvePassword, startSyncIfEnabled } from './connect/lifecycle.js';
|
|
28
|
+
import { importFromPhrase, importFromPortable } from './connect/import.js';
|
|
28
29
|
/**
|
|
29
30
|
* The primary entry point for authentication and identity management.
|
|
30
31
|
*
|
|
@@ -66,13 +67,13 @@ export class AuthManager {
|
|
|
66
67
|
this._userAgent = params.userAgent;
|
|
67
68
|
this._emitter = params.emitter;
|
|
68
69
|
this._storage = params.storage;
|
|
69
|
-
this._vault = params.vault;
|
|
70
70
|
this._defaultPassword = params.defaultPassword;
|
|
71
71
|
this._passwordProvider = params.passwordProvider;
|
|
72
72
|
this._defaultSync = params.defaultSync;
|
|
73
73
|
this._defaultDwnEndpoints = params.defaultDwnEndpoints;
|
|
74
74
|
this._registration = params.registration;
|
|
75
75
|
this._localDwnEndpoint = params.localDwnEndpoint;
|
|
76
|
+
this._connectHandler = params.connectHandler;
|
|
76
77
|
}
|
|
77
78
|
/**
|
|
78
79
|
* Create a new AuthManager instance.
|
|
@@ -110,22 +111,21 @@ export class AuthManager {
|
|
|
110
111
|
localDwnStrategy: options.localDwnStrategy,
|
|
111
112
|
localDwnEndpoint,
|
|
112
113
|
});
|
|
113
|
-
const vault = new VaultManager(userAgent.vault, emitter);
|
|
114
114
|
const manager = new AuthManager({
|
|
115
115
|
userAgent,
|
|
116
116
|
emitter,
|
|
117
117
|
storage,
|
|
118
|
-
vault,
|
|
119
118
|
defaultPassword: options.password,
|
|
120
119
|
passwordProvider: options.passwordProvider,
|
|
121
120
|
defaultSync: options.sync,
|
|
122
121
|
defaultDwnEndpoints: options.dwnEndpoints,
|
|
123
122
|
registration: options.registration,
|
|
124
123
|
localDwnEndpoint,
|
|
124
|
+
connectHandler: options.connectHandler,
|
|
125
125
|
});
|
|
126
126
|
// Determine initial state.
|
|
127
|
-
if (yield vault.isInitialized()) {
|
|
128
|
-
manager._setState(vault.isLocked ? 'locked' : 'unlocked');
|
|
127
|
+
if (yield userAgent.vault.isInitialized()) {
|
|
128
|
+
manager._setState(userAgent.vault.isLocked() ? 'locked' : 'unlocked');
|
|
129
129
|
}
|
|
130
130
|
else {
|
|
131
131
|
manager._setState('uninitialized');
|
|
@@ -135,37 +135,77 @@ export class AuthManager {
|
|
|
135
135
|
}
|
|
136
136
|
// ─── Connection flows ──────────────────────────────────────────
|
|
137
137
|
/**
|
|
138
|
-
*
|
|
138
|
+
* Connect to a wallet or create a local session.
|
|
139
139
|
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
140
|
+
* This is the primary entry point for dapps. It routes to the
|
|
141
|
+
* appropriate flow based on the options:
|
|
142
142
|
*
|
|
143
|
-
*
|
|
143
|
+
* **Handler-based connect** (dapps): Delegates credential acquisition
|
|
144
|
+
* to a {@link ConnectHandler}. Triggered when `protocols` or
|
|
145
|
+
* `connectHandler` is provided.
|
|
146
|
+
*
|
|
147
|
+
* **Local connect** (wallets / CLI): Creates or unlocks a local vault.
|
|
148
|
+
* Triggered when `password`, `createIdentity`, or `recoveryPhrase`
|
|
149
|
+
* is provided.
|
|
150
|
+
*
|
|
151
|
+
* In both cases, `connect()` first attempts to restore a previous
|
|
152
|
+
* session. If a valid session exists, it is returned immediately
|
|
153
|
+
* without any user interaction.
|
|
154
|
+
*
|
|
155
|
+
* @example Dapp (browser)
|
|
156
|
+
* ```ts
|
|
157
|
+
* import { BrowserConnectHandler } from '@enbox/browser';
|
|
158
|
+
*
|
|
159
|
+
* const auth = await AuthManager.create({
|
|
160
|
+
* connectHandler: BrowserConnectHandler(),
|
|
161
|
+
* });
|
|
162
|
+
* const session = await auth.connect({
|
|
163
|
+
* protocols: [NotesProtocol],
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*
|
|
167
|
+
* @example Wallet / CLI
|
|
168
|
+
* ```ts
|
|
169
|
+
* const session = await auth.connect({
|
|
170
|
+
* password: userPin,
|
|
171
|
+
* createIdentity: true,
|
|
172
|
+
* });
|
|
173
|
+
* ```
|
|
174
|
+
*
|
|
175
|
+
* @param options - Connection options. The shape determines the flow.
|
|
144
176
|
* @returns An active AuthSession.
|
|
145
177
|
* @throws If a connection attempt is already in progress.
|
|
178
|
+
* @throws If handler-based connect is attempted without a handler.
|
|
146
179
|
*/
|
|
147
180
|
connect(options) {
|
|
148
181
|
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
-
this.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
182
|
+
return this._withConnect(() => __awaiter(this, void 0, void 0, function* () {
|
|
183
|
+
// 1. Try to restore a previous session first.
|
|
184
|
+
const restored = yield restoreSession(this._flowContext());
|
|
185
|
+
if (restored) {
|
|
186
|
+
return restored;
|
|
187
|
+
}
|
|
188
|
+
// 2. Route to the appropriate flow.
|
|
189
|
+
if (this._isLocalConnect(options)) {
|
|
190
|
+
return localConnect(this._flowContext(), options);
|
|
191
|
+
}
|
|
192
|
+
return this._handlerConnect(options);
|
|
193
|
+
}));
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Create or reconnect a local identity (explicit local connect).
|
|
198
|
+
*
|
|
199
|
+
* Use this when you explicitly want the local vault flow, bypassing
|
|
200
|
+
* auto-detection. This is the preferred method for wallet apps.
|
|
201
|
+
*
|
|
202
|
+
* @param options - Local connect options.
|
|
203
|
+
* @returns An active AuthSession.
|
|
204
|
+
* @throws If a connection attempt is already in progress.
|
|
205
|
+
*/
|
|
206
|
+
connectLocal(options) {
|
|
207
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
208
|
+
return this._withConnect(() => localConnect(this._flowContext(), options));
|
|
169
209
|
});
|
|
170
210
|
}
|
|
171
211
|
/**
|
|
@@ -181,43 +221,7 @@ export class AuthManager {
|
|
|
181
221
|
*/
|
|
182
222
|
walletConnect(options) {
|
|
183
223
|
return __awaiter(this, void 0, void 0, function* () {
|
|
184
|
-
this.
|
|
185
|
-
this._isConnecting = true;
|
|
186
|
-
try {
|
|
187
|
-
// Ensure the agent is initialized and started before wallet connect.
|
|
188
|
-
const isFirstLaunch = yield this._userAgent.firstLaunch();
|
|
189
|
-
let password = this._defaultPassword;
|
|
190
|
-
if (!password && this._passwordProvider) {
|
|
191
|
-
try {
|
|
192
|
-
password = yield this._passwordProvider.getPassword({
|
|
193
|
-
reason: isFirstLaunch ? 'create' : 'unlock',
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
catch (_a) {
|
|
197
|
-
// Provider failed — fall through to insecure default.
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
password !== null && password !== void 0 ? password : (password = 'insecure-static-phrase');
|
|
201
|
-
if (isFirstLaunch) {
|
|
202
|
-
yield this._userAgent.initialize({ password });
|
|
203
|
-
}
|
|
204
|
-
yield this._userAgent.start({ password });
|
|
205
|
-
this._emitter.emit('vault-unlocked', {});
|
|
206
|
-
const session = yield walletConnect({
|
|
207
|
-
userAgent: this._userAgent,
|
|
208
|
-
emitter: this._emitter,
|
|
209
|
-
storage: this._storage,
|
|
210
|
-
defaultSync: this._defaultSync,
|
|
211
|
-
defaultDwnEndpoints: this._defaultDwnEndpoints,
|
|
212
|
-
registration: this._registration,
|
|
213
|
-
}, options);
|
|
214
|
-
this._session = session;
|
|
215
|
-
this._setState('connected');
|
|
216
|
-
return session;
|
|
217
|
-
}
|
|
218
|
-
finally {
|
|
219
|
-
this._isConnecting = false;
|
|
220
|
-
}
|
|
224
|
+
return this._withConnect(() => walletConnect(this._flowContext(), options));
|
|
221
225
|
});
|
|
222
226
|
}
|
|
223
227
|
/**
|
|
@@ -228,24 +232,7 @@ export class AuthManager {
|
|
|
228
232
|
*/
|
|
229
233
|
importFromPhrase(options) {
|
|
230
234
|
return __awaiter(this, void 0, void 0, function* () {
|
|
231
|
-
this.
|
|
232
|
-
this._isConnecting = true;
|
|
233
|
-
try {
|
|
234
|
-
const session = yield importFromPhrase({
|
|
235
|
-
userAgent: this._userAgent,
|
|
236
|
-
emitter: this._emitter,
|
|
237
|
-
storage: this._storage,
|
|
238
|
-
defaultSync: this._defaultSync,
|
|
239
|
-
defaultDwnEndpoints: this._defaultDwnEndpoints,
|
|
240
|
-
registration: this._registration,
|
|
241
|
-
}, options);
|
|
242
|
-
this._session = session;
|
|
243
|
-
this._setState('connected');
|
|
244
|
-
return session;
|
|
245
|
-
}
|
|
246
|
-
finally {
|
|
247
|
-
this._isConnecting = false;
|
|
248
|
-
}
|
|
235
|
+
return this._withConnect(() => importFromPhrase(this._flowContext(), options));
|
|
249
236
|
});
|
|
250
237
|
}
|
|
251
238
|
/**
|
|
@@ -255,24 +242,7 @@ export class AuthManager {
|
|
|
255
242
|
*/
|
|
256
243
|
importFromPortable(options) {
|
|
257
244
|
return __awaiter(this, void 0, void 0, function* () {
|
|
258
|
-
this.
|
|
259
|
-
this._isConnecting = true;
|
|
260
|
-
try {
|
|
261
|
-
const session = yield importFromPortable({
|
|
262
|
-
userAgent: this._userAgent,
|
|
263
|
-
emitter: this._emitter,
|
|
264
|
-
storage: this._storage,
|
|
265
|
-
defaultSync: this._defaultSync,
|
|
266
|
-
defaultDwnEndpoints: this._defaultDwnEndpoints,
|
|
267
|
-
registration: this._registration,
|
|
268
|
-
}, options);
|
|
269
|
-
this._session = session;
|
|
270
|
-
this._setState('connected');
|
|
271
|
-
return session;
|
|
272
|
-
}
|
|
273
|
-
finally {
|
|
274
|
-
this._isConnecting = false;
|
|
275
|
-
}
|
|
245
|
+
return this._withConnect(() => importFromPortable(this._flowContext(), options));
|
|
276
246
|
});
|
|
277
247
|
}
|
|
278
248
|
/**
|
|
@@ -286,14 +256,7 @@ export class AuthManager {
|
|
|
286
256
|
this._guardConcurrency();
|
|
287
257
|
this._isConnecting = true;
|
|
288
258
|
try {
|
|
289
|
-
const session = yield restoreSession(
|
|
290
|
-
userAgent: this._userAgent,
|
|
291
|
-
emitter: this._emitter,
|
|
292
|
-
storage: this._storage,
|
|
293
|
-
defaultPassword: this._defaultPassword,
|
|
294
|
-
passwordProvider: this._passwordProvider,
|
|
295
|
-
defaultSync: this._defaultSync,
|
|
296
|
-
}, options);
|
|
259
|
+
const session = yield restoreSession(this._flowContext(), options);
|
|
297
260
|
if (session) {
|
|
298
261
|
this._session = session;
|
|
299
262
|
this._setState('connected');
|
|
@@ -330,11 +293,11 @@ export class AuthManager {
|
|
|
330
293
|
*/
|
|
331
294
|
connectHeadless(options) {
|
|
332
295
|
return __awaiter(this, void 0, void 0, function* () {
|
|
333
|
-
var _a, _b
|
|
296
|
+
var _a, _b;
|
|
334
297
|
let password = (_a = options === null || options === void 0 ? void 0 : options.password) !== null && _a !== void 0 ? _a : this._defaultPassword;
|
|
298
|
+
const isFirstLaunch = yield this._userAgent.firstLaunch();
|
|
335
299
|
// Try the password provider if no explicit password.
|
|
336
300
|
if (!password && this._passwordProvider) {
|
|
337
|
-
const isFirstLaunch = yield this._userAgent.firstLaunch();
|
|
338
301
|
password = yield this._passwordProvider.getPassword({
|
|
339
302
|
reason: isFirstLaunch ? 'create' : 'unlock',
|
|
340
303
|
});
|
|
@@ -343,14 +306,13 @@ export class AuthManager {
|
|
|
343
306
|
throw new Error('[@enbox/auth] connectHeadless() requires a password. ' +
|
|
344
307
|
'Provide one via options.password, a passwordProvider, or the AuthManager default.');
|
|
345
308
|
}
|
|
346
|
-
// Unlock the vault (initialise on first launch).
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
this._emitter.emit('vault-unlocked', {});
|
|
309
|
+
// Unlock the vault (initialise on first launch, always start).
|
|
310
|
+
yield ensureVaultReady({
|
|
311
|
+
userAgent: this._userAgent,
|
|
312
|
+
emitter: this._emitter,
|
|
313
|
+
password,
|
|
314
|
+
isFirstLaunch,
|
|
315
|
+
});
|
|
354
316
|
// Find the active identity.
|
|
355
317
|
const identities = yield this._userAgent.identity.list();
|
|
356
318
|
if (identities.length === 0) {
|
|
@@ -361,8 +323,7 @@ export class AuthManager {
|
|
|
361
323
|
const identity = (_b = (savedDid
|
|
362
324
|
? identities.find(id => id.did.uri === savedDid || id.metadata.connectedDid === savedDid)
|
|
363
325
|
: undefined)) !== null && _b !== void 0 ? _b : identities[0];
|
|
364
|
-
const connectedDid
|
|
365
|
-
const delegateDid = identity.metadata.connectedDid ? identity.did.uri : undefined;
|
|
326
|
+
const { connectedDid, delegateDid } = resolveIdentityDids(identity);
|
|
366
327
|
const identityInfo = {
|
|
367
328
|
didUri: connectedDid,
|
|
368
329
|
name: identity.metadata.name,
|
|
@@ -399,17 +360,16 @@ export class AuthManager {
|
|
|
399
360
|
*/
|
|
400
361
|
lock() {
|
|
401
362
|
return __awaiter(this, arguments, void 0, function* (options = {}) {
|
|
402
|
-
var _a
|
|
363
|
+
var _a;
|
|
403
364
|
const { timeout = 2000 } = options;
|
|
404
365
|
const did = (_a = this._session) === null || _a === void 0 ? void 0 : _a.did;
|
|
405
366
|
// 1. Stop sync.
|
|
406
|
-
|
|
407
|
-
yield this._userAgent.sync.stopSync(timeout);
|
|
408
|
-
}
|
|
367
|
+
yield this._userAgent.sync.stopSync(timeout);
|
|
409
368
|
// 2. Clear the session (but keep storage markers for restore).
|
|
410
369
|
this._session = undefined;
|
|
411
|
-
// 3. Lock the vault
|
|
412
|
-
yield this.
|
|
370
|
+
// 3. Lock the vault.
|
|
371
|
+
yield this._userAgent.vault.lock();
|
|
372
|
+
this._emitter.emit('vault-locked', {});
|
|
413
373
|
// 4. Transition state.
|
|
414
374
|
this._setState('locked');
|
|
415
375
|
// 5. Emit session-end if there was an active session.
|
|
@@ -428,14 +388,12 @@ export class AuthManager {
|
|
|
428
388
|
*/
|
|
429
389
|
disconnect() {
|
|
430
390
|
return __awaiter(this, arguments, void 0, function* (options = {}) {
|
|
431
|
-
var _a
|
|
391
|
+
var _a;
|
|
432
392
|
const { clearStorage = false, timeout = 2000 } = options;
|
|
433
393
|
const did = (_a = this._session) === null || _a === void 0 ? void 0 : _a.did;
|
|
434
394
|
// Stop sync.
|
|
435
395
|
if (this._session) {
|
|
436
|
-
|
|
437
|
-
yield this._userAgent.sync.stopSync(timeout);
|
|
438
|
-
}
|
|
396
|
+
yield this._userAgent.sync.stopSync(timeout);
|
|
439
397
|
}
|
|
440
398
|
this._session = undefined;
|
|
441
399
|
if (clearStorage) {
|
|
@@ -454,7 +412,7 @@ export class AuthManager {
|
|
|
454
412
|
}
|
|
455
413
|
}
|
|
456
414
|
}
|
|
457
|
-
catch (
|
|
415
|
+
catch (_b) {
|
|
458
416
|
// indexedDB.databases() not available in all browsers.
|
|
459
417
|
}
|
|
460
418
|
}
|
|
@@ -497,47 +455,42 @@ export class AuthManager {
|
|
|
497
455
|
*/
|
|
498
456
|
shutdown() {
|
|
499
457
|
return __awaiter(this, arguments, void 0, function* (options = {}) {
|
|
500
|
-
var _a
|
|
458
|
+
var _a;
|
|
501
459
|
if (this._isShutDown) {
|
|
502
460
|
return;
|
|
503
461
|
}
|
|
504
462
|
const { timeout = 2000 } = options;
|
|
505
463
|
const did = (_a = this._session) === null || _a === void 0 ? void 0 : _a.did;
|
|
506
464
|
// 1. Stop sync.
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
catch (_d) {
|
|
513
|
-
// Best-effort — don't block shutdown on sync errors.
|
|
514
|
-
}
|
|
465
|
+
try {
|
|
466
|
+
yield this._userAgent.sync.stopSync(timeout);
|
|
467
|
+
}
|
|
468
|
+
catch (_b) {
|
|
469
|
+
// Best-effort — don't block shutdown on sync errors.
|
|
515
470
|
}
|
|
516
471
|
// 2. Clear the active session.
|
|
517
472
|
this._session = undefined;
|
|
518
|
-
// 3. Lock the vault
|
|
473
|
+
// 3. Lock the vault.
|
|
519
474
|
try {
|
|
520
|
-
yield this.
|
|
475
|
+
yield this._userAgent.vault.lock();
|
|
476
|
+
this._emitter.emit('vault-locked', {});
|
|
521
477
|
}
|
|
522
|
-
catch (
|
|
478
|
+
catch (_c) {
|
|
523
479
|
// Vault may already be locked or uninitialised — safe to ignore.
|
|
524
480
|
}
|
|
525
481
|
// 4. Close the sync engine (releases LevelDB handles, timers).
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
catch (_f) {
|
|
532
|
-
// Best-effort.
|
|
533
|
-
}
|
|
482
|
+
try {
|
|
483
|
+
yield this._userAgent.sync.close();
|
|
484
|
+
}
|
|
485
|
+
catch (_d) {
|
|
486
|
+
// Best-effort.
|
|
534
487
|
}
|
|
535
488
|
// 5. Close the storage adapter (e.g. LevelDB session store).
|
|
536
489
|
if (typeof this._storage.close === 'function') {
|
|
537
490
|
try {
|
|
538
491
|
yield this._storage.close();
|
|
539
492
|
}
|
|
540
|
-
catch (
|
|
493
|
+
catch (_e) {
|
|
541
494
|
// Best-effort.
|
|
542
495
|
}
|
|
543
496
|
}
|
|
@@ -575,7 +528,6 @@ export class AuthManager {
|
|
|
575
528
|
*/
|
|
576
529
|
switchIdentity(didUri) {
|
|
577
530
|
return __awaiter(this, void 0, void 0, function* () {
|
|
578
|
-
var _a;
|
|
579
531
|
// Disconnect current session cleanly (keep data).
|
|
580
532
|
if (this._session) {
|
|
581
533
|
yield this.disconnect();
|
|
@@ -584,8 +536,7 @@ export class AuthManager {
|
|
|
584
536
|
if (!identity) {
|
|
585
537
|
throw new Error(`[@enbox/auth] Identity not found: ${didUri}`);
|
|
586
538
|
}
|
|
587
|
-
const connectedDid
|
|
588
|
-
const delegateDid = identity.metadata.connectedDid ? identity.did.uri : undefined;
|
|
539
|
+
const { connectedDid, delegateDid } = resolveIdentityDids(identity);
|
|
589
540
|
// Persist the switch.
|
|
590
541
|
yield this._storage.set(STORAGE_KEYS.PREVIOUSLY_CONNECTED, 'true');
|
|
591
542
|
yield this._storage.set(STORAGE_KEYS.ACTIVE_IDENTITY, connectedDid);
|
|
@@ -604,13 +555,10 @@ export class AuthManager {
|
|
|
604
555
|
options: { delegateDid, protocols: [] },
|
|
605
556
|
});
|
|
606
557
|
}
|
|
607
|
-
catch (
|
|
558
|
+
catch (_a) {
|
|
608
559
|
// Already registered — safe to ignore.
|
|
609
560
|
}
|
|
610
|
-
|
|
611
|
-
const syncInterval = sync !== null && sync !== void 0 ? sync : (syncMode === 'live' ? '5m' : '2m');
|
|
612
|
-
this._userAgent.sync.startSync({ mode: syncMode, interval: syncInterval })
|
|
613
|
-
.catch((err) => console.error('[@enbox/auth] Sync failed:', err));
|
|
561
|
+
startSyncIfEnabled(this._userAgent, sync);
|
|
614
562
|
}
|
|
615
563
|
this._session = new AuthSession({
|
|
616
564
|
agent: this._userAgent,
|
|
@@ -671,9 +619,9 @@ export class AuthManager {
|
|
|
671
619
|
});
|
|
672
620
|
}
|
|
673
621
|
// ─── Vault ─────────────────────────────────────────────────────
|
|
674
|
-
/** Access the vault
|
|
622
|
+
/** Access the underlying identity vault for lock/unlock/backup operations. */
|
|
675
623
|
get vault() {
|
|
676
|
-
return this.
|
|
624
|
+
return this._userAgent.vault;
|
|
677
625
|
}
|
|
678
626
|
// ─── Events ────────────────────────────────────────────────────
|
|
679
627
|
/**
|
|
@@ -697,7 +645,7 @@ export class AuthManager {
|
|
|
697
645
|
}
|
|
698
646
|
/** Whether the vault is currently locked. */
|
|
699
647
|
get isLocked() {
|
|
700
|
-
return this.
|
|
648
|
+
return this._userAgent.vault.isLocked();
|
|
701
649
|
}
|
|
702
650
|
/** Whether a connection attempt is in progress. */
|
|
703
651
|
get isConnecting() {
|
|
@@ -718,6 +666,127 @@ export class AuthManager {
|
|
|
718
666
|
return this._localDwnEndpoint;
|
|
719
667
|
}
|
|
720
668
|
// ─── Private helpers ───────────────────────────────────────────
|
|
669
|
+
/**
|
|
670
|
+
* Determine whether the given options indicate a local connect flow.
|
|
671
|
+
*
|
|
672
|
+
* Local connect is indicated by the presence of `password`,
|
|
673
|
+
* `createIdentity`, or `recoveryPhrase` — signals that the caller
|
|
674
|
+
* is managing its own vault/identity lifecycle. In non-browser
|
|
675
|
+
* environments, local connect is the fallback.
|
|
676
|
+
*/
|
|
677
|
+
_isLocalConnect(options) {
|
|
678
|
+
const o = (options !== null && options !== void 0 ? options : {});
|
|
679
|
+
// If any local-connect-specific keys are present, it's definitely local.
|
|
680
|
+
const hasLocalSignals = (o.password !== undefined ||
|
|
681
|
+
o.createIdentity !== undefined ||
|
|
682
|
+
o.recoveryPhrase !== undefined ||
|
|
683
|
+
o.dwnEndpoints !== undefined ||
|
|
684
|
+
o.metadata !== undefined);
|
|
685
|
+
if (hasLocalSignals) {
|
|
686
|
+
return true;
|
|
687
|
+
}
|
|
688
|
+
// If any handler-connect signals are present, use the handler flow.
|
|
689
|
+
const hasHandlerSignals = (o.protocols !== undefined ||
|
|
690
|
+
o.connectHandler !== undefined);
|
|
691
|
+
if (hasHandlerSignals) {
|
|
692
|
+
return false;
|
|
693
|
+
}
|
|
694
|
+
// No explicit signals → default to local connect.
|
|
695
|
+
// Callers that want handler-based connect must provide protocols
|
|
696
|
+
// or a connectHandler.
|
|
697
|
+
return true;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Run a handler-based (delegated) connect flow.
|
|
701
|
+
*
|
|
702
|
+
* 1. Initialize the vault (agent-only, no identity).
|
|
703
|
+
* 2. Normalize protocol permission requests.
|
|
704
|
+
* 3. Delegate to the connect handler for credential acquisition.
|
|
705
|
+
* 4. Import the delegate DID, process grants, set up sync.
|
|
706
|
+
* 5. Finalize and return the AuthSession.
|
|
707
|
+
*/
|
|
708
|
+
_handlerConnect(options) {
|
|
709
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
710
|
+
var _a, _b;
|
|
711
|
+
const ctx = this._flowContext();
|
|
712
|
+
const { userAgent, emitter, storage } = ctx;
|
|
713
|
+
const sync = (_a = options === null || options === void 0 ? void 0 : options.sync) !== null && _a !== void 0 ? _a : ctx.defaultSync;
|
|
714
|
+
if (sync === 'off') {
|
|
715
|
+
throw new Error('[@enbox/auth] Sync must be enabled for delegated connect. ' +
|
|
716
|
+
'Remove sync: "off" or set an interval like "15s".');
|
|
717
|
+
}
|
|
718
|
+
// 1. Initialize vault (agent-only, no identity).
|
|
719
|
+
const isFirstLaunch = yield userAgent.firstLaunch();
|
|
720
|
+
const password = yield resolvePassword(ctx, undefined, isFirstLaunch);
|
|
721
|
+
yield ensureVaultReady({ userAgent, emitter, password, isFirstLaunch });
|
|
722
|
+
// 2. Normalize protocol requests.
|
|
723
|
+
const permissionRequests = normalizeProtocolRequests(options === null || options === void 0 ? void 0 : options.protocols);
|
|
724
|
+
// 3. Resolve the handler.
|
|
725
|
+
const handler = (_b = options === null || options === void 0 ? void 0 : options.connectHandler) !== null && _b !== void 0 ? _b : this._connectHandler;
|
|
726
|
+
if (!handler) {
|
|
727
|
+
throw new Error('[@enbox/auth] No connect handler provided. ' +
|
|
728
|
+
'Install @enbox/browser and pass BrowserConnectHandler(), ' +
|
|
729
|
+
'or provide a custom ConnectHandler.');
|
|
730
|
+
}
|
|
731
|
+
// 4. Delegate to the handler.
|
|
732
|
+
const result = yield handler.requestAccess({ permissionRequests });
|
|
733
|
+
if (!result) {
|
|
734
|
+
throw new Error('[@enbox/auth] Connect was denied or cancelled by the user.');
|
|
735
|
+
}
|
|
736
|
+
// 5. Import delegate DID, process grants, set up sync.
|
|
737
|
+
const { delegatePortableDid, connectedDid, delegateGrants } = result;
|
|
738
|
+
const identity = yield importDelegateAndSetupSync({
|
|
739
|
+
userAgent, delegatePortableDid, connectedDid, delegateGrants,
|
|
740
|
+
flowName: 'Connect',
|
|
741
|
+
});
|
|
742
|
+
// 6. Finalize session.
|
|
743
|
+
return finalizeDelegateSession({
|
|
744
|
+
userAgent, emitter, storage, identity,
|
|
745
|
+
connectedDid, delegateDid: delegatePortableDid.uri, sync,
|
|
746
|
+
});
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Build a `FlowContext` from the manager's current state.
|
|
751
|
+
*
|
|
752
|
+
* Replaces the 5 manual inline context constructions that were
|
|
753
|
+
* previously duplicated across `connect()`, `walletConnect()`,
|
|
754
|
+
* `importFromPhrase()`, `importFromPortable()`, and `restoreSession()`.
|
|
755
|
+
*/
|
|
756
|
+
_flowContext() {
|
|
757
|
+
return {
|
|
758
|
+
userAgent: this._userAgent,
|
|
759
|
+
emitter: this._emitter,
|
|
760
|
+
storage: this._storage,
|
|
761
|
+
defaultPassword: this._defaultPassword,
|
|
762
|
+
passwordProvider: this._passwordProvider,
|
|
763
|
+
defaultSync: this._defaultSync,
|
|
764
|
+
defaultDwnEndpoints: this._defaultDwnEndpoints,
|
|
765
|
+
registration: this._registration,
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Template for connection flows that follow the guard → try/finally → setState pattern.
|
|
770
|
+
*
|
|
771
|
+
* Consolidates the duplicated concurrency guard, `_isConnecting` flag management,
|
|
772
|
+
* session assignment, and state transition across `connect()`, `walletConnect()`,
|
|
773
|
+
* `importFromPhrase()`, and `importFromPortable()`.
|
|
774
|
+
*/
|
|
775
|
+
_withConnect(fn) {
|
|
776
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
777
|
+
this._guardConcurrency();
|
|
778
|
+
this._isConnecting = true;
|
|
779
|
+
try {
|
|
780
|
+
const session = yield fn();
|
|
781
|
+
this._session = session;
|
|
782
|
+
this._setState('connected');
|
|
783
|
+
return session;
|
|
784
|
+
}
|
|
785
|
+
finally {
|
|
786
|
+
this._isConnecting = false;
|
|
787
|
+
}
|
|
788
|
+
});
|
|
789
|
+
}
|
|
721
790
|
_setState(state) {
|
|
722
791
|
if (state === this._state) {
|
|
723
792
|
return;
|