@atcute/oauth-browser-client 1.0.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.
Files changed (69) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +159 -0
  3. package/dist/agents/exchange.d.ts +20 -0
  4. package/dist/agents/exchange.js +87 -0
  5. package/dist/agents/exchange.js.map +1 -0
  6. package/dist/agents/server-agent.d.ts +22 -0
  7. package/dist/agents/server-agent.js +119 -0
  8. package/dist/agents/server-agent.js.map +1 -0
  9. package/dist/agents/sessions.d.ts +11 -0
  10. package/dist/agents/sessions.js +107 -0
  11. package/dist/agents/sessions.js.map +1 -0
  12. package/dist/agents/user-agent.d.ts +13 -0
  13. package/dist/agents/user-agent.js +77 -0
  14. package/dist/agents/user-agent.js.map +1 -0
  15. package/dist/constants.d.ts +1 -0
  16. package/dist/constants.js +2 -0
  17. package/dist/constants.js.map +1 -0
  18. package/dist/dpop.d.ts +4 -0
  19. package/dist/dpop.js +118 -0
  20. package/dist/dpop.js.map +1 -0
  21. package/dist/environment.d.ts +19 -0
  22. package/dist/environment.js +9 -0
  23. package/dist/environment.js.map +1 -0
  24. package/dist/errors.d.ts +31 -0
  25. package/dist/errors.js +59 -0
  26. package/dist/errors.js.map +1 -0
  27. package/dist/index.d.ts +14 -0
  28. package/dist/index.js +15 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/resolvers.d.ts +52 -0
  31. package/dist/resolvers.js +186 -0
  32. package/dist/resolvers.js.map +1 -0
  33. package/dist/store/db.d.ts +18 -0
  34. package/dist/store/db.js +106 -0
  35. package/dist/store/db.js.map +1 -0
  36. package/dist/types/client.d.ts +37 -0
  37. package/dist/types/client.js +2 -0
  38. package/dist/types/client.js.map +1 -0
  39. package/dist/types/dpop.d.ts +7 -0
  40. package/dist/types/dpop.js +2 -0
  41. package/dist/types/dpop.js.map +1 -0
  42. package/dist/types/identity.d.ts +6 -0
  43. package/dist/types/identity.js +2 -0
  44. package/dist/types/identity.js.map +1 -0
  45. package/dist/types/par.d.ts +4 -0
  46. package/dist/types/par.js +2 -0
  47. package/dist/types/par.js.map +1 -0
  48. package/dist/types/server.d.ts +57 -0
  49. package/dist/types/server.js +2 -0
  50. package/dist/types/server.js.map +1 -0
  51. package/dist/types/store.d.ts +6 -0
  52. package/dist/types/store.js +2 -0
  53. package/dist/types/store.js.map +1 -0
  54. package/dist/types/token.d.ts +38 -0
  55. package/dist/types/token.js +2 -0
  56. package/dist/types/token.js.map +1 -0
  57. package/dist/utils/misc.d.ts +3 -0
  58. package/dist/utils/misc.js +10 -0
  59. package/dist/utils/misc.js.map +1 -0
  60. package/dist/utils/response.d.ts +1 -0
  61. package/dist/utils/response.js +4 -0
  62. package/dist/utils/response.js.map +1 -0
  63. package/dist/utils/runtime.d.ts +12 -0
  64. package/dist/utils/runtime.js +44 -0
  65. package/dist/utils/runtime.js.map +1 -0
  66. package/dist/utils/strings.d.ts +2 -0
  67. package/dist/utils/strings.js +4 -0
  68. package/dist/utils/strings.js.map +1 -0
  69. package/package.json +29 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-agent.js","sourceRoot":"","sources":["../../lib/agents/user-agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare const DEFAULT_APPVIEW_URL = "https://public.api.bsky.app";
