@atproto/oauth-provider 0.1.2-rc.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/assets/app/bundle-manifest.json +2 -2
  3. package/dist/assets/app/main.js +3 -3
  4. package/dist/assets/app/main.js.map +1 -1
  5. package/dist/client/client-manager.d.ts.map +1 -1
  6. package/dist/client/client-manager.js +31 -40
  7. package/dist/client/client-manager.js.map +1 -1
  8. package/dist/client/client.d.ts +2 -3
  9. package/dist/client/client.d.ts.map +1 -1
  10. package/dist/client/client.js +5 -9
  11. package/dist/client/client.js.map +1 -1
  12. package/dist/dpop/dpop-manager.d.ts +0 -1
  13. package/dist/dpop/dpop-manager.d.ts.map +1 -1
  14. package/dist/dpop/dpop-manager.js +1 -4
  15. package/dist/dpop/dpop-manager.js.map +1 -1
  16. package/dist/lib/http/parser.d.ts +13 -7
  17. package/dist/lib/http/parser.d.ts.map +1 -1
  18. package/dist/lib/http/parser.js +29 -9
  19. package/dist/lib/http/parser.js.map +1 -1
  20. package/dist/lib/http/request.d.ts +5 -5
  21. package/dist/lib/http/stream.d.ts.map +1 -1
  22. package/dist/lib/http/stream.js +3 -2
  23. package/dist/lib/http/stream.js.map +1 -1
  24. package/dist/metadata/build-metadata.d.ts.map +1 -1
  25. package/dist/metadata/build-metadata.js +0 -14
  26. package/dist/metadata/build-metadata.js.map +1 -1
  27. package/dist/oauth-provider.d.ts +2 -2
  28. package/dist/oauth-provider.d.ts.map +1 -1
  29. package/dist/oauth-provider.js +7 -5
  30. package/dist/oauth-provider.js.map +1 -1
  31. package/dist/request/types.d.ts +4 -4
  32. package/dist/signer/signed-token-payload.d.ts +3 -3
  33. package/dist/signer/signer.d.ts +1 -1
  34. package/dist/token/token-claims.d.ts +3 -3
  35. package/package.json +5 -4
  36. package/src/client/client-manager.ts +46 -60
  37. package/src/client/client.ts +4 -13
  38. package/src/dpop/dpop-manager.ts +1 -6
  39. package/src/lib/http/parser.ts +37 -13
  40. package/src/lib/http/stream.ts +5 -2
  41. package/src/metadata/build-metadata.ts +0 -14
  42. package/src/oauth-provider.ts +6 -18
  43. package/dist/output/send-authorize-page.d.ts +0 -43
  44. package/dist/output/send-authorize-page.d.ts.map +0 -1
  45. package/dist/output/send-authorize-page.js +0 -49
  46. package/dist/output/send-authorize-page.js.map +0 -1
  47. package/dist/output/send-error-page.d.ts +0 -5
  48. package/dist/output/send-error-page.d.ts.map +0 -1
  49. package/dist/output/send-error-page.js +0 -31
  50. package/dist/output/send-error-page.js.map +0 -1
