@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.
- package/CHANGELOG.md +272 -0
- package/README.md +59 -25
- package/dist/cli.js +25 -27
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +15 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +45 -8
- package/dist/config.js.map +1 -1
- package/dist/container.d.ts +4 -1
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js.map +1 -1
- package/dist/db/migrations/0008_flashy_firestar.sql +5 -0
- package/dist/db/migrations/0009_daffy_changeling.sql +1 -0
- package/dist/db/migrations/0010_wealthy_shadow_king.sql +37 -0
- package/dist/db/migrations/0011_overrated_vector.sql +18 -0
- package/dist/db/migrations/0012_brave_darkhawk.sql +28 -0
- package/dist/db/migrations/0013_wonderful_chimera.sql +5 -0
- package/dist/db/migrations/0014_magical_morph.sql +48 -0
- package/{src/db/migrations/meta/0007_snapshot.json → dist/db/migrations/meta/0008_snapshot.json} +136 -32
- package/{src/db/migrations/meta/0006_snapshot.json → dist/db/migrations/meta/0009_snapshot.json} +359 -30
- package/{src/db/migrations/meta/0005_snapshot.json → dist/db/migrations/meta/0010_snapshot.json} +459 -29
- package/{src/db/migrations/meta/0004_snapshot.json → dist/db/migrations/meta/0011_snapshot.json} +594 -30
- package/dist/db/migrations/meta/0012_snapshot.json +3891 -0
- package/dist/db/migrations/meta/0013_snapshot.json +3919 -0
- package/dist/db/migrations/meta/0014_snapshot.json +4311 -0
- package/dist/db/migrations/meta/_journal.json +49 -0
- package/dist/db/reencryptOidcSecrets.d.ts +2 -0
- package/dist/db/reencryptOidcSecrets.d.ts.map +1 -0
- package/dist/db/reencryptOidcSecrets.js +41 -0
- package/dist/db/reencryptOidcSecrets.js.map +1 -0
- package/dist/db/schema.d.ts +2521 -53
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +118 -3
- package/dist/db/schema.js.map +1 -1
- package/dist/db/seed.js +67 -40
- package/dist/db/seed.js.map +1 -1
- package/dist/di.d.ts.map +1 -1
- package/dist/di.js +11 -3
- package/dist/di.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/errors.d.ts +2 -1
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +10 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/plugins/appContext.d.ts.map +1 -1
- package/dist/plugins/appContext.js +3 -12
- package/dist/plugins/appContext.js.map +1 -1
- package/dist/plugins/audit.d.ts.map +1 -1
- package/dist/plugins/audit.js +26 -6
- package/dist/plugins/audit.js.map +1 -1
- package/dist/plugins/auth.d.ts.map +1 -1
- package/dist/plugins/auth.js +32 -7
- package/dist/plugins/auth.js.map +1 -1
- package/dist/plugins/metrics.d.ts.map +1 -1
- package/dist/plugins/mtls.d.ts.map +1 -1
- package/dist/plugins/permissions.d.ts.map +1 -1
- package/dist/plugins/permissions.js +29 -9
- package/dist/plugins/permissions.js.map +1 -1
- package/dist/plugins/rateLimit.d.ts +15 -0
- package/dist/plugins/rateLimit.d.ts.map +1 -1
- package/dist/plugins/rateLimit.js +11 -1
- package/dist/plugins/rateLimit.js.map +1 -1
- package/dist/plugins/requestLogger.d.ts.map +1 -1
- package/dist/repositories/apiKey.d.ts.map +1 -1
- package/dist/repositories/application.d.ts.map +1 -1
- package/dist/repositories/application.js +1 -1
- package/dist/repositories/application.js.map +1 -1
- package/dist/repositories/audit.d.ts.map +1 -1
- package/dist/repositories/index.d.ts +3 -0
- package/dist/repositories/index.d.ts.map +1 -1
- package/dist/repositories/index.js +3 -0
- package/dist/repositories/index.js.map +1 -1
- package/dist/repositories/mfaChallenge.d.ts +23 -0
- package/dist/repositories/mfaChallenge.d.ts.map +1 -0
- package/dist/repositories/mfaChallenge.js +71 -0
- package/dist/repositories/mfaChallenge.js.map +1 -0
- package/dist/repositories/oidcConnection.d.ts +27 -43
- package/dist/repositories/oidcConnection.d.ts.map +1 -1
- package/dist/repositories/oidcConnection.js +15 -6
- package/dist/repositories/oidcConnection.js.map +1 -1
- package/dist/repositories/organization.d.ts +9 -9
- package/dist/repositories/organization.d.ts.map +1 -1
- package/dist/repositories/organization.js +91 -37
- package/dist/repositories/organization.js.map +1 -1
- package/dist/repositories/permission.d.ts.map +1 -1
- package/dist/repositories/permission.js +27 -5
- package/dist/repositories/permission.js.map +1 -1
- package/dist/repositories/samlConnection.d.ts +28 -28
- package/dist/repositories/samlConnection.d.ts.map +1 -1
- package/dist/repositories/samlConnection.js +12 -4
- package/dist/repositories/samlConnection.js.map +1 -1
- package/dist/repositories/scimConnection.d.ts +38 -0
- package/dist/repositories/scimConnection.d.ts.map +1 -0
- package/dist/repositories/scimConnection.js +123 -0
- package/dist/repositories/scimConnection.js.map +1 -0
- package/dist/repositories/scimGroup.d.ts +36 -0
- package/dist/repositories/scimGroup.d.ts.map +1 -0
- package/dist/repositories/scimGroup.js +113 -0
- package/dist/repositories/scimGroup.js.map +1 -0
- package/dist/repositories/session.d.ts +23 -13
- package/dist/repositories/session.d.ts.map +1 -1
- package/dist/repositories/session.js +13 -1
- package/dist/repositories/session.js.map +1 -1
- package/dist/repositories/types.d.ts +112 -5
- package/dist/repositories/types.d.ts.map +1 -1
- package/dist/repositories/types.js +7 -1
- package/dist/repositories/types.js.map +1 -1
- package/dist/repositories/user.d.ts +23 -1
- package/dist/repositories/user.d.ts.map +1 -1
- package/dist/repositories/user.js +180 -4
- package/dist/repositories/user.js.map +1 -1
- package/dist/routes/admin/billing.js +4 -4
- package/dist/routes/admin/billing.js.map +1 -1
- package/dist/routes/admin/helpers.d.ts +16 -20
- package/dist/routes/admin/helpers.d.ts.map +1 -1
- package/dist/routes/admin/helpers.js +53 -10
- package/dist/routes/admin/helpers.js.map +1 -1
- package/dist/routes/admin/organizations.d.ts.map +1 -1
- package/dist/routes/admin/organizations.js +76 -69
- package/dist/routes/admin/organizations.js.map +1 -1
- package/dist/routes/admin/permissions.d.ts.map +1 -1
- package/dist/routes/admin/permissions.js +48 -14
- package/dist/routes/admin/permissions.js.map +1 -1
- package/dist/routes/admin/platform.d.ts.map +1 -1
- package/dist/routes/admin/platform.js +86 -35
- package/dist/routes/admin/platform.js.map +1 -1
- package/dist/routes/admin/sso.d.ts.map +1 -1
- package/dist/routes/admin/sso.js +143 -12
- package/dist/routes/admin/sso.js.map +1 -1
- package/dist/routes/admin/webhooks.js +8 -8
- package/dist/routes/admin/webhooks.js.map +1 -1
- package/dist/routes/apiKeys.d.ts.map +1 -1
- package/dist/routes/apiKeys.js +23 -5
- package/dist/routes/apiKeys.js.map +1 -1
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +112 -22
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/authz.d.ts.map +1 -1
- package/dist/routes/authz.js +16 -4
- package/dist/routes/authz.js.map +1 -1
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +16 -14
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/federation.d.ts.map +1 -1
- package/dist/routes/federation.js +17 -3
- package/dist/routes/federation.js.map +1 -1
- package/dist/routes/magicLinks.d.ts.map +1 -1
- package/dist/routes/magicLinks.js +15 -3
- package/dist/routes/magicLinks.js.map +1 -1
- package/dist/routes/oauth.d.ts.map +1 -1
- package/dist/routes/oauth.js +22 -3
- package/dist/routes/oauth.js.map +1 -1
- package/dist/routes/oauth2.d.ts.map +1 -1
- package/dist/routes/oauth2.js +104 -11
- package/dist/routes/oauth2.js.map +1 -1
- package/dist/routes/oidcEnterprise.d.ts.map +1 -1
- package/dist/routes/oidcEnterprise.js +67 -21
- package/dist/routes/oidcEnterprise.js.map +1 -1
- package/dist/routes/password.d.ts.map +1 -1
- package/dist/routes/password.js.map +1 -1
- package/dist/routes/profile.js +4 -4
- package/dist/routes/profile.js.map +1 -1
- package/dist/routes/saml.d.ts +9 -0
- package/dist/routes/saml.d.ts.map +1 -1
- package/dist/routes/saml.js +187 -11
- package/dist/routes/saml.js.map +1 -1
- package/dist/routes/scim.d.ts +13 -0
- package/dist/routes/scim.d.ts.map +1 -1
- package/dist/routes/scim.js +885 -110
- package/dist/routes/scim.js.map +1 -1
- package/dist/routes/sdk.d.ts.map +1 -1
- package/dist/routes/sdk.js +24 -8
- package/dist/routes/sdk.js.map +1 -1
- package/dist/routes/serviceAccounts.d.ts.map +1 -1
- package/dist/routes/serviceAccounts.js +2 -1
- package/dist/routes/serviceAccounts.js.map +1 -1
- package/dist/routes/setup.d.ts.map +1 -1
- package/dist/routes/setup.js +15 -16
- package/dist/routes/setup.js.map +1 -1
- package/dist/routes/smsOtp.js +1 -1
- package/dist/routes/smsOtp.js.map +1 -1
- package/dist/routes/totp.d.ts.map +1 -1
- package/dist/routes/totp.js +113 -23
- package/dist/routes/totp.js.map +1 -1
- package/dist/routes/webauthn.d.ts.map +1 -1
- package/dist/routes/webauthn.js +44 -8
- package/dist/routes/webauthn.js.map +1 -1
- package/dist/routes/workflows.d.ts.map +1 -1
- package/dist/routes/workflows.js +58 -25
- package/dist/routes/workflows.js.map +1 -1
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +141 -40
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/types.d.ts +60 -29
- package/dist/sdk/types.d.ts.map +1 -1
- package/dist/services/application/authentication.d.ts +39 -1
- package/dist/services/application/authentication.d.ts.map +1 -1
- package/dist/services/application/authentication.js +43 -1
- package/dist/services/application/authentication.js.map +1 -1
- package/dist/services/application/identity.d.ts +10 -7
- package/dist/services/application/identity.d.ts.map +1 -1
- package/dist/services/application/identity.js +13 -10
- package/dist/services/application/identity.js.map +1 -1
- package/dist/services/application/organization.d.ts +11 -7
- package/dist/services/application/organization.d.ts.map +1 -1
- package/dist/services/application/organization.js +160 -12
- package/dist/services/application/organization.js.map +1 -1
- package/dist/services/applications.js +2 -2
- package/dist/services/applications.js.map +1 -1
- package/dist/services/audit.d.ts +1 -0
- package/dist/services/audit.d.ts.map +1 -1
- package/dist/services/audit.js +13 -0
- package/dist/services/audit.js.map +1 -1
- package/dist/services/cache.d.ts.map +1 -1
- package/dist/services/configuration/profiles.d.ts +4 -0
- package/dist/services/configuration/profiles.d.ts.map +1 -1
- package/dist/services/configuration/profiles.js +50 -0
- package/dist/services/configuration/profiles.js.map +1 -1
- package/dist/services/configuration.d.ts.map +1 -1
- package/dist/services/configuration.js.map +1 -1
- package/dist/services/connectors/google.d.ts.map +1 -1
- package/dist/services/connectors/google.js +3 -2
- package/dist/services/connectors/google.js.map +1 -1
- package/dist/services/connectors/oidc.d.ts.map +1 -1
- package/dist/services/connectors/oidc.js +6 -3
- package/dist/services/connectors/oidc.js.map +1 -1
- package/dist/services/connectors/zitadel.d.ts.map +1 -1
- package/dist/services/connectors/zitadel.js +4 -3
- package/dist/services/connectors/zitadel.js.map +1 -1
- package/dist/services/domain/authentication.d.ts +43 -4
- package/dist/services/domain/authentication.d.ts.map +1 -1
- package/dist/services/domain/authentication.js +82 -20
- package/dist/services/domain/authentication.js.map +1 -1
- package/dist/services/domain/authorization.d.ts +11 -0
- package/dist/services/domain/authorization.d.ts.map +1 -1
- package/dist/services/domain/authorization.js +36 -1
- package/dist/services/domain/authorization.js.map +1 -1
- package/dist/services/domain/identity.d.ts +21 -9
- package/dist/services/domain/identity.d.ts.map +1 -1
- package/dist/services/domain/identity.js +187 -10
- package/dist/services/domain/identity.js.map +1 -1
- package/dist/services/domain/organization.d.ts +6 -9
- package/dist/services/domain/organization.d.ts.map +1 -1
- package/dist/services/domain/organization.js +48 -30
- package/dist/services/domain/organization.js.map +1 -1
- package/dist/services/emailVerification.d.ts +2 -2
- package/dist/services/enterpriseSso.d.ts +13 -6
- package/dist/services/enterpriseSso.d.ts.map +1 -1
- package/dist/services/enterpriseSso.js +75 -6
- package/dist/services/enterpriseSso.js.map +1 -1
- package/dist/services/events/subscribers/auditLog.js +1 -1
- package/dist/services/events/subscribers/auditLog.js.map +1 -1
- package/dist/services/events/types.d.ts +7 -1
- package/dist/services/events/types.d.ts.map +1 -1
- package/dist/services/events/types.js.map +1 -1
- package/dist/services/events/validate.d.ts.map +1 -1
- package/dist/services/events/validate.js +27 -0
- package/dist/services/events/validate.js.map +1 -1
- package/dist/services/features.d.ts.map +1 -1
- package/dist/services/features.js.map +1 -1
- package/dist/services/federation.d.ts +6 -1
- package/dist/services/federation.d.ts.map +1 -1
- package/dist/services/federation.js +31 -4
- package/dist/services/federation.js.map +1 -1
- package/dist/services/ipControls.js +2 -2
- package/dist/services/ipControls.js.map +1 -1
- package/dist/services/magicLinks.d.ts +2 -2
- package/dist/services/mfa.d.ts +53 -0
- package/dist/services/mfa.d.ts.map +1 -0
- package/dist/services/mfa.js +157 -0
- package/dist/services/mfa.js.map +1 -0
- package/dist/services/oauth2.d.ts +16 -12
- package/dist/services/oauth2.d.ts.map +1 -1
- package/dist/services/oauth2.js +22 -13
- package/dist/services/oauth2.js.map +1 -1
- package/dist/services/oidcSecretFormat.d.ts +3 -0
- package/dist/services/oidcSecretFormat.d.ts.map +1 -0
- package/dist/services/oidcSecretFormat.js +5 -0
- package/dist/services/oidcSecretFormat.js.map +1 -0
- package/dist/services/organizations.d.ts +4 -16
- package/dist/services/organizations.d.ts.map +1 -1
- package/dist/services/organizations.js +0 -62
- package/dist/services/organizations.js.map +1 -1
- package/dist/services/permissions.d.ts.map +1 -1
- package/dist/services/permissions.js +9 -1
- package/dist/services/permissions.js.map +1 -1
- package/dist/services/plugins/registry.d.ts.map +1 -1
- package/dist/services/plugins/registry.js.map +1 -1
- package/dist/services/plugins/types.d.ts.map +1 -1
- package/dist/services/queue/bullmq.d.ts.map +1 -1
- package/dist/services/queue/inProcess.d.ts.map +1 -1
- package/dist/services/redis.d.ts +1 -1
- package/dist/services/redis.d.ts.map +1 -1
- package/dist/services/scimCredentials.d.ts +46 -0
- package/dist/services/scimCredentials.d.ts.map +1 -0
- package/dist/services/scimCredentials.js +123 -0
- package/dist/services/scimCredentials.js.map +1 -0
- package/dist/services/scimLegacyMigration.d.ts +12 -0
- package/dist/services/scimLegacyMigration.d.ts.map +1 -0
- package/dist/services/scimLegacyMigration.js +44 -0
- package/dist/services/scimLegacyMigration.js.map +1 -0
- package/dist/services/secrets/awsKms.d.ts +2 -2
- package/dist/services/secrets/awsKms.d.ts.map +1 -1
- package/dist/services/secrets/awsKms.js +3 -5
- package/dist/services/secrets/awsKms.js.map +1 -1
- package/dist/services/secrets/azureKeyVault.d.ts.map +1 -1
- package/dist/services/secrets/database.d.ts.map +1 -1
- package/dist/services/secrets/database.js.map +1 -1
- package/dist/services/secrets/environment.d.ts.map +1 -1
- package/dist/services/secrets/environment.js.map +1 -1
- package/dist/services/secrets/index.d.ts.map +1 -1
- package/dist/services/secrets/password.d.ts.map +1 -1
- package/dist/services/secrets/password.js +0 -4
- package/dist/services/secrets/password.js.map +1 -1
- package/dist/services/secrets/provider.d.ts +2 -3
- package/dist/services/secrets/provider.d.ts.map +1 -1
- package/dist/services/secrets/vault.d.ts.map +1 -1
- package/dist/services/setup/configWriter.d.ts.map +1 -1
- package/dist/services/setup/configWriter.js.map +1 -1
- package/dist/services/ssoEndpointPolicy.d.ts +8 -0
- package/dist/services/ssoEndpointPolicy.d.ts.map +1 -0
- package/dist/services/ssoEndpointPolicy.js +136 -0
- package/dist/services/ssoEndpointPolicy.js.map +1 -0
- package/dist/services/stepUp.d.ts +35 -0
- package/dist/services/stepUp.d.ts.map +1 -0
- package/dist/services/stepUp.js +65 -0
- package/dist/services/stepUp.js.map +1 -0
- package/dist/services/tokens.d.ts +37 -11
- package/dist/services/tokens.d.ts.map +1 -1
- package/dist/services/tokens.js +75 -14
- package/dist/services/tokens.js.map +1 -1
- package/dist/services/totp.d.ts +46 -0
- package/dist/services/totp.d.ts.map +1 -1
- package/dist/services/totp.js +178 -41
- package/dist/services/totp.js.map +1 -1
- package/dist/services/users.d.ts +20 -12
- package/dist/services/users.d.ts.map +1 -1
- package/dist/services/users.js +24 -51
- package/dist/services/users.js.map +1 -1
- package/dist/services/webauthn.d.ts +8 -4
- package/dist/services/webauthn.d.ts.map +1 -1
- package/dist/services/webauthn.js +4 -4
- package/dist/services/webauthn.js.map +1 -1
- package/dist/services/webhooks.d.ts +20 -20
- package/dist/services/workflows/engine.d.ts +4 -2
- package/dist/services/workflows/engine.d.ts.map +1 -1
- package/dist/services/workflows/engine.js +181 -12
- package/dist/services/workflows/engine.js.map +1 -1
- package/dist/services/workflows/steps.d.ts +2 -0
- package/dist/services/workflows/steps.d.ts.map +1 -1
- package/dist/services/workflows/steps.js +8 -75
- package/dist/services/workflows/steps.js.map +1 -1
- package/dist/setup-server.js.map +1 -1
- package/dist/types.d.ts +33 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +26 -2
- package/dist/types.js.map +1 -1
- package/package.json +26 -3
- package/dist/tests/errors.test.d.ts +0 -2
- package/dist/tests/errors.test.d.ts.map +0 -1
- package/dist/tests/errors.test.js +0 -64
- package/dist/tests/errors.test.js.map +0 -1
- package/dist/tests/events.test.d.ts +0 -2
- package/dist/tests/events.test.d.ts.map +0 -1
- package/dist/tests/events.test.js +0 -45
- package/dist/tests/events.test.js.map +0 -1
- package/dist/tests/featureFlags.test.d.ts +0 -2
- package/dist/tests/featureFlags.test.d.ts.map +0 -1
- package/dist/tests/featureFlags.test.js +0 -24
- package/dist/tests/featureFlags.test.js.map +0 -1
- package/dist/tests/integration/queue.test.d.ts +0 -2
- package/dist/tests/integration/queue.test.d.ts.map +0 -1
- package/dist/tests/integration/queue.test.js +0 -49
- package/dist/tests/integration/queue.test.js.map +0 -1
- package/dist/tests/plugins.test.d.ts +0 -2
- package/dist/tests/plugins.test.d.ts.map +0 -1
- package/dist/tests/plugins.test.js +0 -56
- package/dist/tests/plugins.test.js.map +0 -1
- package/dist/tests/result.test.d.ts +0 -2
- package/dist/tests/result.test.d.ts.map +0 -1
- package/dist/tests/result.test.js +0 -46
- package/dist/tests/result.test.js.map +0 -1
- package/dist/tests/setup/configWriter.test.d.ts +0 -2
- package/dist/tests/setup/configWriter.test.d.ts.map +0 -1
- package/dist/tests/setup/configWriter.test.js +0 -55
- package/dist/tests/setup/configWriter.test.js.map +0 -1
- package/dist/tests/setup/validation.test.d.ts +0 -2
- package/dist/tests/setup/validation.test.d.ts.map +0 -1
- package/dist/tests/setup/validation.test.js +0 -26
- package/dist/tests/setup/validation.test.js.map +0 -1
- package/dist/tests/smoke.test.d.ts +0 -2
- package/dist/tests/smoke.test.d.ts.map +0 -1
- package/dist/tests/smoke.test.js +0 -124
- package/dist/tests/smoke.test.js.map +0 -1
- package/src/cli.ts +0 -172
- package/src/config.ts +0 -143
- package/src/container.ts +0 -48
- package/src/db/index.ts +0 -53
- package/src/db/migrations/0000_skinny_ben_parker.sql +0 -553
- package/src/db/migrations/0001_brief_joseph.sql +0 -10
- package/src/db/migrations/0002_add_account_lockout.sql +0 -3
- package/src/db/migrations/0003_steep_rachel_grey.sql +0 -1
- package/src/db/migrations/0004_clever_bill_hollister.sql +0 -20
- package/src/db/migrations/0005_steep_the_call.sql +0 -2
- package/src/db/migrations/0006_ambitious_boomer.sql +0 -17
- package/src/db/migrations/0007_greedy_vindicator.sql +0 -40
- package/src/db/migrations/meta/0000_snapshot.json +0 -2964
- package/src/db/migrations/meta/0001_snapshot.json +0 -3031
- package/src/db/migrations/meta/0003_snapshot.json +0 -3051
- package/src/db/migrations/meta/_journal.json +0 -62
- package/src/db/schema.ts +0 -676
- package/src/db/seed.ts +0 -146
- package/src/di.ts +0 -81
- package/src/index.ts +0 -326
- package/src/lib/errors.ts +0 -139
- package/src/lib/result.ts +0 -44
- package/src/lib/webhookSignature.ts +0 -41
- package/src/plugins/appContext.ts +0 -76
- package/src/plugins/audit.ts +0 -42
- package/src/plugins/auth.ts +0 -230
- package/src/plugins/metrics.ts +0 -41
- package/src/plugins/mtls.ts +0 -94
- package/src/plugins/permissions.ts +0 -29
- package/src/plugins/rateLimit.ts +0 -133
- package/src/plugins/requestLogger.ts +0 -25
- package/src/plugins/tracing.ts +0 -22
- package/src/repositories/apiKey.ts +0 -158
- package/src/repositories/application.ts +0 -70
- package/src/repositories/audit.ts +0 -32
- package/src/repositories/index.ts +0 -9
- package/src/repositories/oidcConnection.ts +0 -111
- package/src/repositories/organization.ts +0 -167
- package/src/repositories/permission.ts +0 -153
- package/src/repositories/samlConnection.ts +0 -96
- package/src/repositories/session.ts +0 -86
- package/src/repositories/types.ts +0 -134
- package/src/repositories/user.ts +0 -161
- package/src/routes/admin/billing.ts +0 -48
- package/src/routes/admin/helpers.ts +0 -50
- package/src/routes/admin/index.ts +0 -16
- package/src/routes/admin/organizations.ts +0 -299
- package/src/routes/admin/permissions.ts +0 -80
- package/src/routes/admin/platform.ts +0 -335
- package/src/routes/admin/sso.ts +0 -138
- package/src/routes/admin/webhooks.ts +0 -73
- package/src/routes/admin.ts +0 -1
- package/src/routes/apiKeys.ts +0 -60
- package/src/routes/auth.ts +0 -214
- package/src/routes/authz.ts +0 -38
- package/src/routes/config.ts +0 -67
- package/src/routes/emailVerification.ts +0 -73
- package/src/routes/federation.ts +0 -156
- package/src/routes/helpers.ts +0 -17
- package/src/routes/magicLinks.ts +0 -107
- package/src/routes/oauth.ts +0 -167
- package/src/routes/oauth2.ts +0 -284
- package/src/routes/oidcEnterprise.ts +0 -166
- package/src/routes/password.ts +0 -90
- package/src/routes/profile.ts +0 -44
- package/src/routes/saml.ts +0 -209
- package/src/routes/scim.ts +0 -199
- package/src/routes/sdk.ts +0 -141
- package/src/routes/serviceAccounts.ts +0 -124
- package/src/routes/sessions.ts +0 -62
- package/src/routes/setup.ts +0 -315
- package/src/routes/smsOtp.ts +0 -67
- package/src/routes/totp.ts +0 -122
- package/src/routes/webauthn.ts +0 -147
- package/src/routes/workflows.ts +0 -157
- package/src/sdk/index.ts +0 -152
- package/src/sdk/types.ts +0 -54
- package/src/services/anomalyDetection.ts +0 -73
- package/src/services/application/authentication.ts +0 -75
- package/src/services/application/identity.ts +0 -56
- package/src/services/application/index.ts +0 -3
- package/src/services/application/organization.ts +0 -77
- package/src/services/applications.ts +0 -89
- package/src/services/audit.ts +0 -41
- package/src/services/auditExport.ts +0 -59
- package/src/services/billing.ts +0 -87
- package/src/services/cache.ts +0 -131
- package/src/services/configuration/profiles.ts +0 -115
- package/src/services/configuration.ts +0 -120
- package/src/services/connectors/google.ts +0 -92
- package/src/services/connectors/oidc.ts +0 -111
- package/src/services/connectors/registry.ts +0 -124
- package/src/services/connectors/types.ts +0 -38
- package/src/services/connectors/zitadel.ts +0 -77
- package/src/services/devices.ts +0 -76
- package/src/services/domain/authentication.ts +0 -279
- package/src/services/domain/authorization.ts +0 -49
- package/src/services/domain/identity.ts +0 -108
- package/src/services/domain/index.ts +0 -4
- package/src/services/domain/organization.ts +0 -114
- package/src/services/email.ts +0 -167
- package/src/services/emailVerification.ts +0 -75
- package/src/services/enterpriseSso.ts +0 -58
- package/src/services/events/bus.ts +0 -43
- package/src/services/events/subscribers/anomaly.ts +0 -13
- package/src/services/events/subscribers/auditLog.ts +0 -21
- package/src/services/events/subscribers/webhook.ts +0 -39
- package/src/services/events/subscribers/webhookDispatch.ts +0 -14
- package/src/services/events/types.ts +0 -106
- package/src/services/events/validate.ts +0 -118
- package/src/services/featureFlags.ts +0 -90
- package/src/services/features.ts +0 -22
- package/src/services/federation.ts +0 -30
- package/src/services/hibp.ts +0 -28
- package/src/services/ipControls.ts +0 -99
- package/src/services/magicLinks.ts +0 -51
- package/src/services/oauth2.ts +0 -216
- package/src/services/organizations.ts +0 -171
- package/src/services/permissions.ts +0 -146
- package/src/services/plugins/registry.ts +0 -242
- package/src/services/plugins/types.ts +0 -98
- package/src/services/queue/bullmq.ts +0 -104
- package/src/services/queue/inProcess.ts +0 -75
- package/src/services/queue/index.ts +0 -19
- package/src/services/queue/types.ts +0 -26
- package/src/services/redis.ts +0 -16
- package/src/services/secrets/awsKms.ts +0 -97
- package/src/services/secrets/azureKeyVault.ts +0 -171
- package/src/services/secrets/database.ts +0 -166
- package/src/services/secrets/environment.ts +0 -117
- package/src/services/secrets/index.ts +0 -50
- package/src/services/secrets/password.ts +0 -73
- package/src/services/secrets/provider.ts +0 -36
- package/src/services/secrets/vault.ts +0 -149
- package/src/services/secrets.ts +0 -2
- package/src/services/serviceAccounts.ts +0 -74
- package/src/services/setup/configWriter.ts +0 -200
- package/src/services/setup/diagnostics.ts +0 -76
- package/src/services/setup/token.ts +0 -42
- package/src/services/setup/types.ts +0 -40
- package/src/services/setup/validation.ts +0 -205
- package/src/services/sms.ts +0 -81
- package/src/services/smsOtp.ts +0 -74
- package/src/services/tokens.ts +0 -287
- package/src/services/totp.ts +0 -113
- package/src/services/users.ts +0 -239
- package/src/services/webauthn.ts +0 -193
- package/src/services/webhooks.ts +0 -190
- package/src/services/workflows/engine.ts +0 -125
- package/src/services/workflows/steps.ts +0 -129
- package/src/services/zitadel.ts +0 -277
- package/src/setup-server.ts +0 -71
- package/src/tests/errors.test.ts +0 -74
- package/src/tests/events.test.ts +0 -52
- package/src/tests/featureFlags.test.ts +0 -26
- package/src/tests/integration/queue.test.ts +0 -54
- package/src/tests/plugins.test.ts +0 -73
- package/src/tests/result.test.ts +0 -52
- package/src/tests/setup/configWriter.test.ts +0 -69
- package/src/tests/setup/validation.test.ts +0 -29
- package/src/tests/smoke.test.ts +0 -136
- package/src/types.ts +0 -70
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
import { importPKCS8, importSPKI, exportPKCS8, exportSPKI, generateKeyPair } from "jose";
|
|
3
|
-
import { config } from "../../config.js";
|
|
4
|
-
import type { SecretsProvider, SigningKeyPair } from "./provider.js";
|
|
5
|
-
import { hashPassword, verifyPassword } from "./password.js";
|
|
6
|
-
|
|
7
|
-
let envKeyPair: SigningKeyPair | null = null;
|
|
8
|
-
let envEncryptionKey: Buffer | null = null;
|
|
9
|
-
|
|
10
|
-
export class EnvironmentSecretsProvider implements SecretsProvider {
|
|
11
|
-
readonly name = "environment";
|
|
12
|
-
|
|
13
|
-
hashPassword = hashPassword;
|
|
14
|
-
verifyPassword = verifyPassword;
|
|
15
|
-
|
|
16
|
-
hashApiKey(key: string): string {
|
|
17
|
-
return crypto.createHash("sha256").update(key).digest("hex");
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
hashClientSecret(secret: string): string {
|
|
21
|
-
return crypto.createHash("sha256").update(secret).digest("hex");
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
generateClientSecret(): string {
|
|
25
|
-
return `cs_${crypto.randomBytes(32).toString("base64url")}`;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
generateApiKey(): { key: string; prefix: string } {
|
|
29
|
-
const key = `ks_${crypto.randomBytes(32).toString("base64url")}`;
|
|
30
|
-
const prefix = key.slice(0, 7);
|
|
31
|
-
return { key, prefix };
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async getActiveSigningKey(): Promise<SigningKeyPair> {
|
|
35
|
-
if (envKeyPair) return envKeyPair;
|
|
36
|
-
|
|
37
|
-
if (config.JWT_PRIVATE_KEY && config.JWT_PUBLIC_KEY) {
|
|
38
|
-
const privateKey = await importPKCS8(config.JWT_PRIVATE_KEY, "RS256");
|
|
39
|
-
const publicKey = await importSPKI(config.JWT_PUBLIC_KEY, "RS256");
|
|
40
|
-
envKeyPair = { keyId: "env", privateKey, publicKey };
|
|
41
|
-
return envKeyPair;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (config.NODE_ENV === "production") {
|
|
45
|
-
throw new Error("EnvironmentSecretsProvider requires JWT_PRIVATE_KEY and JWT_PUBLIC_KEY in production");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const pair = await generateKeyPair("RS256", { extractable: true });
|
|
49
|
-
const privatePem = await exportPKCS8(pair.privateKey);
|
|
50
|
-
const publicPem = await exportSPKI(pair.publicKey);
|
|
51
|
-
// eslint-disable-next-line no-console
|
|
52
|
-
console.warn("[secrets] Generated ephemeral JWT keys. Set JWT_PRIVATE_KEY/JWT_PUBLIC_KEY in production.");
|
|
53
|
-
// eslint-disable-next-line no-console
|
|
54
|
-
console.warn("[secrets] JWT_PRIVATE_KEY\n", privatePem);
|
|
55
|
-
// eslint-disable-next-line no-console
|
|
56
|
-
console.warn("[secrets] JWT_PUBLIC_KEY\n", publicPem);
|
|
57
|
-
envKeyPair = { keyId: "env-generated", privateKey: pair.privateKey, publicKey: pair.publicKey };
|
|
58
|
-
return envKeyPair;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async getSigningKeyById(keyId: string): Promise<SigningKeyPair | undefined> {
|
|
62
|
-
const active = await this.getActiveSigningKey();
|
|
63
|
-
if (active.keyId === keyId) return active;
|
|
64
|
-
return undefined;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async rotateSigningKeys(): Promise<SigningKeyPair> {
|
|
68
|
-
envKeyPair = null;
|
|
69
|
-
return this.getActiveSigningKey();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async listActiveSigningKeys(): Promise<{ keyId: string; createdAt: Date; expiresAt?: Date | null }[]> {
|
|
73
|
-
const active = await this.getActiveSigningKey();
|
|
74
|
-
return [{ keyId: active.keyId, createdAt: new Date(), expiresAt: null }];
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
async listValidSigningKeys(): Promise<SigningKeyPair[]> {
|
|
78
|
-
const active = await this.getActiveSigningKey();
|
|
79
|
-
return [active];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async getEncryptionKey(): Promise<Buffer> {
|
|
83
|
-
if (envEncryptionKey) return envEncryptionKey;
|
|
84
|
-
if (config.KEYSTONE_ENCRYPTION_KEY) {
|
|
85
|
-
envEncryptionKey = crypto.createHash("sha256").update(config.KEYSTONE_ENCRYPTION_KEY).digest();
|
|
86
|
-
return envEncryptionKey;
|
|
87
|
-
}
|
|
88
|
-
envEncryptionKey = crypto.randomBytes(32);
|
|
89
|
-
// eslint-disable-next-line no-console
|
|
90
|
-
console.warn("[secrets] Generated ephemeral encryption key. Set KEYSTONE_ENCRYPTION_KEY in production.");
|
|
91
|
-
return envEncryptionKey;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async encryptSecret(plain: string): Promise<string> {
|
|
95
|
-
const key = await this.getEncryptionKey();
|
|
96
|
-
const iv = crypto.randomBytes(16);
|
|
97
|
-
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
|
|
98
|
-
const encrypted = Buffer.concat([cipher.update(plain, "utf8"), cipher.final()]);
|
|
99
|
-
const tag = cipher.getAuthTag();
|
|
100
|
-
const payload = Buffer.concat([iv, tag, encrypted]);
|
|
101
|
-
return `aes-256-gcm$${payload.toString("base64url")}`;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async decryptSecret(cipherText: string): Promise<string> {
|
|
105
|
-
if (!cipherText.startsWith("aes-256-gcm$")) {
|
|
106
|
-
throw new Error("Unsupported cipher format");
|
|
107
|
-
}
|
|
108
|
-
const key = await this.getEncryptionKey();
|
|
109
|
-
const payload = Buffer.from(cipherText.slice("aes-256-gcm$".length), "base64url");
|
|
110
|
-
const iv = payload.subarray(0, 16);
|
|
111
|
-
const tag = payload.subarray(16, 32);
|
|
112
|
-
const encrypted = payload.subarray(32);
|
|
113
|
-
const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
|
|
114
|
-
decipher.setAuthTag(tag);
|
|
115
|
-
return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString("utf8");
|
|
116
|
-
}
|
|
117
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { config } from "../../config.js";
|
|
2
|
-
import { DatabaseSecretsProvider } from "./database.js";
|
|
3
|
-
import { EnvironmentSecretsProvider } from "./environment.js";
|
|
4
|
-
import { VaultSecretsProvider } from "./vault.js";
|
|
5
|
-
import { AwsKmsSecretsProvider } from "./awsKms.js";
|
|
6
|
-
import { AzureKeyVaultSecretsProvider } from "./azureKeyVault.js";
|
|
7
|
-
import type { SecretsProvider } from "./provider.js";
|
|
8
|
-
|
|
9
|
-
function createProvider(): SecretsProvider {
|
|
10
|
-
const providerName = config.KEYSTONE_SECRETS_PROVIDER || "database";
|
|
11
|
-
switch (providerName) {
|
|
12
|
-
case "environment":
|
|
13
|
-
return new EnvironmentSecretsProvider();
|
|
14
|
-
case "vault":
|
|
15
|
-
return new VaultSecretsProvider();
|
|
16
|
-
case "aws-kms":
|
|
17
|
-
return new AwsKmsSecretsProvider();
|
|
18
|
-
case "azure-key-vault":
|
|
19
|
-
return new AzureKeyVaultSecretsProvider();
|
|
20
|
-
case "database":
|
|
21
|
-
default:
|
|
22
|
-
return new DatabaseSecretsProvider();
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const secretsProvider: SecretsProvider = createProvider();
|
|
27
|
-
|
|
28
|
-
// Re-export everything for backwards compatibility.
|
|
29
|
-
export * from "./provider.js";
|
|
30
|
-
export { DatabaseSecretsProvider } from "./database.js";
|
|
31
|
-
export { EnvironmentSecretsProvider } from "./environment.js";
|
|
32
|
-
export { VaultSecretsProvider } from "./vault.js";
|
|
33
|
-
export { AwsKmsSecretsProvider } from "./awsKms.js";
|
|
34
|
-
export { AzureKeyVaultSecretsProvider } from "./azureKeyVault.js";
|
|
35
|
-
|
|
36
|
-
// Convenience re-exports of the active provider's methods.
|
|
37
|
-
export const hashPassword = secretsProvider.hashPassword.bind(secretsProvider);
|
|
38
|
-
export const verifyPassword = secretsProvider.verifyPassword.bind(secretsProvider);
|
|
39
|
-
export const hashApiKey = secretsProvider.hashApiKey.bind(secretsProvider);
|
|
40
|
-
export const hashClientSecret = secretsProvider.hashClientSecret.bind(secretsProvider);
|
|
41
|
-
export const generateClientSecret = secretsProvider.generateClientSecret.bind(secretsProvider);
|
|
42
|
-
export const generateApiKey = secretsProvider.generateApiKey.bind(secretsProvider);
|
|
43
|
-
export const getActiveSigningKey = secretsProvider.getActiveSigningKey.bind(secretsProvider);
|
|
44
|
-
export const getSigningKeyById = secretsProvider.getSigningKeyById.bind(secretsProvider);
|
|
45
|
-
export const rotateSigningKeys = secretsProvider.rotateSigningKeys.bind(secretsProvider);
|
|
46
|
-
export const listActiveSigningKeys = secretsProvider.listActiveSigningKeys.bind(secretsProvider);
|
|
47
|
-
export const listValidSigningKeys = secretsProvider.listValidSigningKeys.bind(secretsProvider);
|
|
48
|
-
export const getEncryptionKey = secretsProvider.getEncryptionKey.bind(secretsProvider);
|
|
49
|
-
export const encryptSecret = secretsProvider.encryptSecret.bind(secretsProvider);
|
|
50
|
-
export const decryptSecret = secretsProvider.decryptSecret.bind(secretsProvider);
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
import * as argon2 from "argon2";
|
|
3
|
-
|
|
4
|
-
// OWASP-recommended minimum parameters for argon2id (as of 2023).
|
|
5
|
-
const ARGON2_MEMORY_COST = 65536;
|
|
6
|
-
const ARGON2_TIME_COST = 3;
|
|
7
|
-
const ARGON2_PARALLELISM = 4;
|
|
8
|
-
|
|
9
|
-
// Legacy scrypt parameters used by early Keystone deployments.
|
|
10
|
-
const SCRYPT_N = 16384;
|
|
11
|
-
const SCRYPT_R = 8;
|
|
12
|
-
const SCRYPT_P = 1;
|
|
13
|
-
|
|
14
|
-
function scryptPromise(
|
|
15
|
-
password: string,
|
|
16
|
-
salt: Buffer,
|
|
17
|
-
keylen: number,
|
|
18
|
-
options: crypto.ScryptOptions
|
|
19
|
-
): Promise<Buffer> {
|
|
20
|
-
return new Promise((resolve, reject) => {
|
|
21
|
-
crypto.scrypt(password, salt, keylen, options, (err, derived) => {
|
|
22
|
-
if (err) return reject(err);
|
|
23
|
-
resolve(derived);
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async function verifyScryptPassword(plain: string, hash: string): Promise<boolean> {
|
|
29
|
-
const parts = hash.split("$");
|
|
30
|
-
if (parts.length !== 6) return false;
|
|
31
|
-
const [, nStr, rStr, pStr, saltB64, derivedB64] = parts;
|
|
32
|
-
const salt = Buffer.from(saltB64, "base64url");
|
|
33
|
-
const expected = Buffer.from(derivedB64, "base64url");
|
|
34
|
-
const derived = await scryptPromise(plain, salt, expected.length, {
|
|
35
|
-
N: Number(nStr),
|
|
36
|
-
r: Number(rStr),
|
|
37
|
-
p: Number(pStr),
|
|
38
|
-
});
|
|
39
|
-
return crypto.timingSafeEqual(derived, expected);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Hash a password using argon2id. The encoded string contains the salt and
|
|
44
|
-
* parameters, so verification does not need external storage.
|
|
45
|
-
*/
|
|
46
|
-
export async function hashPassword(plain: string): Promise<string> {
|
|
47
|
-
return argon2.hash(plain, {
|
|
48
|
-
type: argon2.argon2id,
|
|
49
|
-
memoryCost: ARGON2_MEMORY_COST,
|
|
50
|
-
timeCost: ARGON2_TIME_COST,
|
|
51
|
-
parallelism: ARGON2_PARALLELISM,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Verify a password against an argon2id or legacy scrypt hash.
|
|
57
|
-
*/
|
|
58
|
-
export async function verifyPassword(
|
|
59
|
-
plain: string,
|
|
60
|
-
hash: string | null | undefined
|
|
61
|
-
): Promise<boolean> {
|
|
62
|
-
if (!hash) return false;
|
|
63
|
-
|
|
64
|
-
if (hash.startsWith("scrypt$")) {
|
|
65
|
-
return verifyScryptPassword(plain, hash);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
return await argon2.verify(hash, plain);
|
|
70
|
-
} catch {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export interface SigningKeyPair {
|
|
2
|
-
keyId: string;
|
|
3
|
-
privateKey: CryptoKey | Uint8Array;
|
|
4
|
-
publicKey: CryptoKey;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface SecretsProvider {
|
|
8
|
-
readonly name: string;
|
|
9
|
-
|
|
10
|
-
// Password hashing
|
|
11
|
-
hashPassword(plain: string): Promise<string>;
|
|
12
|
-
verifyPassword(plain: string, hash: string | null | undefined): Promise<boolean>;
|
|
13
|
-
|
|
14
|
-
// API key / client secret hashing
|
|
15
|
-
hashApiKey(key: string): string;
|
|
16
|
-
hashClientSecret(secret: string): string;
|
|
17
|
-
generateClientSecret(): string;
|
|
18
|
-
generateApiKey(): { key: string; prefix: string };
|
|
19
|
-
|
|
20
|
-
// JWT signing keys
|
|
21
|
-
getActiveSigningKey(): Promise<SigningKeyPair>;
|
|
22
|
-
getSigningKeyById(keyId: string): Promise<SigningKeyPair | undefined>;
|
|
23
|
-
rotateSigningKeys(): Promise<SigningKeyPair>;
|
|
24
|
-
listActiveSigningKeys(): Promise<{ keyId: string; createdAt: Date; expiresAt?: Date | null }[]>;
|
|
25
|
-
/**
|
|
26
|
-
* Return all signing keys that are currently valid: the active key plus any
|
|
27
|
-
* recently rotated keys still within the grace period. Used to verify tokens
|
|
28
|
-
* after a key rotation.
|
|
29
|
-
*/
|
|
30
|
-
listValidSigningKeys(): Promise<SigningKeyPair[]>;
|
|
31
|
-
|
|
32
|
-
// Symmetric encryption
|
|
33
|
-
getEncryptionKey(): Promise<Buffer>;
|
|
34
|
-
encryptSecret(plain: string): Promise<string>;
|
|
35
|
-
decryptSecret(cipherText: string): Promise<string>;
|
|
36
|
-
}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
import { importPKCS8, importSPKI, exportPKCS8, exportSPKI, generateKeyPair } from "jose";
|
|
3
|
-
import type { SecretsProvider, SigningKeyPair } from "./provider.js";
|
|
4
|
-
import { hashPassword, verifyPassword } from "./password.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* HashiCorp Vault secrets provider.
|
|
8
|
-
*
|
|
9
|
-
* This is a reference implementation. In production it should call the
|
|
10
|
-
* Vault HTTP API (or use a Vault client library) to retrieve signing keys,
|
|
11
|
-
* encryption keys, and credentials. The password hashing helpers are reused
|
|
12
|
-
* locally because they are compute-bound and do not need external storage.
|
|
13
|
-
*/
|
|
14
|
-
export class VaultSecretsProvider implements SecretsProvider {
|
|
15
|
-
readonly name = "vault";
|
|
16
|
-
|
|
17
|
-
hashPassword = hashPassword;
|
|
18
|
-
verifyPassword = verifyPassword;
|
|
19
|
-
|
|
20
|
-
private vaultAddr: string;
|
|
21
|
-
private vaultToken: string;
|
|
22
|
-
private mountPath: string;
|
|
23
|
-
|
|
24
|
-
constructor() {
|
|
25
|
-
this.vaultAddr = (process.env.VAULT_ADDR || "").replace(/\/$/, "");
|
|
26
|
-
this.vaultToken = process.env.VAULT_TOKEN || "";
|
|
27
|
-
this.mountPath = (process.env.VAULT_MOUNT_PATH || "secret").replace(/(^\/)|(\/$)/g, "");
|
|
28
|
-
|
|
29
|
-
if (!this.vaultAddr || !this.vaultToken) {
|
|
30
|
-
throw new Error("VaultSecretsProvider requires VAULT_ADDR and VAULT_TOKEN");
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
hashApiKey(key: string): string {
|
|
35
|
-
return crypto.createHash("sha256").update(key).digest("hex");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
hashClientSecret(secret: string): string {
|
|
39
|
-
return crypto.createHash("sha256").update(secret).digest("hex");
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
generateClientSecret(): string {
|
|
43
|
-
return `cs_${crypto.randomBytes(32).toString("base64url")}`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
generateApiKey(): { key: string; prefix: string } {
|
|
47
|
-
const key = `ks_${crypto.randomBytes(32).toString("base64url")}`;
|
|
48
|
-
return { key, prefix: key.slice(0, 7) };
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async getActiveSigningKey(): Promise<SigningKeyPair> {
|
|
52
|
-
const stored = await this.readPath("jwt/active");
|
|
53
|
-
if (stored?.private && stored?.public) {
|
|
54
|
-
const privateKey = await importPKCS8(String(stored.private), "RS256");
|
|
55
|
-
const publicKey = await importSPKI(String(stored.public), "RS256");
|
|
56
|
-
return { keyId: String(stored.keyId ?? "vault-active"), privateKey, publicKey };
|
|
57
|
-
}
|
|
58
|
-
return this.rotateSigningKeys();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async getSigningKeyById(keyId: string): Promise<SigningKeyPair | undefined> {
|
|
62
|
-
const active = await this.getActiveSigningKey();
|
|
63
|
-
if (active.keyId === keyId) return active;
|
|
64
|
-
const stored = await this.readPath(`jwt/${keyId}`);
|
|
65
|
-
if (!stored?.private) return undefined;
|
|
66
|
-
const privateKey = await importPKCS8(String(stored.private), "RS256");
|
|
67
|
-
const publicKey = await importSPKI(String(stored.public), "RS256");
|
|
68
|
-
return { keyId, privateKey, publicKey };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async rotateSigningKeys(): Promise<SigningKeyPair> {
|
|
72
|
-
const pair = await generateKeyPair("RS256", { extractable: true });
|
|
73
|
-
const privatePem = await exportPKCS8(pair.privateKey);
|
|
74
|
-
const publicPem = await exportSPKI(pair.publicKey);
|
|
75
|
-
const keyId = `vault-${crypto.randomBytes(8).toString("base64url")}`;
|
|
76
|
-
|
|
77
|
-
await this.writePath("jwt/active", { keyId, private: privatePem, public: publicPem, rotatedAt: new Date().toISOString() });
|
|
78
|
-
|
|
79
|
-
return { keyId, privateKey: pair.privateKey, publicKey: pair.publicKey };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async listActiveSigningKeys(): Promise<{ keyId: string; createdAt: Date; expiresAt?: Date | null }[]> {
|
|
83
|
-
const active = await this.getActiveSigningKey();
|
|
84
|
-
return [{ keyId: active.keyId, createdAt: new Date(), expiresAt: null }];
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
async listValidSigningKeys(): Promise<SigningKeyPair[]> {
|
|
88
|
-
const active = await this.getActiveSigningKey();
|
|
89
|
-
return [active];
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async getEncryptionKey(): Promise<Buffer> {
|
|
93
|
-
const stored = await this.readPath("encryption/active");
|
|
94
|
-
if (stored?.value) {
|
|
95
|
-
return Buffer.from(String(stored.value), "base64url");
|
|
96
|
-
}
|
|
97
|
-
const value = crypto.randomBytes(32);
|
|
98
|
-
await this.writePath("encryption/active", { value: value.toString("base64url") });
|
|
99
|
-
return value;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async encryptSecret(plain: string): Promise<string> {
|
|
103
|
-
const key = await this.getEncryptionKey();
|
|
104
|
-
const iv = crypto.randomBytes(16);
|
|
105
|
-
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
|
|
106
|
-
const encrypted = Buffer.concat([cipher.update(plain, "utf8"), cipher.final()]);
|
|
107
|
-
const tag = cipher.getAuthTag();
|
|
108
|
-
const payload = Buffer.concat([iv, tag, encrypted]);
|
|
109
|
-
return `aes-256-gcm$${payload.toString("base64url")}`;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async decryptSecret(cipherText: string): Promise<string> {
|
|
113
|
-
if (!cipherText.startsWith("aes-256-gcm$")) {
|
|
114
|
-
throw new Error("Unsupported cipher format");
|
|
115
|
-
}
|
|
116
|
-
const key = await this.getEncryptionKey();
|
|
117
|
-
const payload = Buffer.from(cipherText.slice("aes-256-gcm$".length), "base64url");
|
|
118
|
-
const iv = payload.subarray(0, 16);
|
|
119
|
-
const tag = payload.subarray(16, 32);
|
|
120
|
-
const encrypted = payload.subarray(32);
|
|
121
|
-
const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
|
|
122
|
-
decipher.setAuthTag(tag);
|
|
123
|
-
return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString("utf8");
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
private async readPath(path: string): Promise<Record<string, unknown> | undefined> {
|
|
127
|
-
const url = `${this.vaultAddr}/v1/${this.mountPath}/data/${path}`;
|
|
128
|
-
const res = await fetch(url, {
|
|
129
|
-
headers: { "X-Vault-Token": this.vaultToken },
|
|
130
|
-
});
|
|
131
|
-
if (res.status === 404) return undefined;
|
|
132
|
-
if (!res.ok) throw new Error(`Vault read failed: ${res.status}`);
|
|
133
|
-
const data = (await res.json()) as { data?: { data?: Record<string, unknown> } };
|
|
134
|
-
return data.data?.data;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
private async writePath(path: string, data: Record<string, unknown>): Promise<void> {
|
|
138
|
-
const url = `${this.vaultAddr}/v1/${this.mountPath}/data/${path}`;
|
|
139
|
-
const res = await fetch(url, {
|
|
140
|
-
method: "POST",
|
|
141
|
-
headers: {
|
|
142
|
-
"X-Vault-Token": this.vaultToken,
|
|
143
|
-
"Content-Type": "application/json",
|
|
144
|
-
},
|
|
145
|
-
body: JSON.stringify({ data }),
|
|
146
|
-
});
|
|
147
|
-
if (!res.ok) throw new Error(`Vault write failed: ${res.status}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
package/src/services/secrets.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { eq, and, sql } from "drizzle-orm";
|
|
2
|
-
import { db } from "../db/index.js";
|
|
3
|
-
import { serviceAccounts, apiKeys, type ServiceAccount } from "../db/schema.js";
|
|
4
|
-
|
|
5
|
-
export async function createServiceAccount(input: {
|
|
6
|
-
orgId: string;
|
|
7
|
-
name: string;
|
|
8
|
-
description?: string;
|
|
9
|
-
}): Promise<ServiceAccount> {
|
|
10
|
-
const [record] = await db
|
|
11
|
-
.insert(serviceAccounts)
|
|
12
|
-
.values({
|
|
13
|
-
orgId: input.orgId,
|
|
14
|
-
name: input.name,
|
|
15
|
-
description: input.description ?? null,
|
|
16
|
-
})
|
|
17
|
-
.returning();
|
|
18
|
-
return record;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function findServiceAccountsByOrgId(orgId: string): Promise<ServiceAccount[]> {
|
|
22
|
-
return db
|
|
23
|
-
.select()
|
|
24
|
-
.from(serviceAccounts)
|
|
25
|
-
.where(and(eq(serviceAccounts.orgId, orgId), eq(serviceAccounts.isActive, true)))
|
|
26
|
-
.orderBy(serviceAccounts.name);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export async function findServiceAccountById(
|
|
30
|
-
id: string,
|
|
31
|
-
orgId: string
|
|
32
|
-
): Promise<ServiceAccount | undefined> {
|
|
33
|
-
const [record] = await db
|
|
34
|
-
.select()
|
|
35
|
-
.from(serviceAccounts)
|
|
36
|
-
.where(
|
|
37
|
-
and(
|
|
38
|
-
eq(serviceAccounts.id, id),
|
|
39
|
-
eq(serviceAccounts.orgId, orgId),
|
|
40
|
-
eq(serviceAccounts.isActive, true)
|
|
41
|
-
)
|
|
42
|
-
)
|
|
43
|
-
.limit(1);
|
|
44
|
-
return record;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export async function updateServiceAccount(
|
|
48
|
-
id: string,
|
|
49
|
-
orgId: string,
|
|
50
|
-
updates: Partial<{ name: string; description: string; isActive: boolean }>
|
|
51
|
-
): Promise<ServiceAccount | undefined> {
|
|
52
|
-
const [updated] = await db
|
|
53
|
-
.update(serviceAccounts)
|
|
54
|
-
.set({ ...updates, updatedAt: sql`now()` })
|
|
55
|
-
.where(and(eq(serviceAccounts.id, id), eq(serviceAccounts.orgId, orgId)))
|
|
56
|
-
.returning();
|
|
57
|
-
return updated;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export async function listServiceAccountApiKeys(serviceAccountId: string) {
|
|
61
|
-
return db
|
|
62
|
-
.select({
|
|
63
|
-
id: apiKeys.id,
|
|
64
|
-
name: apiKeys.name,
|
|
65
|
-
prefix: apiKeys.prefix,
|
|
66
|
-
scopes: apiKeys.scopes,
|
|
67
|
-
lastUsedAt: apiKeys.lastUsedAt,
|
|
68
|
-
expiresAt: apiKeys.expiresAt,
|
|
69
|
-
revokedAt: apiKeys.revokedAt,
|
|
70
|
-
createdAt: apiKeys.createdAt,
|
|
71
|
-
})
|
|
72
|
-
.from(apiKeys)
|
|
73
|
-
.where(eq(apiKeys.serviceAccountId, serviceAccountId));
|
|
74
|
-
}
|