@atproto/oauth-provider 0.2.6 → 0.2.8

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 (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":";;;AAAA,sCAAuD;AAyErD,uFAzEY,YAAM,OAyEZ;AAxER,sDAI6B;AAG7B,8EAAqE;AA+DnE,gGA/DO,sCAAe,OA+DP;AA9DjB,4DAAwE;AACxE,wDAAgD;AA8D9C,0FA9DO,yBAAS,OA8DP;AA7DX,sFAA4E;AAC5E,4EAAmE;AACnE,8EAAoE;AACpE,kFAAyE;AACzE,gFAA6E;AAE7E,kEAA0D;AAC1D,4EAAmE;AACnE,0EAAiE;AAEjE,kDAA2C;AAC3C,2EAIuC;AAoDvC,MAAa,aAAa;IACR,MAAM,CAAQ;IACd,MAAM,CAAQ;IAEX,eAAe,CAAiB;IAChC,WAAW,CAAa;IACxB,aAAa,CAAe;IAC5B,MAAM,CAAQ;IAEjC,YAAY,EACV,KAAK,EACL,MAAM,EACN,MAAM,EACN,WAAW,GAAG,KAAK,IAAI,IAAI;QACzB,CAAC,CAAC,IAAI,wCAAgB,CAAC,EAAE,KAAK,EAAE,CAAC;QACjC,CAAC,CAAC,IAAI,0CAAiB,EAAE,EAC3B,eAAe,GAAG,sCAAe,CAAC,GAAG,EAErC,GAAG,cAAc,EACI;QACrB,MAAM,YAAY,GAAG,yCAA2B,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAC9D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAA;QAEvC,oCAAoC;QACpC,IAAI,SAAS,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;YAC/B,MAAM,IAAI,SAAS,CACjB,yDAAyD,SAAS,GAAG,CACtE,CAAA;QACH,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,YAAY,CAAA;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,YAAY,YAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,YAAM,CAAC,MAAM,CAAC,CAAA;QAEpE,IAAI,CAAC,eAAe,GAAG,eAAe,CAAA;QACtC,IAAI,CAAC,WAAW,GAAG,IAAI,6BAAW,CAAC,cAAc,CAAC,CAAA;QAClD,IAAI,CAAC,aAAa,GAAG,IAAI,iCAAa,CAAC,WAAW,CAAC,CAAA;QACnD,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACpD,CAAC;IAEM,aAAa;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAA;IACrC,CAAC;IAEM,KAAK,CAAC,cAAc,CACzB,KAAc,EACd,GAAW,EACX,GAAiB,EACjB,WAAoB;QAEpB,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAEpC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CACxD,KAAK,EACL,GAAG,EACH,GAAG,EACH,WAAW,CACZ,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC/D,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,mDAAqB,CAAC,8BAA8B,CAAC,CAAA;QAE5E,OAAO,GAAG,CAAA;IACZ,CAAC;IAES,sBAAsB,CAC9B,SAAyB,EACzB,eAAgC;QAEhC,IACE,IAAI,CAAC,eAAe,KAAK,sCAAe,CAAC,IAAI;YAC7C,IAAI,CAAC,eAAe,KAAK,eAAe,EACxC,CAAC;YACD,MAAM,IAAI,0CAAiB,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAA;QAC9D,CAAC;IACH,CAAC;IAES,KAAK,CAAC,iBAAiB,CAC/B,SAAyB,EACzB,KAAuB,EACvB,OAAsB,EACtB,aAAwC;QAExC,IAAI,CAAC,IAAA,iBAAW,EAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,0CAAiB,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAA;QAC3D,CAAC;QAED,IAAI,CAAC,sBAAsB,CAAC,SAAS,EAAE,sCAAe,CAAC,GAAG,CAAC,CAAA;QAE3D,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM;aAClC,iBAAiB,CAAC,KAAK,CAAC;aACxB,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,MAAM,0CAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QAC9C,CAAC,CAAC,CAAA;QAEJ,OAAO,IAAA,0CAAiB,EACtB,KAAK,EACL,OAAO,CAAC,GAAG,EACX,SAAS,EACT,OAAO,EACP,OAAO,EACP,aAAa,CACd,CAAA;IACH,CAAC;IAEM,KAAK,CAAC,mBAAmB,CAC9B,MAAc,EACd,GAAQ,EACR,OAGC,EACD,aAAwC;QAExC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,IAAA,kDAAwB,EAAC,OAAO,CAAC,aAAa,CAAC,CAAA;QAC1E,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CACvC,OAAO,CAAC,IAAI,EACZ,MAAM,EACN,GAAG,EACH,KAAK,CACN,CAAA;YAED,IAAI,SAAS,KAAK,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;gBACrC,MAAM,IAAI,mDAAqB,CAAC,qBAAqB,CAAC,CAAA;YACxD,CAAC;YAED,OAAO,MAAM,IAAI,CAAC,iBAAiB,CACjC,SAAS,EACT,KAAK,EACL,OAAO,EACP,aAAa,CACd,CAAA;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,2CAAiB;gBAAE,MAAM,GAAG,CAAC,sBAAsB,EAAE,CAAA;YACxE,IAAI,GAAG,YAAY,gDAAoB;gBAAE,MAAM,GAAG,CAAA;YAElD,MAAM,0CAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC;CACF;AA3ID,sCA2IC"}
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) &&