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