@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
package/src/lib/result.ts DELETED
@@ -1,44 +0,0 @@
1
- export interface KeystoneError {
2
- code: string;
3
- message: string;
4
- statusCode?: number;
5
- details?: Record<string, unknown>;
6
- }
7
-
8
- export type Result<T> =
9
- | { success: true; data: T; error?: undefined }
10
- | { success: false; data?: undefined; error: KeystoneError };
11
-
12
- export function ok<T>(data: T): Result<T> {
13
- return { success: true, data };
14
- }
15
-
16
- export function err<T>(error: KeystoneError): Result<T> {
17
- return { success: false, error };
18
- }
19
-
20
- export function errFromMessage<T>(
21
- code: string,
22
- message: string,
23
- statusCode?: number,
24
- details?: Record<string, unknown>
25
- ): Result<T> {
26
- return err({ code, message, statusCode, details });
27
- }
28
-
29
- export function mapResult<T, U>(result: Result<T>, fn: (data: T) => U): Result<U> {
30
- if (result.success) {
31
- return ok(fn(result.data));
32
- }
33
- return err(result.error);
34
- }
35
-
36
- export async function flatMapResult<T, U>(
37
- result: Result<T>,
38
- fn: (data: T) => Promise<Result<U>>
39
- ): Promise<Result<U>> {
40
- if (result.success) {
41
- return fn(result.data);
42
- }
43
- return err(result.error);
44
- }
@@ -1,41 +0,0 @@
1
- import crypto from "node:crypto";
2
-
3
- /**
4
- * Sign a webhook payload using HMAC-SHA256.
5
- * Returns a signature string in the format "t=<timestamp>,v1=<hex>".
6
- */
7
- export function signWebhookPayload(secret: string, payload: unknown): string {
8
- const timestamp = Math.floor(Date.now() / 1000);
9
- const body = JSON.stringify(payload);
10
- const signedPayload = `${timestamp}.${body}`;
11
- const signature = crypto.createHmac("sha256", secret).update(signedPayload).digest("hex");
12
- return `t=${timestamp},v1=${signature}`;
13
- }
14
-
15
- /**
16
- * Verify a webhook signature.
17
- * Returns true if the signature matches the payload and timestamp is within tolerance.
18
- */
19
- export function verifyWebhookPayload(
20
- secret: string,
21
- signatureHeader: string,
22
- payload: unknown,
23
- toleranceSeconds = 300
24
- ): boolean {
25
- const parts = signatureHeader.split(",").reduce<Record<string, string>>((acc, part) => {
26
- const [key, value] = part.split("=");
27
- if (key && value) acc[key.trim()] = value.trim();
28
- return acc;
29
- }, {});
30
-
31
- const timestamp = Number(parts.t);
32
- const signature = parts.v1;
33
- if (!timestamp || !signature) return false;
34
-
35
- const now = Math.floor(Date.now() / 1000);
36
- if (Math.abs(now - timestamp) > toleranceSeconds) return false;
37
-
38
- const body = JSON.stringify(payload);
39
- const expected = crypto.createHmac("sha256", secret).update(`${timestamp}.${body}`).digest("hex");
40
- return crypto.timingSafeEqual(Buffer.from(signature, "hex"), Buffer.from(expected, "hex"));
41
- }
@@ -1,76 +0,0 @@
1
- import fp from "fastify-plugin";
2
- import type { FastifyInstance, FastifyRequest } from "fastify";
3
- import { eq, and, arrayContains } from "drizzle-orm";
4
- import { db } from "../db/index.js";
5
- import { applications, organizations, orgMemberships } from "../db/schema.js";
6
-
7
- export default fp(async function appContextPlugin(app: FastifyInstance) {
8
- app.addHook("onRequest", async (request: FastifyRequest) => {
9
- // Ensure every request has a fresh state object.
10
- request.state = {};
11
-
12
- const clientId = extractClientId(request);
13
- const origin = request.headers.origin;
14
-
15
- const appRecord = clientId
16
- ? await findApplicationByClientId(clientId)
17
- : origin
18
- ? await findApplicationByOrigin(origin)
19
- : undefined;
20
-
21
- if (!appRecord) return;
22
-
23
- request.state.app = appRecord;
24
- request.state.org = appRecord.organization;
25
-
26
- if (request.user) {
27
- const [membership] = await db
28
- .select()
29
- .from(orgMemberships)
30
- .where(
31
- and(
32
- eq(orgMemberships.orgId, appRecord.organization.id),
33
- eq(orgMemberships.userId, request.user.id)
34
- )
35
- )
36
- .limit(1);
37
- if (membership) {
38
- request.state.membership = membership;
39
- }
40
- }
41
- });
42
- });
43
-
44
- function extractClientId(request: FastifyRequest): string | undefined {
45
- const header = request.headers["x-app-client-id"];
46
- if (typeof header === "string" && header) return header;
47
-
48
- const query = (request.query as Record<string, string | undefined>).client_id;
49
- if (query) return query;
50
-
51
- return undefined;
52
- }
53
-
54
- async function findApplicationByClientId(clientId: string) {
55
- const [row] = await db
56
- .select()
57
- .from(applications)
58
- .where(and(eq(applications.clientId, clientId), eq(applications.isActive, true)))
59
- .innerJoin(organizations, eq(applications.orgId, organizations.id))
60
- .limit(1);
61
-
62
- if (!row) return undefined;
63
- return { ...row.applications, organization: row.organizations };
64
- }
65
-
66
- async function findApplicationByOrigin(origin: string) {
67
- const [row] = await db
68
- .select()
69
- .from(applications)
70
- .where(and(arrayContains(applications.allowedOrigins, [origin]), eq(applications.isActive, true)))
71
- .innerJoin(organizations, eq(applications.orgId, organizations.id))
72
- .limit(1);
73
-
74
- if (!row) return undefined;
75
- return { ...row.applications, organization: row.organizations };
76
- }
@@ -1,42 +0,0 @@
1
- import fp from "fastify-plugin";
2
- import type { FastifyInstance, FastifyRequest } from "fastify";
3
- import { audit, type AuditEvent } from "../services/audit.js";
4
- import { emit } from "../services/events/bus.js";
5
- import type { EventPayload } from "../services/events/types.js";
6
-
7
- declare module "fastify" {
8
- interface FastifyRequest {
9
- audit: (event: AuditEvent, metadata?: Record<string, unknown>) => Promise<void>;
10
- emitEvent: (event: string, metadata?: Record<string, unknown>) => Promise<void>;
11
- }
12
- }
13
-
14
- function buildPayload(request: FastifyRequest, metadata?: Record<string, unknown>): EventPayload {
15
- return {
16
- userId: request.user?.id,
17
- orgId: request.state?.org?.id,
18
- appId: request.state?.app?.id,
19
- requestId: request.id,
20
- ip: request.ip,
21
- userAgent: request.headers["user-agent"],
22
- metadata,
23
- };
24
- }
25
-
26
- export default fp(async function auditPlugin(app: FastifyInstance) {
27
- app.decorateRequest("audit", async function (
28
- this: FastifyRequest,
29
- event: AuditEvent,
30
- metadata?: Record<string, unknown>
31
- ) {
32
- await audit({ ...buildPayload(this, metadata), event });
33
- });
34
-
35
- app.decorateRequest("emitEvent", async function (
36
- this: FastifyRequest,
37
- event: string,
38
- metadata?: Record<string, unknown>
39
- ) {
40
- await emit({ type: event, payload: buildPayload(this, metadata) });
41
- });
42
- });
@@ -1,230 +0,0 @@
1
- import fp from "fastify-plugin";
2
- import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
3
- import { eq, and, gt, isNull } from "drizzle-orm";
4
- import { config } from "../config.js";
5
- import { db } from "../db/index.js";
6
- import { apiKeys, users, serviceAccounts, type User } from "../db/schema.js";
7
- import { verifyAccessToken, hashApiKey } from "../services/tokens.js";
8
- import type { TokenClaims } from "../types.js";
9
-
10
- declare module "fastify" {
11
- interface FastifyInstance {
12
- authenticate: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
13
- authenticateOrApiKey: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
14
- requireScopes: (...scopes: string[]) => (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
15
- }
16
-
17
- interface FastifyRequest {
18
- serviceAccount?: typeof serviceAccounts.$inferSelect;
19
- apiKeyScopes?: string[];
20
- }
21
- }
22
-
23
- const DEFAULT_ACCESS_COOKIE = config.COOKIE_NAME;
24
- const DEFAULT_REFRESH_COOKIE = `${config.COOKIE_NAME}-refresh`;
25
-
26
- export function accessCookieName(clientId?: string): string {
27
- return clientId ? `app-${clientId}-session` : DEFAULT_ACCESS_COOKIE;
28
- }
29
-
30
- export function refreshCookieName(clientId?: string): string {
31
- return clientId ? `app-${clientId}-session-refresh` : DEFAULT_REFRESH_COOKIE;
32
- }
33
-
34
- function cookieOptions(): {
35
- path: string;
36
- httpOnly: boolean;
37
- secure: boolean;
38
- sameSite: "strict" | "lax" | "none";
39
- domain: string | undefined;
40
- } {
41
- const sameSite = (config.COOKIE_SAME_SITE as "strict" | "lax" | "none") || (config.NODE_ENV === "production" ? "strict" : "lax");
42
- return {
43
- path: "/",
44
- httpOnly: true,
45
- secure: config.COOKIE_SECURE,
46
- sameSite,
47
- domain: config.COOKIE_DOMAIN || undefined,
48
- };
49
- }
50
-
51
- export function setSessionCookies(
52
- reply: FastifyReply,
53
- accessToken: string,
54
- refreshToken: string,
55
- clientId?: string
56
- ): void {
57
- const opts = cookieOptions();
58
-
59
- reply.setCookie(accessCookieName(clientId), accessToken, {
60
- ...opts,
61
- maxAge: config.ACCESS_TOKEN_TTL_SECONDS,
62
- });
63
- reply.setCookie(refreshCookieName(clientId), refreshToken, {
64
- ...opts,
65
- maxAge: config.REFRESH_TOKEN_TTL_SECONDS,
66
- });
67
- }
68
-
69
- export function clearSessionCookies(reply: FastifyReply, clientId?: string): void {
70
- const opts = cookieOptions();
71
- reply.clearCookie(accessCookieName(clientId), opts);
72
- reply.clearCookie(refreshCookieName(clientId), opts);
73
- }
74
-
75
- export function getRefreshToken(request: FastifyRequest, clientId?: string): string | undefined {
76
- return request.cookies[refreshCookieName(clientId)];
77
- }
78
-
79
- async function resolveUserFromClaims(claims: TokenClaims) {
80
- const [user] = await db.select().from(users).where(eq(users.id, claims.sub)).limit(1);
81
- return user;
82
- }
83
-
84
- async function resolveApiKeyRecord(key: string) {
85
- const hash = hashApiKey(key);
86
- const [keyRecord] = await db
87
- .select()
88
- .from(apiKeys)
89
- .where(and(eq(apiKeys.keyHash, hash), isNull(apiKeys.revokedAt)))
90
- .limit(1);
91
- return keyRecord;
92
- }
93
-
94
- async function resolveUserFromApiKey(key: string): Promise<{ user: User; scopes: string[] } | undefined> {
95
- const keyRecord = await resolveApiKeyRecord(key);
96
- if (!keyRecord) return undefined;
97
- if (keyRecord.expiresAt && keyRecord.expiresAt < new Date()) return undefined;
98
-
99
- await db.update(apiKeys).set({ lastUsedAt: new Date() }).where(eq(apiKeys.id, keyRecord.id));
100
-
101
- if (keyRecord.userId) {
102
- const [user] = await db.select().from(users).where(eq(users.id, keyRecord.userId)).limit(1);
103
- if (!user) return undefined;
104
- return { user, scopes: keyRecord.scopes ?? [] };
105
- }
106
-
107
- return undefined;
108
- }
109
-
110
- function extractAccessToken(request: FastifyRequest): string | undefined {
111
- // Prefer the app-specific cookie if an app context is present.
112
- const appClientId = request.state?.app?.clientId;
113
- const appCookie = appClientId ? request.cookies[accessCookieName(appClientId)] : undefined;
114
- if (appCookie) return appCookie;
115
-
116
- const defaultCookie = request.cookies[DEFAULT_ACCESS_COOKIE];
117
- if (defaultCookie) return defaultCookie;
118
-
119
- const header = request.headers.authorization;
120
- if (header?.startsWith("Bearer ")) return header.slice(7);
121
- return undefined;
122
- }
123
-
124
- export default fp(async function authPlugin(app: FastifyInstance) {
125
- app.decorate("authenticate", async function authenticate(request, reply) {
126
- const token = extractAccessToken(request);
127
- if (!token) {
128
- return reply.status(401).send({ error: "Unauthorized" });
129
- }
130
- try {
131
- const claims = await verifyAccessToken(token);
132
- const user = await resolveUserFromClaims(claims);
133
- if (!user) {
134
- return reply.status(401).send({ error: "User not found" });
135
- }
136
- request.user = user;
137
- } catch {
138
- return reply.status(401).send({ error: "Invalid token" });
139
- }
140
- });
141
-
142
- app.decorate("authenticateOrApiKey", async function authenticateOrApiKey(request, reply) {
143
- const token = extractAccessToken(request);
144
- if (!token) {
145
- return reply.status(401).send({ error: "Unauthorized" });
146
- }
147
-
148
- try {
149
- const claims = await verifyAccessToken(token);
150
- const user = await resolveUserFromClaims(claims);
151
- if (!user) {
152
- return reply.status(401).send({ error: "User not found" });
153
- }
154
- request.user = user;
155
- return;
156
- } catch {
157
- // Not a valid access token — try API key.
158
- }
159
-
160
- const apiKeyUser = await resolveUserFromApiKey(token);
161
- if (apiKeyUser) {
162
- request.user = apiKeyUser.user;
163
- request.apiKeyScopes = apiKeyUser.scopes;
164
- return;
165
- }
166
-
167
- const serviceAccount = await resolveServiceAccountFromApiKey(token);
168
- if (serviceAccount) {
169
- request.serviceAccount = serviceAccount;
170
- request.apiKeyScopes = ["api:read", "api:write", "service_account"];
171
- // Synthesize a user so existing routes that expect request.user keep working.
172
- request.user = {
173
- id: `sa:${serviceAccount.id}`,
174
- email: `service-account@${serviceAccount.id}.internal`,
175
- username: `sa-${serviceAccount.id.slice(0, 8)}`,
176
- name: serviceAccount.name,
177
- avatarUrl: null,
178
- emailVerified: true,
179
- plan: "enterprise",
180
- role: "service_account",
181
- provider: "api_key",
182
- zitadelUserId: null,
183
- defaultOrgId: serviceAccount.orgId,
184
- phoneNumber: null,
185
- phoneVerified: false,
186
- totpSecret: null,
187
- totpEnabled: false,
188
- totpVerifiedAt: null,
189
- createdAt: serviceAccount.createdAt,
190
- updatedAt: serviceAccount.updatedAt,
191
- } as User;
192
- return;
193
- }
194
-
195
- return reply.status(401).send({ error: "Invalid token or API key" });
196
- });
197
-
198
- app.decorate("requireScopes", function requireScopes(...required: string[]) {
199
- return async function scopeCheck(request: FastifyRequest, reply: FastifyReply) {
200
- // Session-based authentication has full scope access.
201
- if (!request.apiKeyScopes) return;
202
- const scopes = request.apiKeyScopes;
203
- const hasAll = required.every((scope) => scopes.includes(scope) || scopes.includes("service_account"));
204
- if (!hasAll) {
205
- return reply.status(403).send({ error: "Insufficient API key scope", required });
206
- }
207
- };
208
- });
209
- });
210
-
211
- async function resolveServiceAccountFromApiKey(key: string) {
212
- const hash = hashApiKey(key);
213
- const [keyRecord] = await db
214
- .select()
215
- .from(apiKeys)
216
- .where(and(eq(apiKeys.keyHash, hash), isNull(apiKeys.revokedAt)))
217
- .limit(1);
218
-
219
- if (!keyRecord) return undefined;
220
- if (keyRecord.expiresAt && keyRecord.expiresAt < new Date()) return undefined;
221
- if (!keyRecord.serviceAccountId) return undefined;
222
-
223
- await db.update(apiKeys).set({ lastUsedAt: new Date() }).where(eq(apiKeys.id, keyRecord.id));
224
- const [account] = await db
225
- .select()
226
- .from(serviceAccounts)
227
- .where(and(eq(serviceAccounts.id, keyRecord.serviceAccountId), eq(serviceAccounts.isActive, true)))
228
- .limit(1);
229
- return account;
230
- }
@@ -1,41 +0,0 @@
1
- import fp from "fastify-plugin";
2
- import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
3
- import { register, Counter, Histogram } from "prom-client";
4
-
5
- export const httpRequestsTotal = new Counter({
6
- name: "keystone_http_requests_total",
7
- help: "Total HTTP requests",
8
- labelNames: ["method", "route", "status_code"],
9
- });
10
-
11
- export const httpRequestDurationSeconds = new Histogram({
12
- name: "keystone_http_request_duration_seconds",
13
- help: "HTTP request duration in seconds",
14
- labelNames: ["method", "route", "status_code"],
15
- buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
16
- });
17
-
18
- export const failedLoginsTotal = new Counter({
19
- name: "keystone_failed_logins_total",
20
- help: "Total failed login attempts",
21
- labelNames: ["reason"],
22
- });
23
-
24
- export default fp(async function metricsPlugin(app: FastifyInstance) {
25
- app.addHook("onResponse", async (request: FastifyRequest, reply: FastifyReply) => {
26
- const route = (request as unknown as { routeOptions?: { url?: string } }).routeOptions?.url || request.url;
27
- const labels = {
28
- method: request.method,
29
- route,
30
- status_code: String(reply.statusCode),
31
- };
32
- httpRequestsTotal.inc(labels);
33
- const elapsedMs = (reply as unknown as { elapsedTime?: number }).elapsedTime ?? 0;
34
- httpRequestDurationSeconds.observe(labels, elapsedMs / 1000);
35
- });
36
-
37
- app.get("/metrics", async (_request: FastifyRequest, reply: FastifyReply) => {
38
- reply.header("Content-Type", register.contentType);
39
- return register.metrics();
40
- });
41
- });
@@ -1,94 +0,0 @@
1
- import fp from "fastify-plugin";
2
- import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
3
- import { eq } from "drizzle-orm";
4
- import { db } from "../db/index.js";
5
- import { serviceAccounts } from "../db/schema.js";
6
-
7
- /**
8
- * mTLS authentication plugin.
9
- *
10
- * In production, terminate TLS at a reverse proxy (nginx, envoy, AWS ALB, etc.)
11
- * that validates the client certificate and forwards the certificate fingerprint
12
- * or subject in a trusted header. This plugin reads that header and maps
13
- * certificates to service accounts.
14
- *
15
- * Headers read:
16
- * - x-client-cert-fingerprint: SHA-256 fingerprint of the client certificate
17
- * - x-forwarded-client-cert: PEM-encoded client certificate or DN subject
18
- * - x-service-account-id: Optional explicit service account ID (for non-mTLS fallback)
19
- */
20
-
21
- const MTLS_HEADER = "x-forwarded-client-cert";
22
- const MTLS_FINGERPRINT_HEADER = "x-client-cert-fingerprint";
23
- const SERVICE_ACCOUNT_ID_HEADER = "x-service-account-id";
24
-
25
- declare module "fastify" {
26
- interface FastifyInstance {
27
- requireMTLS: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
28
- }
29
- }
30
-
31
- export function extractClientCert(request: FastifyRequest): { fingerprint?: string; subject?: string } {
32
- const fingerprint = request.headers[MTLS_FINGERPRINT_HEADER];
33
- const cert = request.headers[MTLS_HEADER];
34
- return {
35
- fingerprint: typeof fingerprint === "string" ? fingerprint : undefined,
36
- subject: typeof cert === "string" ? cert : undefined,
37
- };
38
- }
39
-
40
- async function resolveServiceAccount(request: FastifyRequest): Promise<typeof serviceAccounts.$inferSelect | undefined> {
41
- const explicitId = request.headers[SERVICE_ACCOUNT_ID_HEADER];
42
- if (typeof explicitId === "string" && explicitId) {
43
- const [sa] = await db
44
- .select()
45
- .from(serviceAccounts)
46
- .where(eq(serviceAccounts.id, explicitId))
47
- .limit(1);
48
- if (sa?.isActive) {
49
- return sa;
50
- }
51
- }
52
-
53
- const { fingerprint, subject } = extractClientCert(request);
54
- if (!fingerprint && !subject) return undefined;
55
-
56
- // Look up service accounts by name matching the fingerprint or subject.
57
- // In a production system, you would store the certificate fingerprint in
58
- // the service_accounts table and query by it directly.
59
- const [sa] = await db
60
- .select()
61
- .from(serviceAccounts)
62
- .where(eq(serviceAccounts.name, fingerprint || subject || ""))
63
- .limit(1);
64
-
65
- if (sa?.isActive) {
66
- return sa;
67
- }
68
-
69
- return undefined;
70
- }
71
-
72
- export function requireMTLS() {
73
- return async function (request: FastifyRequest, reply: FastifyReply) {
74
- const { fingerprint, subject } = extractClientCert(request);
75
- const explicitId = request.headers[SERVICE_ACCOUNT_ID_HEADER];
76
-
77
- if (!fingerprint && !subject && !explicitId) {
78
- return reply.status(401).send({ error: "Client certificate required" });
79
- }
80
-
81
- const serviceAccount = await resolveServiceAccount(request);
82
- if (!serviceAccount) {
83
- request.log.warn({ fingerprint, subject }, "mTLS: no matching service account found");
84
- return reply.status(403).send({ error: "Client certificate not mapped to a service account" });
85
- }
86
-
87
- request.serviceAccount = serviceAccount;
88
- request.log.debug({ serviceAccountId: serviceAccount.id }, "mTLS: service account authenticated");
89
- };
90
- }
91
-
92
- export default fp(async function mtlsPlugin(app: FastifyInstance) {
93
- app.decorate("requireMTLS", requireMTLS());
94
- });
@@ -1,29 +0,0 @@
1
- import fp from "fastify-plugin";
2
- import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
3
- import { requirePermission, hasPermission, type PermissionInput } from "../services/permissions.js";
4
-
5
- declare module "fastify" {
6
- interface FastifyInstance {
7
- requirePermission: (resource: string, action: string) => (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
8
- }
9
- }
10
-
11
- export default fp(async function permissionsPlugin(app: FastifyInstance) {
12
- app.decorate(
13
- "requirePermission",
14
- function (resource: string, action: string) {
15
- return async function (request: FastifyRequest, reply: FastifyReply) {
16
- const membership = request.state?.membership;
17
- if (!membership) {
18
- return reply.status(403).send({ error: "Organization membership required" });
19
- }
20
- try {
21
- await requirePermission(membership.role, resource, action);
22
- } catch (err) {
23
- const message = err instanceof Error ? err.message : "Forbidden";
24
- return reply.status(403).send({ error: message });
25
- }
26
- };
27
- }
28
- );
29
- });