@@ -0,0 +1,2 @@
1
+ export const DEFAULT_APPVIEW_URL = 'https://public.api.bsky.app';
2
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../lib/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,6BAA6B,CAAC"}
package/dist/dpop.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { DPoPKey } from './types/dpop.js';
2
+ export declare const createES256Key: () => Promise<DPoPKey>;
3
+ export declare const createDPoPSignage: (issuer: string, dpopKey: DPoPKey) => (method: string, url: string, nonce: string | undefined, ath: string | undefined) => Promise<string>;
4
+ export declare const createDPoPFetch: (issuer: string, dpopKey: DPoPKey, isAuthServer?: boolean) => typeof fetch;
package/dist/dpop.js ADDED
@@ -0,0 +1,118 @@
1
+ import { nanoid } from 'nanoid/non-secure';
2
+ import { database } from './environment.js';
3
+ import { extractContentType } from './utils/response.js';
4
+ import { encoder, fromBase64Url, toBase64Url, toSha256 } from './utils/runtime.js';
5
+ const ES256_ALG = { name: 'ECDSA', namedCurve: 'P-256' };
6
+ export const createES256Key = async () => {
7
+ const pair = await crypto.subtle.generateKey(ES256_ALG, true, ['sign', 'verify']);
8
+ const key = await crypto.subtle.exportKey('pkcs8', pair.privateKey);
9
+ const { ext: _ext, key_ops: _key_opts, ...jwk } = await crypto.subtle.exportKey('jwk', pair.publicKey);
10
+ return {
11
+ typ: 'ES256',
12
+ key: toBase64Url(new Uint8Array(key)),
13
+ jwt: toBase64Url(encoder.encode(JSON.stringify({ typ: 'dpop+jwt', alg: 'ES256', jwk: jwk }))),
14
+ };
15
+ };
16
+ export const createDPoPSignage = (issuer, dpopKey) => {
17
+ const headerString = dpopKey.jwt;
18
+ const keyPromise = crypto.subtle.importKey('pkcs8', fromBase64Url(dpopKey.key), ES256_ALG, true, ['sign']);
19
+ const constructPayload = (method, url, nonce, ath) => {
20
+ const now = (Date.now() / 1_000) | 0;
21
+ const payload = {
22
+ iss: issuer,
23
+ iat: now,
24
+ // This seems fine, we can remake the request if it fails.
25
+ jti: nanoid(12),
26
+ htm: method,
27
+ htu: url,
28
+ nonce: nonce,
29
+ ath: ath,
30
+ };
31
+ return toBase64Url(encoder.encode(JSON.stringify(payload)));
32
+ };
33
+ return async (method, url, nonce, ath) => {
34
+ const payloadString = constructPayload(method, url, nonce, ath);
35
+ const signed = await crypto.subtle.sign({ name: 'ECDSA', hash: { name: 'SHA-256' } }, await keyPromise, encoder.encode(headerString + '.' + payloadString));
36
+ const signatureString = toBase64Url(new Uint8Array(signed));
37
+ return headerString + '.' + payloadString + '.' + signatureString;
38
+ };
39
+ };
40
+ export const createDPoPFetch = (issuer, dpopKey, isAuthServer) => {
41
+ const nonces = database.dpopNonces;
42
+ const sign = createDPoPSignage(issuer, dpopKey);
43
+ return async (input, init) => {
44
+ const request = init == null && input instanceof Request ? input : new Request(input, init);
45
+ const authorizationHeader = request.headers.get('authorization');
46
+ const ath = authorizationHeader?.startsWith('DPoP ')
47
+ ? await toSha256(authorizationHeader.slice(5))
48
+ : undefined;
49
+ const { method, url } = request;
50
+ const { origin } = new URL(url);
51
+ let initNonce;
52
+ try {
53
+ initNonce = nonces.get(origin);
54
+ }
55
+ catch {
56
+ // Ignore get errors, we will just not send a nonce
57
+ }
58
+ const initProof = await sign(method, url, initNonce, ath);
59
+ request.headers.set('dpop', initProof);
60
+ const initResponse = await fetch(request);
61
+ const nextNonce = initResponse.headers.get('dpop-nonce');
62
+ if (!nextNonce || nextNonce === initNonce) {
63
+ // No nonce was returned or it is the same as the one we sent. No need to
64
+ // update the nonce store, or retry the request.
65
+ return initResponse;
66
+ }
67
+ // Store the fresh nonce for future requests
68
+ try {
69
+ nonces.set(origin, nextNonce);
70
+ }
71
+ catch {
72
+ // Ignore set errors
73
+ }
74
+ const shouldRetry = await isUseDpopNonceError(initResponse, isAuthServer);
75
+ if (!shouldRetry) {
76
+ // Not a "use_dpop_nonce" error, so there is no need to retry
77
+ return initResponse;
78
+ }
79
+ // If the input stream was already consumed, we cannot retry the request. A
80
+ // solution would be to clone() the request but that would bufferize the
81
+ // entire stream in memory which can lead to memory starvation. Instead, we
82
+ // will return the original response and let the calling code handle retries.
83
+ if (input === request || init?.body instanceof ReadableStream) {
84
+ return initResponse;
85
+ }
86
+ const nextProof = await sign(method, url, nextNonce, ath);
87
+ const nextRequest = new Request(input, init);
88
+ nextRequest.headers.set('dpop', nextProof);
89
+ return await fetch(nextRequest);
90
+ };
91
+ };
92
+ const isUseDpopNonceError = async (response, isAuthServer) => {
93
+ // https://datatracker.ietf.org/doc/html/rfc6750#section-3
94
+ // https://datatracker.ietf.org/doc/html/rfc9449#name-resource-server-provided-no
95
+ if (isAuthServer === undefined || isAuthServer === false) {
96
+ if (response.status === 401) {
97
+ const wwwAuth = response.headers.get('www-authenticate');
98
+ if (wwwAuth?.startsWith('DPoP')) {
99
+ return wwwAuth.includes('error="use_dpop_nonce"');
100
+ }
101
+ }
102
+ }
103
+ // https://datatracker.ietf.org/doc/html/rfc9449#name-authorization-server-provid
104
+ if (isAuthServer === undefined || isAuthServer === true) {
105
+ if (response.status === 400 && extractContentType(response.headers) === 'application/json') {
106
+ try {
107
+ const json = await response.clone().json();
108
+ return typeof json === 'object' && json?.['error'] === 'use_dpop_nonce';
109
+ }
110
+ catch {
111
+ // Response too big (to be "use_dpop_nonce" error) or invalid JSON
112
+ return false;
113
+ }
114
+ }
115
+ }
116
+ return false;
117
+ };
118
+ //# sourceMappingURL=dpop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dpop.js","sourceRoot":"","sources":["../lib/dpop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type OAuthDatabase } from './store/db.js';
2
+ export declare let CLIENT_ID: string;
3
+ export declare let REDIRECT_URI: string;
4
+ export declare let database: OAuthDatabase;
5
+ export interface ConfigureOAuthOptions {
6
+ /**
7
+ * Client metadata, necessary to drive the whole request
8
+ */
9
+ metadata: {
10
+ client_id: string;
11
+ redirect_uri: string;
12
+ };
13
+ /**
14
+ * Name that will be used as prefix for storage keys needed to persist authentication.
15
+ * @default "atcute-oauth"
16
+ */
17
+ storageName?: string;
18
+ }
19
+ export declare const configureOAuth: (options: ConfigureOAuthOptions) => void;
@@ -0,0 +1,9 @@
1
+ import { createOAuthDatabase } from './store/db.js';
2
+ export let CLIENT_ID;
3
+ export let REDIRECT_URI;
4
+ export let database;
5
+ export const configureOAuth = (options) => {
6
+ ({ client_id: CLIENT_ID, redirect_uri: REDIRECT_URI } = options.metadata);
7
+ database = createOAuthDatabase({ name: options.storageName ?? 'atcute-oauth' });
8
+ };
9
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../lib/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAsB,MAAM,eAAe,CAAC;AAExE,MAAM,CAAC,IAAI,SAAiB,CAAC;AAC7B,MAAM,CAAC,IAAI,YAAoB,CAAC;AAEhC,MAAM,CAAC,IAAI,QAAuB,CAAC;AAkBnC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAA8B,EAAE,EAAE;IAChE,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1E,QAAQ,GAAG,mBAAmB,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,IAAI,cAAc,EAAE,CAAC,CAAC;AACjF,CAAC,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { At } from '@atcute/client/lexicons';
2
+ export declare class LoginError extends Error {
3
+ name: string;
4
+ }
5
+ export declare class AuthorizationError extends Error {
6
+ name: string;
7
+ }
8
+ export declare class ResolverError extends Error {
9
+ name: string;
10
+ }
11
+ export declare class TokenRefreshError extends Error {
12
+ readonly sub: At.DID;
13
+ name: string;
14
+ constructor(sub: At.DID, message: string, options?: ErrorOptions);
15
+ }
16
+ export declare class OAuthResponseError extends Error {
17
+ readonly response: Response;
18
+ readonly data: any;
19
+ name: string;
20
+ readonly error: string | undefined;
21
+ readonly description: string | undefined;
22
+ constructor(response: Response, data: any);
23
+ get status(): number;
24
+ get headers(): Headers;
25
+ }
26
+ export declare class FetchResponseError extends Error {
27
+ readonly response: Response;
28
+ status: number;
29
+ name: string;
30
+ constructor(response: Response, status: number, message: string);
31
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,59 @@
1
+ export class LoginError extends Error {
2
+ name = 'LoginError';
3
+ }
4
+ export class AuthorizationError extends Error {
5
+ name = 'AuthorizationError';
6
+ }
7
+ export class ResolverError extends Error {
8
+ name = 'ResolverError';
9
+ }
10
+ export class TokenRefreshError extends Error {
11
+ sub;
12
+ name = 'TokenRefreshError';
13
+ constructor(sub, message, options) {
14
+ super(message, options);
15
+ this.sub = sub;
16
+ }
17
+ }
18
+ export class OAuthResponseError extends Error {
19
+ response;
20
+ data;
21
+ name = 'OAuthResponseError';
22
+ error;
23
+ description;
24
+ constructor(response, data) {
25
+ const error = ifString(ifObject(data)?.['error']);
26
+ const errorDescription = ifString(ifObject(data)?.['error_description']);
27
+ const messageError = error ? `"${error}"` : 'unknown';
28
+ const messageDesc = errorDescription ? `: ${errorDescription}` : '';
29
+ const message = `OAuth ${messageError} error${messageDesc}`;
30
+ super(message);
31
+ this.response = response;
32
+ this.data = data;
33
+ this.error = error;
34
+ this.description = errorDescription;
35
+ }
36
+ get status() {
37
+ return this.response.status;
38
+ }
39
+ get headers() {
40
+ return this.response.headers;
41
+ }
42
+ }
43
+ export class FetchResponseError extends Error {
44
+ response;
45
+ status;
46
+ name = 'FetchResponseError';
47
+ constructor(response, status, message) {
48
+ super(message);
49
+ this.response = response;
50
+ this.status = status;
51
+ }
52
+ }
53
+ const ifString = (v) => {
54
+ return typeof v === 'string' ? v : undefined;
55
+ };
56
+ const ifObject = (v) => {
57
+ return typeof v === 'object' && v !== null && !Array.isArray(v) ? v : undefined;
58
+ };
59
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../lib/errors.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC3B,IAAI,GAAG,YAAY,CAAC;CAC7B;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IACnC,IAAI,GAAG,oBAAoB,CAAC;CACrC;AAED,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC9B,IAAI,GAAG,eAAe,CAAC;CAChC;AAED,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAI1B;IAHR,IAAI,GAAG,mBAAmB,CAAC;IAEpC,YACiB,GAAW,EAC3B,OAAe,EACf,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAJR,QAAG,GAAH,GAAG,CAAQ;IAK5B,CAAC;CACD;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAO3B;IACA;IAPR,IAAI,GAAG,oBAAoB,CAAC;IAE5B,KAAK,CAAqB;IAC1B,WAAW,CAAqB;IAEzC,YACiB,QAAkB,EAClB,IAAS;QAEzB,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAClD,MAAM,gBAAgB,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAEzE,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;QACtD,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,MAAM,OAAO,GAAG,SAAS,YAAY,SAAS,WAAW,EAAE,CAAC;QAE5D,KAAK,CAAC,OAAO,CAAC,CAAC;QAVC,aAAQ,GAAR,QAAQ,CAAU;QAClB,SAAI,GAAJ,IAAI,CAAK;QAWzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,gBAAgB,CAAC;IACrC,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;IAC9B,CAAC;CACD;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAI3B;IACT;IAJC,IAAI,GAAG,oBAAoB,CAAC;IAErC,YACiB,QAAkB,EAC3B,MAAc,EACrB,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,aAAQ,GAAR,QAAQ,CAAU;QAC3B,WAAM,GAAN,MAAM,CAAQ;IAItB,CAAC;CACD;AAED,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAsB,EAAE;IACnD,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9C,CAAC,CAAC;AACF,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAuC,EAAE;IACpE,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1F,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ export { configureOAuth, type ConfigureOAuthOptions } from './environment.js';
2
+ export * from './errors.js';
3
+ export * from './resolvers.js';
4
+ export * from './agents/exchange.js';
5
+ export * from './agents/server-agent.js';
6
+ export * from './agents/sessions.js';
7
+ export * from './agents/user-agent.js';
8
+ export * from './types/client.js';
9
+ export * from './types/dpop.js';
10
+ export * from './types/identity.js';
11
+ export * from './types/par.js';
12
+ export * from './types/server.js';
13
+ export * from './types/store.js';
14
+ export * from './types/token.js';
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ export { configureOAuth } from './environment.js';
2
+ export * from './errors.js';
3
+ export * from './resolvers.js';
4
+ export * from './agents/exchange.js';
5
+ export * from './agents/server-agent.js';
6
+ export * from './agents/sessions.js';
7
+ export * from './agents/user-agent.js';
8
+ export * from './types/client.js';
9
+ export * from './types/dpop.js';
10
+ export * from './types/identity.js';
11
+ export * from './types/par.js';
12
+ export * from './types/server.js';
13
+ export * from './types/store.js';
14
+ export * from './types/token.js';
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA8B,MAAM,kBAAkB,CAAC;AAE9E,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAE/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,52 @@
1
+ import type { At } from '@atcute/client/lexicons';
2
+ import { type DidDocument } from '@atcute/client/utils/did';
3
+ import type { IdentityMetadata } from './types/identity.js';
4
+ import type { AuthorizationServerMetadata, ProtectedResourceMetadata } from './types/server.js';
5
+ /**
6
+ * Resolves domain handles into DID identifiers, by requesting Bluesky's AppView
7
+ * for identity resolution.
8
+ * @param handle Domain handle to resolve
9
+ * @returns DID identifier resolved from the domain handle
10
+ */
11
+ export declare const resolveHandle: (handle: string) => Promise<At.DID>;
12
+ /**
13
+ * Get DID documents of did:plc (via plc.directory) and did:web identifiers
14
+ * @param did DID identifier we're seeking DID doc from
15
+ * @returns Retrieved DID document
16
+ */
17
+ export declare const getDidDocument: (did: At.DID) => Promise<DidDocument>;
18
+ /**
19
+ * Get OAuth protected resource metadata from a host
20
+ * @param host URL of the host
21
+ * @returns Retrieved protected resource metadata
22
+ */
23
+ export declare const getProtectedResourceMetadata: (host: string) => Promise<ProtectedResourceMetadata>;
24
+ /**
25
+ * Get OAuth authorization server metadata from a host
26
+ * @param host URL of the host
27
+ * @returns Retrieved authorization server metadata
28
+ */
29
+ export declare const getAuthorizationServerMetadata: (host: string) => Promise<AuthorizationServerMetadata>;
30
+ /**
31
+ * Resolve handle domains or DID identifiers to get their PDS and its authorization server metadata
32
+ * @param ident Handle domain or DID identifier to resolve
33
+ * @returns Resolved PDS and authorization server metadata
34
+ */
35
+ export declare const resolveFromIdentity: (ident: string) => Promise<{
36
+ identity: IdentityMetadata;
37
+ metadata: AuthorizationServerMetadata;
38
+ }>;
39
+ /**
40
+ * Request authorization server metadata from a PDS
41
+ * @param host URL of the host
42
+ * @returns Resolved authorization server metadata
43
+ */
44
+ export declare const resolveFromService: (host: string) => Promise<{
45
+ metadata: AuthorizationServerMetadata;
46
+ }>;
47
+ /**
48
+ * Request authorization server metadata from its protected resource metadata
49
+ * @param input URL of the host whose authorization server is delegated
50
+ * @returns Resolved authorization server metadata
51
+ */
52
+ export declare const getMetadataFromResourceServer: (input: string) => Promise<AuthorizationServerMetadata>;
@@ -0,0 +1,186 @@
1
+ import { getPdsEndpoint } from '@atcute/client/utils/did';
2
+ import { DEFAULT_APPVIEW_URL } from './constants.js';
3
+ import { ResolverError } from './errors.js';
4
+ import { extractContentType } from './utils/response.js';
5
+ import { isDid } from './utils/strings.js';
6
+ const DID_WEB_RE = /^([a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*(?:\.[a-zA-Z]{2,}))$/;
7
+ /**
8
+ * Resolves domain handles into DID identifiers, by requesting Bluesky's AppView
9
+ * for identity resolution.
10
+ * @param handle Domain handle to resolve
11
+ * @returns DID identifier resolved from the domain handle
12
+ */
13
+ export const resolveHandle = async (handle) => {
14
+ const url = DEFAULT_APPVIEW_URL + `/xrpc/com.atproto.identity.resolveHandle` + `?handle=${handle}`;
15
+ const response = await fetch(url);
16
+ if (response.status === 400) {
17
+ throw new ResolverError(`domain handle not found`);
18
+ }
19
+ else if (!response.ok) {
20
+ throw new ResolverError(`directory is unreachable`);
21
+ }
22
+ const json = (await response.json());
23
+ return json.did;
24
+ };
25
+ /**
26
+ * Get DID documents of did:plc (via plc.directory) and did:web identifiers
27
+ * @param did DID identifier we're seeking DID doc from
28
+ * @returns Retrieved DID document
29
+ */
30
+ export const getDidDocument = async (did) => {
31
+ const colon_index = did.indexOf(':', 4);
32
+ const type = did.slice(4, colon_index);
33
+ const ident = did.slice(colon_index + 1);
34
+ // 2. retrieve their DID documents
35
+ let doc;
36
+ if (type === 'plc') {
37
+ const response = await fetch(`https://plc.directory/${did}`);
38
+ if (response.status === 404) {
39
+ throw new ResolverError(`did not found in directory`);
40
+ }
41
+ else if (!response.ok) {
42
+ throw new ResolverError(`directory is unreachable`);
43
+ }
44
+ const json = await response.json();
45
+ doc = json;
46
+ }
47
+ else if (type === 'web') {
48
+ if (!DID_WEB_RE.test(ident)) {
49
+ throw new ResolverError(`invalid identifier`);
50
+ }
51
+ const response = await fetch(`https://${ident}/.well-known/did.json`);
52
+ if (!response.ok) {
53
+ throw new ResolverError(`did document is unreachable`);
54
+ }
55
+ const json = await response.json();
56
+ doc = json;
57
+ }
58
+ else {
59
+ throw new ResolverError(`unsupported did method`);
60
+ }
61
+ return doc;
62
+ };
63
+ /**
64
+ * Get OAuth protected resource metadata from a host
65
+ * @param host URL of the host
66
+ * @returns Retrieved protected resource metadata
67
+ */
68
+ export const getProtectedResourceMetadata = async (host) => {
69
+ const url = new URL(`/.well-known/oauth-protected-resource`, host);
70
+ const response = await fetch(url, {
71
+ redirect: 'manual',
72
+ headers: {
73
+ accept: 'application/json',
74
+ },
75
+ });
76
+ if (response.status !== 200 || extractContentType(response.headers) !== 'application/json') {
77
+ throw new ResolverError(`unexpected response`);
78
+ }
79
+ const metadata = (await response.json());
80
+ if (metadata.resource !== url.origin) {
81
+ throw new ResolverError(`unexpected issuer`);
82
+ }
83
+ return metadata;
84
+ };
85
+ /**
86
+ * Get OAuth authorization server metadata from a host
87
+ * @param host URL of the host
88
+ * @returns Retrieved authorization server metadata
89
+ */
90
+ export const getAuthorizationServerMetadata = async (host) => {
91
+ const url = new URL(`/.well-known/oauth-authorization-server`, host);
92
+ const response = await fetch(url, {
93
+ redirect: 'manual',
94
+ headers: {
95
+ accept: 'application/json',
96
+ },
97
+ });
98
+ if (response.status !== 200 || extractContentType(response.headers) !== 'application/json') {
99
+ throw new ResolverError(`unexpected response`);
100
+ }
101
+ const metadata = (await response.json());
102
+ if (metadata.issuer !== url.origin) {
103
+ throw new ResolverError(`unexpected issuer`);
104
+ }
105
+ if (!metadata.client_id_metadata_document_supported) {
106
+ throw new ResolverError(`authorization server does not support 'client_id_metadata_document'`);
107
+ }
108
+ if (!metadata.pushed_authorization_request_endpoint) {
109
+ throw new ResolverError(`authorization server does not support 'pushed_authorization request'`);
110
+ }
111
+ if (metadata.response_types_supported) {
112
+ if (!metadata.response_types_supported.includes('code')) {
113
+ throw new ResolverError(`authorization server does not support 'code' response type`);
114
+ }
115
+ }
116
+ return metadata;
117
+ };
118
+ /**
119
+ * Resolve handle domains or DID identifiers to get their PDS and its authorization server metadata
120
+ * @param ident Handle domain or DID identifier to resolve
121
+ * @returns Resolved PDS and authorization server metadata
122
+ */
123
+ export const resolveFromIdentity = async (ident) => {
124
+ let did;
125
+ if (isDid(ident)) {
126
+ did = ident;
127
+ }
128
+ else {
129
+ const resolved = await resolveHandle(ident);
130
+ did = resolved;
131
+ }
132
+ const doc = await getDidDocument(did);
133
+ const pds = getPdsEndpoint(doc);
134
+ if (!pds) {
135
+ throw new ResolverError(`missing pds endpoint`);
136
+ }
137
+ return {
138
+ identity: {
139
+ id: did,
140
+ raw: ident,
141
+ pds: new URL(pds),
142
+ },
143
+ metadata: await getMetadataFromResourceServer(pds),
144
+ };
145
+ };
146
+ /**
147
+ * Request authorization server metadata from a PDS
148
+ * @param host URL of the host
149
+ * @returns Resolved authorization server metadata
150
+ */
151
+ export const resolveFromService = async (host) => {
152
+ try {
153
+ const metadata = await getMetadataFromResourceServer(host);
154
+ return { metadata };
155
+ }
156
+ catch (err) {
157
+ if (err instanceof ResolverError) {
158
+ try {
159
+ const metadata = await getAuthorizationServerMetadata(host);
160
+ return { metadata };
161
+ }
162
+ catch { }
163
+ }
164
+ throw err;
165
+ }
166
+ };
167
+ /**
168
+ * Request authorization server metadata from its protected resource metadata
169
+ * @param input URL of the host whose authorization server is delegated
170
+ * @returns Resolved authorization server metadata
171
+ */
172
+ export const getMetadataFromResourceServer = async (input) => {
173
+ const rs_metadata = await getProtectedResourceMetadata(input);
174
+ if (rs_metadata.authorization_servers?.length !== 1) {
175
+ throw new ResolverError(`expected exactly one authorization server in the listing`);
176
+ }
177
+ const issuer = rs_metadata.authorization_servers[0];
178
+ const as_metadata = await getAuthorizationServerMetadata(issuer);
179
+ if (as_metadata.protected_resources) {
180
+ if (!as_metadata.protected_resources.includes(rs_metadata.resource)) {
181
+ throw new ResolverError(`server is not in authorization server's jurisdiction`);
182
+ }
183
+ }
184
+ return as_metadata;
185
+ };
186
+ //# sourceMappingURL=resolvers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolvers.js","sourceRoot":"","sources":["../lib/resolvers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { DPoPKey } from '../types/dpop.js';
2
+ import type { AuthorizationServerMetadata } from '../types/server.js';
3
+ import type { SimpleStore } from '../types/store.js';
4
+ import type { Session } from '../types/token.js';
5
+ export interface OAuthDatabaseOptions {
6
+ name: string;
7
+ }
8
+ export type OAuthDatabase = ReturnType<typeof createOAuthDatabase>;
9
+ export declare const createOAuthDatabase: ({ name }: OAuthDatabaseOptions) => {
10
+ dispose: () => void;
11
+ sessions: SimpleStore<`did:${string}`, Session>;
12
+ states: SimpleStore<string, {
13
+ dpopKey: DPoPKey;
14
+ metadata: AuthorizationServerMetadata;
15
+ verifier?: string;
16
+ }>;
17
+ dpopNonces: SimpleStore<string, string>;
18
+ };