@@ -7,6 +7,7 @@ import {
7
7
  KnownNames,
8
8
  KnownParser,
9
9
  KnownTypes,
10
+ parseContentType,
10
11
  ParserForType,
11
12
  ParserResult,
12
13
  parsers,
@@ -64,9 +65,11 @@ export async function parseStream(
64
65
  throw createHttpError(400, 'Invalid content-type')
65
66
  }
66
67
 
68
+ const type = parseContentType(contentType)
69
+
67
70
  const parser = parsers.find(
68
71
  (parser) =>
69
- allow?.includes(parser.name) !== false && parser.test(contentType),
72
+ allow?.includes(parser.name) !== false && parser.test(type.mime),
70
73
  )
71
74
 
72
75
  if (!parser) {
@@ -74,5 +77,5 @@ export async function parseStream(
74
77
  }
75
78
 
76
79
  const buffer = await readStream(req)
77
- return parser.parse(buffer)
80
+ return parser.parse(buffer, type)
78
81
  }
@@ -127,28 +127,14 @@ export function buildMetadata(
127
127
  token_endpoint_auth_signing_alg_values_supported: [...VERIFY_ALGOS],
128
128
 
129
129
  revocation_endpoint: new URL('/oauth/revoke', issuer).href,
130
- revocation_endpoint_auth_methods_supported: [
131
- ...Client.AUTH_METHODS_SUPPORTED,
132
- ],
133
- revocation_endpoint_auth_signing_alg_values_supported: [...VERIFY_ALGOS],
134
130
 
135
131
  introspection_endpoint: new URL('/oauth/introspect', issuer).href,
136
- introspection_endpoint_auth_methods_supported: [
137
- ...Client.AUTH_METHODS_SUPPORTED,
138
- ],
139
- introspection_endpoint_auth_signing_alg_values_supported: [...VERIFY_ALGOS],
140
132
 
141
133
  userinfo_endpoint: new URL('/oauth/userinfo', issuer).href,
142
134
  // end_session_endpoint: new URL('/oauth/logout', issuer).href,
143
135
 
144
136
  // https://datatracker.ietf.org/doc/html/rfc9126#section-5
145
137
  pushed_authorization_request_endpoint: new URL('/oauth/par', issuer).href,
146
- pushed_authorization_request_endpoint_auth_methods_supported: [
147
- ...Client.AUTH_METHODS_SUPPORTED,
148
- ],
149
- pushed_authorization_request_endpoint_auth_signing_alg_values_supported: [
150
- ...VERIFY_ALGOS,
151
- ],
152
138
 
153
139
  require_pushed_authorization_requests: true,
154
140
 
@@ -9,7 +9,6 @@ import {
9
9
  OAuthAuthorizationServerMetadata,
10
10
  OAuthClientIdentification,
11
11
  OAuthClientMetadata,
12
- OAuthEndpointName,
13
12
  OAuthTokenResponse,
14
13
  OAuthTokenType,
15
14
  atprotoLoopbackClientMetadata,
@@ -339,14 +338,11 @@ export class OAuthProvider extends OAuthVerifier {
339
338
 
340
339
  protected async authenticateClient(
341
340
  client: Client,
342
- endpoint: OAuthEndpointName,
343
341
  credentials: OAuthClientIdentification,
344
342
  ): Promise<ClientAuth> {
345
- const { clientAuth, nonce } = await client.verifyCredentials(
346
- credentials,
347
- endpoint,
348
- { audience: this.issuer },
349
- )
343
+ const { clientAuth, nonce } = await client.verifyCredentials(credentials, {
344
+ audience: this.issuer,
345
+ })
350
346
 
351
347
  if (nonce != null) {
352
348
  const unique = await this.replayManager.uniqueAuth(nonce, client.id)
@@ -424,11 +420,7 @@ export class OAuthProvider extends OAuthVerifier {
424
420
  ) {
425
421
  try {
426
422
  const client = await this.clientManager.getClient(input.client_id)
427
- const clientAuth = await this.authenticateClient(
428
- client,
429
- 'pushed_authorization_request',
430
- input,
431
- )
423
+ const clientAuth = await this.authenticateClient(client, input)
432
424
 
433
425
  const { payload: parameters } =
434
426
  'request' in input // Handle JAR
@@ -767,7 +759,7 @@ export class OAuthProvider extends OAuthVerifier {
767
759
  dpopJkt: null | string,
768
760
  ): Promise<OAuthTokenResponse> {
769
761
  const client = await this.clientManager.getClient(input.client_id)
770
- const clientAuth = await this.authenticateClient(client, 'token', input)
762
+ const clientAuth = await this.authenticateClient(client, input)
771
763
 
772
764
  if (!client.metadata.grant_types.includes(input.grant_type)) {
773
765
  throw new InvalidGrantError(
@@ -851,11 +843,7 @@ export class OAuthProvider extends OAuthVerifier {
851
843
  input: Introspect,
852
844
  ): Promise<IntrospectionResponse> {
853
845
  const client = await this.clientManager.getClient(input.client_id)
854
- const clientAuth = await this.authenticateClient(
855
- client,
856
- 'introspection',
857
- input,
858
- )
846
+ const clientAuth = await this.authenticateClient(client, input)
859
847
 
860
848
  // RFC7662 states the following:
861
849
  //
@@ -1,43 +0,0 @@
1
- /// <reference types="node" />
2
- import { OAuthAuthenticationRequestParameters, OAuthClientMetadata } from '@atproto/oauth-types';
3
- import { ServerResponse } from 'node:http';
4
- import { DeviceAccountInfo } from '../account/account-store.js';
5
- import { Account } from '../account/account.js';
6
- import { Client } from '../client/client.js';
7
- import { RequestUri } from '../request/request-uri.js';
8
- import { Customization } from './customization.js';
9
- export type AuthorizationResultAuthorize = {
10
- issuer: string;
11
- client: Client;
12
- parameters: OAuthAuthenticationRequestParameters;
13
- authorize: {
14
- uri: RequestUri;
15
- sessions: readonly {
16
- account: Account;
17
- info: DeviceAccountInfo;
18
- selected: boolean;
19
- loginRequired: boolean;
20
- consentRequired: boolean;
21
- }[];
22
- };
23
- };
24
- type Session = {
25
- account: Account;
26
- info?: never;
27
- selected: boolean;
28
- loginRequired: boolean;
29
- consentRequired: boolean;
30
- };
31
- export type AuthorizeData = {
32
- clientId: string;
33
- clientMetadata: OAuthClientMetadata;
34
- clientTrusted: boolean;
35
- requestUri: string;
36
- csrfCookie: string;
37
- loginHint?: string;
38
- newSessionsRequireConsent: boolean;
39
- sessions: Session[];
40
- };
41
- export declare function sendAuthorizePage(res: ServerResponse, data: AuthorizationResultAuthorize, customization?: Customization): Promise<void>;
42
- export {};
43
- //# sourceMappingURL=send-authorize-page.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"send-authorize-page.d.ts","sourceRoot":"","sources":["../../src/output/send-authorize-page.ts"],"names":[],"mappings":";AAAA,OAAO,EACL,oCAAoC,EACpC,mBAAmB,EACpB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAE/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,EACL,aAAa,EAGd,MAAM,oBAAoB,CAAA;AAG3B,MAAM,MAAM,4BAA4B,GAAG;IACzC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,oCAAoC,CAAA;IAChD,SAAS,EAAE;QACT,GAAG,EAAE,UAAU,CAAA;QACf,QAAQ,EAAE,SAAS;YACjB,OAAO,EAAE,OAAO,CAAA;YAChB,IAAI,EAAE,iBAAiB,CAAA;YAEvB,QAAQ,EAAE,OAAO,CAAA;YACjB,aAAa,EAAE,OAAO,CAAA;YACtB,eAAe,EAAE,OAAO,CAAA;SACzB,EAAE,CAAA;KACJ,CAAA;CACF,CAAA;AAKD,KAAK,OAAO,GAAG;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,KAAK,CAAA;IAEZ,QAAQ,EAAE,OAAO,CAAA;IACjB,aAAa,EAAE,OAAO,CAAA;IACtB,eAAe,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,mBAAmB,CAAA;IACnC,aAAa,EAAE,OAAO,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yBAAyB,EAAE,OAAO,CAAA;IAClC,QAAQ,EAAE,OAAO,EAAE,CAAA;CACpB,CAAA;AAsBD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,4BAA4B,EAClC,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
@@ -1,49 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sendAuthorizePage = void 0;
4
- const index_js_1 = require("../assets/index.js");
5
- const index_js_2 = require("../lib/html/index.js");
6
- const customization_js_1 = require("./customization.js");
7
- const send_web_page_js_1 = require("./send-web-page.js");
8
- function buildAuthorizeData(data) {
9
- return {
10
- clientId: data.client.id,
11
- clientMetadata: data.client.metadata,
12
- clientTrusted: data.client.info.isTrusted,
13
- requestUri: data.authorize.uri,
14
- csrfCookie: `csrf-${data.authorize.uri}`,
15
- loginHint: data.parameters.login_hint,
16
- newSessionsRequireConsent: data.parameters.prompt === 'consent',
17
- sessions: data.authorize.sessions.map((session) => ({
18
- account: session.account,
19
- selected: session.selected,
20
- loginRequired: session.loginRequired,
21
- consentRequired: session.consentRequired,
22
- })),
23
- };
24
- }
25
- async function sendAuthorizePage(res, data, customization) {
26
- res.setHeader('Cache-Control', 'no-store');
27
- res.setHeader('Permissions-Policy', 'otp-credentials=*, document-domain=()');
28
- const [jsAsset, cssAsset] = await Promise.all([
29
- (0, index_js_1.getAsset)('main.js'),
30
- (0, index_js_1.getAsset)('main.css'),
31
- ]);
32
- return (0, send_web_page_js_1.sendWebPage)(res, {
33
- scripts: [
34
- (0, send_web_page_js_1.declareBackendData)('__customizationData', (0, customization_js_1.buildCustomizationData)(customization)),
35
- (0, send_web_page_js_1.declareBackendData)('__authorizeData', buildAuthorizeData(data)),
36
- jsAsset, // Last (to be able to read the global variables)
37
- ],
38
- styles: [
39
- cssAsset, // First (to be overridden by customization)
40
- (0, index_js_2.cssCode)((0, customization_js_1.buildCustomizationCss)(customization)),
41
- ],
42
- links: customization?.links,
43
- htmlAttrs: { lang: 'en' },
44
- title: 'Authorize',
45
- body: (0, index_js_2.html) `<div id="root"></div>`,
46
- });
47
- }
48
- exports.sendAuthorizePage = sendAuthorizePage;
49
- //# sourceMappingURL=send-authorize-page.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"send-authorize-page.js","sourceRoot":"","sources":["../../src/output/send-authorize-page.ts"],"names":[],"mappings":";;;AAQA,iDAA6C;AAE7C,mDAAoD;AAEpD,yDAI2B;AAC3B,yDAAoE;AA0CpE,SAAS,kBAAkB,CAAC,IAAkC;IAC5D,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE;QACxB,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;QACpC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS;QACzC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG;QAC9B,UAAU,EAAE,QAAQ,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;QACxC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU;QACrC,yBAAyB,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,SAAS;QAC/D,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CACnC,CAAC,OAAO,EAAW,EAAE,CAAC,CAAC;YACrB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,eAAe,EAAE,OAAO,CAAC,eAAe;SACzC,CAAC,CACH;KACF,CAAA;AACH,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,GAAmB,EACnB,IAAkC,EAClC,aAA6B;IAE7B,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;IAC1C,GAAG,CAAC,SAAS,CAAC,oBAAoB,EAAE,uCAAuC,CAAC,CAAA;IAE5E,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC5C,IAAA,mBAAQ,EAAC,SAAS,CAAC;QACnB,IAAA,mBAAQ,EAAC,UAAU,CAAC;KACrB,CAAC,CAAA;IAEF,OAAO,IAAA,8BAAW,EAAC,GAAG,EAAE;QACtB,OAAO,EAAE;YACP,IAAA,qCAAkB,EAChB,qBAAqB,EACrB,IAAA,yCAAsB,EAAC,aAAa,CAAC,CACtC;YACD,IAAA,qCAAkB,EAAC,iBAAiB,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAC/D,OAAO,EAAE,iDAAiD;SAC3D;QACD,MAAM,EAAE;YACN,QAAQ,EAAE,4CAA4C;YACtD,IAAA,kBAAO,EAAC,IAAA,wCAAqB,EAAC,aAAa,CAAC,CAAC;SAC9C;QACD,KAAK,EAAE,aAAa,EAAE,KAAK;QAC3B,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;QACzB,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,IAAA,eAAI,EAAA,uBAAuB;KAClC,CAAC,CAAA;AACJ,CAAC;AA/BD,8CA+BC"}
@@ -1,5 +0,0 @@
1
- /// <reference types="node" />
2
- import { ServerResponse } from 'node:http';
3
- import { Customization } from './customization.js';
4
- export declare function sendErrorPage(res: ServerResponse, err: unknown, customization?: Customization): Promise<void>;
5
- //# sourceMappingURL=send-error-page.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"send-error-page.d.ts","sourceRoot":"","sources":["../../src/output/send-error-page.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAK1C,OAAO,EACL,aAAa,EAGd,MAAM,oBAAoB,CAAA;AAG3B,wBAAsB,aAAa,CACjC,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,OAAO,EACZ,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,IAAI,CAAC,CAwBf"}
@@ -1,31 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sendErrorPage = void 0;
4
- const index_js_1 = require("../assets/index.js");
5
- const index_js_2 = require("../lib/html/index.js");
6
- const build_error_payload_js_1 = require("./build-error-payload.js");
7
- const customization_js_1 = require("./customization.js");
8
- const send_web_page_js_1 = require("./send-web-page.js");
9
- async function sendErrorPage(res, err, customization) {
10
- const [jsAsset, cssAsset] = await Promise.all([
11
- (0, index_js_1.getAsset)('main.js'),
12
- (0, index_js_1.getAsset)('main.css'),
13
- ]);
14
- return (0, send_web_page_js_1.sendWebPage)(res, {
15
- status: (0, build_error_payload_js_1.buildErrorStatus)(err),
16
- scripts: [
17
- (0, send_web_page_js_1.declareBackendData)('__customizationData', (0, customization_js_1.buildCustomizationData)(customization)),
18
- (0, send_web_page_js_1.declareBackendData)('__errorData', (0, build_error_payload_js_1.buildErrorPayload)(err)),
19
- jsAsset, // Last (to be able to read the global variables)
20
- ],
21
- styles: [
22
- cssAsset, // First (to be overridden by customization)
23
- (0, index_js_2.cssCode)((0, customization_js_1.buildCustomizationCss)(customization)),
24
- ],
25
- htmlAttrs: { lang: 'en' },
26
- title: 'Error',
27
- body: (0, index_js_2.html) `<div id="root"></div>`,
28
- });
29
- }
30
- exports.sendErrorPage = sendErrorPage;
31
- //# sourceMappingURL=send-error-page.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"send-error-page.js","sourceRoot":"","sources":["../../src/output/send-error-page.ts"],"names":[],"mappings":";;;AAEA,iDAA6C;AAC7C,mDAAoD;AACpD,qEAA8E;AAC9E,yDAI2B;AAC3B,yDAAoE;AAE7D,KAAK,UAAU,aAAa,CACjC,GAAmB,EACnB,GAAY,EACZ,aAA6B;IAE7B,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC5C,IAAA,mBAAQ,EAAC,SAAS,CAAC;QACnB,IAAA,mBAAQ,EAAC,UAAU,CAAC;KACrB,CAAC,CAAA;IAEF,OAAO,IAAA,8BAAW,EAAC,GAAG,EAAE;QACtB,MAAM,EAAE,IAAA,yCAAgB,EAAC,GAAG,CAAC;QAC7B,OAAO,EAAE;YACP,IAAA,qCAAkB,EAChB,qBAAqB,EACrB,IAAA,yCAAsB,EAAC,aAAa,CAAC,CACtC;YACD,IAAA,qCAAkB,EAAC,aAAa,EAAE,IAAA,0CAAiB,EAAC,GAAG,CAAC,CAAC;YACzD,OAAO,EAAE,iDAAiD;SAC3D;QACD,MAAM,EAAE;YACN,QAAQ,EAAE,4CAA4C;YACtD,IAAA,kBAAO,EAAC,IAAA,wCAAqB,EAAC,aAAa,CAAC,CAAC;SAC9C;QACD,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;QACzB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,IAAA,eAAI,EAAA,uBAAuB;KAClC,CAAC,CAAA;AACJ,CAAC;AA5BD,sCA4BC"}