@atproto/oauth-client-browser 0.3.41 → 0.4.0-next.0

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.
Files changed (40) hide show
  1. package/dist/browser-oauth-client.d.ts +4 -1
  2. package/dist/browser-oauth-client.d.ts.map +1 -1
  3. package/dist/browser-oauth-client.js +24 -38
  4. package/dist/browser-oauth-client.js.map +1 -1
  5. package/dist/browser-oauth-database.d.ts +2 -2
  6. package/dist/browser-oauth-database.d.ts.map +1 -1
  7. package/dist/browser-oauth-database.js +19 -35
  8. package/dist/browser-oauth-database.js.map +1 -1
  9. package/dist/browser-runtime-implementation.d.ts +1 -1
  10. package/dist/browser-runtime-implementation.d.ts.map +1 -1
  11. package/dist/browser-runtime-implementation.js +4 -13
  12. package/dist/browser-runtime-implementation.js.map +1 -1
  13. package/dist/errors.js +2 -11
  14. package/dist/errors.js.map +1 -1
  15. package/dist/index.d.ts +2 -2
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +7 -25
  18. package/dist/index.js.map +1 -1
  19. package/dist/indexed-db/db-index.js +8 -17
  20. package/dist/indexed-db/db-index.js.map +1 -1
  21. package/dist/indexed-db/db-object-store.js +13 -22
  22. package/dist/indexed-db/db-object-store.js.map +1 -1
  23. package/dist/indexed-db/db-transaction.d.ts +1 -1
  24. package/dist/indexed-db/db-transaction.d.ts.map +1 -1
  25. package/dist/indexed-db/db-transaction.js +13 -29
  26. package/dist/indexed-db/db-transaction.js.map +1 -1
  27. package/dist/indexed-db/db.d.ts +1 -1
  28. package/dist/indexed-db/db.d.ts.map +1 -1
  29. package/dist/indexed-db/db.js +13 -34
  30. package/dist/indexed-db/db.js.map +1 -1
  31. package/dist/indexed-db/index.js +4 -20
  32. package/dist/indexed-db/index.js.map +1 -1
  33. package/dist/indexed-db/schema.js +1 -2
  34. package/dist/indexed-db/util.js +2 -6
  35. package/dist/indexed-db/util.js.map +1 -1
  36. package/dist/indexed-db-store.js +5 -19
  37. package/dist/indexed-db-store.js.map +1 -1
  38. package/dist/util.js +3 -6
  39. package/dist/util.js.map +1 -1
  40. package/package.json +14 -13
@@ -42,7 +42,10 @@ export declare class BrowserOAuthClient extends OAuthClient implements AsyncDisp
42
42
  revoke(sub: string): Promise<void>;
43
43
  signIn(input: string, options?: AuthorizeOptions): Promise<OAuthSession>;
44
44
  signInRedirect(input: string, options?: AuthorizeOptions): Promise<never>;
45
- signInPopup(input: string, options?: Omit<AuthorizeOptions, 'state'>): Promise<OAuthSession>;
45
+ signInPopup(input: string, options?: Omit<AuthorizeOptions, 'state'> & {
46
+ popupName?: string;
47
+ popupFeatures?: string;
48
+ }): Promise<OAuthSession>;
46
49
  findRedirectUrl(): `http://[::1]${string}` | "http://127.0.0.1" | `http://127.0.0.1#${string}` | `http://127.0.0.1?${string}` | `http://127.0.0.1/${string}` | `http://127.0.0.1:${string}` | `https://${string}` | `${string}.${string}:/${string}` | undefined;
47
50
  readCallbackParams(): URLSearchParams | null;
48
51
  initCallback(params?: URLSearchParams | null, redirectUri?: `http://[::1]${string}` | "http://127.0.0.1" | `http://127.0.0.1#${string}` | `http://127.0.0.1?${string}` | `http://127.0.0.1/${string}` | `http://127.0.0.1:${string}` | `https://${string}` | `${string}.${string}:/${string}` | undefined): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"browser-oauth-client.d.ts","sourceRoot":"","sources":["../src/browser-oauth-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,KAAK,EAEL,WAAW,EACX,kBAAkB,EAClB,YAAY,EAEb,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EAIlB,MAAM,sBAAsB,CAAA;AAI7B,OAAO,EAAE,QAAQ,EAAyB,MAAM,WAAW,CAAA;AAE3D,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAC9C;IACE,cAAc,CAAC,EAAE,QAAQ,CAAC,wBAAwB,CAAC,CAAA;IACnD,YAAY,CAAC,EAAE,OAAO,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA;IACtD,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,GAAG,IAAI,CACN,kBAAkB,EAEhB,gBAAgB,GAChB,cAAc,GACd,QAAQ,GACR,OAAO,GAEP,uBAAuB,GACvB,cAAc,GACd,YAAY,GACZ,UAAU,GACV,aAAa,GACb,gBAAgB,GAChB,kCAAkC,GAClC,gCAAgC,CACnC,CACF,CAAA;AAkCD,MAAM,MAAM,6BAA6B,GAAG,QAAQ,CAClD;IACE,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,GAAG,IAAI,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,CACtD,CAAA;AAID,qBAAa,kBAAmB,SAAQ,WAAY,YAAW,eAAe;WAC/D,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,6BAA6B;IAgBzE,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAwB;IAE3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;gBAEnC,EACV,cAEC,EAED,YAAyB,EACzB,GAAG,OAAO,EACX,EAAE,yBAAyB;IA6E5B;;;;;;;;;;;;OAYG;IACG,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAElC;QAAE,OAAO,EAAE,YAAY,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,GAExC;QAAE,OAAO,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAE/C,SAAS,CACZ;IAYK,WAAW,CAAC,OAAO,CAAC,EAAE,OAAO;;;IAiB7B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC;IAM9D,MAAM,CAAC,GAAG,EAAE,MAAM;IAKlB,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,YAAY,CAAC;IAQlB,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,KAAK,CAAC;IAqBX,WAAW,CACf,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,GACxC,OAAO,CAAC,YAAY,CAAC;IA+EjB,eAAe;IAcf,kBAAkB,IAAI,eAAe,GAAG,IAAI;IActC,YAAY,CACvB,MAAM,yBAA4B,EAClC,WAAW,gPAAyB,GACnC,OAAO,CAAC;QACT,OAAO,EAAE,YAAY,CAAA;QACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KACrB,CAAC;IA0FI,CAAC,MAAM,CAAC,YAAY,CAAC;IAQ3B,OAAO;CAGR"}
