@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
@@ -1,104 +0,0 @@
1
- import { Queue as BullQueue, Worker, type Job as BullJob } from "bullmq";
2
- import type { Queue, Job, JobHandler, QueueStats } from "./types.js";
3
-
4
- export class BullMQQueue implements Queue {
5
- private queue: BullQueue;
6
- private workers = new Map<string, Worker>();
7
- private handlers = new Map<string, JobHandler>();
8
- private redisUrl: string;
9
-
10
- constructor(redisUrl: string) {
11
- this.redisUrl = redisUrl;
12
- this.queue = new BullQueue("keystone", {
13
- connection: { url: redisUrl },
14
- defaultJobOptions: {
15
- removeOnComplete: 100,
16
- removeOnFail: 100,
17
- attempts: 3,
18
- backoff: { type: "exponential", delay: 1000 },
19
- },
20
- });
21
- }
22
-
23
- async enqueue<T>(job: Job<T>): Promise<void> {
24
- await this.queue.add(job.type, job.payload, {
25
- jobId: job.id,
26
- attempts: job.attempts ?? 3,
27
- });
28
- }
29
-
30
- process(type: string, handler: JobHandler): void {
31
- if (this.handlers.has(type)) {
32
- console.warn(`[bullmq-queue] handler for ${type} already registered`);
33
- return;
34
- }
35
- this.handlers.set(type, handler);
36
-
37
- const worker = new Worker(
38
- "keystone",
39
- async (bullJob: BullJob) => {
40
- const job: Job = {
41
- id: bullJob.id,
42
- type: bullJob.name,
43
- payload: bullJob.data,
44
- attempts: bullJob.attemptsMade,
45
- createdAt: bullJob.timestamp ? new Date(bullJob.timestamp) : undefined,
46
- };
47
- await handler(job);
48
- },
49
- {
50
- connection: { url: this.redisUrl },
51
- concurrency: 5,
52
- }
53
- );
54
-
55
- worker.on("failed", (job, err) => {
56
- console.error(`[bullmq-queue] job ${job?.name} ${job?.id} failed:`, err);
57
- });
58
-
59
- this.workers.set(type, worker);
60
- }
61
-
62
- async getStats(): Promise<QueueStats[]> {
63
- const counts = await this.queue.getJobCounts("waiting", "active", "completed", "failed", "delayed");
64
- return [
65
- {
66
- type: "all",
67
- count: (counts.waiting ?? 0) + (counts.active ?? 0) + (counts.completed ?? 0),
68
- failed: counts.failed ?? 0,
69
- delayed: counts.delayed ?? 0,
70
- },
71
- ];
72
- }
73
-
74
- async getFailed(limit = 50): Promise<Job[]> {
75
- const jobs = await this.queue.getFailed(0, limit);
76
- return jobs.map((j) => ({
77
- id: String(j.id),
78
- type: j.name,
79
- payload: j.data,
80
- attempts: j.attemptsMade,
81
- createdAt: j.timestamp ? new Date(j.timestamp) : undefined,
82
- }));
83
- }
84
-
85
- async retry(jobId: string): Promise<void> {
86
- const job = await this.queue.getJob(jobId);
87
- if (job) await job.retry();
88
- }
89
-
90
- async retryAll(): Promise<void> {
91
- const jobs = await this.queue.getFailed();
92
- await Promise.all(jobs.map((j) => j.retry()));
93
- }
94
-
95
- async close(): Promise<void> {
96
- await Promise.all(Array.from(this.workers.values()).map((worker) => worker.close()));
97
- await this.queue.close();
98
- // Reset registries so a closed instance (e.g. the shared singleton after a
99
- // test's app.close()) can accept process()/enqueue() again with fresh
100
- // connections instead of silently reusing dead ones.
101
- this.workers.clear();
102
- this.handlers.clear();
103
- }
104
- }
@@ -1,75 +0,0 @@
1
- import type { Queue, Job, JobHandler, QueueStats } from "./types.js";
2
-
3
- const DEFAULT_ATTEMPTS = 3;
4
-
5
- export class InProcessQueue implements Queue {
6
- private handlers = new Map<string, JobHandler>();
7
- private stats = new Map<string, { count: number; failed: number }>();
8
-
9
- async enqueue<T>(job: Job<T>): Promise<void> {
10
- setImmediate(() => {
11
- this.run(job, 1).catch((err) => {
12
- console.error(`[in-process-queue] job ${job.type} failed permanently:`, err);
13
- });
14
- });
15
- }
16
-
17
- process(type: string, handler: JobHandler): void {
18
- this.handlers.set(type, handler);
19
- }
20
-
21
- async getStats(): Promise<QueueStats[]> {
22
- return Array.from(this.stats.entries()).map(([type, s]) => ({
23
- type,
24
- count: s.count,
25
- failed: s.failed,
26
- }));
27
- }
28
-
29
- async getFailed(): Promise<Job[]> {
30
- return [];
31
- }
32
-
33
- async retry(): Promise<void> {
34
- // No persisted failed jobs in the in-process queue.
35
- }
36
-
37
- async retryAll(): Promise<void> {
38
- // No persisted failed jobs in the in-process queue.
39
- }
40
-
41
- async close(): Promise<void> {
42
- this.handlers.clear();
43
- this.stats.clear();
44
- }
45
-
46
- private async run(job: Job, attempt: number): Promise<void> {
47
- const handler = this.handlers.get(job.type);
48
- if (!handler) {
49
- console.warn(`[in-process-queue] no handler registered for ${job.type}`);
50
- return;
51
- }
52
-
53
- this.increment(job.type, "count");
54
-
55
- try {
56
- await handler(job);
57
- } catch (err) {
58
- const maxAttempts = job.attempts ?? DEFAULT_ATTEMPTS;
59
- if (attempt < maxAttempts) {
60
- const delay = Math.min(1000 * 2 ** (attempt - 1), 30000);
61
- console.warn(`[in-process-queue] job ${job.type} failed (attempt ${attempt}/${maxAttempts}), retrying in ${delay}ms`);
62
- setTimeout(() => this.run(job, attempt + 1), delay);
63
- return;
64
- }
65
- this.increment(job.type, "failed");
66
- throw err;
67
- }
68
- }
69
-
70
- private increment(type: string, key: "count" | "failed"): void {
71
- const current = this.stats.get(type) ?? { count: 0, failed: 0 };
72
- current[key]++;
73
- this.stats.set(type, current);
74
- }
75
- }
@@ -1,19 +0,0 @@
1
- import { config } from "../../config.js";
2
- import { InProcessQueue } from "./inProcess.js";
3
- import { BullMQQueue } from "./bullmq.js";
4
- import type { Queue } from "./types.js";
5
-
6
- export * from "./types.js";
7
- export { InProcessQueue } from "./inProcess.js";
8
- export { BullMQQueue } from "./bullmq.js";
9
-
10
- export function createQueue(): Queue {
11
- const explicitProvider = config.KEYSTONE_QUEUE_PROVIDER;
12
- if (explicitProvider === "in-process") return new InProcessQueue();
13
- if (explicitProvider === "bullmq") return new BullMQQueue(config.REDIS_URL);
14
- // Default to bullmq when Redis is available, otherwise fall back to in-process.
15
- if (config.REDIS_URL) return new BullMQQueue(config.REDIS_URL);
16
- return new InProcessQueue();
17
- }
18
-
19
- export const queue = createQueue();
@@ -1,26 +0,0 @@
1
- export interface Job<T = unknown> {
2
- id?: string;
3
- type: string;
4
- payload: T;
5
- attempts?: number;
6
- createdAt?: Date;
7
- }
8
-
9
- export type JobHandler = (job: Job) => void | Promise<void>;
10
-
11
- export interface QueueStats {
12
- type: string;
13
- count: number;
14
- failed?: number;
15
- delayed?: number;
16
- }
17
-
18
- export interface Queue {
19
- enqueue<T>(job: Job<T>): Promise<void>;
20
- process(type: string, handler: JobHandler): void;
21
- getStats?(): Promise<QueueStats[]>;
22
- getFailed?(limit: number): Promise<Job[]>;
23
- retry?(jobId: string): Promise<void>;
24
- retryAll?(): Promise<void>;
25
- close?(): Promise<void>;
26
- }
@@ -1,16 +0,0 @@
1
- import { Redis } from "ioredis";
2
- import { config } from "../config.js";
3
-
4
- /**
5
- * Shared Redis connection used by rate limiting, anomaly detection, and any
6
- * other distributed state in Keystone. Lazy connection means the process will
7
- * not fail at import time if Redis is temporarily unavailable.
8
- */
9
- export const redis = new Redis(config.REDIS_URL, {
10
- maxRetriesPerRequest: 3,
11
- lazyConnect: true,
12
- });
13
-
14
- export function isRedisReady(): boolean {
15
- return redis.status === "ready" || redis.status === "connect";
16
- }
@@ -1,97 +0,0 @@
1
- import crypto from "node:crypto";
2
- import { importPKCS8, importSPKI, exportPKCS8, exportSPKI, generateKeyPair } from "jose";
3
- import type { SecretsProvider, SigningKeyPair } from "./provider.js";
4
- import { hashPassword, verifyPassword } from "./password.js";
5
-
6
- /**
7
- * AWS KMS secrets provider reference implementation.
8
- *
9
- * In a real deployment this would use the AWS SDK to:
10
- * - Store/retrieve JWT signing keys in AWS Secrets Manager or Parameter Store
11
- * - Use KMS for envelope encryption of secrets
12
- *
13
- * The current implementation keeps keys in memory and encrypts the data
14
- * encryption key (DEK) with a KMS key ID supplied via KMS_KEY_ID. It is
15
- * intended as a starting point for a full AWS integration.
16
- */
17
- export class AwsKmsSecretsProvider implements SecretsProvider {
18
- readonly name = "aws-kms";
19
-
20
- hashPassword = hashPassword;
21
- verifyPassword = verifyPassword;
22
-
23
- private kmsKeyId?: string;
24
- private keyPair: SigningKeyPair | null = null;
25
-
26
- constructor() {
27
- this.kmsKeyId = process.env.KMS_KEY_ID;
28
- if (!this.kmsKeyId) {
29
- throw new Error("AwsKmsSecretsProvider requires KMS_KEY_ID");
30
- }
31
- }
32
-
33
- hashApiKey(key: string): string {
34
- return crypto.createHash("sha256").update(key).digest("hex");
35
- }
36
-
37
- hashClientSecret(secret: string): string {
38
- return crypto.createHash("sha256").update(secret).digest("hex");
39
- }
40
-
41
- generateClientSecret(): string {
42
- return `cs_${crypto.randomBytes(32).toString("base64url")}`;
43
- }
44
-
45
- generateApiKey(): { key: string; prefix: string } {
46
- const key = `ks_${crypto.randomBytes(32).toString("base64url")}`;
47
- return { key, prefix: key.slice(0, 7) };
48
- }
49
-
50
- async getActiveSigningKey(): Promise<SigningKeyPair> {
51
- if (this.keyPair) return this.keyPair;
52
- return this.rotateSigningKeys();
53
- }
54
-
55
- async getSigningKeyById(keyId: string): Promise<SigningKeyPair | undefined> {
56
- const active = await this.getActiveSigningKey();
57
- if (active.keyId === keyId) return active;
58
- return undefined;
59
- }
60
-
61
- async rotateSigningKeys(): Promise<SigningKeyPair> {
62
- const pair = await generateKeyPair("RS256", { extractable: true });
63
- const privatePem = await exportPKCS8(pair.privateKey);
64
- const publicPem = await exportSPKI(pair.publicKey);
65
- const keyId = `aws-${crypto.randomBytes(8).toString("base64url")}`;
66
-
67
- // In production: store privatePem/publicPem in AWS Secrets Manager encrypted by KMS.
68
- // eslint-disable-next-line no-console
69
- console.warn(`[aws-kms] New signing key ${keyId} generated. In production, store it in AWS Secrets Manager.`);
70
-
71
- this.keyPair = { keyId, privateKey: pair.privateKey, publicKey: pair.publicKey };
72
- return this.keyPair;
73
- }
74
-
75
- async listActiveSigningKeys(): Promise<{ keyId: string; createdAt: Date; expiresAt?: Date | null }[]> {
76
- const active = await this.getActiveSigningKey();
77
- return [{ keyId: active.keyId, createdAt: new Date(), expiresAt: null }];
78
- }
79
-
80
- async listValidSigningKeys(): Promise<SigningKeyPair[]> {
81
- const active = await this.getActiveSigningKey();
82
- return [active];
83
- }
84
-
85
- async getEncryptionKey(): Promise<Buffer> {
86
- // In production: decrypt a stored data key using KMS.
87
- throw new Error("AwsKmsSecretsProvider.getEncryptionKey() is not yet implemented");
88
- }
89
-
90
- async encryptSecret(plain: string): Promise<string> {
91
- throw new Error("AwsKmsSecretsProvider.encryptSecret() is not yet implemented");
92
- }
93
-
94
- async decryptSecret(cipherText: string): Promise<string> {
95
- throw new Error("AwsKmsSecretsProvider.decryptSecret() is not yet implemented");
96
- }
97
- }
@@ -1,171 +0,0 @@
1
- import crypto from "node:crypto";
2
- import { importPKCS8, importSPKI, exportPKCS8, exportSPKI, generateKeyPair } from "jose";
3
- import type { SecretsProvider, SigningKeyPair } from "./provider.js";
4
- import { hashPassword, verifyPassword } from "./password.js";
5
-
6
- /**
7
- * Azure Key Vault secrets provider.
8
- *
9
- * This is a reference implementation. In production it should use the Azure
10
- * SDK (@azure/identity and @azure/keyvault-keys/secrets) to retrieve signing
11
- * keys, encryption keys, and credentials from Azure Key Vault. Password hashing
12
- * helpers are reused locally because they are compute-bound.
13
- */
14
- export class AzureKeyVaultSecretsProvider implements SecretsProvider {
15
- readonly name = "azure-key-vault";
16
-
17
- hashPassword = hashPassword;
18
- verifyPassword = verifyPassword;
19
-
20
- private vaultUrl: string;
21
- private tenantId: string;
22
- private clientId: string;
23
- private clientSecret: string;
24
-
25
- constructor() {
26
- this.vaultUrl = (process.env.AZURE_KEY_VAULT_URL || "").replace(/\/$/, "");
27
- this.tenantId = process.env.AZURE_TENANT_ID || "";
28
- this.clientId = process.env.AZURE_CLIENT_ID || "";
29
- this.clientSecret = process.env.AZURE_CLIENT_SECRET || "";
30
-
31
- if (!this.vaultUrl || !this.tenantId || !this.clientId || !this.clientSecret) {
32
- throw new Error(
33
- "AzureKeyVaultSecretsProvider requires AZURE_KEY_VAULT_URL, AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET"
34
- );
35
- }
36
- }
37
-
38
- hashApiKey(key: string): string {
39
- return crypto.createHash("sha256").update(key).digest("hex");
40
- }
41
-
42
- hashClientSecret(secret: string): string {
43
- return crypto.createHash("sha256").update(secret).digest("hex");
44
- }
45
-
46
- generateClientSecret(): string {
47
- return `cs_${crypto.randomBytes(32).toString("base64url")}`;
48
- }
49
-
50
- generateApiKey(): { key: string; prefix: string } {
51
- const key = `ks_${crypto.randomBytes(32).toString("base64url")}`;
52
- return { key, prefix: key.slice(0, 7) };
53
- }
54
-
55
- async getActiveSigningKey(): Promise<SigningKeyPair> {
56
- const stored = await this.readKey("jwt-active");
57
- if (stored?.private && stored?.public) {
58
- const privateKey = await importPKCS8(String(stored.private), "RS256");
59
- const publicKey = await importSPKI(String(stored.public), "RS256");
60
- return { keyId: String(stored.keyId ?? "azure-active"), privateKey, publicKey };
61
- }
62
- return this.rotateSigningKeys();
63
- }
64
-
65
- async getSigningKeyById(keyId: string): Promise<SigningKeyPair | undefined> {
66
- const active = await this.getActiveSigningKey();
67
- if (active.keyId === keyId) return active;
68
- const stored = await this.readKey(`jwt-${keyId}`);
69
- if (!stored?.private) return undefined;
70
- const privateKey = await importPKCS8(String(stored.private), "RS256");
71
- const publicKey = await importSPKI(String(stored.public), "RS256");
72
- return { keyId, privateKey, publicKey };
73
- }
74
-
75
- async rotateSigningKeys(): Promise<SigningKeyPair> {
76
- const pair = await generateKeyPair("RS256", { extractable: true });
77
- const privatePem = await exportPKCS8(pair.privateKey);
78
- const publicPem = await exportSPKI(pair.publicKey);
79
- const keyId = `azure-${crypto.randomBytes(8).toString("base64url")}`;
80
-
81
- await this.writeKey("jwt-active", { keyId, private: privatePem, public: publicPem, rotatedAt: new Date().toISOString() });
82
-
83
- return { keyId, privateKey: pair.privateKey, publicKey: pair.publicKey };
84
- }
85
-
86
- async listActiveSigningKeys(): Promise<{ keyId: string; createdAt: Date; expiresAt?: Date | null }[]> {
87
- const active = await this.getActiveSigningKey();
88
- return [{ keyId: active.keyId, createdAt: new Date(), expiresAt: null }];
89
- }
90
-
91
- async listValidSigningKeys(): Promise<SigningKeyPair[]> {
92
- return [await this.getActiveSigningKey()];
93
- }
94
-
95
- async getEncryptionKey(): Promise<Buffer> {
96
- const stored = await this.readKey("encryption-key");
97
- if (stored?.value) {
98
- return Buffer.from(String(stored.value), "base64");
99
- }
100
- const key = crypto.randomBytes(32);
101
- await this.writeKey("encryption-key", { value: key.toString("base64") });
102
- return key;
103
- }
104
-
105
- async encryptSecret(plain: string): Promise<string> {
106
- const key = await this.getEncryptionKey();
107
- const iv = crypto.randomBytes(16);
108
- const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
109
- const encrypted = Buffer.concat([cipher.update(plain, "utf-8"), cipher.final()]);
110
- return `${iv.toString("base64")}:${encrypted.toString("base64")}`;
111
- }
112
-
113
- async decryptSecret(cipherText: string): Promise<string> {
114
- const key = await this.getEncryptionKey();
115
- const [ivBase64, encryptedBase64] = cipherText.split(":");
116
- if (!ivBase64 || !encryptedBase64) throw new Error("Invalid cipher text format");
117
- const iv = Buffer.from(ivBase64, "base64");
118
- const encrypted = Buffer.from(encryptedBase64, "base64");
119
- const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
120
- return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString("utf-8");
121
- }
122
-
123
- // Reference stubs for Azure Key Vault HTTP API integration.
124
- private async readPath(path: string): Promise<Record<string, unknown> | undefined> {
125
- const url = `${this.vaultUrl}/secrets/${path}?api-version=7.4`;
126
- const token = await this.getAccessToken();
127
- const response = await fetch(url, {
128
- headers: { Authorization: `Bearer ${token}`, Accept: "application/json" },
129
- });
130
- if (response.status === 404) return undefined;
131
- if (!response.ok) throw new Error(`Azure Key Vault read failed: ${response.status}`);
132
- const body = await response.json();
133
- return typeof body.value === "string" ? JSON.parse(body.value) : body.value;
134
- }
135
-
136
- private async readKey(name: string): Promise<Record<string, unknown> | undefined> {
137
- return this.readPath(name);
138
- }
139
-
140
- private async writeKey(name: string, value: Record<string, unknown>): Promise<void> {
141
- const url = `${this.vaultUrl}/secrets/${name}?api-version=7.4`;
142
- const token = await this.getAccessToken();
143
- const response = await fetch(url, {
144
- method: "PUT",
145
- headers: {
146
- Authorization: `Bearer ${token}`,
147
- "Content-Type": "application/json",
148
- },
149
- body: JSON.stringify({ value: JSON.stringify(value) }),
150
- });
151
- if (!response.ok) throw new Error(`Azure Key Vault write failed: ${response.status}`);
152
- }
153
-
154
- private async getAccessToken(): Promise<string> {
155
- const url = `https://login.microsoftonline.com/${this.tenantId}/oauth2/v2.0/token`;
156
- const params = new URLSearchParams();
157
- params.set("client_id", this.clientId);
158
- params.set("client_secret", this.clientSecret);
159
- params.set("scope", "https://vault.azure.net/.default");
160
- params.set("grant_type", "client_credentials");
161
-
162
- const response = await fetch(url, {
163
- method: "POST",
164
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
165
- body: params.toString(),
166
- });
167
- if (!response.ok) throw new Error(`Azure authentication failed: ${response.status}`);
168
- const body = await response.json();
169
- return String(body.access_token);
170
- }
171
- }
@@ -1,166 +0,0 @@
1
- import crypto from "node:crypto";
2
- import { eq, and, or, gt, isNull } from "drizzle-orm";
3
- import { importPKCS8, importSPKI, exportPKCS8, exportSPKI, generateKeyPair } from "jose";
4
- import { db } from "../../db/index.js";
5
- import { secrets, type Secret } from "../../db/schema.js";
6
- import { config } from "../../config.js";
7
- import type { SecretsProvider, SigningKeyPair } from "./provider.js";
8
- import { hashPassword, verifyPassword } from "./password.js";
9
-
10
- const ENCRYPTION_ALGORITHM = "aes-256-gcm";
11
- const IV_LENGTH = 16;
12
- const AUTH_TAG_LENGTH = 16;
13
- const KEY_ID_BYTES = 8;
14
-
15
- export class DatabaseSecretsProvider implements SecretsProvider {
16
- readonly name = "database";
17
-
18
- hashPassword = hashPassword;
19
- verifyPassword = verifyPassword;
20
-
21
- hashApiKey(key: string): string {
22
- return crypto.createHash("sha256").update(key).digest("hex");
23
- }
24
-
25
- hashClientSecret(secret: string): string {
26
- return crypto.createHash("sha256").update(secret).digest("hex");
27
- }
28
-
29
- generateClientSecret(): string {
30
- return `cs_${crypto.randomBytes(32).toString("base64url")}`;
31
- }
32
-
33
- generateApiKey(): { key: string; prefix: string } {
34
- const key = `ks_${crypto.randomBytes(32).toString("base64url")}`;
35
- const prefix = key.slice(0, 7);
36
- return { key, prefix };
37
- }
38
-
39
- async getActiveSigningKey(): Promise<SigningKeyPair> {
40
- const [active] = await db
41
- .select()
42
- .from(secrets)
43
- .where(and(eq(secrets.type, "jwt_signing"), eq(secrets.isActive, true), isNull(secrets.expiresAt)))
44
- .orderBy(secrets.createdAt)
45
- .limit(1);
46
-
47
- if (active) {
48
- return this.loadKeyPair(active);
49
- }
50
-
51
- return this.createSigningKey();
52
- }
53
-
54
- async getSigningKeyById(keyId: string): Promise<SigningKeyPair | undefined> {
55
- const [record] = await db.select().from(secrets).where(eq(secrets.keyId, keyId)).limit(1);
56
- if (!record || record.type !== "jwt_signing") return undefined;
57
- return this.loadKeyPair(record);
58
- }
59
-
60
- async rotateSigningKeys(): Promise<SigningKeyPair> {
61
- await db
62
- .update(secrets)
63
- .set({ isActive: false, expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000) })
64
- .where(eq(secrets.type, "jwt_signing"));
65
- return this.createSigningKey();
66
- }
67
-
68
- private async createSigningKey(): Promise<SigningKeyPair> {
69
- const pair = await generateKeyPair("RS256", { extractable: true });
70
- const privatePem = await exportPKCS8(pair.privateKey);
71
- const publicPem = await exportSPKI(pair.publicKey);
72
- const keyId = crypto.randomBytes(KEY_ID_BYTES).toString("base64url");
73
-
74
- await db.insert(secrets).values({
75
- keyId,
76
- type: "jwt_signing",
77
- value: JSON.stringify({ private: privatePem, public: publicPem }),
78
- algorithm: "RS256",
79
- isActive: true,
80
- rotatedAt: new Date(),
81
- });
82
-
83
- return { keyId, privateKey: pair.privateKey, publicKey: pair.publicKey };
84
- }
85
-
86
- private async loadKeyPair(record: Secret): Promise<SigningKeyPair> {
87
- const parsed = JSON.parse(record.value) as { private: string; public: string };
88
- const privateKey = await importPKCS8(parsed.private, "RS256");
89
- const publicKey = await importSPKI(parsed.public, "RS256");
90
- return { keyId: record.keyId, privateKey, publicKey };
91
- }
92
-
93
- async getEncryptionKey(): Promise<Buffer> {
94
- if (config.KEYSTONE_ENCRYPTION_KEY) {
95
- return crypto.createHash("sha256").update(config.KEYSTONE_ENCRYPTION_KEY).digest();
96
- }
97
-
98
- const [active] = await db
99
- .select()
100
- .from(secrets)
101
- .where(and(eq(secrets.type, "encryption"), eq(secrets.isActive, true)))
102
- .limit(1);
103
-
104
- if (active) {
105
- return Buffer.from(active.value, "base64url");
106
- }
107
-
108
- const value = crypto.randomBytes(32);
109
- await db.insert(secrets).values({
110
- keyId: `enc-${crypto.randomBytes(KEY_ID_BYTES).toString("base64url")}`,
111
- type: "encryption",
112
- value: value.toString("base64url"),
113
- algorithm: "aes-256-gcm",
114
- isActive: true,
115
- });
116
- return value;
117
- }
118
-
119
- async encryptSecret(plain: string): Promise<string> {
120
- const key = await this.getEncryptionKey();
121
- const iv = crypto.randomBytes(IV_LENGTH);
122
- const cipher = crypto.createCipheriv(ENCRYPTION_ALGORITHM, key, iv);
123
- const encrypted = Buffer.concat([cipher.update(plain, "utf8"), cipher.final()]);
124
- const tag = cipher.getAuthTag();
125
- const payload = Buffer.concat([iv, tag, encrypted]);
126
- return `${ENCRYPTION_ALGORITHM}$${payload.toString("base64url")}`;
127
- }
128
-
129
- async decryptSecret(cipherText: string): Promise<string> {
130
- if (!cipherText.startsWith(`${ENCRYPTION_ALGORITHM}$`)) {
131
- throw new Error("Unsupported cipher format");
132
- }
133
- const key = await this.getEncryptionKey();
134
- const payload = Buffer.from(cipherText.slice(`${ENCRYPTION_ALGORITHM}$`.length), "base64url");
135
- const iv = payload.subarray(0, IV_LENGTH);
136
- const tag = payload.subarray(IV_LENGTH, IV_LENGTH + AUTH_TAG_LENGTH);
137
- const encrypted = payload.subarray(IV_LENGTH + AUTH_TAG_LENGTH);
138
- const decipher = crypto.createDecipheriv(ENCRYPTION_ALGORITHM, key, iv);
139
- decipher.setAuthTag(tag);
140
- return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString("utf8");
141
- }
142
-
143
- async listActiveSigningKeys(): Promise<{ keyId: string; createdAt: Date; expiresAt?: Date | null }[]> {
144
- const rows = await db
145
- .select({ keyId: secrets.keyId, createdAt: secrets.createdAt, expiresAt: secrets.expiresAt })
146
- .from(secrets)
147
- .where(and(eq(secrets.type, "jwt_signing"), eq(secrets.isActive, true)))
148
- .orderBy(secrets.createdAt);
149
- return rows;
150
- }
151
-
152
- async listValidSigningKeys(): Promise<SigningKeyPair[]> {
153
- const now = new Date();
154
- const rows = await db
155
- .select()
156
- .from(secrets)
157
- .where(
158
- and(
159
- eq(secrets.type, "jwt_signing"),
160
- or(eq(secrets.isActive, true), and(eq(secrets.isActive, false), gt(secrets.expiresAt, now)))
161
- )
162
- )
163
- .orderBy(secrets.createdAt);
164
- return Promise.all(rows.map((row) => this.loadKeyPair(row)));
165
- }
166
- }