@atproto/oauth-provider 0.2.6 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. package/CHANGELOG.md +13 -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/assets/assets-middleware.js +1 -1
  6. package/dist/assets/assets-middleware.js.map +1 -1
  7. package/dist/client/client.d.ts +2 -2
  8. package/dist/client/client.d.ts.map +1 -1
  9. package/dist/client/client.js.map +1 -1
  10. package/dist/lib/http/accept.d.ts +1 -0
  11. package/dist/lib/http/accept.d.ts.map +1 -1
  12. package/dist/lib/http/accept.js +1 -0
  13. package/dist/lib/http/accept.js.map +1 -1
  14. package/dist/lib/http/middleware.js +1 -1
  15. package/dist/lib/http/middleware.js.map +1 -1
  16. package/dist/lib/http/response.d.ts +9 -5
  17. package/dist/lib/http/response.d.ts.map +1 -1
  18. package/dist/lib/http/response.js +18 -59
  19. package/dist/lib/http/response.js.map +1 -1
  20. package/dist/oauth-provider.d.ts.map +1 -1
  21. package/dist/oauth-provider.js +19 -9
  22. package/dist/oauth-provider.js.map +1 -1
  23. package/dist/oauth-verifier.d.ts +2 -2
  24. package/dist/oauth-verifier.d.ts.map +1 -1
  25. package/dist/oauth-verifier.js.map +1 -1
  26. package/dist/output/send-web-page.d.ts +3 -3
  27. package/dist/output/send-web-page.d.ts.map +1 -1
  28. package/dist/output/send-web-page.js +2 -2
  29. package/dist/output/send-web-page.js.map +1 -1
  30. package/dist/request/request-uri.d.ts.map +1 -1
  31. package/dist/request/request-uri.js +0 -1
  32. package/dist/request/request-uri.js.map +1 -1
  33. package/dist/signer/signed-token-payload.d.ts +3 -3
  34. package/dist/signer/signer.d.ts +1 -1
  35. package/dist/token/token-claims.d.ts +3 -3
  36. package/package.json +2 -2
  37. package/src/assets/assets-middleware.ts +1 -1
  38. package/src/client/client.ts +2 -1
  39. package/src/lib/http/accept.ts +1 -0
  40. package/src/lib/http/middleware.ts +1 -1
  41. package/src/lib/http/response.ts +37 -78
  42. package/src/oauth-provider.ts +18 -10
  43. package/src/oauth-verifier.ts +2 -1
  44. package/src/output/send-web-page.ts +5 -3
  45. package/src/request/request-uri.ts +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-verifier.js","sourceRoot":"","sources":["../src/oauth-verifier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oauth-verifier.js","sourceRoot":"","sources":["../src/oauth-verifier.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { ServerResponse } from 'node:http';
2
2
  import { BuildDocumentOptions, Html } from '../lib/html/index.js';
3
+ import { WriteResponseOptions } from '../lib/http/response.js';
3
4
  export declare function declareBackendData(name: string, data: unknown): Html;
4
- export declare function sendWebPage(res: ServerResponse, { status, ...options }: BuildDocumentOptions & {
5
- status?: number;
6
- }): Promise<void>;
5
+ export type SendWebPageOptions = BuildDocumentOptions & WriteResponseOptions;
6
+ export declare function sendWebPage(res: ServerResponse, options: SendWebPageOptions): Promise<void>;
7
7
  //# sourceMappingURL=send-web-page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"send-web-page.d.ts","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE1C,OAAO,EAGL,oBAAoB,EACpB,IAAI,EAEL,MAAM,sBAAsB,CAAA;AAG7B,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,QAM7D;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,cAAc,EACnB,EAAE,MAAY,EAAE,GAAG,OAAO,EAAE,EAAE,oBAAoB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACvE,OAAO,CAAC,IAAI,CAAC,CAiCf"}
1
+ {"version":3,"file":"send-web-page.d.ts","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE1C,OAAO,EAGL,oBAAoB,EACpB,IAAI,EAEL,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAa,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAEzE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,QAM7D;AAED,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,GAAG,oBAAoB,CAAA;AAE5E,wBAAsB,WAAW,CAC/B,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAiCf"}
@@ -12,7 +12,7 @@ function declareBackendData(name, data) {
12
12
  // "readBackendData" in "src/assets/app/backend-data.ts".
13
13
  return (0, index_js_1.js) `window[${name}]=${data};document.currentScript.remove();`;
14
14
  }