1
+ {"version":3,"file":"browser-oauth-client.d.ts","sourceRoot":"","sources":["../src/browser-oauth-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,KAAK,EAEL,WAAW,EACX,kBAAkB,EAClB,YAAY,EAEb,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EAIlB,MAAM,sBAAsB,CAAA;AAI7B,OAAO,EAAE,QAAQ,EAAyB,MAAM,WAAW,CAAA;AAE3D,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAC9C;IACE,cAAc,CAAC,EAAE,QAAQ,CAAC,wBAAwB,CAAC,CAAA;IACnD,YAAY,CAAC,EAAE,OAAO,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA;IACtD,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,GAAG,IAAI,CACN,kBAAkB,EAEhB,gBAAgB,GAChB,cAAc,GACd,QAAQ,GACR,OAAO,GAEP,uBAAuB,GACvB,cAAc,GACd,YAAY,GACZ,UAAU,GACV,aAAa,GACb,gBAAgB,GAChB,kCAAkC,GAClC,gCAAgC,CACnC,CACF,CAAA;AAkCD,MAAM,MAAM,6BAA6B,GAAG,QAAQ,CAClD;IACE,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,GAAG,IAAI,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,CACtD,CAAA;AAID,qBAAa,kBAAmB,SAAQ,WAAY,YAAW,eAAe;WAC/D,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,6BAA6B;IAgBzE,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAwB;IAE3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;gBAEnC,EACV,cAEC,EAED,YAAyB,EACzB,GAAG,OAAO,EACX,EAAE,yBAAyB;IA6E5B;;;;;;;;;;;;OAYG;IACG,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAElC;QAAE,OAAO,EAAE,YAAY,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,GAExC;QAAE,OAAO,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAE/C,SAAS,CACZ;IAYK,WAAW,CAAC,OAAO,CAAC,EAAE,OAAO;;;IAiB7B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC;IAM9D,MAAM,CAAC,GAAG,EAAE,MAAM;IAKlB,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,YAAY,CAAC;IAQlB,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,KAAK,CAAC;IAqBX,WAAW,CACf,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,GAAG;QAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,GACA,OAAO,CAAC,YAAY,CAAC;IAkFjB,eAAe;IAcf,kBAAkB,IAAI,eAAe,GAAG,IAAI;IActC,YAAY,CACvB,MAAM,yBAA4B,EAClC,WAAW,gPAAyB,GACnC,OAAO,CAAC;QACT,OAAO,EAAE,YAAY,CAAA;QACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KACrB,CAAC;IA0FI,CAAC,MAAM,CAAC,YAAY,CAAC;IAQ3B,OAAO;CAGR"}
@@ -1,27 +1,24 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BrowserOAuthClient = void 0;
4
- const oauth_client_1 = require("@atproto/oauth-client");
5
- const oauth_types_1 = require("@atproto/oauth-types");
6
- const browser_oauth_database_js_1 = require("./browser-oauth-database.js");
7
- const browser_runtime_implementation_js_1 = require("./browser-runtime-implementation.js");
8
- const errors_js_1 = require("./errors.js");
9
- const util_js_1 = require("./util.js");
1
+ import { OAuthCallbackError, OAuthClient, } from '@atproto/oauth-client';
2
+ import { assertOAuthDiscoverableClientId, atprotoLoopbackClientMetadata, isOAuthClientIdLoopback, } from '@atproto/oauth-types';
3
+ import { BrowserOAuthDatabase } from './browser-oauth-database.js';
4
+ import { BrowserRuntimeImplementation } from './browser-runtime-implementation.js';
5
+ import { LoginContinuedInParentWindowError } from './errors.js';
6
+ import { buildLoopbackClientId } from './util.js';
10
7
  const NAMESPACE = `@@atproto/oauth-client-browser`;
11
8
  //- Popup channel
12
9
  const POPUP_CHANNEL_NAME = `${NAMESPACE}(popup-channel)`;
13
10
  const POPUP_STATE_PREFIX = `${NAMESPACE}(popup-state):`;
14
11
  const syncChannel = new BroadcastChannel(`${NAMESPACE}(synchronization-channel:2)`);
15
- const runtimeImplementation = new browser_runtime_implementation_js_1.BrowserRuntimeImplementation();
16
- class BrowserOAuthClient extends oauth_client_1.OAuthClient {
12
+ const runtimeImplementation = new BrowserRuntimeImplementation();
13
+ export class BrowserOAuthClient extends OAuthClient {
17
14
  static async load({ clientId, ...options }) {
18
15
  if (clientId.startsWith('http:')) {
19
- const clientMetadata = (0, oauth_types_1.atprotoLoopbackClientMetadata)(clientId);
16
+ const clientMetadata = atprotoLoopbackClientMetadata(clientId);
20
17
  return new BrowserOAuthClient({ clientMetadata, ...options });
21
18
  }
22
19
  else if (clientId.startsWith('https:')) {
23
- (0, oauth_types_1.assertOAuthDiscoverableClientId)(clientId);
24
- const clientMetadata = await oauth_client_1.OAuthClient.fetchMetadata({
20
+ assertOAuthDiscoverableClientId(clientId);
21
+ const clientMetadata = await OAuthClient.fetchMetadata({
25
22
  clientId,
26
23
  ...options,
27
24
  });
@@ -31,7 +28,7 @@ class BrowserOAuthClient extends oauth_client_1.OAuthClient {
31
28
  throw new TypeError(`Invalid client id: ${clientId}`);
32
29
  }
33
30
  }
34
- constructor({ clientMetadata = (0, oauth_types_1.atprotoLoopbackClientMetadata)((0, util_js_1.buildLoopbackClientId)(window.location)),
31
+ constructor({ clientMetadata = atprotoLoopbackClientMetadata(buildLoopbackClientId(window.location)),
35
32
  // "fragment" is a safer default as the query params will not be sent to the server
36
33
  responseMode = 'fragment', ...options }) {
37
34
  if (!globalThis.crypto?.subtle) {
@@ -41,7 +38,7 @@ class BrowserOAuthClient extends oauth_client_1.OAuthClient {
41
38
  // Make sure "form_post" is not used as it is not supported in the browser
42
39
  throw new TypeError(`Invalid response mode: ${responseMode}`);
43
40
  }
44
- const database = new browser_oauth_database_js_1.BrowserOAuthDatabase();
41
+ const database = new BrowserOAuthDatabase();
45
42
  super({
46
43
  ...options,
47
44
  clientMetadata,
@@ -73,18 +70,7 @@ class BrowserOAuthClient extends oauth_client_1.OAuthClient {
73
70
  return options.onUpdate?.call(null, sub, session);
74
71
  },
75
72
  });
76
- Object.defineProperty(this, "ac", {
77
- enumerable: true,
78
- configurable: true,
79
- writable: true,
80
- value: new AbortController()
81
- });
82
- Object.defineProperty(this, "database", {
83
- enumerable: true,
84
- configurable: true,
85
- writable: true,
86
- value: void 0
87
- });
73
+ this.ac = new AbortController();
88
74
  this.database = database;
89
75
  const { signal } = this.ac;
90
76
  // Trigger hooks when an event is emitted in another tab
@@ -168,9 +154,10 @@ class BrowserOAuthClient extends oauth_client_1.OAuthClient {
168
154
  });
169
155
  }
170
156
  async signInPopup(input, options) {
157
+ const popupTarget = options?.popupName ?? '_blank';
171
158
  // Open new window asap to prevent popup busting by browsers
172
- const popupFeatures = 'width=600,height=600,menubar=no,toolbar=no';
173
- let popup = window.open('about:blank', '_blank', popupFeatures);
159
+ const popupFeatures = options?.popupFeatures ?? 'width=600,height=600,menubar=no,toolbar=no';
160
+ let popup = window.open('about:blank', popupTarget, popupFeatures);
174
161
  const stateKey = `${Math.random().toString(36).slice(2)}`;
175
162
  const url = await this.authorize(input, {
176
163
  ...options,
@@ -182,7 +169,7 @@ class BrowserOAuthClient extends oauth_client_1.OAuthClient {
182
169
  popup.window.location.href = url.href;
183
170
  }
184
171
  else {
185
- popup = window.open(url.href, '_blank', popupFeatures);
172
+ popup = window.open(url.href, popupTarget, popupFeatures);
186
173
  }
187
174
  popup?.focus();
188
175
  return new Promise((resolve, reject) => {
@@ -224,7 +211,7 @@ class BrowserOAuthClient extends oauth_client_1.OAuthClient {
224
211
  }
225
212
  else {
226
213
  const { message, params } = result.reason;
227
- reject(new oauth_client_1.OAuthCallbackError(new URLSearchParams(params), message));
214
+ reject(new OAuthCallbackError(new URLSearchParams(params), message));
228
215
  }
229
216
  };
230
217
  popupChannel.addEventListener('message', onMessage);
@@ -295,13 +282,13 @@ class BrowserOAuthClient extends oauth_client_1.OAuthClient {
295
282
  // Revoke the credentials if the parent window was closed
296
283
  if (!receivedByParent)
297
284
  await result.session.signOut();
298
- throw new errors_js_1.LoginContinuedInParentWindowError(); // signInPopup
285
+ throw new LoginContinuedInParentWindowError(); // signInPopup
299
286
  }
300
287
  localStorage.setItem(`${NAMESPACE}(sub)`, result.session.sub);
301
288
  return result;
302
289
  })
303
290
  .catch(async (err) => {
304
- if (err instanceof oauth_client_1.OAuthCallbackError &&
291
+ if (err instanceof OAuthCallbackError &&
305
292
  err.state?.startsWith(POPUP_STATE_PREFIX)) {
306
293
  await sendPopupResult({
307
294
  key: err.state.slice(POPUP_STATE_PREFIX.length),
@@ -313,14 +300,14 @@ class BrowserOAuthClient extends oauth_client_1.OAuthClient {
313
300
  },
314
301
  },
315
302
  });
316
- throw new errors_js_1.LoginContinuedInParentWindowError(); // signInPopup
303
+ throw new LoginContinuedInParentWindowError(); // signInPopup
317
304
  }
318
305
  // Most probable cause at this point is that the "state" parameter is
319
306
  // invalid.
320
307
  throw err;
321
308
  })
322
309
  .catch((err) => {
323
- if (err instanceof errors_js_1.LoginContinuedInParentWindowError) {
310
+ if (err instanceof LoginContinuedInParentWindowError) {
324
311
  // parent will also try to close the popup
325
312
  window.close();
326
313
  }
@@ -339,7 +326,6 @@ class BrowserOAuthClient extends oauth_client_1.OAuthClient {
339
326
  this[Symbol.dispose]();
340
327
  }
341
328
  }
342
- exports.BrowserOAuthClient = BrowserOAuthClient;
343
329
  /**
344
330
  * Since "localhost" is often used either in IP mode or in hostname mode,
345
331
  * and because the redirect uris must use the IP mode, we need to make sure
@@ -350,7 +336,7 @@ exports.BrowserOAuthClient = BrowserOAuthClient;
350
336
  * redirect uris.
351
337
  */
352
338
  function fixLocation(clientMetadata) {
353
- if (!(0, oauth_types_1.isOAuthClientIdLoopback)(clientMetadata.client_id))
339
+ if (!isOAuthClientIdLoopback(clientMetadata.client_id))
354
340
  return;
355
341
  if (window.location.hostname !== 'localhost')
356
342
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"browser-oauth-client.js","sourceRoot":"","sources":["../src/browser-oauth-client.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AuthorizeOptions,\n ClientMetadata,\n Fetch,\n OAuthCallbackError,\n OAuthClient,\n OAuthClientOptions,\n OAuthSession,\n SessionHooks,\n} from '@atproto/oauth-client'\nimport {\n OAuthClientMetadataInput,\n OAuthResponseMode,\n assertOAuthDiscoverableClientId,\n atprotoLoopbackClientMetadata,\n isOAuthClientIdLoopback,\n} from '@atproto/oauth-types'\nimport { BrowserOAuthDatabase } from './browser-oauth-database.js'\nimport { BrowserRuntimeImplementation } from './browser-runtime-implementation.js'\nimport { LoginContinuedInParentWindowError } from './errors.js'\nimport { Simplify, buildLoopbackClientId } from './util.js'\n\nexport type BrowserOAuthClientOptions = Simplify<\n {\n clientMetadata?: Readonly<OAuthClientMetadataInput>\n responseMode?: Exclude<OAuthResponseMode, 'form_post'>\n fetch?: Fetch\n } & Omit<\n OAuthClientOptions,\n // Overridden by this lib\n | 'clientMetadata'\n | 'responseMode'\n | 'keyset'\n | 'fetch'\n // Provided by this lib\n | 'runtimeImplementation'\n | 'sessionStore'\n | 'stateStore'\n | 'didCache'\n | 'handleCache'\n | 'dpopNonceCache'\n | 'authorizationServerMetadataCache'\n | 'protectedResourceMetadataCache'\n >\n>\n\nconst NAMESPACE = `@@atproto/oauth-client-browser`\n\n//- Popup channel\n\nconst POPUP_CHANNEL_NAME = `${NAMESPACE}(popup-channel)`\nconst POPUP_STATE_PREFIX = `${NAMESPACE}(popup-state):`\n\ntype PopupChannelResultData = {\n key: string\n result: PromiseRejectedResult | PromiseFulfilledResult<string>\n}\n\ntype PopupChannelAckData = {\n key: string\n ack: true\n}\n\ntype PopupChannelData = PopupChannelResultData | PopupChannelAckData\n\n//- State synchronization channel\n\ntype SyncChannelMessage = {\n [K in keyof SessionHooks & string]: {\n name: K\n args: Parameters<NonNullable<SessionHooks[K]>>\n }\n}[keyof SessionHooks]\n\nconst syncChannel = new BroadcastChannel(\n `${NAMESPACE}(synchronization-channel:2)`,\n)\n\nexport type BrowserOAuthClientLoadOptions = Simplify<\n {\n clientId: string\n signal?: AbortSignal\n } & Omit<BrowserOAuthClientOptions, 'clientMetadata'>\n>\n\nconst runtimeImplementation = new BrowserRuntimeImplementation()\n\nexport class BrowserOAuthClient extends OAuthClient implements AsyncDisposable {\n static async load({ clientId, ...options }: BrowserOAuthClientLoadOptions) {\n if (clientId.startsWith('http:')) {\n const clientMetadata = atprotoLoopbackClientMetadata(clientId)\n return new BrowserOAuthClient({ clientMetadata, ...options })\n } else if (clientId.startsWith('https:')) {\n assertOAuthDiscoverableClientId(clientId)\n const clientMetadata = await OAuthClient.fetchMetadata({\n clientId,\n ...options,\n })\n return new BrowserOAuthClient({ ...options, clientMetadata })\n } else {\n throw new TypeError(`Invalid client id: ${clientId}`)\n }\n }\n\n private readonly ac = new AbortController()\n\n private readonly database: BrowserOAuthDatabase\n\n constructor({\n clientMetadata = atprotoLoopbackClientMetadata(\n buildLoopbackClientId(window.location),\n ),\n // \"fragment\" is a safer default as the query params will not be sent to the server\n responseMode = 'fragment',\n ...options\n }: BrowserOAuthClientOptions) {\n if (!globalThis.crypto?.subtle) {\n throw new Error('WebCrypto API is required')\n }\n\n if (!['query', 'fragment'].includes(responseMode)) {\n // Make sure \"form_post\" is not used as it is not supported in the browser\n throw new TypeError(`Invalid response mode: ${responseMode}`)\n }\n\n const database = new BrowserOAuthDatabase()\n\n super({\n ...options,\n\n clientMetadata,\n responseMode,\n keyset: undefined,\n\n runtimeImplementation,\n\n sessionStore: database.getSessionStore(),\n stateStore: database.getStateStore(),\n\n didCache: database.getDidCache(),\n handleCache: database.getHandleCache(),\n dpopNonceCache: database.getDpopNonceCache(),\n authorizationServerMetadataCache:\n database.getAuthorizationServerMetadataCache(),\n protectedResourceMetadataCache:\n database.getProtectedResourceMetadataCache(),\n\n onDelete: async (sub, cause) => {\n if (localStorage.getItem(`${NAMESPACE}(sub)`) === sub) {\n localStorage.removeItem(`${NAMESPACE}(sub)`)\n }\n\n syncChannel.postMessage({\n name: 'onDelete',\n args: [sub, cause],\n } satisfies SyncChannelMessage)\n\n return options.onDelete?.call(null, sub, cause)\n },\n\n onUpdate: async (sub, session) => {\n syncChannel.postMessage({\n name: 'onUpdate',\n args: [sub, session],\n } satisfies SyncChannelMessage)\n\n return options.onUpdate?.call(null, sub, session)\n },\n })\n\n this.database = database\n\n const { signal } = this.ac\n\n // Trigger hooks when an event is emitted in another tab\n syncChannel.addEventListener(\n 'message',\n (event) => {\n if (event.source === window) return\n\n const { name, args } = event.data as SyncChannelMessage\n\n const hook = options[name]\n\n // @ts-expect-error TS has a hard time matching the args with the hook\n void hook?.(...args)\n },\n // Remove the listener when the client is disposed\n { signal },\n )\n }\n\n /**\n * This method will automatically restore any existing session, or attempt to\n * process login callback if the URL contains oauth parameters.\n *\n * Use {@link BrowserOAuthClient.initCallback} instead of this method if you\n * want to force a login callback. This can be esp. useful if you are using\n * this lib from a framework that has some kind of URL manipulation (like a\n * client side router).\n *\n * Use {@link BrowserOAuthClient.initRestore} instead of this method if you\n * want to only restore existing sessions, and bypass the automatic processing\n * of login callbacks.\n */\n async init(refresh?: boolean): Promise<\n // Session restored\n | { session: OAuthSession; state?: never }\n // Login callback processed\n | { session: OAuthSession; state: string | null }\n // No session or callback\n | undefined\n > {\n // If the URL currently contains oauth query parameters (\"state\" + \"code\" or\n // \"state\" + \"error\"), let's automatically process them.\n const params = this.readCallbackParams()\n if (params) {\n const redirectUri = this.findRedirectUrl()\n if (redirectUri) return this.initCallback(params, redirectUri)\n }\n\n return this.initRestore(refresh)\n }\n\n async initRestore(refresh?: boolean) {\n // @NOTE Fixing the location should not be needed from callback endpoints\n // since callback endpoint are required to use IP based URLs (for localhost)\n await fixLocation(this.clientMetadata)\n\n const sub = localStorage.getItem(`${NAMESPACE}(sub)`)\n if (sub) {\n try {\n const session = await this.restore(sub, refresh)\n return { session }\n } catch (err) {\n localStorage.removeItem(`${NAMESPACE}(sub)`)\n throw err\n }\n }\n }\n\n async restore(sub: string, refresh?: boolean): Promise<OAuthSession> {\n const session = await super.restore(sub, refresh)\n localStorage.setItem(`${NAMESPACE}(sub)`, session.sub)\n return session\n }\n\n async revoke(sub: string) {\n localStorage.removeItem(`${NAMESPACE}(sub)`)\n return super.revoke(sub)\n }\n\n async signIn(\n input: string,\n options?: AuthorizeOptions,\n ): Promise<OAuthSession> {\n if (options?.display === 'popup') {\n return this.signInPopup(input, options)\n } else {\n return this.signInRedirect(input, options)\n }\n }\n\n async signInRedirect(\n input: string,\n options?: AuthorizeOptions,\n ): Promise<never> {\n const url = await this.authorize(input, options)\n\n window.location.href = url.href\n\n // back-forward cache\n return new Promise<never>((resolve, reject) => {\n setTimeout(\n (err: Error) => {\n // Take the opportunity to proactively cancel the pending request\n this.abortRequest(url).then(\n () => reject(err),\n (reason) => reject(new AggregateError([err, reason])),\n )\n },\n 5e3,\n new Error('User navigated back'),\n )\n })\n }\n\n async signInPopup(\n input: string,\n options?: Omit<AuthorizeOptions, 'state'>,\n ): Promise<OAuthSession> {\n // Open new window asap to prevent popup busting by browsers\n const popupFeatures = 'width=600,height=600,menubar=no,toolbar=no'\n let popup: Window | null = window.open(\n 'about:blank',\n '_blank',\n popupFeatures,\n )\n\n const stateKey = `${Math.random().toString(36).slice(2)}`\n\n const url = await this.authorize(input, {\n ...options,\n state: `${POPUP_STATE_PREFIX}${stateKey}`,\n display: options?.display ?? 'popup',\n })\n\n options?.signal?.throwIfAborted()\n\n if (popup) {\n popup.window.location.href = url.href\n } else {\n popup = window.open(url.href, '_blank', popupFeatures)\n }\n\n popup?.focus()\n\n return new Promise<OAuthSession>((resolve, reject) => {\n const popupChannel = new BroadcastChannel(POPUP_CHANNEL_NAME)\n\n const cleanup = () => {\n clearTimeout(timeout)\n popupChannel.removeEventListener('message', onMessage)\n popupChannel.close()\n options?.signal?.removeEventListener('abort', cancel)\n popup?.close()\n }\n\n const cancel = () => {\n // @TODO Store fact that the request was cancelled, allowing any\n // callback (e.g. in the popup) to revoke the session or credentials.\n\n reject(new Error(options?.signal?.aborted ? 'Aborted' : 'Timeout'))\n cleanup()\n }\n\n options?.signal?.addEventListener('abort', cancel)\n\n const timeout = setTimeout(cancel, 5 * 60e3)\n\n const onMessage = async ({ data }: MessageEvent<PopupChannelData>) => {\n if (data.key !== stateKey) return\n if (!('result' in data)) return\n\n // Send acknowledgment to popup window\n popupChannel.postMessage({ key: stateKey, ack: true })\n\n cleanup()\n\n const { result } = data\n if (result.status === 'fulfilled') {\n const sub = result.value\n try {\n options?.signal?.throwIfAborted()\n resolve(await this.restore(sub, false))\n } catch (err) {\n reject(err)\n void this.revoke(sub)\n }\n } else {\n const { message, params } = result.reason\n reject(new OAuthCallbackError(new URLSearchParams(params), message))\n }\n }\n\n popupChannel.addEventListener('message', onMessage)\n })\n }\n\n public findRedirectUrl() {\n for (const uri of this.clientMetadata.redirect_uris) {\n const url = new URL(uri)\n if (\n location.origin === url.origin &&\n location.pathname === url.pathname\n ) {\n return uri\n }\n }\n\n return undefined\n }\n\n public readCallbackParams(): URLSearchParams | null {\n const params =\n this.responseMode === 'fragment'\n ? new URLSearchParams(location.hash.slice(1))\n : new URLSearchParams(location.search)\n\n // Only if the current URL contains a valid oauth response params\n if (!params.has('state') || !(params.has('code') || params.has('error'))) {\n return null\n }\n\n return params\n }\n\n public async initCallback(\n params = this.readCallbackParams(),\n redirectUri = this.findRedirectUrl(),\n ): Promise<{\n session: OAuthSession\n state: string | null\n }> {\n if (!params) {\n throw new TypeError('No OAuth callback parameters found in the URL')\n }\n\n // Replace the current history entry without the params (this will prevent\n // the following code to run again if the user refreshes the page)\n if (this.responseMode === 'fragment') {\n history.replaceState(null, '', location.pathname + location.search)\n } else if (this.responseMode === 'query') {\n history.replaceState(null, '', location.pathname)\n }\n\n // Utility function to send the result of the popup to the parent window\n const sendPopupResult = (message: PopupChannelResultData) => {\n const popupChannel = new BroadcastChannel(POPUP_CHANNEL_NAME)\n\n return new Promise<boolean>((resolve) => {\n const cleanup = (result: boolean) => {\n clearTimeout(timer)\n popupChannel.removeEventListener('message', onMessage)\n popupChannel.close()\n resolve(result)\n }\n\n const onMessage = ({ data }: MessageEvent<PopupChannelData>) => {\n if ('ack' in data && message.key === data.key) cleanup(true)\n }\n\n popupChannel.addEventListener('message', onMessage)\n popupChannel.postMessage(message)\n // Receiving of \"ack\" should be very fast, giving it 500 ms anyway\n const timer = setTimeout(cleanup, 500, false)\n })\n }\n\n return this.callback(params, { redirect_uri: redirectUri })\n .then(async (result) => {\n if (result.state?.startsWith(POPUP_STATE_PREFIX)) {\n const receivedByParent = await sendPopupResult({\n key: result.state.slice(POPUP_STATE_PREFIX.length),\n result: {\n status: 'fulfilled',\n value: result.session.sub,\n },\n })\n\n // Revoke the credentials if the parent window was closed\n if (!receivedByParent) await result.session.signOut()\n\n throw new LoginContinuedInParentWindowError() // signInPopup\n }\n\n localStorage.setItem(`${NAMESPACE}(sub)`, result.session.sub)\n\n return result\n })\n .catch(async (err) => {\n if (\n err instanceof OAuthCallbackError &&\n err.state?.startsWith(POPUP_STATE_PREFIX)\n ) {\n await sendPopupResult({\n key: err.state.slice(POPUP_STATE_PREFIX.length),\n result: {\n status: 'rejected',\n reason: {\n message: err.message,\n params: Array.from(err.params.entries()),\n },\n },\n })\n\n throw new LoginContinuedInParentWindowError() // signInPopup\n }\n\n // Most probable cause at this point is that the \"state\" parameter is\n // invalid.\n throw err\n })\n .catch((err) => {\n if (err instanceof LoginContinuedInParentWindowError) {\n // parent will also try to close the popup\n window.close()\n }\n\n throw err\n })\n }\n\n async [Symbol.asyncDispose]() {\n try {\n this.ac.abort()\n } finally {\n await this.database[Symbol.asyncDispose]()\n }\n }\n\n dispose() {\n this[Symbol.dispose]()\n }\n}\n\n/**\n * Since \"localhost\" is often used either in IP mode or in hostname mode,\n * and because the redirect uris must use the IP mode, we need to make sure\n * that the current location url is not using \"localhost\".\n *\n * This is required for the IndexedDB to work properly. Indeed, the IndexedDB\n * is shared by origin, so we must ensure to be on the same origin as the\n * redirect uris.\n */\nfunction fixLocation(clientMetadata: ClientMetadata) {\n if (!isOAuthClientIdLoopback(clientMetadata.client_id)) return\n if (window.location.hostname !== 'localhost') return\n\n const locationUrl = new URL(window.location.href)\n\n for (const uri of clientMetadata.redirect_uris) {\n const url = new URL(uri)\n if (\n (url.hostname === '127.0.0.1' || url.hostname === '[::1]') &&\n (!url.port || url.port === locationUrl.port) &&\n url.protocol === locationUrl.protocol &&\n url.pathname === locationUrl.pathname\n ) {\n url.port = locationUrl.port\n window.location.href = url.href\n\n // Prevent init() on the wrong origin\n throw new Error('Redirecting to loopback IP...')\n }\n }\n\n throw new Error(\n `Please use the loopback IP address instead of ${locationUrl}`,\n )\n}\n"]}
1
+ {"version":3,"file":"browser-oauth-client.js","sourceRoot":"","sources":["../src/browser-oauth-client.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AuthorizeOptions,\n ClientMetadata,\n Fetch,\n OAuthCallbackError,\n OAuthClient,\n OAuthClientOptions,\n OAuthSession,\n SessionHooks,\n} from '@atproto/oauth-client'\nimport {\n OAuthClientMetadataInput,\n OAuthResponseMode,\n assertOAuthDiscoverableClientId,\n atprotoLoopbackClientMetadata,\n isOAuthClientIdLoopback,\n} from '@atproto/oauth-types'\nimport { BrowserOAuthDatabase } from './browser-oauth-database.js'\nimport { BrowserRuntimeImplementation } from './browser-runtime-implementation.js'\nimport { LoginContinuedInParentWindowError } from './errors.js'\nimport { Simplify, buildLoopbackClientId } from './util.js'\n\nexport type BrowserOAuthClientOptions = Simplify<\n {\n clientMetadata?: Readonly<OAuthClientMetadataInput>\n responseMode?: Exclude<OAuthResponseMode, 'form_post'>\n fetch?: Fetch\n } & Omit<\n OAuthClientOptions,\n // Overridden by this lib\n | 'clientMetadata'\n | 'responseMode'\n | 'keyset'\n | 'fetch'\n // Provided by this lib\n | 'runtimeImplementation'\n | 'sessionStore'\n | 'stateStore'\n | 'didCache'\n | 'handleCache'\n | 'dpopNonceCache'\n | 'authorizationServerMetadataCache'\n | 'protectedResourceMetadataCache'\n >\n>\n\nconst NAMESPACE = `@@atproto/oauth-client-browser`\n\n//- Popup channel\n\nconst POPUP_CHANNEL_NAME = `${NAMESPACE}(popup-channel)`\nconst POPUP_STATE_PREFIX = `${NAMESPACE}(popup-state):`\n\ntype PopupChannelResultData = {\n key: string\n result: PromiseRejectedResult | PromiseFulfilledResult<string>\n}\n\ntype PopupChannelAckData = {\n key: string\n ack: true\n}\n\ntype PopupChannelData = PopupChannelResultData | PopupChannelAckData\n\n//- State synchronization channel\n\ntype SyncChannelMessage = {\n [K in keyof SessionHooks & string]: {\n name: K\n args: Parameters<NonNullable<SessionHooks[K]>>\n }\n}[keyof SessionHooks]\n\nconst syncChannel = new BroadcastChannel(\n `${NAMESPACE}(synchronization-channel:2)`,\n)\n\nexport type BrowserOAuthClientLoadOptions = Simplify<\n {\n clientId: string\n signal?: AbortSignal\n } & Omit<BrowserOAuthClientOptions, 'clientMetadata'>\n>\n\nconst runtimeImplementation = new BrowserRuntimeImplementation()\n\nexport class BrowserOAuthClient extends OAuthClient implements AsyncDisposable {\n static async load({ clientId, ...options }: BrowserOAuthClientLoadOptions) {\n if (clientId.startsWith('http:')) {\n const clientMetadata = atprotoLoopbackClientMetadata(clientId)\n return new BrowserOAuthClient({ clientMetadata, ...options })\n } else if (clientId.startsWith('https:')) {\n assertOAuthDiscoverableClientId(clientId)\n const clientMetadata = await OAuthClient.fetchMetadata({\n clientId,\n ...options,\n })\n return new BrowserOAuthClient({ ...options, clientMetadata })\n } else {\n throw new TypeError(`Invalid client id: ${clientId}`)\n }\n }\n\n private readonly ac = new AbortController()\n\n private readonly database: BrowserOAuthDatabase\n\n constructor({\n clientMetadata = atprotoLoopbackClientMetadata(\n buildLoopbackClientId(window.location),\n ),\n // \"fragment\" is a safer default as the query params will not be sent to the server\n responseMode = 'fragment',\n ...options\n }: BrowserOAuthClientOptions) {\n if (!globalThis.crypto?.subtle) {\n throw new Error('WebCrypto API is required')\n }\n\n if (!['query', 'fragment'].includes(responseMode)) {\n // Make sure \"form_post\" is not used as it is not supported in the browser\n throw new TypeError(`Invalid response mode: ${responseMode}`)\n }\n\n const database = new BrowserOAuthDatabase()\n\n super({\n ...options,\n\n clientMetadata,\n responseMode,\n keyset: undefined,\n\n runtimeImplementation,\n\n sessionStore: database.getSessionStore(),\n stateStore: database.getStateStore(),\n\n didCache: database.getDidCache(),\n handleCache: database.getHandleCache(),\n dpopNonceCache: database.getDpopNonceCache(),\n authorizationServerMetadataCache:\n database.getAuthorizationServerMetadataCache(),\n protectedResourceMetadataCache:\n database.getProtectedResourceMetadataCache(),\n\n onDelete: async (sub, cause) => {\n if (localStorage.getItem(`${NAMESPACE}(sub)`) === sub) {\n localStorage.removeItem(`${NAMESPACE}(sub)`)\n }\n\n syncChannel.postMessage({\n name: 'onDelete',\n args: [sub, cause],\n } satisfies SyncChannelMessage)\n\n return options.onDelete?.call(null, sub, cause)\n },\n\n onUpdate: async (sub, session) => {\n syncChannel.postMessage({\n name: 'onUpdate',\n args: [sub, session],\n } satisfies SyncChannelMessage)\n\n return options.onUpdate?.call(null, sub, session)\n },\n })\n\n this.database = database\n\n const { signal } = this.ac\n\n // Trigger hooks when an event is emitted in another tab\n syncChannel.addEventListener(\n 'message',\n (event) => {\n if (event.source === window) return\n\n const { name, args } = event.data as SyncChannelMessage\n\n const hook = options[name]\n\n // @ts-expect-error TS has a hard time matching the args with the hook\n void hook?.(...args)\n },\n // Remove the listener when the client is disposed\n { signal },\n )\n }\n\n /**\n * This method will automatically restore any existing session, or attempt to\n * process login callback if the URL contains oauth parameters.\n *\n * Use {@link BrowserOAuthClient.initCallback} instead of this method if you\n * want to force a login callback. This can be esp. useful if you are using\n * this lib from a framework that has some kind of URL manipulation (like a\n * client side router).\n *\n * Use {@link BrowserOAuthClient.initRestore} instead of this method if you\n * want to only restore existing sessions, and bypass the automatic processing\n * of login callbacks.\n */\n async init(refresh?: boolean): Promise<\n // Session restored\n | { session: OAuthSession; state?: never }\n // Login callback processed\n | { session: OAuthSession; state: string | null }\n // No session or callback\n | undefined\n > {\n // If the URL currently contains oauth query parameters (\"state\" + \"code\" or\n // \"state\" + \"error\"), let's automatically process them.\n const params = this.readCallbackParams()\n if (params) {\n const redirectUri = this.findRedirectUrl()\n if (redirectUri) return this.initCallback(params, redirectUri)\n }\n\n return this.initRestore(refresh)\n }\n\n async initRestore(refresh?: boolean) {\n // @NOTE Fixing the location should not be needed from callback endpoints\n // since callback endpoint are required to use IP based URLs (for localhost)\n await fixLocation(this.clientMetadata)\n\n const sub = localStorage.getItem(`${NAMESPACE}(sub)`)\n if (sub) {\n try {\n const session = await this.restore(sub, refresh)\n return { session }\n } catch (err) {\n localStorage.removeItem(`${NAMESPACE}(sub)`)\n throw err\n }\n }\n }\n\n async restore(sub: string, refresh?: boolean): Promise<OAuthSession> {\n const session = await super.restore(sub, refresh)\n localStorage.setItem(`${NAMESPACE}(sub)`, session.sub)\n return session\n }\n\n async revoke(sub: string) {\n localStorage.removeItem(`${NAMESPACE}(sub)`)\n return super.revoke(sub)\n }\n\n async signIn(\n input: string,\n options?: AuthorizeOptions,\n ): Promise<OAuthSession> {\n if (options?.display === 'popup') {\n return this.signInPopup(input, options)\n } else {\n return this.signInRedirect(input, options)\n }\n }\n\n async signInRedirect(\n input: string,\n options?: AuthorizeOptions,\n ): Promise<never> {\n const url = await this.authorize(input, options)\n\n window.location.href = url.href\n\n // back-forward cache\n return new Promise<never>((resolve, reject) => {\n setTimeout(\n (err: Error) => {\n // Take the opportunity to proactively cancel the pending request\n this.abortRequest(url).then(\n () => reject(err),\n (reason) => reject(new AggregateError([err, reason])),\n )\n },\n 5e3,\n new Error('User navigated back'),\n )\n })\n }\n\n async signInPopup(\n input: string,\n options?: Omit<AuthorizeOptions, 'state'> & {\n popupName?: string\n popupFeatures?: string\n },\n ): Promise<OAuthSession> {\n const popupTarget = options?.popupName ?? '_blank'\n\n // Open new window asap to prevent popup busting by browsers\n const popupFeatures =\n options?.popupFeatures ?? 'width=600,height=600,menubar=no,toolbar=no'\n let popup: Window | null = window.open(\n 'about:blank',\n popupTarget,\n popupFeatures,\n )\n\n const stateKey = `${Math.random().toString(36).slice(2)}`\n\n const url = await this.authorize(input, {\n ...options,\n state: `${POPUP_STATE_PREFIX}${stateKey}`,\n display: options?.display ?? 'popup',\n })\n\n options?.signal?.throwIfAborted()\n\n if (popup) {\n popup.window.location.href = url.href\n } else {\n popup = window.open(url.href, popupTarget, popupFeatures)\n }\n\n popup?.focus()\n\n return new Promise<OAuthSession>((resolve, reject) => {\n const popupChannel = new BroadcastChannel(POPUP_CHANNEL_NAME)\n\n const cleanup = () => {\n clearTimeout(timeout)\n popupChannel.removeEventListener('message', onMessage)\n popupChannel.close()\n options?.signal?.removeEventListener('abort', cancel)\n popup?.close()\n }\n\n const cancel = () => {\n // @TODO Store fact that the request was cancelled, allowing any\n // callback (e.g. in the popup) to revoke the session or credentials.\n\n reject(new Error(options?.signal?.aborted ? 'Aborted' : 'Timeout'))\n cleanup()\n }\n\n options?.signal?.addEventListener('abort', cancel)\n\n const timeout = setTimeout(cancel, 5 * 60e3)\n\n const onMessage = async ({ data }: MessageEvent<PopupChannelData>) => {\n if (data.key !== stateKey) return\n if (!('result' in data)) return\n\n // Send acknowledgment to popup window\n popupChannel.postMessage({ key: stateKey, ack: true })\n\n cleanup()\n\n const { result } = data\n if (result.status === 'fulfilled') {\n const sub = result.value\n try {\n options?.signal?.throwIfAborted()\n resolve(await this.restore(sub, false))\n } catch (err) {\n reject(err)\n void this.revoke(sub)\n }\n } else {\n const { message, params } = result.reason\n reject(new OAuthCallbackError(new URLSearchParams(params), message))\n }\n }\n\n popupChannel.addEventListener('message', onMessage)\n })\n }\n\n public findRedirectUrl() {\n for (const uri of this.clientMetadata.redirect_uris) {\n const url = new URL(uri)\n if (\n location.origin === url.origin &&\n location.pathname === url.pathname\n ) {\n return uri\n }\n }\n\n return undefined\n }\n\n public readCallbackParams(): URLSearchParams | null {\n const params =\n this.responseMode === 'fragment'\n ? new URLSearchParams(location.hash.slice(1))\n : new URLSearchParams(location.search)\n\n // Only if the current URL contains a valid oauth response params\n if (!params.has('state') || !(params.has('code') || params.has('error'))) {\n return null\n }\n\n return params\n }\n\n public async initCallback(\n params = this.readCallbackParams(),\n redirectUri = this.findRedirectUrl(),\n ): Promise<{\n session: OAuthSession\n state: string | null\n }> {\n if (!params) {\n throw new TypeError('No OAuth callback parameters found in the URL')\n }\n\n // Replace the current history entry without the params (this will prevent\n // the following code to run again if the user refreshes the page)\n if (this.responseMode === 'fragment') {\n history.replaceState(null, '', location.pathname + location.search)\n } else if (this.responseMode === 'query') {\n history.replaceState(null, '', location.pathname)\n }\n\n // Utility function to send the result of the popup to the parent window\n const sendPopupResult = (message: PopupChannelResultData) => {\n const popupChannel = new BroadcastChannel(POPUP_CHANNEL_NAME)\n\n return new Promise<boolean>((resolve) => {\n const cleanup = (result: boolean) => {\n clearTimeout(timer)\n popupChannel.removeEventListener('message', onMessage)\n popupChannel.close()\n resolve(result)\n }\n\n const onMessage = ({ data }: MessageEvent<PopupChannelData>) => {\n if ('ack' in data && message.key === data.key) cleanup(true)\n }\n\n popupChannel.addEventListener('message', onMessage)\n popupChannel.postMessage(message)\n // Receiving of \"ack\" should be very fast, giving it 500 ms anyway\n const timer = setTimeout(cleanup, 500, false)\n })\n }\n\n return this.callback(params, { redirect_uri: redirectUri })\n .then(async (result) => {\n if (result.state?.startsWith(POPUP_STATE_PREFIX)) {\n const receivedByParent = await sendPopupResult({\n key: result.state.slice(POPUP_STATE_PREFIX.length),\n result: {\n status: 'fulfilled',\n value: result.session.sub,\n },\n })\n\n // Revoke the credentials if the parent window was closed\n if (!receivedByParent) await result.session.signOut()\n\n throw new LoginContinuedInParentWindowError() // signInPopup\n }\n\n localStorage.setItem(`${NAMESPACE}(sub)`, result.session.sub)\n\n return result\n })\n .catch(async (err) => {\n if (\n err instanceof OAuthCallbackError &&\n err.state?.startsWith(POPUP_STATE_PREFIX)\n ) {\n await sendPopupResult({\n key: err.state.slice(POPUP_STATE_PREFIX.length),\n result: {\n status: 'rejected',\n reason: {\n message: err.message,\n params: Array.from(err.params.entries()),\n },\n },\n })\n\n throw new LoginContinuedInParentWindowError() // signInPopup\n }\n\n // Most probable cause at this point is that the \"state\" parameter is\n // invalid.\n throw err\n })\n .catch((err) => {\n if (err instanceof LoginContinuedInParentWindowError) {\n // parent will also try to close the popup\n window.close()\n }\n\n throw err\n })\n }\n\n async [Symbol.asyncDispose]() {\n try {\n this.ac.abort()\n } finally {\n await this.database[Symbol.asyncDispose]()\n }\n }\n\n dispose() {\n this[Symbol.dispose]()\n }\n}\n\n/**\n * Since \"localhost\" is often used either in IP mode or in hostname mode,\n * and because the redirect uris must use the IP mode, we need to make sure\n * that the current location url is not using \"localhost\".\n *\n * This is required for the IndexedDB to work properly. Indeed, the IndexedDB\n * is shared by origin, so we must ensure to be on the same origin as the\n * redirect uris.\n */\nfunction fixLocation(clientMetadata: ClientMetadata) {\n if (!isOAuthClientIdLoopback(clientMetadata.client_id)) return\n if (window.location.hostname !== 'localhost') return\n\n const locationUrl = new URL(window.location.href)\n\n for (const uri of clientMetadata.redirect_uris) {\n const url = new URL(uri)\n if (\n (url.hostname === '127.0.0.1' || url.hostname === '[::1]') &&\n (!url.port || url.port === locationUrl.port) &&\n url.protocol === locationUrl.protocol &&\n url.pathname === locationUrl.pathname\n ) {\n url.port = locationUrl.port\n window.location.href = url.href\n\n // Prevent init() on the wrong origin\n throw new Error('Redirecting to loopback IP...')\n }\n }\n\n throw new Error(\n `Please use the loopback IP address instead of ${locationUrl}`,\n )\n}\n"]}
@@ -23,7 +23,7 @@ export type Schema = {
23
23
  dpopNonceCache: Item<string>;
24
24
  handleCache: Item<ResolvedHandle>;
25
25
  authorizationServerMetadataCache: Item<OAuthAuthorizationServerMetadata>;
26
- protectedResourceMetadataCache: Item<OAuthProtectedResourceMetadata>;
26
+ protectedResourceMetadataCache: Item<OAuthProtectedResourceMetadata | null>;
27
27
  };
28
28
  export type DatabaseStore<V extends Value> = SimpleStore<string, V>;
29
29
  export type BrowserOAuthDatabaseOptions = {
@@ -46,7 +46,7 @@ export declare class BrowserOAuthDatabase {
46
46
  getDidCache(): DatabaseStore<DidDocument>;
47
47
  getHandleCache(): DatabaseStore<ResolvedHandle>;
48
48
  getAuthorizationServerMetadataCache(): undefined | DatabaseStore<OAuthAuthorizationServerMetadata>;
49
- getProtectedResourceMetadataCache(): undefined | DatabaseStore<OAuthProtectedResourceMetadata>;
49
+ getProtectedResourceMetadataCache(): undefined | DatabaseStore<OAuthProtectedResourceMetadata | null>;
50
50
  cleanup(): Promise<void>;
51
51
  [Symbol.asyncDispose](): Promise<void>;
52
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"browser-oauth-database.d.ts","sourceRoot":"","sources":["../src/browser-oauth-database.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browser-oauth-database.d.ts","sourceRoot":"","sources":["../src/browser-oauth-database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG1C,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,EACL,gCAAgC,EAChC,8BAA8B,EAC/B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAC/D,OAAO,EAAM,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAGzD,KAAK,IAAI,CAAC,CAAC,IAAI;IACb,KAAK,EAAE,CAAC,CAAA;IACR,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,aAAa,CAAA;CACvB,CAAA;AAgBD,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,GAAG;QAAE,OAAO,EAAE,UAAU,CAAA;KAAE,CAAC,CAAA;IACzE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,GAAG;QAAE,OAAO,EAAE,UAAU,CAAA;KAAE,CAAC,CAAA;IACjE,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IAC3B,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC5B,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;IACjC,gCAAgC,EAAE,IAAI,CAAC,gCAAgC,CAAC,CAAA;IACxE,8BAA8B,EAAE,IAAI,CAAC,8BAA8B,GAAG,IAAI,CAAC,CAAA;CAC5E,CAAA;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAanE,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IACjC,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,qBAAa,oBAAoB;;gBAInB,OAAO,CAAC,EAAE,2BAA2B;cAmBjC,GAAG,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,CAAC,EAC3C,SAAS,EAAE,CAAC,EACZ,IAAI,EAAE,UAAU,GAAG,WAAW,EAC9B,EAAE,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAClD,OAAO,CAAC,CAAC,CAAC;IAOb,SAAS,CAAC,WAAW,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,CAAC,SAAS,KAAK,EAC3D,IAAI,EAAE,CAAC,EACP,EACE,MAAM,EACN,MAAM,EACN,SAAS,GACV,EAAE;QACD,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;QAC1E,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QAC3D,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,IAAI,CAAA;KACrC,GACA,aAAa,CAAC,CAAC,CAAC;IAqCnB,eAAe,IAAI,aAAa,CAAC,OAAO,CAAC;IAiBzC,aAAa,IAAI,aAAa,CAAC,iBAAiB,CAAC;IAcjD,iBAAiB,IAAI,aAAa,CAAC,MAAM,CAAC;IAQ1C,WAAW,IAAI,aAAa,CAAC,WAAW,CAAC;IAQzC,cAAc,IAAI,aAAa,CAAC,cAAc,CAAC;IAQ/C,mCAAmC,IAC/B,SAAS,GACT,aAAa,CAAC,gCAAgC,CAAC;IAQnD,iCAAiC,IAC7B,SAAS,GACT,aAAa,CAAC,8BAA8B,GAAG,IAAI,CAAC;IAQlD,OAAO;IAaP,CAAC,MAAM,CAAC,YAAY,CAAC;CAc5B"}
@@ -1,22 +1,7 @@
1
- "use strict";
2
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
- if (kind === "m") throw new TypeError("Private method is not writable");
4
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
- };
8
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
- };
13
- var _BrowserOAuthDatabase_dbPromise, _BrowserOAuthDatabase_cleanupInterval;
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.BrowserOAuthDatabase = void 0;
16
- const jwk_webcrypto_1 = require("@atproto/jwk-webcrypto");
17
- const index_js_1 = require("./indexed-db/index.js");
1
+ import { WebcryptoKey } from '@atproto/jwk-webcrypto';
2
+ import { DB } from './indexed-db/index.js';
18
3
  function encodeKey(key) {
19
- if (!(key instanceof jwk_webcrypto_1.WebcryptoKey) || !key.kid) {
4
+ if (!(key instanceof WebcryptoKey) || !key.kid) {
20
5
  throw new Error('Invalid key object');
21
6
  }
22
7
  return {
@@ -25,7 +10,7 @@ function encodeKey(key) {
25
10
  };
26
11
  }
27
12
  async function decodeKey(encoded) {
28
- return jwk_webcrypto_1.WebcryptoKey.fromKeypair(encoded.keyPair, encoded.keyId);
13
+ return WebcryptoKey.fromKeypair(encoded.keyPair, encoded.keyId);
29
14
  }
30
15
  const STORES = [
31
16
  'state',
@@ -36,24 +21,24 @@ const STORES = [
36
21
  'authorizationServerMetadataCache',
37
22
  'protectedResourceMetadataCache',
38
23
  ];
39
- class BrowserOAuthDatabase {
24
+ export class BrowserOAuthDatabase {
25
+ #dbPromise;
26
+ #cleanupInterval;
40
27
  constructor(options) {
41
- _BrowserOAuthDatabase_dbPromise.set(this, void 0);
42
- _BrowserOAuthDatabase_cleanupInterval.set(this, void 0);
43
- __classPrivateFieldSet(this, _BrowserOAuthDatabase_dbPromise, index_js_1.DB.open(options?.name ?? '@atproto-oauth-client', [
28
+ this.#dbPromise = DB.open(options?.name ?? '@atproto-oauth-client', [
44
29
  (db) => {
45
30
  for (const name of STORES) {
46
31
  const store = db.createObjectStore(name, { autoIncrement: true });
47
32
  store.createIndex('expiresAt', 'expiresAt', { unique: false });
48
33
  }
49
34
  },
50
- ], { durability: options?.durability ?? 'strict' }), "f");
51
- __classPrivateFieldSet(this, _BrowserOAuthDatabase_cleanupInterval, setInterval(() => {
35
+ ], { durability: options?.durability ?? 'strict' });
36
+ this.#cleanupInterval = setInterval(() => {
52
37
  void this.cleanup();
53
- }, options?.cleanupInterval ?? 30e3), "f");
38
+ }, options?.cleanupInterval ?? 30e3);
54
39
  }
55
40
  async run(storeName, mode, fn) {
56
- const db = await __classPrivateFieldGet(this, _BrowserOAuthDatabase_dbPromise, "f");
41
+ const db = await this.#dbPromise;
57
42
  return await db.transaction([storeName], mode, (tx) => fn(tx.objectStore(storeName)));
58
43
  }
59
44
  createStore(name, { encode, decode, expiresAt, }) {
@@ -151,7 +136,7 @@ class BrowserOAuthDatabase {
151
136
  });
152
137
  }
153
138
  async cleanup() {
154
- const db = await __classPrivateFieldGet(this, _BrowserOAuthDatabase_dbPromise, "f");
139
+ const db = await this.#dbPromise;
155
140
  for (const name of STORES) {
156
141
  await db.transaction([name], 'readwrite', (tx) => tx
157
142
  .objectStore(name)
@@ -159,18 +144,17 @@ class BrowserOAuthDatabase {
159
144
  .deleteAll(IDBKeyRange.upperBound(Date.now())));
160
145
  }
161
146
  }
162
- async [(_BrowserOAuthDatabase_dbPromise = new WeakMap(), _BrowserOAuthDatabase_cleanupInterval = new WeakMap(), Symbol.asyncDispose)]() {
163
- clearInterval(__classPrivateFieldGet(this, _BrowserOAuthDatabase_cleanupInterval, "f"));
164
- __classPrivateFieldSet(this, _BrowserOAuthDatabase_cleanupInterval, undefined, "f");
165
- const dbPromise = __classPrivateFieldGet(this, _BrowserOAuthDatabase_dbPromise, "f");
166
- __classPrivateFieldSet(this, _BrowserOAuthDatabase_dbPromise, Promise.reject(new Error('Database has been disposed')), "f");
147
+ async [Symbol.asyncDispose]() {
148
+ clearInterval(this.#cleanupInterval);
149
+ this.#cleanupInterval = undefined;
150
+ const dbPromise = this.#dbPromise;
151
+ this.#dbPromise = Promise.reject(new Error('Database has been disposed'));
167
152
  // Avoid "unhandled promise rejection"
168
- __classPrivateFieldGet(this, _BrowserOAuthDatabase_dbPromise, "f").catch(() => null);
153
+ this.#dbPromise.catch(() => null);
169
154
  // Spec recommends not to throw errors in dispose
170
155
  const db = await dbPromise.catch(() => null);
171
156
  if (db)
172
157
  await (db[Symbol.asyncDispose] || db[Symbol.dispose]).call(db);
173
158
  }
174
159
  }
175
- exports.BrowserOAuthDatabase = BrowserOAuthDatabase;
176
160
  //# sourceMappingURL=browser-oauth-database.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser-oauth-database.js","sourceRoot":"","sources":["../src/browser-oauth-database.ts"],"names":[],"mappings":"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","sourcesContent":["import { DidDocument } from '@atproto/did'\nimport { Key } from '@atproto/jwk'\nimport { WebcryptoKey } from '@atproto/jwk-webcrypto'\nimport { InternalStateData, Session } from '@atproto/oauth-client'\nimport {\n OAuthAuthorizationServerMetadata,\n OAuthProtectedResourceMetadata,\n} from '@atproto/oauth-types'\nimport { ResolvedHandle } from '@atproto-labs/handle-resolver'\nimport { SimpleStore, Value } from '@atproto-labs/simple-store'\nimport { DB, DBObjectStore } from './indexed-db/index.js'\nimport { TupleUnion } from './util.js'\n\ntype Item<V> = {\n value: V\n expiresAt?: string // ISO Date\n}\n\ntype EncodedKey = {\n keyId: string\n keyPair: CryptoKeyPair\n}\n\nfunction encodeKey(key: Key): EncodedKey {\n if (!(key instanceof WebcryptoKey) || !key.kid) {\n throw new Error('Invalid key object')\n }\n return {\n keyId: key.kid,\n keyPair: key.cryptoKeyPair,\n }\n}\n\nasync function decodeKey(encoded: EncodedKey): Promise<Key> {\n return WebcryptoKey.fromKeypair(encoded.keyPair, encoded.keyId)\n}\n\nexport type Schema = {\n state: Item<Omit<InternalStateData, 'dpopKey'> & { dpopKey: EncodedKey }>\n session: Item<Omit<Session, 'dpopKey'> & { dpopKey: EncodedKey }>\n didCache: Item<DidDocument>\n dpopNonceCache: Item<string>\n handleCache: Item<ResolvedHandle>\n authorizationServerMetadataCache: Item<OAuthAuthorizationServerMetadata>\n protectedResourceMetadataCache: Item<OAuthProtectedResourceMetadata>\n}\n\nexport type DatabaseStore<V extends Value> = SimpleStore<string, V>\n\nconst STORES: TupleUnion<keyof Schema> = [\n 'state',\n 'session',\n\n 'didCache',\n 'dpopNonceCache',\n 'handleCache',\n 'authorizationServerMetadataCache',\n 'protectedResourceMetadataCache',\n]\n\nexport type BrowserOAuthDatabaseOptions = {\n name?: string\n durability?: 'strict' | 'relaxed'\n cleanupInterval?: number\n}\n\nexport class BrowserOAuthDatabase {\n #dbPromise: Promise<DB<Schema>>\n #cleanupInterval?: ReturnType<typeof setInterval>\n\n constructor(options?: BrowserOAuthDatabaseOptions) {\n this.#dbPromise = DB.open<Schema>(\n options?.name ?? '@atproto-oauth-client',\n [\n (db) => {\n for (const name of STORES) {\n const store = db.createObjectStore(name, { autoIncrement: true })\n store.createIndex('expiresAt', 'expiresAt', { unique: false })\n }\n },\n ],\n { durability: options?.durability ?? 'strict' },\n )\n\n this.#cleanupInterval = setInterval(() => {\n void this.cleanup()\n }, options?.cleanupInterval ?? 30e3)\n }\n\n protected async run<N extends keyof Schema, R>(\n storeName: N,\n mode: 'readonly' | 'readwrite',\n fn: (s: DBObjectStore<Schema[N]>) => R | Promise<R>,\n ): Promise<R> {\n const db = await this.#dbPromise\n return await db.transaction([storeName], mode, (tx) =>\n fn(tx.objectStore(storeName)),\n )\n }\n\n protected createStore<N extends keyof Schema, V extends Value>(\n name: N,\n {\n encode,\n decode,\n expiresAt,\n }: {\n encode: (value: V) => Schema[N]['value'] | PromiseLike<Schema[N]['value']>\n decode: (encoded: Schema[N]['value']) => V | PromiseLike<V>\n expiresAt: (value: V) => null | Date\n },\n ): DatabaseStore<V> {\n return {\n get: async (key) => {\n // Find item in store\n const item = await this.run(name, 'readonly', (store) => store.get(key))\n\n // Not found\n if (item === undefined) return undefined\n\n // Too old (delete)\n if (item.expiresAt != null && new Date(item.expiresAt) < new Date()) {\n await this.run(name, 'readwrite', (store) => store.delete(key))\n return undefined\n }\n\n // Item found and valid. Decode\n return decode(item.value)\n },\n\n set: async (key, value) => {\n // Create encoded item record\n const item = {\n value: await encode(value),\n expiresAt: expiresAt(value)?.toISOString(),\n } as Schema[N]\n\n // Store item record\n await this.run(name, 'readwrite', (store) => store.put(item, key))\n },\n\n del: async (key) => {\n // Delete\n await this.run(name, 'readwrite', (store) => store.delete(key))\n },\n }\n }\n\n getSessionStore(): DatabaseStore<Session> {\n return this.createStore('session', {\n expiresAt: ({ tokenSet }) =>\n tokenSet.refresh_token || tokenSet.expires_at == null\n ? null\n : new Date(tokenSet.expires_at),\n encode: ({ dpopKey, ...session }) => ({\n ...session,\n dpopKey: encodeKey(dpopKey),\n }),\n decode: async ({ dpopKey, ...encoded }) => ({\n ...encoded,\n dpopKey: await decodeKey(dpopKey),\n }),\n })\n }\n\n getStateStore(): DatabaseStore<InternalStateData> {\n return this.createStore('state', {\n expiresAt: (_value) => new Date(Date.now() + 10 * 60e3),\n encode: ({ dpopKey, ...session }) => ({\n ...session,\n dpopKey: encodeKey(dpopKey),\n }),\n decode: async ({ dpopKey, ...encoded }) => ({\n ...encoded,\n dpopKey: await decodeKey(dpopKey),\n }),\n })\n }\n\n getDpopNonceCache(): DatabaseStore<string> {\n return this.createStore('dpopNonceCache', {\n expiresAt: (_value) => new Date(Date.now() + 600e3),\n encode: (value) => value,\n decode: (encoded) => encoded,\n })\n }\n\n getDidCache(): DatabaseStore<DidDocument> {\n return this.createStore('didCache', {\n expiresAt: (_value) => new Date(Date.now() + 60e3),\n encode: (value) => value,\n decode: (encoded) => encoded,\n })\n }\n\n getHandleCache(): DatabaseStore<ResolvedHandle> {\n return this.createStore('handleCache', {\n expiresAt: (_value) => new Date(Date.now() + 60e3),\n encode: (value) => value,\n decode: (encoded) => encoded,\n })\n }\n\n getAuthorizationServerMetadataCache():\n | undefined\n | DatabaseStore<OAuthAuthorizationServerMetadata> {\n return this.createStore('authorizationServerMetadataCache', {\n expiresAt: (_value) => new Date(Date.now() + 60e3),\n encode: (value) => value,\n decode: (encoded) => encoded,\n })\n }\n\n getProtectedResourceMetadataCache():\n | undefined\n | DatabaseStore<OAuthProtectedResourceMetadata> {\n return this.createStore('protectedResourceMetadataCache', {\n expiresAt: (_value) => new Date(Date.now() + 60e3),\n encode: (value) => value,\n decode: (encoded) => encoded,\n })\n }\n\n async cleanup() {\n const db = await this.#dbPromise\n\n for (const name of STORES) {\n await db.transaction([name], 'readwrite', (tx) =>\n tx\n .objectStore(name)\n .index('expiresAt')\n .deleteAll(IDBKeyRange.upperBound(Date.now())),\n )\n }\n }\n\n async [Symbol.asyncDispose]() {\n clearInterval(this.#cleanupInterval)\n this.#cleanupInterval = undefined\n\n const dbPromise = this.#dbPromise\n this.#dbPromise = Promise.reject(new Error('Database has been disposed'))\n\n // Avoid \"unhandled promise rejection\"\n this.#dbPromise.catch(() => null)\n\n // Spec recommends not to throw errors in dispose\n const db = await dbPromise.catch(() => null)\n if (db) await (db[Symbol.asyncDispose] || db[Symbol.dispose]).call(db)\n }\n}\n"]}
1
+ {"version":3,"file":"browser-oauth-database.js","sourceRoot":"","sources":["../src/browser-oauth-database.ts"],"names":[],"mappings":"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","sourcesContent":["import { DidDocument } from '@atproto/did'\nimport { Key } from '@atproto/jwk'\nimport { WebcryptoKey } from '@atproto/jwk-webcrypto'\nimport { InternalStateData, Session } from '@atproto/oauth-client'\nimport {\n OAuthAuthorizationServerMetadata,\n OAuthProtectedResourceMetadata,\n} from '@atproto/oauth-types'\nimport { ResolvedHandle } from '@atproto-labs/handle-resolver'\nimport { SimpleStore, Value } from '@atproto-labs/simple-store'\nimport { DB, DBObjectStore } from './indexed-db/index.js'\nimport { TupleUnion } from './util.js'\n\ntype Item<V> = {\n value: V\n expiresAt?: string // ISO Date\n}\n\ntype EncodedKey = {\n keyId: string\n keyPair: CryptoKeyPair\n}\n\nfunction encodeKey(key: Key): EncodedKey {\n if (!(key instanceof WebcryptoKey) || !key.kid) {\n throw new Error('Invalid key object')\n }\n return {\n keyId: key.kid,\n keyPair: key.cryptoKeyPair,\n }\n}\n\nasync function decodeKey(encoded: EncodedKey): Promise<Key> {\n return WebcryptoKey.fromKeypair(encoded.keyPair, encoded.keyId)\n}\n\nexport type Schema = {\n state: Item<Omit<InternalStateData, 'dpopKey'> & { dpopKey: EncodedKey }>\n session: Item<Omit<Session, 'dpopKey'> & { dpopKey: EncodedKey }>\n didCache: Item<DidDocument>\n dpopNonceCache: Item<string>\n handleCache: Item<ResolvedHandle>\n authorizationServerMetadataCache: Item<OAuthAuthorizationServerMetadata>\n protectedResourceMetadataCache: Item<OAuthProtectedResourceMetadata | null>\n}\n\nexport type DatabaseStore<V extends Value> = SimpleStore<string, V>\n\nconst STORES: TupleUnion<keyof Schema> = [\n 'state',\n 'session',\n\n 'didCache',\n 'dpopNonceCache',\n 'handleCache',\n 'authorizationServerMetadataCache',\n 'protectedResourceMetadataCache',\n]\n\nexport type BrowserOAuthDatabaseOptions = {\n name?: string\n durability?: 'strict' | 'relaxed'\n cleanupInterval?: number\n}\n\nexport class BrowserOAuthDatabase {\n #dbPromise: Promise<DB<Schema>>\n #cleanupInterval?: ReturnType<typeof setInterval>\n\n constructor(options?: BrowserOAuthDatabaseOptions) {\n this.#dbPromise = DB.open<Schema>(\n options?.name ?? '@atproto-oauth-client',\n [\n (db) => {\n for (const name of STORES) {\n const store = db.createObjectStore(name, { autoIncrement: true })\n store.createIndex('expiresAt', 'expiresAt', { unique: false })\n }\n },\n ],\n { durability: options?.durability ?? 'strict' },\n )\n\n this.#cleanupInterval = setInterval(() => {\n void this.cleanup()\n }, options?.cleanupInterval ?? 30e3)\n }\n\n protected async run<N extends keyof Schema, R>(\n storeName: N,\n mode: 'readonly' | 'readwrite',\n fn: (s: DBObjectStore<Schema[N]>) => R | Promise<R>,\n ): Promise<R> {\n const db = await this.#dbPromise\n return await db.transaction([storeName], mode, (tx) =>\n fn(tx.objectStore(storeName)),\n )\n }\n\n protected createStore<N extends keyof Schema, V extends Value>(\n name: N,\n {\n encode,\n decode,\n expiresAt,\n }: {\n encode: (value: V) => Schema[N]['value'] | PromiseLike<Schema[N]['value']>\n decode: (encoded: Schema[N]['value']) => V | PromiseLike<V>\n expiresAt: (value: V) => null | Date\n },\n ): DatabaseStore<V> {\n return {\n get: async (key) => {\n // Find item in store\n const item = await this.run(name, 'readonly', (store) => store.get(key))\n\n // Not found\n if (item === undefined) return undefined\n\n // Too old (delete)\n if (item.expiresAt != null && new Date(item.expiresAt) < new Date()) {\n await this.run(name, 'readwrite', (store) => store.delete(key))\n return undefined\n }\n\n // Item found and valid. Decode\n return decode(item.value)\n },\n\n set: async (key, value) => {\n // Create encoded item record\n const item = {\n value: await encode(value),\n expiresAt: expiresAt(value)?.toISOString(),\n } as Schema[N]\n\n // Store item record\n await this.run(name, 'readwrite', (store) => store.put(item, key))\n },\n\n del: async (key) => {\n // Delete\n await this.run(name, 'readwrite', (store) => store.delete(key))\n },\n }\n }\n\n getSessionStore(): DatabaseStore<Session> {\n return this.createStore('session', {\n expiresAt: ({ tokenSet }) =>\n tokenSet.refresh_token || tokenSet.expires_at == null\n ? null\n : new Date(tokenSet.expires_at),\n encode: ({ dpopKey, ...session }) => ({\n ...session,\n dpopKey: encodeKey(dpopKey),\n }),\n decode: async ({ dpopKey, ...encoded }) => ({\n ...encoded,\n dpopKey: await decodeKey(dpopKey),\n }),\n })\n }\n\n getStateStore(): DatabaseStore<InternalStateData> {\n return this.createStore('state', {\n expiresAt: (_value) => new Date(Date.now() + 10 * 60e3),\n encode: ({ dpopKey, ...session }) => ({\n ...session,\n dpopKey: encodeKey(dpopKey),\n }),\n decode: async ({ dpopKey, ...encoded }) => ({\n ...encoded,\n dpopKey: await decodeKey(dpopKey),\n }),\n })\n }\n\n getDpopNonceCache(): DatabaseStore<string> {\n return this.createStore('dpopNonceCache', {\n expiresAt: (_value) => new Date(Date.now() + 600e3),\n encode: (value) => value,\n decode: (encoded) => encoded,\n })\n }\n\n getDidCache(): DatabaseStore<DidDocument> {\n return this.createStore('didCache', {\n expiresAt: (_value) => new Date(Date.now() + 60e3),\n encode: (value) => value,\n decode: (encoded) => encoded,\n })\n }\n\n getHandleCache(): DatabaseStore<ResolvedHandle> {\n return this.createStore('handleCache', {\n expiresAt: (_value) => new Date(Date.now() + 60e3),\n encode: (value) => value,\n decode: (encoded) => encoded,\n })\n }\n\n getAuthorizationServerMetadataCache():\n | undefined\n | DatabaseStore<OAuthAuthorizationServerMetadata> {\n return this.createStore('authorizationServerMetadataCache', {\n expiresAt: (_value) => new Date(Date.now() + 60e3),\n encode: (value) => value,\n decode: (encoded) => encoded,\n })\n }\n\n getProtectedResourceMetadataCache():\n | undefined\n | DatabaseStore<OAuthProtectedResourceMetadata | null> {\n return this.createStore('protectedResourceMetadataCache', {\n expiresAt: (_value) => new Date(Date.now() + 60e3),\n encode: (value) => value,\n decode: (encoded) => encoded,\n })\n }\n\n async cleanup() {\n const db = await this.#dbPromise\n\n for (const name of STORES) {\n await db.transaction([name], 'readwrite', (tx) =>\n tx\n .objectStore(name)\n .index('expiresAt')\n .deleteAll(IDBKeyRange.upperBound(Date.now())),\n )\n }\n }\n\n async [Symbol.asyncDispose]() {\n clearInterval(this.#cleanupInterval)\n this.#cleanupInterval = undefined\n\n const dbPromise = this.#dbPromise\n this.#dbPromise = Promise.reject(new Error('Database has been disposed'))\n\n // Avoid \"unhandled promise rejection\"\n this.#dbPromise.catch(() => null)\n\n // Spec recommends not to throw errors in dispose\n const db = await dbPromise.catch(() => null)\n if (db) await (db[Symbol.asyncDispose] || db[Symbol.dispose]).call(db)\n }\n}\n"]}
@@ -4,6 +4,6 @@ export declare class BrowserRuntimeImplementation implements RuntimeImplementati
4
4
  constructor();
5
5
  createKey(algs: string[]): Promise<Key>;
6
6
  getRandomValues(byteLength: number): Uint8Array;
7
- digest(data: Uint8Array, { name }: DigestAlgorithm): Promise<Uint8Array>;
7
+ digest(data: Uint8Array<ArrayBuffer>, { name }: DigestAlgorithm): Promise<Uint8Array<ArrayBuffer>>;
8
8
  }
9
9
  //# sourceMappingURL=browser-runtime-implementation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser-runtime-implementation.d.ts","sourceRoot":"","sources":["../src/browser-runtime-implementation.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,GAAG,EACH,qBAAqB,EACrB,WAAW,EACZ,MAAM,uBAAuB,CAAA;AAW9B,qBAAa,4BAA6B,YAAW,qBAAqB;IACxE,WAAW,0BAAoB;;IAmBzB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAI7C,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU;IAIzC,MAAM,CACV,IAAI,EAAE,UAAU,EAChB,EAAE,IAAI,EAAE,EAAE,eAAe,GACxB,OAAO,CAAC,UAAU,CAAC;CAYvB"}
1
+ {"version":3,"file":"browser-runtime-implementation.d.ts","sourceRoot":"","sources":["../src/browser-runtime-implementation.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,GAAG,EACH,qBAAqB,EACrB,WAAW,EACZ,MAAM,uBAAuB,CAAA;AAW9B,qBAAa,4BAA6B,YAAW,qBAAqB;IACxE,WAAW,0BAAoB;;IAmBzB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAI7C,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU;IAIzC,MAAM,CACV,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,EAC7B,EAAE,IAAI,EAAE,EAAE,eAAe,GACxB,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;CAYpC"}
@@ -1,21 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BrowserRuntimeImplementation = void 0;
4
- const jwk_webcrypto_1 = require("@atproto/jwk-webcrypto");
1
+ import { WebcryptoKey } from '@atproto/jwk-webcrypto';
5
2
  /**
6
3
  * @see {@link // https://developer.mozilla.org/en-US/docs/Web/API/LockManager/request}
7
4
  */
8
5
  const nativeRequestLock = typeof navigator !== 'undefined' && navigator.locks?.request
9
6
  ? (name, fn) => navigator.locks.request(name, { mode: 'exclusive' }, async () => fn())
10
7
  : undefined;
11
- class BrowserRuntimeImplementation {
8
+ export class BrowserRuntimeImplementation {
12
9
  constructor() {
13
- Object.defineProperty(this, "requestLock", {
14
- enumerable: true,
15
- configurable: true,
16
- writable: true,
17
- value: nativeRequestLock
18
- });
10
+ this.requestLock = nativeRequestLock;
19
11
  if (typeof crypto !== 'object' || !crypto?.subtle) {
20
12
  throw new Error('Crypto with CryptoSubtle is required. If running in a browser, make sure the current page is loaded over HTTPS.');
21
13
  }
@@ -27,7 +19,7 @@ class BrowserRuntimeImplementation {
27
19
  }
28
20
  }
29
21
  async createKey(algs) {
30
- return jwk_webcrypto_1.WebcryptoKey.generate(algs);
22
+ return WebcryptoKey.generate(algs);
31
23
  }
32
24
  getRandomValues(byteLength) {
33
25
  return crypto.getRandomValues(new Uint8Array(byteLength));
@@ -45,5 +37,4 @@ class BrowserRuntimeImplementation {
45
37
  }
46
38
  }
47
39
  }
48
- exports.BrowserRuntimeImplementation = BrowserRuntimeImplementation;
49
40
  //# sourceMappingURL=browser-runtime-implementation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser-runtime-implementation.js","sourceRoot":"","sources":["../src/browser-runtime-implementation.ts"],"names":[],"mappings":";;;AAAA,0DAAqD;AAQrD;;GAEG;AACH,MAAM,iBAAiB,GACrB,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO;IAC1D,CAAC,CAAC,CAAI,IAAY,EAAE,EAA4B,EAAc,EAAE,CAC5D,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;IAC1E,CAAC,CAAC,SAAS,CAAA;AAEf,MAAa,4BAA4B;IAGvC;QAFA;;;;mBAAc,iBAAiB;WAAA;QAG7B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CACb,iHAAiH,CAClH,CAAA;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,wEAAwE;YACxE,yEAAyE;YACzE,qBAAqB;YACrB,OAAO,CAAC,IAAI,CACV,2EAA2E,CAC5E,CAAA;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,IAAc;QAC5B,OAAO,4BAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IACpC,CAAC;IAED,eAAe,CAAC,UAAkB;QAChC,OAAO,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;IAC3D,CAAC;IAED,KAAK,CAAC,MAAM,CACV,IAAgB,EAChB,EAAE,IAAI,EAAmB;QAEzB,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,QAAQ,CAAC;YACd,KAAK,QAAQ,CAAC;YACd,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;gBACpE,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAA;YAC5B,CAAC;YACD;gBACE,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC;CACF;AA3CD,oEA2CC","sourcesContent":["import { WebcryptoKey } from '@atproto/jwk-webcrypto'\nimport {\n DigestAlgorithm,\n Key,\n RuntimeImplementation,\n RuntimeLock,\n} from '@atproto/oauth-client'\n\n/**\n * @see {@link // https://developer.mozilla.org/en-US/docs/Web/API/LockManager/request}\n */\nconst nativeRequestLock: undefined | RuntimeLock =\n typeof navigator !== 'undefined' && navigator.locks?.request\n ? <T>(name: string, fn: () => T | PromiseLike<T>): Promise<T> =>\n navigator.locks.request(name, { mode: 'exclusive' }, async () => fn())\n : undefined\n\nexport class BrowserRuntimeImplementation implements RuntimeImplementation {\n requestLock = nativeRequestLock\n\n constructor() {\n if (typeof crypto !== 'object' || !crypto?.subtle) {\n throw new Error(\n 'Crypto with CryptoSubtle is required. If running in a browser, make sure the current page is loaded over HTTPS.',\n )\n }\n\n if (!this.requestLock) {\n // There is no real need to polyfill this on older browsers. Indeed, the\n // oauth-client library will try and recover from concurrency issues when\n // refreshing tokens.\n console.warn(\n 'Locks API not available. You should consider using a more recent browser.',\n )\n }\n }\n\n async createKey(algs: string[]): Promise<Key> {\n return WebcryptoKey.generate(algs)\n }\n\n getRandomValues(byteLength: number): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(byteLength))\n }\n\n async digest(\n data: Uint8Array,\n { name }: DigestAlgorithm,\n ): Promise<Uint8Array> {\n switch (name) {\n case 'sha256':\n case 'sha384':\n case 'sha512': {\n const buf = await crypto.subtle.digest(`SHA-${name.slice(3)}`, data)\n return new Uint8Array(buf)\n }\n default:\n throw new Error(`Unsupported digest algorithm: ${name}`)\n }\n }\n}\n"]}
1
+ {"version":3,"file":"browser-runtime-implementation.js","sourceRoot":"","sources":["../src/browser-runtime-implementation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAQrD;;GAEG;AACH,MAAM,iBAAiB,GACrB,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO;IAC1D,CAAC,CAAC,CAAI,IAAY,EAAE,EAA4B,EAAc,EAAE,CAC5D,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;IAC1E,CAAC,CAAC,SAAS,CAAA;AAEf,MAAM,OAAO,4BAA4B;IAGvC;QAFA,gBAAW,GAAG,iBAAiB,CAAA;QAG7B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CACb,iHAAiH,CAClH,CAAA;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,wEAAwE;YACxE,yEAAyE;YACzE,qBAAqB;YACrB,OAAO,CAAC,IAAI,CACV,2EAA2E,CAC5E,CAAA;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,IAAc;QAC5B,OAAO,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IACpC,CAAC;IAED,eAAe,CAAC,UAAkB;QAChC,OAAO,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;IAC3D,CAAC;IAED,KAAK,CAAC,MAAM,CACV,IAA6B,EAC7B,EAAE,IAAI,EAAmB;QAEzB,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,QAAQ,CAAC;YACd,KAAK,QAAQ,CAAC;YACd,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;gBACpE,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAA;YAC5B,CAAC;YACD;gBACE,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC;CACF","sourcesContent":["import { WebcryptoKey } from '@atproto/jwk-webcrypto'\nimport {\n DigestAlgorithm,\n Key,\n RuntimeImplementation,\n RuntimeLock,\n} from '@atproto/oauth-client'\n\n/**\n * @see {@link // https://developer.mozilla.org/en-US/docs/Web/API/LockManager/request}\n */\nconst nativeRequestLock: undefined | RuntimeLock =\n typeof navigator !== 'undefined' && navigator.locks?.request\n ? <T>(name: string, fn: () => T | PromiseLike<T>): Promise<T> =>\n navigator.locks.request(name, { mode: 'exclusive' }, async () => fn())\n : undefined\n\nexport class BrowserRuntimeImplementation implements RuntimeImplementation {\n requestLock = nativeRequestLock\n\n constructor() {\n if (typeof crypto !== 'object' || !crypto?.subtle) {\n throw new Error(\n 'Crypto with CryptoSubtle is required. If running in a browser, make sure the current page is loaded over HTTPS.',\n )\n }\n\n if (!this.requestLock) {\n // There is no real need to polyfill this on older browsers. Indeed, the\n // oauth-client library will try and recover from concurrency issues when\n // refreshing tokens.\n console.warn(\n 'Locks API not available. You should consider using a more recent browser.',\n )\n }\n }\n\n async createKey(algs: string[]): Promise<Key> {\n return WebcryptoKey.generate(algs)\n }\n\n getRandomValues(byteLength: number): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(byteLength))\n }\n\n async digest(\n data: Uint8Array<ArrayBuffer>,\n { name }: DigestAlgorithm,\n ): Promise<Uint8Array<ArrayBuffer>> {\n switch (name) {\n case 'sha256':\n case 'sha384':\n case 'sha512': {\n const buf = await crypto.subtle.digest(`SHA-${name.slice(3)}`, data)\n return new Uint8Array(buf)\n }\n default:\n throw new Error(`Unsupported digest algorithm: ${name}`)\n }\n }\n}\n"]}