@hilbras/keystone 1.5.0 → 1.9.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 (559) hide show
  1. package/CHANGELOG.md +272 -0
  2. package/README.md +59 -25
  3. package/dist/cli.js +25 -27
  4. package/dist/cli.js.map +1 -1
  5. package/dist/config.d.ts +15 -1
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +45 -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/{src/db/migrations/meta/0007_snapshot.json → dist/db/migrations/meta/0008_snapshot.json} +136 -32
  20. package/{src/db/migrations/meta/0006_snapshot.json → dist/db/migrations/meta/0009_snapshot.json} +359 -30
  21. package/{src/db/migrations/meta/0005_snapshot.json → dist/db/migrations/meta/0010_snapshot.json} +459 -29
  22. package/{src/db/migrations/meta/0004_snapshot.json → dist/db/migrations/meta/0011_snapshot.json} +594 -30
  23. package/dist/db/migrations/meta/0012_snapshot.json +3891 -0
  24. package/dist/db/migrations/meta/0013_snapshot.json +3919 -0
  25. package/dist/db/migrations/meta/0014_snapshot.json +4311 -0
  26. package/dist/db/migrations/meta/_journal.json +49 -0
  27. package/dist/db/reencryptOidcSecrets.d.ts +2 -0
  28. package/dist/db/reencryptOidcSecrets.d.ts.map +1 -0
  29. package/dist/db/reencryptOidcSecrets.js +41 -0
  30. package/dist/db/reencryptOidcSecrets.js.map +1 -0
  31. package/dist/db/schema.d.ts +2521 -53
  32. package/dist/db/schema.d.ts.map +1 -1
  33. package/dist/db/schema.js +118 -3
  34. package/dist/db/schema.js.map +1 -1
  35. package/dist/db/seed.js +67 -40
  36. package/dist/db/seed.js.map +1 -1
  37. package/dist/di.d.ts.map +1 -1
  38. package/dist/di.js +11 -3
  39. package/dist/di.js.map +1 -1
  40. package/dist/index.d.ts +2 -2
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +26 -2
  43. package/dist/index.js.map +1 -1
  44. package/dist/lib/errors.d.ts +2 -1
  45. package/dist/lib/errors.d.ts.map +1 -1
  46. package/dist/lib/errors.js +10 -0
  47. package/dist/lib/errors.js.map +1 -1
  48. package/dist/plugins/appContext.d.ts.map +1 -1
  49. package/dist/plugins/appContext.js +3 -12
  50. package/dist/plugins/appContext.js.map +1 -1
  51. package/dist/plugins/audit.d.ts.map +1 -1
  52. package/dist/plugins/audit.js +26 -6
  53. package/dist/plugins/audit.js.map +1 -1
  54. package/dist/plugins/auth.d.ts.map +1 -1
  55. package/dist/plugins/auth.js +32 -7
  56. package/dist/plugins/auth.js.map +1 -1
  57. package/dist/plugins/metrics.d.ts.map +1 -1
  58. package/dist/plugins/mtls.d.ts.map +1 -1
  59. package/dist/plugins/permissions.d.ts.map +1 -1
  60. package/dist/plugins/permissions.js +29 -9
  61. package/dist/plugins/permissions.js.map +1 -1
  62. package/dist/plugins/rateLimit.d.ts +15 -0
  63. package/dist/plugins/rateLimit.d.ts.map +1 -1
  64. package/dist/plugins/rateLimit.js +11 -1
  65. package/dist/plugins/rateLimit.js.map +1 -1
  66. package/dist/plugins/requestLogger.d.ts.map +1 -1
  67. package/dist/repositories/apiKey.d.ts.map +1 -1
  68. package/dist/repositories/application.d.ts.map +1 -1
  69. package/dist/repositories/application.js +1 -1
  70. package/dist/repositories/application.js.map +1 -1
  71. package/dist/repositories/audit.d.ts.map +1 -1
  72. package/dist/repositories/index.d.ts +3 -0
  73. package/dist/repositories/index.d.ts.map +1 -1
  74. package/dist/repositories/index.js +3 -0
  75. package/dist/repositories/index.js.map +1 -1
  76. package/dist/repositories/mfaChallenge.d.ts +23 -0
  77. package/dist/repositories/mfaChallenge.d.ts.map +1 -0
  78. package/dist/repositories/mfaChallenge.js +71 -0
  79. package/dist/repositories/mfaChallenge.js.map +1 -0
  80. package/dist/repositories/oidcConnection.d.ts +27 -43
  81. package/dist/repositories/oidcConnection.d.ts.map +1 -1
  82. package/dist/repositories/oidcConnection.js +15 -6
  83. package/dist/repositories/oidcConnection.js.map +1 -1
  84. package/dist/repositories/organization.d.ts +9 -9
  85. package/dist/repositories/organization.d.ts.map +1 -1
  86. package/dist/repositories/organization.js +91 -37
  87. package/dist/repositories/organization.js.map +1 -1
  88. package/dist/repositories/permission.d.ts.map +1 -1
  89. package/dist/repositories/permission.js +27 -5
  90. package/dist/repositories/permission.js.map +1 -1
  91. package/dist/repositories/samlConnection.d.ts +28 -28
  92. package/dist/repositories/samlConnection.d.ts.map +1 -1
  93. package/dist/repositories/samlConnection.js +12 -4
  94. package/dist/repositories/samlConnection.js.map +1 -1
  95. package/dist/repositories/scimConnection.d.ts +38 -0
  96. package/dist/repositories/scimConnection.d.ts.map +1 -0
  97. package/dist/repositories/scimConnection.js +123 -0
  98. package/dist/repositories/scimConnection.js.map +1 -0
  99. package/dist/repositories/scimGroup.d.ts +36 -0
  100. package/dist/repositories/scimGroup.d.ts.map +1 -0
  101. package/dist/repositories/scimGroup.js +113 -0
  102. package/dist/repositories/scimGroup.js.map +1 -0
  103. package/dist/repositories/session.d.ts +23 -13
  104. package/dist/repositories/session.d.ts.map +1 -1
  105. package/dist/repositories/session.js +13 -1
  106. package/dist/repositories/session.js.map +1 -1
  107. package/dist/repositories/types.d.ts +112 -5
  108. package/dist/repositories/types.d.ts.map +1 -1
  109. package/dist/repositories/types.js +7 -1
  110. package/dist/repositories/types.js.map +1 -1
  111. package/dist/repositories/user.d.ts +23 -1
  112. package/dist/repositories/user.d.ts.map +1 -1
  113. package/dist/repositories/user.js +180 -4
  114. package/dist/repositories/user.js.map +1 -1
  115. package/dist/routes/admin/billing.js +4 -4
  116. package/dist/routes/admin/billing.js.map +1 -1
  117. package/dist/routes/admin/helpers.d.ts +16 -20
  118. package/dist/routes/admin/helpers.d.ts.map +1 -1
  119. package/dist/routes/admin/helpers.js +53 -10
  120. package/dist/routes/admin/helpers.js.map +1 -1
  121. package/dist/routes/admin/organizations.d.ts.map +1 -1
  122. package/dist/routes/admin/organizations.js +76 -69
  123. package/dist/routes/admin/organizations.js.map +1 -1
  124. package/dist/routes/admin/permissions.d.ts.map +1 -1
  125. package/dist/routes/admin/permissions.js +48 -14
  126. package/dist/routes/admin/permissions.js.map +1 -1
  127. package/dist/routes/admin/platform.d.ts.map +1 -1
  128. package/dist/routes/admin/platform.js +86 -35
  129. package/dist/routes/admin/platform.js.map +1 -1
  130. package/dist/routes/admin/sso.d.ts.map +1 -1
  131. package/dist/routes/admin/sso.js +143 -12
  132. package/dist/routes/admin/sso.js.map +1 -1
  133. package/dist/routes/admin/webhooks.js +8 -8
  134. package/dist/routes/admin/webhooks.js.map +1 -1
  135. package/dist/routes/apiKeys.d.ts.map +1 -1
  136. package/dist/routes/apiKeys.js +23 -5
  137. package/dist/routes/apiKeys.js.map +1 -1
  138. package/dist/routes/auth.d.ts.map +1 -1
  139. package/dist/routes/auth.js +112 -22
  140. package/dist/routes/auth.js.map +1 -1
  141. package/dist/routes/authz.d.ts.map +1 -1
  142. package/dist/routes/authz.js +16 -4
  143. package/dist/routes/authz.js.map +1 -1
  144. package/dist/routes/config.d.ts.map +1 -1
  145. package/dist/routes/config.js +16 -14
  146. package/dist/routes/config.js.map +1 -1
  147. package/dist/routes/federation.d.ts.map +1 -1
  148. package/dist/routes/federation.js +17 -3
  149. package/dist/routes/federation.js.map +1 -1
  150. package/dist/routes/magicLinks.d.ts.map +1 -1
  151. package/dist/routes/magicLinks.js +15 -3
  152. package/dist/routes/magicLinks.js.map +1 -1
  153. package/dist/routes/oauth.d.ts.map +1 -1
  154. package/dist/routes/oauth.js +22 -3
  155. package/dist/routes/oauth.js.map +1 -1
  156. package/dist/routes/oauth2.d.ts.map +1 -1
  157. package/dist/routes/oauth2.js +104 -11
  158. package/dist/routes/oauth2.js.map +1 -1
  159. package/dist/routes/oidcEnterprise.d.ts.map +1 -1
  160. package/dist/routes/oidcEnterprise.js +67 -21
  161. package/dist/routes/oidcEnterprise.js.map +1 -1
  162. package/dist/routes/password.d.ts.map +1 -1
  163. package/dist/routes/password.js.map +1 -1
  164. package/dist/routes/profile.js +4 -4
  165. package/dist/routes/profile.js.map +1 -1
  166. package/dist/routes/saml.d.ts +9 -0
  167. package/dist/routes/saml.d.ts.map +1 -1
  168. package/dist/routes/saml.js +187 -11
  169. package/dist/routes/saml.js.map +1 -1
  170. package/dist/routes/scim.d.ts +13 -0
  171. package/dist/routes/scim.d.ts.map +1 -1
  172. package/dist/routes/scim.js +885 -110
  173. package/dist/routes/scim.js.map +1 -1
  174. package/dist/routes/sdk.d.ts.map +1 -1
  175. package/dist/routes/sdk.js +24 -8
  176. package/dist/routes/sdk.js.map +1 -1
  177. package/dist/routes/serviceAccounts.d.ts.map +1 -1
  178. package/dist/routes/serviceAccounts.js +2 -1
  179. package/dist/routes/serviceAccounts.js.map +1 -1
  180. package/dist/routes/setup.d.ts.map +1 -1
  181. package/dist/routes/setup.js +15 -16
  182. package/dist/routes/setup.js.map +1 -1
  183. package/dist/routes/smsOtp.js +1 -1
  184. package/dist/routes/smsOtp.js.map +1 -1
  185. package/dist/routes/totp.d.ts.map +1 -1
  186. package/dist/routes/totp.js +113 -23
  187. package/dist/routes/totp.js.map +1 -1
  188. package/dist/routes/webauthn.d.ts.map +1 -1
  189. package/dist/routes/webauthn.js +44 -8
  190. package/dist/routes/webauthn.js.map +1 -1
  191. package/dist/routes/workflows.d.ts.map +1 -1
  192. package/dist/routes/workflows.js +58 -25
  193. package/dist/routes/workflows.js.map +1 -1
  194. package/dist/sdk/index.d.ts.map +1 -1
  195. package/dist/sdk/index.js +141 -40
  196. package/dist/sdk/index.js.map +1 -1
  197. package/dist/sdk/types.d.ts +60 -29
  198. package/dist/sdk/types.d.ts.map +1 -1
  199. package/dist/services/application/authentication.d.ts +39 -1
  200. package/dist/services/application/authentication.d.ts.map +1 -1
  201. package/dist/services/application/authentication.js +43 -1
  202. package/dist/services/application/authentication.js.map +1 -1
  203. package/dist/services/application/identity.d.ts +10 -7
  204. package/dist/services/application/identity.d.ts.map +1 -1
  205. package/dist/services/application/identity.js +13 -10
  206. package/dist/services/application/identity.js.map +1 -1
  207. package/dist/services/application/organization.d.ts +11 -7
  208. package/dist/services/application/organization.d.ts.map +1 -1
  209. package/dist/services/application/organization.js +160 -12
  210. package/dist/services/application/organization.js.map +1 -1
  211. package/dist/services/applications.js +2 -2
  212. package/dist/services/applications.js.map +1 -1
  213. package/dist/services/audit.d.ts +1 -0
  214. package/dist/services/audit.d.ts.map +1 -1
  215. package/dist/services/audit.js +13 -0
  216. package/dist/services/audit.js.map +1 -1
  217. package/dist/services/cache.d.ts.map +1 -1
  218. package/dist/services/configuration/profiles.d.ts +4 -0
  219. package/dist/services/configuration/profiles.d.ts.map +1 -1
  220. package/dist/services/configuration/profiles.js +50 -0
  221. package/dist/services/configuration/profiles.js.map +1 -1
  222. package/dist/services/configuration.d.ts.map +1 -1
  223. package/dist/services/configuration.js.map +1 -1
  224. package/dist/services/connectors/google.d.ts.map +1 -1
  225. package/dist/services/connectors/google.js +3 -2
  226. package/dist/services/connectors/google.js.map +1 -1
  227. package/dist/services/connectors/oidc.d.ts.map +1 -1
  228. package/dist/services/connectors/oidc.js +6 -3
  229. package/dist/services/connectors/oidc.js.map +1 -1
  230. package/dist/services/connectors/zitadel.d.ts.map +1 -1
  231. package/dist/services/connectors/zitadel.js +4 -3
  232. package/dist/services/connectors/zitadel.js.map +1 -1
  233. package/dist/services/domain/authentication.d.ts +43 -4
  234. package/dist/services/domain/authentication.d.ts.map +1 -1
  235. package/dist/services/domain/authentication.js +82 -20
  236. package/dist/services/domain/authentication.js.map +1 -1
  237. package/dist/services/domain/authorization.d.ts +11 -0
  238. package/dist/services/domain/authorization.d.ts.map +1 -1
  239. package/dist/services/domain/authorization.js +36 -1
  240. package/dist/services/domain/authorization.js.map +1 -1
  241. package/dist/services/domain/identity.d.ts +21 -9
  242. package/dist/services/domain/identity.d.ts.map +1 -1
  243. package/dist/services/domain/identity.js +187 -10
  244. package/dist/services/domain/identity.js.map +1 -1
  245. package/dist/services/domain/organization.d.ts +6 -9
  246. package/dist/services/domain/organization.d.ts.map +1 -1
  247. package/dist/services/domain/organization.js +48 -30
  248. package/dist/services/domain/organization.js.map +1 -1
  249. package/dist/services/emailVerification.d.ts +2 -2
  250. package/dist/services/enterpriseSso.d.ts +13 -6
  251. package/dist/services/enterpriseSso.d.ts.map +1 -1
  252. package/dist/services/enterpriseSso.js +75 -6
  253. package/dist/services/enterpriseSso.js.map +1 -1
  254. package/dist/services/events/subscribers/auditLog.js +1 -1
  255. package/dist/services/events/subscribers/auditLog.js.map +1 -1
  256. package/dist/services/events/types.d.ts +7 -1
  257. package/dist/services/events/types.d.ts.map +1 -1
  258. package/dist/services/events/types.js.map +1 -1
  259. package/dist/services/events/validate.d.ts.map +1 -1
  260. package/dist/services/events/validate.js +27 -0
  261. package/dist/services/events/validate.js.map +1 -1
  262. package/dist/services/features.d.ts.map +1 -1
  263. package/dist/services/features.js.map +1 -1
  264. package/dist/services/federation.d.ts +6 -1
  265. package/dist/services/federation.d.ts.map +1 -1
  266. package/dist/services/federation.js +31 -4
  267. package/dist/services/federation.js.map +1 -1
  268. package/dist/services/ipControls.js +2 -2
  269. package/dist/services/ipControls.js.map +1 -1
  270. package/dist/services/magicLinks.d.ts +2 -2
  271. package/dist/services/mfa.d.ts +53 -0
  272. package/dist/services/mfa.d.ts.map +1 -0
  273. package/dist/services/mfa.js +157 -0
  274. package/dist/services/mfa.js.map +1 -0
  275. package/dist/services/oauth2.d.ts +16 -12
  276. package/dist/services/oauth2.d.ts.map +1 -1
  277. package/dist/services/oauth2.js +22 -13
  278. package/dist/services/oauth2.js.map +1 -1
  279. package/dist/services/oidcSecretFormat.d.ts +3 -0
  280. package/dist/services/oidcSecretFormat.d.ts.map +1 -0
  281. package/dist/services/oidcSecretFormat.js +5 -0
  282. package/dist/services/oidcSecretFormat.js.map +1 -0
  283. package/dist/services/organizations.d.ts +4 -16
  284. package/dist/services/organizations.d.ts.map +1 -1
  285. package/dist/services/organizations.js +0 -62
  286. package/dist/services/organizations.js.map +1 -1
  287. package/dist/services/permissions.d.ts.map +1 -1
  288. package/dist/services/permissions.js +9 -1
  289. package/dist/services/permissions.js.map +1 -1
  290. package/dist/services/plugins/registry.d.ts.map +1 -1
  291. package/dist/services/plugins/registry.js.map +1 -1
  292. package/dist/services/plugins/types.d.ts.map +1 -1
  293. package/dist/services/queue/bullmq.d.ts.map +1 -1
  294. package/dist/services/queue/inProcess.d.ts.map +1 -1
  295. package/dist/services/redis.d.ts +1 -1
  296. package/dist/services/redis.d.ts.map +1 -1
  297. package/dist/services/scimCredentials.d.ts +46 -0
  298. package/dist/services/scimCredentials.d.ts.map +1 -0
  299. package/dist/services/scimCredentials.js +123 -0
  300. package/dist/services/scimCredentials.js.map +1 -0
  301. package/dist/services/scimLegacyMigration.d.ts +12 -0
  302. package/dist/services/scimLegacyMigration.d.ts.map +1 -0
  303. package/dist/services/scimLegacyMigration.js +44 -0
  304. package/dist/services/scimLegacyMigration.js.map +1 -0
  305. package/dist/services/secrets/awsKms.d.ts +2 -2
  306. package/dist/services/secrets/awsKms.d.ts.map +1 -1
  307. package/dist/services/secrets/awsKms.js +3 -5
  308. package/dist/services/secrets/awsKms.js.map +1 -1
  309. package/dist/services/secrets/azureKeyVault.d.ts.map +1 -1
  310. package/dist/services/secrets/database.d.ts.map +1 -1
  311. package/dist/services/secrets/database.js.map +1 -1
  312. package/dist/services/secrets/environment.d.ts.map +1 -1
  313. package/dist/services/secrets/environment.js.map +1 -1
  314. package/dist/services/secrets/index.d.ts.map +1 -1
  315. package/dist/services/secrets/password.d.ts.map +1 -1
  316. package/dist/services/secrets/password.js +0 -4
  317. package/dist/services/secrets/password.js.map +1 -1
  318. package/dist/services/secrets/provider.d.ts +2 -3
  319. package/dist/services/secrets/provider.d.ts.map +1 -1
  320. package/dist/services/secrets/vault.d.ts.map +1 -1
  321. package/dist/services/setup/configWriter.d.ts.map +1 -1
  322. package/dist/services/setup/configWriter.js.map +1 -1
  323. package/dist/services/ssoEndpointPolicy.d.ts +8 -0
  324. package/dist/services/ssoEndpointPolicy.d.ts.map +1 -0
  325. package/dist/services/ssoEndpointPolicy.js +136 -0
  326. package/dist/services/ssoEndpointPolicy.js.map +1 -0
  327. package/dist/services/stepUp.d.ts +35 -0
  328. package/dist/services/stepUp.d.ts.map +1 -0
  329. package/dist/services/stepUp.js +65 -0
  330. package/dist/services/stepUp.js.map +1 -0
  331. package/dist/services/tokens.d.ts +37 -11
  332. package/dist/services/tokens.d.ts.map +1 -1
  333. package/dist/services/tokens.js +75 -14
  334. package/dist/services/tokens.js.map +1 -1
  335. package/dist/services/totp.d.ts +46 -0
  336. package/dist/services/totp.d.ts.map +1 -1
  337. package/dist/services/totp.js +178 -41
  338. package/dist/services/totp.js.map +1 -1
  339. package/dist/services/users.d.ts +20 -12
  340. package/dist/services/users.d.ts.map +1 -1
  341. package/dist/services/users.js +24 -51
  342. package/dist/services/users.js.map +1 -1
  343. package/dist/services/webauthn.d.ts +8 -4
  344. package/dist/services/webauthn.d.ts.map +1 -1
  345. package/dist/services/webauthn.js +4 -4
  346. package/dist/services/webauthn.js.map +1 -1
  347. package/dist/services/webhooks.d.ts +20 -20
  348. package/dist/services/workflows/engine.d.ts +4 -2
  349. package/dist/services/workflows/engine.d.ts.map +1 -1
  350. package/dist/services/workflows/engine.js +181 -12
  351. package/dist/services/workflows/engine.js.map +1 -1
  352. package/dist/services/workflows/steps.d.ts +2 -0
  353. package/dist/services/workflows/steps.d.ts.map +1 -1
  354. package/dist/services/workflows/steps.js +8 -75
  355. package/dist/services/workflows/steps.js.map +1 -1
  356. package/dist/setup-server.js.map +1 -1
  357. package/dist/types.d.ts +33 -4
  358. package/dist/types.d.ts.map +1 -1
  359. package/dist/types.js +26 -2
  360. package/dist/types.js.map +1 -1
  361. package/package.json +26 -3
  362. package/dist/tests/errors.test.d.ts +0 -2
  363. package/dist/tests/errors.test.d.ts.map +0 -1
  364. package/dist/tests/errors.test.js +0 -64
  365. package/dist/tests/errors.test.js.map +0 -1
  366. package/dist/tests/events.test.d.ts +0 -2
  367. package/dist/tests/events.test.d.ts.map +0 -1
  368. package/dist/tests/events.test.js +0 -45
  369. package/dist/tests/events.test.js.map +0 -1
  370. package/dist/tests/featureFlags.test.d.ts +0 -2
  371. package/dist/tests/featureFlags.test.d.ts.map +0 -1
  372. package/dist/tests/featureFlags.test.js +0 -24
  373. package/dist/tests/featureFlags.test.js.map +0 -1
  374. package/dist/tests/integration/queue.test.d.ts +0 -2
  375. package/dist/tests/integration/queue.test.d.ts.map +0 -1
  376. package/dist/tests/integration/queue.test.js +0 -49
  377. package/dist/tests/integration/queue.test.js.map +0 -1
  378. package/dist/tests/plugins.test.d.ts +0 -2
  379. package/dist/tests/plugins.test.d.ts.map +0 -1
  380. package/dist/tests/plugins.test.js +0 -56
  381. package/dist/tests/plugins.test.js.map +0 -1
  382. package/dist/tests/result.test.d.ts +0 -2
  383. package/dist/tests/result.test.d.ts.map +0 -1
  384. package/dist/tests/result.test.js +0 -46
  385. package/dist/tests/result.test.js.map +0 -1
  386. package/dist/tests/setup/configWriter.test.d.ts +0 -2
  387. package/dist/tests/setup/configWriter.test.d.ts.map +0 -1
  388. package/dist/tests/setup/configWriter.test.js +0 -55
  389. package/dist/tests/setup/configWriter.test.js.map +0 -1
  390. package/dist/tests/setup/validation.test.d.ts +0 -2
  391. package/dist/tests/setup/validation.test.d.ts.map +0 -1
  392. package/dist/tests/setup/validation.test.js +0 -26
  393. package/dist/tests/setup/validation.test.js.map +0 -1
  394. package/dist/tests/smoke.test.d.ts +0 -2
  395. package/dist/tests/smoke.test.d.ts.map +0 -1
  396. package/dist/tests/smoke.test.js +0 -124
  397. package/dist/tests/smoke.test.js.map +0 -1
  398. package/src/cli.ts +0 -172
  399. package/src/config.ts +0 -143
  400. package/src/container.ts +0 -48
  401. package/src/db/index.ts +0 -53
  402. package/src/db/migrations/0000_skinny_ben_parker.sql +0 -553
  403. package/src/db/migrations/0001_brief_joseph.sql +0 -10
  404. package/src/db/migrations/0002_add_account_lockout.sql +0 -3
  405. package/src/db/migrations/0003_steep_rachel_grey.sql +0 -1
  406. package/src/db/migrations/0004_clever_bill_hollister.sql +0 -20
  407. package/src/db/migrations/0005_steep_the_call.sql +0 -2
  408. package/src/db/migrations/0006_ambitious_boomer.sql +0 -17
  409. package/src/db/migrations/0007_greedy_vindicator.sql +0 -40
  410. package/src/db/migrations/meta/0000_snapshot.json +0 -2964
  411. package/src/db/migrations/meta/0001_snapshot.json +0 -3031
  412. package/src/db/migrations/meta/0003_snapshot.json +0 -3051
  413. package/src/db/migrations/meta/_journal.json +0 -62
  414. package/src/db/schema.ts +0 -676
  415. package/src/db/seed.ts +0 -146
  416. package/src/di.ts +0 -81
  417. package/src/index.ts +0 -326
  418. package/src/lib/errors.ts +0 -139
  419. package/src/lib/result.ts +0 -44
  420. package/src/lib/webhookSignature.ts +0 -41
  421. package/src/plugins/appContext.ts +0 -76
  422. package/src/plugins/audit.ts +0 -42
  423. package/src/plugins/auth.ts +0 -230
  424. package/src/plugins/metrics.ts +0 -41
  425. package/src/plugins/mtls.ts +0 -94
  426. package/src/plugins/permissions.ts +0 -29
  427. package/src/plugins/rateLimit.ts +0 -133
  428. package/src/plugins/requestLogger.ts +0 -25
  429. package/src/plugins/tracing.ts +0 -22
  430. package/src/repositories/apiKey.ts +0 -158
  431. package/src/repositories/application.ts +0 -70
  432. package/src/repositories/audit.ts +0 -32
  433. package/src/repositories/index.ts +0 -9
  434. package/src/repositories/oidcConnection.ts +0 -111
  435. package/src/repositories/organization.ts +0 -167
  436. package/src/repositories/permission.ts +0 -153
  437. package/src/repositories/samlConnection.ts +0 -96
  438. package/src/repositories/session.ts +0 -86
  439. package/src/repositories/types.ts +0 -134
  440. package/src/repositories/user.ts +0 -161
  441. package/src/routes/admin/billing.ts +0 -48
  442. package/src/routes/admin/helpers.ts +0 -50
  443. package/src/routes/admin/index.ts +0 -16
  444. package/src/routes/admin/organizations.ts +0 -299
  445. package/src/routes/admin/permissions.ts +0 -80
  446. package/src/routes/admin/platform.ts +0 -335
  447. package/src/routes/admin/sso.ts +0 -138
  448. package/src/routes/admin/webhooks.ts +0 -73
  449. package/src/routes/admin.ts +0 -1
  450. package/src/routes/apiKeys.ts +0 -60
  451. package/src/routes/auth.ts +0 -214
  452. package/src/routes/authz.ts +0 -38
  453. package/src/routes/config.ts +0 -67
  454. package/src/routes/emailVerification.ts +0 -73
  455. package/src/routes/federation.ts +0 -156
  456. package/src/routes/helpers.ts +0 -17
  457. package/src/routes/magicLinks.ts +0 -107
  458. package/src/routes/oauth.ts +0 -167
  459. package/src/routes/oauth2.ts +0 -284
  460. package/src/routes/oidcEnterprise.ts +0 -166
  461. package/src/routes/password.ts +0 -90
  462. package/src/routes/profile.ts +0 -44
  463. package/src/routes/saml.ts +0 -209
  464. package/src/routes/scim.ts +0 -199
  465. package/src/routes/sdk.ts +0 -141
  466. package/src/routes/serviceAccounts.ts +0 -124
  467. package/src/routes/sessions.ts +0 -62
  468. package/src/routes/setup.ts +0 -315
  469. package/src/routes/smsOtp.ts +0 -67
  470. package/src/routes/totp.ts +0 -122
  471. package/src/routes/webauthn.ts +0 -147
  472. package/src/routes/workflows.ts +0 -157
  473. package/src/sdk/index.ts +0 -152
  474. package/src/sdk/types.ts +0 -54
  475. package/src/services/anomalyDetection.ts +0 -73
  476. package/src/services/application/authentication.ts +0 -75
  477. package/src/services/application/identity.ts +0 -56
  478. package/src/services/application/index.ts +0 -3
  479. package/src/services/application/organization.ts +0 -77
  480. package/src/services/applications.ts +0 -89
  481. package/src/services/audit.ts +0 -41
  482. package/src/services/auditExport.ts +0 -59
  483. package/src/services/billing.ts +0 -87
  484. package/src/services/cache.ts +0 -131
  485. package/src/services/configuration/profiles.ts +0 -115
  486. package/src/services/configuration.ts +0 -120
  487. package/src/services/connectors/google.ts +0 -92
  488. package/src/services/connectors/oidc.ts +0 -111
  489. package/src/services/connectors/registry.ts +0 -124
  490. package/src/services/connectors/types.ts +0 -38
  491. package/src/services/connectors/zitadel.ts +0 -77
  492. package/src/services/devices.ts +0 -76
  493. package/src/services/domain/authentication.ts +0 -279
  494. package/src/services/domain/authorization.ts +0 -49
  495. package/src/services/domain/identity.ts +0 -108
  496. package/src/services/domain/index.ts +0 -4
  497. package/src/services/domain/organization.ts +0 -114
  498. package/src/services/email.ts +0 -167
  499. package/src/services/emailVerification.ts +0 -75
  500. package/src/services/enterpriseSso.ts +0 -58
  501. package/src/services/events/bus.ts +0 -43
  502. package/src/services/events/subscribers/anomaly.ts +0 -13
  503. package/src/services/events/subscribers/auditLog.ts +0 -21
  504. package/src/services/events/subscribers/webhook.ts +0 -39
  505. package/src/services/events/subscribers/webhookDispatch.ts +0 -14
  506. package/src/services/events/types.ts +0 -106
  507. package/src/services/events/validate.ts +0 -118
  508. package/src/services/featureFlags.ts +0 -90
  509. package/src/services/features.ts +0 -22
  510. package/src/services/federation.ts +0 -30
  511. package/src/services/hibp.ts +0 -28
  512. package/src/services/ipControls.ts +0 -99
  513. package/src/services/magicLinks.ts +0 -51
  514. package/src/services/oauth2.ts +0 -216
  515. package/src/services/organizations.ts +0 -171
  516. package/src/services/permissions.ts +0 -146
  517. package/src/services/plugins/registry.ts +0 -242
  518. package/src/services/plugins/types.ts +0 -98
  519. package/src/services/queue/bullmq.ts +0 -104
  520. package/src/services/queue/inProcess.ts +0 -75
  521. package/src/services/queue/index.ts +0 -19
  522. package/src/services/queue/types.ts +0 -26
  523. package/src/services/redis.ts +0 -16
  524. package/src/services/secrets/awsKms.ts +0 -97
  525. package/src/services/secrets/azureKeyVault.ts +0 -171
  526. package/src/services/secrets/database.ts +0 -166
  527. package/src/services/secrets/environment.ts +0 -117
  528. package/src/services/secrets/index.ts +0 -50
  529. package/src/services/secrets/password.ts +0 -73
  530. package/src/services/secrets/provider.ts +0 -36
  531. package/src/services/secrets/vault.ts +0 -149
  532. package/src/services/secrets.ts +0 -2
  533. package/src/services/serviceAccounts.ts +0 -74
  534. package/src/services/setup/configWriter.ts +0 -200
  535. package/src/services/setup/diagnostics.ts +0 -76
  536. package/src/services/setup/token.ts +0 -42
  537. package/src/services/setup/types.ts +0 -40
  538. package/src/services/setup/validation.ts +0 -205
  539. package/src/services/sms.ts +0 -81
  540. package/src/services/smsOtp.ts +0 -74
  541. package/src/services/tokens.ts +0 -287
  542. package/src/services/totp.ts +0 -113
  543. package/src/services/users.ts +0 -239
  544. package/src/services/webauthn.ts +0 -193
  545. package/src/services/webhooks.ts +0 -190
  546. package/src/services/workflows/engine.ts +0 -125
  547. package/src/services/workflows/steps.ts +0 -129
  548. package/src/services/zitadel.ts +0 -277
  549. package/src/setup-server.ts +0 -71
  550. package/src/tests/errors.test.ts +0 -74
  551. package/src/tests/events.test.ts +0 -52
  552. package/src/tests/featureFlags.test.ts +0 -26
  553. package/src/tests/integration/queue.test.ts +0 -54
  554. package/src/tests/plugins.test.ts +0 -73
  555. package/src/tests/result.test.ts +0 -52
  556. package/src/tests/setup/configWriter.test.ts +0 -69
  557. package/src/tests/setup/validation.test.ts +0 -29
  558. package/src/tests/smoke.test.ts +0 -136
  559. package/src/types.ts +0 -70
