@enbox/auth 0.3.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 +496 -0
- package/dist/esm/auth-manager.js.map +1 -0
- package/dist/esm/events.js +65 -0
- package/dist/esm/events.js.map +1 -0
- package/dist/esm/flows/dwn-discovery.js +281 -0
- package/dist/esm/flows/dwn-discovery.js.map +1 -0
- package/dist/esm/flows/dwn-registration.js +122 -0
- package/dist/esm/flows/dwn-registration.js.map +1 -0
- package/dist/esm/flows/import-identity.js +175 -0
- package/dist/esm/flows/import-identity.js.map +1 -0
- package/dist/esm/flows/local-connect.js +141 -0
- package/dist/esm/flows/local-connect.js.map +1 -0
- package/dist/esm/flows/session-restore.js +109 -0
- package/dist/esm/flows/session-restore.js.map +1 -0
- package/dist/esm/flows/wallet-connect.js +199 -0
- package/dist/esm/flows/wallet-connect.js.map +1 -0
- package/dist/esm/identity-session.js +33 -0
- package/dist/esm/identity-session.js.map +1 -0
- package/dist/esm/index.js +50 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/storage/storage.js +152 -0
- package/dist/esm/storage/storage.js.map +1 -0
- package/dist/esm/types.js +30 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/vault/vault-manager.js +95 -0
- package/dist/esm/vault/vault-manager.js.map +1 -0
- package/dist/types/auth-manager.d.ts +176 -0
- package/dist/types/auth-manager.d.ts.map +1 -0
- package/dist/types/events.d.ts +36 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/flows/dwn-discovery.d.ts +157 -0
- package/dist/types/flows/dwn-discovery.d.ts.map +1 -0
- package/dist/types/flows/dwn-registration.d.ts +39 -0
- package/dist/types/flows/dwn-registration.d.ts.map +1 -0
- package/dist/types/flows/import-identity.d.ts +35 -0
- package/dist/types/flows/import-identity.d.ts.map +1 -0
- package/dist/types/flows/local-connect.d.ts +29 -0
- package/dist/types/flows/local-connect.d.ts.map +1 -0
- package/dist/types/flows/session-restore.d.ts +27 -0
- package/dist/types/flows/session-restore.d.ts.map +1 -0
- package/dist/types/flows/wallet-connect.d.ts +44 -0
- package/dist/types/flows/wallet-connect.d.ts.map +1 -0
- package/dist/types/identity-session.d.ts +52 -0
- package/dist/types/identity-session.d.ts.map +1 -0
- package/dist/types/index.d.ts +45 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/storage/storage.d.ts +54 -0
- package/dist/types/storage/storage.d.ts.map +1 -0
- package/dist/types/types.d.ts +312 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/vault/vault-manager.d.ts +57 -0
- package/dist/types/vault/vault-manager.d.ts.map +1 -0
- package/package.json +71 -0
- package/src/auth-manager.ts +569 -0
- package/src/events.ts +66 -0
- package/src/flows/dwn-discovery.ts +300 -0
- package/src/flows/dwn-registration.ts +157 -0
- package/src/flows/import-identity.ts +217 -0
- package/src/flows/local-connect.ts +171 -0
- package/src/flows/session-restore.ts +135 -0
- package/src/flows/wallet-connect.ts +225 -0
- package/src/identity-session.ts +65 -0
- package/src/index.ts +89 -0
- package/src/storage/storage.ts +136 -0
- package/src/types.ts +388 -0
- package/src/vault/vault-manager.ts +89 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local DWN discovery integration for browser and CLI environments.
|
|
3
|
+
*
|
|
4
|
+
* This module bridges the local DWN discovery mechanisms (implemented in
|
|
5
|
+
* `@enbox/agent`) with the `@enbox/auth` storage, session lifecycle, and
|
|
6
|
+
* event system.
|
|
7
|
+
*
|
|
8
|
+
* ## Discovery channels (browser, highest to lowest priority)
|
|
9
|
+
*
|
|
10
|
+
* 1. **URL fragment payload** — A `dwn://register` redirect just landed
|
|
11
|
+
* on the page with the endpoint in `#`. Highest priority because it's
|
|
12
|
+
* fresh and explicit.
|
|
13
|
+
* 2. **Persisted endpoint** (localStorage) — A previously discovered
|
|
14
|
+
* endpoint restored and re-validated via `GET /info`.
|
|
15
|
+
* 3. **Agent-level discovery** (transparent, runs on every `sendRequest`)
|
|
16
|
+
* — `~/.enbox/dwn.json` discovery file (Node/Bun only; skipped in
|
|
17
|
+
* browsers) and sequential port probing on `127.0.0.1:{3000,55500–55509}`.
|
|
18
|
+
* This channel works even if the browser-specific functions here
|
|
19
|
+
* return `false`.
|
|
20
|
+
*
|
|
21
|
+
* ## Discovery channels (CLI / native, all transparent)
|
|
22
|
+
*
|
|
23
|
+
* In Node/Bun environments, all discovery happens automatically inside
|
|
24
|
+
* `AgentDwnApi.getLocalDwnEndpoint()`. The browser-specific functions
|
|
25
|
+
* in this module (`checkUrlForDwnDiscoveryPayload`, `requestLocalDwnDiscovery`)
|
|
26
|
+
* are not needed — the agent reads `~/.enbox/dwn.json` and probes ports
|
|
27
|
+
* on its own.
|
|
28
|
+
*
|
|
29
|
+
* @see https://github.com/enboxorg/enbox/issues/589
|
|
30
|
+
* @module
|
|
31
|
+
*/
|
|
32
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
33
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
34
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
35
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
36
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
37
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
38
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
import { buildDwnRegisterUrl, readDwnDiscoveryPayloadFromUrl } from '@enbox/agent';
|
|
42
|
+
import { STORAGE_KEYS } from '../types.js';
|
|
43
|
+
/**
|
|
44
|
+
* Check the current page URL for a `DwnDiscoveryPayload` in the fragment.
|
|
45
|
+
*
|
|
46
|
+
* This is called once at the start of a connection flow to detect whether
|
|
47
|
+
* the user was just redirected back from a `dwn://register` handler. If a
|
|
48
|
+
* valid payload is found, the endpoint is persisted and the fragment is
|
|
49
|
+
* cleared to prevent double-reads.
|
|
50
|
+
*
|
|
51
|
+
* @returns The discovered endpoint string, or `undefined` if no payload
|
|
52
|
+
* was found in the URL.
|
|
53
|
+
*/
|
|
54
|
+
export function checkUrlForDwnDiscoveryPayload() {
|
|
55
|
+
if (typeof globalThis.location === 'undefined') {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
const payload = readDwnDiscoveryPayloadFromUrl(globalThis.location.href);
|
|
59
|
+
if (!payload) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
// Clear the fragment to prevent re-reading on subsequent calls or
|
|
63
|
+
// if the user refreshes the page after the redirect.
|
|
64
|
+
if (typeof globalThis.history !== 'undefined' && globalThis.history.replaceState) {
|
|
65
|
+
const cleanUrl = globalThis.location.href.split('#')[0];
|
|
66
|
+
globalThis.history.replaceState(null, '', cleanUrl);
|
|
67
|
+
}
|
|
68
|
+
return payload.endpoint;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Persist a discovered local DWN endpoint in auth storage.
|
|
72
|
+
*
|
|
73
|
+
* @param storage - The auth storage adapter.
|
|
74
|
+
* @param endpoint - The local DWN server base URL.
|
|
75
|
+
*/
|
|
76
|
+
export function persistLocalDwnEndpoint(storage, endpoint) {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
yield storage.set(STORAGE_KEYS.LOCAL_DWN_ENDPOINT, endpoint);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Clear the persisted local DWN endpoint from auth storage.
|
|
83
|
+
*
|
|
84
|
+
* Call this when the cached endpoint is found to be stale (server no
|
|
85
|
+
* longer running).
|
|
86
|
+
*
|
|
87
|
+
* @param storage - The auth storage adapter.
|
|
88
|
+
*/
|
|
89
|
+
export function clearLocalDwnEndpoint(storage) {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
yield storage.remove(STORAGE_KEYS.LOCAL_DWN_ENDPOINT);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Restore a previously persisted local DWN endpoint and inject it into the
|
|
96
|
+
* agent's discovery cache.
|
|
97
|
+
*
|
|
98
|
+
* The endpoint is validated by the agent (via `GET /info`) before being
|
|
99
|
+
* accepted. If validation fails, the stale entry is removed from storage.
|
|
100
|
+
*
|
|
101
|
+
* @param agent - The running EnboxUserAgent.
|
|
102
|
+
* @param storage - The auth storage adapter.
|
|
103
|
+
* @returns `true` if an endpoint was restored and validated, `false` otherwise.
|
|
104
|
+
*/
|
|
105
|
+
export function restoreLocalDwnEndpoint(agent, storage) {
|
|
106
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
107
|
+
const endpoint = yield storage.get(STORAGE_KEYS.LOCAL_DWN_ENDPOINT);
|
|
108
|
+
if (!endpoint) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
const accepted = yield agent.dwn.setCachedLocalDwnEndpoint(endpoint);
|
|
112
|
+
if (!accepted) {
|
|
113
|
+
// The server is no longer running — remove the stale entry.
|
|
114
|
+
yield clearLocalDwnEndpoint(storage);
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
return true;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Run the full local DWN discovery sequence for a browser connection flow.
|
|
122
|
+
*
|
|
123
|
+
* This function handles the **receiving** side of local DWN discovery in
|
|
124
|
+
* the browser. It does NOT trigger the `dwn://register` redirect — use
|
|
125
|
+
* {@link requestLocalDwnDiscovery} for that.
|
|
126
|
+
*
|
|
127
|
+
* The discovery channels, from highest to lowest priority:
|
|
128
|
+
*
|
|
129
|
+
* 1. **URL fragment payload** — A `dwn://register` redirect just landed on
|
|
130
|
+
* this page with the DWN endpoint in `#`. This is the highest-priority
|
|
131
|
+
* signal because it's fresh and explicit.
|
|
132
|
+
*
|
|
133
|
+
* 2. **Persisted endpoint** (localStorage) — A previously discovered
|
|
134
|
+
* endpoint is restored and re-validated via `GET /info`.
|
|
135
|
+
*
|
|
136
|
+
* 3. **Agent-level discovery** (transparent) — Even if this function
|
|
137
|
+
* returns `false`, the agent's `LocalDwnDiscovery` will independently
|
|
138
|
+
* try the discovery file (`~/.enbox/dwn.json`) and port probing on
|
|
139
|
+
* every `sendRequest()` call. Those channels are not available in
|
|
140
|
+
* browsers (no filesystem access, CORS may block probes), but they
|
|
141
|
+
* work transparently in Node/Bun CLI environments.
|
|
142
|
+
*
|
|
143
|
+
* When an `emitter` is provided, this function emits:
|
|
144
|
+
* - `'local-dwn-available'` with the endpoint when discovery succeeds.
|
|
145
|
+
* - `'local-dwn-unavailable'` when no local DWN could be reached.
|
|
146
|
+
*
|
|
147
|
+
* @param agent - The running EnboxUserAgent.
|
|
148
|
+
* @param storage - The auth storage adapter.
|
|
149
|
+
* @param emitter - Optional event emitter for local DWN status notifications.
|
|
150
|
+
* @returns `true` if a local DWN endpoint was discovered and injected.
|
|
151
|
+
*/
|
|
152
|
+
export function applyLocalDwnDiscovery(agent, storage, emitter) {
|
|
153
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
154
|
+
// Step 1: Check for a fresh payload in the URL fragment (redirect just happened).
|
|
155
|
+
const freshEndpoint = checkUrlForDwnDiscoveryPayload();
|
|
156
|
+
if (freshEndpoint) {
|
|
157
|
+
const accepted = yield agent.dwn.setCachedLocalDwnEndpoint(freshEndpoint);
|
|
158
|
+
if (accepted) {
|
|
159
|
+
yield persistLocalDwnEndpoint(storage, freshEndpoint);
|
|
160
|
+
emitter === null || emitter === void 0 ? void 0 : emitter.emit('local-dwn-available', { endpoint: freshEndpoint });
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
// Payload was in the URL but the server is not reachable — fall through.
|
|
164
|
+
}
|
|
165
|
+
// Step 2: Try restoring from storage.
|
|
166
|
+
const restored = yield restoreLocalDwnEndpoint(agent, storage);
|
|
167
|
+
if (restored) {
|
|
168
|
+
const endpoint = yield storage.get(STORAGE_KEYS.LOCAL_DWN_ENDPOINT);
|
|
169
|
+
if (endpoint) {
|
|
170
|
+
emitter === null || emitter === void 0 ? void 0 : emitter.emit('local-dwn-available', { endpoint });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
emitter === null || emitter === void 0 ? void 0 : emitter.emit('local-dwn-unavailable', {});
|
|
175
|
+
}
|
|
176
|
+
return restored;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
// ─── dwn://register trigger ─────────────────────────────────────
|
|
180
|
+
/**
|
|
181
|
+
* Initiate the `dwn://register` flow by opening the register URL.
|
|
182
|
+
*
|
|
183
|
+
* This asks the operating system to route `dwn://register?callback=<url>`
|
|
184
|
+
* to the registered handler (electrobun-dwn), which will redirect the
|
|
185
|
+
* user's browser back to `callbackUrl` with the local DWN endpoint
|
|
186
|
+
* encoded in the URL fragment.
|
|
187
|
+
*
|
|
188
|
+
* **Important:** There is no reliable cross-browser API to detect whether
|
|
189
|
+
* a `dwn://` handler is installed. If no handler is registered, this call
|
|
190
|
+
* will silently fail or show an OS-level error dialog. Use
|
|
191
|
+
* {@link probeLocalDwn} first to check if a local DWN is already
|
|
192
|
+
* reachable via port probing — if it is, you can skip the register flow
|
|
193
|
+
* entirely and call {@link applyLocalDwnDiscovery} instead.
|
|
194
|
+
*
|
|
195
|
+
* @param callbackUrl - The URL to redirect back to. Defaults to the
|
|
196
|
+
* current page URL (without its fragment) if running in a browser.
|
|
197
|
+
* @returns `true` if the register URL was opened, `false` if no
|
|
198
|
+
* callback URL could be determined (e.g. no `globalThis.location`).
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```ts
|
|
202
|
+
* // Check if local DWN is already available via direct probe.
|
|
203
|
+
* const alreadyAvailable = await probeLocalDwn();
|
|
204
|
+
* if (!alreadyAvailable) {
|
|
205
|
+
* // No local DWN found — trigger the dwn://register flow.
|
|
206
|
+
* requestLocalDwnDiscovery();
|
|
207
|
+
* // The page will reload with the endpoint in the URL fragment.
|
|
208
|
+
* }
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
export function requestLocalDwnDiscovery(callbackUrl) {
|
|
212
|
+
const resolvedCallback = callbackUrl !== null && callbackUrl !== void 0 ? callbackUrl : currentPageUrl();
|
|
213
|
+
if (!resolvedCallback) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
const registerUrl = buildDwnRegisterUrl(resolvedCallback);
|
|
217
|
+
// Open the dwn:// URL. Use window.open() rather than location.href
|
|
218
|
+
// assignment to avoid navigating away from the current page if the
|
|
219
|
+
// OS handler isn't installed.
|
|
220
|
+
if (typeof globalThis.open === 'function') {
|
|
221
|
+
globalThis.open(registerUrl);
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
// Fallback for environments with location but no window.open.
|
|
225
|
+
if (typeof globalThis.location !== 'undefined') {
|
|
226
|
+
globalThis.location.href = registerUrl;
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Probe whether a local DWN server is reachable via direct HTTP fetch.
|
|
233
|
+
*
|
|
234
|
+
* Attempts `GET http://127.0.0.1:{port}/info` on the well-known port
|
|
235
|
+
* candidates and returns the endpoint URL of the first server that
|
|
236
|
+
* responds with a valid `@enbox/dwn-server` identity.
|
|
237
|
+
*
|
|
238
|
+
* This is useful in browsers to check if a local DWN is available
|
|
239
|
+
* *before* triggering the `dwn://register` redirect flow — if the
|
|
240
|
+
* server is already reachable (CORS permitting), the redirect is
|
|
241
|
+
* unnecessary.
|
|
242
|
+
*
|
|
243
|
+
* @returns The local DWN endpoint URL, or `undefined` if no server
|
|
244
|
+
* was found. Returns `undefined` (rather than throwing) on CORS
|
|
245
|
+
* errors or network failures.
|
|
246
|
+
*/
|
|
247
|
+
export function probeLocalDwn() {
|
|
248
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
249
|
+
// Import port candidates from @enbox/agent. Using a dynamic import
|
|
250
|
+
// here keeps the function self-contained and avoids circular deps.
|
|
251
|
+
const { localDwnPortCandidates, localDwnHostCandidates } = yield import('@enbox/agent');
|
|
252
|
+
for (const port of localDwnPortCandidates) {
|
|
253
|
+
for (const host of localDwnHostCandidates) {
|
|
254
|
+
const endpoint = `http://${host}:${port}`;
|
|
255
|
+
try {
|
|
256
|
+
const response = yield fetch(`${endpoint}/info`, { signal: AbortSignal.timeout(2000) });
|
|
257
|
+
if (!response.ok) {
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
const serverInfo = yield response.json();
|
|
261
|
+
if ((serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.server) === '@enbox/dwn-server') {
|
|
262
|
+
return endpoint;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
catch (_a) {
|
|
266
|
+
// Network error, CORS block, or timeout — try next candidate.
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return undefined;
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
// ─── Internal helpers ───────────────────────────────────────────
|
|
274
|
+
/** Return the current page URL without the fragment, or `undefined`. */
|
|
275
|
+
function currentPageUrl() {
|
|
276
|
+
if (typeof globalThis.location === 'undefined') {
|
|
277
|
+
return undefined;
|
|
278
|
+
}
|
|
279
|
+
return globalThis.location.href.split('#')[0];
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=dwn-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dwn-discovery.js","sourceRoot":"","sources":["../../../src/flows/dwn-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DWN registration flow.
|
|
3
|
+
*
|
|
4
|
+
* Registers the agent DID and connected DID with DWN endpoints.
|
|
5
|
+
* Supports two registration paths:
|
|
6
|
+
* 1. Provider auth (`provider-auth-v0`) — OAuth-style with tokens
|
|
7
|
+
* 2. Proof of Work (default) — PoW challenge-response
|
|
8
|
+
*
|
|
9
|
+
* This matches the registration logic from `Enbox.connect()` but as a
|
|
10
|
+
* standalone, reusable function.
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
import { DwnRegistrar } from '@enbox/dwn-clients';
|
|
23
|
+
/**
|
|
24
|
+
* Register the agent and connected DIDs with the configured DWN endpoints.
|
|
25
|
+
*
|
|
26
|
+
* For each endpoint:
|
|
27
|
+
* 1. Fetches server info to check registration requirements.
|
|
28
|
+
* 2. If the server requires `provider-auth-v0` and the app provides
|
|
29
|
+
* `onProviderAuthRequired`, runs the OAuth flow (with token refresh).
|
|
30
|
+
* 3. Otherwise falls back to PoW registration.
|
|
31
|
+
* 4. Calls `onSuccess` when all endpoints succeed, `onFailure` on error.
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export function registerWithDwnEndpoints(ctx, registration) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
var _a;
|
|
38
|
+
const { userAgent, dwnEndpoints, agentDid, connectedDid } = ctx;
|
|
39
|
+
const updatedTokens = Object.assign({}, ((_a = registration.registrationTokens) !== null && _a !== void 0 ? _a : {}));
|
|
40
|
+
try {
|
|
41
|
+
for (const dwnEndpoint of dwnEndpoints) {
|
|
42
|
+
const serverInfo = yield userAgent.rpc.getServerInfo(dwnEndpoint);
|
|
43
|
+
if (serverInfo.registrationRequirements.length === 0) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
// Deduplicate DIDs to register.
|
|
47
|
+
const didsToRegister = [agentDid, connectedDid]
|
|
48
|
+
.filter((did, i, arr) => arr.indexOf(did) === i);
|
|
49
|
+
const hasProviderAuth = serverInfo.registrationRequirements.includes('provider-auth-v0')
|
|
50
|
+
&& serverInfo.providerAuth !== undefined;
|
|
51
|
+
if (hasProviderAuth && registration.onProviderAuthRequired) {
|
|
52
|
+
// --- Provider Auth Path ---
|
|
53
|
+
let tokenData = updatedTokens[dwnEndpoint];
|
|
54
|
+
// Refresh expired tokens.
|
|
55
|
+
if ((tokenData === null || tokenData === void 0 ? void 0 : tokenData.expiresAt) !== undefined && tokenData.expiresAt < Date.now()) {
|
|
56
|
+
if (tokenData.refreshUrl && tokenData.refreshToken) {
|
|
57
|
+
const refreshed = yield DwnRegistrar.refreshRegistrationToken(tokenData.refreshUrl, tokenData.refreshToken);
|
|
58
|
+
tokenData = {
|
|
59
|
+
registrationToken: refreshed.registrationToken,
|
|
60
|
+
refreshToken: refreshed.refreshToken,
|
|
61
|
+
expiresAt: refreshed.expiresIn !== undefined
|
|
62
|
+
? Date.now() + (refreshed.expiresIn * 1000) : undefined,
|
|
63
|
+
tokenUrl: tokenData.tokenUrl,
|
|
64
|
+
refreshUrl: tokenData.refreshUrl,
|
|
65
|
+
};
|
|
66
|
+
updatedTokens[dwnEndpoint] = tokenData;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
tokenData = undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Run the auth flow if no valid token exists.
|
|
73
|
+
if (tokenData === undefined) {
|
|
74
|
+
const state = crypto.randomUUID();
|
|
75
|
+
const providerAuth = serverInfo.providerAuth;
|
|
76
|
+
const separator = providerAuth.authorizeUrl.includes('?') ? '&' : '?';
|
|
77
|
+
const authorizeUrl = `${providerAuth.authorizeUrl}${separator}`
|
|
78
|
+
+ `redirect_uri=${encodeURIComponent(dwnEndpoint)}`
|
|
79
|
+
+ `&state=${encodeURIComponent(state)}`;
|
|
80
|
+
const authResult = yield registration.onProviderAuthRequired({
|
|
81
|
+
authorizeUrl,
|
|
82
|
+
dwnEndpoint,
|
|
83
|
+
state,
|
|
84
|
+
});
|
|
85
|
+
if (authResult.state !== state) {
|
|
86
|
+
throw new Error('Provider auth state mismatch \u2014 possible CSRF attack.');
|
|
87
|
+
}
|
|
88
|
+
const tokenResponse = yield DwnRegistrar.exchangeAuthCode(providerAuth.tokenUrl, authResult.code, dwnEndpoint);
|
|
89
|
+
tokenData = {
|
|
90
|
+
registrationToken: tokenResponse.registrationToken,
|
|
91
|
+
refreshToken: tokenResponse.refreshToken,
|
|
92
|
+
expiresAt: tokenResponse.expiresIn !== undefined
|
|
93
|
+
? Date.now() + (tokenResponse.expiresIn * 1000) : undefined,
|
|
94
|
+
tokenUrl: providerAuth.tokenUrl,
|
|
95
|
+
refreshUrl: providerAuth.refreshUrl,
|
|
96
|
+
};
|
|
97
|
+
updatedTokens[dwnEndpoint] = tokenData;
|
|
98
|
+
}
|
|
99
|
+
// Register each DID using the provider auth token.
|
|
100
|
+
for (const did of didsToRegister) {
|
|
101
|
+
yield DwnRegistrar.registerTenantWithToken(dwnEndpoint, did, tokenData.registrationToken);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// --- Default Path (PoW / general registration) ---
|
|
106
|
+
for (const did of didsToRegister) {
|
|
107
|
+
yield DwnRegistrar.registerTenant(dwnEndpoint, did);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Notify app of updated tokens for persistence.
|
|
112
|
+
if (registration.onRegistrationTokens) {
|
|
113
|
+
registration.onRegistrationTokens(updatedTokens);
|
|
114
|
+
}
|
|
115
|
+
registration.onSuccess();
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
registration.onFailure(error);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=dwn-registration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dwn-registration.js","sourceRoot":"","sources":["../../../src/flows/dwn-registration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity import flows.
|
|
3
|
+
*
|
|
4
|
+
* - Import from BIP-39 recovery phrase (re-derive vault + identity).
|
|
5
|
+
* - Import from PortableIdentity JSON.
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
9
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
10
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
11
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
12
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
13
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
14
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
import { AuthSession } from '../identity-session.js';
|
|
18
|
+
import { registerWithDwnEndpoints } from './dwn-registration.js';
|
|
19
|
+
import { STORAGE_KEYS } from '../types.js';
|
|
20
|
+
/**
|
|
21
|
+
* Import (or recover) an identity from a BIP-39 recovery phrase.
|
|
22
|
+
*
|
|
23
|
+
* This re-initializes the vault with the given phrase and password,
|
|
24
|
+
* recovering the agent DID and all derived keys.
|
|
25
|
+
*/
|
|
26
|
+
export function importFromPhrase(ctx, options) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
var _a, _b, _c;
|
|
29
|
+
const { userAgent, emitter, storage } = ctx;
|
|
30
|
+
const { recoveryPhrase, password } = options;
|
|
31
|
+
const sync = (_a = options.sync) !== null && _a !== void 0 ? _a : ctx.defaultSync;
|
|
32
|
+
const dwnEndpoints = (_c = (_b = options.dwnEndpoints) !== null && _b !== void 0 ? _b : ctx.defaultDwnEndpoints) !== null && _c !== void 0 ? _c : ['https://enbox-dwn.fly.dev'];
|
|
33
|
+
// Initialize the vault with the recovery phrase.
|
|
34
|
+
// This re-derives the same agent DID and CEK from the mnemonic.
|
|
35
|
+
if (yield userAgent.firstLaunch()) {
|
|
36
|
+
yield userAgent.initialize({
|
|
37
|
+
password,
|
|
38
|
+
recoveryPhrase,
|
|
39
|
+
dwnEndpoints,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
yield userAgent.start({ password });
|
|
43
|
+
emitter.emit('vault-unlocked', {});
|
|
44
|
+
// The recovery phrase re-derives the same agent DID,
|
|
45
|
+
// but the user identity might not exist yet — create one if needed.
|
|
46
|
+
const identities = yield userAgent.identity.list();
|
|
47
|
+
let identity = identities[0];
|
|
48
|
+
let isNewIdentity = false;
|
|
49
|
+
if (!identity) {
|
|
50
|
+
isNewIdentity = true;
|
|
51
|
+
identity = yield userAgent.identity.create({
|
|
52
|
+
didMethod: 'dht',
|
|
53
|
+
metadata: { name: 'Default' },
|
|
54
|
+
didOptions: {
|
|
55
|
+
services: [
|
|
56
|
+
{
|
|
57
|
+
id: 'dwn',
|
|
58
|
+
type: 'DecentralizedWebNode',
|
|
59
|
+
serviceEndpoint: dwnEndpoints,
|
|
60
|
+
enc: '#enc',
|
|
61
|
+
sig: '#sig',
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
verificationMethods: [
|
|
65
|
+
{
|
|
66
|
+
algorithm: 'Ed25519',
|
|
67
|
+
id: 'sig',
|
|
68
|
+
purposes: ['assertionMethod', 'authentication'],
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
algorithm: 'X25519',
|
|
72
|
+
id: 'enc',
|
|
73
|
+
purposes: ['keyAgreement'],
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const connectedDid = identity.did.uri;
|
|
80
|
+
// Register with DWN endpoints (if registration options are provided).
|
|
81
|
+
if (ctx.registration) {
|
|
82
|
+
yield registerWithDwnEndpoints({
|
|
83
|
+
userAgent: userAgent,
|
|
84
|
+
dwnEndpoints,
|
|
85
|
+
agentDid: userAgent.agentDid.uri,
|
|
86
|
+
connectedDid,
|
|
87
|
+
}, ctx.registration);
|
|
88
|
+
}
|
|
89
|
+
// Register and start sync.
|
|
90
|
+
if (isNewIdentity && sync !== 'off') {
|
|
91
|
+
yield userAgent.sync.registerIdentity({ did: connectedDid, options: { protocols: [] } });
|
|
92
|
+
}
|
|
93
|
+
if (sync !== 'off') {
|
|
94
|
+
const syncMode = sync === undefined ? 'live' : 'poll';
|
|
95
|
+
const syncInterval = sync !== null && sync !== void 0 ? sync : (syncMode === 'live' ? '5m' : '2m');
|
|
96
|
+
userAgent.sync.startSync({ mode: syncMode, interval: syncInterval })
|
|
97
|
+
.catch((err) => console.error('[@enbox/auth] Sync failed:', err));
|
|
98
|
+
}
|
|
99
|
+
yield storage.set(STORAGE_KEYS.PREVIOUSLY_CONNECTED, 'true');
|
|
100
|
+
yield storage.set(STORAGE_KEYS.ACTIVE_IDENTITY, connectedDid);
|
|
101
|
+
const identityInfo = {
|
|
102
|
+
didUri: connectedDid,
|
|
103
|
+
name: identity.metadata.name,
|
|
104
|
+
};
|
|
105
|
+
const session = new AuthSession({
|
|
106
|
+
agent: userAgent,
|
|
107
|
+
did: connectedDid,
|
|
108
|
+
identity: identityInfo,
|
|
109
|
+
});
|
|
110
|
+
emitter.emit('identity-added', { identity: identityInfo });
|
|
111
|
+
emitter.emit('session-start', {
|
|
112
|
+
session: { did: connectedDid, identity: identityInfo },
|
|
113
|
+
});
|
|
114
|
+
return session;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Import an identity from a PortableIdentity JSON object.
|
|
119
|
+
*
|
|
120
|
+
* The portable identity contains the DID's private keys and metadata,
|
|
121
|
+
* allowing it to be used on this device.
|
|
122
|
+
*/
|
|
123
|
+
export function importFromPortable(ctx, options) {
|
|
124
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
125
|
+
var _a, _b, _c;
|
|
126
|
+
const { userAgent, emitter, storage } = ctx;
|
|
127
|
+
const sync = (_a = options.sync) !== null && _a !== void 0 ? _a : ctx.defaultSync;
|
|
128
|
+
const identity = yield userAgent.identity.import({
|
|
129
|
+
portableIdentity: options.portableIdentity,
|
|
130
|
+
});
|
|
131
|
+
const connectedDid = (_b = identity.metadata.connectedDid) !== null && _b !== void 0 ? _b : identity.did.uri;
|
|
132
|
+
const delegateDid = identity.metadata.connectedDid ? identity.did.uri : undefined;
|
|
133
|
+
// Register with DWN endpoints (if registration options are provided).
|
|
134
|
+
// For portable imports, extract endpoints from the DID document's DWN service.
|
|
135
|
+
if (ctx.registration) {
|
|
136
|
+
const dwnEndpoints = (_c = ctx.defaultDwnEndpoints) !== null && _c !== void 0 ? _c : ['https://enbox-dwn.fly.dev'];
|
|
137
|
+
yield registerWithDwnEndpoints({
|
|
138
|
+
userAgent: userAgent,
|
|
139
|
+
dwnEndpoints,
|
|
140
|
+
agentDid: userAgent.agentDid.uri,
|
|
141
|
+
connectedDid,
|
|
142
|
+
}, ctx.registration);
|
|
143
|
+
}
|
|
144
|
+
// Register and start sync.
|
|
145
|
+
if (sync !== 'off') {
|
|
146
|
+
yield userAgent.sync.registerIdentity({
|
|
147
|
+
did: connectedDid,
|
|
148
|
+
options: { delegateDid, protocols: [] },
|
|
149
|
+
});
|
|
150
|
+
const syncMode = sync === undefined ? 'live' : 'poll';
|
|
151
|
+
const syncInterval = sync !== null && sync !== void 0 ? sync : (syncMode === 'live' ? '5m' : '2m');
|
|
152
|
+
userAgent.sync.startSync({ mode: syncMode, interval: syncInterval })
|
|
153
|
+
.catch((err) => console.error('[@enbox/auth] Sync failed:', err));
|
|
154
|
+
}
|
|
155
|
+
yield storage.set(STORAGE_KEYS.PREVIOUSLY_CONNECTED, 'true');
|
|
156
|
+
yield storage.set(STORAGE_KEYS.ACTIVE_IDENTITY, connectedDid);
|
|
157
|
+
const identityInfo = {
|
|
158
|
+
didUri: connectedDid,
|
|
159
|
+
name: identity.metadata.name,
|
|
160
|
+
connectedDid: identity.metadata.connectedDid,
|
|
161
|
+
};
|
|
162
|
+
const session = new AuthSession({
|
|
163
|
+
agent: userAgent,
|
|
164
|
+
did: connectedDid,
|
|
165
|
+
delegateDid,
|
|
166
|
+
identity: identityInfo,
|
|
167
|
+
});
|
|
168
|
+
emitter.emit('identity-added', { identity: identityInfo });
|
|
169
|
+
emitter.emit('session-start', {
|
|
170
|
+
session: { did: connectedDid, delegateDid, identity: identityInfo },
|
|
171
|
+
});
|
|
172
|
+
return session;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=import-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-identity.js","sourceRoot":"","sources":["../../../src/flows/import-identity.ts"],"names":[],"mappings":"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"}
|