@atproto/oauth-provider 0.16.5 → 0.17.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.
Files changed (321) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/access-token/access-token-mode.js +2 -5
  3. package/dist/access-token/access-token-mode.js.map +1 -1
  4. package/dist/account/account-manager.js +25 -33
  5. package/dist/account/account-manager.js.map +1 -1
  6. package/dist/account/account-store.js +11 -32
  7. package/dist/account/account-store.js.map +1 -1
  8. package/dist/account/sign-in-data.js +9 -12
  9. package/dist/account/sign-in-data.js.map +1 -1
  10. package/dist/account/sign-up-input.js +14 -17
  11. package/dist/account/sign-up-input.js.map +1 -1
  12. package/dist/client/client-auth.js +1 -2
  13. package/dist/client/client-data.js +1 -2
  14. package/dist/client/client-id.js +2 -5
  15. package/dist/client/client-id.js.map +1 -1
  16. package/dist/client/client-info.js +1 -2
  17. package/dist/client/client-manager.js +86 -97
  18. package/dist/client/client-manager.js.map +1 -1
  19. package/dist/client/client-store.js +7 -26
  20. package/dist/client/client-store.js.map +1 -1
  21. package/dist/client/client-utils.js +10 -14
  22. package/dist/client/client-utils.js.map +1 -1
  23. package/dist/client/client.js +43 -53
  24. package/dist/client/client.js.map +1 -1
  25. package/dist/constants.js +28 -31
  26. package/dist/constants.js.map +1 -1
  27. package/dist/customization/branding.js +8 -11
  28. package/dist/customization/branding.js.map +1 -1
  29. package/dist/customization/build-customization-css.js +8 -11
  30. package/dist/customization/build-customization-css.js.map +1 -1
  31. package/dist/customization/build-customization-data.js +1 -4
  32. package/dist/customization/build-customization-data.js.map +1 -1
  33. package/dist/customization/colors.js +11 -14
  34. package/dist/customization/colors.js.map +1 -1
  35. package/dist/customization/customization.js +8 -11
  36. package/dist/customization/customization.js.map +1 -1
  37. package/dist/customization/links.js +7 -10
  38. package/dist/customization/links.js.map +1 -1
  39. package/dist/device/device-data.js +7 -10
  40. package/dist/device/device-data.js.map +1 -1
  41. package/dist/device/device-id.js +11 -16
  42. package/dist/device/device-id.js.map +1 -1
  43. package/dist/device/device-manager.js +32 -38
  44. package/dist/device/device-manager.js.map +1 -1
  45. package/dist/device/device-store.js +7 -25
  46. package/dist/device/device-store.js.map +1 -1
  47. package/dist/device/session-id.js +9 -13
  48. package/dist/device/session-id.js.map +1 -1
  49. package/dist/dpop/dpop-manager.d.ts +3 -3
  50. package/dist/dpop/dpop-manager.js +38 -43
  51. package/dist/dpop/dpop-manager.js.map +1 -1
  52. package/dist/dpop/dpop-nonce.d.ts +2 -2
  53. package/dist/dpop/dpop-nonce.d.ts.map +1 -1
  54. package/dist/dpop/dpop-nonce.js +14 -18
  55. package/dist/dpop/dpop-nonce.js.map +1 -1
  56. package/dist/dpop/dpop-proof.js +1 -2
  57. package/dist/errors/access-denied-error.js +2 -6
  58. package/dist/errors/access-denied-error.js.map +1 -1
  59. package/dist/errors/account-selection-required-error.js +2 -6
  60. package/dist/errors/account-selection-required-error.js.map +1 -1
  61. package/dist/errors/authorization-error.js +7 -12
  62. package/dist/errors/authorization-error.js.map +1 -1
  63. package/dist/errors/consent-required-error.js +2 -6
  64. package/dist/errors/consent-required-error.js.map +1 -1
  65. package/dist/errors/error-parser.js +14 -18
  66. package/dist/errors/error-parser.js.map +1 -1
  67. package/dist/errors/handle-unavailable-error.js +2 -7
  68. package/dist/errors/handle-unavailable-error.js.map +1 -1
  69. package/dist/errors/invalid-authorization-details-error.js +2 -6
  70. package/dist/errors/invalid-authorization-details-error.js.map +1 -1
  71. package/dist/errors/invalid-client-error.js +2 -6
  72. package/dist/errors/invalid-client-error.js.map +1 -1
  73. package/dist/errors/invalid-client-id-error.js +2 -6
  74. package/dist/errors/invalid-client-id-error.js.map +1 -1
  75. package/dist/errors/invalid-client-metadata-error.js +7 -11
  76. package/dist/errors/invalid-client-metadata-error.js.map +1 -1
  77. package/dist/errors/invalid-credentials-error.js +2 -7
  78. package/dist/errors/invalid-credentials-error.js.map +1 -1
  79. package/dist/errors/invalid-dpop-key-binding-error.js +2 -6
  80. package/dist/errors/invalid-dpop-key-binding-error.js.map +1 -1
  81. package/dist/errors/invalid-dpop-proof-error.js +2 -6
  82. package/dist/errors/invalid-dpop-proof-error.js.map +1 -1
  83. package/dist/errors/invalid-grant-error.js +2 -6
  84. package/dist/errors/invalid-grant-error.js.map +1 -1
  85. package/dist/errors/invalid-invite-code-error.d.ts +1 -1
  86. package/dist/errors/invalid-invite-code-error.d.ts.map +1 -1
  87. package/dist/errors/invalid-invite-code-error.js +2 -6
  88. package/dist/errors/invalid-invite-code-error.js.map +1 -1
  89. package/dist/errors/invalid-redirect-uri-error.js +2 -6
  90. package/dist/errors/invalid-redirect-uri-error.js.map +1 -1
  91. package/dist/errors/invalid-request-error.js +3 -7
  92. package/dist/errors/invalid-request-error.js.map +1 -1
  93. package/dist/errors/invalid-scope-error.js +2 -6
  94. package/dist/errors/invalid-scope-error.js.map +1 -1
  95. package/dist/errors/invalid-token-error.js +10 -15
  96. package/dist/errors/invalid-token-error.js.map +1 -1
  97. package/dist/errors/login-required-error.js +2 -6
  98. package/dist/errors/login-required-error.js.map +1 -1
  99. package/dist/errors/oauth-error.js +1 -9
  100. package/dist/errors/oauth-error.js.map +1 -1
  101. package/dist/errors/second-authentication-factor-required-error.js +2 -8
  102. package/dist/errors/second-authentication-factor-required-error.js.map +1 -1
  103. package/dist/errors/unauthorized-client-error.js +2 -6
  104. package/dist/errors/unauthorized-client-error.js.map +1 -1
  105. package/dist/errors/use-dpop-nonce-error.js +4 -8
  106. package/dist/errors/use-dpop-nonce-error.js.map +1 -1
  107. package/dist/errors/www-authenticate-error.js +4 -9
  108. package/dist/errors/www-authenticate-error.js.map +1 -1
  109. package/dist/index.js +14 -30
  110. package/dist/index.js.map +1 -1
  111. package/dist/lexicon/lexicon-data.js +1 -2
  112. package/dist/lexicon/lexicon-getter.js +6 -10
  113. package/dist/lexicon/lexicon-getter.js.map +1 -1
  114. package/dist/lexicon/lexicon-manager.js +10 -30
  115. package/dist/lexicon/lexicon-manager.js.map +1 -1
  116. package/dist/lexicon/lexicon-store.js +5 -10
  117. package/dist/lexicon/lexicon-store.js.map +1 -1
  118. package/dist/lib/csp/index.js +3 -8
  119. package/dist/lib/csp/index.js.map +1 -1
  120. package/dist/lib/hcaptcha.js +33 -43
  121. package/dist/lib/hcaptcha.js.map +1 -1
  122. package/dist/lib/html/build-document.js +19 -24
  123. package/dist/lib/html/build-document.js.map +1 -1
  124. package/dist/lib/html/escapers.js +10 -16
  125. package/dist/lib/html/escapers.js.map +1 -1
  126. package/dist/lib/html/html.js +1 -5
  127. package/dist/lib/html/html.js.map +1 -1
  128. package/dist/lib/html/hydration-data.js +6 -10
  129. package/dist/lib/html/hydration-data.js.map +1 -1
  130. package/dist/lib/html/index.js +3 -19
  131. package/dist/lib/html/index.js.map +1 -1
  132. package/dist/lib/html/tags.js +14 -23
  133. package/dist/lib/html/tags.js.map +1 -1
  134. package/dist/lib/html/util.js +1 -4
  135. package/dist/lib/html/util.js.map +1 -1
  136. package/dist/lib/http/accept.d.ts.map +1 -1
  137. package/dist/lib/http/accept.js +8 -8
  138. package/dist/lib/http/accept.js.map +1 -1
  139. package/dist/lib/http/context.js +1 -4
  140. package/dist/lib/http/context.js.map +1 -1
  141. package/dist/lib/http/headers.js +1 -4
  142. package/dist/lib/http/headers.js.map +1 -1
  143. package/dist/lib/http/index.js +10 -26
  144. package/dist/lib/http/index.js.map +1 -1
  145. package/dist/lib/http/method.js +1 -4
  146. package/dist/lib/http/method.js.map +1 -1
  147. package/dist/lib/http/middleware.js +11 -17
  148. package/dist/lib/http/middleware.js.map +1 -1
  149. package/dist/lib/http/parser.js +13 -20
  150. package/dist/lib/http/parser.js.map +1 -1
  151. package/dist/lib/http/path.js +1 -4
  152. package/dist/lib/http/path.js.map +1 -1
  153. package/dist/lib/http/request.d.ts.map +1 -1
  154. package/dist/lib/http/request.js +32 -47
  155. package/dist/lib/http/request.js.map +1 -1
  156. package/dist/lib/http/response.js +14 -27
  157. package/dist/lib/http/response.js.map +1 -1
  158. package/dist/lib/http/route.js +9 -12
  159. package/dist/lib/http/route.js.map +1 -1
  160. package/dist/lib/http/router.js +8 -13
  161. package/dist/lib/http/router.js.map +1 -1
  162. package/dist/lib/http/security-headers.js +10 -15
  163. package/dist/lib/http/security-headers.js.map +1 -1
  164. package/dist/lib/http/stream.js +12 -20
  165. package/dist/lib/http/stream.js.map +1 -1
  166. package/dist/lib/http/types.js +1 -2
  167. package/dist/lib/http/url.js +1 -4
  168. package/dist/lib/http/url.js.map +1 -1
  169. package/dist/lib/nsid.js +4 -8
  170. package/dist/lib/nsid.js.map +1 -1
  171. package/dist/lib/redis.js +4 -7
  172. package/dist/lib/redis.js.map +1 -1
  173. package/dist/lib/util/authorization-header.js +11 -15
  174. package/dist/lib/util/authorization-header.js.map +1 -1
  175. package/dist/lib/util/cast.js +3 -8
  176. package/dist/lib/util/cast.js.map +1 -1
  177. package/dist/lib/util/color.js +23 -32
  178. package/dist/lib/util/color.js.map +1 -1
  179. package/dist/lib/util/crypto.js +5 -10
  180. package/dist/lib/util/crypto.js.map +1 -1
  181. package/dist/lib/util/date.js +2 -6
  182. package/dist/lib/util/date.js.map +1 -1
  183. package/dist/lib/util/error.js +5 -8
  184. package/dist/lib/util/error.js.map +1 -1
  185. package/dist/lib/util/function.js +3 -8
  186. package/dist/lib/util/function.js.map +1 -1
  187. package/dist/lib/util/locale.js +3 -6
  188. package/dist/lib/util/locale.js.map +1 -1
  189. package/dist/lib/util/object.js +1 -4
  190. package/dist/lib/util/object.js.map +1 -1
  191. package/dist/lib/util/redirect-uri.js +3 -6
  192. package/dist/lib/util/redirect-uri.js.map +1 -1
  193. package/dist/lib/util/time.js +5 -9
  194. package/dist/lib/util/time.js.map +1 -1
  195. package/dist/lib/util/type.d.ts.map +1 -1
  196. package/dist/lib/util/type.js +1 -5
  197. package/dist/lib/util/type.js.map +1 -1
  198. package/dist/lib/util/ui8.js +3 -8
  199. package/dist/lib/util/ui8.js.map +1 -1
  200. package/dist/lib/util/well-known.js +1 -4
  201. package/dist/lib/util/well-known.js.map +1 -1
  202. package/dist/lib/util/zod-error.js +4 -8
  203. package/dist/lib/util/zod-error.js.map +1 -1
  204. package/dist/lib/write-form-redirect.js +9 -12
  205. package/dist/lib/write-form-redirect.js.map +1 -1
  206. package/dist/lib/write-html.js +12 -15
  207. package/dist/lib/write-html.js.map +1 -1
  208. package/dist/metadata/build-metadata.js +9 -12
  209. package/dist/metadata/build-metadata.js.map +1 -1
  210. package/dist/oauth-client.js +2 -18
  211. package/dist/oauth-client.js.map +1 -1
  212. package/dist/oauth-dpop.js +2 -18
  213. package/dist/oauth-dpop.js.map +1 -1
  214. package/dist/oauth-errors.js +24 -42
  215. package/dist/oauth-errors.js.map +1 -1
  216. package/dist/oauth-hooks.js +8 -15
  217. package/dist/oauth-hooks.js.map +1 -1
  218. package/dist/oauth-middleware.js +13 -16
  219. package/dist/oauth-middleware.js.map +1 -1
  220. package/dist/oauth-provider.js +108 -125
  221. package/dist/oauth-provider.js.map +1 -1
  222. package/dist/oauth-store.js +7 -23
  223. package/dist/oauth-store.js.map +1 -1
  224. package/dist/oauth-verifier.js +41 -53
  225. package/dist/oauth-verifier.js.map +1 -1
  226. package/dist/oidc/sub.js +2 -5
  227. package/dist/oidc/sub.js.map +1 -1
  228. package/dist/replay/replay-manager.js +6 -11
  229. package/dist/replay/replay-manager.js.map +1 -1
  230. package/dist/replay/replay-store-memory.js +5 -7
  231. package/dist/replay/replay-store-memory.js.map +1 -1
  232. package/dist/replay/replay-store-redis.js +3 -8
  233. package/dist/replay/replay-store-redis.js.map +1 -1
  234. package/dist/replay/replay-store.js +3 -8
  235. package/dist/replay/replay-store.js.map +1 -1
  236. package/dist/request/code.js +10 -15
  237. package/dist/request/code.js.map +1 -1
  238. package/dist/request/request-data.js +1 -5
  239. package/dist/request/request-data.js.map +1 -1
  240. package/dist/request/request-id.js +9 -13
  241. package/dist/request/request-id.js.map +1 -1
  242. package/dist/request/request-manager.js +61 -71
  243. package/dist/request/request-manager.js.map +1 -1
  244. package/dist/request/request-store.js +9 -27
  245. package/dist/request/request-store.js.map +1 -1
  246. package/dist/request/request-uri.js +17 -23
  247. package/dist/request/request-uri.js.map +1 -1
  248. package/dist/result/authorization-redirect-parameters.js +1 -2
  249. package/dist/result/authorization-result-authorize-page.js +1 -2
  250. package/dist/result/authorization-result-redirect.js +1 -2
  251. package/dist/router/assets/assets-manifest.d.ts.map +1 -1
  252. package/dist/router/assets/assets-manifest.js +14 -15
  253. package/dist/router/assets/assets-manifest.js.map +1 -1
  254. package/dist/router/assets/assets.d.ts.map +1 -1
  255. package/dist/router/assets/assets.js +25 -27
  256. package/dist/router/assets/assets.js.map +1 -1
  257. package/dist/router/assets/csrf.js +16 -25
  258. package/dist/router/assets/csrf.js.map +1 -1
  259. package/dist/router/assets/send-account-page.js +3 -6
  260. package/dist/router/assets/send-account-page.js.map +1 -1
  261. package/dist/router/assets/send-authorization-page.js +3 -6
  262. package/dist/router/assets/send-authorization-page.js.map +1 -1
  263. package/dist/router/assets/send-cookie-error-page.js +3 -6
  264. package/dist/router/assets/send-cookie-error-page.js.map +1 -1
  265. package/dist/router/assets/send-error-page.js +6 -9
  266. package/dist/router/assets/send-error-page.js.map +1 -1
  267. package/dist/router/assets/send-redirect.js +12 -20
  268. package/dist/router/assets/send-redirect.js.map +1 -1
  269. package/dist/router/create-account-page-middleware.js +11 -14
  270. package/dist/router/create-account-page-middleware.js.map +1 -1
  271. package/dist/router/create-api-middleware.js +83 -90
  272. package/dist/router/create-api-middleware.js.map +1 -1
  273. package/dist/router/create-authorization-page-middleware.js +43 -46
  274. package/dist/router/create-authorization-page-middleware.js.map +1 -1
  275. package/dist/router/create-oauth-middleware.js +31 -34
  276. package/dist/router/create-oauth-middleware.js.map +1 -1
  277. package/dist/router/error-handler.js +1 -2
  278. package/dist/router/middleware-options.js +1 -2
  279. package/dist/signer/access-token-payload.js +12 -15
  280. package/dist/signer/access-token-payload.js.map +1 -1
  281. package/dist/signer/api-token-payload.js +8 -11
  282. package/dist/signer/api-token-payload.js.map +1 -1
  283. package/dist/signer/signer.js +11 -17
  284. package/dist/signer/signer.js.map +1 -1
  285. package/dist/token/refresh-token.js +10 -15
  286. package/dist/token/refresh-token.js.map +1 -1
  287. package/dist/token/token-claims.js +1 -2
  288. package/dist/token/token-data.js +1 -2
  289. package/dist/token/token-id.js +10 -15
  290. package/dist/token/token-id.js.map +1 -1
  291. package/dist/token/token-manager.js +40 -51
  292. package/dist/token/token-manager.js.map +1 -1
  293. package/dist/token/token-store.js +7 -25
  294. package/dist/token/token-store.js.map +1 -1
  295. package/dist/types/authorization-response-error.js +8 -12
  296. package/dist/types/authorization-response-error.js.map +1 -1
  297. package/dist/types/color-hue.js +2 -5
  298. package/dist/types/color-hue.js.map +1 -1
  299. package/dist/types/email-otp.js +2 -5
  300. package/dist/types/email-otp.js.map +1 -1
  301. package/dist/types/email.js +6 -9
  302. package/dist/types/email.js.map +1 -1
  303. package/dist/types/handle.js +6 -9
  304. package/dist/types/handle.js.map +1 -1
  305. package/dist/types/invite-code.js +2 -5
  306. package/dist/types/invite-code.js.map +1 -1
  307. package/dist/types/par-response-error.js +5 -9
  308. package/dist/types/par-response-error.js.map +1 -1
  309. package/dist/types/password.js +3 -6
  310. package/dist/types/password.js.map +1 -1
  311. package/dist/types/rgb-color.js +7 -10
  312. package/dist/types/rgb-color.js.map +1 -1
  313. package/package.json +20 -22
  314. package/src/dpop/dpop-nonce.ts +1 -1
  315. package/src/errors/invalid-invite-code-error.ts +1 -1
  316. package/src/lib/http/accept.ts +4 -1
  317. package/src/lib/http/request.ts +4 -1
  318. package/src/lib/util/type.ts +0 -1
  319. package/src/router/assets/assets-manifest.ts +3 -1
  320. package/src/router/assets/assets.ts +2 -0
  321. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,29 +1,24 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ReplayManager = void 0;
