@hilbras/keystone 1.6.0 → 2.5.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 (604) hide show
  1. package/CHANGELOG.md +625 -0
  2. package/README.md +198 -50
  3. package/dist/cli.js +25 -27
  4. package/dist/cli.js.map +1 -1
  5. package/dist/config.d.ts +23 -1
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +53 -8
  8. package/dist/config.js.map +1 -1
  9. package/dist/container.d.ts +4 -1
  10. package/dist/container.d.ts.map +1 -1
  11. package/dist/container.js.map +1 -1
  12. package/dist/db/migrations/0008_flashy_firestar.sql +5 -0
  13. package/dist/db/migrations/0009_daffy_changeling.sql +1 -0
  14. package/dist/db/migrations/0010_wealthy_shadow_king.sql +37 -0
  15. package/dist/db/migrations/0011_overrated_vector.sql +18 -0
  16. package/dist/db/migrations/0012_brave_darkhawk.sql +28 -0
  17. package/dist/db/migrations/0013_wonderful_chimera.sql +5 -0
  18. package/dist/db/migrations/0014_magical_morph.sql +48 -0
  19. package/dist/db/migrations/0015_chief_vargas.sql +7 -0
  20. package/dist/db/migrations/0016_gorgeous_charles_xavier.sql +5 -0
  21. package/dist/db/migrations/0017_flashy_nekra.sql +1 -0
  22. package/{src/db/migrations/meta/0007_snapshot.json → dist/db/migrations/meta/0008_snapshot.json} +136 -32
  23. package/{src/db/migrations/meta/0006_snapshot.json → dist/db/migrations/meta/0009_snapshot.json} +359 -30
  24. package/{src/db/migrations/meta/0005_snapshot.json → dist/db/migrations/meta/0010_snapshot.json} +459 -29
  25. package/{src/db/migrations/meta/0004_snapshot.json → dist/db/migrations/meta/0011_snapshot.json} +594 -30
  26. package/dist/db/migrations/meta/0012_snapshot.json +3891 -0
  27. package/dist/db/migrations/meta/0013_snapshot.json +3919 -0
  28. package/dist/db/migrations/meta/0014_snapshot.json +4311 -0
  29. package/dist/db/migrations/meta/0015_snapshot.json +4340 -0
  30. package/dist/db/migrations/meta/0016_snapshot.json +4363 -0
  31. package/dist/db/migrations/meta/0017_snapshot.json +4370 -0
  32. package/dist/db/migrations/meta/_journal.json +70 -0
  33. package/dist/db/reencryptOidcSecrets.d.ts +2 -0
  34. package/dist/db/reencryptOidcSecrets.d.ts.map +1 -0
  35. package/dist/db/reencryptOidcSecrets.js +41 -0
  36. package/dist/db/reencryptOidcSecrets.js.map +1 -0
  37. package/dist/db/schema.d.ts +2693 -88
  38. package/dist/db/schema.d.ts.map +1 -1
  39. package/dist/db/schema.js +157 -4
  40. package/dist/db/schema.js.map +1 -1
  41. package/dist/db/seed.js +67 -40
  42. package/dist/db/seed.js.map +1 -1
  43. package/dist/di.d.ts.map +1 -1
  44. package/dist/di.js +11 -3
  45. package/dist/di.js.map +1 -1
  46. package/dist/index.d.ts +2 -2
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +34 -3
  49. package/dist/index.js.map +1 -1
  50. package/dist/lib/errors.d.ts +2 -1
  51. package/dist/lib/errors.d.ts.map +1 -1
  52. package/dist/lib/errors.js +10 -0
  53. package/dist/lib/errors.js.map +1 -1
  54. package/dist/plugins/appContext.d.ts.map +1 -1
  55. package/dist/plugins/appContext.js +3 -12
  56. package/dist/plugins/appContext.js.map +1 -1
  57. package/dist/plugins/audit.d.ts.map +1 -1
  58. package/dist/plugins/audit.js +26 -6
  59. package/dist/plugins/audit.js.map +1 -1
  60. package/dist/plugins/auth.d.ts.map +1 -1
  61. package/dist/plugins/auth.js +32 -7
  62. package/dist/plugins/auth.js.map +1 -1
  63. package/dist/plugins/headerSanitization.d.ts +15 -0
  64. package/dist/plugins/headerSanitization.d.ts.map +1 -0
  65. package/dist/plugins/headerSanitization.js +39 -0
  66. package/dist/plugins/headerSanitization.js.map +1 -0
  67. package/dist/plugins/metrics.d.ts.map +1 -1
  68. package/dist/plugins/mtls.d.ts +21 -2
  69. package/dist/plugins/mtls.d.ts.map +1 -1
  70. package/dist/plugins/mtls.js +94 -47
  71. package/dist/plugins/mtls.js.map +1 -1
  72. package/dist/plugins/permissions.d.ts.map +1 -1
  73. package/dist/plugins/permissions.js +29 -9
  74. package/dist/plugins/permissions.js.map +1 -1
  75. package/dist/plugins/rateLimit.d.ts +16 -0
  76. package/dist/plugins/rateLimit.d.ts.map +1 -1
  77. package/dist/plugins/rateLimit.js +16 -3
  78. package/dist/plugins/rateLimit.js.map +1 -1
  79. package/dist/plugins/requestLogger.d.ts.map +1 -1
  80. package/dist/repositories/apiKey.d.ts.map +1 -1
  81. package/dist/repositories/application.d.ts +1 -1
  82. package/dist/repositories/application.d.ts.map +1 -1
  83. package/dist/repositories/application.js +9 -3
  84. package/dist/repositories/application.js.map +1 -1
  85. package/dist/repositories/audit.d.ts.map +1 -1
  86. package/dist/repositories/index.d.ts +3 -0
  87. package/dist/repositories/index.d.ts.map +1 -1
  88. package/dist/repositories/index.js +3 -0
  89. package/dist/repositories/index.js.map +1 -1
  90. package/dist/repositories/mfaChallenge.d.ts +23 -0
  91. package/dist/repositories/mfaChallenge.d.ts.map +1 -0
  92. package/dist/repositories/mfaChallenge.js +71 -0
  93. package/dist/repositories/mfaChallenge.js.map +1 -0
  94. package/dist/repositories/oidcConnection.d.ts +27 -43
  95. package/dist/repositories/oidcConnection.d.ts.map +1 -1
  96. package/dist/repositories/oidcConnection.js +15 -6
  97. package/dist/repositories/oidcConnection.js.map +1 -1
  98. package/dist/repositories/organization.d.ts +9 -9
  99. package/dist/repositories/organization.d.ts.map +1 -1
  100. package/dist/repositories/organization.js +91 -37
  101. package/dist/repositories/organization.js.map +1 -1
  102. package/dist/repositories/permission.d.ts.map +1 -1
  103. package/dist/repositories/permission.js +27 -5
  104. package/dist/repositories/permission.js.map +1 -1
  105. package/dist/repositories/samlConnection.d.ts +28 -28
  106. package/dist/repositories/samlConnection.d.ts.map +1 -1
  107. package/dist/repositories/samlConnection.js +12 -4
  108. package/dist/repositories/samlConnection.js.map +1 -1
  109. package/dist/repositories/scimConnection.d.ts +38 -0
  110. package/dist/repositories/scimConnection.d.ts.map +1 -0
  111. package/dist/repositories/scimConnection.js +123 -0
  112. package/dist/repositories/scimConnection.js.map +1 -0
  113. package/dist/repositories/scimGroup.d.ts +36 -0
  114. package/dist/repositories/scimGroup.d.ts.map +1 -0
  115. package/dist/repositories/scimGroup.js +113 -0
  116. package/dist/repositories/scimGroup.js.map +1 -0
  117. package/dist/repositories/session.d.ts +24 -13
  118. package/dist/repositories/session.d.ts.map +1 -1
  119. package/dist/repositories/session.js +13 -1
  120. package/dist/repositories/session.js.map +1 -1
  121. package/dist/repositories/types.d.ts +117 -6
  122. package/dist/repositories/types.d.ts.map +1 -1
  123. package/dist/repositories/types.js +7 -1
  124. package/dist/repositories/types.js.map +1 -1
  125. package/dist/repositories/user.d.ts +23 -1
  126. package/dist/repositories/user.d.ts.map +1 -1
  127. package/dist/repositories/user.js +180 -4
  128. package/dist/repositories/user.js.map +1 -1
  129. package/dist/routes/admin/billing.js +4 -4
  130. package/dist/routes/admin/billing.js.map +1 -1
  131. package/dist/routes/admin/helpers.d.ts +16 -20
  132. package/dist/routes/admin/helpers.d.ts.map +1 -1
  133. package/dist/routes/admin/helpers.js +53 -10
  134. package/dist/routes/admin/helpers.js.map +1 -1
  135. package/dist/routes/admin/organizations.d.ts.map +1 -1
  136. package/dist/routes/admin/organizations.js +105 -69
  137. package/dist/routes/admin/organizations.js.map +1 -1
  138. package/dist/routes/admin/permissions.d.ts.map +1 -1
  139. package/dist/routes/admin/permissions.js +48 -14
  140. package/dist/routes/admin/permissions.js.map +1 -1
  141. package/dist/routes/admin/platform.d.ts.map +1 -1
  142. package/dist/routes/admin/platform.js +86 -35
  143. package/dist/routes/admin/platform.js.map +1 -1
  144. package/dist/routes/admin/sso.d.ts.map +1 -1
  145. package/dist/routes/admin/sso.js +143 -12
  146. package/dist/routes/admin/sso.js.map +1 -1
  147. package/dist/routes/admin/webhooks.js +8 -8
  148. package/dist/routes/admin/webhooks.js.map +1 -1
  149. package/dist/routes/apiKeys.d.ts.map +1 -1
  150. package/dist/routes/apiKeys.js +23 -5
  151. package/dist/routes/apiKeys.js.map +1 -1
  152. package/dist/routes/auth.d.ts.map +1 -1
  153. package/dist/routes/auth.js +112 -22
  154. package/dist/routes/auth.js.map +1 -1
  155. package/dist/routes/authz.d.ts.map +1 -1
  156. package/dist/routes/authz.js +16 -4
  157. package/dist/routes/authz.js.map +1 -1
  158. package/dist/routes/config.d.ts.map +1 -1
  159. package/dist/routes/config.js +16 -14
  160. package/dist/routes/config.js.map +1 -1
  161. package/dist/routes/federation.d.ts.map +1 -1
  162. package/dist/routes/federation.js +17 -3
  163. package/dist/routes/federation.js.map +1 -1
  164. package/dist/routes/magicLinks.d.ts.map +1 -1
  165. package/dist/routes/magicLinks.js +15 -3
  166. package/dist/routes/magicLinks.js.map +1 -1
  167. package/dist/routes/oauth.d.ts.map +1 -1
  168. package/dist/routes/oauth.js +60 -5
  169. package/dist/routes/oauth.js.map +1 -1
  170. package/dist/routes/oauth2.d.ts.map +1 -1
  171. package/dist/routes/oauth2.js +188 -22
  172. package/dist/routes/oauth2.js.map +1 -1
  173. package/dist/routes/oidcEnterprise.d.ts.map +1 -1
  174. package/dist/routes/oidcEnterprise.js +67 -21
  175. package/dist/routes/oidcEnterprise.js.map +1 -1
  176. package/dist/routes/password.d.ts.map +1 -1
  177. package/dist/routes/password.js.map +1 -1
  178. package/dist/routes/profile.js +4 -4
  179. package/dist/routes/profile.js.map +1 -1
  180. package/dist/routes/saml.d.ts +33 -0
  181. package/dist/routes/saml.d.ts.map +1 -1
  182. package/dist/routes/saml.js +217 -12
  183. package/dist/routes/saml.js.map +1 -1
  184. package/dist/routes/scim.d.ts +13 -0
  185. package/dist/routes/scim.d.ts.map +1 -1
  186. package/dist/routes/scim.js +885 -110
  187. package/dist/routes/scim.js.map +1 -1
  188. package/dist/routes/sdk.d.ts.map +1 -1
  189. package/dist/routes/sdk.js +24 -8
  190. package/dist/routes/sdk.js.map +1 -1
  191. package/dist/routes/serviceAccounts.d.ts.map +1 -1
  192. package/dist/routes/serviceAccounts.js +63 -2
  193. package/dist/routes/serviceAccounts.js.map +1 -1
  194. package/dist/routes/setup.d.ts.map +1 -1
  195. package/dist/routes/setup.js +15 -16
  196. package/dist/routes/setup.js.map +1 -1
  197. package/dist/routes/smsOtp.js +1 -1
  198. package/dist/routes/smsOtp.js.map +1 -1
  199. package/dist/routes/totp.d.ts.map +1 -1
  200. package/dist/routes/totp.js +112 -23
  201. package/dist/routes/totp.js.map +1 -1
  202. package/dist/routes/webauthn.d.ts.map +1 -1
  203. package/dist/routes/webauthn.js +44 -8
  204. package/dist/routes/webauthn.js.map +1 -1
  205. package/dist/routes/workflows.d.ts.map +1 -1
  206. package/dist/routes/workflows.js +58 -25
  207. package/dist/routes/workflows.js.map +1 -1
  208. package/dist/sdk/index.d.ts.map +1 -1
  209. package/dist/sdk/index.js +141 -40
  210. package/dist/sdk/index.js.map +1 -1
  211. package/dist/sdk/types.d.ts +64 -30
  212. package/dist/sdk/types.d.ts.map +1 -1
  213. package/dist/services/application/authentication.d.ts +39 -1
  214. package/dist/services/application/authentication.d.ts.map +1 -1
  215. package/dist/services/application/authentication.js +43 -1
  216. package/dist/services/application/authentication.js.map +1 -1
  217. package/dist/services/application/identity.d.ts +10 -7
  218. package/dist/services/application/identity.d.ts.map +1 -1
  219. package/dist/services/application/identity.js +13 -10
  220. package/dist/services/application/identity.js.map +1 -1
  221. package/dist/services/application/organization.d.ts +16 -8
  222. package/dist/services/application/organization.d.ts.map +1 -1
  223. package/dist/services/application/organization.js +160 -12
  224. package/dist/services/application/organization.js.map +1 -1
  225. package/dist/services/applications.js +2 -2
  226. package/dist/services/applications.js.map +1 -1
  227. package/dist/services/audit.d.ts +1 -0
  228. package/dist/services/audit.d.ts.map +1 -1
  229. package/dist/services/audit.js +13 -0
  230. package/dist/services/audit.js.map +1 -1
  231. package/dist/services/cache.d.ts.map +1 -1
  232. package/dist/services/configuration/profiles.d.ts +4 -0
  233. package/dist/services/configuration/profiles.d.ts.map +1 -1
  234. package/dist/services/configuration/profiles.js +50 -0
  235. package/dist/services/configuration/profiles.js.map +1 -1
  236. package/dist/services/configuration.d.ts.map +1 -1
  237. package/dist/services/configuration.js.map +1 -1
  238. package/dist/services/connectors/google.d.ts +18 -1
  239. package/dist/services/connectors/google.d.ts.map +1 -1
  240. package/dist/services/connectors/google.js +27 -4
  241. package/dist/services/connectors/google.js.map +1 -1
  242. package/dist/services/connectors/oidc.d.ts +14 -2
  243. package/dist/services/connectors/oidc.d.ts.map +1 -1
  244. package/dist/services/connectors/oidc.js +35 -6
  245. package/dist/services/connectors/oidc.js.map +1 -1
  246. package/dist/services/connectors/types.d.ts +13 -1
  247. package/dist/services/connectors/types.d.ts.map +1 -1
  248. package/dist/services/connectors/zitadel.d.ts.map +1 -1
  249. package/dist/services/connectors/zitadel.js +4 -3
  250. package/dist/services/connectors/zitadel.js.map +1 -1
  251. package/dist/services/domain/authentication.d.ts +43 -4
  252. package/dist/services/domain/authentication.d.ts.map +1 -1
  253. package/dist/services/domain/authentication.js +119 -40
  254. package/dist/services/domain/authentication.js.map +1 -1
  255. package/dist/services/domain/authorization.d.ts +11 -0
  256. package/dist/services/domain/authorization.d.ts.map +1 -1
  257. package/dist/services/domain/authorization.js +36 -1
  258. package/dist/services/domain/authorization.js.map +1 -1
  259. package/dist/services/domain/identity.d.ts +21 -9
  260. package/dist/services/domain/identity.d.ts.map +1 -1
  261. package/dist/services/domain/identity.js +187 -10
  262. package/dist/services/domain/identity.js.map +1 -1
  263. package/dist/services/domain/organization.d.ts +11 -10
  264. package/dist/services/domain/organization.d.ts.map +1 -1
  265. package/dist/services/domain/organization.js +48 -30
  266. package/dist/services/domain/organization.js.map +1 -1
  267. package/dist/services/emailVerification.d.ts +2 -2
  268. package/dist/services/enterpriseSso.d.ts +13 -6
  269. package/dist/services/enterpriseSso.d.ts.map +1 -1
  270. package/dist/services/enterpriseSso.js +75 -6
  271. package/dist/services/enterpriseSso.js.map +1 -1
  272. package/dist/services/events/subscribers/auditLog.js +1 -1
  273. package/dist/services/events/subscribers/auditLog.js.map +1 -1
  274. package/dist/services/events/types.d.ts +7 -1
  275. package/dist/services/events/types.d.ts.map +1 -1
  276. package/dist/services/events/types.js.map +1 -1
  277. package/dist/services/events/validate.d.ts.map +1 -1
  278. package/dist/services/events/validate.js +33 -0
  279. package/dist/services/events/validate.js.map +1 -1
  280. package/dist/services/features.d.ts.map +1 -1
  281. package/dist/services/features.js.map +1 -1
  282. package/dist/services/federation.d.ts +6 -1
  283. package/dist/services/federation.d.ts.map +1 -1
  284. package/dist/services/federation.js +31 -4
  285. package/dist/services/federation.js.map +1 -1
  286. package/dist/services/ipControls.js +2 -2
  287. package/dist/services/ipControls.js.map +1 -1
  288. package/dist/services/magicLinks.d.ts +2 -2
  289. package/dist/services/magicLinks.d.ts.map +1 -1
  290. package/dist/services/magicLinks.js +13 -9
  291. package/dist/services/magicLinks.js.map +1 -1
  292. package/dist/services/mfa.d.ts +53 -0
  293. package/dist/services/mfa.d.ts.map +1 -0
  294. package/dist/services/mfa.js +157 -0
  295. package/dist/services/mfa.js.map +1 -0
  296. package/dist/services/oauth2.d.ts +88 -14
  297. package/dist/services/oauth2.d.ts.map +1 -1
  298. package/dist/services/oauth2.js +125 -16
  299. package/dist/services/oauth2.js.map +1 -1
  300. package/dist/services/oidcSecretFormat.d.ts +3 -0
  301. package/dist/services/oidcSecretFormat.d.ts.map +1 -0
  302. package/dist/services/oidcSecretFormat.js +5 -0
  303. package/dist/services/oidcSecretFormat.js.map +1 -0
  304. package/dist/services/organizations.d.ts +4 -16
  305. package/dist/services/organizations.d.ts.map +1 -1
  306. package/dist/services/organizations.js +0 -62
  307. package/dist/services/organizations.js.map +1 -1
  308. package/dist/services/permissions.d.ts.map +1 -1
  309. package/dist/services/permissions.js +9 -1
  310. package/dist/services/permissions.js.map +1 -1
  311. package/dist/services/plugins/registry.d.ts.map +1 -1
  312. package/dist/services/plugins/registry.js.map +1 -1
  313. package/dist/services/plugins/types.d.ts.map +1 -1
  314. package/dist/services/queue/bullmq.d.ts.map +1 -1
  315. package/dist/services/queue/inProcess.d.ts.map +1 -1
  316. package/dist/services/redirectUri.d.ts +56 -0
  317. package/dist/services/redirectUri.d.ts.map +1 -0
  318. package/dist/services/redirectUri.js +129 -0
  319. package/dist/services/redirectUri.js.map +1 -0
  320. package/dist/services/redis.d.ts +1 -1
  321. package/dist/services/redis.d.ts.map +1 -1
  322. package/dist/services/scimCredentials.d.ts +46 -0
  323. package/dist/services/scimCredentials.d.ts.map +1 -0
  324. package/dist/services/scimCredentials.js +123 -0
  325. package/dist/services/scimCredentials.js.map +1 -0
  326. package/dist/services/scimLegacyMigration.d.ts +12 -0
  327. package/dist/services/scimLegacyMigration.d.ts.map +1 -0
  328. package/dist/services/scimLegacyMigration.js +44 -0
  329. package/dist/services/scimLegacyMigration.js.map +1 -0
  330. package/dist/services/secrets/awsKms.d.ts +2 -2
  331. package/dist/services/secrets/awsKms.d.ts.map +1 -1
  332. package/dist/services/secrets/awsKms.js +3 -5
  333. package/dist/services/secrets/awsKms.js.map +1 -1
  334. package/dist/services/secrets/azureKeyVault.d.ts.map +1 -1
  335. package/dist/services/secrets/database.d.ts.map +1 -1
  336. package/dist/services/secrets/database.js.map +1 -1
  337. package/dist/services/secrets/environment.d.ts.map +1 -1
  338. package/dist/services/secrets/environment.js.map +1 -1
  339. package/dist/services/secrets/index.d.ts.map +1 -1
  340. package/dist/services/secrets/password.d.ts.map +1 -1
  341. package/dist/services/secrets/password.js +0 -4
  342. package/dist/services/secrets/password.js.map +1 -1
  343. package/dist/services/secrets/provider.d.ts +2 -3
  344. package/dist/services/secrets/provider.d.ts.map +1 -1
  345. package/dist/services/secrets/vault.d.ts.map +1 -1
  346. package/dist/services/serviceAccounts.d.ts +20 -0
  347. package/dist/services/serviceAccounts.d.ts.map +1 -1
  348. package/dist/services/serviceAccounts.js +47 -1
  349. package/dist/services/serviceAccounts.js.map +1 -1
  350. package/dist/services/sessionRevocation.d.ts +76 -0
  351. package/dist/services/sessionRevocation.d.ts.map +1 -0
  352. package/dist/services/sessionRevocation.js +86 -0
  353. package/dist/services/sessionRevocation.js.map +1 -0
  354. package/dist/services/setup/configWriter.d.ts.map +1 -1
  355. package/dist/services/setup/configWriter.js.map +1 -1
  356. package/dist/services/singleUse.d.ts +68 -0
  357. package/dist/services/singleUse.d.ts.map +1 -0
  358. package/dist/services/singleUse.js +54 -0
  359. package/dist/services/singleUse.js.map +1 -0
  360. package/dist/services/smsOtp.d.ts.map +1 -1
  361. package/dist/services/smsOtp.js +12 -8
  362. package/dist/services/smsOtp.js.map +1 -1
  363. package/dist/services/ssoEndpointPolicy.d.ts +8 -0
  364. package/dist/services/ssoEndpointPolicy.d.ts.map +1 -0
  365. package/dist/services/ssoEndpointPolicy.js +136 -0
  366. package/dist/services/ssoEndpointPolicy.js.map +1 -0
  367. package/dist/services/stepUp.d.ts +35 -0
  368. package/dist/services/stepUp.d.ts.map +1 -0
  369. package/dist/services/stepUp.js +65 -0
  370. package/dist/services/stepUp.js.map +1 -0
  371. package/dist/services/tokens.d.ts +39 -11
  372. package/dist/services/tokens.d.ts.map +1 -1
  373. package/dist/services/tokens.js +80 -14
  374. package/dist/services/tokens.js.map +1 -1
  375. package/dist/services/totp.d.ts +46 -0
  376. package/dist/services/totp.d.ts.map +1 -1
  377. package/dist/services/totp.js +178 -41
  378. package/dist/services/totp.js.map +1 -1
  379. package/dist/services/trustedProxies.d.ts +90 -0
  380. package/dist/services/trustedProxies.d.ts.map +1 -0
  381. package/dist/services/trustedProxies.js +283 -0
  382. package/dist/services/trustedProxies.js.map +1 -0
  383. package/dist/services/users.d.ts +20 -12
  384. package/dist/services/users.d.ts.map +1 -1
  385. package/dist/services/users.js +24 -51
  386. package/dist/services/users.js.map +1 -1
  387. package/dist/services/webauthn.d.ts +8 -4
  388. package/dist/services/webauthn.d.ts.map +1 -1
  389. package/dist/services/webauthn.js +4 -4
  390. package/dist/services/webauthn.js.map +1 -1
  391. package/dist/services/webhooks.d.ts +20 -20
  392. package/dist/services/workflows/engine.d.ts +4 -2
  393. package/dist/services/workflows/engine.d.ts.map +1 -1
  394. package/dist/services/workflows/engine.js +181 -12
  395. package/dist/services/workflows/engine.js.map +1 -1
  396. package/dist/services/workflows/steps.d.ts +2 -0
  397. package/dist/services/workflows/steps.d.ts.map +1 -1
  398. package/dist/services/workflows/steps.js +8 -75
  399. package/dist/services/workflows/steps.js.map +1 -1
  400. package/dist/setup-server.js +2 -1
  401. package/dist/setup-server.js.map +1 -1
  402. package/dist/types.d.ts +33 -4
  403. package/dist/types.d.ts.map +1 -1
  404. package/dist/types.js +26 -2
  405. package/dist/types.js.map +1 -1
  406. package/package.json +25 -3
  407. package/dist/tests/errors.test.d.ts +0 -2
  408. package/dist/tests/errors.test.d.ts.map +0 -1
  409. package/dist/tests/errors.test.js +0 -64
  410. package/dist/tests/errors.test.js.map +0 -1
  411. package/dist/tests/events.test.d.ts +0 -2
  412. package/dist/tests/events.test.d.ts.map +0 -1
  413. package/dist/tests/events.test.js +0 -45
  414. package/dist/tests/events.test.js.map +0 -1
  415. package/dist/tests/featureFlags.test.d.ts +0 -2
  416. package/dist/tests/featureFlags.test.d.ts.map +0 -1
  417. package/dist/tests/featureFlags.test.js +0 -24
  418. package/dist/tests/featureFlags.test.js.map +0 -1
  419. package/dist/tests/integration/queue.test.d.ts +0 -2
  420. package/dist/tests/integration/queue.test.d.ts.map +0 -1
  421. package/dist/tests/integration/queue.test.js +0 -49
  422. package/dist/tests/integration/queue.test.js.map +0 -1
  423. package/dist/tests/plugins.test.d.ts +0 -2
  424. package/dist/tests/plugins.test.d.ts.map +0 -1
  425. package/dist/tests/plugins.test.js +0 -56
  426. package/dist/tests/plugins.test.js.map +0 -1
  427. package/dist/tests/result.test.d.ts +0 -2
  428. package/dist/tests/result.test.d.ts.map +0 -1
  429. package/dist/tests/result.test.js +0 -46
  430. package/dist/tests/result.test.js.map +0 -1
  431. package/dist/tests/setup/configWriter.test.d.ts +0 -2
  432. package/dist/tests/setup/configWriter.test.d.ts.map +0 -1
  433. package/dist/tests/setup/configWriter.test.js +0 -55
  434. package/dist/tests/setup/configWriter.test.js.map +0 -1
  435. package/dist/tests/setup/validation.test.d.ts +0 -2
  436. package/dist/tests/setup/validation.test.d.ts.map +0 -1
  437. package/dist/tests/setup/validation.test.js +0 -26
  438. package/dist/tests/setup/validation.test.js.map +0 -1
  439. package/dist/tests/smoke.test.d.ts +0 -2
  440. package/dist/tests/smoke.test.d.ts.map +0 -1
  441. package/dist/tests/smoke.test.js +0 -124
  442. package/dist/tests/smoke.test.js.map +0 -1
  443. package/src/cli.ts +0 -172
  444. package/src/config.ts +0 -143
  445. package/src/container.ts +0 -48
  446. package/src/db/index.ts +0 -53
  447. package/src/db/migrations/0000_skinny_ben_parker.sql +0 -553
  448. package/src/db/migrations/0001_brief_joseph.sql +0 -10
  449. package/src/db/migrations/0002_add_account_lockout.sql +0 -3
  450. package/src/db/migrations/0003_steep_rachel_grey.sql +0 -1
  451. package/src/db/migrations/0004_clever_bill_hollister.sql +0 -20
  452. package/src/db/migrations/0005_steep_the_call.sql +0 -2
  453. package/src/db/migrations/0006_ambitious_boomer.sql +0 -17
  454. package/src/db/migrations/0007_greedy_vindicator.sql +0 -40
  455. package/src/db/migrations/meta/0000_snapshot.json +0 -2964
  456. package/src/db/migrations/meta/0001_snapshot.json +0 -3031
  457. package/src/db/migrations/meta/0003_snapshot.json +0 -3051
  458. package/src/db/migrations/meta/_journal.json +0 -62
  459. package/src/db/schema.ts +0 -676
  460. package/src/db/seed.ts +0 -146
  461. package/src/di.ts +0 -81
  462. package/src/index.ts +0 -326
  463. package/src/lib/errors.ts +0 -139
  464. package/src/lib/result.ts +0 -44
  465. package/src/lib/webhookSignature.ts +0 -41
  466. package/src/plugins/appContext.ts +0 -76
  467. package/src/plugins/audit.ts +0 -42
  468. package/src/plugins/auth.ts +0 -230
  469. package/src/plugins/metrics.ts +0 -41
  470. package/src/plugins/mtls.ts +0 -94
  471. package/src/plugins/permissions.ts +0 -29
  472. package/src/plugins/rateLimit.ts +0 -133
  473. package/src/plugins/requestLogger.ts +0 -25
  474. package/src/plugins/tracing.ts +0 -22
  475. package/src/repositories/apiKey.ts +0 -158
  476. package/src/repositories/application.ts +0 -70
  477. package/src/repositories/audit.ts +0 -32
  478. package/src/repositories/index.ts +0 -9
  479. package/src/repositories/oidcConnection.ts +0 -111
  480. package/src/repositories/organization.ts +0 -167
  481. package/src/repositories/permission.ts +0 -153
  482. package/src/repositories/samlConnection.ts +0 -96
  483. package/src/repositories/session.ts +0 -86
  484. package/src/repositories/types.ts +0 -134
  485. package/src/repositories/user.ts +0 -161
  486. package/src/routes/admin/billing.ts +0 -48
  487. package/src/routes/admin/helpers.ts +0 -50
  488. package/src/routes/admin/index.ts +0 -16
  489. package/src/routes/admin/organizations.ts +0 -299
  490. package/src/routes/admin/permissions.ts +0 -80
  491. package/src/routes/admin/platform.ts +0 -335
  492. package/src/routes/admin/sso.ts +0 -138
  493. package/src/routes/admin/webhooks.ts +0 -73
  494. package/src/routes/admin.ts +0 -1
  495. package/src/routes/apiKeys.ts +0 -60
  496. package/src/routes/auth.ts +0 -214
  497. package/src/routes/authz.ts +0 -38
  498. package/src/routes/config.ts +0 -67
  499. package/src/routes/emailVerification.ts +0 -73
  500. package/src/routes/federation.ts +0 -156
  501. package/src/routes/helpers.ts +0 -17
  502. package/src/routes/magicLinks.ts +0 -107
  503. package/src/routes/oauth.ts +0 -167
  504. package/src/routes/oauth2.ts +0 -284
  505. package/src/routes/oidcEnterprise.ts +0 -166
  506. package/src/routes/password.ts +0 -90
  507. package/src/routes/profile.ts +0 -44
  508. package/src/routes/saml.ts +0 -209
  509. package/src/routes/scim.ts +0 -199
  510. package/src/routes/sdk.ts +0 -141
  511. package/src/routes/serviceAccounts.ts +0 -124
  512. package/src/routes/sessions.ts +0 -62
  513. package/src/routes/setup.ts +0 -315
  514. package/src/routes/smsOtp.ts +0 -67
  515. package/src/routes/totp.ts +0 -122
  516. package/src/routes/webauthn.ts +0 -147
  517. package/src/routes/workflows.ts +0 -157
  518. package/src/sdk/index.ts +0 -152
  519. package/src/sdk/types.ts +0 -54
  520. package/src/services/anomalyDetection.ts +0 -73
  521. package/src/services/application/authentication.ts +0 -75
  522. package/src/services/application/identity.ts +0 -56
  523. package/src/services/application/index.ts +0 -3
  524. package/src/services/application/organization.ts +0 -77
  525. package/src/services/applications.ts +0 -89
  526. package/src/services/audit.ts +0 -41
  527. package/src/services/auditExport.ts +0 -59
  528. package/src/services/billing.ts +0 -87
  529. package/src/services/cache.ts +0 -131
  530. package/src/services/configuration/profiles.ts +0 -115
  531. package/src/services/configuration.ts +0 -120
  532. package/src/services/connectors/google.ts +0 -92
  533. package/src/services/connectors/oidc.ts +0 -111
  534. package/src/services/connectors/registry.ts +0 -124
  535. package/src/services/connectors/types.ts +0 -38
  536. package/src/services/connectors/zitadel.ts +0 -77
  537. package/src/services/devices.ts +0 -76
  538. package/src/services/domain/authentication.ts +0 -279
  539. package/src/services/domain/authorization.ts +0 -49
  540. package/src/services/domain/identity.ts +0 -108
  541. package/src/services/domain/index.ts +0 -4
  542. package/src/services/domain/organization.ts +0 -114
  543. package/src/services/email.ts +0 -167
  544. package/src/services/emailVerification.ts +0 -75
  545. package/src/services/enterpriseSso.ts +0 -58
  546. package/src/services/events/bus.ts +0 -43
  547. package/src/services/events/subscribers/anomaly.ts +0 -13
  548. package/src/services/events/subscribers/auditLog.ts +0 -21
  549. package/src/services/events/subscribers/webhook.ts +0 -39
  550. package/src/services/events/subscribers/webhookDispatch.ts +0 -14
  551. package/src/services/events/types.ts +0 -106
  552. package/src/services/events/validate.ts +0 -118
  553. package/src/services/featureFlags.ts +0 -90
  554. package/src/services/features.ts +0 -22
  555. package/src/services/federation.ts +0 -30
  556. package/src/services/hibp.ts +0 -28
  557. package/src/services/ipControls.ts +0 -99
  558. package/src/services/magicLinks.ts +0 -51
  559. package/src/services/oauth2.ts +0 -216
  560. package/src/services/organizations.ts +0 -171
  561. package/src/services/permissions.ts +0 -146
  562. package/src/services/plugins/registry.ts +0 -242
  563. package/src/services/plugins/types.ts +0 -98
  564. package/src/services/queue/bullmq.ts +0 -104
  565. package/src/services/queue/inProcess.ts +0 -75
  566. package/src/services/queue/index.ts +0 -19
  567. package/src/services/queue/types.ts +0 -26
  568. package/src/services/redis.ts +0 -16
  569. package/src/services/secrets/awsKms.ts +0 -97
  570. package/src/services/secrets/azureKeyVault.ts +0 -171
  571. package/src/services/secrets/database.ts +0 -166
  572. package/src/services/secrets/environment.ts +0 -117
  573. package/src/services/secrets/index.ts +0 -50
  574. package/src/services/secrets/password.ts +0 -73
  575. package/src/services/secrets/provider.ts +0 -36
  576. package/src/services/secrets/vault.ts +0 -149
  577. package/src/services/secrets.ts +0 -2
  578. package/src/services/serviceAccounts.ts +0 -74
  579. package/src/services/setup/configWriter.ts +0 -200
  580. package/src/services/setup/diagnostics.ts +0 -76
  581. package/src/services/setup/token.ts +0 -42
  582. package/src/services/setup/types.ts +0 -40
  583. package/src/services/setup/validation.ts +0 -205
  584. package/src/services/sms.ts +0 -81
  585. package/src/services/smsOtp.ts +0 -74
  586. package/src/services/tokens.ts +0 -287
  587. package/src/services/totp.ts +0 -113
  588. package/src/services/users.ts +0 -239
  589. package/src/services/webauthn.ts +0 -193
  590. package/src/services/webhooks.ts +0 -190
  591. package/src/services/workflows/engine.ts +0 -125
  592. package/src/services/workflows/steps.ts +0 -129
  593. package/src/services/zitadel.ts +0 -277
  594. package/src/setup-server.ts +0 -71
  595. package/src/tests/errors.test.ts +0 -74
  596. package/src/tests/events.test.ts +0 -52
  597. package/src/tests/featureFlags.test.ts +0 -26
  598. package/src/tests/integration/queue.test.ts +0 -54
  599. package/src/tests/plugins.test.ts +0 -73
  600. package/src/tests/result.test.ts +0 -52
  601. package/src/tests/setup/configWriter.test.ts +0 -69
  602. package/src/tests/setup/validation.test.ts +0 -29
  603. package/src/tests/smoke.test.ts +0 -136
  604. package/src/types.ts +0 -70
