@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
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { config } from "../config.js";
|
|
3
|
+
import { emit } from "./events/bus.js";
|
|
4
|
+
import { verifyBackupCode, verifyUserTotpCode } from "./totp.js";
|
|
5
|
+
import { err, ok } from "../lib/result.js";
|
|
6
|
+
/** Challenges newer than this are not superseded by a repeat password step. */
|
|
7
|
+
const SUPERSEDE_GRACE_MS = 10_000;
|
|
8
|
+
export function hashMfaChallenge(challenge) {
|
|
9
|
+
return crypto.createHash("sha256").update(challenge).digest("hex");
|
|
10
|
+
}
|
|
11
|
+
export function isMfaChallengeUsable(challenge, now = new Date()) {
|
|
12
|
+
if (challenge.status !== "requires_mfa" || challenge.consumedAt)
|
|
13
|
+
return false;
|
|
14
|
+
if (challenge.attempts >= challenge.maxAttempts)
|
|
15
|
+
return false;
|
|
16
|
+
return challenge.expiresAt > now;
|
|
17
|
+
}
|
|
18
|
+
export class MfaService {
|
|
19
|
+
challenges;
|
|
20
|
+
users;
|
|
21
|
+
constructor(challenges, users) {
|
|
22
|
+
this.challenges = challenges;
|
|
23
|
+
this.users = users;
|
|
24
|
+
}
|
|
25
|
+
async createChallenge(user, flow, clientId, meta = {}) {
|
|
26
|
+
// Supersede older challenges so a leaked one cannot outlive a fresh
|
|
27
|
+
// password step. A short grace period is kept so a client that retries
|
|
28
|
+
// login moments apart does not cancel the attempt it just started.
|
|
29
|
+
await this.challenges.invalidateUserChallenges(user.id, new Date(Date.now() - SUPERSEDE_GRACE_MS));
|
|
30
|
+
const challenge = crypto.randomBytes(32).toString("base64url");
|
|
31
|
+
const expiresAt = new Date(Date.now() + config.MFA_CHALLENGE_TTL_SECONDS * 1000);
|
|
32
|
+
await this.challenges.create({
|
|
33
|
+
challengeHash: hashMfaChallenge(challenge),
|
|
34
|
+
userId: user.id,
|
|
35
|
+
flow: normalizeFlow(flow),
|
|
36
|
+
clientId,
|
|
37
|
+
ipAddress: meta.ipAddress,
|
|
38
|
+
userAgent: meta.userAgent,
|
|
39
|
+
expiresAt,
|
|
40
|
+
maxAttempts: config.MFA_MAX_ATTEMPTS,
|
|
41
|
+
});
|
|
42
|
+
await emit({
|
|
43
|
+
type: "mfa_challenge_created",
|
|
44
|
+
payload: {
|
|
45
|
+
userId: user.id,
|
|
46
|
+
flow,
|
|
47
|
+
client_id: clientId,
|
|
48
|
+
ip: meta.ipAddress,
|
|
49
|
+
expiresAt: expiresAt.toISOString(),
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
return { challenge, expiresAt, flow, clientId };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Verify a second factor for an outstanding challenge and consume it.
|
|
56
|
+
* No token is issued here: the caller decides what to issue after the state
|
|
57
|
+
* transition to `mfa_verified` has succeeded.
|
|
58
|
+
*/
|
|
59
|
+
async verifyChallenge(challengeToken, code, factor, loadUser) {
|
|
60
|
+
const now = new Date();
|
|
61
|
+
const challenge = await this.challenges.findByHash(hashMfaChallenge(challengeToken));
|
|
62
|
+
if (!challenge) {
|
|
63
|
+
await emit({ type: "mfa_challenge_rejected", payload: { reason: "unknown_challenge" } });
|
|
64
|
+
return err({ code: "MFA_CHALLENGE_INVALID", message: "The MFA challenge is invalid or has expired.", statusCode: 401 });
|
|
65
|
+
}
|
|
66
|
+
if (challenge.expiresAt <= now) {
|
|
67
|
+
await emit({ type: "mfa_challenge_expired", payload: { userId: challenge.userId, reason: "expired" } });
|
|
68
|
+
return err({ code: "MFA_CHALLENGE_EXPIRED", message: "The MFA challenge is invalid or has expired.", statusCode: 401 });
|
|
69
|
+
}
|
|
70
|
+
if (!isMfaChallengeUsable(challenge, now)) {
|
|
71
|
+
const reason = challenge.status !== "requires_mfa" ? challenge.status : "attempts_exhausted";
|
|
72
|
+
await emit({
|
|
73
|
+
type: challenge.status === "requires_mfa" ? "mfa_challenge_failed" : "mfa_challenge_rejected",
|
|
74
|
+
payload: { userId: challenge.userId, reason },
|
|
75
|
+
});
|
|
76
|
+
return err({
|
|
77
|
+
code: challenge.status === "consumed" ? "MFA_CHALLENGE_REPLAYED" : "MFA_CHALLENGE_LOCKED",
|
|
78
|
+
message: "The MFA challenge is invalid or has expired.",
|
|
79
|
+
statusCode: 401,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const user = await loadUser(challenge.userId);
|
|
83
|
+
if (!user || !user.isActive) {
|
|
84
|
+
await this.challenges.invalidateUserChallenges(challenge.userId, now);
|
|
85
|
+
await emit({ type: "mfa_challenge_failed", payload: { userId: challenge.userId, reason: "account_unusable" } });
|
|
86
|
+
return err({ code: "ACCOUNT_UNAVAILABLE", message: "This account cannot sign in.", statusCode: 403 });
|
|
87
|
+
}
|
|
88
|
+
// The password step refuses these states; the MFA step must not be the
|
|
89
|
+
// weaker door, or a challenge opened moments earlier would still work.
|
|
90
|
+
if (user.accountReviewRequired) {
|
|
91
|
+
await this.challenges.invalidateUserChallenges(user.id, now);
|
|
92
|
+
await emit({ type: "mfa_challenge_failed", payload: { userId: user.id, reason: "account_review_required" } });
|
|
93
|
+
return err({ code: "ACCOUNT_REVIEW_REQUIRED", message: "This account is pending review.", statusCode: 403 });
|
|
94
|
+
}
|
|
95
|
+
if (user.lockedUntil && user.lockedUntil > new Date()) {
|
|
96
|
+
await this.challenges.invalidateUserChallenges(user.id, now);
|
|
97
|
+
await emit({ type: "mfa_challenge_failed", payload: { userId: user.id, reason: "account_locked" } });
|
|
98
|
+
return err({ code: "ACCOUNT_LOCKED", message: "Account is temporarily locked due to too many failed attempts. Try again later.", statusCode: 403 });
|
|
99
|
+
}
|
|
100
|
+
if (!user.totpEnabled) {
|
|
101
|
+
// The factor was disabled while the challenge was outstanding.
|
|
102
|
+
await this.challenges.invalidateUserChallenges(user.id, now);
|
|
103
|
+
await emit({ type: "mfa_challenge_failed", payload: { userId: user.id, reason: "mfa_disabled" } });
|
|
104
|
+
return err({ code: "MFA_NOT_REQUIRED", message: "Multi-factor authentication is no longer required.", statusCode: 409 });
|
|
105
|
+
}
|
|
106
|
+
const verified = factor === "totp"
|
|
107
|
+
? (await verifyUserTotpCode(user, code)).valid
|
|
108
|
+
: await verifyBackupCode(user.id, code);
|
|
109
|
+
if (!verified) {
|
|
110
|
+
const updated = await this.challenges.recordFailedAttempt(challenge.id, now);
|
|
111
|
+
// Count factor failures toward the account lockout so a stolen password
|
|
112
|
+
// cannot be brute-forced through the MFA step at its own slower pace.
|
|
113
|
+
const afterFailure = await this.users.recordFailedLogin(user.id);
|
|
114
|
+
const failedAttempts = afterFailure?.failedLoginAttempts ?? 0;
|
|
115
|
+
if (failedAttempts >= config.ACCOUNT_LOCKOUT_THRESHOLD) {
|
|
116
|
+
await this.users.lockAccount(user.id, new Date(Date.now() + config.ACCOUNT_LOCKOUT_DURATION_SECONDS * 1000));
|
|
117
|
+
await this.challenges.invalidateUserChallenges(user.id, new Date());
|
|
118
|
+
await emit({
|
|
119
|
+
type: "mfa_challenge_failed",
|
|
120
|
+
payload: { userId: user.id, factor, reason: "account_locked", attempts: failedAttempts },
|
|
121
|
+
});
|
|
122
|
+
return err({ code: "ACCOUNT_LOCKED", message: "Account locked due to too many failed attempts. Try again later.", statusCode: 403 });
|
|
123
|
+
}
|
|
124
|
+
await emit({
|
|
125
|
+
type: "mfa_challenge_failed",
|
|
126
|
+
payload: {
|
|
127
|
+
userId: user.id,
|
|
128
|
+
factor,
|
|
129
|
+
attempts: updated?.attempts ?? challenge.attempts + 1,
|
|
130
|
+
attemptsRemaining: updated ? Math.max(0, updated.maxAttempts - updated.attempts) : 0,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
return err({ code: "MFA_INVALID_CODE", message: "The verification code is invalid.", statusCode: 401 });
|
|
134
|
+
}
|
|
135
|
+
const consumed = await this.challenges.consume(challenge.id, new Date());
|
|
136
|
+
if (!consumed) {
|
|
137
|
+
// Lost the race against a concurrent verification of the same challenge.
|
|
138
|
+
await emit({ type: "mfa_challenge_rejected", payload: { userId: user.id, reason: "already_consumed" } });
|
|
139
|
+
return err({ code: "MFA_CHALLENGE_REPLAYED", message: "The MFA challenge is invalid or has expired.", statusCode: 401 });
|
|
140
|
+
}
|
|
141
|
+
await this.users.resetFailedLogins(user.id);
|
|
142
|
+
await emit({
|
|
143
|
+
type: "mfa_verified",
|
|
144
|
+
payload: { userId: user.id, factor, flow: challenge.flow },
|
|
145
|
+
});
|
|
146
|
+
return ok({
|
|
147
|
+
challengeId: challenge.id,
|
|
148
|
+
user,
|
|
149
|
+
flow: normalizeFlow(challenge.flow),
|
|
150
|
+
clientId: challenge.clientId ?? undefined,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function normalizeFlow(flow) {
|
|
155
|
+
return flow === "token_login" ? "token_login" : "login";
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=mfa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfa.js","sourceRoot":"","sources":["../../src/services/mfa.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { oauth2AuthorizationCodes, type User, type Application } from "../db/schema.js";
|
|
1
|
+
import { oauth2AuthorizationCodes, oauth2Consents, type User, type Application } from "../db/schema.js";
|
|
2
|
+
import { type MfaAssertion } from "./tokens.js";
|
|
2
3
|
export interface AuthorizationCodeInput {
|
|
3
4
|
appId: string;
|
|
4
5
|
userId: string;
|
|
@@ -7,6 +8,7 @@ export interface AuthorizationCodeInput {
|
|
|
7
8
|
redirectUri?: string;
|
|
8
9
|
scopes?: string[];
|
|
9
10
|
nonce?: string;
|
|
11
|
+
mfaFactor?: MfaAssertion;
|
|
10
12
|
}
|
|
11
13
|
export declare function generateAuthorizationCode(): {
|
|
12
14
|
code: string;
|
|
@@ -14,44 +16,116 @@ export declare function generateAuthorizationCode(): {
|
|
|
14
16
|
};
|
|
15
17
|
export declare function storeAuthorizationCode(input: AuthorizationCodeInput): Promise<{
|
|
16
18
|
code: string;
|
|
17
|
-
id: string;
|
|
18
|
-
createdAt: Date;
|
|
19
|
-
userId: string;
|
|
20
|
-
expiresAt: Date;
|
|
21
19
|
appId: string;
|
|
22
|
-
scopes: string[];
|
|
23
|
-
codeHash: string;
|
|
24
20
|
challenge: string | null;
|
|
25
21
|
challengeMethod: string | null;
|
|
26
|
-
|
|
22
|
+
codeHash: string;
|
|
23
|
+
createdAt: Date;
|
|
24
|
+
expiresAt: Date;
|
|
25
|
+
id: string;
|
|
26
|
+
mfaFactor: string | null;
|
|
27
27
|
nonce: string | null;
|
|
28
|
+
redirectUri: string | null;
|
|
29
|
+
scopes: string[];
|
|
28
30
|
usedAt: Date | null;
|
|
31
|
+
userId: string;
|
|
29
32
|
}>;
|
|
30
33
|
export declare function consumeAuthorizationCode(code: string, appId: string, redirectUri?: string): Promise<typeof oauth2AuthorizationCodes.$inferSelect | undefined>;
|
|
31
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Verify a PKCE code verifier against a stored challenge.
|
|
36
|
+
*
|
|
37
|
+
* `requireChallenge` exists because the previous shape of this function was the
|
|
38
|
+
* whole PKCE story at the token endpoint, and it was not a check at all:
|
|
39
|
+
*
|
|
40
|
+
* ```ts
|
|
41
|
+
* if (!challenge) return true; // no challenge was registered -> accept
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* A client that omitted `code_challenge` at `/authorize` and then sent any
|
|
45
|
+
* string as `code_verifier` at `/token` passed. The endpoint required a
|
|
46
|
+
* verifier to be *present*, so the requirement looked enforced while proving
|
|
47
|
+
* nothing. For a public client — an SPA or a mobile app that cannot hold a
|
|
48
|
+
* secret — PKCE is the only thing standing between an intercepted authorization
|
|
49
|
+
* code and a stolen account, so "optional" meant "unprotected".
|
|
50
|
+
*
|
|
51
|
+
* The two failure modes are now separated deliberately:
|
|
52
|
+
* - no challenge and `requireChallenge` false: a confidential client that chose
|
|
53
|
+
* not to use PKCE. Permitted, because it authenticates with a secret.
|
|
54
|
+
* - a challenge but a mismatched or malformed verifier: always a failure.
|
|
55
|
+
*/
|
|
56
|
+
export declare function verifyPKCE(challenge: string | null | undefined, method: string | null | undefined, verifier: string | null | undefined, options?: {
|
|
57
|
+
requireChallenge?: boolean;
|
|
58
|
+
}): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* A client that cannot keep a secret must use PKCE.
|
|
61
|
+
*
|
|
62
|
+
* Today every application has a non-null `client_secret_hash`, so this reduces to
|
|
63
|
+
* "the client has no usable secret" — which is the honest test regardless of how
|
|
64
|
+
* the column is populated, and stays correct if secretless public clients are
|
|
65
|
+
* introduced later.
|
|
66
|
+
*/
|
|
67
|
+
export declare function requiresPkce(clientSecretHash: string | null | undefined): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Reduce requested scopes to the ones actually granted.
|
|
70
|
+
*
|
|
71
|
+
* The effective set is the intersection of what the client is registered to ask
|
|
72
|
+
* for, what it asked for, and what the user consented to. Previously the
|
|
73
|
+
* client's `scope` parameter was stored verbatim and the only filter applied was
|
|
74
|
+
* consent, so a client could put any string it liked into the issued token.
|
|
75
|
+
*
|
|
76
|
+
* Rejecting rather than silently dropping is deliberate: a client asking for
|
|
77
|
+
* something it was never registered for is a misconfiguration or an attempt to
|
|
78
|
+
* escalate, and quietly handing back a lesser scope set hides both. The error
|
|
79
|
+
* names the offending scope so the client can be fixed.
|
|
80
|
+
*
|
|
81
|
+
* An empty `allowedScopes` means "no restriction registered", which preserves
|
|
82
|
+
* every existing application. Once an application has an allowlist, it is
|
|
83
|
+
* enforced.
|
|
84
|
+
*/
|
|
85
|
+
export declare function resolveEffectiveScopes(input: {
|
|
86
|
+
requested: string[];
|
|
87
|
+
allowed: string[];
|
|
88
|
+
consented: string[] | null;
|
|
89
|
+
}): {
|
|
90
|
+
ok: true;
|
|
91
|
+
scopes: string[];
|
|
92
|
+
} | {
|
|
93
|
+
ok: false;
|
|
94
|
+
error: string;
|
|
95
|
+
scope: string;
|
|
96
|
+
};
|
|
32
97
|
export declare function hasConsent(userId: string, appId: string, requestedScopes: string[]): Promise<boolean>;
|
|
98
|
+
/**
|
|
99
|
+
* The user's current consent record, or undefined if they have never consented
|
|
100
|
+
* or have revoked it.
|
|
101
|
+
*
|
|
102
|
+
* Kept separate from `hasConsent` because the scope intersection needs the
|
|
103
|
+
* granted set itself, not a yes/no answer to it.
|
|
104
|
+
*/
|
|
105
|
+
export declare function findConsent(userId: string, appId: string): Promise<typeof oauth2Consents.$inferSelect | undefined>;
|
|
33
106
|
export declare function grantConsent(userId: string, appId: string, scopes: string[]): Promise<{
|
|
34
|
-
id: string;
|
|
35
|
-
userId: string;
|
|
36
107
|
appId: string;
|
|
108
|
+
grantedAt: Date;
|
|
109
|
+
id: string;
|
|
37
110
|
revokedAt: Date | null;
|
|
38
111
|
scopes: string[];
|
|
39
|
-
|
|
112
|
+
userId: string;
|
|
40
113
|
}>;
|
|
41
114
|
export declare function revokeConsent(userId: string, appId: string): Promise<void>;
|
|
42
115
|
export declare function listConsentsByAppId(appId: string): Promise<{
|
|
43
116
|
id: string;
|
|
44
|
-
userId: string;
|
|
45
117
|
appId: string;
|
|
46
|
-
|
|
118
|
+
userId: string;
|
|
47
119
|
scopes: string[];
|
|
48
120
|
grantedAt: Date;
|
|
121
|
+
revokedAt: Date | null;
|
|
49
122
|
}[]>;
|
|
50
123
|
export declare function createTokenResponse(user: User, app: Application, scopes: string[], opts?: {
|
|
51
124
|
ip?: string;
|
|
52
125
|
userAgent?: string;
|
|
53
126
|
deviceFingerprint?: string;
|
|
54
127
|
nonce?: string;
|
|
128
|
+
mfaFactor?: MfaAssertion;
|
|
55
129
|
}): Promise<Record<string, unknown>>;
|
|
56
130
|
export declare function findApplicationByClientId(clientId: string): Promise<Application | undefined>;
|
|
57
131
|
export declare function verifyClientSecret(clientId: string, secret: string): Promise<Application | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth2.d.ts","sourceRoot":"","sources":["../../src/services/oauth2.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,wBAAwB,
|
|
1
|
+
{"version":3,"file":"oauth2.d.ts","sourceRoot":"","sources":["../../src/services/oauth2.ts"],"names":[],"mappings":"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"}
|
package/dist/services/oauth2.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { eq, and, gt, isNull } from "drizzle-orm";
|
|
3
3
|
import { db } from "../db/index.js";
|
|
4
|
-
import { oauth2AuthorizationCodes, oauth2Consents, applications, } from "../db/schema.js";
|
|
4
|
+
import { oauth2AuthorizationCodes, oauth2Consents, applications, orgMemberships, } from "../db/schema.js";
|
|
5
5
|
import { config } from "../config.js";
|
|
6
6
|
import { createTokenSet, createIdToken } from "./tokens.js";
|
|
7
7
|
export function generateAuthorizationCode() {
|
|
@@ -23,6 +23,7 @@ export async function storeAuthorizationCode(input) {
|
|
|
23
23
|
redirectUri: input.redirectUri ?? null,
|
|
24
24
|
scopes: input.scopes ?? [],
|
|
25
25
|
nonce: input.nonce ?? null,
|
|
26
|
+
mfaFactor: input.mfaFactor ?? null,
|
|
26
27
|
expiresAt,
|
|
27
28
|
})
|
|
28
29
|
.returning();
|
|
@@ -31,29 +32,111 @@ export async function storeAuthorizationCode(input) {
|
|
|
31
32
|
export async function consumeAuthorizationCode(code, appId, redirectUri) {
|
|
32
33
|
const codeHash = crypto.createHash("sha256").update(code).digest("hex");
|
|
33
34
|
const now = new Date();
|
|
34
|
-
const
|
|
35
|
-
.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
const conditions = [
|
|
36
|
+
eq(oauth2AuthorizationCodes.codeHash, codeHash),
|
|
37
|
+
eq(oauth2AuthorizationCodes.appId, appId),
|
|
38
|
+
gt(oauth2AuthorizationCodes.expiresAt, now),
|
|
39
|
+
isNull(oauth2AuthorizationCodes.usedAt),
|
|
40
|
+
];
|
|
41
|
+
// Exact match, no exceptions. `redirect_uri` is required at /authorize, so
|
|
42
|
+
// there is always a stored value to compare against; tolerating a missing one
|
|
43
|
+
// here would let a stolen code be redeemed against any redirect URI.
|
|
44
|
+
if (redirectUri) {
|
|
45
|
+
conditions.push(eq(oauth2AuthorizationCodes.redirectUri, redirectUri));
|
|
43
46
|
}
|
|
44
|
-
await db
|
|
47
|
+
const [record] = await db
|
|
45
48
|
.update(oauth2AuthorizationCodes)
|
|
46
49
|
.set({ usedAt: now })
|
|
47
|
-
.where(
|
|
50
|
+
.where(and(...conditions))
|
|
51
|
+
.returning();
|
|
48
52
|
return record;
|
|
49
53
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Verify a PKCE code verifier against a stored challenge.
|
|
56
|
+
*
|
|
57
|
+
* `requireChallenge` exists because the previous shape of this function was the
|
|
58
|
+
* whole PKCE story at the token endpoint, and it was not a check at all:
|
|
59
|
+
*
|
|
60
|
+
* ```ts
|
|
61
|
+
* if (!challenge) return true; // no challenge was registered -> accept
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* A client that omitted `code_challenge` at `/authorize` and then sent any
|
|
65
|
+
* string as `code_verifier` at `/token` passed. The endpoint required a
|
|
66
|
+
* verifier to be *present*, so the requirement looked enforced while proving
|
|
67
|
+
* nothing. For a public client — an SPA or a mobile app that cannot hold a
|
|
68
|
+
* secret — PKCE is the only thing standing between an intercepted authorization
|
|
69
|
+
* code and a stolen account, so "optional" meant "unprotected".
|
|
70
|
+
*
|
|
71
|
+
* The two failure modes are now separated deliberately:
|
|
72
|
+
* - no challenge and `requireChallenge` false: a confidential client that chose
|
|
73
|
+
* not to use PKCE. Permitted, because it authenticates with a secret.
|
|
74
|
+
* - a challenge but a mismatched or malformed verifier: always a failure.
|
|
75
|
+
*/
|
|
76
|
+
export function verifyPKCE(challenge, method, verifier, options = {}) {
|
|
77
|
+
if (!challenge) {
|
|
78
|
+
// No challenge to verify against. Only acceptable when PKCE was not
|
|
79
|
+
// required for this client.
|
|
80
|
+
return !options.requireChallenge;
|
|
81
|
+
}
|
|
82
|
+
if (typeof verifier !== "string" || verifier === "")
|
|
83
|
+
return false;
|
|
53
84
|
if (method?.toLowerCase() !== "s256")
|
|
54
85
|
return false;
|
|
55
86
|
const hash = crypto.createHash("sha256").update(verifier).digest("base64url");
|
|
56
|
-
return hash
|
|
87
|
+
return timingSafeEqual(hash, challenge);
|
|
88
|
+
}
|
|
89
|
+
/** Constant-time comparison, so a verifier cannot be recovered byte by byte. */
|
|
90
|
+
function timingSafeEqual(a, b) {
|
|
91
|
+
const bufA = Buffer.from(a, "utf8");
|
|
92
|
+
const bufB = Buffer.from(b, "utf8");
|
|
93
|
+
if (bufA.length !== bufB.length)
|
|
94
|
+
return false;
|
|
95
|
+
return crypto.timingSafeEqual(bufA, bufB);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* A client that cannot keep a secret must use PKCE.
|
|
99
|
+
*
|
|
100
|
+
* Today every application has a non-null `client_secret_hash`, so this reduces to
|
|
101
|
+
* "the client has no usable secret" — which is the honest test regardless of how
|
|
102
|
+
* the column is populated, and stays correct if secretless public clients are
|
|
103
|
+
* introduced later.
|
|
104
|
+
*/
|
|
105
|
+
export function requiresPkce(clientSecretHash) {
|
|
106
|
+
return !clientSecretHash || clientSecretHash === "";
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Reduce requested scopes to the ones actually granted.
|
|
110
|
+
*
|
|
111
|
+
* The effective set is the intersection of what the client is registered to ask
|
|
112
|
+
* for, what it asked for, and what the user consented to. Previously the
|
|
113
|
+
* client's `scope` parameter was stored verbatim and the only filter applied was
|
|
114
|
+
* consent, so a client could put any string it liked into the issued token.
|
|
115
|
+
*
|
|
116
|
+
* Rejecting rather than silently dropping is deliberate: a client asking for
|
|
117
|
+
* something it was never registered for is a misconfiguration or an attempt to
|
|
118
|
+
* escalate, and quietly handing back a lesser scope set hides both. The error
|
|
119
|
+
* names the offending scope so the client can be fixed.
|
|
120
|
+
*
|
|
121
|
+
* An empty `allowedScopes` means "no restriction registered", which preserves
|
|
122
|
+
* every existing application. Once an application has an allowlist, it is
|
|
123
|
+
* enforced.
|
|
124
|
+
*/
|
|
125
|
+
export function resolveEffectiveScopes(input) {
|
|
126
|
+
const requested = [...new Set(input.requested.filter(Boolean))];
|
|
127
|
+
const allowed = new Set(input.allowed);
|
|
128
|
+
const consented = input.consented === null ? null : new Set(input.consented);
|
|
129
|
+
const effective = [];
|
|
130
|
+
for (const scope of requested) {
|
|
131
|
+
if (allowed.size > 0 && !allowed.has(scope)) {
|
|
132
|
+
return { ok: false, error: "invalid_scope", scope };
|
|
133
|
+
}
|
|
134
|
+
if (consented && !consented.has(scope)) {
|
|
135
|
+
return { ok: false, error: "invalid_scope", scope };
|
|
136
|
+
}
|
|
137
|
+
effective.push(scope);
|
|
138
|
+
}
|
|
139
|
+
return { ok: true, scopes: effective };
|
|
57
140
|
}
|
|
58
141
|
export async function hasConsent(userId, appId, requestedScopes) {
|
|
59
142
|
if (requestedScopes.length === 0)
|
|
@@ -68,6 +151,21 @@ export async function hasConsent(userId, appId, requestedScopes) {
|
|
|
68
151
|
const granted = new Set(consent.scopes);
|
|
69
152
|
return requestedScopes.every((scope) => granted.has(scope));
|
|
70
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* The user's current consent record, or undefined if they have never consented
|
|
156
|
+
* or have revoked it.
|
|
157
|
+
*
|
|
158
|
+
* Kept separate from `hasConsent` because the scope intersection needs the
|
|
159
|
+
* granted set itself, not a yes/no answer to it.
|
|
160
|
+
*/
|
|
161
|
+
export async function findConsent(userId, appId) {
|
|
162
|
+
const [consent] = await db
|
|
163
|
+
.select()
|
|
164
|
+
.from(oauth2Consents)
|
|
165
|
+
.where(and(eq(oauth2Consents.appId, appId), eq(oauth2Consents.userId, userId), isNull(oauth2Consents.revokedAt)))
|
|
166
|
+
.limit(1);
|
|
167
|
+
return consent;
|
|
168
|
+
}
|
|
71
169
|
export async function grantConsent(userId, appId, scopes) {
|
|
72
170
|
const now = new Date();
|
|
73
171
|
const [record] = await db
|
|
@@ -102,10 +200,21 @@ export async function listConsentsByAppId(appId) {
|
|
|
102
200
|
.where(and(eq(oauth2Consents.appId, appId), isNull(oauth2Consents.revokedAt)));
|
|
103
201
|
}
|
|
104
202
|
export async function createTokenResponse(user, app, scopes, opts = {}) {
|
|
203
|
+
const [membership] = await db
|
|
204
|
+
.select({ id: orgMemberships.id })
|
|
205
|
+
.from(orgMemberships)
|
|
206
|
+
.where(and(eq(orgMemberships.orgId, app.orgId), eq(orgMemberships.userId, user.id)))
|
|
207
|
+
.limit(1);
|
|
208
|
+
if (!membership)
|
|
209
|
+
throw new Error("OAuth user is not a member of the application organization");
|
|
105
210
|
const tokenOpts = {
|
|
106
211
|
appId: app.id,
|
|
107
212
|
orgId: app.orgId,
|
|
108
213
|
clientId: app.clientId,
|
|
214
|
+
// The granted set is persisted on the refresh token so it survives rotation
|
|
215
|
+
// instead of being dropped at the first refresh.
|
|
216
|
+
...(scopes.length > 0 ? { scopes } : {}),
|
|
217
|
+
...(opts.mfaFactor ? { mfaFactor: opts.mfaFactor } : {}),
|
|
109
218
|
};
|
|
110
219
|
const tokenSet = await createTokenSet(user, opts.ip, opts.userAgent, tokenOpts, opts.deviceFingerprint);
|
|
111
220
|
const response = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth2.js","sourceRoot":"","sources":["../../src/services/oauth2.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"oauth2.js","sourceRoot":"","sources":["../../src/services/oauth2.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidcSecretFormat.d.ts","sourceRoot":"","sources":["../../src/services/oidcSecretFormat.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,YAAY,CAAC;AAEnD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidcSecretFormat.js","sourceRoot":"","sources":["../../src/services/oidcSecretFormat.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG,SAAS,CAAC;AAEnD,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,KAAK,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -1,38 +1,26 @@
|
|
|
1
1
|
import { type Organization, type OrgMembership } from "../db/schema.js";
|
|
2
2
|
export type OrgRole = "owner" | "admin" | "member";
|
|
3
3
|
export declare function slugify(name: string): string;
|
|
4
|
-
export declare function createOrganization(input: {
|
|
5
|
-
name: string;
|
|
6
|
-
slug?: string;
|
|
7
|
-
plan?: string;
|
|
8
|
-
}): Promise<Organization>;
|
|
9
4
|
export declare function findOrganizationById(id: string): Promise<Organization | undefined>;
|
|
10
5
|
export declare function findOrganizationBySlug(slug: string): Promise<Organization | undefined>;
|
|
11
6
|
export declare function findOrganizationsByUserId(userId: string): Promise<Organization[]>;
|
|
12
|
-
export declare function addOrgMembership(input: {
|
|
13
|
-
orgId: string;
|
|
14
|
-
userId: string;
|
|
15
|
-
role: OrgRole;
|
|
16
|
-
}): Promise<OrgMembership>;
|
|
17
7
|
export declare function findMembership(orgId: string, userId: string): Promise<OrgMembership | undefined>;
|
|
18
|
-
export declare function updateMembershipRole(orgId: string, userId: string, role: OrgRole): Promise<OrgMembership | undefined>;
|
|
19
|
-
export declare function removeMembership(orgId: string, userId: string): Promise<boolean>;
|
|
20
8
|
export declare function countOwners(orgId: string): Promise<number>;
|
|
21
9
|
export declare function requireOrgRole(userId: string, orgId: string, allowedRoles: OrgRole[]): Promise<OrgMembership>;
|
|
22
10
|
export declare function listOrgMembers(orgId: string): Promise<{
|
|
23
11
|
membership: {
|
|
24
12
|
id: string;
|
|
13
|
+
orgId: string;
|
|
14
|
+
userId: string;
|
|
15
|
+
role: string;
|
|
25
16
|
createdAt: Date;
|
|
26
17
|
updatedAt: Date;
|
|
27
|
-
role: string;
|
|
28
|
-
userId: string;
|
|
29
|
-
orgId: string;
|
|
30
18
|
};
|
|
31
19
|
user: {
|
|
32
20
|
id: string;
|
|
33
|
-
name: string | null;
|
|
34
21
|
email: string;
|
|
35
22
|
username: string;
|
|
23
|
+
name: string | null;
|
|
36
24
|
avatarUrl: string | null;
|
|
37
25
|
};
|
|
38
26
|
}[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../src/services/organizations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwC,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE9G,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEnD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO5C;AAED,wBAAsB,
|
|
1
|
+
{"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../src/services/organizations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwC,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE9G,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEnD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO5C;AAED,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAGxF;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAG5F;AAED,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAOvF;AAED,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAOpC;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMhE;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,OAAO,EAAE,GACtB,OAAO,CAAC,aAAa,CAAC,CAexB;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM;;;;;;;;;;;;;;;;KAejD"}
|