@@ -1,200 +0,0 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import { ok, err, type Result } from "../../lib/result.js";
5
- import type { ConfigWriter } from "./types.js";
6
-
7
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
-
9
- function formatEnvValue(value: string): string {
10
- // Quote values that contain whitespace or special characters.
11
- if (/[\s#'"]/.test(value)) {
12
- const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
13
- return `"${escaped}"`;
14
- }
15
- return value;
16
- }
17
-
18
- function parseEnvLine(line: string): { key?: string; value?: string; comment?: boolean } {
19
- const trimmed = line.trim();
20
- if (!trimmed || trimmed.startsWith("#")) {
21
- return { comment: true };
22
- }
23
- const match = trimmed.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);
24
- if (!match) return { comment: true };
25
- let value = match[2];
26
- if (value.startsWith('"') && value.endsWith('"')) {
27
- value = value
28
- .slice(1, -1)
29
- .replace(/\\"/g, '"')
30
- .replace(/\\\\/g, "\\");
31
- }
32
- return { key: match[1], value };
33
- }
34
-
35
- export class EnvFileConfigWriter implements ConfigWriter {
36
- private readonly filePath: string;
37
-
38
- constructor(filePath?: string) {
39
- this.filePath = filePath || path.resolve(__dirname, "../../../.env");
40
- }
41
-
42
- async read(): Promise<Record<string, string | undefined>> {
43
- try {
44
- const content = await fs.readFile(this.filePath, "utf-8");
45
- const values: Record<string, string | undefined> = {};
46
- for (const line of content.split(/\r?\n/)) {
47
- const { key, value } = parseEnvLine(line);
48
- if (key) values[key] = value;
49
- }
50
- return values;
51
- } catch (error) {
52
- if ((error as NodeJS.ErrnoException).code === "ENOENT") {
53
- return {};
54
- }
55
- throw error;
56
- }
57
- }
58
-
59
- async write(values: Record<string, string>): Promise<Result<void>> {
60
- try {
61
- const stats = await fs.stat(this.filePath).catch(() => null);
62
- if (stats && !stats.isFile()) {
63
- return err({ code: "NOT_A_FILE", message: `${this.filePath} is not a regular file`, statusCode: 400 });
64
- }
65
-
66
- const existing = await this.read();
67
- const merged = { ...existing, ...values };
68
-
69
- // Preserve comments and ordering from existing file when possible.
70
- let lines: string[] = [];
71
- try {
72
- const content = await fs.readFile(this.filePath, "utf-8");
73
- lines = content.split(/\r?\n/);
74
- } catch {
75
- // File does not exist yet; start fresh.
76
- }
77
-
78
- const seen = new Set<string>();
79
- const updatedLines: string[] = [];
80
-
81
- for (const line of lines) {
82
- const { key } = parseEnvLine(line);
83
- if (key && key in merged) {
84
- updatedLines.push(`${key}=${formatEnvValue(merged[key]!)}`);
85
- seen.add(key);
86
- } else {
87
- updatedLines.push(line);
88
- }
89
- }
90
-
91
- // Append any new keys at the end.
92
- const newKeys = Object.keys(merged).filter((k) => !seen.has(k));
93
- if (newKeys.length > 0) {
94
- if (updatedLines.length > 0 && updatedLines[updatedLines.length - 1] !== "") {
95
- updatedLines.push("");
96
- }
97
- for (const key of newKeys) {
98
- updatedLines.push(`${key}=${formatEnvValue(merged[key]!)}`);
99
- }
100
- }
101
-
102
- await fs.writeFile(this.filePath, updatedLines.join("\n") + "\n", { mode: 0o600 });
103
- return ok(undefined);
104
- } catch (error) {
105
- const message = error instanceof Error ? error.message : String(error);
106
- return err({ code: "WRITE_FAILED", message, statusCode: 500 });
107
- }
108
- }
109
-
110
- async backup(): Promise<Result<string>> {
111
- try {
112
- const stats = await fs.stat(this.filePath).catch(() => null);
113
- if (!stats || !stats.isFile()) {
114
- return ok("");
115
- }
116
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
117
- const backupPath = `${this.filePath}.backup-${timestamp}`;
118
- await fs.copyFile(this.filePath, backupPath);
119
- return ok(backupPath);
120
- } catch (error) {
121
- const message = error instanceof Error ? error.message : String(error);
122
- return err({ code: "BACKUP_FAILED", message, statusCode: 500 });
123
- }
124
- }
125
- }
126
-
127
- export class JsonConfigWriter implements ConfigWriter {
128
- private readonly filePath: string;
129
-
130
- constructor(filePath?: string) {
131
- this.filePath = filePath || path.resolve(__dirname, "../../../config/keystone.json");
132
- }
133
-
134
- async read(): Promise<Record<string, string | undefined>> {
135
- try {
136
- const content = await fs.readFile(this.filePath, "utf-8");
137
- const parsed = JSON.parse(content);
138
- if (typeof parsed !== "object" || parsed === null) return {};
139
- const result: Record<string, string | undefined> = {};
140
- for (const [key, value] of Object.entries(parsed)) {
141
- result[key] = typeof value === "string" ? value : String(value);
142
- }
143
- return result;
144
- } catch (error) {
145
- if ((error as NodeJS.ErrnoException).code === "ENOENT") {
146
- return {};
147
- }
148
- throw error;
149
- }
150
- }
151
-
152
- async write(values: Record<string, string>): Promise<Result<void>> {
153
- try {
154
- const existing = await this.read();
155
- const merged = { ...existing, ...values };
156
- await fs.mkdir(path.dirname(this.filePath), { recursive: true });
157
- await fs.writeFile(this.filePath, JSON.stringify(merged, null, 2) + "\n", { mode: 0o600 });
158
- return ok(undefined);
159
- } catch (error) {
160
- const message = error instanceof Error ? error.message : String(error);
161
- return err({ code: "WRITE_FAILED", message, statusCode: 500 });
162
- }
163
- }
164
-
165
- async backup(): Promise<Result<string>> {
166
- try {
167
- const stats = await fs.stat(this.filePath).catch(() => null);
168
- if (!stats || !stats.isFile()) {
169
- return ok("");
170
- }
171
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
172
- const backupPath = `${this.filePath}.backup-${timestamp}`;
173
- await fs.copyFile(this.filePath, backupPath);
174
- return ok(backupPath);
175
- } catch (error) {
176
- const message = error instanceof Error ? error.message : String(error);
177
- return err({ code: "BACKUP_FAILED", message, statusCode: 500 });
178
- }
179
- }
180
- }
181
-
182
- export function createConfigWriter(): ConfigWriter {
183
- const mode = process.env.KEYSTONE_CONFIG_MODE?.toLowerCase();
184
- if (mode === "json" || isRunningInDocker()) {
185
- return new JsonConfigWriter();
186
- }
187
- return new EnvFileConfigWriter();
188
- }
189
-
190
- function isRunningInDocker(): boolean {
191
- // Best-effort detection: presence of /.dockerenv or docker in cgroup.
192
- try {
193
- const fs = require("node:fs");
194
- if (fs.existsSync("/.dockerenv")) return true;
195
- const cgroup = fs.readFileSync("/proc/self/cgroup", "utf-8");
196
- return cgroup.includes("docker") || cgroup.includes("containerd");
197
- } catch {
198
- return false;
199
- }
200
- }
@@ -1,76 +0,0 @@
1
- import { sql } from "drizzle-orm";
2
- import { config } from "../../config.js";
3
- import { db } from "../../db/index.js";
4
- import { redis } from "../redis.js";
5
- import { getPublicJwks } from "../tokens.js";
6
-
7
- export interface DiagnosticCheck {
8
- name: string;
9
- status: "ok" | "error" | "warning" | "skipped";
10
- message?: string;
11
- }
12
-
13
- export async function runSetupDiagnostics(): Promise<DiagnosticCheck[]> {
14
- const checks: DiagnosticCheck[] = [];
15
-
16
- // Database
17
- try {
18
- if (db) {
19
- await db.execute(sql`SELECT 1`);
20
- checks.push({ name: "Database connectivity", status: "ok" });
21
- } else {
22
- checks.push({ name: "Database connectivity", status: "error", message: "Database not initialized" });
23
- }
24
- } catch (err) {
25
- checks.push({ name: "Database connectivity", status: "error", message: err instanceof Error ? err.message : String(err) });
26
- }
27
-
28
- // Redis
29
- try {
30
- if (redis.status === "ready" || redis.status === "connect") {
31
- await redis.ping();
32
- checks.push({ name: "Redis connectivity", status: "ok" });
33
- } else {
34
- checks.push({ name: "Redis connectivity", status: "warning", message: "Redis not connected" });
35
- }
36
- } catch (err) {
37
- checks.push({ name: "Redis connectivity", status: "error", message: err instanceof Error ? err.message : String(err) });
38
- }
39
-
40
- // JWT keys
41
- try {
42
- const jwks = await getPublicJwks();
43
- if (jwks.keys.length > 0) {
44
- checks.push({ name: "JWT signing keys", status: "ok", message: `${jwks.keys.length} key(s) available` });
45
- } else {
46
- checks.push({ name: "JWT signing keys", status: "error", message: "No signing keys available" });
47
- }
48
- } catch (err) {
49
- checks.push({ name: "JWT signing keys", status: "error", message: err instanceof Error ? err.message : String(err) });
50
- }
51
-
52
- // Internal API key
53
- if (config.INTERNAL_API_KEY) {
54
- checks.push({ name: "Internal API key", status: "ok" });
55
- } else {
56
- checks.push({ name: "Internal API key", status: "warning", message: "Internal API key is not set" });
57
- }
58
-
59
- // Email provider
60
- if (config.EMAIL_PROVIDER === "none") {
61
- checks.push({ name: "Email provider", status: "skipped", message: "No email provider configured" });
62
- } else if (config.EMAIL_PROVIDER === "console") {
63
- checks.push({ name: "Email provider", status: "ok", message: "Console email provider" });
64
- } else {
65
- checks.push({ name: "Email provider", status: "ok", message: `${config.EMAIL_PROVIDER} configured` });
66
- }
67
-
68
- // Allowed origins
69
- if (config.ALLOWED_ORIGINS.length > 0) {
70
- checks.push({ name: "CORS origins", status: "ok", message: `${config.ALLOWED_ORIGINS.length} origin(s) configured` });
71
- } else {
72
- checks.push({ name: "CORS origins", status: "warning", message: "No allowed origins configured" });
73
- }
74
-
75
- return checks;
76
- }
@@ -1,42 +0,0 @@
1
- import crypto from "node:crypto";
2
-
3
- const SETUP_TOKEN_ENV = "KEYSTONE_SETUP_TOKEN";
4
-
5
- let generatedToken: string | null = null;
6
-
7
- export function getSetupToken(): string | undefined {
8
- return process.env[SETUP_TOKEN_ENV] || generatedToken || undefined;
9
- }
10
-
11
- export function generateSetupToken(): string {
12
- if (!generatedToken) {
13
- generatedToken = crypto.randomBytes(32).toString("hex");
14
- }
15
- return generatedToken;
16
- }
17
-
18
- export function validateSetupToken(token: string | undefined): boolean {
19
- if (!token) return false;
20
- const expected = getSetupToken();
21
- if (!expected) return false;
22
-
23
- // Ignore accidental whitespace / newlines when pasting from the terminal.
24
- const cleanToken = token.trim().toLowerCase();
25
- const cleanExpected = expected.trim().toLowerCase();
26
-
27
- if (cleanToken.length !== cleanExpected.length) {
28
- console.log(`[debug] token length mismatch: sent=${cleanToken.length} expected=${cleanExpected.length}`);
29
- return false;
30
- }
31
- return crypto.timingSafeEqual(Buffer.from(cleanToken), Buffer.from(cleanExpected));
32
- }
33
-
34
- export function printSetupToken(): void {
35
- const token = getSetupToken();
36
- if (token) {
37
- // eslint-disable-next-line no-console
38
- console.log(`\n🔐 Keystone setup token: ${token}\n`);
39
- // eslint-disable-next-line no-console
40
- console.log(` Use this token to complete setup at http://localhost:${process.env.PORT || 4001}/setup\n`);
41
- }
42
- }
@@ -1,40 +0,0 @@
1
- import type { Result } from "../../lib/result.js";
2
-
3
- export interface ConfigWriter {
4
- read(): Promise<Record<string, string | undefined>>;
5
- write(values: Record<string, string>): Promise<Result<void>>;
6
- backup(): Promise<Result<string>>;
7
- }
8
-
9
- export interface DatabaseValidationInput {
10
- databaseUrl: string;
11
- }
12
-
13
- export interface RedisValidationInput {
14
- redisUrl: string;
15
- }
16
-
17
- export interface EmailValidationInput {
18
- provider: "none" | "console" | "smtp" | "sendgrid" | "mailgun";
19
- from: string;
20
- smtpHost?: string;
21
- smtpPort?: number;
22
- smtpUser?: string;
23
- smtpPass?: string;
24
- smtpSecure?: boolean;
25
- sendgridApiKey?: string;
26
- mailgunApiKey?: string;
27
- mailgunDomain?: string;
28
- }
29
-
30
- export interface SmsValidationInput {
31
- provider: "none" | "console" | "twilio";
32
- twilioAccountSid?: string;
33
- twilioAuthToken?: string;
34
- twilioFromNumber?: string;
35
- twilioMessagingServiceSid?: string;
36
- }
37
-
38
- export interface SetupConfigInput {
39
- env: Record<string, string>;
40
- }
@@ -1,205 +0,0 @@
1
- import postgres from "postgres";
2
- import { Redis } from "ioredis";
3
- import { ok, err, type Result } from "../../lib/result.js";
4
- import type { DatabaseValidationInput, RedisValidationInput, EmailValidationInput, SmsValidationInput } from "./types.js";
5
-
6
- export async function validateDatabase(input: DatabaseValidationInput): Promise<Result<void>> {
7
- const { databaseUrl } = input;
8
- if (!databaseUrl) {
9
- return err({ code: "MISSING_DATABASE_URL", message: "Database URL is required", statusCode: 400 });
10
- }
11
-
12
- let client: postgres.Sql | undefined;
13
- try {
14
- client = postgres(databaseUrl, { max: 1, connect_timeout: 5 });
15
-
16
- // Test basic connectivity.
17
- await client`SELECT 1`;
18
-
19
- // Test DDL privileges by creating and dropping a temporary table.
20
- await client`CREATE TABLE IF NOT EXISTS __keystone_setup_probe (id serial PRIMARY KEY)`;
21
- await client`ALTER TABLE __keystone_setup_probe ADD COLUMN IF NOT EXISTS probe_text text`;
22
- await client`DROP TABLE __keystone_setup_probe`;
23
-
24
- await client.end();
25
- return ok(undefined);
26
- } catch (error) {
27
- await client?.end().catch(() => {});
28
- const message = error instanceof Error ? error.message : "Database validation failed";
29
- return err({ code: "DATABASE_VALIDATION_FAILED", message, statusCode: 400 });
30
- }
31
- }
32
-
33
- export async function validateRedis(input: RedisValidationInput): Promise<Result<void>> {
34
- const { redisUrl } = input;
35
- if (!redisUrl) {
36
- return err({ code: "MISSING_REDIS_URL", message: "Redis URL is required", statusCode: 400 });
37
- }
38
-
39
- const redis = new Redis(redisUrl, {
40
- maxRetriesPerRequest: 1,
41
- lazyConnect: true,
42
- connectTimeout: 5000,
43
- });
44
-
45
- try {
46
- await redis.connect();
47
- await redis.ping();
48
- redis.disconnect();
49
- return ok(undefined);
50
- } catch (error) {
51
- try { redis.disconnect(); } catch { /* ignore */ }
52
- const message = error instanceof Error ? error.message : "Redis validation failed";
53
- return err({ code: "REDIS_VALIDATION_FAILED", message, statusCode: 400 });
54
- }
55
- }
56
-
57
- export async function validateEmail(input: EmailValidationInput, to: string): Promise<Result<void>> {
58
- if (input.provider === "none" || input.provider === "console") {
59
- return ok(undefined);
60
- }
61
-
62
- try {
63
- const provider = createTransientEmailProvider(input);
64
- await provider.send({
65
- to,
66
- subject: "Hilbras Keystone setup test",
67
- text: "This is a test message from the Hilbras Keystone setup wizard.",
68
- });
69
- return ok(undefined);
70
- } catch (error) {
71
- const message = error instanceof Error ? error.message : "Email validation failed";
72
- return err({ code: "EMAIL_VALIDATION_FAILED", message, statusCode: 400 });
73
- }
74
- }
75
-
76
- export async function validateSms(input: SmsValidationInput, to: string): Promise<Result<void>> {
77
- if (input.provider === "none" || input.provider === "console") {
78
- return ok(undefined);
79
- }
80
-
81
- try {
82
- const provider = createTransientSmsProvider(input);
83
- await provider.send({
84
- to,
85
- body: "Hilbras Keystone setup test message.",
86
- });
87
- return ok(undefined);
88
- } catch (error) {
89
- const message = error instanceof Error ? error.message : "SMS validation failed";
90
- return err({ code: "SMS_VALIDATION_FAILED", message, statusCode: 400 });
91
- }
92
- }
93
-
94
- function createTransientEmailProvider(input: EmailValidationInput) {
95
- return {
96
- send: async (message: { to: string; subject: string; text: string }) => {
97
- switch (input.provider) {
98
- case "smtp":
99
- return sendSmtp(input, message);
100
- case "sendgrid":
101
- return sendSendGrid(input, message);
102
- case "mailgun":
103
- return sendMailgun(input, message);
104
- default:
105
- throw new Error("Unsupported email provider");
106
- }
107
- },
108
- };
109
- }
110
-
111
- async function sendSmtp(input: EmailValidationInput, message: { to: string; subject: string; text: string }) {
112
- if (!input.smtpHost) throw new Error("SMTP host is required");
113
- const { createTransport } = await import("nodemailer");
114
- const transporter = createTransport({
115
- host: input.smtpHost,
116
- port: input.smtpPort || 587,
117
- secure: input.smtpSecure || false,
118
- auth: input.smtpUser && input.smtpPass ? { user: input.smtpUser, pass: input.smtpPass } : undefined,
119
- });
120
- await transporter.verify();
121
- await transporter.sendMail({
122
- from: input.from,
123
- to: message.to,
124
- subject: message.subject,
125
- text: message.text,
126
- });
127
- }
128
-
129
- async function sendSendGrid(input: EmailValidationInput, message: { to: string; subject: string; text: string }) {
130
- if (!input.sendgridApiKey) throw new Error("SendGrid API key is required");
131
- const response = await fetch("https://api.sendgrid.com/v3/mail/send", {
132
- method: "POST",
133
- headers: {
134
- Authorization: `Bearer ${input.sendgridApiKey}`,
135
- "Content-Type": "application/json",
136
- },
137
- body: JSON.stringify({
138
- personalizations: [{ to: [{ email: message.to }] }],
139
- from: { email: input.from },
140
- subject: message.subject,
141
- content: [{ type: "text/plain", value: message.text }],
142
- }),
143
- });
144
- if (!response.ok) {
145
- const body = await response.text();
146
- throw new Error(`SendGrid request failed: ${response.status} ${body}`);
147
- }
148
- }
149
-
150
- async function sendMailgun(input: EmailValidationInput, message: { to: string; subject: string; text: string }) {
151
- if (!input.mailgunApiKey || !input.mailgunDomain) throw new Error("Mailgun API key and domain are required");
152
- const params = new URLSearchParams();
153
- params.set("from", input.from);
154
- params.set("to", message.to);
155
- params.set("subject", message.subject);
156
- params.set("text", message.text);
157
- const response = await fetch(`https://api.mailgun.net/v3/${input.mailgunDomain}/messages`, {
158
- method: "POST",
159
- headers: {
160
- Authorization: `Basic ${Buffer.from(`api:${input.mailgunApiKey}`).toString("base64")}`,
161
- "Content-Type": "application/x-www-form-urlencoded",
162
- },
163
- body: params.toString(),
164
- });
165
- if (!response.ok) {
166
- const body = await response.text();
167
- throw new Error(`Mailgun request failed: ${response.status} ${body}`);
168
- }
169
- }
170
-
171
- function createTransientSmsProvider(input: SmsValidationInput) {
172
- return {
173
- send: async (message: { to: string; body: string }) => {
174
- if (input.provider !== "twilio") throw new Error("Unsupported SMS provider");
175
- if (!input.twilioAccountSid || !input.twilioAuthToken) {
176
- throw new Error("Twilio account SID and auth token are required");
177
- }
178
- const params = new URLSearchParams();
179
- params.set("To", message.to);
180
- params.set("Body", message.body);
181
- if (input.twilioMessagingServiceSid) {
182
- params.set("MessagingServiceSid", input.twilioMessagingServiceSid);
183
- } else if (input.twilioFromNumber) {
184
- params.set("From", input.twilioFromNumber);
185
- } else {
186
- throw new Error("Twilio messaging service SID or from number is required");
187
- }
188
- const response = await fetch(
189
- `https://api.twilio.com/2010-04-01/Accounts/${input.twilioAccountSid}/Messages.json`,
190
- {
191
- method: "POST",
192
- headers: {
193
- Authorization: `Basic ${Buffer.from(`${input.twilioAccountSid}:${input.twilioAuthToken}`).toString("base64")}`,
194
- "Content-Type": "application/x-www-form-urlencoded",
195
- },
196
- body: params.toString(),
197
- }
198
- );
199
- if (!response.ok) {
200
- const body = await response.text();
201
- throw new Error(`Twilio request failed: ${response.status} ${body}`);
202
- }
203
- },
204
- };
205
- }
@@ -1,81 +0,0 @@
1
- import { config } from "../config.js";
2
- import { getPluginSmsProvider } from "./plugins/registry.js";
3
-
4
- export interface SmsMessage {
5
- to: string;
6
- body: string;
7
- }
8
-
9
- export interface SmsProvider {
10
- name?: string;
11
- send(message: SmsMessage): Promise<void>;
12
- }
13
-
14
- class NoOpSmsProvider implements SmsProvider {
15
- async send(message: SmsMessage): Promise<void> {
16
- console.log("[sms] no-op provider would send:", JSON.stringify(message));
17
- }
18
- }
19
-
20
- class ConsoleSmsProvider implements SmsProvider {
21
- async send(message: SmsMessage): Promise<void> {
22
- console.log("[sms] console provider:");
23
- console.log(`To: ${message.to}`);
24
- console.log(message.body);
25
- }
26
- }
27
-
28
- class TwilioSmsProvider implements SmsProvider {
29
- async send(message: SmsMessage): Promise<void> {
30
- if (!config.TWILIO_ACCOUNT_SID || !config.TWILIO_AUTH_TOKEN) {
31
- throw new Error("Twilio provider requires TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN");
32
- }
33
-
34
- const params = new URLSearchParams();
35
- params.set("To", message.to);
36
- params.set("Body", message.body);
37
-
38
- if (config.TWILIO_MESSAGING_SERVICE_SID) {
39
- params.set("MessagingServiceSid", config.TWILIO_MESSAGING_SERVICE_SID);
40
- } else if (config.TWILIO_FROM_NUMBER) {
41
- params.set("From", config.TWILIO_FROM_NUMBER);
42
- } else {
43
- throw new Error("Twilio provider requires TWILIO_MESSAGING_SERVICE_SID or TWILIO_FROM_NUMBER");
44
- }
45
-
46
- const response = await fetch(
47
- `https://api.twilio.com/2010-04-01/Accounts/${config.TWILIO_ACCOUNT_SID}/Messages.json`,
48
- {
49
- method: "POST",
50
- headers: {
51
- Authorization: `Basic ${Buffer.from(`${config.TWILIO_ACCOUNT_SID}:${config.TWILIO_AUTH_TOKEN}`).toString("base64")}`,
52
- "Content-Type": "application/x-www-form-urlencoded",
53
- },
54
- body: params.toString(),
55
- }
56
- );
57
-
58
- if (!response.ok) {
59
- const body = await response.text();
60
- throw new Error(`Twilio request failed: ${response.status} ${body}`);
61
- }
62
- }
63
- }
64
-
65
- function createSmsProvider(): SmsProvider {
66
- const plugin = getPluginSmsProvider();
67
- if (plugin) return plugin;
68
-
69
- const provider = config.SMS_PROVIDER || "none";
70
- switch (provider) {
71
- case "twilio":
72
- return new TwilioSmsProvider();
73
- case "console":
74
- return new ConsoleSmsProvider();
75
- case "none":
76
- default:
77
- return new NoOpSmsProvider();
78
- }
79
- }
80
-
81
- export const smsProvider = createSmsProvider();