@@ -0,0 +1,15 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ /**
3
+ * Runs before routing, authentication, and every route handler.
4
+ *
5
+ * Identity-bearing headers are removed from any request that did not arrive
6
+ * from a configured trusted proxy. Stripping — rather than merely ignoring the
7
+ * headers where we happen to check them — means no route, plugin, or future
8
+ * feature can read a spoofed identity by accident.
9
+ *
10
+ * With no trusted proxies configured, this strips unconditionally, which is
11
+ * the safe default.
12
+ */
13
+ declare const _default: (app: FastifyInstance) => Promise<void>;
14
+ export default _default;
15
+ //# sourceMappingURL=headerSanitization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headerSanitization.d.ts","sourceRoot":"","sources":["../../src/plugins/headerSanitization.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQ/C;;;;;;;;;;GAUG;8BAC4D,eAAe"}
@@ -0,0 +1,39 @@
1
+ import fp from "fastify-plugin";
2
+ import { describeUntrustedPeer, hasTrustedProxies, peerAddress, stripUntrustedHeaders, } from "../services/trustedProxies.js";
3
+ /**
4
+ * Runs before routing, authentication, and every route handler.
5
+ *
6
+ * Identity-bearing headers are removed from any request that did not arrive
7
+ * from a configured trusted proxy. Stripping — rather than merely ignoring the
8
+ * headers where we happen to check them — means no route, plugin, or future
9
+ * feature can read a spoofed identity by accident.
10
+ *
11
+ * With no trusted proxies configured, this strips unconditionally, which is
12
+ * the safe default.
13
+ */
14
+ export default fp(async function headerSanitizationPlugin(app) {
15
+ let warned = false;
16
+ app.addHook("onRequest", async (request) => {
17
+ const trusted = stripUntrustedHeaders(request);
18
+ if (trusted)
19
+ return;
20
+ request.log.debug({ peer: peerAddress(request) }, "stripped untrusted client-identity headers");
21
+ // The one stripping outcome that indicates a broken deployment rather than
22
+ // a hostile client: an infrastructure address arriving while no trusted
23
+ // proxy is configured. That state fails silently — every client shares one
24
+ // rate-limit budget — so say so once instead of leaving it to be guessed.
25
+ if (!warned) {
26
+ const reason = describeUntrustedPeer(peerAddress(request));
27
+ if (reason) {
28
+ warned = true;
29
+ request.log.warn({ peer: peerAddress(request) }, `mTLS/proxy trust boundary not configured: ${reason}`);
30
+ }
31
+ }
32
+ });
33
+ // State the trust posture at boot. A deployment that expected a proxy to be
34
+ // trusted should not have to discover the mistake from a support ticket.
35
+ app.log.info(hasTrustedProxies()
36
+ ? "client-identity headers will be honoured from configured trusted proxies"
37
+ : "no trusted proxies configured: client-identity headers will be stripped from every request");
38
+ });
39
+ //# sourceMappingURL=headerSanitization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headerSanitization.js","sourceRoot":"","sources":["../../src/plugins/headerSanitization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEhC,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,EACX,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AAEvC;;;;;;;;;;GAUG;AACH,eAAe,EAAE,CAAC,KAAK,UAAU,wBAAwB,CAAC,GAAoB;IAC5E,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACzC,MAAM,OAAO,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,OAAO;YAAE,OAAO;QAEpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,4CAA4C,CAAC,CAAC;QAEhG,2EAA2E;QAC3E,wEAAwE;QACxE,2EAA2E;QAC3E,0EAA0E;QAC1E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,qBAAqB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3D,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,GAAG,IAAI,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,IAAI,CACd,EAAE,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,EAC9B,6CAA6C,MAAM,EAAE,CACtD,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,4EAA4E;IAC5E,yEAAyE;IACzE,GAAG,CAAC,GAAG,CAAC,IAAI,CACV,iBAAiB,EAAE;QACjB,CAAC,CAAC,0EAA0E;QAC5E,CAAC,CAAC,4FAA4F,CACjG,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/plugins/metrics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAY,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE3D,eAAO,MAAM,iBAAiB,6CAI5B,CAAC;AAEH,eAAO,MAAM,0BAA0B,+CAKrC,CAAC;AAEH,eAAO,MAAM,iBAAiB,mBAI5B,CAAC;8BAEiD,eAAe;AAAnE,wBAiBG"}
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/plugins/metrics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAY,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE3D,eAAO,MAAM,iBAAiB,6CAI5B,CAAC;AAEH,eAAO,MAAM,0BAA0B,+CAKrC,CAAC;AAEH,eAAO,MAAM,iBAAiB,mBAI5B,CAAC;8BAEiD,eAAe"}
@@ -4,11 +4,30 @@ declare module "fastify" {
4
4
  requireMTLS: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
5
5
  }