15
- async function sendWebPage(res, { status = 200, ...options }) {
15
+ async function sendWebPage(res, options) {
16
16
  // @TODO: make these headers configurable (?)
17
17
  res.setHeader('Permissions-Policy', 'otp-credentials=*, document-domain=()');
18
18
  res.setHeader('Cross-Origin-Embedder-Policy', 'credentialless');
@@ -35,7 +35,7 @@ async function sendWebPage(res, { status = 200, ...options }) {
35
35
  `upgrade-insecure-requests`,
36
36
  ].join('; '));
37
37
  const html = (0, index_js_1.buildDocument)(options);
38
- return (0, response_js_1.writeHtml)(res, html.toString(), status);
38
+ return (0, response_js_1.writeHtml)(res, html.toString(), options);
39
39
  }
40
40
  function assetToHash(asset) {
41
41
  return asset instanceof index_js_1.Html
@@ -1 +1 @@
1
- {"version":3,"file":"send-web-page.js","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":";;AAYA,gDAMC;AAED,kCAoCC;AAxDD,6CAAwC;AAGxC,mDAM6B;AAC7B,yDAAmD;AAEnD,SAAgB,kBAAkB,CAAC,IAAY,EAAE,IAAa;IAC5D,8EAA8E;IAC9E,8EAA8E;IAC9E,8DAA8D;IAC9D,yDAAyD;IACzD,OAAO,IAAA,aAAE,EAAA,UAAU,IAAI,KAAK,IAAI,mCAAmC,CAAA;AACrE,CAAC;AAEM,KAAK,UAAU,WAAW,CAC/B,GAAmB,EACnB,EAAE,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,EAA8C;IAExE,6CAA6C;IAC7C,GAAG,CAAC,SAAS,CAAC,oBAAoB,EAAE,uCAAuC,CAAC,CAAA;IAC5E,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,gBAAgB,CAAC,CAAA;IAC/D,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,aAAa,CAAC,CAAA;IAC5D,GAAG,CAAC,SAAS,CAAC,4BAA4B,EAAE,aAAa,CAAC,CAAA;IAC1D,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;IAC/C,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAA;IACxC,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAA;IAClD,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAA;IACtC,GAAG,CAAC,SAAS,CAAC,2BAA2B,EAAE,kBAAkB,CAAC,CAAA;IAC9D,GAAG,CAAC,SAAS,CACX,yBAAyB,EACzB;QACE,oBAAoB;QACpB,wBAAwB;QACxB,oBAAoB;QACpB,YAAY,OAAO,CAAC,IAAI,EAAE,MAAM,IAAI,QAAQ,EAAE;QAC9C,qBACE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EACpE,EAAE;QACF,oBACE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EACnE,EAAE;QACF,6BAA6B;QAC7B,oBAAoB;QACpB,2BAA2B;KAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAA;IAED,MAAM,IAAI,GAAG,IAAA,wBAAa,EAAC,OAAO,CAAC,CAAA;IAEnC,OAAO,IAAA,uBAAS,EAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAA;AAChD,CAAC;AAED,SAAS,WAAW,CAAC,KAAsB;IACzC,OAAO,KAAK,YAAY,eAAI;QAC1B,CAAC,CAAC,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QAChE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAA;AAClB,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,WAAW,IAAI,GAAG,CAAA;AAC3B,CAAC"}
1
+ {"version":3,"file":"send-web-page.js","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":";;AAYA,gDAMC;AAID,kCAoCC;AA1DD,6CAAwC;AAGxC,mDAM6B;AAC7B,yDAAyE;AAEzE,SAAgB,kBAAkB,CAAC,IAAY,EAAE,IAAa;IAC5D,8EAA8E;IAC9E,8EAA8E;IAC9E,8DAA8D;IAC9D,yDAAyD;IACzD,OAAO,IAAA,aAAE,EAAA,UAAU,IAAI,KAAK,IAAI,mCAAmC,CAAA;AACrE,CAAC;AAIM,KAAK,UAAU,WAAW,CAC/B,GAAmB,EACnB,OAA2B;IAE3B,6CAA6C;IAC7C,GAAG,CAAC,SAAS,CAAC,oBAAoB,EAAE,uCAAuC,CAAC,CAAA;IAC5E,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,gBAAgB,CAAC,CAAA;IAC/D,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,aAAa,CAAC,CAAA;IAC5D,GAAG,CAAC,SAAS,CAAC,4BAA4B,EAAE,aAAa,CAAC,CAAA;IAC1D,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;IAC/C,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAA;IACxC,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAA;IAClD,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAA;IACtC,GAAG,CAAC,SAAS,CAAC,2BAA2B,EAAE,kBAAkB,CAAC,CAAA;IAC9D,GAAG,CAAC,SAAS,CACX,yBAAyB,EACzB;QACE,oBAAoB;QACpB,wBAAwB;QACxB,oBAAoB;QACpB,YAAY,OAAO,CAAC,IAAI,EAAE,MAAM,IAAI,QAAQ,EAAE;QAC9C,qBACE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EACpE,EAAE;QACF,oBACE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EACnE,EAAE;QACF,6BAA6B;QAC7B,oBAAoB;QACpB,2BAA2B;KAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAA;IAED,MAAM,IAAI,GAAG,IAAA,wBAAa,EAAC,OAAO,CAAC,CAAA;IAEnC,OAAO,IAAA,uBAAS,EAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAA;AACjD,CAAC;AAED,SAAS,WAAW,CAAC,KAAsB;IACzC,OAAO,KAAK,YAAY,eAAI;QAC1B,CAAC,CAAC,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QAChE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAA;AAClB,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,WAAW,IAAI,GAAG,CAAA;AAC3B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"request-uri.d.ts","sourceRoot":"","sources":["../../src/request/request-uri.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,SAAS,EAAmB,MAAM,iBAAiB,CAAA;AAE5D,eAAO,MAAM,kBAAkB,uCAAuC,CAAA;AAEtE,eAAO,MAAM,gBAAgB,sFAW1B,CAAA;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAEzD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,UAAU,CAEjE;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,CAGlE"}
1
+ {"version":3,"file":"request-uri.d.ts","sourceRoot":"","sources":["../../src/request/request-uri.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,SAAS,EAAmB,MAAM,iBAAiB,CAAA;AAE5D,eAAO,MAAM,kBAAkB,uCAAuC,CAAA;AAEtE,eAAO,MAAM,gBAAgB,sFAU1B,CAAA;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAEzD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,UAAU,CAEjE;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,CAGlE"}
@@ -8,7 +8,6 @@ const request_id_js_1 = require("./request-id.js");
8
8
  exports.REQUEST_URI_PREFIX = 'urn:ietf:params:oauth:request_uri:';
9
9
  exports.requestUriSchema = zod_1.z
10
10
  .string()
11
- .url()
12
11
  .refinement((data) => data.startsWith(exports.REQUEST_URI_PREFIX) &&
13
12
  request_id_js_1.requestIdSchema.safeParse(decodeRequestUri(data)).success, {
14
13
  code: zod_1.z.ZodIssueCode.custom,
@@ -1 +1 @@
1
- {"version":3,"file":"request-uri.js","sourceRoot":"","sources":["../../src/request/request-uri.ts"],"names":[],"mappings":";;;AAqBA,4CAEC;AAED,4CAGC;AA5BD,6BAAuB;AAEvB,mDAA4D;AAE/C,QAAA,kBAAkB,GAAG,oCAAoC,CAAA;AAEzD,QAAA,gBAAgB,GAAG,OAAC;KAC9B,MAAM,EAAE;KACR,GAAG,EAAE;KACL,UAAU,CACT,CAAC,IAAI,EAAsD,EAAE,CAC3D,IAAI,CAAC,UAAU,CAAC,0BAAkB,CAAC;IACnC,+BAAe,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAW,CAAC,CAAC,CAAC,OAAO,EAClE;IACE,IAAI,EAAE,OAAC,CAAC,YAAY,CAAC,MAAM;IAC3B,OAAO,EAAE,4BAA4B;CACtC,CACF,CAAA;AAIH,SAAgB,gBAAgB,CAAC,SAAoB;IACnD,OAAO,GAAG,0BAAkB,GAAG,kBAAkB,CAAC,SAAS,CAAc,EAAE,CAAA;AAC7E,CAAC;AAED,SAAgB,gBAAgB,CAAC,UAAsB;IACrD,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,0BAAkB,CAAC,MAAM,CAAC,CAAA;IAChE,OAAO,kBAAkB,CAAC,YAAY,CAAc,CAAA;AACtD,CAAC"}
1
+ {"version":3,"file":"request-uri.js","sourceRoot":"","sources":["../../src/request/request-uri.ts"],"names":[],"mappings":";;;AAoBA,4CAEC;AAED,4CAGC;AA3BD,6BAAuB;AAEvB,mDAA4D;AAE/C,QAAA,kBAAkB,GAAG,oCAAoC,CAAA;AAEzD,QAAA,gBAAgB,GAAG,OAAC;KAC9B,MAAM,EAAE;KACR,UAAU,CACT,CAAC,IAAI,EAAsD,EAAE,CAC3D,IAAI,CAAC,UAAU,CAAC,0BAAkB,CAAC;IACnC,+BAAe,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAW,CAAC,CAAC,CAAC,OAAO,EAClE;IACE,IAAI,EAAE,OAAC,CAAC,YAAY,CAAC,MAAM;IAC3B,OAAO,EAAE,4BAA4B;CACtC,CACF,CAAA;AAIH,SAAgB,gBAAgB,CAAC,SAAoB;IACnD,OAAO,GAAG,0BAAkB,GAAG,kBAAkB,CAAC,SAAS,CAAc,EAAE,CAAA;AAC7E,CAAC;AAED,SAAgB,gBAAgB,CAAC,UAAsB;IACrD,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,0BAAkB,CAAC,MAAM,CAAC,CAAA;IAChE,OAAO,kBAAkB,CAAC,YAAY,CAAc,CAAA;AACtD,CAAC"}
@@ -42,6 +42,7 @@ export declare const signedTokenPayloadSchema: z.ZodIntersection<z.ZodObject<{
42
42
  identifier: z.ZodOptional<z.ZodString>;
43
43
  privileges: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
44
44
  }, z.ZodTypeAny, "passthrough">>, "many">>>;
45
+ email: z.ZodOptional<z.ZodOptional<z.ZodString>>;
45
46
  auth_time: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
46
47
  acr: z.ZodOptional<z.ZodOptional<z.ZodString>>;
47
48
  name: z.ZodOptional<z.ZodOptional<z.ZodString>>;
@@ -58,7 +59,6 @@ export declare const signedTokenPayloadSchema: z.ZodIntersection<z.ZodObject<{
58
59
  zoneinfo: z.ZodOptional<z.ZodOptional<z.ZodString>>;
59
60
  locale: z.ZodOptional<z.ZodOptional<z.ZodString>>;
60
61
  updated_at: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
61
- email: z.ZodOptional<z.ZodOptional<z.ZodString>>;
62
62
  email_verified: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
63
63
  phone_number: z.ZodOptional<z.ZodOptional<z.ZodString>>;
64
64
  phone_number_verified: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
@@ -1393,6 +1393,7 @@ export declare const signedTokenPayloadSchema: z.ZodIntersection<z.ZodObject<{
1393
1393
  identifier: z.ZodOptional<z.ZodString>;
1394
1394
  privileges: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1395
1395
  }, z.ZodTypeAny, "passthrough">[] | undefined;
1396
+ email?: string | undefined;
1396
1397
  auth_time?: number | undefined;
1397
1398
  acr?: string | undefined;
1398
1399
  name?: string | undefined;
@@ -1409,7 +1410,6 @@ export declare const signedTokenPayloadSchema: z.ZodIntersection<z.ZodObject<{
1409
1410
  zoneinfo?: string | undefined;
1410
1411
  locale?: string | undefined;
1411
1412
  updated_at?: number | undefined;
1412
- email?: string | undefined;
1413
1413
  email_verified?: boolean | undefined;
1414
1414
  phone_number?: string | undefined;
1415
1415
  phone_number_verified?: boolean | undefined;
@@ -1548,6 +1548,7 @@ export declare const signedTokenPayloadSchema: z.ZodIntersection<z.ZodObject<{
1548
1548
  identifier: z.ZodOptional<z.ZodString>;
1549
1549
  privileges: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1550
1550
  }, z.ZodTypeAny, "passthrough">[] | undefined;
1551
+ email?: string | undefined;
1551
1552
  auth_time?: number | undefined;
1552
1553
  acr?: string | undefined;
1553
1554
  name?: string | undefined;
@@ -1564,7 +1565,6 @@ export declare const signedTokenPayloadSchema: z.ZodIntersection<z.ZodObject<{
1564
1565
  zoneinfo?: string | undefined;
1565
1566
  locale?: string | undefined;
1566
1567
  updated_at?: number | undefined;
1567
- email?: string | undefined;
1568
1568
  email_verified?: boolean | undefined;
1569
1569
  phone_number?: string | undefined;
1570
1570
  phone_number_verified?: boolean | undefined;
@@ -39,6 +39,7 @@ export declare class Signer {
39
39
  identifier: import("zod").ZodOptional<import("zod").ZodString>;
40
40
  privileges: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString, "many">>;
41
41
  }, import("zod").ZodTypeAny, "passthrough">[] | undefined;
42
+ email?: string | undefined;
42
43
  auth_time?: number | undefined;
43
44
  acr?: string | undefined;
44
45
  name?: string | undefined;
@@ -55,7 +56,6 @@ export declare class Signer {
55
56
  zoneinfo?: string | undefined;
56
57
  locale?: string | undefined;
57
58
  updated_at?: number | undefined;
58
- email?: string | undefined;
59
59
  email_verified?: boolean | undefined;
60
60
  phone_number?: string | undefined;
61
61
  phone_number_verified?: boolean | undefined;
@@ -38,6 +38,7 @@ export declare const tokenClaimsSchema: z.ZodIntersection<z.ZodObject<{
38
38
  identifier: z.ZodOptional<z.ZodString>;
39
39
  privileges: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
40
40
  }, z.ZodTypeAny, "passthrough">>, "many">>>;
41
+ email: z.ZodOptional<z.ZodOptional<z.ZodString>>;
41
42
  auth_time: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
42
43
  acr: z.ZodOptional<z.ZodOptional<z.ZodString>>;
43
44
  name: z.ZodOptional<z.ZodOptional<z.ZodString>>;
@@ -54,7 +55,6 @@ export declare const tokenClaimsSchema: z.ZodIntersection<z.ZodObject<{
54
55
  zoneinfo: z.ZodOptional<z.ZodOptional<z.ZodString>>;
55
56
  locale: z.ZodOptional<z.ZodOptional<z.ZodString>>;
56
57
  updated_at: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
57
- email: z.ZodOptional<z.ZodOptional<z.ZodString>>;
58
58
  email_verified: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
59
59
  phone_number: z.ZodOptional<z.ZodOptional<z.ZodString>>;
60
60
  phone_number_verified: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
@@ -1387,6 +1387,7 @@ export declare const tokenClaimsSchema: z.ZodIntersection<z.ZodObject<{
1387
1387
  identifier: z.ZodOptional<z.ZodString>;
1388
1388
  privileges: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1389
1389
  }, z.ZodTypeAny, "passthrough">[] | undefined;
1390
+ email?: string | undefined;
1390
1391
  auth_time?: number | undefined;
1391
1392
  acr?: string | undefined;
1392
1393
  name?: string | undefined;
@@ -1403,7 +1404,6 @@ export declare const tokenClaimsSchema: z.ZodIntersection<z.ZodObject<{
1403
1404
  zoneinfo?: string | undefined;
1404
1405
  locale?: string | undefined;
1405
1406
  updated_at?: number | undefined;
1406
- email?: string | undefined;
1407
1407
  email_verified?: boolean | undefined;
1408
1408
  phone_number?: string | undefined;
1409
1409
  phone_number_verified?: boolean | undefined;
@@ -1541,6 +1541,7 @@ export declare const tokenClaimsSchema: z.ZodIntersection<z.ZodObject<{
1541
1541
  identifier: z.ZodOptional<z.ZodString>;
1542
1542
  privileges: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1543
1543
  }, z.ZodTypeAny, "passthrough">[] | undefined;
1544
+ email?: string | undefined;
1544
1545
  auth_time?: number | undefined;
1545
1546
  acr?: string | undefined;
1546
1547
  name?: string | undefined;
@@ -1557,7 +1558,6 @@ export declare const tokenClaimsSchema: z.ZodIntersection<z.ZodObject<{
1557
1558
  zoneinfo?: string | undefined;
1558
1559
  locale?: string | undefined;
1559
1560
  updated_at?: number | undefined;
1560
- email?: string | undefined;
1561
1561
  email_verified?: boolean | undefined;
1562
1562
  phone_number?: string | undefined;
1563
1563
  phone_number_verified?: boolean | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/oauth-provider",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "license": "MIT",
5
5
  "description": "Generic OAuth2 and OpenID Connect provider for Node.js. Currently only supports features needed for Atproto.",
6
6
  "keywords": [
@@ -46,7 +46,7 @@
46
46
  "@atproto/common": "^0.4.4",
47
47
  "@atproto/jwk": "0.1.1",
48
48
  "@atproto/jwk-jose": "0.1.2",
49
- "@atproto/oauth-types": "0.2.0"
49
+ "@atproto/oauth-types": "0.2.1"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@rollup/plugin-commonjs": "^25.0.7",
@@ -41,6 +41,6 @@ export function authorizeAssetsMiddleware(): Middleware {
41
41
  res.setHeader('Cache-Control', 'public, max-age=31536000, immutable')
42
42
  }
43
43
 
44
- await writeStream(res, asset.createStream(), asset.type)
44
+ writeStream(res, asset.createStream(), { contentType: asset.type })
45
45
  }
46
46
  }
@@ -4,6 +4,7 @@ import {
4
4
  OAuthAuthorizationRequestParameters,
5
5
  OAuthClientCredentials,
6
6
  OAuthClientMetadata,
7
+ OAuthRedirectUri,
7
8
  } from '@atproto/oauth-types'
8
9
  import {
9
10
  UnsecuredJWT,
@@ -323,7 +324,7 @@ export class Client {
323
324
  return parameters
324
325
  }
325
326
 
326
- get defaultRedirectUri(): string | undefined {
327
+ get defaultRedirectUri(): OAuthRedirectUri | undefined {
327
328
  const { redirect_uris } = this.metadata
328
329
  return redirect_uris.length === 1 ? redirect_uris[0] : undefined
329
330
  }
@@ -39,6 +39,7 @@ type View<
39
39
  * }
40
40
  * )
41
41
  * )
42
+ * ```
42
43
  */
43
44
  export function acceptMiddleware<
44
45
  D,
@@ -95,7 +95,7 @@ export function createFinalHandler(
95
95
  res.setHeader('Content-Security-Policy', "default-src 'none'")
96
96
  res.setHeader('X-Content-Type-Options', 'nosniff')
97
97
 
98
- writeJson(res, payload, status)
98
+ writeJson(res, payload, { status })
99
99
  }
100
100
  }
101
101
 
@@ -1,6 +1,4 @@
1
- import { PassThrough, Readable, Transform } from 'node:stream'
2
- import { pipeline } from 'node:stream/promises'
3
- import { constants, createBrotliCompress, createGzip } from 'node:zlib'
1
+ import { Readable, pipeline } from 'node:stream'
4
2
 
5
3
  import { Handler, ServerResponse } from './types.js'
6
4
 
@@ -26,108 +24,69 @@ export function writeRedirect(
26
24
  res.writeHead(status, { Location: url }).end()
27
25
  }
28
26
 
29
- function negotiateEncoding(accept?: string | string[]) {
30
- if (accept?.includes('br')) return 'br'
31
- if (accept?.includes('gzip')) return 'gzip'
32
- return 'identity'
27
+ export type WriteResponseOptions = {
28
+ status?: number
29
+ contentType?: string
33
30
  }
34
31
 
35
- function getEncoder(encoding: string): Transform {
36
- switch (encoding) {
37
- case 'br':
38
- return createBrotliCompress({
39
- // Default quality is too slow
40
- params: { [constants.BROTLI_PARAM_QUALITY]: 5 },
41
- })
42
- case 'gzip':
43
- return createGzip()
44
- case 'identity':
45
- return new PassThrough()
46
- default:
47
- throw new Error(`Unsupported encoding: ${encoding}`)
48
- }
49
- }
50
-
51
- const ifString = (value: unknown): string | undefined =>
52
- typeof value === 'string' ? value : undefined
53
-
54
- export async function writeStream(
32
+ export function writeStream(
55
33
  res: ServerResponse,
56
34
  stream: Readable,
57
- contentType = ifString((stream as any).headers?.['content-type']) ||
58
- 'application/octet-stream',
59
- status = 200,
60
- ): Promise<void> {
35
+ {
36
+ status = 200,
37
+ contentType = 'application/octet-stream',
38
+ }: WriteResponseOptions = {},
39
+ ): void {
61
40
  res.statusCode = status
62
41
  res.setHeader('content-type', contentType)
63
- appendHeader(res, 'vary', 'accept-encoding')
64
-
65
- const encoding = negotiateEncoding(res.req.headers['accept-encoding'])
66
-
67
- res.setHeader('content-encoding', encoding)
68
- res.setHeader('transfer-encoding', 'chunked')
69
42
 
70
43
  if (res.req.method === 'HEAD') {
71
44
  res.end()
72
45
  stream.destroy()
73
- return
74
- }
75
-
76
- try {
77
- await pipeline(stream, getEncoder(encoding), res)
78
- } catch (err) {
79
- // Prevent the socket from being left open in a bad state
80
- res.socket?.destroy()
81
-
82
- if (err != null && typeof err === 'object') {
83
- // If an abort signal is used, we can consider this function's job successful
84
- if ('name' in err && err.name === 'AbortError') return
85
-
86
- // If the client closes the connection, we don't care about the error
87
- if ('code' in err && err.code === 'ERR_STREAM_PREMATURE_CLOSE') return
88
- }
89
-
90
- throw err
46
+ } else {
47
+ pipeline([stream, res], (_err: Error | null) => {
48
+ // The error will be propagated through the streams
49
+ })
91
50
  }
92
51
  }
93
52
 
94
- export async function writeBuffer(
53
+ export function writeBuffer(
95
54
  res: ServerResponse,
96
- buffer: Buffer,
97
- contentType?: string,
98
- status = 200,
99
- ): Promise<void> {
100
- const stream = Readable.from([buffer])
101
- return writeStream(res, stream, contentType, status)
55
+ chunk: string | Buffer,
56
+ {
57
+ status = 200,
58
+ contentType = 'application/octet-stream',
59
+ }: WriteResponseOptions = {},
60
+ ): void {
61
+ res.statusCode = status
62
+ res.setHeader('content-type', contentType)
63
+ res.end(chunk)
102
64
  }
103
65
 
104
- export async function writeJson(
66
+ export function writeJson(
105
67
  res: ServerResponse,
106
68
  payload: unknown,
107
- status = 200,
108
- contentType = 'application/json',
109
- ): Promise<void> {
69
+ { contentType = 'application/json', ...options }: WriteResponseOptions = {},
70
+ ): void {
110
71
  const buffer = Buffer.from(JSON.stringify(payload))
111
- return writeBuffer(res, buffer, contentType, status)
72
+ writeBuffer(res, buffer, { ...options, contentType })
112
73
  }
113
74
 
114
- export function staticJsonHandler(
75
+ export function staticJsonMiddleware(
115
76
  value: unknown,
116
- contentType = 'application/json',
117
- status = 200,
77
+ { contentType = 'application/json', ...options }: WriteResponseOptions = {},
118
78
  ): Handler<unknown> {
119
79
  const buffer = Buffer.from(JSON.stringify(value))
120
- return function (req, res, next) {
121
- void writeBuffer(res, buffer, contentType, status).catch(next)
80
+ const staticOptions: WriteResponseOptions = { ...options, contentType }
81
+ return function (req, res) {
82
+ writeBuffer(res, buffer, staticOptions)
122
83
  }
123
84
  }
124
85
 
125
- export async function writeHtml(
86
+ export function writeHtml(
126
87
  res: ServerResponse,
127
88
  html: Buffer | string,
128
- status = 200,
129
- contentType = 'text/html',
130
- ): Promise<void> {
131
- const buffer = Buffer.isBuffer(html) ? html : Buffer.from(html)
132
- return writeBuffer(res, buffer, contentType, status)
89
+ { contentType = 'text/html', ...options }: WriteResponseOptions = {},
90
+ ): void {
91
+ writeBuffer(res, html, { ...options, contentType })
133
92
  }
@@ -29,6 +29,8 @@ import {
29
29
  oauthTokenIdentificationSchema,
30
30
  oauthTokenRequestSchema,
31
31
  } from '@atproto/oauth-types'
32
+ import { mediaType } from '@hapi/accept'
33
+ import createHttpError from 'http-errors'
32
34
  import type { Redis, RedisOptions } from 'ioredis'
33
35
  import z, { ZodError } from 'zod'
34
36
 
@@ -75,7 +77,7 @@ import {
75
77
  combineMiddlewares,
76
78
  parseHttpRequest,
77
79
  setupCsrfToken,
78
- staticJsonHandler,
80
+ staticJsonMiddleware,
79
81
  validateCsrfToken,
80
82
  validateFetchDest,
81
83
  validateFetchMode,
@@ -1028,7 +1030,7 @@ export class OAuthProvider extends OAuthVerifier {
1028
1030
  res.setHeader('Cache-Control', 'max-age=300')
1029
1031
  next()
1030
1032
  },
1031
- staticJsonHandler(json),
1033
+ staticJsonMiddleware(json),
1032
1034
  ])
1033
1035
 
1034
1036
  /**
@@ -1056,9 +1058,18 @@ export class OAuthProvider extends OAuthVerifier {
1056
1058
  }
1057
1059
 
1058
1060
  try {
1061
+ // Ensure we can agree on a content encoding & type before starting to
1062
+ // build the JSON response.
1063
+ if (!mediaType(req.headers['accept'], ['application/json'])) {
1064
+ throw createHttpError(406, 'Unsupported media type')
1065
+ }
1066
+
1059
1067
  const result = await buildJson.call(this, req, res)
1060
- if (result !== undefined) writeJson(res, result, status)
1061
- else if (!res.headersSent) res.writeHead(status ?? 204).end()
1068
+ if (result !== undefined) {
1069
+ writeJson(res, result, { status })
1070
+ } else if (!res.headersSent) {
1071
+ res.writeHead(status ?? 204).end()
1072
+ }
1062
1073
  } catch (err) {
1063
1074
  if (!res.headersSent) {
1064
1075
  if (err instanceof WWWAuthenticateError) {
@@ -1067,7 +1078,9 @@ export class OAuthProvider extends OAuthVerifier {
1067
1078
  res.appendHeader('Access-Control-Expose-Headers', name)
1068
1079
  }
1069
1080
 
1070
- writeJson(res, buildErrorPayload(err), buildErrorStatus(err))
1081
+ const payload = buildErrorPayload(err)
1082
+ const status = buildErrorStatus(err)
1083
+ writeJson(res, payload, { status })
1071
1084
  } else {
1072
1085
  res.destroy()
1073
1086
  }
@@ -1096,11 +1109,6 @@ export class OAuthProvider extends OAuthVerifier {
1096
1109
  validateSameOrigin(req, res, issuerOrigin)
1097
1110
 
1098
1111
  await handler.call(this, req, res)
1099
-
1100
- // Should never happen (fool proofing)
1101
- if (!res.headersSent) {
1102
- throw new Error('Navigation handler did not send a response')
1103
- }
1104
1112
  } catch (err) {
1105
1113
  onError?.(
1106
1114
  req,
@@ -1,6 +1,7 @@
1
1
  import { Key, Keyset, isSignedJwt } from '@atproto/jwk'
2
2
  import {
3
3
  OAuthAccessToken,
4
+ OAuthIssuerIdentifier,
4
5
  OAuthTokenType,
5
6
  oauthIssuerIdentifierSchema,
6
7
  } from '@atproto/oauth-types'
@@ -77,7 +78,7 @@ export {
77
78
  }
78
79
 
79
80
  export class OAuthVerifier {
80
- public readonly issuer: string
81
+ public readonly issuer: OAuthIssuerIdentifier
81
82
  public readonly keyset: Keyset
82
83
 
83
84
  protected readonly accessTokenType: AccessTokenType
@@ -8,7 +8,7 @@ import {
8
8
  Html,
9
9
  js,
10
10
  } from '../lib/html/index.js'
11
- import { writeHtml } from '../lib/http/response.js'
11
+ import { writeHtml, WriteResponseOptions } from '../lib/http/response.js'
12
12
 
13
13
  export function declareBackendData(name: string, data: unknown) {
14
14
  // The script tag is removed after the data is assigned to the global variable
@@ -18,9 +18,11 @@ export function declareBackendData(name: string, data: unknown) {
18
18
  return js`window[${name}]=${data};document.currentScript.remove();`
19
19
  }
20
20
 
21
+ export type SendWebPageOptions = BuildDocumentOptions & WriteResponseOptions
22
+
21
23
  export async function sendWebPage(
22
24
  res: ServerResponse,
23
- { status = 200, ...options }: BuildDocumentOptions & { status?: number },
25
+ options: SendWebPageOptions,
24
26
  ): Promise<void> {
25
27
  // @TODO: make these headers configurable (?)
26
28
  res.setHeader('Permissions-Policy', 'otp-credentials=*, document-domain=()')
@@ -53,7 +55,7 @@ export async function sendWebPage(
53
55
 
54
56
  const html = buildDocument(options)
55
57
 
56
- return writeHtml(res, html.toString(), status)
58
+ return writeHtml(res, html.toString(), options)
57
59
  }
58
60
 
59
61
  function assetToHash(asset: Html | AssetRef): string {
@@ -6,7 +6,6 @@ export const REQUEST_URI_PREFIX = 'urn:ietf:params:oauth:request_uri:'
6
6
 
7
7
  export const requestUriSchema = z
8
8
  .string()
9
- .url()
10
9
  .refinement(
11
10
  (data): data is `${typeof REQUEST_URI_PREFIX}${RequestId}` =>
12
11
  data.startsWith(REQUEST_URI_PREFIX) &&