@atproto/oauth-client 0.1.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.
- package/CHANGELOG.md +20 -0
- package/LICENSE.txt +7 -0
- package/README.md +124 -0
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -0
- package/dist/fetch-dpop.d.ts +21 -0
- package/dist/fetch-dpop.d.ts.map +1 -0
- package/dist/fetch-dpop.js +149 -0
- package/dist/fetch-dpop.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/lock.d.ts +2 -0
- package/dist/lock.d.ts.map +1 -0
- package/dist/lock.js +33 -0
- package/dist/lock.js.map +1 -0
- package/dist/oauth-agent.d.ts +29 -0
- package/dist/oauth-agent.d.ts.map +1 -0
- package/dist/oauth-agent.js +138 -0
- package/dist/oauth-agent.js.map +1 -0
- package/dist/oauth-authorization-server-metadata-resolver.d.ts +15 -0
- package/dist/oauth-authorization-server-metadata-resolver.d.ts.map +1 -0
- package/dist/oauth-authorization-server-metadata-resolver.js +56 -0
- package/dist/oauth-authorization-server-metadata-resolver.js.map +1 -0
- package/dist/oauth-callback-error.d.ts +7 -0
- package/dist/oauth-callback-error.d.ts.map +1 -0
- package/dist/oauth-callback-error.js +28 -0
- package/dist/oauth-callback-error.js.map +1 -0
- package/dist/oauth-client.d.ts +78 -0
- package/dist/oauth-client.d.ts.map +1 -0
- package/dist/oauth-client.js +278 -0
- package/dist/oauth-client.js.map +1 -0
- package/dist/oauth-protected-resource-metadata-resolver.d.ts +15 -0
- package/dist/oauth-protected-resource-metadata-resolver.d.ts.map +1 -0
- package/dist/oauth-protected-resource-metadata-resolver.js +58 -0
- package/dist/oauth-protected-resource-metadata-resolver.js.map +1 -0
- package/dist/oauth-resolver-error.d.ts +7 -0
- package/dist/oauth-resolver-error.d.ts.map +1 -0
- package/dist/oauth-resolver-error.js +17 -0
- package/dist/oauth-resolver-error.js.map +1 -0
- package/dist/oauth-resolver.d.ts +62 -0
- package/dist/oauth-resolver.d.ts.map +1 -0
- package/dist/oauth-resolver.js +73 -0
- package/dist/oauth-resolver.js.map +1 -0
- package/dist/oauth-response-error.d.ts +11 -0
- package/dist/oauth-response-error.d.ts.map +1 -0
- package/dist/oauth-response-error.js +48 -0
- package/dist/oauth-response-error.js.map +1 -0
- package/dist/oauth-server-agent.d.ts +51 -0
- package/dist/oauth-server-agent.d.ts.map +1 -0
- package/dist/oauth-server-agent.js +228 -0
- package/dist/oauth-server-agent.js.map +1 -0
- package/dist/oauth-server-factory.d.ts +20 -0
- package/dist/oauth-server-factory.d.ts.map +1 -0
- package/dist/oauth-server-factory.js +53 -0
- package/dist/oauth-server-factory.js.map +1 -0
- package/dist/refresh-error.d.ts +7 -0
- package/dist/refresh-error.d.ts.map +1 -0
- package/dist/refresh-error.js +16 -0
- package/dist/refresh-error.js.map +1 -0
- package/dist/runtime-implementation.d.ts +12 -0
- package/dist/runtime-implementation.d.ts.map +1 -0
- package/dist/runtime-implementation.js +3 -0
- package/dist/runtime-implementation.js.map +1 -0
- package/dist/runtime.d.ts +35 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +185 -0
- package/dist/runtime.js.map +1 -0
- package/dist/session-getter.d.ts +30 -0
- package/dist/session-getter.d.ts.map +1 -0
- package/dist/session-getter.js +149 -0
- package/dist/session-getter.js.map +1 -0
- package/dist/types.d.ts +1580 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/util.d.ts +9 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +35 -0
- package/dist/util.js.map +1 -0
- package/dist/validate-client-metadata.d.ts +5 -0
- package/dist/validate-client-metadata.d.ts.map +1 -0
- package/dist/validate-client-metadata.js +46 -0
- package/dist/validate-client-metadata.js.map +1 -0
- package/package.json +46 -0
- package/src/constants.ts +4 -0
- package/src/fetch-dpop.ts +235 -0
- package/src/index.ts +18 -0
- package/src/lock.ts +34 -0
- package/src/oauth-agent.ts +150 -0
- package/src/oauth-authorization-server-metadata-resolver.ts +98 -0
- package/src/oauth-callback-error.ts +16 -0
- package/src/oauth-client.ts +440 -0
- package/src/oauth-protected-resource-metadata-resolver.ts +102 -0
- package/src/oauth-resolver-error.ts +12 -0
- package/src/oauth-resolver.ts +111 -0
- package/src/oauth-response-error.ts +31 -0
- package/src/oauth-server-agent.ts +275 -0
- package/src/oauth-server-factory.ts +41 -0
- package/src/refresh-error.ts +9 -0
- package/src/runtime-implementation.ts +17 -0
- package/src/runtime.ts +211 -0
- package/src/session-getter.ts +182 -0
- package/src/types.ts +26 -0
- package/src/util.ts +51 -0
- package/src/validate-client-metadata.ts +61 -0
- package/tsconfig.build.json +8 -0
- package/tsconfig.json +4 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Fetch } from '@atproto-labs/fetch';
|
|
2
|
+
import { CachedGetter, GetCachedOptions, SimpleStore } from '@atproto-labs/simple-store';
|
|
3
|
+
import { OAuthAuthorizationServerMetadata } from '@atproto/oauth-types';
|
|
4
|
+
export type { GetCachedOptions, OAuthAuthorizationServerMetadata };
|
|
5
|
+
export type AuthorizationServerMetadataCache = SimpleStore<string, OAuthAuthorizationServerMetadata>;
|
|
6
|
+
/**
|
|
7
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc8414}
|
|
8
|
+
*/
|
|
9
|
+
export declare class OAuthAuthorizationServerMetadataResolver extends CachedGetter<string, OAuthAuthorizationServerMetadata> {
|
|
10
|
+
private readonly fetch;
|
|
11
|
+
constructor(cache: AuthorizationServerMetadataCache, fetch?: Fetch);
|
|
12
|
+
get(issuer: string, options?: GetCachedOptions): Promise<OAuthAuthorizationServerMetadata>;
|
|
13
|
+
private fetchMetadata;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=oauth-authorization-server-metadata-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-authorization-server-metadata-resolver.d.ts","sourceRoot":"","sources":["../src/oauth-authorization-server-metadata-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,EAEN,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACZ,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACL,gCAAgC,EAGjC,MAAM,sBAAsB,CAAA;AAG7B,YAAY,EAAE,gBAAgB,EAAE,gCAAgC,EAAE,CAAA;AAElE,MAAM,MAAM,gCAAgC,GAAG,WAAW,CACxD,MAAM,EACN,gCAAgC,CACjC,CAAA;AAED;;GAEG;AACH,qBAAa,wCAAyC,SAAQ,YAAY,CACxE,MAAM,EACN,gCAAgC,CACjC;IACC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;gBAE1B,KAAK,EAAE,gCAAgC,EAAE,KAAK,CAAC,EAAE,KAAK;IAM5D,GAAG,CACP,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,gCAAgC,CAAC;YAI9B,aAAa;CAkD5B"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OAuthAuthorizationServerMetadataResolver = void 0;
|
|
4
|
+
const fetch_1 = require("@atproto-labs/fetch");
|
|
5
|
+
const simple_store_1 = require("@atproto-labs/simple-store");
|
|
6
|
+
const oauth_types_1 = require("@atproto/oauth-types");
|
|
7
|
+
const util_1 = require("./util");
|
|
8
|
+
/**
|
|
9
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc8414}
|
|
10
|
+
*/
|
|
11
|
+
class OAuthAuthorizationServerMetadataResolver extends simple_store_1.CachedGetter {
|
|
12
|
+
constructor(cache, fetch) {
|
|
13
|
+
super(async (issuer, options) => this.fetchMetadata(issuer, options), cache);
|
|
14
|
+
Object.defineProperty(this, "fetch", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: void 0
|
|
19
|
+
});
|
|
20
|
+
this.fetch = (0, fetch_1.bindFetch)(fetch);
|
|
21
|
+
}
|
|
22
|
+
async get(issuer, options) {
|
|
23
|
+
return super.get(oauth_types_1.oauthIssuerIdentifierSchema.parse(issuer), options);
|
|
24
|
+
}
|
|
25
|
+
async fetchMetadata(issuer, options) {
|
|
26
|
+
const headers = new Headers([['accept', 'application/json']]);
|
|
27
|
+
if (options?.noCache)
|
|
28
|
+
headers.set('cache-control', 'no-cache');
|
|
29
|
+
const url = new URL(`/.well-known/oauth-authorization-server`, issuer);
|
|
30
|
+
const request = new Request(url, {
|
|
31
|
+
signal: options?.signal,
|
|
32
|
+
headers,
|
|
33
|
+
redirect: 'manual', // response must be 200 OK
|
|
34
|
+
});
|
|
35
|
+
const response = await this.fetch(request);
|
|
36
|
+
// https://datatracker.ietf.org/doc/html/rfc8414#section-3.2
|
|
37
|
+
if (response.status !== 200) {
|
|
38
|
+
await (0, fetch_1.cancelBody)(response, 'log');
|
|
39
|
+
throw await fetch_1.FetchResponseError.from(response, `Unexpected status code ${response.status} for "${url}"`, undefined, { cause: request });
|
|
40
|
+
}
|
|
41
|
+
if ((0, util_1.contentMime)(response.headers) !== 'application/json') {
|
|
42
|
+
await (0, fetch_1.cancelBody)(response, 'log');
|
|
43
|
+
throw await fetch_1.FetchResponseError.from(response, `Unexpected content type for "${url}"`, undefined, { cause: request });
|
|
44
|
+
}
|
|
45
|
+
const metadata = oauth_types_1.oauthAuthorizationServerMetadataValidator.parse(await response.json());
|
|
46
|
+
// Validate the issuer (MIX-UP attacks)
|
|
47
|
+
// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#name-mix-up-attacks
|
|
48
|
+
// https://datatracker.ietf.org/doc/html/rfc8414#section-2
|
|
49
|
+
if (metadata.issuer !== issuer) {
|
|
50
|
+
throw new TypeError(`Invalid issuer ${metadata.issuer}`);
|
|
51
|
+
}
|
|
52
|
+
return metadata;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.OAuthAuthorizationServerMetadataResolver = OAuthAuthorizationServerMetadataResolver;
|
|
56
|
+
//# sourceMappingURL=oauth-authorization-server-metadata-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-authorization-server-metadata-resolver.js","sourceRoot":"","sources":["../src/oauth-authorization-server-metadata-resolver.ts"],"names":[],"mappings":";;;AAAA,+CAK4B;AAC5B,6DAImC;AACnC,sDAI6B;AAC7B,iCAAoC;AASpC;;GAEG;AACH,MAAa,wCAAyC,SAAQ,2BAG7D;IAGC,YAAY,KAAuC,EAAE,KAAa;QAChE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAA;QAH7D;;;;;WAAqB;QAKpC,IAAI,CAAC,KAAK,GAAG,IAAA,iBAAS,EAAC,KAAK,CAAC,CAAA;IAC/B,CAAC;IAED,KAAK,CAAC,GAAG,CACP,MAAc,EACd,OAA0B;QAE1B,OAAO,KAAK,CAAC,GAAG,CAAC,yCAA2B,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAA;IACtE,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,MAAc,EACd,OAA0B;QAE1B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAA;QAC7D,IAAI,OAAO,EAAE,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;QAE9D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,yCAAyC,EAAE,MAAM,CAAC,CAAA;QACtE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE;YAC/B,MAAM,EAAE,OAAO,EAAE,MAAM;YACvB,OAAO;YACP,QAAQ,EAAE,QAAQ,EAAE,0BAA0B;SAC/C,CAAC,CAAA;QAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAE1C,4DAA4D;QAC5D,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAA,kBAAU,EAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;YACjC,MAAM,MAAM,0BAAkB,CAAC,IAAI,CACjC,QAAQ,EACR,0BAA0B,QAAQ,CAAC,MAAM,SAAS,GAAG,GAAG,EACxD,SAAS,EACT,EAAE,KAAK,EAAE,OAAO,EAAE,CACnB,CAAA;QACH,CAAC;QAED,IAAI,IAAA,kBAAW,EAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,kBAAkB,EAAE,CAAC;YACzD,MAAM,IAAA,kBAAU,EAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;YACjC,MAAM,MAAM,0BAAkB,CAAC,IAAI,CACjC,QAAQ,EACR,gCAAgC,GAAG,GAAG,EACtC,SAAS,EACT,EAAE,KAAK,EAAE,OAAO,EAAE,CACnB,CAAA;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,uDAAyC,CAAC,KAAK,CAC9D,MAAM,QAAQ,CAAC,IAAI,EAAE,CACtB,CAAA;QAED,uCAAuC;QACvC,6FAA6F;QAC7F,0DAA0D;QAC1D,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC/B,MAAM,IAAI,SAAS,CAAC,kBAAkB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;QAC1D,CAAC;QAED,OAAO,QAAQ,CAAA;IACjB,CAAC;CACF;AArED,4FAqEC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare class OAuthCallbackError extends Error {
|
|
2
|
+
readonly params: URLSearchParams;
|
|
3
|
+
readonly state?: string | undefined;
|
|
4
|
+
static from(err: unknown, params: URLSearchParams, state?: string): OAuthCallbackError;
|
|
5
|
+
constructor(params: URLSearchParams, message?: string, state?: string | undefined, cause?: unknown);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=oauth-callback-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-callback-error.d.ts","sourceRoot":"","sources":["../src/oauth-callback-error.ts"],"names":[],"mappings":"AAAA,qBAAa,kBAAmB,SAAQ,KAAK;aAQzB,MAAM,EAAE,eAAe;aAEvB,KAAK,CAAC;IATxB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,EAAE,MAAM;gBAO/C,MAAM,EAAE,eAAe,EACvC,OAAO,SAA4D,EACnD,KAAK,CAAC,oBAAQ,EAC9B,KAAK,CAAC,EAAE,OAAO;CAIlB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OAuthCallbackError = void 0;
|
|
4
|
+
class OAuthCallbackError extends Error {
|
|
5
|
+
static from(err, params, state) {
|
|
6
|
+
if (err instanceof OAuthCallbackError)
|
|
7
|
+
return err;
|
|
8
|
+
const message = err instanceof Error ? err.message : undefined;
|
|
9
|
+
return new OAuthCallbackError(params, message, state, err);
|
|
10
|
+
}
|
|
11
|
+
constructor(params, message = params.get('error_description') || 'OAuth callback error', state, cause) {
|
|
12
|
+
super(message, { cause });
|
|
13
|
+
Object.defineProperty(this, "params", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: params
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(this, "state", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: state
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.OAuthCallbackError = OAuthCallbackError;
|
|
28
|
+
//# sourceMappingURL=oauth-callback-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-callback-error.js","sourceRoot":"","sources":["../src/oauth-callback-error.ts"],"names":[],"mappings":";;;AAAA,MAAa,kBAAmB,SAAQ,KAAK;IAC3C,MAAM,CAAC,IAAI,CAAC,GAAY,EAAE,MAAuB,EAAE,KAAc;QAC/D,IAAI,GAAG,YAAY,kBAAkB;YAAE,OAAO,GAAG,CAAA;QACjD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;QAC9D,OAAO,IAAI,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;IAC5D,CAAC;IAED,YACkB,MAAuB,EACvC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,sBAAsB,EACnD,KAAc,EAC9B,KAAe;QAEf,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QALzB;;;;mBAAgB,MAAM;WAAiB;QAEvC;;;;mBAAgB,KAAK;WAAS;IAIhC,CAAC;CACF;AAfD,gDAeC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { DidCache } from '@atproto-labs/did-resolver';
|
|
2
|
+
import { Fetch } from '@atproto-labs/fetch';
|
|
3
|
+
import { HandleCache, HandleResolver } from '@atproto-labs/handle-resolver';
|
|
4
|
+
import { IdentityResolver } from '@atproto-labs/identity-resolver';
|
|
5
|
+
import { SimpleStore } from '@atproto-labs/simple-store';
|
|
6
|
+
import { Key, Keyset } from '@atproto/jwk';
|
|
7
|
+
import { OAuthClientMetadata, OAuthClientMetadataInput, OAuthResponseMode } from '@atproto/oauth-types';
|
|
8
|
+
import { OAuthAgent } from './oauth-agent.js';
|
|
9
|
+
import { AuthorizationServerMetadataCache } from './oauth-authorization-server-metadata-resolver.js';
|
|
10
|
+
import { ProtectedResourceMetadataCache } from './oauth-protected-resource-metadata-resolver.js';
|
|
11
|
+
import { OAuthResolver } from './oauth-resolver.js';
|
|
12
|
+
import { DpopNonceCache, OAuthServerAgent } from './oauth-server-agent.js';
|
|
13
|
+
import { OAuthServerFactory } from './oauth-server-factory.js';
|
|
14
|
+
import { RuntimeImplementation } from './runtime-implementation.js';
|
|
15
|
+
import { Runtime } from './runtime.js';
|
|
16
|
+
import { SessionGetter, SessionStore } from './session-getter.js';
|
|
17
|
+
import { AuthorizeOptions, ClientMetadata } from './types.js';
|
|
18
|
+
export type InternalStateData = {
|
|
19
|
+
iss: string;
|
|
20
|
+
nonce: string;
|
|
21
|
+
dpopKey: Key;
|
|
22
|
+
verifier?: string;
|
|
23
|
+
/**
|
|
24
|
+
* @note This could be parametrized to be of any type. This wasn't done for
|
|
25
|
+
* the sake of simplicity but could be added in a later development.
|
|
26
|
+
*/
|
|
27
|
+
appState?: string;
|
|
28
|
+
};
|
|
29
|
+
export type StateStore = SimpleStore<string, InternalStateData>;
|
|
30
|
+
export type { AuthorizationServerMetadataCache, DpopNonceCache, Fetch, Keyset, OAuthClientMetadata, OAuthClientMetadataInput, OAuthResponseMode, ProtectedResourceMetadataCache, RuntimeImplementation, SessionStore, };
|
|
31
|
+
export type OAuthClientOptions = {
|
|
32
|
+
responseMode: OAuthResponseMode;
|
|
33
|
+
clientMetadata: Readonly<OAuthClientMetadataInput>;
|
|
34
|
+
keyset?: Keyset | Iterable<Key | undefined | null | false>;
|
|
35
|
+
stateStore: StateStore;
|
|
36
|
+
sessionStore: SessionStore;
|
|
37
|
+
didCache?: DidCache;
|
|
38
|
+
handleCache?: HandleCache;
|
|
39
|
+
authorizationServerMetadataCache?: AuthorizationServerMetadataCache;
|
|
40
|
+
protectedResourceMetadataCache?: ProtectedResourceMetadataCache;
|
|
41
|
+
dpopNonceCache?: DpopNonceCache;
|
|
42
|
+
handleResolver: HandleResolver | URL | string;
|
|
43
|
+
plcDirectoryUrl?: URL | string;
|
|
44
|
+
runtimeImplementation: RuntimeImplementation;
|
|
45
|
+
fetch?: Fetch;
|
|
46
|
+
};
|
|
47
|
+
export declare class OAuthClient {
|
|
48
|
+
readonly clientMetadata: ClientMetadata;
|
|
49
|
+
readonly responseMode: OAuthResponseMode;
|
|
50
|
+
readonly keyset?: Keyset;
|
|
51
|
+
readonly runtime: Runtime;
|
|
52
|
+
readonly fetch: Fetch;
|
|
53
|
+
readonly oauthResolver: OAuthResolver;
|
|
54
|
+
readonly serverFactory: OAuthServerFactory;
|
|
55
|
+
readonly sessionGetter: SessionGetter;
|
|
56
|
+
readonly stateStore: StateStore;
|
|
57
|
+
constructor({ fetch, stateStore, sessionStore, didCache, dpopNonceCache, handleCache, authorizationServerMetadataCache, protectedResourceMetadataCache, responseMode, clientMetadata, handleResolver, plcDirectoryUrl, runtimeImplementation, keyset, }: OAuthClientOptions);
|
|
58
|
+
get identityResolver(): IdentityResolver;
|
|
59
|
+
get didResolver(): import("@atproto-labs/did-resolver").DidResolver<"web" | "plc">;
|
|
60
|
+
get handleResolver(): HandleResolver;
|
|
61
|
+
authorize(input: string, options?: AuthorizeOptions & {
|
|
62
|
+
signal?: AbortSignal;
|
|
63
|
+
}): Promise<URL>;
|
|
64
|
+
callback(params: URLSearchParams): Promise<{
|
|
65
|
+
agent: OAuthAgent;
|
|
66
|
+
state: string | null;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* Build an agent from a stored session. This will refresh the token only if
|
|
70
|
+
* needed (about to expire) by default.
|
|
71
|
+
*
|
|
72
|
+
* @param refresh See {@link SessionGetter.getSession}
|
|
73
|
+
*/
|
|
74
|
+
restore(sub: string, refresh?: boolean): Promise<OAuthAgent>;
|
|
75
|
+
revoke(sub: string): Promise<void>;
|
|
76
|
+
createAgent(server: OAuthServerAgent, sub: string): OAuthAgent;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=oauth-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-client.d.ts","sourceRoot":"","sources":["../src/oauth-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OAuthClient = void 0;
|
|
4
|
+
const did_resolver_1 = require("@atproto-labs/did-resolver");
|
|
5
|
+
const handle_resolver_1 = require("@atproto-labs/handle-resolver");
|
|
6
|
+
const identity_resolver_1 = require("@atproto-labs/identity-resolver");
|
|
7
|
+
const simple_store_memory_1 = require("@atproto-labs/simple-store-memory");
|
|
8
|
+
const jwk_1 = require("@atproto/jwk");
|
|
9
|
+
const constants_js_1 = require("./constants.js");
|
|
10
|
+
const oauth_agent_js_1 = require("./oauth-agent.js");
|
|
11
|
+
const oauth_authorization_server_metadata_resolver_js_1 = require("./oauth-authorization-server-metadata-resolver.js");
|
|
12
|
+
const oauth_callback_error_js_1 = require("./oauth-callback-error.js");
|
|
13
|
+
const oauth_protected_resource_metadata_resolver_js_1 = require("./oauth-protected-resource-metadata-resolver.js");
|
|
14
|
+
const oauth_resolver_js_1 = require("./oauth-resolver.js");
|
|
15
|
+
const oauth_server_factory_js_1 = require("./oauth-server-factory.js");
|
|
16
|
+
const runtime_js_1 = require("./runtime.js");
|
|
17
|
+
const session_getter_js_1 = require("./session-getter.js");
|
|
18
|
+
const validate_client_metadata_js_1 = require("./validate-client-metadata.js");
|
|
19
|
+
class OAuthClient {
|
|
20
|
+
constructor({ fetch = globalThis.fetch, stateStore, sessionStore, didCache = undefined, dpopNonceCache = new simple_store_memory_1.SimpleStoreMemory({ ttl: 60e3, max: 100 }), handleCache = undefined, authorizationServerMetadataCache = new simple_store_memory_1.SimpleStoreMemory({
|
|
21
|
+
ttl: 60e3,
|
|
22
|
+
max: 100,
|
|
23
|
+
}), protectedResourceMetadataCache = new simple_store_memory_1.SimpleStoreMemory({
|
|
24
|
+
ttl: 60e3,
|
|
25
|
+
max: 100,
|
|
26
|
+
}), responseMode, clientMetadata, handleResolver, plcDirectoryUrl, runtimeImplementation, keyset, }) {
|
|
27
|
+
// Config
|
|
28
|
+
Object.defineProperty(this, "clientMetadata", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
configurable: true,
|
|
31
|
+
writable: true,
|
|
32
|
+
value: void 0
|
|
33
|
+
});
|
|
34
|
+
Object.defineProperty(this, "responseMode", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
configurable: true,
|
|
37
|
+
writable: true,
|
|
38
|
+
value: void 0
|
|
39
|
+
});
|
|
40
|
+
Object.defineProperty(this, "keyset", {
|
|
41
|
+
enumerable: true,
|
|
42
|
+
configurable: true,
|
|
43
|
+
writable: true,
|
|
44
|
+
value: void 0
|
|
45
|
+
});
|
|
46
|
+
// Services
|
|
47
|
+
Object.defineProperty(this, "runtime", {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
configurable: true,
|
|
50
|
+
writable: true,
|
|
51
|
+
value: void 0
|
|
52
|
+
});
|
|
53
|
+
Object.defineProperty(this, "fetch", {
|
|
54
|
+
enumerable: true,
|
|
55
|
+
configurable: true,
|
|
56
|
+
writable: true,
|
|
57
|
+
value: void 0
|
|
58
|
+
});
|
|
59
|
+
Object.defineProperty(this, "oauthResolver", {
|
|
60
|
+
enumerable: true,
|
|
61
|
+
configurable: true,
|
|
62
|
+
writable: true,
|
|
63
|
+
value: void 0
|
|
64
|
+
});
|
|
65
|
+
Object.defineProperty(this, "serverFactory", {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
configurable: true,
|
|
68
|
+
writable: true,
|
|
69
|
+
value: void 0
|
|
70
|
+
});
|
|
71
|
+
// Stores
|
|
72
|
+
Object.defineProperty(this, "sessionGetter", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
configurable: true,
|
|
75
|
+
writable: true,
|
|
76
|
+
value: void 0
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(this, "stateStore", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
configurable: true,
|
|
81
|
+
writable: true,
|
|
82
|
+
value: void 0
|
|
83
|
+
});
|
|
84
|
+
this.keyset = keyset
|
|
85
|
+
? keyset instanceof jwk_1.Keyset
|
|
86
|
+
? keyset
|
|
87
|
+
: new jwk_1.Keyset(keyset)
|
|
88
|
+
: undefined;
|
|
89
|
+
this.clientMetadata = (0, validate_client_metadata_js_1.validateClientMetadata)(clientMetadata, this.keyset);
|
|
90
|
+
this.responseMode = responseMode;
|
|
91
|
+
this.runtime = new runtime_js_1.Runtime(runtimeImplementation);
|
|
92
|
+
this.fetch = fetch;
|
|
93
|
+
this.oauthResolver = new oauth_resolver_js_1.OAuthResolver(new identity_resolver_1.IdentityResolver(new did_resolver_1.DidResolverCached(new did_resolver_1.DidResolverCommon({ fetch, plcDirectoryUrl }), didCache), new handle_resolver_1.CachedHandleResolver(handle_resolver_1.AppViewHandleResolver.from(handleResolver, { fetch }), handleCache)), new oauth_protected_resource_metadata_resolver_js_1.OAuthProtectedResourceMetadataResolver(protectedResourceMetadataCache, fetch), new oauth_authorization_server_metadata_resolver_js_1.OAuthAuthorizationServerMetadataResolver(authorizationServerMetadataCache, fetch));
|
|
94
|
+
this.serverFactory = new oauth_server_factory_js_1.OAuthServerFactory(this.clientMetadata, this.runtime, this.oauthResolver, this.fetch, this.keyset, dpopNonceCache);
|
|
95
|
+
this.sessionGetter = new session_getter_js_1.SessionGetter(sessionStore, this.serverFactory, this.runtime);
|
|
96
|
+
this.stateStore = stateStore;
|
|
97
|
+
}
|
|
98
|
+
// Exposed as public API for convenience
|
|
99
|
+
get identityResolver() {
|
|
100
|
+
return this.oauthResolver.identityResolver;
|
|
101
|
+
}
|
|
102
|
+
// Exposed as public API for convenience
|
|
103
|
+
get didResolver() {
|
|
104
|
+
return this.identityResolver.didResolver;
|
|
105
|
+
}
|
|
106
|
+
// Exposed as public API for convenience
|
|
107
|
+
get handleResolver() {
|
|
108
|
+
return this.identityResolver.handleResolver;
|
|
109
|
+
}
|
|
110
|
+
async authorize(input, options) {
|
|
111
|
+
const redirectUri = options?.redirect_uri ?? this.clientMetadata.redirect_uris[0];
|
|
112
|
+
if (!this.clientMetadata.redirect_uris.includes(redirectUri)) {
|
|
113
|
+
// The server will enforce this, but let's catch it early
|
|
114
|
+
throw new TypeError('Invalid redirect_uri');
|
|
115
|
+
}
|
|
116
|
+
const signal = options?.signal;
|
|
117
|
+
const { identity, metadata } = /^https?:\/\//.test(input)
|
|
118
|
+
? // Allow using an entryway url directly as login input (e.g. when the
|
|
119
|
+
// user forgot their handle, or when the handle does not resolve to a
|
|
120
|
+
// DID)
|
|
121
|
+
{
|
|
122
|
+
identity: undefined,
|
|
123
|
+
metadata: await this.oauthResolver.resolveMetadata(input, { signal }),
|
|
124
|
+
}
|
|
125
|
+
: await this.oauthResolver.resolve(input, { signal });
|
|
126
|
+
const nonce = await this.runtime.generateNonce();
|
|
127
|
+
const pkce = await this.runtime.generatePKCE();
|
|
128
|
+
const dpopKey = await this.runtime.generateKey(metadata.dpop_signing_alg_values_supported || [constants_js_1.FALLBACK_ALG]);
|
|
129
|
+
const state = await this.runtime.generateNonce();
|
|
130
|
+
await this.stateStore.set(state, {
|
|
131
|
+
iss: metadata.issuer,
|
|
132
|
+
dpopKey,
|
|
133
|
+
nonce,
|
|
134
|
+
verifier: pkce?.verifier,
|
|
135
|
+
appState: options?.state,
|
|
136
|
+
});
|
|
137
|
+
const parameters = {
|
|
138
|
+
client_id: this.clientMetadata.client_id,
|
|
139
|
+
redirect_uri: redirectUri,
|
|
140
|
+
code_challenge: pkce?.challenge,
|
|
141
|
+
code_challenge_method: pkce?.method,
|
|
142
|
+
nonce,
|
|
143
|
+
state,
|
|
144
|
+
login_hint: identity?.did || undefined,
|
|
145
|
+
response_mode: this.responseMode,
|
|
146
|
+
response_type:
|
|
147
|
+
// Negotiate by using the order in the client metadata
|
|
148
|
+
this.clientMetadata.response_types?.find((t) => metadata['response_types_supported']?.includes(t)) ?? 'code',
|
|
149
|
+
display: options?.display,
|
|
150
|
+
id_token_hint: options?.id_token_hint,
|
|
151
|
+
max_age: options?.max_age, // this.clientMetadata.default_max_age
|
|
152
|
+
prompt: options?.prompt,
|
|
153
|
+
scope: options?.scope
|
|
154
|
+
?.split(' ')
|
|
155
|
+
.filter((s) => metadata.scopes_supported?.includes(s))
|
|
156
|
+
.join(' '),
|
|
157
|
+
ui_locales: options?.ui_locales,
|
|
158
|
+
};
|
|
159
|
+
if (metadata.pushed_authorization_request_endpoint) {
|
|
160
|
+
const server = await this.serverFactory.fromMetadata(metadata, dpopKey);
|
|
161
|
+
const parResponse = await server.request('pushed_authorization_request', parameters);
|
|
162
|
+
const authorizationUrl = new URL(metadata.authorization_endpoint);
|
|
163
|
+
authorizationUrl.searchParams.set('client_id', this.clientMetadata.client_id);
|
|
164
|
+
authorizationUrl.searchParams.set('request_uri', parResponse.request_uri);
|
|
165
|
+
return authorizationUrl;
|
|
166
|
+
}
|
|
167
|
+
else if (metadata.require_pushed_authorization_requests) {
|
|
168
|
+
throw new Error('Server requires pushed authorization requests (PAR) but no PAR endpoint is available');
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
const authorizationUrl = new URL(metadata.authorization_endpoint);
|
|
172
|
+
for (const [key, value] of Object.entries(parameters)) {
|
|
173
|
+
if (value)
|
|
174
|
+
authorizationUrl.searchParams.set(key, String(value));
|
|
175
|
+
}
|
|
176
|
+
// Length of the URL that will be sent to the server
|
|
177
|
+
const urlLength = authorizationUrl.pathname.length + authorizationUrl.search.length;
|
|
178
|
+
if (urlLength < 2048) {
|
|
179
|
+
return authorizationUrl;
|
|
180
|
+
}
|
|
181
|
+
else if (!metadata.pushed_authorization_request_endpoint) {
|
|
182
|
+
throw new Error('Login URL too long');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
throw new Error('Server does not support pushed authorization requests (PAR)');
|
|
186
|
+
}
|
|
187
|
+
async callback(params) {
|
|
188
|
+
const responseJwt = params.get('response');
|
|
189
|
+
if (responseJwt != null) {
|
|
190
|
+
// https://openid.net/specs/oauth-v2-jarm.html
|
|
191
|
+
throw new oauth_callback_error_js_1.OAuthCallbackError(params, 'JARM not supported');
|
|
192
|
+
}
|
|
193
|
+
const issuerParam = params.get('iss');
|
|
194
|
+
const stateParam = params.get('state');
|
|
195
|
+
const errorParam = params.get('error');
|
|
196
|
+
const codeParam = params.get('code');
|
|
197
|
+
if (!stateParam) {
|
|
198
|
+
throw new oauth_callback_error_js_1.OAuthCallbackError(params, 'Missing "state" parameter');
|
|
199
|
+
}
|
|
200
|
+
const stateData = await this.stateStore.get(stateParam);
|
|
201
|
+
if (stateData) {
|
|
202
|
+
// Prevent any kind of replay
|
|
203
|
+
await this.stateStore.del(stateParam);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
throw new oauth_callback_error_js_1.OAuthCallbackError(params, `Unknown authorization session "${stateParam}"`);
|
|
207
|
+
}
|
|
208
|
+
try {
|
|
209
|
+
if (errorParam != null) {
|
|
210
|
+
throw new oauth_callback_error_js_1.OAuthCallbackError(params, undefined, stateData.appState);
|
|
211
|
+
}
|
|
212
|
+
if (!codeParam) {
|
|
213
|
+
throw new oauth_callback_error_js_1.OAuthCallbackError(params, 'Missing "code" query param', stateData.appState);
|
|
214
|
+
}
|
|
215
|
+
const server = await this.serverFactory.fromIssuer(stateData.iss, stateData.dpopKey);
|
|
216
|
+
if (issuerParam != null) {
|
|
217
|
+
if (!server.serverMetadata.issuer) {
|
|
218
|
+
throw new oauth_callback_error_js_1.OAuthCallbackError(params, 'Issuer not found in metadata', stateData.appState);
|
|
219
|
+
}
|
|
220
|
+
if (server.serverMetadata.issuer !== issuerParam) {
|
|
221
|
+
throw new oauth_callback_error_js_1.OAuthCallbackError(params, 'Issuer mismatch', stateData.appState);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
else if (server.serverMetadata.authorization_response_iss_parameter_supported) {
|
|
225
|
+
throw new oauth_callback_error_js_1.OAuthCallbackError(params, 'iss missing from the response', stateData.appState);
|
|
226
|
+
}
|
|
227
|
+
const tokenSet = await server.exchangeCode(codeParam, stateData.verifier);
|
|
228
|
+
try {
|
|
229
|
+
if (tokenSet.id_token) {
|
|
230
|
+
await this.runtime.validateIdTokenClaims(tokenSet.id_token, stateParam, stateData.nonce, codeParam, tokenSet.access_token);
|
|
231
|
+
}
|
|
232
|
+
const { sub } = tokenSet;
|
|
233
|
+
await this.sessionGetter.setStored(sub, {
|
|
234
|
+
dpopKey: stateData.dpopKey,
|
|
235
|
+
tokenSet,
|
|
236
|
+
});
|
|
237
|
+
const agent = this.createAgent(server, sub);
|
|
238
|
+
return { agent, state: stateData.appState ?? null };
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
await server.revoke(tokenSet.access_token);
|
|
242
|
+
throw err;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
// Make sure, whatever the underlying error, that the appState is
|
|
247
|
+
// available in the calling code
|
|
248
|
+
throw oauth_callback_error_js_1.OAuthCallbackError.from(err, params, stateData.appState);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Build an agent from a stored session. This will refresh the token only if
|
|
253
|
+
* needed (about to expire) by default.
|
|
254
|
+
*
|
|
255
|
+
* @param refresh See {@link SessionGetter.getSession}
|
|
256
|
+
*/
|
|
257
|
+
async restore(sub, refresh) {
|
|
258
|
+
const { dpopKey, tokenSet } = await this.sessionGetter.getSession(sub, refresh);
|
|
259
|
+
const server = await this.serverFactory.fromIssuer(tokenSet.iss, dpopKey, {
|
|
260
|
+
noCache: refresh === true,
|
|
261
|
+
allowStale: refresh === false,
|
|
262
|
+
});
|
|
263
|
+
return this.createAgent(server, sub);
|
|
264
|
+
}
|
|
265
|
+
async revoke(sub) {
|
|
266
|
+
const { dpopKey, tokenSet } = await this.sessionGetter.get(sub, {
|
|
267
|
+
allowStale: true,
|
|
268
|
+
});
|
|
269
|
+
const server = await this.serverFactory.fromIssuer(tokenSet.iss, dpopKey);
|
|
270
|
+
await server.revoke(tokenSet.access_token);
|
|
271
|
+
await this.sessionGetter.delStored(sub);
|
|
272
|
+
}
|
|
273
|
+
createAgent(server, sub) {
|
|
274
|
+
return new oauth_agent_js_1.OAuthAgent(server, sub, this.sessionGetter, this.fetch);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
exports.OAuthClient = OAuthClient;
|
|
278
|
+
//# sourceMappingURL=oauth-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-client.js","sourceRoot":"","sources":["../src/oauth-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Fetch } from '@atproto-labs/fetch';
|
|
2
|
+
import { CachedGetter, GetCachedOptions, SimpleStore } from '@atproto-labs/simple-store';
|
|
3
|
+
import { OAuthProtectedResourceMetadata } from '@atproto/oauth-types';
|
|
4
|
+
export type { GetCachedOptions, OAuthProtectedResourceMetadata };
|
|
5
|
+
export type ProtectedResourceMetadataCache = SimpleStore<string, OAuthProtectedResourceMetadata>;
|
|
6
|
+
/**
|
|
7
|
+
* @see {@link https://datatracker.ietf.org/doc/html/draft-ietf-oauth-resource-metadata-05}
|
|
8
|
+
*/
|
|
9
|
+
export declare class OAuthProtectedResourceMetadataResolver extends CachedGetter<string, OAuthProtectedResourceMetadata> {
|
|
10
|
+
private readonly fetch;
|
|
11
|
+
constructor(cache: ProtectedResourceMetadataCache, fetch?: Fetch);
|
|
12
|
+
get(resource: string | URL, options?: GetCachedOptions): Promise<OAuthProtectedResourceMetadata>;
|
|
13
|
+
private fetchMetadata;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=oauth-protected-resource-metadata-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-protected-resource-metadata-resolver.d.ts","sourceRoot":"","sources":["../src/oauth-protected-resource-metadata-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EAIN,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACZ,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACL,8BAA8B,EAE/B,MAAM,sBAAsB,CAAA;AAG7B,YAAY,EAAE,gBAAgB,EAAE,8BAA8B,EAAE,CAAA;AAEhE,MAAM,MAAM,8BAA8B,GAAG,WAAW,CACtD,MAAM,EACN,8BAA8B,CAC/B,CAAA;AAED;;GAEG;AACH,qBAAa,sCAAuC,SAAQ,YAAY,CACtE,MAAM,EACN,8BAA8B,CAC/B;IACC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;gBAGpC,KAAK,EAAE,8BAA8B,EACrC,KAAK,GAAE,KAAwB;IAO3B,GAAG,CACP,QAAQ,EAAE,MAAM,GAAG,GAAG,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,8BAA8B,CAAC;YAQ5B,aAAa;CAgD5B"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OAuthProtectedResourceMetadataResolver = void 0;
|
|
4
|
+
const fetch_1 = require("@atproto-labs/fetch");
|
|
5
|
+
const simple_store_1 = require("@atproto-labs/simple-store");
|
|
6
|
+
const oauth_types_1 = require("@atproto/oauth-types");
|
|
7
|
+
const util_1 = require("./util");
|
|
8
|
+
/**
|
|
9
|
+
* @see {@link https://datatracker.ietf.org/doc/html/draft-ietf-oauth-resource-metadata-05}
|
|
10
|
+
*/
|
|
11
|
+
class OAuthProtectedResourceMetadataResolver extends simple_store_1.CachedGetter {
|
|
12
|
+
constructor(cache, fetch = globalThis.fetch) {
|
|
13
|
+
super(async (origin, options) => this.fetchMetadata(origin, options), cache);
|
|
14
|
+
Object.defineProperty(this, "fetch", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: void 0
|
|
19
|
+
});
|
|
20
|
+
this.fetch = (0, fetch_1.bindFetch)(fetch);
|
|
21
|
+
}
|
|
22
|
+
async get(resource, options) {
|
|
23
|
+
const { protocol, origin } = new URL(resource);
|
|
24
|
+
if (protocol !== 'https:' && protocol !== 'http:') {
|
|
25
|
+
throw new TypeError(`Invalid resource server ${protocol}`);
|
|
26
|
+
}
|
|
27
|
+
return super.get(origin, options);
|
|
28
|
+
}
|
|
29
|
+
async fetchMetadata(origin, options) {
|
|
30
|
+
const headers = new Headers([['accept', 'application/json']]);
|
|
31
|
+
if (options?.noCache)
|
|
32
|
+
headers.set('cache-control', 'no-cache');
|
|
33
|
+
const url = new URL(`/.well-known/oauth-protected-resource`, origin);
|
|
34
|
+
const request = new Request(url, {
|
|
35
|
+
signal: options?.signal,
|
|
36
|
+
headers,
|
|
37
|
+
redirect: 'error', // response must be 200 OK
|
|
38
|
+
});
|
|
39
|
+
const response = await this.fetch(request);
|
|
40
|
+
// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-resource-metadata-05#section-3.2
|
|
41
|
+
if (response.status !== 200) {
|
|
42
|
+
await (0, fetch_1.cancelBody)(response, 'log');
|
|
43
|
+
throw await fetch_1.FetchResponseError.from(response, `Unexpected status code ${response.status} for "${url}"`, undefined, { cause: request });
|
|
44
|
+
}
|
|
45
|
+
if ((0, util_1.contentMime)(response.headers) !== 'application/json') {
|
|
46
|
+
await (0, fetch_1.cancelBody)(response, 'log');
|
|
47
|
+
throw await fetch_1.FetchResponseError.from(response, `Unexpected content type for "${url}"`, undefined, { cause: request });
|
|
48
|
+
}
|
|
49
|
+
const metadata = oauth_types_1.oauthProtectedResourceMetadataSchema.parse(await response.json());
|
|
50
|
+
// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-resource-metadata-05#section-3.3
|
|
51
|
+
if (metadata.resource !== origin) {
|
|
52
|
+
throw new TypeError(`Invalid issuer ${metadata.resource}`);
|
|
53
|
+
}
|
|
54
|
+
return metadata;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.OAuthProtectedResourceMetadataResolver = OAuthProtectedResourceMetadataResolver;
|
|
58
|
+
//# sourceMappingURL=oauth-protected-resource-metadata-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-protected-resource-metadata-resolver.js","sourceRoot":"","sources":["../src/oauth-protected-resource-metadata-resolver.ts"],"names":[],"mappings":";;;AAAA,+CAK4B;AAC5B,6DAImC;AACnC,sDAG6B;AAC7B,iCAAoC;AASpC;;GAEG;AACH,MAAa,sCAAuC,SAAQ,2BAG3D;IAGC,YACE,KAAqC,EACrC,QAAe,UAAU,CAAC,KAAK;QAE/B,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAA;QAN7D;;;;;WAAqB;QAQpC,IAAI,CAAC,KAAK,GAAG,IAAA,iBAAS,EAAC,KAAK,CAAC,CAAA;IAC/B,CAAC;IAED,KAAK,CAAC,GAAG,CACP,QAAsB,EACtB,OAA0B;QAE1B,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC9C,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YAClD,MAAM,IAAI,SAAS,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAA;QAC5D,CAAC;QACD,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,MAAc,EACd,OAA0B;QAE1B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAA;QAC7D,IAAI,OAAO,EAAE,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;QAE9D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,uCAAuC,EAAE,MAAM,CAAC,CAAA;QACpE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE;YAC/B,MAAM,EAAE,OAAO,EAAE,MAAM;YACvB,OAAO;YACP,QAAQ,EAAE,OAAO,EAAE,0BAA0B;SAC9C,CAAC,CAAA;QAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAE1C,0FAA0F;QAC1F,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAA,kBAAU,EAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;YACjC,MAAM,MAAM,0BAAkB,CAAC,IAAI,CACjC,QAAQ,EACR,0BAA0B,QAAQ,CAAC,MAAM,SAAS,GAAG,GAAG,EACxD,SAAS,EACT,EAAE,KAAK,EAAE,OAAO,EAAE,CACnB,CAAA;QACH,CAAC;QAED,IAAI,IAAA,kBAAW,EAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,kBAAkB,EAAE,CAAC;YACzD,MAAM,IAAA,kBAAU,EAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;YACjC,MAAM,MAAM,0BAAkB,CAAC,IAAI,CACjC,QAAQ,EACR,gCAAgC,GAAG,GAAG,EACtC,SAAS,EACT,EAAE,KAAK,EAAE,OAAO,EAAE,CACnB,CAAA;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,kDAAoC,CAAC,KAAK,CACzD,MAAM,QAAQ,CAAC,IAAI,EAAE,CACtB,CAAA;QAED,0FAA0F;QAC1F,IAAI,QAAQ,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YACjC,MAAM,IAAI,SAAS,CAAC,kBAAkB,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC5D,CAAC;QAED,OAAO,QAAQ,CAAA;IACjB,CAAC;CACF;AA1ED,wFA0EC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-resolver-error.d.ts","sourceRoot":"","sources":["../src/oauth-resolver-error.ts"],"names":[],"mappings":"AAAA,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;IAI1D,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,kBAAkB;CAMlE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OAuthResolverError = void 0;
|
|
4
|
+
class OAuthResolverError extends Error {
|
|
5
|
+
constructor(message, options) {
|
|
6
|
+
super(message, options);
|
|
7
|
+
}
|
|
8
|
+
static from(cause, message) {
|
|
9
|
+
if (cause instanceof OAuthResolverError)
|
|
10
|
+
return cause;
|
|
11
|
+
return new OAuthResolverError(message ?? `Unable to resolve identity`, {
|
|
12
|
+
cause,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.OAuthResolverError = OAuthResolverError;
|
|
17
|
+
//# sourceMappingURL=oauth-resolver-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-resolver-error.js","sourceRoot":"","sources":["../src/oauth-resolver-error.ts"],"names":[],"mappings":";;;AAAA,MAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACzB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,KAAc,EAAE,OAAgB;QAC1C,IAAI,KAAK,YAAY,kBAAkB;YAAE,OAAO,KAAK,CAAA;QACrD,OAAO,IAAI,kBAAkB,CAAC,OAAO,IAAI,4BAA4B,EAAE;YACrE,KAAK;SACN,CAAC,CAAA;IACJ,CAAC;CACF;AAXD,gDAWC"}
|