@hilbras/keystone 1.6.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 +239 -0
- package/README.md +55 -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
package/src/services/zitadel.ts
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import { config, zitadelBaseUrl } from "../config.js";
|
|
2
|
-
|
|
3
|
-
interface ServiceToken {
|
|
4
|
-
token: string;
|
|
5
|
-
expiresAt: number;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
let cachedServiceToken: ServiceToken | null = null;
|
|
9
|
-
let cachedJwksUrl: string | null = null;
|
|
10
|
-
let cachedDiscovery: Record<string, unknown> | null = null;
|
|
11
|
-
|
|
12
|
-
export async function getServiceToken(): Promise<string | undefined> {
|
|
13
|
-
if (config.ZITADEL_SERVICE_PAT) {
|
|
14
|
-
return config.ZITADEL_SERVICE_PAT;
|
|
15
|
-
}
|
|
16
|
-
if (!config.ZITADEL_SERVICE_CLIENT_ID || !config.ZITADEL_SERVICE_CLIENT_SECRET) {
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const now = Date.now();
|
|
21
|
-
if (cachedServiceToken && cachedServiceToken.expiresAt > now + 60_000) {
|
|
22
|
-
return cachedServiceToken.token;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const params = new URLSearchParams();
|
|
26
|
-
params.set("grant_type", "client_credentials");
|
|
27
|
-
params.set("client_id", config.ZITADEL_SERVICE_CLIENT_ID);
|
|
28
|
-
params.set("client_secret", config.ZITADEL_SERVICE_CLIENT_SECRET);
|
|
29
|
-
params.set("scope", serviceAccountScope());
|
|
30
|
-
|
|
31
|
-
const res = await fetch(`${zitadelBaseUrl()}/oauth/v2/token`, {
|
|
32
|
-
method: "POST",
|
|
33
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
34
|
-
body: params.toString(),
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
if (!res.ok) {
|
|
38
|
-
const text = await res.text();
|
|
39
|
-
throw new Error(`Zitadel service token failed: ${res.status} ${text}`);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const data = (await res.json()) as { access_token: string; expires_in?: number };
|
|
43
|
-
cachedServiceToken = {
|
|
44
|
-
token: data.access_token,
|
|
45
|
-
expiresAt: now + (data.expires_in ?? 3600) * 1000,
|
|
46
|
-
};
|
|
47
|
-
return cachedServiceToken.token;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function serviceAccountScope(): string {
|
|
51
|
-
const scopes = ["urn:zitadel:iam:org:project:id:zitadel:aud"];
|
|
52
|
-
if (config.ZITADEL_ORG_ID) {
|
|
53
|
-
scopes.push(`urn:zitadel:iam:org:id:${config.ZITADEL_ORG_ID}:aud`);
|
|
54
|
-
}
|
|
55
|
-
return scopes.join(" ");
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function orgHeader(): Record<string, string> {
|
|
59
|
-
const headers: Record<string, string> = {};
|
|
60
|
-
if (config.ZITADEL_ORG_ID) {
|
|
61
|
-
headers["x-zitadel-orgid"] = config.ZITADEL_ORG_ID;
|
|
62
|
-
}
|
|
63
|
-
return headers;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export interface CreateHumanUserInput {
|
|
67
|
-
userId?: string;
|
|
68
|
-
username: string;
|
|
69
|
-
email: string;
|
|
70
|
-
name: string;
|
|
71
|
-
password: string;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export async function createHumanUser(input: CreateHumanUserInput): Promise<string> {
|
|
75
|
-
const token = await getServiceToken();
|
|
76
|
-
const headers: Record<string, string> = {
|
|
77
|
-
"Content-Type": "application/json",
|
|
78
|
-
...orgHeader(),
|
|
79
|
-
};
|
|
80
|
-
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
81
|
-
|
|
82
|
-
const names = splitName(input.name || input.username);
|
|
83
|
-
const body: Record<string, unknown> = {
|
|
84
|
-
username: input.username,
|
|
85
|
-
profile: {
|
|
86
|
-
givenName: names.givenName,
|
|
87
|
-
familyName: names.familyName,
|
|
88
|
-
},
|
|
89
|
-
email: {
|
|
90
|
-
email: input.email,
|
|
91
|
-
isVerified: true,
|
|
92
|
-
},
|
|
93
|
-
password: {
|
|
94
|
-
password: input.password,
|
|
95
|
-
changeRequired: false,
|
|
96
|
-
},
|
|
97
|
-
};
|
|
98
|
-
if (input.userId) body.userId = input.userId;
|
|
99
|
-
if (config.ZITADEL_ORG_ID) {
|
|
100
|
-
body.organization = { orgId: config.ZITADEL_ORG_ID };
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const res = await fetch(`${zitadelBaseUrl()}/v2/users/human`, {
|
|
104
|
-
method: "POST",
|
|
105
|
-
headers,
|
|
106
|
-
body: JSON.stringify(body),
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
if (!res.ok) {
|
|
110
|
-
const text = await res.text();
|
|
111
|
-
throw new Error(`Zitadel create user failed: ${res.status} ${text}`);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const data = (await res.json()) as { userId?: string; user?: { userId?: string } };
|
|
115
|
-
return data.userId ?? data.user?.userId ?? "";
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export async function verifyPassword(email: string, password: string): Promise<boolean> {
|
|
119
|
-
const token = await getServiceToken();
|
|
120
|
-
const headers: Record<string, string> = {
|
|
121
|
-
"Content-Type": "application/json",
|
|
122
|
-
...orgHeader(),
|
|
123
|
-
};
|
|
124
|
-
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
125
|
-
|
|
126
|
-
const res = await fetch(`${zitadelBaseUrl()}/v2/sessions`, {
|
|
127
|
-
method: "POST",
|
|
128
|
-
headers,
|
|
129
|
-
body: JSON.stringify({
|
|
130
|
-
checks: {
|
|
131
|
-
user: { loginName: email },
|
|
132
|
-
password: { password },
|
|
133
|
-
},
|
|
134
|
-
lifetime: "3600s",
|
|
135
|
-
}),
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
// Consume/close the session? Zitadel does not require explicit cleanup for short-lived sessions.
|
|
139
|
-
return res.ok;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export async function requestPasswordReset(zitadelUserId: string, redirectUrl: string): Promise<void> {
|
|
143
|
-
const token = await getServiceToken();
|
|
144
|
-
if (!token) throw new Error("Zitadel service token not available for password reset");
|
|
145
|
-
|
|
146
|
-
const res = await fetch(`${zitadelBaseUrl()}/v2/users/${zitadelUserId}/password_reset`, {
|
|
147
|
-
method: "POST",
|
|
148
|
-
headers: {
|
|
149
|
-
"Content-Type": "application/json",
|
|
150
|
-
Authorization: `Bearer ${token}`,
|
|
151
|
-
...orgHeader(),
|
|
152
|
-
},
|
|
153
|
-
body: JSON.stringify({
|
|
154
|
-
sendLink: {
|
|
155
|
-
notificationType: "NOTIFICATION_TYPE_Email",
|
|
156
|
-
urlTemplate: redirectUrl,
|
|
157
|
-
},
|
|
158
|
-
}),
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
if (!res.ok) {
|
|
162
|
-
const text = await res.text();
|
|
163
|
-
throw new Error(`Zitadel password reset failed: ${res.status} ${text}`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export async function setPassword(
|
|
168
|
-
zitadelUserId: string,
|
|
169
|
-
verificationCode: string,
|
|
170
|
-
newPassword: string
|
|
171
|
-
): Promise<void> {
|
|
172
|
-
const token = await getServiceToken();
|
|
173
|
-
if (!token) throw new Error("Zitadel service token not available for password reset");
|
|
174
|
-
|
|
175
|
-
const res = await fetch(`${zitadelBaseUrl()}/v2/users/${zitadelUserId}/password`, {
|
|
176
|
-
method: "POST",
|
|
177
|
-
headers: {
|
|
178
|
-
"Content-Type": "application/json",
|
|
179
|
-
Authorization: `Bearer ${token}`,
|
|
180
|
-
...orgHeader(),
|
|
181
|
-
},
|
|
182
|
-
body: JSON.stringify({
|
|
183
|
-
newPassword: {
|
|
184
|
-
password: newPassword,
|
|
185
|
-
changeRequired: false,
|
|
186
|
-
},
|
|
187
|
-
verificationCode,
|
|
188
|
-
}),
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
if (!res.ok) {
|
|
192
|
-
const text = await res.text();
|
|
193
|
-
throw new Error(`Zitadel set password failed: ${res.status} ${text}`);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export function buildAuthorizeUrl(provider: "google" | "github", state: string): string {
|
|
198
|
-
const redirectUri = `${configPublicUrl()}/auth/callback/${provider}`;
|
|
199
|
-
const params = new URLSearchParams({
|
|
200
|
-
client_id: config.ZITADEL_CLIENT_ID,
|
|
201
|
-
redirect_uri: redirectUri,
|
|
202
|
-
response_type: "code",
|
|
203
|
-
scope: "openid profile email",
|
|
204
|
-
state,
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
const idpId = provider === "google" ? config.ZITADEL_GOOGLE_IDP_ID : config.ZITADEL_GITHUB_IDP_ID;
|
|
208
|
-
if (idpId) {
|
|
209
|
-
params.set("idp_hint", idpId);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return `${zitadelBaseUrl()}/oauth/v2/authorize?${params.toString()}`;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
export async function exchangeOAuthCode(
|
|
216
|
-
provider: "google" | "github",
|
|
217
|
-
code: string
|
|
218
|
-
): Promise<{ idToken: string; accessToken: string; refreshToken?: string }> {
|
|
219
|
-
const redirectUri = `${configPublicUrl()}/auth/callback/${provider}`;
|
|
220
|
-
const params = new URLSearchParams({
|
|
221
|
-
grant_type: "authorization_code",
|
|
222
|
-
client_id: config.ZITADEL_CLIENT_ID,
|
|
223
|
-
client_secret: config.ZITADEL_CLIENT_SECRET,
|
|
224
|
-
code,
|
|
225
|
-
redirect_uri: redirectUri,
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
const res = await fetch(`${zitadelBaseUrl()}/oauth/v2/token`, {
|
|
229
|
-
method: "POST",
|
|
230
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
231
|
-
body: params.toString(),
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
if (!res.ok) {
|
|
235
|
-
const text = await res.text();
|
|
236
|
-
throw new Error(`Zitadel token exchange failed: ${res.status} ${text}`);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const data = (await res.json()) as {
|
|
240
|
-
id_token: string;
|
|
241
|
-
access_token: string;
|
|
242
|
-
refresh_token?: string;
|
|
243
|
-
};
|
|
244
|
-
return {
|
|
245
|
-
idToken: data.id_token,
|
|
246
|
-
accessToken: data.access_token,
|
|
247
|
-
refreshToken: data.refresh_token,
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
export async function getZitadelJwksUrl(): Promise<string> {
|
|
252
|
-
if (cachedJwksUrl) return cachedJwksUrl;
|
|
253
|
-
const discovery = await getDiscovery();
|
|
254
|
-
const url = (discovery.jwks_uri as string) || `${zitadelBaseUrl()}/oauth/v2/keys`;
|
|
255
|
-
cachedJwksUrl = url;
|
|
256
|
-
return url;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
export async function getDiscovery(): Promise<Record<string, unknown>> {
|
|
260
|
-
if (cachedDiscovery) return cachedDiscovery;
|
|
261
|
-
const res = await fetch(`${zitadelBaseUrl()}/.well-known/openid-configuration`);
|
|
262
|
-
if (!res.ok) {
|
|
263
|
-
throw new Error(`Zitadel discovery failed: ${res.status}`);
|
|
264
|
-
}
|
|
265
|
-
cachedDiscovery = (await res.json()) as Record<string, unknown>;
|
|
266
|
-
return cachedDiscovery;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
function configPublicUrl(): string {
|
|
270
|
-
return process.env.AUTH_API_PUBLIC_URL || `http://localhost:${config.PORT}`;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
function splitName(name: string): { givenName: string; familyName: string } {
|
|
274
|
-
const parts = name.trim().split(/\s+/);
|
|
275
|
-
if (parts.length === 1) return { givenName: parts[0], familyName: "" };
|
|
276
|
-
return { givenName: parts[0], familyName: parts.slice(1).join(" ") };
|
|
277
|
-
}
|
package/src/setup-server.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
|
-
import fastify from "fastify";
|
|
5
|
-
import cors from "@fastify/cors";
|
|
6
|
-
import { config } from "./config.js";
|
|
7
|
-
import { generateSetupToken, printSetupToken } from "./services/setup/token.js";
|
|
8
|
-
import setupRoutes from "./routes/setup.js";
|
|
9
|
-
|
|
10
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
-
|
|
12
|
-
async function buildSetupApp() {
|
|
13
|
-
const app = fastify({
|
|
14
|
-
logger: { level: config.NODE_ENV === "production" ? "info" : "debug" },
|
|
15
|
-
trustProxy: true,
|
|
16
|
-
genReqId: () => crypto.randomUUID(),
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
await app.register(cors, {
|
|
20
|
-
origin: true,
|
|
21
|
-
credentials: true,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
await app.register(setupRoutes, { prefix: "/setup" });
|
|
25
|
-
|
|
26
|
-
// Serve the built setup frontend if available.
|
|
27
|
-
const frontendDist = path.resolve(__dirname, "../frontend/dist");
|
|
28
|
-
try {
|
|
29
|
-
const stat = await fs.stat(frontendDist);
|
|
30
|
-
if (stat.isDirectory()) {
|
|
31
|
-
app.register(import("@fastify/static"), {
|
|
32
|
-
root: frontendDist,
|
|
33
|
-
wildcard: true,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
} catch {
|
|
37
|
-
// Built frontend not present; the Vite dev server should be used instead.
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
app.get("/health", async () => ({ status: "setup" }));
|
|
41
|
-
|
|
42
|
-
app.setErrorHandler((error: unknown, request, reply) => {
|
|
43
|
-
if (error && typeof error === "object" && "validation" in error) {
|
|
44
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
45
|
-
return reply.status(400).send({ error: "Invalid input", details: message });
|
|
46
|
-
}
|
|
47
|
-
request.log.error({ err: error }, "Unhandled error");
|
|
48
|
-
const message = config.NODE_ENV === "production" ? "Internal server error" : String(error);
|
|
49
|
-
return reply.status(500).send({ error: message });
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
return app;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async function start() {
|
|
56
|
-
generateSetupToken();
|
|
57
|
-
printSetupToken();
|
|
58
|
-
|
|
59
|
-
const app = await buildSetupApp();
|
|
60
|
-
try {
|
|
61
|
-
await app.listen({ port: config.PORT, host: config.HOST });
|
|
62
|
-
app.log.info(`Hilbras Keystone setup server running on http://${config.HOST}:${config.PORT}`);
|
|
63
|
-
} catch (err) {
|
|
64
|
-
app.log.error(err);
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
|
|
70
|
-
start();
|
|
71
|
-
}
|
package/src/tests/errors.test.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { describe, it } from "node:test";
|
|
2
|
-
import assert from "node:assert";
|
|
3
|
-
|
|
4
|
-
process.env.DATABASE_URL = process.env.DATABASE_URL || "postgresql://hilbras:hilbras@localhost:5432/hilbras";
|
|
5
|
-
|
|
6
|
-
const { classifyOAuthError, buildOAuthErrorRedirect, buildOAuthErrorResponse } = await import("../lib/errors.js");
|
|
7
|
-
|
|
8
|
-
describe("OAuth error sanitization", () => {
|
|
9
|
-
it("classifies state mismatches as access_denied", () => {
|
|
10
|
-
const result = classifyOAuthError(new Error("Invalid OAuth state"));
|
|
11
|
-
assert.strictEqual(result.code, "access_denied");
|
|
12
|
-
assert.strictEqual(result.statusCode, 400);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("classifies unknown clients as invalid_client", () => {
|
|
16
|
-
const result = classifyOAuthError(new Error("Unknown client"));
|
|
17
|
-
assert.strictEqual(result.code, "invalid_client");
|
|
18
|
-
assert.strictEqual(result.statusCode, 400);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("classifies token exchange failures as invalid_grant", () => {
|
|
22
|
-
const result = classifyOAuthError(new Error("Token exchange failed: invalid code"));
|
|
23
|
-
assert.strictEqual(result.code, "invalid_grant");
|
|
24
|
-
assert.strictEqual(result.statusCode, 400);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("classifies provider communication failures as identity_broker_failure", () => {
|
|
28
|
-
const result = classifyOAuthError(new Error("Federation callback failed"));
|
|
29
|
-
assert.strictEqual(result.code, "identity_broker_failure");
|
|
30
|
-
assert.strictEqual(result.statusCode, 502);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("classifies configuration errors as server_error", () => {
|
|
34
|
-
const result = classifyOAuthError(new Error("Connector not configured"));
|
|
35
|
-
assert.strictEqual(result.code, "server_error");
|
|
36
|
-
assert.strictEqual(result.statusCode, 500);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it("classifies generic errors as server_error", () => {
|
|
40
|
-
const result = classifyOAuthError(new Error("Something went wrong"));
|
|
41
|
-
assert.strictEqual(result.code, "server_error");
|
|
42
|
-
assert.strictEqual(result.statusCode, 500);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it("builds a redirect URL with a sanitized code and state", () => {
|
|
46
|
-
const url = buildOAuthErrorRedirect(new Error("secret details"), "http://example.com/cb?foo=bar", {
|
|
47
|
-
state: "xyz",
|
|
48
|
-
includeDescription: false,
|
|
49
|
-
});
|
|
50
|
-
assert.ok(url.startsWith("http://example.com/cb"));
|
|
51
|
-
assert.ok(url.includes("error=server_error"));
|
|
52
|
-
assert.ok(url.includes("state=xyz"));
|
|
53
|
-
assert.ok(url.includes("foo=bar"));
|
|
54
|
-
assert.ok(!url.includes("secret"));
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("includes descriptions in development mode", () => {
|
|
58
|
-
const { statusCode, body } = buildOAuthErrorResponse(new Error("detailed message"), {
|
|
59
|
-
includeDescription: true,
|
|
60
|
-
});
|
|
61
|
-
assert.strictEqual(statusCode, 500);
|
|
62
|
-
assert.strictEqual(body.error, "server_error");
|
|
63
|
-
assert.strictEqual(body.error_description, "detailed message");
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it("omits descriptions outside development mode", () => {
|
|
67
|
-
const { statusCode, body } = buildOAuthErrorResponse(new Error("detailed message"), {
|
|
68
|
-
includeDescription: false,
|
|
69
|
-
});
|
|
70
|
-
assert.strictEqual(statusCode, 500);
|
|
71
|
-
assert.strictEqual(body.error, "server_error");
|
|
72
|
-
assert.strictEqual(body.error_description, undefined);
|
|
73
|
-
});
|
|
74
|
-
});
|
package/src/tests/events.test.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { describe, it } from "node:test";
|
|
2
|
-
import assert from "node:assert";
|
|
3
|
-
import { validateEvent, normalizeEvent } from "../services/events/validate.js";
|
|
4
|
-
import { emit, subscribe, buildEvent } from "../services/events/bus.js";
|
|
5
|
-
|
|
6
|
-
describe("Event validation", () => {
|
|
7
|
-
it("accepts a valid event", () => {
|
|
8
|
-
const result = validateEvent(buildEvent("user_login", { userId: "1" }));
|
|
9
|
-
assert.strictEqual(result.valid, true);
|
|
10
|
-
assert.deepStrictEqual(result.errors, []);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it("rejects an unknown event type", () => {
|
|
14
|
-
const result = validateEvent(buildEvent("unknown_event", {}));
|
|
15
|
-
assert.strictEqual(result.valid, false);
|
|
16
|
-
assert.ok(result.errors.some((e) => e.includes("Unknown event type")));
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("rejects a missing payload", () => {
|
|
20
|
-
const result = validateEvent({ type: "user_login" } as never);
|
|
21
|
-
assert.strictEqual(result.valid, false);
|
|
22
|
-
assert.ok(result.errors.some((e) => e.includes("payload")));
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("rejects an invalid version", () => {
|
|
26
|
-
const result = validateEvent({ type: "user_login", version: 0, payload: {} } as never);
|
|
27
|
-
assert.strictEqual(result.valid, false);
|
|
28
|
-
assert.ok(result.errors.some((e) => e.includes("version")));
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("normalizes an event with version and timestamp", () => {
|
|
32
|
-
const event = normalizeEvent(buildEvent("user_login", { userId: "1" }));
|
|
33
|
-
assert.strictEqual(event.type, "user_login");
|
|
34
|
-
assert.strictEqual(event.version, 1);
|
|
35
|
-
assert.ok(event.timestamp instanceof Date);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
describe("Event bus", () => {
|
|
40
|
-
it("delivers emitted events to subscribers", async () => {
|
|
41
|
-
const received: unknown[] = [];
|
|
42
|
-
const unsubscribe = subscribe("user_login", (event) => {
|
|
43
|
-
received.push(event.payload);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
await emit(buildEvent("user_login", { userId: "42" }));
|
|
47
|
-
unsubscribe();
|
|
48
|
-
|
|
49
|
-
assert.strictEqual(received.length, 1);
|
|
50
|
-
assert.deepStrictEqual((received[0] as { userId: string }).userId, "42");
|
|
51
|
-
});
|
|
52
|
-
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { describe, it } from "node:test";
|
|
2
|
-
import assert from "node:assert";
|
|
3
|
-
import { getConfigurationProfile, listConfigurationProfiles } from "../services/configuration/profiles.js";
|
|
4
|
-
|
|
5
|
-
describe("Configuration profiles", () => {
|
|
6
|
-
it("lists all predefined profiles", () => {
|
|
7
|
-
const profiles = listConfigurationProfiles();
|
|
8
|
-
assert.ok(profiles.some((p) => p.id === "development"));
|
|
9
|
-
assert.ok(profiles.some((p) => p.id === "production"));
|
|
10
|
-
assert.ok(profiles.some((p) => p.id === "docker"));
|
|
11
|
-
assert.ok(profiles.some((p) => p.id === "docker-compose"));
|
|
12
|
-
assert.ok(profiles.some((p) => p.id === "kubernetes"));
|
|
13
|
-
assert.ok(profiles.some((p) => p.id === "high-availability"));
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it("returns a profile with values", () => {
|
|
17
|
-
const profile = getConfigurationProfile("development");
|
|
18
|
-
assert.ok(profile);
|
|
19
|
-
assert.strictEqual(profile.values.NODE_ENV, "development");
|
|
20
|
-
assert.ok(profile.values.DATABASE_URL);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it("returns undefined for unknown profiles", () => {
|
|
24
|
-
assert.strictEqual(getConfigurationProfile("unknown"), undefined);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { describe, it } from "node:test";
|
|
2
|
-
import assert from "node:assert";
|
|
3
|
-
import net from "node:net";
|
|
4
|
-
|
|
5
|
-
process.env.DATABASE_URL = process.env.DATABASE_URL || "postgresql://hilbras:hilbras@localhost:5432/hilbras";
|
|
6
|
-
|
|
7
|
-
function redisReachable(host = "localhost", port = 6379): Promise<boolean> {
|
|
8
|
-
return new Promise((resolve) => {
|
|
9
|
-
const socket = net.createConnection({ host, port });
|
|
10
|
-
socket.on("connect", () => {
|
|
11
|
-
socket.destroy();
|
|
12
|
-
resolve(true);
|
|
13
|
-
});
|
|
14
|
-
socket.on("error", () => resolve(false));
|
|
15
|
-
socket.setTimeout(1000, () => {
|
|
16
|
-
socket.destroy();
|
|
17
|
-
resolve(false);
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const redisAvailable = await redisReachable();
|
|
23
|
-
const { BullMQQueue } = await import("../../services/queue/bullmq.js");
|
|
24
|
-
|
|
25
|
-
describe("Background job queue", () => {
|
|
26
|
-
(redisAvailable ? it : it.skip)("processes a job through BullMQ", async () => {
|
|
27
|
-
const queue = new BullMQQueue(process.env.REDIS_URL || "redis://localhost:6379");
|
|
28
|
-
const payload = { hello: "world" };
|
|
29
|
-
let received: unknown;
|
|
30
|
-
const processed = new Promise<void>((resolve) => {
|
|
31
|
-
queue.process("integration_test", async (job) => {
|
|
32
|
-
received = job.payload;
|
|
33
|
-
resolve();
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
await queue.enqueue({ id: `integration-test-${Date.now()}`, type: "integration_test", payload });
|
|
39
|
-
|
|
40
|
-
// Wait for the worker to pick up the job, bounded by a timeout so a slow
|
|
41
|
-
// or dead worker fails the test instead of hanging the process.
|
|
42
|
-
await Promise.race([
|
|
43
|
-
processed,
|
|
44
|
-
new Promise((resolve) => setTimeout(resolve, 5000)),
|
|
45
|
-
]);
|
|
46
|
-
|
|
47
|
-
assert.deepStrictEqual(received, payload);
|
|
48
|
-
} finally {
|
|
49
|
-
// Always release the worker + Redis connection, even on assertion failure,
|
|
50
|
-
// or open handles keep the node:test process alive indefinitely.
|
|
51
|
-
await queue.close();
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
});
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { describe, it } from "node:test";
|
|
2
|
-
import assert from "node:assert";
|
|
3
|
-
import {
|
|
4
|
-
registerPlugin,
|
|
5
|
-
unregisterPlugin,
|
|
6
|
-
listRegisteredPlugins,
|
|
7
|
-
listExtensionPoints,
|
|
8
|
-
getConnectorFactory,
|
|
9
|
-
getPluginWorkflowStep,
|
|
10
|
-
getAuthenticationMethodFactory,
|
|
11
|
-
} from "../services/plugins/registry.js";
|
|
12
|
-
import type { KeystonePlugin } from "../services/plugins/types.js";
|
|
13
|
-
import type { IdentityConnector } from "../services/connectors/types.js";
|
|
14
|
-
|
|
15
|
-
describe("Plugin registry", () => {
|
|
16
|
-
it("registers a plugin with metadata and extension points", () => {
|
|
17
|
-
const plugin: KeystonePlugin = {
|
|
18
|
-
metadata: { name: "test-plugin", version: "1.0.0", description: "Test" },
|
|
19
|
-
connectors: {
|
|
20
|
-
test: () =>
|
|
21
|
-
({
|
|
22
|
-
id: "test",
|
|
23
|
-
name: "Test",
|
|
24
|
-
type: "test",
|
|
25
|
-
getAuthorizeUrl: () => "",
|
|
26
|
-
exchangeCode: async () => ({ sub: "1", email: "test@example.com" }),
|
|
27
|
-
} satisfies IdentityConnector),
|
|
28
|
-
},
|
|
29
|
-
workflowSteps: {
|
|
30
|
-
testStep: () => ({ output: { done: "true" } }),
|
|
31
|
-
},
|
|
32
|
-
authenticationMethods: {
|
|
33
|
-
testAuth: () => ({
|
|
34
|
-
id: "testAuth",
|
|
35
|
-
name: "Test Auth",
|
|
36
|
-
authenticate: async () => ({ success: false, error: { code: "test", message: "test" } }),
|
|
37
|
-
}),
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
registerPlugin(plugin);
|
|
42
|
-
|
|
43
|
-
const plugins = listRegisteredPlugins();
|
|
44
|
-
assert.ok(plugins.some((p) => p.metadata.name === "test-plugin"));
|
|
45
|
-
assert.deepStrictEqual(plugins.find((p) => p.metadata.name === "test-plugin")?.extensionPoints.sort(), [
|
|
46
|
-
"authenticationMethods",
|
|
47
|
-
"connectors",
|
|
48
|
-
"workflowSteps",
|
|
49
|
-
]);
|
|
50
|
-
|
|
51
|
-
assert.ok(getConnectorFactory("test"));
|
|
52
|
-
assert.ok(getPluginWorkflowStep("testStep"));
|
|
53
|
-
assert.ok(getAuthenticationMethodFactory("testAuth"));
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("lists extension points with registered entries", () => {
|
|
57
|
-
const points = listExtensionPoints();
|
|
58
|
-
assert.ok(points.some((p) => p.name === "connectors" && p.registered.includes("test")));
|
|
59
|
-
assert.ok(points.some((p) => p.name === "workflowSteps" && p.registered.includes("testStep")));
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("unregisters a plugin and removes its extension points", () => {
|
|
63
|
-
const removed = unregisterPlugin("test-plugin");
|
|
64
|
-
assert.strictEqual(removed, true);
|
|
65
|
-
assert.strictEqual(getConnectorFactory("test"), undefined);
|
|
66
|
-
assert.strictEqual(getPluginWorkflowStep("testStep"), undefined);
|
|
67
|
-
assert.strictEqual(getAuthenticationMethodFactory("testAuth"), undefined);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("returns false when unregistering an unknown plugin", () => {
|
|
71
|
-
assert.strictEqual(unregisterPlugin("does-not-exist"), false);
|
|
72
|
-
});
|
|
73
|
-
});
|
package/src/tests/result.test.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { describe, it } from "node:test";
|
|
2
|
-
import assert from "node:assert";
|
|
3
|
-
import { ok, err, errFromMessage, mapResult, flatMapResult } from "../lib/result.js";
|
|
4
|
-
|
|
5
|
-
describe("Result<T> helpers", () => {
|
|
6
|
-
it("ok wraps data in a success result", () => {
|
|
7
|
-
const result = ok(42);
|
|
8
|
-
assert.strictEqual(result.success, true);
|
|
9
|
-
assert.strictEqual(result.data, 42);
|
|
10
|
-
assert.strictEqual(result.error, undefined);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it("err wraps an error in a failure result", () => {
|
|
14
|
-
const result = err<number>({ code: "FAIL", message: "failed" });
|
|
15
|
-
assert.strictEqual(result.success, false);
|
|
16
|
-
assert.strictEqual(result.error.code, "FAIL");
|
|
17
|
-
assert.strictEqual(result.error.message, "failed");
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("errFromMessage builds a failure result from code and message", () => {
|
|
21
|
-
const result = errFromMessage<number>("NOT_FOUND", "missing", 404);
|
|
22
|
-
assert.strictEqual(result.success, false);
|
|
23
|
-
assert.strictEqual(result.error.code, "NOT_FOUND");
|
|
24
|
-
assert.strictEqual(result.error.statusCode, 404);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("mapResult transforms success data", async () => {
|
|
28
|
-
const mapped = mapResult(ok(2), (n) => n * 3);
|
|
29
|
-
assert.strictEqual(mapped.success, true);
|
|
30
|
-
assert.strictEqual(mapped.data, 6);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("mapResult propagates errors", async () => {
|
|
34
|
-
const error = errFromMessage<number>("BAD", "bad");
|
|
35
|
-
const mapped = mapResult(error, (n) => n * 3);
|
|
36
|
-
assert.strictEqual(mapped.success, false);
|
|
37
|
-
assert.strictEqual(mapped.error.code, "BAD");
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("flatMapResult chains async results", async () => {
|
|
41
|
-
const chained = await flatMapResult(ok(2), async (n) => ok(n * 3));
|
|
42
|
-
assert.strictEqual(chained.success, true);
|
|
43
|
-
assert.strictEqual(chained.data, 6);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("flatMapResult short-circuits on failure", async () => {
|
|
47
|
-
const error = errFromMessage<number>("BAD", "bad");
|
|
48
|
-
const chained = await flatMapResult(error, async () => ok(99));
|
|
49
|
-
assert.strictEqual(chained.success, false);
|
|
50
|
-
assert.strictEqual(chained.error.code, "BAD");
|
|
51
|
-
});
|
|
52
|
-
});
|