@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,74 +0,0 @@
1
- import crypto from "node:crypto";
2
- import { eq, and, gt, isNull } from "drizzle-orm";
3
- import { db } from "../db/index.js";
4
- import { smsOtpCodes, users, type User } from "../db/schema.js";
5
- import { smsProvider } from "./sms.js";
6
-
7
- const CODE_TTL_SECONDS = 300;
8
- const CODE_LENGTH = 6;
9
-
10
- export function generateSmsCode(): string {
11
- return crypto.randomInt(0, 1_000_000).toString().padStart(CODE_LENGTH, "0");
12
- }
13
-
14
- function hashCode(code: string): string {
15
- return crypto.createHash("sha256").update(code).digest("hex");
16
- }
17
-
18
- export async function sendSmsOtp(user: User, phoneNumber: string): Promise<string> {
19
- const code = generateSmsCode();
20
- const expiresAt = new Date(Date.now() + CODE_TTL_SECONDS * 1000);
21
-
22
- await db.insert(smsOtpCodes).values({
23
- userId: user.id,
24
- phoneNumber,
25
- codeHash: hashCode(code),
26
- expiresAt,
27
- });
28
-
29
- await smsProvider.send({
30
- to: phoneNumber,
31
- body: `Your Hilbras verification code is: ${code}`,
32
- });
33
-
34
- return code;
35
- }
36
-
37
- export async function verifySmsOtp(userId: string, code: string): Promise<boolean> {
38
- const codeHash = hashCode(code);
39
- const now = new Date();
40
-
41
- const [record] = await db
42
- .select()
43
- .from(smsOtpCodes)
44
- .where(
45
- and(
46
- eq(smsOtpCodes.userId, userId),
47
- eq(smsOtpCodes.codeHash, codeHash),
48
- gt(smsOtpCodes.expiresAt, now),
49
- isNull(smsOtpCodes.usedAt)
50
- )
51
- )
52
- .limit(1);
53
-
54
- if (!record) return false;
55
-
56
- await db.update(smsOtpCodes).set({ usedAt: now }).where(eq(smsOtpCodes.id, record.id));
57
- return true;
58
- }
59
-
60
- export async function hasVerifiedPhone(userId: string): Promise<boolean> {
61
- const [user] = await db
62
- .select({ phoneVerified: users.phoneVerified })
63
- .from(users)
64
- .where(eq(users.id, userId))
65
- .limit(1);
66
- return user?.phoneVerified ?? false;
67
- }
68
-
69
- export async function markPhoneVerified(userId: string, phoneNumber: string): Promise<void> {
70
- await db
71
- .update(users)
72
- .set({ phoneNumber, phoneVerified: true })
73
- .where(eq(users.id, userId));
74
- }
@@ -1,287 +0,0 @@
1
- import crypto from "node:crypto";
2
- import {
3
- SignJWT,
4
- importPKCS8,
5
- importSPKI,
6
- jwtVerify,
7
- decodeProtectedHeader,
8
- exportJWK,
9
- type JWTPayload,
10
- } from "jose";
11
- import { eq, and, gt, isNull } from "drizzle-orm";
12
- import { db } from "../db/index.js";
13
- import {
14
- refreshTokens,
15
- users,
16
- type User,
17
- type RefreshToken,
18
- type Application,
19
- } from "../db/schema.js";
20
- import { config } from "../config.js";
21
- import type { TokenClaims } from "../types.js";
22
- import {
23
- getActiveSigningKey,
24
- listValidSigningKeys,
25
- type SigningKeyPair,
26
- } from "./secrets.js";
27
- import { SessionRepository } from "../repositories/session.js";
28
-
29
- /** Active signing key used to issue new tokens. */
30
- let activeKey: SigningKeyPair | null = null;
31
- /** All valid signing keys (active + grace-period keys) used for verification. */
32
- const validKeys = new Map<string, SigningKeyPair>();
33
-
34
- export async function loadSigningKeys(): Promise<void> {
35
- if (config.JWT_PRIVATE_KEY && config.JWT_PUBLIC_KEY) {
36
- const privateKey = await importPKCS8(config.JWT_PRIVATE_KEY, "RS256");
37
- const publicKey = await importSPKI(config.JWT_PUBLIC_KEY, "RS256");
38
- activeKey = { keyId: "env", privateKey, publicKey };
39
- validKeys.set(activeKey.keyId, activeKey);
40
- return;
41
- }
42
-
43
- activeKey = await getActiveSigningKey();
44
- const keys = await listValidSigningKeys();
45
- validKeys.clear();
46
- for (const key of keys) {
47
- validKeys.set(key.keyId, key);
48
- }
49
- }
50
-
51
- /**
52
- * Return the public JWK for the active signing key. Kept for backwards
53
- * compatibility; new code should prefer `getPublicJwks()`.
54
- */
55
- export async function getPublicJWK() {
56
- if (!activeKey) await loadSigningKeys();
57
- return exportJWK(activeKey!.publicKey);
58
- }
59
-
60
- /**
61
- * Return the JWKS document containing every valid public key, including
62
- * recently rotated keys still within the grace period.
63
- */
64
- export async function getPublicJwks() {
65
- if (validKeys.size === 0) await loadSigningKeys();
66
- const keys = await Promise.all(
67
- Array.from(validKeys.values()).map(async (key) => {
68
- const jwk = await exportJWK(key.publicKey);
69
- return { ...jwk, kid: key.keyId, use: "sig", key_ops: ["verify"] };
70
- })
71
- );
72
- return { keys };
73
- }
74
-
75
- function issuer(): string {
76
- return process.env.AUTH_API_PUBLIC_URL || `http://localhost:${config.PORT}`;
77
- }
78
-
79
- export interface AccessTokenOptions {
80
- appId?: string;
81
- orgId?: string;
82
- clientId?: string;
83
- deviceFingerprint?: string;
84
- }
85
-
86
- export function createAccessToken(user: User, opts: AccessTokenOptions = {}): Promise<string> {
87
- if (!activeKey) throw new Error("JWT signing keys not loaded");
88
- const claims: TokenClaims = {
89
- sub: user.id,
90
- email: user.email,
91
- username: user.username,
92
- name: user.name ?? undefined,
93
- plan: user.plan,
94
- role: user.role,
95
- provider: user.provider,
96
- };
97
- if (opts.orgId) claims.org_id = opts.orgId;
98
- if (opts.appId) claims.app_id = opts.appId;
99
- if (opts.clientId) claims.client_id = opts.clientId;
100
- if (opts.deviceFingerprint) claims.device_fingerprint = opts.deviceFingerprint;
101
- return new SignJWT(claims as unknown as Record<string, unknown>)
102
- .setProtectedHeader({ alg: "RS256", typ: "JWT", kid: activeKey.keyId })
103
- .setIssuedAt()
104
- .setIssuer(issuer())
105
- .setAudience("hilbras")
106
- .setExpirationTime(`${config.ACCESS_TOKEN_TTL_SECONDS}s`)
107
- .sign(activeKey.privateKey);
108
- }
109
-
110
- export interface ApplicationAccessTokenOptions {
111
- appId: string;
112
- orgId: string;
113
- clientId: string;
114
- scopes?: string[];
115
- }
116
-
117
- export function createApplicationAccessToken(
118
- opts: ApplicationAccessTokenOptions
119
- ): Promise<string> {
120
- if (!activeKey) throw new Error("JWT signing keys not loaded");
121
- const claims: Record<string, unknown> = {
122
- sub: opts.clientId,
123
- client_id: opts.clientId,
124
- app_id: opts.appId,
125
- org_id: opts.orgId,
126
- };
127
- if (opts.scopes && opts.scopes.length > 0) {
128
- claims.scope = opts.scopes.join(" ");
129
- }
130
- return new SignJWT(claims)
131
- .setProtectedHeader({ alg: "RS256", typ: "JWT", kid: activeKey.keyId })
132
- .setIssuedAt()
133
- .setIssuer(issuer())
134
- .setAudience("hilbras")
135
- .setExpirationTime(`${config.ACCESS_TOKEN_TTL_SECONDS}s`)
136
- .sign(activeKey.privateKey);
137
- }
138
-
139
- export async function createIdToken(
140
- user: User,
141
- app: Application,
142
- nonce?: string
143
- ): Promise<string> {
144
- if (!activeKey) throw new Error("JWT signing keys not loaded");
145
- const claims: Record<string, unknown> = {
146
- sub: user.id,
147
- email: user.email,
148
- email_verified: user.emailVerified,
149
- username: user.username,
150
- name: user.name,
151
- picture: user.avatarUrl,
152
- aud: app.clientId,
153
- azp: app.clientId,
154
- };
155
- if (nonce) claims.nonce = nonce;
156
- return new SignJWT(claims)
157
- .setProtectedHeader({ alg: "RS256", typ: "JWT", kid: activeKey.keyId })
158
- .setIssuedAt()
159
- .setIssuer(issuer())
160
- .setExpirationTime(`${config.ACCESS_TOKEN_TTL_SECONDS}s`)
161
- .sign(activeKey.privateKey);
162
- }
163
-
164
- export interface TokenSet {
165
- accessToken: string;
166
- refreshToken: string;
167
- refreshTokenHash: string;
168
- expiresAt: Date;
169
- }
170
-
171
- export async function createTokenSet(
172
- user: User,
173
- ip?: string,
174
- userAgent?: string,
175
- opts: AccessTokenOptions = {},
176
- deviceFingerprint?: string
177
- ): Promise<TokenSet> {
178
- const accessToken = await createAccessToken(user, opts);
179
- const refreshToken = crypto.randomBytes(48).toString("base64url");
180
- const refreshTokenHash = hashToken(refreshToken);
181
- const expiresAt = new Date(Date.now() + config.REFRESH_TOKEN_TTL_SECONDS * 1000);
182
-
183
- const [inserted] = await db.insert(refreshTokens).values({
184
- userId: user.id,
185
- appId: opts.appId ?? null,
186
- tokenHash: refreshTokenHash,
187
- expiresAt,
188
- ipAddress: ip ?? null,
189
- userAgent: userAgent ?? null,
190
- deviceFingerprint: deviceFingerprint ?? null,
191
- }).returning();
192
-
193
- try {
194
- const sessions = new SessionRepository();
195
- await sessions.create({
196
- userId: user.id,
197
- refreshTokenId: inserted.id,
198
- deviceFingerprint,
199
- ipAddress: ip,
200
- userAgent,
201
- expiresAt,
202
- });
203
- } catch {
204
- // Session tracking is best-effort; token creation must not fail because of it.
205
- }
206
-
207
- return { accessToken, refreshToken, refreshTokenHash, expiresAt };
208
- }
209
-
210
- export async function verifyAccessToken(token: string): Promise<TokenClaims> {
211
- if (!activeKey) await loadSigningKeys();
212
-
213
- const header = decodeProtectedHeader(token);
214
- const keyPair = header.kid ? validKeys.get(header.kid) : undefined;
215
- const publicKey = keyPair?.publicKey ?? activeKey?.publicKey;
216
-
217
- if (!publicKey) {
218
- throw new Error("JWT signing keys not loaded");
219
- }
220
-
221
- const { payload } = await jwtVerify(token, publicKey, {
222
- issuer: issuer(),
223
- audience: "hilbras",
224
- });
225
- return payload as unknown as TokenClaims;
226
- }
227
-
228
- export async function rotateRefreshToken(
229
- token: string,
230
- ip?: string,
231
- userAgent?: string
232
- ): Promise<TokenSet | null> {
233
- const hash = hashToken(token);
234
- const now = new Date();
235
-
236
- const [existing] = await db
237
- .select()
238
- .from(refreshTokens)
239
- .where(
240
- and(
241
- eq(refreshTokens.tokenHash, hash),
242
- gt(refreshTokens.expiresAt, now),
243
- isNull(refreshTokens.revokedAt)
244
- )
245
- )
246
- .limit(1);
247
-
248
- if (!existing) return null;
249
-
250
- // Revoke old token immediately.
251
- await db
252
- .update(refreshTokens)
253
- .set({ revokedAt: now })
254
- .where(eq(refreshTokens.id, existing.id));
255
-
256
- const [user] = await db.select().from(users).where(eq(users.id, existing.userId)).limit(1);
257
- if (!user) return null;
258
-
259
- return createTokenSet(
260
- user,
261
- ip,
262
- userAgent,
263
- {
264
- appId: existing.appId ?? undefined,
265
- orgId: undefined,
266
- clientId: undefined,
267
- deviceFingerprint: existing.deviceFingerprint ?? undefined,
268
- },
269
- existing.deviceFingerprint ?? undefined
270
- );
271
- }
272
-
273
- export async function revokeRefreshToken(token: string): Promise<void> {
274
- const hash = hashToken(token);
275
- await db.update(refreshTokens).set({ revokedAt: new Date() }).where(eq(refreshTokens.tokenHash, hash));
276
- }
277
-
278
- export async function revokeAllUserRefreshTokens(userId: string): Promise<void> {
279
- await db.update(refreshTokens).set({ revokedAt: new Date() }).where(eq(refreshTokens.userId, userId));
280
- }
281
-
282
- function hashToken(token: string): string {
283
- return crypto.createHash("sha256").update(token).digest("hex");
284
- }
285
-
286
- // Re-exported from secrets service for backwards compatibility.
287
- export { hashApiKey, generateApiKey } from "./secrets.js";
@@ -1,113 +0,0 @@
1
- import crypto from "node:crypto";
2
- import { eq, and, isNull } from "drizzle-orm";
3
- import { Secret, TOTP } from "otpauth";
4
- import { config } from "../config.js";
5
- import { db } from "../db/index.js";
6
- import { totpBackupCodes } from "../db/schema.js";
7
-
8
- const ALGORITHM = "aes-256-cbc";
9
- const IV_LENGTH = 16;
10
-
11
- function getEncryptionKey(): Buffer {
12
- const raw = config.TOTP_ENCRYPTION_KEY || config.INTERNAL_API_KEY;
13
- if (raw && raw.length >= 32) {
14
- return Buffer.from(raw.slice(0, 32));
15
- }
16
- return crypto.createHash("sha256").update(raw || "keystone-totp-default").digest();
17
- }
18
-
19
- export function generateSecret(): string {
20
- return new Secret({ size: 20 }).base32;
21
- }
22
-
23
- export function buildProvisioningUri(input: { secret: string; email: string; issuer?: string }): string {
24
- const issuer = input.issuer || config.TOTP_ISSUER;
25
- const totp = new TOTP({
26
- issuer,
27
- label: input.email,
28
- algorithm: "SHA1",
29
- digits: 6,
30
- period: 30,
31
- secret: Secret.fromBase32(input.secret),
32
- });
33
- return totp.toString();
34
- }
35
-
36
- export function verifyTOTP(secret: string, code: string, window = 1): boolean {
37
- try {
38
- const totp = new TOTP({
39
- algorithm: "SHA1",
40
- digits: 6,
41
- period: 30,
42
- secret: Secret.fromBase32(secret),
43
- });
44
- const delta = totp.validate({ token: code, window });
45
- return delta !== null;
46
- } catch {
47
- return false;
48
- }
49
- }
50
-
51
- export function encryptSecret(secret: string): string {
52
- const key = getEncryptionKey();
53
- const iv = crypto.randomBytes(IV_LENGTH);
54
- const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
55
- const encrypted = Buffer.concat([cipher.update(secret, "utf8"), cipher.final()]);
56
- return `${iv.toString("base64url")}:${encrypted.toString("base64url")}`;
57
- }
58
-
59
- export function decryptSecret(encrypted: string): string {
60
- const [ivBase64, dataBase64] = encrypted.split(":");
61
- if (!ivBase64 || !dataBase64) throw new Error("Invalid encrypted secret format");
62
- const key = getEncryptionKey();
63
- const iv = Buffer.from(ivBase64, "base64url");
64
- const encryptedData = Buffer.from(dataBase64, "base64url");
65
- const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
66
- const decrypted = Buffer.concat([decipher.update(encryptedData), decipher.final()]);
67
- return decrypted.toString("utf8");
68
- }
69
-
70
- export function generateBackupCodes(): { codes: string[]; hashes: string[] } {
71
- const codes: string[] = [];
72
- const hashes: string[] = [];
73
- for (let i = 0; i < 10; i++) {
74
- const code = crypto.randomBytes(4).toString("hex").toLowerCase();
75
- codes.push(code);
76
- hashes.push(crypto.createHash("sha256").update(code).digest("hex"));
77
- }
78
- return { codes, hashes };
79
- }
80
-
81
- export async function storeBackupCodes(userId: string, codeHashes: string[]): Promise<void> {
82
- if (codeHashes.length === 0) return;
83
- await db.delete(totpBackupCodes).where(eq(totpBackupCodes.userId, userId));
84
- await db.insert(totpBackupCodes).values(
85
- codeHashes.map((hash) => ({ userId, codeHash: hash }))
86
- );
87
- }
88
-
89
- export async function verifyBackupCode(userId: string, code: string): Promise<boolean> {
90
- const codeHash = crypto.createHash("sha256").update(code).digest("hex");
91
- const now = new Date();
92
-
93
- const [record] = await db
94
- .select()
95
- .from(totpBackupCodes)
96
- .where(
97
- and(
98
- eq(totpBackupCodes.userId, userId),
99
- eq(totpBackupCodes.codeHash, codeHash),
100
- isNull(totpBackupCodes.usedAt)
101
- )
102
- )
103
- .limit(1);
104
-
105
- if (!record) return false;
106
-
107
- await db
108
- .update(totpBackupCodes)
109
- .set({ usedAt: now })
110
- .where(eq(totpBackupCodes.id, record.id));
111
-
112
- return true;
113
- }
@@ -1,239 +0,0 @@
1
- import { eq, sql } from "drizzle-orm";
2
- import { db } from "../db/index.js";
3
- import { users, userIdentities, identityProviders, orgMemberships, type User } from "../db/schema.js";
4
-
5
- export interface OAuthClaims {
6
- sub: string;
7
- email: string;
8
- username?: string;
9
- name?: string;
10
- picture?: string;
11
- email_verified?: boolean;
12
- }
13
-
14
- export async function findUserByEmail(email: string): Promise<User | undefined> {
15
- const [user] = await db.select().from(users).where(eq(users.email, email.toLowerCase())).limit(1);
16
- return user;
17
- }
18
-
19
- export async function findUserById(id: string): Promise<User | undefined> {
20
- const [user] = await db.select().from(users).where(eq(users.id, id)).limit(1);
21
- return user;
22
- }
23
-
24
- export async function findUserByZitadelId(zitadelUserId: string): Promise<User | undefined> {
25
- const [user] = await db.select().from(users).where(eq(users.zitadelUserId, zitadelUserId)).limit(1);
26
- return user;
27
- }
28
-
29
- export async function createPasswordUser(input: {
30
- zitadelUserId?: string;
31
- passwordHash?: string;
32
- username: string;
33
- email: string;
34
- name: string;
35
- emailVerified?: boolean;
36
- }): Promise<User> {
37
- const [user] = await db
38
- .insert(users)
39
- .values({
40
- zitadelUserId: input.zitadelUserId ?? null,
41
- passwordHash: input.passwordHash ?? null,
42
- username: slugifyUsername(input.username),
43
- email: input.email.toLowerCase().trim(),
44
- name: input.name.trim() || input.username,
45
- provider: "password",
46
- emailVerified: input.emailVerified ?? true,
47
- })
48
- .returning();
49
- return user;
50
- }
51
-
52
- export async function upsertOAuthUser(
53
- claims: OAuthClaims,
54
- providerType: string,
55
- providerId?: string
56
- ): Promise<User> {
57
- const username = slugifyUsername(claims.username || claims.name || claims.email.split("@")[0]);
58
- const email = claims.email.toLowerCase().trim();
59
-
60
- // Prefer linking by external identity when a provider record is available.
61
- if (providerId) {
62
- const [existingLink] = await db
63
- .select({ user: users })
64
- .from(userIdentities)
65
- .where(eq(userIdentities.externalSub, claims.sub))
66
- .innerJoin(users, eq(userIdentities.userId, users.id))
67
- .limit(1);
68
-
69
- if (existingLink) {
70
- const existing = existingLink.user;
71
- const [updated] = await db
72
- .update(users)
73
- .set({
74
- email,
75
- username: await ensureUniqueUsername(username, existing.id),
76
- name: claims.name || existing.name,
77
- avatarUrl: claims.picture || existing.avatarUrl,
78
- emailVerified: claims.email_verified ?? existing.emailVerified ?? true,
79
- provider: providerType,
80
- updatedAt: sql`now()`,
81
- })
82
- .where(eq(users.id, existing.id))
83
- .returning();
84
- return updated;
85
- }
86
- }
87
-
88
- // Fall back to email-based matching.
89
- const existing = await findUserByEmail(email);
90
- if (existing) {
91
- const [updated] = await db
92
- .update(users)
93
- .set({
94
- email,
95
- username: await ensureUniqueUsername(username, existing.id),
96
- name: claims.name || existing.name,
97
- avatarUrl: claims.picture || existing.avatarUrl,
98
- emailVerified: claims.email_verified ?? existing.emailVerified ?? true,
99
- provider: providerType,
100
- updatedAt: sql`now()`,
101
- })
102
- .where(eq(users.id, existing.id))
103
- .returning();
104
- return updated;
105
- }
106
-
107
- const [user] = await db
108
- .insert(users)
109
- .values({
110
- email,
111
- username: await ensureUniqueUsername(username),
112
- name: claims.name || username,
113
- avatarUrl: claims.picture,
114
- emailVerified: claims.email_verified ?? true,
115
- provider: providerType,
116
- })
117
- .returning();
118
-
119
- if (providerId) {
120
- await db.insert(userIdentities).values({
121
- userId: user.id,
122
- providerId,
123
- providerType,
124
- externalSub: claims.sub,
125
- email,
126
- profile: { name: claims.name, picture: claims.picture, username: claims.username },
127
- });
128
- }
129
-
130
- return user;
131
- }
132
-
133
- export async function linkUserIdentity(
134
- userId: string,
135
- providerId: string,
136
- providerType: string,
137
- externalSub: string,
138
- email?: string,
139
- profile?: Record<string, unknown>
140
- ): Promise<void> {
141
- const [provider] = await db.select().from(identityProviders).where(eq(identityProviders.id, providerId)).limit(1);
142
- if (!provider) throw new Error("Identity provider not found");
143
- await db
144
- .insert(userIdentities)
145
- .values({
146
- userId,
147
- providerId,
148
- providerType,
149
- externalSub,
150
- email,
151
- profile: profile ?? {},
152
- })
153
- .onConflictDoNothing({ target: [userIdentities.providerId, userIdentities.externalSub] });
154
- }
155
-
156
- export async function updateUserLastSeen(id: string): Promise<void> {
157
- await db.update(users).set({ updatedAt: sql`now()` }).where(eq(users.id, id));
158
- }
159
-
160
- export async function findOrCreateUserByEmail(input: {
161
- email: string;
162
- name?: string;
163
- username?: string;
164
- }): Promise<User> {
165
- const existing = await findUserByEmail(input.email);
166
- if (existing) return existing;
167
-
168
- const baseUsername = input.username || input.email.split("@")[0];
169
- const username = await ensureUniqueUsername(slugifyUsername(baseUsername));
170
-
171
- const [user] = await db
172
- .insert(users)
173
- .values({
174
- email: input.email.toLowerCase().trim(),
175
- username,
176
- name: input.name || username,
177
- provider: "password",
178
- emailVerified: false,
179
- })
180
- .returning();
181
- return user;
182
- }
183
-
184
- export async function listUsersByOrg(orgId: string): Promise<User[]> {
185
- const rows = await db
186
- .select({ user: users })
187
- .from(users)
188
- .innerJoin(orgMemberships, eq(users.id, orgMemberships.userId))
189
- .where(eq(orgMemberships.orgId, orgId));
190
- return rows.map((r) => r.user);
191
- }
192
-
193
- export async function updateUser(
194
- userId: string,
195
- updates: Partial<{
196
- name: string;
197
- username: string;
198
- role: string;
199
- emailVerified: boolean;
200
- }>
201
- ): Promise<User | undefined> {
202
- const [updated] = await db
203
- .update(users)
204
- .set({ ...updates, updatedAt: sql`now()` })
205
- .where(eq(users.id, userId))
206
- .returning();
207
- return updated;
208
- }
209
-
210
- export async function deactivateUser(userId: string): Promise<void> {
211
- await db.update(users).set({ emailVerified: false, updatedAt: sql`now()` }).where(eq(users.id, userId));
212
- }
213
-
214
- export function slugifyUsername(input: string): string {
215
- return input
216
- .toLowerCase()
217
- .trim()
218
- .replace(/[^a-z0-9_-]+/g, "-")
219
- .replace(/^-+|-+$/g, "")
220
- .slice(0, 32);
221
- }
222
-
223
- export async function ensureUniqueUsername(base: string, excludeId?: string): Promise<string> {
224
- let username = base || "user";
225
- let counter = 2;
226
- while (true) {
227
- const existing = await db
228
- .select({ id: users.id })
229
- .from(users)
230
- .where(eq(users.username, username))
231
- .limit(1);
232
- if (existing.length === 0 || existing[0].id === excludeId) {
233
- return username;
234
- }
235
- username = `${base}-${counter}`;
236
- counter++;
237
- }
238
- }
239
-