6
6
  }
7
- export declare function extractClientCert(request: FastifyRequest): {
7
+ export interface ClientCertEvidence {
8
8
  fingerprint?: string;
9
9
  subject?: string;
10
- };
10
+ /** Whether the evidence came from a configured trusted proxy. */
11
+ trusted: boolean;
12
+ }
13
+ /**
14
+ * Read certificate evidence. Returns nothing when the peer is not a trusted
15
+ * proxy, even if the headers are present.
16
+ */
17
+ export declare function extractClientCert(request: FastifyRequest): ClientCertEvidence;
11
18
  export declare function requireMTLS(): (request: FastifyRequest, reply: FastifyReply) => Promise<undefined>;
12
19
  declare const _default: (app: FastifyInstance) => Promise<void>;
13
20
  export default _default;
21
+ /** Exported for tests: find any service account bound to a fingerprint. */
22
+ export declare function findServiceAccountByFingerprint(fingerprint: string): Promise<{
23
+ certFingerprint: string | null;
24
+ createdAt: Date;
25
+ description: string | null;
26
+ id: string;
27
+ isActive: boolean;
28
+ name: string;
29
+ orgId: string;
30
+ revokedAt: Date | null;
31
+ updatedAt: Date;
32
+ } | undefined>;
14
33
  //# sourceMappingURL=mtls.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mtls.d.ts","sourceRoot":"","sources":["../../src/plugins/mtls.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAuB7E,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,WAAW,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9E;CACF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAOrG;AAkCD,wBAAgB,WAAW,KACF,SAAS,cAAc,EAAE,OAAO,YAAY,wBAiBpE;8BAEgD,eAAe;AAAhE,wBAEG"}