4
- const constants_js_1 = require("../constants.js");
1
+ import { CLIENT_ASSERTION_MAX_AGE, CODE_CHALLENGE_REPLAY_TIMEFRAME, DPOP_NONCE_MAX_AGE, JAR_MAX_AGE, } from '../constants.js';
5
2
  const SECURITY_RATIO = 1.1; // 10% extra time for security
6
3
  const asTimeFrame = (timeFrame) => Math.ceil(timeFrame * SECURITY_RATIO);
7
- class ReplayManager {
8
- replayStore;
4
+ export class ReplayManager {
9
5
  constructor(replayStore) {
10
6
  this.replayStore = replayStore;
11
7
  }
12
8
  async uniqueAuth(jti, clientId, exp) {
13
9
  const timeFrame = exp == null
14
- ? asTimeFrame(constants_js_1.CLIENT_ASSERTION_MAX_AGE)
10
+ ? asTimeFrame(CLIENT_ASSERTION_MAX_AGE)
15
11
  : exp * 1000 - Date.now();
16
12
  return this.replayStore.unique(`Auth@${clientId}`, jti, timeFrame);
17
13
  }
18
14
  async uniqueJar(jti, clientId) {
19
- return this.replayStore.unique(`JAR@${clientId}`, jti, asTimeFrame(constants_js_1.JAR_MAX_AGE));
15
+ return this.replayStore.unique(`JAR@${clientId}`, jti, asTimeFrame(JAR_MAX_AGE));
20
16
  }
21
17
  async uniqueDpop(jti, clientId) {
22
- return this.replayStore.unique(clientId ? `DPoP@${clientId}` : `DPoP`, jti, asTimeFrame(constants_js_1.DPOP_NONCE_MAX_AGE));
18
+ return this.replayStore.unique(clientId ? `DPoP@${clientId}` : `DPoP`, jti, asTimeFrame(DPOP_NONCE_MAX_AGE));
23
19
  }
24
20
  async uniqueCodeChallenge(challenge) {
25
- return this.replayStore.unique('CodeChallenge', challenge, asTimeFrame(constants_js_1.CODE_CHALLENGE_REPLAY_TIMEFRAME));
21
+ return this.replayStore.unique('CodeChallenge', challenge, asTimeFrame(CODE_CHALLENGE_REPLAY_TIMEFRAME));
26
22
  }
27
23
  }
28
- exports.ReplayManager = ReplayManager;
29
24
  //# sourceMappingURL=replay-manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"replay-manager.js","sourceRoot":"","sources":["../../src/replay/replay-manager.ts"],"names":[],"mappings":";;;AACA,kDAKwB;AAGxB,MAAM,cAAc,GAAG,GAAG,CAAA,CAAC,8BAA8B;AACzD,MAAM,WAAW,GAAG,CAAC,SAAiB,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,cAAc,CAAC,CAAA;AAEhF,MAAa,aAAa;IACO;IAA/B,YAA+B,WAAwB;QAAxB,gBAAW,GAAX,WAAW,CAAa;IAAG,CAAC;IAE3D,KAAK,CAAC,UAAU,CACd,GAAW,EACX,QAAkB,EAClB,GAAY;QAEZ,MAAM,SAAS,GACb,GAAG,IAAI,IAAI;YACT,CAAC,CAAC,WAAW,CAAC,uCAAwB,CAAC;YACvC,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC7B,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,QAAQ,EAAE,EAAE,GAAG,EAAE,SAAS,CAAC,CAAA;IACpE,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW,EAAE,QAAkB;QAC7C,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAC5B,OAAO,QAAQ,EAAE,EACjB,GAAG,EACH,WAAW,CAAC,0BAAW,CAAC,CACzB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAW,EAAE,QAAmB;QAC/C,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAC5B,QAAQ,CAAC,CAAC,CAAC,QAAQ,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,EACtC,GAAG,EACH,WAAW,CAAC,iCAAkB,CAAC,CAChC,CAAA;IACH,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,SAAiB;QACzC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAC5B,eAAe,EACf,SAAS,EACT,WAAW,CAAC,8CAA+B,CAAC,CAC7C,CAAA;IACH,CAAC;CACF;AAtCD,sCAsCC","sourcesContent":["import { ClientId } from '../client/client-id.js'\nimport {\n CLIENT_ASSERTION_MAX_AGE,\n CODE_CHALLENGE_REPLAY_TIMEFRAME,\n DPOP_NONCE_MAX_AGE,\n JAR_MAX_AGE,\n} from '../constants.js'\nimport { ReplayStore } from './replay-store.js'\n\nconst SECURITY_RATIO = 1.1 // 10% extra time for security\nconst asTimeFrame = (timeFrame: number) => Math.ceil(timeFrame * SECURITY_RATIO)\n\nexport class ReplayManager {\n constructor(protected readonly replayStore: ReplayStore) {}\n\n async uniqueAuth(\n jti: string,\n clientId: ClientId,\n exp?: number,\n ): Promise<boolean> {\n const timeFrame =\n exp == null\n ? asTimeFrame(CLIENT_ASSERTION_MAX_AGE)\n : exp * 1000 - Date.now()\n return this.replayStore.unique(`Auth@${clientId}`, jti, timeFrame)\n }\n\n async uniqueJar(jti: string, clientId: ClientId): Promise<boolean> {\n return this.replayStore.unique(\n `JAR@${clientId}`,\n jti,\n asTimeFrame(JAR_MAX_AGE),\n )\n }\n\n async uniqueDpop(jti: string, clientId?: ClientId): Promise<boolean> {\n return this.replayStore.unique(\n clientId ? `DPoP@${clientId}` : `DPoP`,\n jti,\n asTimeFrame(DPOP_NONCE_MAX_AGE),\n )\n }\n\n async uniqueCodeChallenge(challenge: string): Promise<boolean> {\n return this.replayStore.unique(\n 'CodeChallenge',\n challenge,\n asTimeFrame(CODE_CHALLENGE_REPLAY_TIMEFRAME),\n )\n }\n}\n"]}
1
+ {"version":3,"file":"replay-manager.js","sourceRoot":"","sources":["../../src/replay/replay-manager.ts"],"names":[],"mappings":"AACA,OAAO,EACL,wBAAwB,EACxB,+BAA+B,EAC/B,kBAAkB,EAClB,WAAW,GACZ,MAAM,iBAAiB,CAAA;AAGxB,MAAM,cAAc,GAAG,GAAG,CAAA,CAAC,8BAA8B;AACzD,MAAM,WAAW,GAAG,CAAC,SAAiB,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,cAAc,CAAC,CAAA;AAEhF,MAAM,OAAO,aAAa;IACxB,YAA+B,WAAwB;QAAxB,gBAAW,GAAX,WAAW,CAAa;IAAG,CAAC;IAE3D,KAAK,CAAC,UAAU,CACd,GAAW,EACX,QAAkB,EAClB,GAAY;QAEZ,MAAM,SAAS,GACb,GAAG,IAAI,IAAI;YACT,CAAC,CAAC,WAAW,CAAC,wBAAwB,CAAC;YACvC,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC7B,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,QAAQ,EAAE,EAAE,GAAG,EAAE,SAAS,CAAC,CAAA;IACpE,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW,EAAE,QAAkB;QAC7C,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAC5B,OAAO,QAAQ,EAAE,EACjB,GAAG,EACH,WAAW,CAAC,WAAW,CAAC,CACzB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAW,EAAE,QAAmB;QAC/C,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAC5B,QAAQ,CAAC,CAAC,CAAC,QAAQ,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,EACtC,GAAG,EACH,WAAW,CAAC,kBAAkB,CAAC,CAChC,CAAA;IACH,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,SAAiB;QACzC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAC5B,eAAe,EACf,SAAS,EACT,WAAW,CAAC,+BAA+B,CAAC,CAC7C,CAAA;IACH,CAAC;CACF","sourcesContent":["import { ClientId } from '../client/client-id.js'\nimport {\n CLIENT_ASSERTION_MAX_AGE,\n CODE_CHALLENGE_REPLAY_TIMEFRAME,\n DPOP_NONCE_MAX_AGE,\n JAR_MAX_AGE,\n} from '../constants.js'\nimport { ReplayStore } from './replay-store.js'\n\nconst SECURITY_RATIO = 1.1 // 10% extra time for security\nconst asTimeFrame = (timeFrame: number) => Math.ceil(timeFrame * SECURITY_RATIO)\n\nexport class ReplayManager {\n constructor(protected readonly replayStore: ReplayStore) {}\n\n async uniqueAuth(\n jti: string,\n clientId: ClientId,\n exp?: number,\n ): Promise<boolean> {\n const timeFrame =\n exp == null\n ? asTimeFrame(CLIENT_ASSERTION_MAX_AGE)\n : exp * 1000 - Date.now()\n return this.replayStore.unique(`Auth@${clientId}`, jti, timeFrame)\n }\n\n async uniqueJar(jti: string, clientId: ClientId): Promise<boolean> {\n return this.replayStore.unique(\n `JAR@${clientId}`,\n jti,\n asTimeFrame(JAR_MAX_AGE),\n )\n }\n\n async uniqueDpop(jti: string, clientId?: ClientId): Promise<boolean> {\n return this.replayStore.unique(\n clientId ? `DPoP@${clientId}` : `DPoP`,\n jti,\n asTimeFrame(DPOP_NONCE_MAX_AGE),\n )\n }\n\n async uniqueCodeChallenge(challenge: string): Promise<boolean> {\n return this.replayStore.unique(\n 'CodeChallenge',\n challenge,\n asTimeFrame(CODE_CHALLENGE_REPLAY_TIMEFRAME),\n )\n }\n}\n"]}
@@ -1,9 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ReplayStoreMemory = void 0;
4
- class ReplayStoreMemory {
5
- lastCleanup = Date.now();
6
- nonces = new Map();
1
+ export class ReplayStoreMemory {
2
+ constructor() {
3
+ this.lastCleanup = Date.now();
4
+ this.nonces = new Map();
5
+ }
7
6
  /**
8
7
  * Returns true if the nonce is unique within the given time frame.
9
8
  */
@@ -26,5 +25,4 @@ class ReplayStoreMemory {
26
25
  }
27
26
  }
28
27
  }
29
- exports.ReplayStoreMemory = ReplayStoreMemory;
30
28
  //# sourceMappingURL=replay-store-memory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"replay-store-memory.js","sourceRoot":"","sources":["../../src/replay/replay-store-memory.ts"],"names":[],"mappings":";;;AAEA,MAAa,iBAAiB;IACpB,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAA;IAE1C;;OAEG;IACH,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,KAAa,EACb,SAAiB;QAEjB,IAAI,CAAC,OAAO,EAAE,CAAA;QACd,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,KAAK,EAAE,CAAA;QAEnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,CAAC,CAAA;QAErC,OAAO,GAAG,IAAI,IAAI,IAAI,GAAG,GAAG,GAAG,CAAA;IACjC,CAAC;IAEO,OAAO;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEtB,IAAI,IAAI,CAAC,WAAW,GAAG,GAAG,GAAG,MAAM,EAAE,CAAC;YACpC,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzC,IAAI,OAAO,GAAG,GAAG;oBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5C,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,GAAG,CAAA;QACxB,CAAC;IACH,CAAC;CACF;AAjCD,8CAiCC","sourcesContent":["import type { ReplayStore } from './replay-store.js'\n\nexport class ReplayStoreMemory implements ReplayStore {\n private lastCleanup = Date.now()\n private nonces = new Map<string, number>()\n\n /**\n * Returns true if the nonce is unique within the given time frame.\n */\n async unique(\n namespace: string,\n nonce: string,\n timeFrame: number,\n ): Promise<boolean> {\n this.cleanup()\n const key = `${namespace}:${nonce}`\n\n const now = Date.now()\n\n const exp = this.nonces.get(key)\n this.nonces.set(key, now + timeFrame)\n\n return exp == null || exp < now\n }\n\n private cleanup() {\n const now = Date.now()\n\n if (this.lastCleanup < now - 60_000) {\n for (const [key, expires] of this.nonces) {\n if (expires < now) this.nonces.delete(key)\n }\n this.lastCleanup = now\n }\n }\n}\n"]}
1
+ {"version":3,"file":"replay-store-memory.js","sourceRoot":"","sources":["../../src/replay/replay-store-memory.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,iBAAiB;IAA9B;QACU,gBAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACxB,WAAM,GAAG,IAAI,GAAG,EAAkB,CAAA;IA+B5C,CAAC;IA7BC;;OAEG;IACH,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,KAAa,EACb,SAAiB;QAEjB,IAAI,CAAC,OAAO,EAAE,CAAA;QACd,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,KAAK,EAAE,CAAA;QAEnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,CAAC,CAAA;QAErC,OAAO,GAAG,IAAI,IAAI,IAAI,GAAG,GAAG,GAAG,CAAA;IACjC,CAAC;IAEO,OAAO;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEtB,IAAI,IAAI,CAAC,WAAW,GAAG,GAAG,GAAG,MAAM,EAAE,CAAC;YACpC,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzC,IAAI,OAAO,GAAG,GAAG;oBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5C,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,GAAG,CAAA;QACxB,CAAC;IACH,CAAC;CACF","sourcesContent":["import type { ReplayStore } from './replay-store.js'\n\nexport class ReplayStoreMemory implements ReplayStore {\n private lastCleanup = Date.now()\n private nonces = new Map<string, number>()\n\n /**\n * Returns true if the nonce is unique within the given time frame.\n */\n async unique(\n namespace: string,\n nonce: string,\n timeFrame: number,\n ): Promise<boolean> {\n this.cleanup()\n const key = `${namespace}:${nonce}`\n\n const now = Date.now()\n\n const exp = this.nonces.get(key)\n this.nonces.set(key, now + timeFrame)\n\n return exp == null || exp < now\n }\n\n private cleanup() {\n const now = Date.now()\n\n if (this.lastCleanup < now - 60_000) {\n for (const [key, expires] of this.nonces) {\n if (expires < now) this.nonces.delete(key)\n }\n this.lastCleanup = now\n }\n }\n}\n"]}
@@ -1,11 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ReplayStoreRedis = void 0;
4
- const redis_js_1 = require("../lib/redis.js");
5
- class ReplayStoreRedis {
6
- redis;
1
+ import { createRedis } from '../lib/redis.js';
2
+ export class ReplayStoreRedis {
7
3
  constructor(options) {
8
- this.redis = (0, redis_js_1.createRedis)(options.redis);
4
+ this.redis = createRedis(options.redis);
9
5
  }
10
6
  /**
11
7
  * Returns true if the nonce is unique within the given time frame.
@@ -16,5 +12,4 @@ class ReplayStoreRedis {
16
12
  return prev == null;
17
13
  }
18
14
  }
19
- exports.ReplayStoreRedis = ReplayStoreRedis;
20
15
  //# sourceMappingURL=replay-store-redis.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"replay-store-redis.js","sourceRoot":"","sources":["../../src/replay/replay-store-redis.ts"],"names":[],"mappings":";;;AACA,8CAAiE;AASjE,MAAa,gBAAgB;IACV,KAAK,CAAO;IAE7B,YAAY,OAAgC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAA,sBAAW,EAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,KAAa,EACb,SAAiB;QAEjB,MAAM,GAAG,GAAG,UAAU,SAAS,IAAI,KAAK,EAAE,CAAA;QAC1C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;QACnE,OAAO,IAAI,IAAI,IAAI,CAAA;IACrB,CAAC;CACF;AAnBD,4CAmBC","sourcesContent":["import type { Redis } from 'ioredis'\nimport { CreateRedisOptions, createRedis } from '../lib/redis.js'\nimport type { ReplayStore } from './replay-store.js'\n\nexport type { CreateRedisOptions, Redis }\n\nexport type ReplayStoreRedisOptions = {\n redis: CreateRedisOptions\n}\n\nexport class ReplayStoreRedis implements ReplayStore {\n private readonly redis: Redis\n\n constructor(options: ReplayStoreRedisOptions) {\n this.redis = createRedis(options.redis)\n }\n\n /**\n * Returns true if the nonce is unique within the given time frame.\n */\n async unique(\n namespace: string,\n nonce: string,\n timeFrame: number,\n ): Promise<boolean> {\n const key = `nonces:${namespace}:${nonce}`\n const prev = await this.redis.set(key, '1', 'PX', timeFrame, 'GET')\n return prev == null\n }\n}\n"]}
1
+ {"version":3,"file":"replay-store-redis.js","sourceRoot":"","sources":["../../src/replay/replay-store-redis.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,WAAW,EAAE,MAAM,iBAAiB,CAAA;AASjE,MAAM,OAAO,gBAAgB;IAG3B,YAAY,OAAgC;QAC1C,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,KAAa,EACb,SAAiB;QAEjB,MAAM,GAAG,GAAG,UAAU,SAAS,IAAI,KAAK,EAAE,CAAA;QAC1C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;QACnE,OAAO,IAAI,IAAI,IAAI,CAAA;IACrB,CAAC;CACF","sourcesContent":["import type { Redis } from 'ioredis'\nimport { CreateRedisOptions, createRedis } from '../lib/redis.js'\nimport type { ReplayStore } from './replay-store.js'\n\nexport type { CreateRedisOptions, Redis }\n\nexport type ReplayStoreRedisOptions = {\n redis: CreateRedisOptions\n}\n\nexport class ReplayStoreRedis implements ReplayStore {\n private readonly redis: Redis\n\n constructor(options: ReplayStoreRedisOptions) {\n this.redis = createRedis(options.redis)\n }\n\n /**\n * Returns true if the nonce is unique within the given time frame.\n */\n async unique(\n namespace: string,\n nonce: string,\n timeFrame: number,\n ): Promise<boolean> {\n const key = `nonces:${namespace}:${nonce}`\n const prev = await this.redis.set(key, '1', 'PX', timeFrame, 'GET')\n return prev == null\n }\n}\n"]}
@@ -1,18 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isReplayStore = isReplayStore;
4
- exports.ifReplayStore = ifReplayStore;
5
- exports.asReplayStore = asReplayStore;
6
- function isReplayStore(implementation) {
1
+ export function isReplayStore(implementation) {
7
2
  return typeof implementation.unique === 'function';
8
3
  }
9
- function ifReplayStore(implementation) {
4
+ export function ifReplayStore(implementation) {
10
5
  if (implementation && isReplayStore(implementation)) {
11
6
  return implementation;
12
7
  }
13
8
  return undefined;
14
9
  }
15
- function asReplayStore(implementation) {
10
+ export function asReplayStore(implementation) {
16
11
  const store = ifReplayStore(implementation);
17
12
  if (store)
18
13
  return store;
@@ -1 +1 @@
1
- {"version":3,"file":"replay-store.js","sourceRoot":"","sources":["../../src/replay/replay-store.ts"],"names":[],"mappings":";;AAoBA,sCAIC;AAED,sCAQC;AAED,sCAOC;AAvBD,SAAgB,aAAa,CAC3B,cAA8D;IAE9D,OAAO,OAAO,cAAc,CAAC,MAAM,KAAK,UAAU,CAAA;AACpD,CAAC;AAED,SAAgB,aAAa,CAC3B,cAA+D;IAE/D,IAAI,cAAc,IAAI,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC;QACpD,OAAO,cAAc,CAAA;IACvB,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAgB,aAAa,CAC3B,cAA+D;IAE/D,MAAM,KAAK,GAAG,aAAa,CAAC,cAAc,CAAC,CAAA;IAC3C,IAAI,KAAK;QAAE,OAAO,KAAK,CAAA;IAEvB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;AACvD,CAAC","sourcesContent":["import { Awaitable } from '../lib/util/type.js'\n\n// Export all types needed to implement the ReplayStore interface\nexport type { Awaitable }\n\nexport interface ReplayStore {\n /**\n * Returns true if the nonce is unique within the given time frame. While not\n * strictly necessary for security purposes, the namespace should be used to\n * mitigate denial of service attacks from one client to the other.\n *\n * @param timeFrame expressed in milliseconds.\n */\n unique(\n namespace: string,\n nonce: string,\n timeFrame: number,\n ): Awaitable<boolean>\n}\n\nexport function isReplayStore(\n implementation: Record<string, unknown> & Partial<ReplayStore>,\n): implementation is Record<string, unknown> & ReplayStore {\n return typeof implementation.unique === 'function'\n}\n\nexport function ifReplayStore(\n implementation?: Record<string, unknown> & Partial<ReplayStore>,\n): ReplayStore | undefined {\n if (implementation && isReplayStore(implementation)) {\n return implementation\n }\n\n return undefined\n}\n\nexport function asReplayStore(\n implementation?: Record<string, unknown> & Partial<ReplayStore>,\n): ReplayStore {\n const store = ifReplayStore(implementation)\n if (store) return store\n\n throw new Error('Invalid ReplayStore implementation')\n}\n"]}
1
+ {"version":3,"file":"replay-store.js","sourceRoot":"","sources":["../../src/replay/replay-store.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,aAAa,CAC3B,cAA8D;IAE9D,OAAO,OAAO,cAAc,CAAC,MAAM,KAAK,UAAU,CAAA;AACpD,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,cAA+D;IAE/D,IAAI,cAAc,IAAI,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC;QACpD,OAAO,cAAc,CAAA;IACvB,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,cAA+D;IAE/D,MAAM,KAAK,GAAG,aAAa,CAAC,cAAc,CAAC,CAAA;IAC3C,IAAI,KAAK;QAAE,OAAO,KAAK,CAAA;IAEvB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;AACvD,CAAC","sourcesContent":["import { Awaitable } from '../lib/util/type.js'\n\n// Export all types needed to implement the ReplayStore interface\nexport type { Awaitable }\n\nexport interface ReplayStore {\n /**\n * Returns true if the nonce is unique within the given time frame. While not\n * strictly necessary for security purposes, the namespace should be used to\n * mitigate denial of service attacks from one client to the other.\n *\n * @param timeFrame expressed in milliseconds.\n */\n unique(\n namespace: string,\n nonce: string,\n timeFrame: number,\n ): Awaitable<boolean>\n}\n\nexport function isReplayStore(\n implementation: Record<string, unknown> & Partial<ReplayStore>,\n): implementation is Record<string, unknown> & ReplayStore {\n return typeof implementation.unique === 'function'\n}\n\nexport function ifReplayStore(\n implementation?: Record<string, unknown> & Partial<ReplayStore>,\n): ReplayStore | undefined {\n if (implementation && isReplayStore(implementation)) {\n return implementation\n }\n\n return undefined\n}\n\nexport function asReplayStore(\n implementation?: Record<string, unknown> & Partial<ReplayStore>,\n): ReplayStore {\n const store = ifReplayStore(implementation)\n if (store) return store\n\n throw new Error('Invalid ReplayStore implementation')\n}\n"]}
@@ -1,20 +1,15 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateCode = exports.isCode = exports.codeSchema = exports.CODE_LENGTH = void 0;
4
- const zod_1 = require("zod");
5
- const constants_js_1 = require("../constants.js");
6
- const crypto_js_1 = require("../lib/util/crypto.js");
7
- exports.CODE_LENGTH = constants_js_1.CODE_PREFIX.length + constants_js_1.CODE_BYTES_LENGTH * 2; // hex encoding
8
- exports.codeSchema = zod_1.z
1
+ import { z } from 'zod';
2
+ import { CODE_BYTES_LENGTH, CODE_PREFIX } from '../constants.js';
3
+ import { randomHexId } from '../lib/util/crypto.js';
4
+ export const CODE_LENGTH = CODE_PREFIX.length + CODE_BYTES_LENGTH * 2; // hex encoding
5
+ export const codeSchema = z
9
6
  .string()
10
- .length(exports.CODE_LENGTH) // hex encoding
11
- .refine((v) => v.startsWith(constants_js_1.CODE_PREFIX), {
7
+ .length(CODE_LENGTH) // hex encoding
8
+ .refine((v) => v.startsWith(CODE_PREFIX), {
12
9
  message: `Invalid code format`,
13
10
  });
14
- const isCode = (data) => exports.codeSchema.safeParse(data).success;
15
- exports.isCode = isCode;
16
- const generateCode = async () => {
17
- return `${constants_js_1.CODE_PREFIX}${await (0, crypto_js_1.randomHexId)(constants_js_1.CODE_BYTES_LENGTH)}`;
11
+ export const isCode = (data) => codeSchema.safeParse(data).success;
12
+ export const generateCode = async () => {
13
+ return `${CODE_PREFIX}${await randomHexId(CODE_BYTES_LENGTH)}`;
18
14
  };
19
- exports.generateCode = generateCode;
20
15
  //# sourceMappingURL=code.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/request/code.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AACvB,kDAAgE;AAChE,qDAAmD;AAEtC,QAAA,WAAW,GAAG,0BAAW,CAAC,MAAM,GAAG,gCAAiB,GAAG,CAAC,CAAA,CAAC,eAAe;AAExE,QAAA,UAAU,GAAG,OAAC;KACxB,MAAM,EAAE;KACR,MAAM,CAAC,mBAAW,CAAC,CAAC,eAAe;KACnC,MAAM,CACL,CAAC,CAAC,EAAyC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,0BAAW,CAAC,EACvE;IACE,OAAO,EAAE,qBAAqB;CAC/B,CACF,CAAA;AAEI,MAAM,MAAM,GAAG,CAAC,IAAa,EAAgB,EAAE,CACpD,kBAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAA;AADvB,QAAA,MAAM,UACiB;AAG7B,MAAM,YAAY,GAAG,KAAK,IAAmB,EAAE;IACpD,OAAO,GAAG,0BAAW,GAAG,MAAM,IAAA,uBAAW,EAAC,gCAAiB,CAAC,EAAE,CAAA;AAChE,CAAC,CAAA;AAFY,QAAA,YAAY,gBAExB","sourcesContent":["import { z } from 'zod'\nimport { CODE_BYTES_LENGTH, CODE_PREFIX } from '../constants.js'\nimport { randomHexId } from '../lib/util/crypto.js'\n\nexport const CODE_LENGTH = CODE_PREFIX.length + CODE_BYTES_LENGTH * 2 // hex encoding\n\nexport const codeSchema = z\n .string()\n .length(CODE_LENGTH) // hex encoding\n .refine(\n (v): v is `${typeof CODE_PREFIX}${string}` => v.startsWith(CODE_PREFIX),\n {\n message: `Invalid code format`,\n },\n )\n\nexport const isCode = (data: unknown): data is Code =>\n codeSchema.safeParse(data).success\n\nexport type Code = z.infer<typeof codeSchema>\nexport const generateCode = async (): Promise<Code> => {\n return `${CODE_PREFIX}${await randomHexId(CODE_BYTES_LENGTH)}`\n}\n"]}
1
+ {"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/request/code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAEnD,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,GAAG,iBAAiB,GAAG,CAAC,CAAA,CAAC,eAAe;AAErF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,EAAE;KACR,MAAM,CAAC,WAAW,CAAC,CAAC,eAAe;KACnC,MAAM,CACL,CAAC,CAAC,EAAyC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,EACvE;IACE,OAAO,EAAE,qBAAqB;CAC/B,CACF,CAAA;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAa,EAAgB,EAAE,CACpD,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAA;AAGpC,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,IAAmB,EAAE;IACpD,OAAO,GAAG,WAAW,GAAG,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAA;AAChE,CAAC,CAAA","sourcesContent":["import { z } from 'zod'\nimport { CODE_BYTES_LENGTH, CODE_PREFIX } from '../constants.js'\nimport { randomHexId } from '../lib/util/crypto.js'\n\nexport const CODE_LENGTH = CODE_PREFIX.length + CODE_BYTES_LENGTH * 2 // hex encoding\n\nexport const codeSchema = z\n .string()\n .length(CODE_LENGTH) // hex encoding\n .refine(\n (v): v is `${typeof CODE_PREFIX}${string}` => v.startsWith(CODE_PREFIX),\n {\n message: `Invalid code format`,\n },\n )\n\nexport const isCode = (data: unknown): data is Code =>\n codeSchema.safeParse(data).success\n\nexport type Code = z.infer<typeof codeSchema>\nexport const generateCode = async (): Promise<Code> => {\n return `${CODE_PREFIX}${await randomHexId(CODE_BYTES_LENGTH)}`\n}\n"]}
@@ -1,6 +1,2 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isRequestDataAuthorized = void 0;
4
- const isRequestDataAuthorized = (data) => data.sub !== null && data.deviceId !== null;
5
- exports.isRequestDataAuthorized = isRequestDataAuthorized;
1
+ export const isRequestDataAuthorized = (data) => data.sub !== null && data.deviceId !== null;
6
2
  //# sourceMappingURL=request-data.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"request-data.js","sourceRoot":"","sources":["../../src/request/request-data.ts"],"names":[],"mappings":";;;AAiCO,MAAM,uBAAuB,GAAG,CACrC,IAAiB,EACc,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAA;AAFlE,QAAA,uBAAuB,2BAE2C","sourcesContent":["import { OAuthAuthorizationRequestParameters } from '@atproto/oauth-types'\nimport { ClientAuth, ClientAuthLegacy } from '../client/client-auth.js'\nimport { ClientId } from '../client/client-id.js'\nimport { DeviceId } from '../device/device-id.js'\nimport { NonNullableKeys } from '../lib/util/type.js'\nimport { Sub } from '../oidc/sub.js'\nimport { Code } from './code.js'\n\nexport type {\n ClientAuth,\n ClientAuthLegacy,\n ClientId,\n Code,\n DeviceId,\n OAuthAuthorizationRequestParameters,\n Sub,\n}\n\nexport type RequestData = {\n clientId: ClientId\n clientAuth: null | ClientAuth | ClientAuthLegacy\n parameters: Readonly<OAuthAuthorizationRequestParameters>\n expiresAt: Date\n deviceId: DeviceId | null\n sub: Sub | null\n code: Code | null\n}\n\nexport type RequestDataAuthorized = NonNullableKeys<\n RequestData,\n 'sub' | 'deviceId'\n>\n\nexport const isRequestDataAuthorized = (\n data: RequestData,\n): data is RequestDataAuthorized => data.sub !== null && data.deviceId !== null\n"]}
1
+ {"version":3,"file":"request-data.js","sourceRoot":"","sources":["../../src/request/request-data.ts"],"names":[],"mappings":"AAiCA,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,IAAiB,EACc,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAA","sourcesContent":["import { OAuthAuthorizationRequestParameters } from '@atproto/oauth-types'\nimport { ClientAuth, ClientAuthLegacy } from '../client/client-auth.js'\nimport { ClientId } from '../client/client-id.js'\nimport { DeviceId } from '../device/device-id.js'\nimport { NonNullableKeys } from '../lib/util/type.js'\nimport { Sub } from '../oidc/sub.js'\nimport { Code } from './code.js'\n\nexport type {\n ClientAuth,\n ClientAuthLegacy,\n ClientId,\n Code,\n DeviceId,\n OAuthAuthorizationRequestParameters,\n Sub,\n}\n\nexport type RequestData = {\n clientId: ClientId\n clientAuth: null | ClientAuth | ClientAuthLegacy\n parameters: Readonly<OAuthAuthorizationRequestParameters>\n expiresAt: Date\n deviceId: DeviceId | null\n sub: Sub | null\n code: Code | null\n}\n\nexport type RequestDataAuthorized = NonNullableKeys<\n RequestData,\n 'sub' | 'deviceId'\n>\n\nexport const isRequestDataAuthorized = (\n data: RequestData,\n): data is RequestDataAuthorized => data.sub !== null && data.deviceId !== null\n"]}
@@ -1,18 +1,14 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateRequestId = exports.requestIdSchema = exports.REQUEST_ID_LENGTH = void 0;
4
- const zod_1 = require("zod");
5
- const constants_js_1 = require("../constants.js");
6
- const crypto_js_1 = require("../lib/util/crypto.js");
7
- exports.REQUEST_ID_LENGTH = constants_js_1.REQUEST_ID_PREFIX.length + constants_js_1.REQUEST_ID_BYTES_LENGTH * 2; // hex encoding
8
- exports.requestIdSchema = zod_1.z
1
+ import { z } from 'zod';
2
+ import { REQUEST_ID_BYTES_LENGTH, REQUEST_ID_PREFIX } from '../constants.js';
3
+ import { randomHexId } from '../lib/util/crypto.js';
4
+ export const REQUEST_ID_LENGTH = REQUEST_ID_PREFIX.length + REQUEST_ID_BYTES_LENGTH * 2; // hex encoding
5
+ export const requestIdSchema = z
9
6
  .string()
10
- .length(exports.REQUEST_ID_LENGTH)
11
- .refine((v) => v.startsWith(constants_js_1.REQUEST_ID_PREFIX), {
7
+ .length(REQUEST_ID_LENGTH)
8
+ .refine((v) => v.startsWith(REQUEST_ID_PREFIX), {
12
9
  message: `Invalid request ID format`,
13
10
  });
14
- const generateRequestId = async () => {
15
- return `${constants_js_1.REQUEST_ID_PREFIX}${await (0, crypto_js_1.randomHexId)(constants_js_1.REQUEST_ID_BYTES_LENGTH)}`;
11
+ export const generateRequestId = async () => {
12
+ return `${REQUEST_ID_PREFIX}${await randomHexId(REQUEST_ID_BYTES_LENGTH)}`;
16
13
  };
17
- exports.generateRequestId = generateRequestId;
18
14
  //# sourceMappingURL=request-id.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"request-id.js","sourceRoot":"","sources":["../../src/request/request-id.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AACvB,kDAA4E;AAC5E,qDAAmD;AAEtC,QAAA,iBAAiB,GAC5B,gCAAiB,CAAC,MAAM,GAAG,sCAAuB,GAAG,CAAC,CAAA,CAAC,eAAe;AAE3D,QAAA,eAAe,GAAG,OAAC;KAC7B,MAAM,EAAE;KACR,MAAM,CAAC,yBAAiB,CAAC;KACzB,MAAM,CACL,CAAC,CAAC,EAA+C,EAAE,CACjD,CAAC,CAAC,UAAU,CAAC,gCAAiB,CAAC,EACjC;IACE,OAAO,EAAE,2BAA2B;CACrC,CACF,CAAA;AAGI,MAAM,iBAAiB,GAAG,KAAK,IAAwB,EAAE;IAC9D,OAAO,GAAG,gCAAiB,GAAG,MAAM,IAAA,uBAAW,EAAC,sCAAuB,CAAC,EAAE,CAAA;AAC5E,CAAC,CAAA;AAFY,QAAA,iBAAiB,qBAE7B","sourcesContent":["import { z } from 'zod'\nimport { REQUEST_ID_BYTES_LENGTH, REQUEST_ID_PREFIX } from '../constants.js'\nimport { randomHexId } from '../lib/util/crypto.js'\n\nexport const REQUEST_ID_LENGTH =\n REQUEST_ID_PREFIX.length + REQUEST_ID_BYTES_LENGTH * 2 // hex encoding\n\nexport const requestIdSchema = z\n .string()\n .length(REQUEST_ID_LENGTH)\n .refine(\n (v): v is `${typeof REQUEST_ID_PREFIX}${string}` =>\n v.startsWith(REQUEST_ID_PREFIX),\n {\n message: `Invalid request ID format`,\n },\n )\n\nexport type RequestId = z.infer<typeof requestIdSchema>\nexport const generateRequestId = async (): Promise<RequestId> => {\n return `${REQUEST_ID_PREFIX}${await randomHexId(REQUEST_ID_BYTES_LENGTH)}`\n}\n"]}
1
+ {"version":3,"file":"request-id.js","sourceRoot":"","sources":["../../src/request/request-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAEnD,MAAM,CAAC,MAAM,iBAAiB,GAC5B,iBAAiB,CAAC,MAAM,GAAG,uBAAuB,GAAG,CAAC,CAAA,CAAC,eAAe;AAExE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC;KAC7B,MAAM,EAAE;KACR,MAAM,CAAC,iBAAiB,CAAC;KACzB,MAAM,CACL,CAAC,CAAC,EAA+C,EAAE,CACjD,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC,EACjC;IACE,OAAO,EAAE,2BAA2B;CACrC,CACF,CAAA;AAGH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,IAAwB,EAAE;IAC9D,OAAO,GAAG,iBAAiB,GAAG,MAAM,WAAW,CAAC,uBAAuB,CAAC,EAAE,CAAA;AAC5E,CAAC,CAAA","sourcesContent":["import { z } from 'zod'\nimport { REQUEST_ID_BYTES_LENGTH, REQUEST_ID_PREFIX } from '../constants.js'\nimport { randomHexId } from '../lib/util/crypto.js'\n\nexport const REQUEST_ID_LENGTH =\n REQUEST_ID_PREFIX.length + REQUEST_ID_BYTES_LENGTH * 2 // hex encoding\n\nexport const requestIdSchema = z\n .string()\n .length(REQUEST_ID_LENGTH)\n .refine(\n (v): v is `${typeof REQUEST_ID_PREFIX}${string}` =>\n v.startsWith(REQUEST_ID_PREFIX),\n {\n message: `Invalid request ID format`,\n },\n )\n\nexport type RequestId = z.infer<typeof requestIdSchema>\nexport const generateRequestId = async (): Promise<RequestId> => {\n return `${REQUEST_ID_PREFIX}${await randomHexId(REQUEST_ID_BYTES_LENGTH)}`\n}\n"]}
@@ -1,30 +1,21 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RequestManager = void 0;
4
- const did_1 = require("@atproto/did");
5
- const lex_resolver_1 = require("@atproto/lex-resolver");
6
- const oauth_scopes_1 = require("@atproto/oauth-scopes");
7
- const syntax_1 = require("@atproto/syntax");
8
- const constants_js_1 = require("../constants.js");
9
- const access_denied_error_js_1 = require("../errors/access-denied-error.js");
10
- const authorization_error_js_1 = require("../errors/authorization-error.js");
11
- const consent_required_error_js_1 = require("../errors/consent-required-error.js");
12
- const invalid_authorization_details_error_js_1 = require("../errors/invalid-authorization-details-error.js");
13
- const invalid_grant_error_js_1 = require("../errors/invalid-grant-error.js");
14
- const invalid_request_error_js_1 = require("../errors/invalid-request-error.js");
15
- const invalid_scope_error_js_1 = require("../errors/invalid-scope-error.js");
16
- const code_js_1 = require("./code.js");
17
- const request_data_js_1 = require("./request-data.js");
18
- const request_id_js_1 = require("./request-id.js");
19
- const request_uri_js_1 = require("./request-uri.js");
20
- class RequestManager {
21
- store;
22
- lexiconManager;
23
- signer;
24
- metadata;
25
- hooks;
26
- tokenMaxAge;
27
- constructor(store, lexiconManager, signer, metadata, hooks, tokenMaxAge = constants_js_1.TOKEN_MAX_AGE) {
1
+ import { isAtprotoDid } from '@atproto/did';
2
+ import { LexResolverError } from '@atproto/lex-resolver';
3
+ import { isAtprotoOauthScope } from '@atproto/oauth-scopes';
4
+ import { isValidHandle } from '@atproto/syntax';
5
+ import { AUTHORIZATION_INACTIVITY_TIMEOUT, NODE_ENV, PAR_EXPIRES_IN, TOKEN_MAX_AGE, } from '../constants.js';
6
+ import { AccessDeniedError } from '../errors/access-denied-error.js';
7
+ import { AuthorizationError } from '../errors/authorization-error.js';
8
+ import { ConsentRequiredError } from '../errors/consent-required-error.js';
9
+ import { InvalidAuthorizationDetailsError } from '../errors/invalid-authorization-details-error.js';
10
+ import { InvalidGrantError } from '../errors/invalid-grant-error.js';
11
+ import { InvalidRequestError } from '../errors/invalid-request-error.js';
12
+ import { InvalidScopeError } from '../errors/invalid-scope-error.js';
13
+ import { generateCode } from './code.js';
14
+ import { isRequestDataAuthorized, } from './request-data.js';
15
+ import { generateRequestId } from './request-id.js';
16
+ import { decodeRequestUri, encodeRequestUri, } from './request-uri.js';
17
+ export class RequestManager {
18
+ constructor(store, lexiconManager, signer, metadata, hooks, tokenMaxAge = TOKEN_MAX_AGE) {
28
19
  this.store = store;
29
20
  this.lexiconManager = lexiconManager;
30
21
  this.signer = signer;
@@ -42,8 +33,8 @@ class RequestManager {
42
33
  clientAuth,
43
34
  parameters,
44
35
  });
45
- const expiresAt = new Date(Date.now() + constants_js_1.PAR_EXPIRES_IN);
46
- const requestId = await (0, request_id_js_1.generateRequestId)();
36
+ const expiresAt = new Date(Date.now() + PAR_EXPIRES_IN);
37
+ const requestId = await generateRequestId();
47
38
  await this.store.createRequest(requestId, {
48
39
  clientId: client.id,
49
40
  clientAuth,
@@ -53,7 +44,7 @@ class RequestManager {
53
44
  sub: null,
54
45
  code: null,
55
46
  });
56
- const requestUri = (0, request_uri_js_1.encodeRequestUri)(requestId);
47
+ const requestUri = encodeRequestUri(requestId);
57
48
  return { requestUri, expiresAt, parameters };
58
49
  }
59
50
  async validate(client, clientAuth, parameters) {
@@ -67,23 +58,23 @@ class RequestManager {
67
58
  'nonce', // note that OIDC "nonce" is redundant with PKCE
68
59
  ]) {
69
60
  if (parameters[k] !== undefined) {
70
- throw new authorization_error_js_1.AuthorizationError(parameters, `Unsupported "${k}" parameter`);
61
+ throw new AuthorizationError(parameters, `Unsupported "${k}" parameter`);
71
62
  }
72
63
  }
73
64
  // -----------------------
74
65
  // Validate against server
75
66
  // -----------------------
76
67
  if (!this.metadata.response_types_supported?.includes(parameters.response_type)) {
77
- throw new authorization_error_js_1.AuthorizationError(parameters, `Unsupported response_type "${parameters.response_type}"`, 'unsupported_response_type');
68
+ throw new AuthorizationError(parameters, `Unsupported response_type "${parameters.response_type}"`, 'unsupported_response_type');
78
69
  }
79
70
  if (parameters.response_type === 'code' &&
80
71
  !this.metadata.grant_types_supported?.includes('authorization_code')) {
81
- throw new authorization_error_js_1.AuthorizationError(parameters, `Unsupported grant_type "authorization_code"`, 'invalid_request');
72
+ throw new AuthorizationError(parameters, `Unsupported grant_type "authorization_code"`, 'invalid_request');
82
73
  }
83
74
  if (parameters.authorization_details) {
84
75
  for (const detail of parameters.authorization_details) {
85
76
  if (!this.metadata.authorization_details_types_supported?.includes(detail.type)) {
86
- throw new invalid_authorization_details_error_js_1.InvalidAuthorizationDetailsError(parameters, `Unsupported "authorization_details" type "${detail.type}"`);
77
+ throw new InvalidAuthorizationDetailsError(parameters, `Unsupported "authorization_details" type "${detail.type}"`);
87
78
  }
88
79
  }
89
80
  }
@@ -97,7 +88,7 @@ class RequestManager {
97
88
  if (!parameters.redirect_uri) {
98
89
  // Should already be ensured by client.validateRequest(). Adding here for
99
90
  // clarity & extra safety.
100
- throw new authorization_error_js_1.AuthorizationError(parameters, 'Missing "redirect_uri"');
91
+ throw new AuthorizationError(parameters, 'Missing "redirect_uri"');
101
92
  }
102
93
  // https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-10#section-1.4.1
103
94
  // > The authorization server MAY fully or partially ignore the scope
@@ -113,7 +104,7 @@ class RequestManager {
113
104
  // re-authenticate the user once the scopes are supported. This is due to
114
105
  // the fact that the AS does not know how to properly display those scopes
115
106
  // to the user, so it cannot properly ask for consent.
116
- const scope = Array.from(scopes).filter(oauth_scopes_1.isAtprotoOauthScope).join(' ') || undefined;
107
+ const scope = Array.from(scopes).filter(isAtprotoOauthScope).join(' ') || undefined;
117
108
  parameters = { ...parameters, scope };
118
109
  if (parameters.code_challenge) {
119
110
  switch (parameters.code_challenge_method) {
@@ -125,14 +116,14 @@ class RequestManager {
125
116
  case 'S256':
126
117
  break;
127
118
  default: {
128
- throw new authorization_error_js_1.AuthorizationError(parameters, `Unsupported code_challenge_method "${parameters.code_challenge_method}"`);
119
+ throw new AuthorizationError(parameters, `Unsupported code_challenge_method "${parameters.code_challenge_method}"`);
129
120
  }
130
121
  }
131
122
  }
132
123
  else {
133
124
  if (parameters.code_challenge_method) {
134
125
  // https://datatracker.ietf.org/doc/html/rfc7636#section-4.4.1
135
- throw new authorization_error_js_1.AuthorizationError(parameters, 'code_challenge is required when code_challenge_method is provided');
126
+ throw new AuthorizationError(parameters, 'code_challenge is required when code_challenge_method is provided');
136
127
  }
137
128
  // https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-11#section-4.1.2.1
138
129
  //
@@ -148,22 +139,22 @@ class RequestManager {
148
139
  //
149
140
  // atproto does not implement the OpenID Connect nonce mechanism, so we
150
141
  // require the use of PKCE for all clients.
151
- throw new authorization_error_js_1.AuthorizationError(parameters, 'Use of PKCE is required');
142
+ throw new AuthorizationError(parameters, 'Use of PKCE is required');
152
143
  }
153
144
  // -----------------
154
145
  // atproto extension
155
146
  // -----------------
156
147
  if (parameters.response_type !== 'code') {
157
- throw new authorization_error_js_1.AuthorizationError(parameters, 'atproto only supports the "code" response_type');
148
+ throw new AuthorizationError(parameters, 'atproto only supports the "code" response_type');
158
149
  }
159
150
  if (!scopes.has('atproto')) {
160
- throw new invalid_scope_error_js_1.InvalidScopeError(parameters, 'The "atproto" scope is required');
151
+ throw new InvalidScopeError(parameters, 'The "atproto" scope is required');
161
152
  }
162
153
  else if (scopes.has('openid')) {
163
- throw new invalid_scope_error_js_1.InvalidScopeError(parameters, 'OpenID Connect is not compatible with atproto');
154
+ throw new InvalidScopeError(parameters, 'OpenID Connect is not compatible with atproto');
164
155
  }
165
156
  if (parameters.code_challenge_method !== 'S256') {
166
- throw new authorization_error_js_1.AuthorizationError(parameters, 'atproto requires use of "S256" code_challenge_method');
157
+ throw new AuthorizationError(parameters, 'atproto requires use of "S256" code_challenge_method');
167
158
  }
168
159
  // atproto extension: if the client is not trusted, and not authenticated,
169
160
  // force users to consent to authorization requests. We do this to avoid
@@ -173,7 +164,7 @@ class RequestManager {
173
164
  !client.info.isFirstParty &&
174
165
  client.metadata.token_endpoint_auth_method === 'none') {
175
166
  if (parameters.prompt === 'none') {
176
- throw new consent_required_error_js_1.ConsentRequiredError(parameters, 'Public clients are not allowed to use silent-sign-on');
167
+ throw new ConsentRequiredError(parameters, 'Public clients are not allowed to use silent-sign-on');
177
168
  }
178
169
  // force "consent" for unauthenticated third party clients, unless they
179
170
  // are trying to create accounts:
@@ -185,8 +176,8 @@ class RequestManager {
185
176
  // @NOTE we to allow invalid case here, which is not spec'd anywhere.
186
177
  const hint = parameters.login_hint?.toLowerCase();
187
178
  if (hint) {
188
- if (!(0, did_1.isAtprotoDid)(hint) && !(0, syntax_1.isValidHandle)(hint)) {
189
- throw new authorization_error_js_1.AuthorizationError(parameters, `Invalid login_hint "${hint}"`);
179
+ if (!isAtprotoDid(hint) && !isValidHandle(hint)) {
180
+ throw new AuthorizationError(parameters, `Invalid login_hint "${hint}"`);
190
181
  }
191
182
  // @TODO: ensure that the account actually exists on this server (there is
192
183
  // no point in showing the UI to the user if the account does not exist).
@@ -201,8 +192,8 @@ class RequestManager {
201
192
  }
202
193
  catch (err) {
203
194
  // Parse expected errors
204
- if (err instanceof lex_resolver_1.LexResolverError) {
205
- throw new authorization_error_js_1.AuthorizationError(parameters, err.message, 'invalid_scope', err);
195
+ if (err instanceof LexResolverError) {
196
+ throw new AuthorizationError(parameters, err.message, 'invalid_scope', err);
206
197
  }
207
198
  // Unexpected error
208
199
  throw err;
@@ -217,37 +208,37 @@ class RequestManager {
217
208
  * Returns `undefined` when no such request exists.
218
209
  */
219
210
  async peekClientId(requestUri) {
220
- const requestId = (0, request_uri_js_1.decodeRequestUri)(requestUri);
211
+ const requestId = decodeRequestUri(requestUri);
221
212
  const data = await this.store.readRequest(requestId);
222
213
  return data?.clientId;
223
214
  }
224
215
  async get(requestUri, deviceId, clientId) {
225
- const requestId = (0, request_uri_js_1.decodeRequestUri)(requestUri);
216
+ const requestId = decodeRequestUri(requestUri);
226
217
  const data = await this.store.readRequest(requestId);
227
218
  if (!data)
228
- throw new invalid_request_error_js_1.InvalidRequestError('Unknown request_uri');
219
+ throw new InvalidRequestError('Unknown request_uri');
229
220
  const updates = {};
230
221
  try {
231
222
  if (data.sub || data.code) {
232
223
  // If an account was linked to the request, the next step is to exchange
233
224
  // the code for a token.
234
- throw new access_denied_error_js_1.AccessDeniedError(data.parameters, 'This request was already authorized');
225
+ throw new AccessDeniedError(data.parameters, 'This request was already authorized');
235
226
  }
236
227
  if (data.expiresAt < new Date()) {
237
- throw new access_denied_error_js_1.AccessDeniedError(data.parameters, 'This request has expired');
228
+ throw new AccessDeniedError(data.parameters, 'This request has expired');
238
229
  }
239
230
  else {
240
- updates.expiresAt = new Date(Date.now() + constants_js_1.AUTHORIZATION_INACTIVITY_TIMEOUT);
231
+ updates.expiresAt = new Date(Date.now() + AUTHORIZATION_INACTIVITY_TIMEOUT);
241
232
  }
242
233
  if (clientId != null && data.clientId !== clientId) {
243
- throw new access_denied_error_js_1.AccessDeniedError(data.parameters, 'This request was initiated for another client');
234
+ throw new AccessDeniedError(data.parameters, 'This request was initiated for another client');
244
235
  }
245
236
  if (deviceId != null) {
246
237
  if (!data.deviceId) {
247
238
  updates.deviceId = deviceId;
248
239
  }
249
240
  else if (data.deviceId !== deviceId) {
250
- throw new access_denied_error_js_1.AccessDeniedError(data.parameters, 'This request was initiated from another device');
241
+ throw new AccessDeniedError(data.parameters, 'This request was initiated from another device');
251
242
  }
252
243
  }
253
244
  }
@@ -266,23 +257,23 @@ class RequestManager {
266
257
  };
267
258
  }
268
259
  async setAuthorized(requestUri, client, account, deviceId, deviceMetadata, scopeOverride) {
269
- const requestId = (0, request_uri_js_1.decodeRequestUri)(requestUri);
260
+ const requestId = decodeRequestUri(requestUri);
270
261
  const data = await this.store.readRequest(requestId);
271
262
  if (!data)
272
- throw new invalid_request_error_js_1.InvalidRequestError('Unknown request_uri');
263
+ throw new InvalidRequestError('Unknown request_uri');
273
264
  let { parameters } = data;
274
265
  try {
275
266
  if (data.expiresAt < new Date()) {
276
- throw new access_denied_error_js_1.AccessDeniedError(parameters, 'This request has expired');
267
+ throw new AccessDeniedError(parameters, 'This request has expired');
277
268
  }
278
269
  if (!data.deviceId) {
279
- throw new access_denied_error_js_1.AccessDeniedError(parameters, 'This request was not initiated');
270
+ throw new AccessDeniedError(parameters, 'This request was not initiated');
280
271
  }
281
272
  if (data.deviceId !== deviceId) {
282
- throw new access_denied_error_js_1.AccessDeniedError(parameters, 'This request was initiated from another device');
273
+ throw new AccessDeniedError(parameters, 'This request was initiated from another device');
283
274
  }
284
275
  if (data.sub || data.code) {
285
- throw new access_denied_error_js_1.AccessDeniedError(parameters, 'This request was already authorized');
276
+ throw new AccessDeniedError(parameters, 'This request was already authorized');
286
277
  }
287
278
  // If a new scope value is provided, update the parameters by ensuring
288
279
  // that every existing scope in the parameters is also present in the
@@ -295,18 +286,18 @@ class RequestManager {
295
286
  const newScopes = existingScopes?.filter((s) => allowedScopes.has(s));
296
287
  // Validate: make sure the new scopes are valid
297
288
  if (!newScopes?.includes('atproto')) {
298
- throw new access_denied_error_js_1.AccessDeniedError(parameters, 'The "atproto" scope is required');
289
+ throw new AccessDeniedError(parameters, 'The "atproto" scope is required');
299
290
  }
300
291
  parameters = { ...parameters, scope: newScopes.join(' ') };
301
292
  }
302
293
  // Only response_type=code is supported
303
- const code = await (0, code_js_1.generateCode)();
294
+ const code = await generateCode();
304
295
  // Bind the request to the account, preventing it from being used again.
305
296
  await this.store.updateRequest(requestId, {
306
297
  sub: account.sub,
307
298
  code,
308
299
  // Allow the client to exchange the code for a token within the next 60 seconds.
309
- expiresAt: new Date(Date.now() + constants_js_1.AUTHORIZATION_INACTIVITY_TIMEOUT),
300
+ expiresAt: new Date(Date.now() + AUTHORIZATION_INACTIVITY_TIMEOUT),
310
301
  parameters,
311
302
  });
312
303
  await this.hooks.onAuthorized?.call(null, {
@@ -331,29 +322,28 @@ class RequestManager {
331
322
  async consumeCode(code) {
332
323
  const result = await this.store.consumeRequestCode(code);
333
324
  if (!result)
334
- throw new invalid_grant_error_js_1.InvalidGrantError('Invalid code');
325
+ throw new InvalidGrantError('Invalid code');
335
326
  const { requestId, data } = result;
336
327
  // Fool-proofing the store implementation against code replay attacks (in
337
328
  // case consumeRequestCode() does not delete the request).
338
- if (constants_js_1.NODE_ENV !== 'production') {
329
+ if (NODE_ENV !== 'production') {
339
330
  const result = await this.store.readRequest(requestId);
340
331
  if (result) {
341
332
  throw new Error('Invalid store implementation: request not deleted');
342
333
  }
343
334
  }
344
- if (!(0, request_data_js_1.isRequestDataAuthorized)(data) || data.code !== code) {
335
+ if (!isRequestDataAuthorized(data) || data.code !== code) {
345
336
  // Should never happen: maybe the store implementation is faulty ?
346
337
  throw new Error('Unexpected request state');
347
338
  }
348
339
  if (data.expiresAt < new Date()) {
349
- throw new invalid_grant_error_js_1.InvalidGrantError('This code has expired');
340
+ throw new InvalidGrantError('This code has expired');
350
341
  }
351
342
  return data;
352
343
  }
353
344
  async delete(requestUri) {
354
- const requestId = (0, request_uri_js_1.decodeRequestUri)(requestUri);
345
+ const requestId = decodeRequestUri(requestUri);
355
346
  await this.store.deleteRequest(requestId);
356
347
  }
357
348
  }
358
- exports.RequestManager = RequestManager;
359
349
  //# sourceMappingURL=request-manager.js.map