1
+ {"version":3,"file":"mtls.d.ts","sourceRoot":"","sources":["../../src/plugins/mtls.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA2C7E,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,WAAW,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9E;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,kBAAkB,CAiB7E;AAyCD,wBAAgB,WAAW,cACO,cAAc,SAAS,YAAY,wBAuCpE;8BAEgD,eAAe;;AAIhE,2EAA2E;AAC3E,wBAAsB,+BAA+B,CAAC,WAAW,EAAE,MAAM;;;;;;;;;;eAExE"}
@@ -1,70 +1,112 @@
1
1
  import fp from "fastify-plugin";
2
- import { eq } from "drizzle-orm";
2
+ import { and, eq, isNull, or } from "drizzle-orm";
3
3
  import { db } from "../db/index.js";
4
4
  import { serviceAccounts } from "../db/schema.js";
5
+ import { canonicalFingerprint, isFromTrustedProxy, isValidFingerprint, peerAddress, } from "../services/trustedProxies.js";
5
6
  /**
6
- * mTLS authentication plugin.
7
+ * mTLS service-account authentication.
7
8
  *
8
- * In production, terminate TLS at a reverse proxy (nginx, envoy, AWS ALB, etc.)
9
- * that validates the client certificate and forwards the certificate fingerprint
10
- * or subject in a trusted header. This plugin reads that header and maps
11
- * certificates to service accounts.
9
+ * TLS is terminated at a reverse proxy that validates the client certificate.
10
+ * Keystone learns the result from headers the proxy sets — but only when the
11
+ * request actually came from that proxy.
12
12
  *
13
- * Headers read:
14
- * - x-client-cert-fingerprint: SHA-256 fingerprint of the client certificate
15
- * - x-forwarded-client-cert: PEM-encoded client certificate or DN subject
16
- * - x-service-account-id: Optional explicit service account ID (for non-mTLS fallback)
13
+ * Rules this plugin enforces:
14
+ *
15
+ * 1. **A header never establishes identity by itself.** Identity comes from a
16
+ * client certificate fingerprint that a trusted proxy forwarded, and that
17
+ * fingerprint is cryptographically bound to the service account in the
18
+ * database. The previous `x-service-account-id` shortcut is gone: it let any
19
+ * client name a service account and become it, with no certificate at all.
20
+ * 2. **A request that did not come from a trusted proxy has no certificate
21
+ * identity.** `x-service-account-id` is accepted only as a *hint*, and only
22
+ * when the request also presents a valid fingerprint; the hint is then
23
+ * cross-checked against that fingerprint's binding.
24
+ * 3. **A fingerprint must be a well-formed SHA-256 digest**, so a garbage or
25
+ * oversized header cannot be used as a lookup key.
26
+ *
27
+ * Service accounts without a bound fingerprint cannot authenticate by
28
+ * certificate at all.
17
29
  */
18
30
  const MTLS_HEADER = "x-forwarded-client-cert";
19
31
  const MTLS_FINGERPRINT_HEADER = "x-client-cert-fingerprint";
20
32
  const SERVICE_ACCOUNT_ID_HEADER = "x-service-account-id";
33
+ /** Cap on header length before parsing, so a hostile proxy cannot inflate work. */
34
+ const MAX_CERT_HEADER_LENGTH = 8192;
35
+ /**
36
+ * Read certificate evidence. Returns nothing when the peer is not a trusted
37
+ * proxy, even if the headers are present.
38
+ */
21
39
  export function extractClientCert(request) {
22
- const fingerprint = request.headers[MTLS_FINGERPRINT_HEADER];
23
- const cert = request.headers[MTLS_HEADER];
24
- return {
25
- fingerprint: typeof fingerprint === "string" ? fingerprint : undefined,
26
- subject: typeof cert === "string" ? cert : undefined,
27
- };
40
+ if (!isFromTrustedProxy(request))
41
+ return { trusted: false };
42
+ const rawFingerprint = request.headers[MTLS_FINGERPRINT_HEADER];
43
+ const rawCert = request.headers[MTLS_HEADER];
44
+ const fingerprint = typeof rawFingerprint === "string" && isValidFingerprint(rawFingerprint.trim())
45
+ ? canonicalFingerprint(rawFingerprint)
46
+ : undefined;
47
+ const subject = typeof rawCert === "string" && rawCert.length > 0 && rawCert.length <= MAX_CERT_HEADER_LENGTH
48
+ ? rawCert
49
+ : undefined;
50
+ return { fingerprint, subject, trusted: true };
28
51
  }
29
- async function resolveServiceAccount(request) {
30
- const explicitId = request.headers[SERVICE_ACCOUNT_ID_HEADER];
31
- if (typeof explicitId === "string" && explicitId) {
32
- const [sa] = await db
33
- .select()
34
- .from(serviceAccounts)
35
- .where(eq(serviceAccounts.id, explicitId))
36
- .limit(1);
37
- if (sa?.isActive) {
38
- return sa;
39
- }
40
- }
41
- const { fingerprint, subject } = extractClientCert(request);
42
- if (!fingerprint && !subject)
43
- return undefined;
44
- // Look up service accounts by name matching the fingerprint or subject.
45
- // In a production system, you would store the certificate fingerprint in
46
- // the service_accounts table and query by it directly.
47
- const [sa] = await db
52
+ /**
53
+ * Resolve a service account from a validated certificate fingerprint.
54
+ *
55
+ * The lookup is by `certFingerprint`, not by `name`: a name is operator-chosen
56
+ * and guessable, whereas the fingerprint is pinned to a certificate.
57
+ */
58
+ async function resolveByFingerprint(fingerprint) {
59
+ const [record] = await db
48
60
  .select()
49
61
  .from(serviceAccounts)
50
- .where(eq(serviceAccounts.name, fingerprint || subject || ""))
62
+ .where(and(eq(serviceAccounts.certFingerprint, fingerprint), eq(serviceAccounts.isActive, true), isNull(serviceAccounts.revokedAt)))
51
63
  .limit(1);
52
- if (sa?.isActive) {
53
- return sa;
54
- }
55
- return undefined;
64
+ return record;
65
+ }
66
+ /**
67
+ * Optional narrowing: when the proxy also named the service account, the named
68
+ * account must be the one bound to the presented certificate. A mismatch is a
69
+ * spoofing signal, not a fallback.
70
+ */
71
+ async function crossCheckHint(hintId, fingerprint) {
72
+ const [hinted] = await db
73
+ .select()
74
+ .from(serviceAccounts)
75
+ .where(and(eq(serviceAccounts.id, hintId), isNull(serviceAccounts.revokedAt)))
76
+ .limit(1);
77
+ if (!hinted)
78
+ return undefined;
79
+ if (hinted.certFingerprint && hinted.certFingerprint !== fingerprint)
80
+ return undefined;
81
+ return resolveByFingerprint(fingerprint);
56
82
  }
57
83
  export function requireMTLS() {
58
84
  return async function (request, reply) {
59
- const { fingerprint, subject } = extractClientCert(request);
60
- const explicitId = request.headers[SERVICE_ACCOUNT_ID_HEADER];
61
- if (!fingerprint && !subject && !explicitId) {
62
- return reply.status(401).send({ error: "Client certificate required" });
85
+ const evidence = extractClientCert(request);
86
+ if (!evidence.trusted) {
87
+ // Distinguish "not behind a proxy we trust" from "no certificate" so an
88
+ // operator can tell a misconfiguration from an attack.
89
+ return reply.status(401).send({
90
+ error: "Client certificate required",
91
+ code: isFromTrustedProxy(request) ? "MTLS_CERTIFICATE_MISSING" : "MTLS_UNTRUSTED_PEER",
92
+ });
63
93
  }
64
- const serviceAccount = await resolveServiceAccount(request);
94
+ if (!evidence.fingerprint) {
95
+ return reply.status(401).send({
96
+ error: "A valid client certificate fingerprint is required",
97
+ code: "MTLS_FINGERPRINT_MISSING",
98
+ });
99
+ }
100
+ const hint = request.headers[SERVICE_ACCOUNT_ID_HEADER];
101
+ const serviceAccount = typeof hint === "string" && hint
102
+ ? await crossCheckHint(hint, evidence.fingerprint)
103
+ : await resolveByFingerprint(evidence.fingerprint);
65
104
  if (!serviceAccount) {
66
- request.log.warn({ fingerprint, subject }, "mTLS: no matching service account found");
67
- return reply.status(403).send({ error: "Client certificate not mapped to a service account" });
105
+ request.log.warn({ fingerprint: evidence.fingerprint, peer: peerAddress(request) }, "mTLS: no active service account is bound to the presented certificate");
106
+ return reply.status(403).send({
107
+ error: "Client certificate not mapped to a service account",
108
+ code: "MTLS_CERTIFICATE_UNMAPPED",
109
+ });
68
110
  }
69
111
  request.serviceAccount = serviceAccount;
70
112
  request.log.debug({ serviceAccountId: serviceAccount.id }, "mTLS: service account authenticated");
@@ -73,4 +115,9 @@ export function requireMTLS() {
73
115
  export default fp(async function mtlsPlugin(app) {
74
116
  app.decorate("requireMTLS", requireMTLS());
75
117
  });
118
+ /** Exported for tests: find any service account bound to a fingerprint. */
119
+ export async function findServiceAccountByFingerprint(fingerprint) {
120
+ return resolveByFingerprint(canonicalFingerprint(fingerprint));
121
+ }
122
+ void or;
76
123
  //# sourceMappingURL=mtls.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mtls.js","sourceRoot":"","sources":["../../src/plugins/mtls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEhC,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,GAAG,yBAAyB,CAAC;AAC9C,MAAM,uBAAuB,GAAG,2BAA2B,CAAC;AAC5D,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAQzD,MAAM,UAAU,iBAAiB,CAAC,OAAuB;IACvD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1C,OAAO;QACL,WAAW,EAAE,OAAO,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;QACtE,OAAO,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;KACrD,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,OAAuB;IAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC9D,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,EAAE,CAAC;QACjD,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE;aAClB,MAAM,EAAE;aACR,IAAI,CAAC,eAAe,CAAC;aACrB,KAAK,CAAC,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;aACzC,KAAK,CAAC,CAAC,CAAC,CAAC;QACZ,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC;YACjB,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC5D,IAAI,CAAC,WAAW,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAE/C,wEAAwE;IACxE,yEAAyE;IACzE,uDAAuD;IACvD,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE;SAClB,MAAM,EAAE;SACR,IAAI,CAAC,eAAe,CAAC;SACrB,KAAK,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,WAAW,IAAI,OAAO,IAAI,EAAE,CAAC,CAAC;SAC7D,KAAK,CAAC,CAAC,CAAC,CAAC;IAEZ,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC;QACjB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,KAAK,WAAW,OAAuB,EAAE,KAAmB;QACjE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;QAE9D,IAAI,CAAC,WAAW,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5C,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,yCAAyC,CAAC,CAAC;YACtF,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oDAAoD,EAAE,CAAC,CAAC;QACjG,CAAC;QAED,OAAO,CAAC,cAAc,GAAG,cAAc,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,gBAAgB,EAAE,cAAc,CAAC,EAAE,EAAE,EAAE,qCAAqC,CAAC,CAAC;IACpG,CAAC,CAAC;AACJ,CAAC;AAED,eAAe,EAAE,CAAC,KAAK,UAAU,UAAU,CAAC,GAAoB;IAC9D,GAAG,CAAC,QAAQ,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"mtls.js","sourceRoot":"","sources":["../../src/plugins/mtls.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/plugins/permissions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAG7E,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC1H;CACF;8BAEuD,eAAe;AAAvE,wBAkBG"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/plugins/permissions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAG7E,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC1H;CACF;8BAEuD,eAAe"}
@@ -1,19 +1,39 @@
1
1
  import fp from "fastify-plugin";
2
- import { requirePermission } from "../services/permissions.js";
2
+ import { isOrganizationRole } from "../services/domain/authorization.js";
3
3
  export default fp(async function permissionsPlugin(app) {
4
4
  app.decorate("requirePermission", function (resource, action) {
5
5
  return async function (request, reply) {
6
- const membership = request.state?.membership;
7
- if (!membership) {
8
- return reply.status(403).send({ error: "Organization membership required" });
6
+ await request.server.authenticate(request, reply);
7
+ if (reply.sent)
8
+ return;
9
+ const { id: orgId } = request.params;
10
+ if (!orgId) {
11
+ return reply.status(403).send({ error: "Organization context required" });
9
12
  }
10
- try {
11
- await requirePermission(membership.role, resource, action);
13
+ const membership = await request.server.container.organizationRepository.findMembership(orgId, request.user.id);
14
+ if (!membership || !isOrganizationRole(membership.role)) {
15
+ await request.audit("unauthorized_access", {
16
+ action: "organization_permission_required",
17
+ orgId,
18
+ resource,
19
+ requiredAction: action,
20
+ });
21
+ return reply.status(403).send({ error: "Organization membership required" });
12
22
  }
13
- catch (err) {
14
- const message = err instanceof Error ? err.message : "Forbidden";
15
- return reply.status(403).send({ error: message });
23
+ const allowed = await request.server.container.permissionRepository.hasPermission(membership.role, resource, action);
24
+ if (!allowed) {
25
+ await request.audit("unauthorized_access", {
26
+ action: "organization_permission_required",
27
+ orgId,
28
+ resource,
29
+ requiredAction: action,
30
+ });
31
+ return reply.status(403).send({ error: `Missing permission ${resource}:${action}` });
16
32
  }
33
+ request.state.membership = membership;
34
+ const organization = await request.server.container.organizationRepository.findById(orgId);
35
+ if (organization)
36
+ request.state.org = organization;
17
37
  };
18
38
  });
19
39
  });
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/plugins/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEhC,OAAO,EAAE,iBAAiB,EAAuC,MAAM,4BAA4B,CAAC;AAQpG,eAAe,EAAE,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAoB;IACrE,GAAG,CAAC,QAAQ,CACV,mBAAmB,EACnB,UAAU,QAAgB,EAAE,MAAc;QACxC,OAAO,KAAK,WAAW,OAAuB,EAAE,KAAmB;YACjE,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC;YAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC,CAAC;YAC/E,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,iBAAiB,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC7D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC;gBACjE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YACpD,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/plugins/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAQzE,eAAe,EAAE,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAoB;IACrE,GAAG,CAAC,QAAQ,CACV,mBAAmB,EACnB,UAAU,QAAgB,EAAE,MAAc;QACxC,OAAO,KAAK,WAAW,OAAuB,EAAE,KAAmB;YACjE,MAAM,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAClD,IAAI,KAAK,CAAC,IAAI;gBAAE,OAAO;YAEvB,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,MAAyB,CAAC;YACxD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;YAC5E,CAAC;YAED,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,IAAK,CAAC,EAAE,CAAC,CAAC;YACjH,IAAI,CAAC,UAAU,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxD,MAAM,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE;oBACzC,MAAM,EAAE,kCAAkC;oBAC1C,KAAK;oBACL,QAAQ;oBACR,cAAc,EAAE,MAAM;iBACvB,CAAC,CAAC;gBACH,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC,CAAC;YAC/E,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACrH,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE;oBACzC,MAAM,EAAE,kCAAkC;oBAC1C,KAAK;oBACL,QAAQ;oBACR,cAAc,EAAE,MAAM;iBACvB,CAAC,CAAC;gBACH,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,QAAQ,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;YACvF,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;YACtC,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC3F,IAAI,YAAY;gBAAE,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,YAAY,CAAC;QACrD,CAAC,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -1,14 +1,30 @@
1
1
  import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
2
+ import { clientAddress } from "../services/trustedProxies.js";
2
3
  interface RateLimitPluginOptions {
3
4
  keyPrefix: string;
4
5
  maxAttempts: number;
5
6
  windowSeconds: number;
7
+ /**
8
+ * Override how the caller is identified. Used where the meaningful principal
9
+ * is not an IP address — for example SCIM, which is limited per credential so
10
+ * one noisy identity provider cannot exhaust the budget of every other tenant.
11
+ */
12
+ keyFrom?: (request: FastifyRequest) => string;
6
13
  }
7
14
  export interface GlobalRateLimitOptions {
8
15
  maxRequests?: number;
9
16
  windowSeconds?: number;
10
17
  keyPrefix?: string;
11
18
  }
19
+ declare function isAllowed(key: string, maxAttempts: number, windowSeconds: number): Promise<boolean>;
20
+ /**
21
+ * Re-exported so a route that must run before the normal limiter (because it
22
+ * emits audit events on failure) can still budget itself rather than being
23
+ * unbounded.
24
+ */
25
+ export { clientAddress };
26
+ /** Raw sliding-window check, for the same pre-limiter case. */
27
+ export { isAllowed };
12
28
  export declare function rateLimit(options: RateLimitPluginOptions): (request: FastifyRequest, reply: FastifyReply) => Promise<undefined>;
13
29
  export declare function globalRateLimit(options?: GlobalRateLimitOptions): (request: FastifyRequest, reply: FastifyReply) => Promise<undefined>;
14
30
  export declare function appRateLimit(options: {
@@ -1 +1 @@
1
- {"version":3,"file":"rateLimit.d.ts","sourceRoot":"","sources":["../../src/plugins/rateLimit.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG7E,UAAU,sBAAsB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkED,wBAAgB,SAAS,CAAC,OAAO,EAAE,sBAAsB,IACtB,SAAS,cAAc,EAAE,OAAO,YAAY,wBAW9E;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,IAKlC,SAAS,cAAc,EAAE,OAAO,YAAY,wBAW7E;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,IACjD,SAAS,cAAc,EAAE,OAAO,YAAY,wBAY9E;8BAEqD,eAAe;AAArE,wBAIG"}
1
+ {"version":3,"file":"rateLimit.d.ts","sourceRoot":"","sources":["../../src/plugins/rateLimit.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE7E,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,UAAU,sBAAsB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,MAAM,CAAC;CAC/C;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA4BD,iBAAe,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAyBlG;AAeD;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,+DAA+D;AAC/D,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,wBAAgB,SAAS,CAAC,OAAO,EAAE,sBAAsB,aACb,cAAc,SAAS,YAAY,wBAW9E;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,aAKzB,cAAc,SAAS,YAAY,wBAW7E;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,aACxC,cAAc,SAAS,YAAY,wBAY9E;8BAEqD,eAAe"}
@@ -1,6 +1,7 @@
1
1
  import crypto from "node:crypto";
2
2
  import fp from "fastify-plugin";
3
3
  import { redis, isRedisReady } from "../services/redis.js";
4
+ import { clientAddress } from "../services/trustedProxies.js";
4
5
  /**
5
6
  * Atomic sliding-window rate limit script.
6
7
  *
@@ -46,13 +47,25 @@ async function isAllowed(key, maxAttempts, windowSeconds) {
46
47
  function cryptoRandom() {
47
48
  return crypto.randomBytes(8).toString("hex");
48
49
  }
50
+ /**
51
+ * Rate-limit key source. Uses the peer address unless the request came from a
52
+ * configured trusted proxy, so a client cannot rotate `x-forwarded-for` to get a
53
+ * fresh budget.
54
+ */
49
55
  function clientIdentifier(request) {
50
- return (request.headers["x-forwarded-for"]?.split(",")[0]?.trim() ||
51
- request.ip);
56
+ return clientAddress(request);
52
57
  }
58
+ /**
59
+ * Re-exported so a route that must run before the normal limiter (because it
60
+ * emits audit events on failure) can still budget itself rather than being
61
+ * unbounded.
62
+ */
63
+ export { clientAddress };
64
+ /** Raw sliding-window check, for the same pre-limiter case. */
65
+ export { isAllowed };
53
66
  export function rateLimit(options) {
54
67
  return async function preHandler(request, reply) {
55
- const id = clientIdentifier(request);
68
+ const id = options.keyFrom ? options.keyFrom(request) : clientIdentifier(request);
56
69
  const key = `${options.keyPrefix}:${id}:${request.body?.email ?? ""}`;
57
70
  const allowed = await isAllowed(key, options.maxAttempts, options.windowSeconds);
58
71
  if (!allowed) {
@@ -1 +1 @@
1
- {"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../src/plugins/rateLimit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../src/plugins/rateLimit.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"requestLogger.d.ts","sourceRoot":"","sources":["../../src/plugins/requestLogger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;8BAEzB,eAAe;AAAnE,wBAqBG"}
1
+ {"version":3,"file":"requestLogger.d.ts","sourceRoot":"","sources":["../../src/plugins/requestLogger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;8BAEzB,eAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"apiKey.d.ts","sourceRoot":"","sources":["../../src/repositories/apiKey.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEvD,KAAK,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,KAAK,EAAE;QACZ,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;KACzB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACtD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACpD,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC1E,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IACzF,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;CACxF;AAED,qBAAa,uBAAwB,YAAW,gBAAgB;IACxD,MAAM,CAAC,KAAK,EAAE;QAClB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;KACzB,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBb,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAoBrD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAoBnD,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAoBzE,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAsBxF,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;CAqB7F"}
1
+ {"version":3,"file":"apiKey.d.ts","sourceRoot":"","sources":["../../src/repositories/apiKey.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEvD,KAAK,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,KAAK,EAAE;QACZ,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;KACzB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACtD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACpD,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC1E,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IACzF,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;CACxF;AAED,qBAAa,uBAAwB,YAAW,gBAAgB;IACxD,MAAM,CAAC,KAAK,EAAE;QAClB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;KACzB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBlB;IAEK,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAkB1D;IAEK,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAkBxD;IAEK,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAkB9E;IAEK,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAoB7F;IAEK,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAoB3F;CACF"}
@@ -3,7 +3,7 @@ import type { ApplicationRepository, CreateApplicationInput, UpdateApplicationIn
3
3
  export declare class DrizzleApplicationRepository implements ApplicationRepository {
4
4
  private generateClientId;
5
5
  create(input: CreateApplicationInput): Promise<Application & {
6
- clientSecret: string;
6
+ clientSecret: string | null;
7
7
  }>;
8
8
  findByClientId(clientId: string): Promise<Application | undefined>;
9
9
  listByOrgId(orgId: string): Promise<Application[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../src/repositories/application.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEjE,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,qBAAa,4BAA6B,YAAW,qBAAqB;IACxE,OAAO,CAAC,gBAAgB;IAIlB,MAAM,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,GAAG;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAgBtF,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IASlE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAIlD,MAAM,CACV,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAS7B,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;CAW7F"}
1
+ {"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../src/repositories/application.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEjE,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,qBAAa,4BAA6B,YAAW,qBAAqB;IACxE,OAAO,CAAC,gBAAgB;IAIlB,MAAM,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,GAAG;QAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAoBlG;IAEK,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAOvE;IAEK,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAEvD;IAEK,MAAM,CACV,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAOlC;IAEK,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAU3F;CACF"}
@@ -8,13 +8,19 @@ export class DrizzleApplicationRepository {
8
8
  return `app_${crypto.randomBytes(16).toString("base64url")}`;
9
9
  }
10
10
  async create(input) {
11
- const clientSecret = input.clientSecret || generateClientSecret();
11
+ // A public client is issued no secret at all, rather than a secret it is
12
+ // expected to ignore. Storing one would leave a credential in the database
13
+ // that appears to protect the client and does not.
14
+ const clientType = input.clientType ?? "confidential";
15
+ const clientSecret = clientType === "public" ? null : input.clientSecret || generateClientSecret();
12
16
  const [app] = await db
13
17
  .insert(applications)
14
18
  .values({
15
19
  orgId: input.orgId,
16
20
  clientId: input.clientId || this.generateClientId(),
17
- clientSecretHash: hashClientSecret(clientSecret),
21
+ clientSecretHash: clientSecret ? hashClientSecret(clientSecret) : null,
22
+ clientType,
23
+ allowedScopes: input.allowedScopes ?? [],
18
24
  name: input.name,
19
25
  redirectUris: input.redirectUris ?? [],
20
26
  allowedOrigins: input.allowedOrigins ?? [],
@@ -26,7 +32,7 @@ export class DrizzleApplicationRepository {
26
32
  const [app] = await db
27
33
  .select()
28
34
  .from(applications)
29
- .where(eq(applications.clientId, clientId))
35
+ .where(and(eq(applications.clientId, clientId), eq(applications.isActive, true)))
30
36
  .limit(1);
31
37
  return app;
32
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"application.js","sourceRoot":"","sources":["../../src/repositories/application.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,YAAY,EAAoB,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAOhF,MAAM,OAAO,4BAA4B;IAC/B,gBAAgB;QACtB,OAAO,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAA6B;QACxC,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,IAAI,oBAAoB,EAAE,CAAC;QAClE,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE;aACnB,MAAM,CAAC,YAAY,CAAC;aACpB,MAAM,CAAC;YACN,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACnD,gBAAgB,EAAE,gBAAgB,CAAC,YAAY,CAAC;YAChD,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,EAAE;YACtC,cAAc,EAAE,KAAK,CAAC,cAAc,IAAI,EAAE;SAC3C,CAAC;aACD,SAAS,EAAE,CAAC;QACf,OAAO,EAAE,GAAG,GAAG,EAAE,YAAY,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAAgB;QACnC,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE;aACnB,MAAM,EAAE;aACR,IAAI,CAAC,YAAY,CAAC;aAClB,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;aAC1C,KAAK,CAAC,CAAC,CAAC,CAAC;QACZ,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAa;QAC7B,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,MAAM,CACV,KAAa,EACb,KAAa,EACb,KAA6B;QAE7B,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE;aACvB,MAAM,CAAC,YAAY,CAAC;aACpB,GAAG,CAAC,KAAK,CAAC;aACV,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;aACrE,SAAS,EAAE,CAAC;QACf,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,QAAgB,EAAE,MAAc;QACvD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE;aACnB,MAAM,EAAE;aACR,IAAI,CAAC,YAAY,CAAC;aAClB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;aAChF,KAAK,CAAC,CAAC,CAAC,CAAC;QAEZ,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,IAAI,GAAG,CAAC,gBAAgB,KAAK,gBAAgB,CAAC,MAAM,CAAC;YAAE,OAAO,SAAS,CAAC;QACxE,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
1
+ {"version":3,"file":"application.js","sourceRoot":"","sources":["../../src/repositories/application.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/repositories/audit.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,qBAAa,sBAAuB,YAAW,eAAe;IACtD,IAAI,CAAC,IAAI,EAAE;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,OAAO,QAAQ,CAAC,YAAY,EAAE,CAAC;CAkB5C"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/repositories/audit.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,qBAAa,sBAAuB,YAAW,eAAe;IACtD,IAAI,CAAC,IAAI,EAAE;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,OAAO,QAAQ,CAAC,YAAY,EAAE,CAAC,CAiB1C;CACF"}
@@ -7,4 +7,7 @@ export { DrizzlePermissionRepository } from "./permission.js";
7
7
  export { DrizzleApiKeyRepository, type ApiKeyRepository } from "./apiKey.js";
8
8
  export { DrizzleSamlConnectionRepository, type SamlConnectionRepository } from "./samlConnection.js";
9
9
  export { DrizzleOidcConnectionRepository, type OidcConnectionRepository } from "./oidcConnection.js";
10
+ export { DrizzleMfaChallengeRepository } from "./mfaChallenge.js";
11
+ export { DrizzleScimConnectionRepository } from "./scimConnection.js";
12
+ export { DrizzleScimGroupRepository } from "./scimGroup.js";
10
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repositories/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,+BAA+B,EAAE,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,+BAA+B,EAAE,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repositories/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,+BAA+B,EAAE,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,+BAA+B,EAAE,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC"}
@@ -7,4 +7,7 @@ export { DrizzlePermissionRepository } from "./permission.js";
7
7
  export { DrizzleApiKeyRepository } from "./apiKey.js";
8
8
  export { DrizzleSamlConnectionRepository } from "./samlConnection.js";
9
9
  export { DrizzleOidcConnectionRepository } from "./oidcConnection.js";
10
+ export { DrizzleMfaChallengeRepository } from "./mfaChallenge.js";
11
+ export { DrizzleScimConnectionRepository } from "./scimConnection.js";
12
+ export { DrizzleScimGroupRepository } from "./scimGroup.js";
10
13
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/repositories/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAyB,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,+BAA+B,EAAiC,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,+BAA+B,EAAiC,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/repositories/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAyB,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,+BAA+B,EAAiC,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,+BAA+B,EAAiC,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { type MfaChallenge } from "../db/schema.js";
2
+ import type { CreateMfaChallengeInput, MfaChallengeRepository } from "./types.js";
3
+ /**
4
+ * Durable storage for pre-authentication MFA challenges.
5
+ *
6
+ * Challenges are single-use: `consume` performs a conditional update so two
7
+ * concurrent verifications can never both complete, and only the stored hash of
8
+ * the challenge is persisted.
9
+ */
10
+ export declare class DrizzleMfaChallengeRepository implements MfaChallengeRepository {
11
+ create(input: CreateMfaChallengeInput): Promise<MfaChallenge>;
12
+ findByHash(challengeHash: string): Promise<MfaChallenge | undefined>;
13
+ /**
14
+ * Record a failed attempt only while the challenge is still active and below
15
+ * its attempt budget. Reaching the budget marks the challenge failed so it can
16
+ * never be used again.
17
+ */
18
+ recordFailedAttempt(id: string, now: Date): Promise<MfaChallenge | undefined>;
19
+ consume(id: string, now: Date): Promise<MfaChallenge | undefined>;
20
+ invalidateUserChallenges(userId: string, now: Date): Promise<void>;
21
+ deleteExpired(now: Date): Promise<number>;
22
+ }
23
+ //# sourceMappingURL=mfaChallenge.d.ts.map