@hilbras/keystone 1.6.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +239 -0
- package/README.md +55 -25
- package/dist/cli.js +25 -27
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +15 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +45 -8
- package/dist/config.js.map +1 -1
- package/dist/container.d.ts +4 -1
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js.map +1 -1
- package/dist/db/migrations/0008_flashy_firestar.sql +5 -0
- package/dist/db/migrations/0009_daffy_changeling.sql +1 -0
- package/dist/db/migrations/0010_wealthy_shadow_king.sql +37 -0
- package/dist/db/migrations/0011_overrated_vector.sql +18 -0
- package/dist/db/migrations/0012_brave_darkhawk.sql +28 -0
- package/dist/db/migrations/0013_wonderful_chimera.sql +5 -0
- package/dist/db/migrations/0014_magical_morph.sql +48 -0
- package/{src/db/migrations/meta/0007_snapshot.json → dist/db/migrations/meta/0008_snapshot.json} +136 -32
- package/{src/db/migrations/meta/0006_snapshot.json → dist/db/migrations/meta/0009_snapshot.json} +359 -30
- package/{src/db/migrations/meta/0005_snapshot.json → dist/db/migrations/meta/0010_snapshot.json} +459 -29
- package/{src/db/migrations/meta/0004_snapshot.json → dist/db/migrations/meta/0011_snapshot.json} +594 -30
- package/dist/db/migrations/meta/0012_snapshot.json +3891 -0
- package/dist/db/migrations/meta/0013_snapshot.json +3919 -0
- package/dist/db/migrations/meta/0014_snapshot.json +4311 -0
- package/dist/db/migrations/meta/_journal.json +49 -0
- package/dist/db/reencryptOidcSecrets.d.ts +2 -0
- package/dist/db/reencryptOidcSecrets.d.ts.map +1 -0
- package/dist/db/reencryptOidcSecrets.js +41 -0
- package/dist/db/reencryptOidcSecrets.js.map +1 -0
- package/dist/db/schema.d.ts +2521 -53
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +118 -3
- package/dist/db/schema.js.map +1 -1
- package/dist/db/seed.js +67 -40
- package/dist/db/seed.js.map +1 -1
- package/dist/di.d.ts.map +1 -1
- package/dist/di.js +11 -3
- package/dist/di.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/errors.d.ts +2 -1
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +10 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/plugins/appContext.d.ts.map +1 -1
- package/dist/plugins/appContext.js +3 -12
- package/dist/plugins/appContext.js.map +1 -1
- package/dist/plugins/audit.d.ts.map +1 -1
- package/dist/plugins/audit.js +26 -6
- package/dist/plugins/audit.js.map +1 -1
- package/dist/plugins/auth.d.ts.map +1 -1
- package/dist/plugins/auth.js +32 -7
- package/dist/plugins/auth.js.map +1 -1
- package/dist/plugins/metrics.d.ts.map +1 -1
- package/dist/plugins/mtls.d.ts.map +1 -1
- package/dist/plugins/permissions.d.ts.map +1 -1
- package/dist/plugins/permissions.js +29 -9
- package/dist/plugins/permissions.js.map +1 -1
- package/dist/plugins/rateLimit.d.ts +15 -0
- package/dist/plugins/rateLimit.d.ts.map +1 -1
- package/dist/plugins/rateLimit.js +11 -1
- package/dist/plugins/rateLimit.js.map +1 -1
- package/dist/plugins/requestLogger.d.ts.map +1 -1
- package/dist/repositories/apiKey.d.ts.map +1 -1
- package/dist/repositories/application.d.ts.map +1 -1
- package/dist/repositories/application.js +1 -1
- package/dist/repositories/application.js.map +1 -1
- package/dist/repositories/audit.d.ts.map +1 -1
- package/dist/repositories/index.d.ts +3 -0
- package/dist/repositories/index.d.ts.map +1 -1
- package/dist/repositories/index.js +3 -0
- package/dist/repositories/index.js.map +1 -1
- package/dist/repositories/mfaChallenge.d.ts +23 -0
- package/dist/repositories/mfaChallenge.d.ts.map +1 -0
- package/dist/repositories/mfaChallenge.js +71 -0
- package/dist/repositories/mfaChallenge.js.map +1 -0
- package/dist/repositories/oidcConnection.d.ts +27 -43
- package/dist/repositories/oidcConnection.d.ts.map +1 -1
- package/dist/repositories/oidcConnection.js +15 -6
- package/dist/repositories/oidcConnection.js.map +1 -1
- package/dist/repositories/organization.d.ts +9 -9
- package/dist/repositories/organization.d.ts.map +1 -1
- package/dist/repositories/organization.js +91 -37
- package/dist/repositories/organization.js.map +1 -1
- package/dist/repositories/permission.d.ts.map +1 -1
- package/dist/repositories/permission.js +27 -5
- package/dist/repositories/permission.js.map +1 -1
- package/dist/repositories/samlConnection.d.ts +28 -28
- package/dist/repositories/samlConnection.d.ts.map +1 -1
- package/dist/repositories/samlConnection.js +12 -4
- package/dist/repositories/samlConnection.js.map +1 -1
- package/dist/repositories/scimConnection.d.ts +38 -0
- package/dist/repositories/scimConnection.d.ts.map +1 -0
- package/dist/repositories/scimConnection.js +123 -0
- package/dist/repositories/scimConnection.js.map +1 -0
- package/dist/repositories/scimGroup.d.ts +36 -0
- package/dist/repositories/scimGroup.d.ts.map +1 -0
- package/dist/repositories/scimGroup.js +113 -0
- package/dist/repositories/scimGroup.js.map +1 -0
- package/dist/repositories/session.d.ts +23 -13
- package/dist/repositories/session.d.ts.map +1 -1
- package/dist/repositories/session.js +13 -1
- package/dist/repositories/session.js.map +1 -1
- package/dist/repositories/types.d.ts +112 -5
- package/dist/repositories/types.d.ts.map +1 -1
- package/dist/repositories/types.js +7 -1
- package/dist/repositories/types.js.map +1 -1
- package/dist/repositories/user.d.ts +23 -1
- package/dist/repositories/user.d.ts.map +1 -1
- package/dist/repositories/user.js +180 -4
- package/dist/repositories/user.js.map +1 -1
- package/dist/routes/admin/billing.js +4 -4
- package/dist/routes/admin/billing.js.map +1 -1
- package/dist/routes/admin/helpers.d.ts +16 -20
- package/dist/routes/admin/helpers.d.ts.map +1 -1
- package/dist/routes/admin/helpers.js +53 -10
- package/dist/routes/admin/helpers.js.map +1 -1
- package/dist/routes/admin/organizations.d.ts.map +1 -1
- package/dist/routes/admin/organizations.js +76 -69
- package/dist/routes/admin/organizations.js.map +1 -1
- package/dist/routes/admin/permissions.d.ts.map +1 -1
- package/dist/routes/admin/permissions.js +48 -14
- package/dist/routes/admin/permissions.js.map +1 -1
- package/dist/routes/admin/platform.d.ts.map +1 -1
- package/dist/routes/admin/platform.js +86 -35
- package/dist/routes/admin/platform.js.map +1 -1
- package/dist/routes/admin/sso.d.ts.map +1 -1
- package/dist/routes/admin/sso.js +143 -12
- package/dist/routes/admin/sso.js.map +1 -1
- package/dist/routes/admin/webhooks.js +8 -8
- package/dist/routes/admin/webhooks.js.map +1 -1
- package/dist/routes/apiKeys.d.ts.map +1 -1
- package/dist/routes/apiKeys.js +23 -5
- package/dist/routes/apiKeys.js.map +1 -1
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +112 -22
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/authz.d.ts.map +1 -1
- package/dist/routes/authz.js +16 -4
- package/dist/routes/authz.js.map +1 -1
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +16 -14
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/federation.d.ts.map +1 -1
- package/dist/routes/federation.js +17 -3
- package/dist/routes/federation.js.map +1 -1
- package/dist/routes/magicLinks.d.ts.map +1 -1
- package/dist/routes/magicLinks.js +15 -3
- package/dist/routes/magicLinks.js.map +1 -1
- package/dist/routes/oauth.d.ts.map +1 -1
- package/dist/routes/oauth.js +22 -3
- package/dist/routes/oauth.js.map +1 -1
- package/dist/routes/oauth2.d.ts.map +1 -1
- package/dist/routes/oauth2.js +104 -11
- package/dist/routes/oauth2.js.map +1 -1
- package/dist/routes/oidcEnterprise.d.ts.map +1 -1
- package/dist/routes/oidcEnterprise.js +67 -21
- package/dist/routes/oidcEnterprise.js.map +1 -1
- package/dist/routes/password.d.ts.map +1 -1
- package/dist/routes/password.js.map +1 -1
- package/dist/routes/profile.js +4 -4
- package/dist/routes/profile.js.map +1 -1
- package/dist/routes/saml.d.ts +9 -0
- package/dist/routes/saml.d.ts.map +1 -1
- package/dist/routes/saml.js +187 -11
- package/dist/routes/saml.js.map +1 -1
- package/dist/routes/scim.d.ts +13 -0
- package/dist/routes/scim.d.ts.map +1 -1
- package/dist/routes/scim.js +885 -110
- package/dist/routes/scim.js.map +1 -1
- package/dist/routes/sdk.d.ts.map +1 -1
- package/dist/routes/sdk.js +24 -8
- package/dist/routes/sdk.js.map +1 -1
- package/dist/routes/serviceAccounts.d.ts.map +1 -1
- package/dist/routes/serviceAccounts.js +2 -1
- package/dist/routes/serviceAccounts.js.map +1 -1
- package/dist/routes/setup.d.ts.map +1 -1
- package/dist/routes/setup.js +15 -16
- package/dist/routes/setup.js.map +1 -1
- package/dist/routes/smsOtp.js +1 -1
- package/dist/routes/smsOtp.js.map +1 -1
- package/dist/routes/totp.d.ts.map +1 -1
- package/dist/routes/totp.js +113 -23
- package/dist/routes/totp.js.map +1 -1
- package/dist/routes/webauthn.d.ts.map +1 -1
- package/dist/routes/webauthn.js +44 -8
- package/dist/routes/webauthn.js.map +1 -1
- package/dist/routes/workflows.d.ts.map +1 -1
- package/dist/routes/workflows.js +58 -25
- package/dist/routes/workflows.js.map +1 -1
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +141 -40
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/types.d.ts +60 -29
- package/dist/sdk/types.d.ts.map +1 -1
- package/dist/services/application/authentication.d.ts +39 -1
- package/dist/services/application/authentication.d.ts.map +1 -1
- package/dist/services/application/authentication.js +43 -1
- package/dist/services/application/authentication.js.map +1 -1
- package/dist/services/application/identity.d.ts +10 -7
- package/dist/services/application/identity.d.ts.map +1 -1
- package/dist/services/application/identity.js +13 -10
- package/dist/services/application/identity.js.map +1 -1
- package/dist/services/application/organization.d.ts +11 -7
- package/dist/services/application/organization.d.ts.map +1 -1
- package/dist/services/application/organization.js +160 -12
- package/dist/services/application/organization.js.map +1 -1
- package/dist/services/applications.js +2 -2
- package/dist/services/applications.js.map +1 -1
- package/dist/services/audit.d.ts +1 -0
- package/dist/services/audit.d.ts.map +1 -1
- package/dist/services/audit.js +13 -0
- package/dist/services/audit.js.map +1 -1
- package/dist/services/cache.d.ts.map +1 -1
- package/dist/services/configuration/profiles.d.ts +4 -0
- package/dist/services/configuration/profiles.d.ts.map +1 -1
- package/dist/services/configuration/profiles.js +50 -0
- package/dist/services/configuration/profiles.js.map +1 -1
- package/dist/services/configuration.d.ts.map +1 -1
- package/dist/services/configuration.js.map +1 -1
- package/dist/services/connectors/google.d.ts.map +1 -1
- package/dist/services/connectors/google.js +3 -2
- package/dist/services/connectors/google.js.map +1 -1
- package/dist/services/connectors/oidc.d.ts.map +1 -1
- package/dist/services/connectors/oidc.js +6 -3
- package/dist/services/connectors/oidc.js.map +1 -1
- package/dist/services/connectors/zitadel.d.ts.map +1 -1
- package/dist/services/connectors/zitadel.js +4 -3
- package/dist/services/connectors/zitadel.js.map +1 -1
- package/dist/services/domain/authentication.d.ts +43 -4
- package/dist/services/domain/authentication.d.ts.map +1 -1
- package/dist/services/domain/authentication.js +82 -20
- package/dist/services/domain/authentication.js.map +1 -1
- package/dist/services/domain/authorization.d.ts +11 -0
- package/dist/services/domain/authorization.d.ts.map +1 -1
- package/dist/services/domain/authorization.js +36 -1
- package/dist/services/domain/authorization.js.map +1 -1
- package/dist/services/domain/identity.d.ts +21 -9
- package/dist/services/domain/identity.d.ts.map +1 -1
- package/dist/services/domain/identity.js +187 -10
- package/dist/services/domain/identity.js.map +1 -1
- package/dist/services/domain/organization.d.ts +6 -9
- package/dist/services/domain/organization.d.ts.map +1 -1
- package/dist/services/domain/organization.js +48 -30
- package/dist/services/domain/organization.js.map +1 -1
- package/dist/services/emailVerification.d.ts +2 -2
- package/dist/services/enterpriseSso.d.ts +13 -6
- package/dist/services/enterpriseSso.d.ts.map +1 -1
- package/dist/services/enterpriseSso.js +75 -6
- package/dist/services/enterpriseSso.js.map +1 -1
- package/dist/services/events/subscribers/auditLog.js +1 -1
- package/dist/services/events/subscribers/auditLog.js.map +1 -1
- package/dist/services/events/types.d.ts +7 -1
- package/dist/services/events/types.d.ts.map +1 -1
- package/dist/services/events/types.js.map +1 -1
- package/dist/services/events/validate.d.ts.map +1 -1
- package/dist/services/events/validate.js +27 -0
- package/dist/services/events/validate.js.map +1 -1
- package/dist/services/features.d.ts.map +1 -1
- package/dist/services/features.js.map +1 -1
- package/dist/services/federation.d.ts +6 -1
- package/dist/services/federation.d.ts.map +1 -1
- package/dist/services/federation.js +31 -4
- package/dist/services/federation.js.map +1 -1
- package/dist/services/ipControls.js +2 -2
- package/dist/services/ipControls.js.map +1 -1
- package/dist/services/magicLinks.d.ts +2 -2
- package/dist/services/mfa.d.ts +53 -0
- package/dist/services/mfa.d.ts.map +1 -0
- package/dist/services/mfa.js +157 -0
- package/dist/services/mfa.js.map +1 -0
- package/dist/services/oauth2.d.ts +16 -12
- package/dist/services/oauth2.d.ts.map +1 -1
- package/dist/services/oauth2.js +22 -13
- package/dist/services/oauth2.js.map +1 -1
- package/dist/services/oidcSecretFormat.d.ts +3 -0
- package/dist/services/oidcSecretFormat.d.ts.map +1 -0
- package/dist/services/oidcSecretFormat.js +5 -0
- package/dist/services/oidcSecretFormat.js.map +1 -0
- package/dist/services/organizations.d.ts +4 -16
- package/dist/services/organizations.d.ts.map +1 -1
- package/dist/services/organizations.js +0 -62
- package/dist/services/organizations.js.map +1 -1
- package/dist/services/permissions.d.ts.map +1 -1
- package/dist/services/permissions.js +9 -1
- package/dist/services/permissions.js.map +1 -1
- package/dist/services/plugins/registry.d.ts.map +1 -1
- package/dist/services/plugins/registry.js.map +1 -1
- package/dist/services/plugins/types.d.ts.map +1 -1
- package/dist/services/queue/bullmq.d.ts.map +1 -1
- package/dist/services/queue/inProcess.d.ts.map +1 -1
- package/dist/services/redis.d.ts +1 -1
- package/dist/services/redis.d.ts.map +1 -1
- package/dist/services/scimCredentials.d.ts +46 -0
- package/dist/services/scimCredentials.d.ts.map +1 -0
- package/dist/services/scimCredentials.js +123 -0
- package/dist/services/scimCredentials.js.map +1 -0
- package/dist/services/scimLegacyMigration.d.ts +12 -0
- package/dist/services/scimLegacyMigration.d.ts.map +1 -0
- package/dist/services/scimLegacyMigration.js +44 -0
- package/dist/services/scimLegacyMigration.js.map +1 -0
- package/dist/services/secrets/awsKms.d.ts +2 -2
- package/dist/services/secrets/awsKms.d.ts.map +1 -1
- package/dist/services/secrets/awsKms.js +3 -5
- package/dist/services/secrets/awsKms.js.map +1 -1
- package/dist/services/secrets/azureKeyVault.d.ts.map +1 -1
- package/dist/services/secrets/database.d.ts.map +1 -1
- package/dist/services/secrets/database.js.map +1 -1
- package/dist/services/secrets/environment.d.ts.map +1 -1
- package/dist/services/secrets/environment.js.map +1 -1
- package/dist/services/secrets/index.d.ts.map +1 -1
- package/dist/services/secrets/password.d.ts.map +1 -1
- package/dist/services/secrets/password.js +0 -4
- package/dist/services/secrets/password.js.map +1 -1
- package/dist/services/secrets/provider.d.ts +2 -3
- package/dist/services/secrets/provider.d.ts.map +1 -1
- package/dist/services/secrets/vault.d.ts.map +1 -1
- package/dist/services/setup/configWriter.d.ts.map +1 -1
- package/dist/services/setup/configWriter.js.map +1 -1
- package/dist/services/ssoEndpointPolicy.d.ts +8 -0
- package/dist/services/ssoEndpointPolicy.d.ts.map +1 -0
- package/dist/services/ssoEndpointPolicy.js +136 -0
- package/dist/services/ssoEndpointPolicy.js.map +1 -0
- package/dist/services/stepUp.d.ts +35 -0
- package/dist/services/stepUp.d.ts.map +1 -0
- package/dist/services/stepUp.js +65 -0
- package/dist/services/stepUp.js.map +1 -0
- package/dist/services/tokens.d.ts +37 -11
- package/dist/services/tokens.d.ts.map +1 -1
- package/dist/services/tokens.js +75 -14
- package/dist/services/tokens.js.map +1 -1
- package/dist/services/totp.d.ts +46 -0
- package/dist/services/totp.d.ts.map +1 -1
- package/dist/services/totp.js +178 -41
- package/dist/services/totp.js.map +1 -1
- package/dist/services/users.d.ts +20 -12
- package/dist/services/users.d.ts.map +1 -1
- package/dist/services/users.js +24 -51
- package/dist/services/users.js.map +1 -1
- package/dist/services/webauthn.d.ts +8 -4
- package/dist/services/webauthn.d.ts.map +1 -1
- package/dist/services/webauthn.js +4 -4
- package/dist/services/webauthn.js.map +1 -1
- package/dist/services/webhooks.d.ts +20 -20
- package/dist/services/workflows/engine.d.ts +4 -2
- package/dist/services/workflows/engine.d.ts.map +1 -1
- package/dist/services/workflows/engine.js +181 -12
- package/dist/services/workflows/engine.js.map +1 -1
- package/dist/services/workflows/steps.d.ts +2 -0
- package/dist/services/workflows/steps.d.ts.map +1 -1
- package/dist/services/workflows/steps.js +8 -75
- package/dist/services/workflows/steps.js.map +1 -1
- package/dist/setup-server.js.map +1 -1
- package/dist/types.d.ts +33 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +26 -2
- package/dist/types.js.map +1 -1
- package/package.json +26 -3
- package/dist/tests/errors.test.d.ts +0 -2
- package/dist/tests/errors.test.d.ts.map +0 -1
- package/dist/tests/errors.test.js +0 -64
- package/dist/tests/errors.test.js.map +0 -1
- package/dist/tests/events.test.d.ts +0 -2
- package/dist/tests/events.test.d.ts.map +0 -1
- package/dist/tests/events.test.js +0 -45
- package/dist/tests/events.test.js.map +0 -1
- package/dist/tests/featureFlags.test.d.ts +0 -2
- package/dist/tests/featureFlags.test.d.ts.map +0 -1
- package/dist/tests/featureFlags.test.js +0 -24
- package/dist/tests/featureFlags.test.js.map +0 -1
- package/dist/tests/integration/queue.test.d.ts +0 -2
- package/dist/tests/integration/queue.test.d.ts.map +0 -1
- package/dist/tests/integration/queue.test.js +0 -49
- package/dist/tests/integration/queue.test.js.map +0 -1
- package/dist/tests/plugins.test.d.ts +0 -2
- package/dist/tests/plugins.test.d.ts.map +0 -1
- package/dist/tests/plugins.test.js +0 -56
- package/dist/tests/plugins.test.js.map +0 -1
- package/dist/tests/result.test.d.ts +0 -2
- package/dist/tests/result.test.d.ts.map +0 -1
- package/dist/tests/result.test.js +0 -46
- package/dist/tests/result.test.js.map +0 -1
- package/dist/tests/setup/configWriter.test.d.ts +0 -2
- package/dist/tests/setup/configWriter.test.d.ts.map +0 -1
- package/dist/tests/setup/configWriter.test.js +0 -55
- package/dist/tests/setup/configWriter.test.js.map +0 -1
- package/dist/tests/setup/validation.test.d.ts +0 -2
- package/dist/tests/setup/validation.test.d.ts.map +0 -1
- package/dist/tests/setup/validation.test.js +0 -26
- package/dist/tests/setup/validation.test.js.map +0 -1
- package/dist/tests/smoke.test.d.ts +0 -2
- package/dist/tests/smoke.test.d.ts.map +0 -1
- package/dist/tests/smoke.test.js +0 -124
- package/dist/tests/smoke.test.js.map +0 -1
- package/src/cli.ts +0 -172
- package/src/config.ts +0 -143
- package/src/container.ts +0 -48
- package/src/db/index.ts +0 -53
- package/src/db/migrations/0000_skinny_ben_parker.sql +0 -553
- package/src/db/migrations/0001_brief_joseph.sql +0 -10
- package/src/db/migrations/0002_add_account_lockout.sql +0 -3
- package/src/db/migrations/0003_steep_rachel_grey.sql +0 -1
- package/src/db/migrations/0004_clever_bill_hollister.sql +0 -20
- package/src/db/migrations/0005_steep_the_call.sql +0 -2
- package/src/db/migrations/0006_ambitious_boomer.sql +0 -17
- package/src/db/migrations/0007_greedy_vindicator.sql +0 -40
- package/src/db/migrations/meta/0000_snapshot.json +0 -2964
- package/src/db/migrations/meta/0001_snapshot.json +0 -3031
- package/src/db/migrations/meta/0003_snapshot.json +0 -3051
- package/src/db/migrations/meta/_journal.json +0 -62
- package/src/db/schema.ts +0 -676
- package/src/db/seed.ts +0 -146
- package/src/di.ts +0 -81
- package/src/index.ts +0 -326
- package/src/lib/errors.ts +0 -139
- package/src/lib/result.ts +0 -44
- package/src/lib/webhookSignature.ts +0 -41
- package/src/plugins/appContext.ts +0 -76
- package/src/plugins/audit.ts +0 -42
- package/src/plugins/auth.ts +0 -230
- package/src/plugins/metrics.ts +0 -41
- package/src/plugins/mtls.ts +0 -94
- package/src/plugins/permissions.ts +0 -29
- package/src/plugins/rateLimit.ts +0 -133
- package/src/plugins/requestLogger.ts +0 -25
- package/src/plugins/tracing.ts +0 -22
- package/src/repositories/apiKey.ts +0 -158
- package/src/repositories/application.ts +0 -70
- package/src/repositories/audit.ts +0 -32
- package/src/repositories/index.ts +0 -9
- package/src/repositories/oidcConnection.ts +0 -111
- package/src/repositories/organization.ts +0 -167
- package/src/repositories/permission.ts +0 -153
- package/src/repositories/samlConnection.ts +0 -96
- package/src/repositories/session.ts +0 -86
- package/src/repositories/types.ts +0 -134
- package/src/repositories/user.ts +0 -161
- package/src/routes/admin/billing.ts +0 -48
- package/src/routes/admin/helpers.ts +0 -50
- package/src/routes/admin/index.ts +0 -16
- package/src/routes/admin/organizations.ts +0 -299
- package/src/routes/admin/permissions.ts +0 -80
- package/src/routes/admin/platform.ts +0 -335
- package/src/routes/admin/sso.ts +0 -138
- package/src/routes/admin/webhooks.ts +0 -73
- package/src/routes/admin.ts +0 -1
- package/src/routes/apiKeys.ts +0 -60
- package/src/routes/auth.ts +0 -214
- package/src/routes/authz.ts +0 -38
- package/src/routes/config.ts +0 -67
- package/src/routes/emailVerification.ts +0 -73
- package/src/routes/federation.ts +0 -156
- package/src/routes/helpers.ts +0 -17
- package/src/routes/magicLinks.ts +0 -107
- package/src/routes/oauth.ts +0 -167
- package/src/routes/oauth2.ts +0 -284
- package/src/routes/oidcEnterprise.ts +0 -166
- package/src/routes/password.ts +0 -90
- package/src/routes/profile.ts +0 -44
- package/src/routes/saml.ts +0 -209
- package/src/routes/scim.ts +0 -199
- package/src/routes/sdk.ts +0 -141
- package/src/routes/serviceAccounts.ts +0 -124
- package/src/routes/sessions.ts +0 -62
- package/src/routes/setup.ts +0 -315
- package/src/routes/smsOtp.ts +0 -67
- package/src/routes/totp.ts +0 -122
- package/src/routes/webauthn.ts +0 -147
- package/src/routes/workflows.ts +0 -157
- package/src/sdk/index.ts +0 -152
- package/src/sdk/types.ts +0 -54
- package/src/services/anomalyDetection.ts +0 -73
- package/src/services/application/authentication.ts +0 -75
- package/src/services/application/identity.ts +0 -56
- package/src/services/application/index.ts +0 -3
- package/src/services/application/organization.ts +0 -77
- package/src/services/applications.ts +0 -89
- package/src/services/audit.ts +0 -41
- package/src/services/auditExport.ts +0 -59
- package/src/services/billing.ts +0 -87
- package/src/services/cache.ts +0 -131
- package/src/services/configuration/profiles.ts +0 -115
- package/src/services/configuration.ts +0 -120
- package/src/services/connectors/google.ts +0 -92
- package/src/services/connectors/oidc.ts +0 -111
- package/src/services/connectors/registry.ts +0 -124
- package/src/services/connectors/types.ts +0 -38
- package/src/services/connectors/zitadel.ts +0 -77
- package/src/services/devices.ts +0 -76
- package/src/services/domain/authentication.ts +0 -279
- package/src/services/domain/authorization.ts +0 -49
- package/src/services/domain/identity.ts +0 -108
- package/src/services/domain/index.ts +0 -4
- package/src/services/domain/organization.ts +0 -114
- package/src/services/email.ts +0 -167
- package/src/services/emailVerification.ts +0 -75
- package/src/services/enterpriseSso.ts +0 -58
- package/src/services/events/bus.ts +0 -43
- package/src/services/events/subscribers/anomaly.ts +0 -13
- package/src/services/events/subscribers/auditLog.ts +0 -21
- package/src/services/events/subscribers/webhook.ts +0 -39
- package/src/services/events/subscribers/webhookDispatch.ts +0 -14
- package/src/services/events/types.ts +0 -106
- package/src/services/events/validate.ts +0 -118
- package/src/services/featureFlags.ts +0 -90
- package/src/services/features.ts +0 -22
- package/src/services/federation.ts +0 -30
- package/src/services/hibp.ts +0 -28
- package/src/services/ipControls.ts +0 -99
- package/src/services/magicLinks.ts +0 -51
- package/src/services/oauth2.ts +0 -216
- package/src/services/organizations.ts +0 -171
- package/src/services/permissions.ts +0 -146
- package/src/services/plugins/registry.ts +0 -242
- package/src/services/plugins/types.ts +0 -98
- package/src/services/queue/bullmq.ts +0 -104
- package/src/services/queue/inProcess.ts +0 -75
- package/src/services/queue/index.ts +0 -19
- package/src/services/queue/types.ts +0 -26
- package/src/services/redis.ts +0 -16
- package/src/services/secrets/awsKms.ts +0 -97
- package/src/services/secrets/azureKeyVault.ts +0 -171
- package/src/services/secrets/database.ts +0 -166
- package/src/services/secrets/environment.ts +0 -117
- package/src/services/secrets/index.ts +0 -50
- package/src/services/secrets/password.ts +0 -73
- package/src/services/secrets/provider.ts +0 -36
- package/src/services/secrets/vault.ts +0 -149
- package/src/services/secrets.ts +0 -2
- package/src/services/serviceAccounts.ts +0 -74
- package/src/services/setup/configWriter.ts +0 -200
- package/src/services/setup/diagnostics.ts +0 -76
- package/src/services/setup/token.ts +0 -42
- package/src/services/setup/types.ts +0 -40
- package/src/services/setup/validation.ts +0 -205
- package/src/services/sms.ts +0 -81
- package/src/services/smsOtp.ts +0 -74
- package/src/services/tokens.ts +0 -287
- package/src/services/totp.ts +0 -113
- package/src/services/users.ts +0 -239
- package/src/services/webauthn.ts +0 -193
- package/src/services/webhooks.ts +0 -190
- package/src/services/workflows/engine.ts +0 -125
- package/src/services/workflows/steps.ts +0 -129
- package/src/services/zitadel.ts +0 -277
- package/src/setup-server.ts +0 -71
- package/src/tests/errors.test.ts +0 -74
- package/src/tests/events.test.ts +0 -52
- package/src/tests/featureFlags.test.ts +0 -26
- package/src/tests/integration/queue.test.ts +0 -54
- package/src/tests/plugins.test.ts +0 -73
- package/src/tests/result.test.ts +0 -52
- package/src/tests/setup/configWriter.test.ts +0 -69
- package/src/tests/setup/validation.test.ts +0 -29
- package/src/tests/smoke.test.ts +0 -136
- package/src/types.ts +0 -70
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
import { eq, and, gt, isNull } from "drizzle-orm";
|
|
3
|
-
import { config, isZitadelConfigured } from "../../config.js";
|
|
4
|
-
import { db } from "../../db/index.js";
|
|
5
|
-
import { users, passwordResetTokens, type User } from "../../db/schema.js";
|
|
6
|
-
import { createHumanUser, verifyPassword as verifyZitadelPassword } from "../zitadel.js";
|
|
7
|
-
import { createTokenSet, rotateRefreshToken, revokeRefreshToken, type TokenSet } from "../tokens.js";
|
|
8
|
-
import { isPasswordBreached } from "../hibp.js";
|
|
9
|
-
import { recordFailedLogin, isFailedLoginAnomaly } from "../anomalyDetection.js";
|
|
10
|
-
import { emit } from "../events/bus.js";
|
|
11
|
-
import type { UserRepository, ApplicationRepository } from "../../repositories/types.js";
|
|
12
|
-
import { ok, err, type Result } from "../../lib/result.js";
|
|
13
|
-
import { hashPassword, verifyPassword } from "../secrets/index.js";
|
|
14
|
-
|
|
15
|
-
export interface AuthContext {
|
|
16
|
-
app?: { id: string; clientId: string; orgId: string };
|
|
17
|
-
org?: { id: string };
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface RegisterInput {
|
|
21
|
-
username: string;
|
|
22
|
-
email: string;
|
|
23
|
-
password: string;
|
|
24
|
-
name?: string;
|
|
25
|
-
clientId?: string;
|
|
26
|
-
metadata?: Record<string, unknown>;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface LoginInput {
|
|
30
|
-
email: string;
|
|
31
|
-
password: string;
|
|
32
|
-
clientId?: string;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface TokenResponse {
|
|
36
|
-
user: User;
|
|
37
|
-
tokens: TokenSet;
|
|
38
|
-
context: AuthContext;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export class AuthenticationDomainService {
|
|
42
|
-
constructor(
|
|
43
|
-
private readonly users: UserRepository,
|
|
44
|
-
private readonly applications: ApplicationRepository
|
|
45
|
-
) {}
|
|
46
|
-
|
|
47
|
-
private async loadAppContext(clientId?: string): Promise<AuthContext> {
|
|
48
|
-
if (!clientId) return {};
|
|
49
|
-
const app = await this.applications.findByClientId(clientId);
|
|
50
|
-
if (!app) return {};
|
|
51
|
-
return {
|
|
52
|
-
app: { id: app.id, clientId: app.clientId, orgId: app.orgId },
|
|
53
|
-
org: { id: app.orgId },
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async register(input: RegisterInput): Promise<Result<TokenResponse>> {
|
|
58
|
-
if (config.HIBP_CHECK_ENABLED) {
|
|
59
|
-
const breached = await isPasswordBreached(input.password);
|
|
60
|
-
if (breached) {
|
|
61
|
-
return err({ code: "BREACHED_PASSWORD", message: "This password has appeared in a data breach.", statusCode: 400 });
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const existing = await this.users.findByEmail(input.email);
|
|
66
|
-
if (existing) {
|
|
67
|
-
return err({ code: "EMAIL_EXISTS", message: "An account with this email already exists.", statusCode: 409 });
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const passwordHash = await hashPassword(input.password);
|
|
71
|
-
const username = await this.users.ensureUniqueUsername(
|
|
72
|
-
input.username.toLowerCase().trim().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32)
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
let zitadelUserId: string | undefined;
|
|
76
|
-
if (isZitadelConfigured()) {
|
|
77
|
-
try {
|
|
78
|
-
zitadelUserId = await createHumanUser({
|
|
79
|
-
username: input.username,
|
|
80
|
-
email: input.email,
|
|
81
|
-
name: input.name || input.username,
|
|
82
|
-
password: input.password,
|
|
83
|
-
});
|
|
84
|
-
} catch (err) {
|
|
85
|
-
console.warn("Zitadel user mirror failed; continuing with local user", err);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const user = await this.users.create({
|
|
90
|
-
email: input.email,
|
|
91
|
-
username,
|
|
92
|
-
name: input.name || input.username,
|
|
93
|
-
passwordHash,
|
|
94
|
-
provider: "password",
|
|
95
|
-
emailVerified: !config.EMAIL_VERIFICATION_REQUIRED,
|
|
96
|
-
zitadelUserId,
|
|
97
|
-
metadata: input.metadata,
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
if (config.EMAIL_VERIFICATION_REQUIRED) {
|
|
101
|
-
try {
|
|
102
|
-
const { sendVerificationEmail } = await import("../emailVerification.js");
|
|
103
|
-
sendVerificationEmail(user).catch((err: unknown) => {
|
|
104
|
-
console.error("[auth] failed to send verification email:", err);
|
|
105
|
-
});
|
|
106
|
-
} catch {
|
|
107
|
-
// emailVerification module may not be available in all configurations
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const context = await this.loadAppContext(input.clientId);
|
|
112
|
-
const tokens = await createTokenSet(user, undefined, undefined, {
|
|
113
|
-
appId: context.app?.id,
|
|
114
|
-
orgId: context.org?.id,
|
|
115
|
-
clientId: context.app?.clientId,
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
await emit({
|
|
119
|
-
type: "user_registered",
|
|
120
|
-
payload: {
|
|
121
|
-
provider: "password",
|
|
122
|
-
zitadelUserId,
|
|
123
|
-
userId: user.id,
|
|
124
|
-
username: user.username,
|
|
125
|
-
email: user.email,
|
|
126
|
-
client_id: input.clientId,
|
|
127
|
-
appId: context.app?.id,
|
|
128
|
-
orgId: context.org?.id,
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
return ok({ user, tokens, context });
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
async login(input: LoginInput): Promise<Result<TokenResponse>> {
|
|
136
|
-
const user = await this.users.findByEmail(input.email);
|
|
137
|
-
|
|
138
|
-
if (!user) {
|
|
139
|
-
if (isZitadelConfigured()) {
|
|
140
|
-
await verifyZitadelPassword(input.email, input.password).catch(() => {});
|
|
141
|
-
}
|
|
142
|
-
await recordFailedLogin(input.email);
|
|
143
|
-
await emit({ type: "user_login_failed", payload: { reason: "unknown_user" } });
|
|
144
|
-
if (await isFailedLoginAnomaly(input.email)) {
|
|
145
|
-
return err({ code: "TOO_MANY_ATTEMPTS", message: "Too many failed attempts. Please try again later.", statusCode: 429 });
|
|
146
|
-
}
|
|
147
|
-
return err({ code: "INVALID_CREDENTIALS", message: "Invalid email or password.", statusCode: 401 });
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (user.lockedUntil && user.lockedUntil > new Date()) {
|
|
151
|
-
await emit({ type: "user_login_failed", payload: { reason: "account_locked", userId: user.id } });
|
|
152
|
-
return err({ code: "ACCOUNT_LOCKED", message: "Account is temporarily locked due to too many failed attempts. Try again later.", statusCode: 403 });
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
let valid = false;
|
|
156
|
-
if (user.passwordHash) {
|
|
157
|
-
valid = await verifyPassword(input.password, user.passwordHash);
|
|
158
|
-
} else if (user.provider === "zitadel" && isZitadelConfigured()) {
|
|
159
|
-
valid = await verifyZitadelPassword(input.email, input.password);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (!valid) {
|
|
163
|
-
const updated = await this.users.recordFailedLogin(user.id);
|
|
164
|
-
await emit({ type: "user_login_failed", payload: { reason: "invalid_password", userId: user.id } });
|
|
165
|
-
|
|
166
|
-
const attempts = updated?.failedLoginAttempts ?? 0;
|
|
167
|
-
if (attempts >= config.ACCOUNT_LOCKOUT_THRESHOLD) {
|
|
168
|
-
const lockedUntil = new Date(Date.now() + config.ACCOUNT_LOCKOUT_DURATION_SECONDS * 1000);
|
|
169
|
-
await this.users.lockAccount(user.id, lockedUntil);
|
|
170
|
-
return err({ code: "ACCOUNT_LOCKED", message: "Account locked due to too many failed attempts. Try again later.", statusCode: 403 });
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if (await isFailedLoginAnomaly(user.id)) {
|
|
174
|
-
return err({ code: "TOO_MANY_ATTEMPTS", message: "Too many failed attempts. Please try again later.", statusCode: 429 });
|
|
175
|
-
}
|
|
176
|
-
return err({ code: "INVALID_CREDENTIALS", message: "Invalid email or password.", statusCode: 401 });
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
await this.users.resetFailedLogins(user.id);
|
|
180
|
-
await this.users.updateLastSeen(user.id);
|
|
181
|
-
const context = await this.loadAppContext(input.clientId);
|
|
182
|
-
const tokens = await createTokenSet(user, undefined, undefined, {
|
|
183
|
-
appId: context.app?.id,
|
|
184
|
-
orgId: context.org?.id,
|
|
185
|
-
clientId: context.app?.clientId,
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
await emit({
|
|
189
|
-
type: "user_login",
|
|
190
|
-
payload: { provider: user.provider, userId: user.id, appId: context.app?.id, orgId: context.org?.id },
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
return ok({ user, tokens, context });
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
async refresh(refreshToken: string, clientId?: string): Promise<Result<{ tokens: TokenSet; userId?: string }>> {
|
|
197
|
-
const tokens = await rotateRefreshToken(refreshToken, undefined, undefined);
|
|
198
|
-
if (!tokens) {
|
|
199
|
-
await emit({ type: "token_refresh_failed", payload: { reason: "invalid_refresh_token" } });
|
|
200
|
-
return err({ code: "INVALID_REFRESH_TOKEN", message: "Invalid or expired session.", statusCode: 401 });
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
await emit({ type: "token_refresh", payload: {} });
|
|
204
|
-
return ok({ tokens, userId: undefined });
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
async logout(refreshToken?: string): Promise<Result<void>> {
|
|
208
|
-
if (refreshToken) {
|
|
209
|
-
await revokeRefreshToken(refreshToken);
|
|
210
|
-
}
|
|
211
|
-
return ok(undefined);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
async createPasswordResetToken(email: string): Promise<Result<{ token: string; user: User } | null>> {
|
|
215
|
-
const user = await this.users.findByEmail(email);
|
|
216
|
-
if (!user) return ok(null);
|
|
217
|
-
|
|
218
|
-
const token = crypto.randomBytes(48).toString("base64url");
|
|
219
|
-
const tokenHash = crypto.createHash("sha256").update(token).digest("hex");
|
|
220
|
-
const expiresAt = new Date(Date.now() + 60 * 60 * 1000); // 1 hour
|
|
221
|
-
|
|
222
|
-
await db.insert(passwordResetTokens).values({
|
|
223
|
-
userId: user.id,
|
|
224
|
-
tokenHash,
|
|
225
|
-
expiresAt,
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
await emit({ type: "password_reset_requested", payload: { userId: user.id } });
|
|
229
|
-
return ok({ token, user });
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
async resetPasswordWithToken(token: string, newPassword: string): Promise<Result<User>> {
|
|
233
|
-
const tokenHash = crypto.createHash("sha256").update(token).digest("hex");
|
|
234
|
-
const now = new Date();
|
|
235
|
-
|
|
236
|
-
const [record] = await db
|
|
237
|
-
.select()
|
|
238
|
-
.from(passwordResetTokens)
|
|
239
|
-
.where(
|
|
240
|
-
and(
|
|
241
|
-
eq(passwordResetTokens.tokenHash, tokenHash),
|
|
242
|
-
gt(passwordResetTokens.expiresAt, now),
|
|
243
|
-
isNull(passwordResetTokens.usedAt)
|
|
244
|
-
)
|
|
245
|
-
)
|
|
246
|
-
.limit(1);
|
|
247
|
-
|
|
248
|
-
if (!record) {
|
|
249
|
-
return err({ code: "INVALID_TOKEN", message: "Invalid or expired reset token.", statusCode: 400 });
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const user = await this.users.findById(record.userId);
|
|
253
|
-
if (!user) {
|
|
254
|
-
return err({ code: "USER_NOT_FOUND", message: "User not found.", statusCode: 400 });
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (config.HIBP_CHECK_ENABLED) {
|
|
258
|
-
const breached = await isPasswordBreached(newPassword);
|
|
259
|
-
if (breached) {
|
|
260
|
-
return err({ code: "BREACHED_PASSWORD", message: "This password has appeared in a data breach.", statusCode: 400 });
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const passwordHash = await hashPassword(newPassword);
|
|
265
|
-
await db.transaction(async (tx) => {
|
|
266
|
-
await tx
|
|
267
|
-
.update(passwordResetTokens)
|
|
268
|
-
.set({ usedAt: now })
|
|
269
|
-
.where(eq(passwordResetTokens.id, record.id));
|
|
270
|
-
await tx
|
|
271
|
-
.update(users)
|
|
272
|
-
.set({ passwordHash, updatedAt: now })
|
|
273
|
-
.where(eq(users.id, user.id));
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
await emit({ type: "password_reset_completed", payload: { userId: user.id } });
|
|
277
|
-
return ok(user);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { OrgMembership } from "../../db/schema.js";
|
|
2
|
-
import type { OrganizationRepository, PermissionRepository } from "../../repositories/types.js";
|
|
3
|
-
import { ok, err, type Result } from "../../lib/result.js";
|
|
4
|
-
|
|
5
|
-
export interface PermissionInput {
|
|
6
|
-
resource: string;
|
|
7
|
-
action: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export { type PermissionInput as PermissionRequirement };
|
|
11
|
-
export type OrgRole = "owner" | "admin" | "member";
|
|
12
|
-
|
|
13
|
-
export class AuthorizationDomainService {
|
|
14
|
-
constructor(
|
|
15
|
-
private readonly organizations: OrganizationRepository,
|
|
16
|
-
private readonly permissions: PermissionRepository
|
|
17
|
-
) {}
|
|
18
|
-
|
|
19
|
-
async requirePermission(role: string, resource: string, action: string): Promise<Result<void>> {
|
|
20
|
-
const allowed = await this.permissions.hasPermission(role, resource, action);
|
|
21
|
-
if (!allowed) {
|
|
22
|
-
return err({ code: "FORBIDDEN", message: `Missing permission ${resource}:${action}`, statusCode: 403 });
|
|
23
|
-
}
|
|
24
|
-
return ok(undefined);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async hasPermission(role: string, resource: string, action: string): Promise<boolean> {
|
|
28
|
-
return this.permissions.hasPermission(role, resource, action);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async hasAnyPermission(role: string, required: PermissionInput[]): Promise<boolean> {
|
|
32
|
-
return this.permissions.hasAnyPermission(role, required);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async requireOrgRole(userId: string, orgId: string, allowedRoles: OrgRole[]): Promise<Result<OrgMembership>> {
|
|
36
|
-
const membership = await this.organizations.findMembership(orgId, userId);
|
|
37
|
-
if (!membership) {
|
|
38
|
-
return err({ code: "NOT_MEMBER", message: "Not a member of this organization", statusCode: 403 });
|
|
39
|
-
}
|
|
40
|
-
if (!allowedRoles.includes(membership.role as OrgRole)) {
|
|
41
|
-
return err({ code: "INSUFFICIENT_ROLE", message: "Insufficient organization permissions", statusCode: 403 });
|
|
42
|
-
}
|
|
43
|
-
return ok(membership);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async isOrgMember(userId: string, orgId: string): Promise<OrgMembership | undefined> {
|
|
47
|
-
return this.organizations.findMembership(orgId, userId);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import type { User } from "../../db/schema.js";
|
|
2
|
-
import type { UserRepository, IdentityRepository } from "../../repositories/types.js";
|
|
3
|
-
import type { TokenSet } from "../tokens.js";
|
|
4
|
-
import { createTokenSet } from "../tokens.js";
|
|
5
|
-
import { emit } from "../events/bus.js";
|
|
6
|
-
import { getFederationAuthorizeUrl as getFederationAuthorizeUrlService, completeFederationLogin as completeFederationLoginService } from "../federation.js";
|
|
7
|
-
import { ok, err, type Result } from "../../lib/result.js";
|
|
8
|
-
|
|
9
|
-
export class IdentityDomainService {
|
|
10
|
-
constructor(
|
|
11
|
-
private readonly users: UserRepository,
|
|
12
|
-
private readonly identities: IdentityRepository
|
|
13
|
-
) {}
|
|
14
|
-
|
|
15
|
-
async findUser(id: string): Promise<Result<User>> {
|
|
16
|
-
const user = await this.users.findById(id);
|
|
17
|
-
if (!user) return err({ code: "USER_NOT_FOUND", message: "User not found", statusCode: 404 });
|
|
18
|
-
return ok(user);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async findUserByEmail(email: string): Promise<Result<User>> {
|
|
22
|
-
const user = await this.users.findByEmail(email);
|
|
23
|
-
if (!user) return err({ code: "USER_NOT_FOUND", message: "User not found", statusCode: 404 });
|
|
24
|
-
return ok(user);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async upsertInvitedUser(input: { email: string; name?: string; username?: string }): Promise<Result<User>> {
|
|
28
|
-
const existing = await this.users.findByEmail(input.email);
|
|
29
|
-
if (existing) return ok(existing);
|
|
30
|
-
|
|
31
|
-
const baseUsername = input.username || input.email.split("@")[0];
|
|
32
|
-
const username = await this.users.ensureUniqueUsername(
|
|
33
|
-
baseUsername.toLowerCase().trim().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32)
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
const user = await this.users.create({
|
|
37
|
-
email: input.email,
|
|
38
|
-
username,
|
|
39
|
-
name: input.name || username,
|
|
40
|
-
provider: "password",
|
|
41
|
-
emailVerified: false,
|
|
42
|
-
});
|
|
43
|
-
return ok(user);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async updateUserProfile(
|
|
47
|
-
userId: string,
|
|
48
|
-
updates: Partial<{ name: string; username: string; role: string; emailVerified: boolean }>
|
|
49
|
-
): Promise<Result<User>> {
|
|
50
|
-
const updated = await this.users.update(userId, updates);
|
|
51
|
-
if (!updated) return err({ code: "USER_NOT_FOUND", message: "User not found", statusCode: 404 });
|
|
52
|
-
return ok(updated);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async deactivate(userId: string): Promise<Result<void>> {
|
|
56
|
-
await this.users.deactivate(userId);
|
|
57
|
-
return ok(undefined);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async listOrganizationUsers(orgId: string): Promise<User[]> {
|
|
61
|
-
return this.users.listByOrg(orgId);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async touchLastSeen(userId: string): Promise<void> {
|
|
65
|
-
await this.users.updateLastSeen(userId);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async linkUserIdentity(
|
|
69
|
-
userId: string,
|
|
70
|
-
providerId: string,
|
|
71
|
-
providerType: string,
|
|
72
|
-
externalSub: string,
|
|
73
|
-
email?: string
|
|
74
|
-
): Promise<Result<void>> {
|
|
75
|
-
await this.identities.link({ userId, providerId, providerType, externalSub, email });
|
|
76
|
-
return ok(undefined);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async getFederationAuthorizeUrl(provider: string, state: string, redirectUri: string): Promise<Result<{ url: string }>> {
|
|
80
|
-
const url = await getFederationAuthorizeUrlService(provider, state, redirectUri);
|
|
81
|
-
return ok({ url });
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async completeFederationLogin(
|
|
85
|
-
provider: string,
|
|
86
|
-
code: string,
|
|
87
|
-
redirectUri: string
|
|
88
|
-
): Promise<Result<{ user: User; tokens: { accessToken: string; refreshToken: string } }>> {
|
|
89
|
-
const result = await completeFederationLoginService(provider, code, redirectUri);
|
|
90
|
-
await emit({
|
|
91
|
-
type: "federation_login",
|
|
92
|
-
payload: { provider, userId: result.user.id, email: result.user.email },
|
|
93
|
-
});
|
|
94
|
-
return ok(result);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async issueLocalTokenSet(
|
|
98
|
-
user: User,
|
|
99
|
-
opts?: {
|
|
100
|
-
appId?: string;
|
|
101
|
-
orgId?: string;
|
|
102
|
-
clientId?: string;
|
|
103
|
-
deviceFingerprint?: string;
|
|
104
|
-
}
|
|
105
|
-
): Promise<TokenSet> {
|
|
106
|
-
return createTokenSet(user, undefined, undefined, opts, opts?.deviceFingerprint);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import type { Organization, Application, OrgMembership } from "../../db/schema.js";
|
|
2
|
-
import type { OrganizationRepository, ApplicationRepository, UserRepository } from "../../repositories/types.js";
|
|
3
|
-
import { emit } from "../events/bus.js";
|
|
4
|
-
import { ok, err, type Result } from "../../lib/result.js";
|
|
5
|
-
|
|
6
|
-
export type OrgRole = "owner" | "admin" | "member";
|
|
7
|
-
|
|
8
|
-
export class OrganizationDomainService {
|
|
9
|
-
constructor(
|
|
10
|
-
private readonly organizations: OrganizationRepository,
|
|
11
|
-
private readonly applications: ApplicationRepository,
|
|
12
|
-
private readonly users?: UserRepository
|
|
13
|
-
) {}
|
|
14
|
-
|
|
15
|
-
async createOrganization(
|
|
16
|
-
input: { name: string; slug?: string; plan?: string },
|
|
17
|
-
userId?: string
|
|
18
|
-
): Promise<Result<Organization>> {
|
|
19
|
-
const org = await this.organizations.create(input);
|
|
20
|
-
if (userId) {
|
|
21
|
-
await this.organizations.addMembership({ orgId: org.id, userId, role: "owner" });
|
|
22
|
-
}
|
|
23
|
-
return ok(org);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async getOrganization(id: string): Promise<Result<Organization>> {
|
|
27
|
-
const org = await this.organizations.findById(id);
|
|
28
|
-
if (!org) return err({ code: "ORG_NOT_FOUND", message: "Organization not found", statusCode: 404 });
|
|
29
|
-
return ok(org);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async listUserOrganizations(userId: string): Promise<Organization[]> {
|
|
33
|
-
return this.organizations.listByUserId(userId);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async addOrgMembership(input: { orgId: string; userId: string; role: OrgRole }): Promise<Result<OrgMembership>> {
|
|
37
|
-
const membership = await this.organizations.addMembership(input);
|
|
38
|
-
return ok(membership);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async getMembership(orgId: string, userId: string): Promise<Result<OrgMembership>> {
|
|
42
|
-
const membership = await this.organizations.findMembership(orgId, userId);
|
|
43
|
-
if (!membership) return err({ code: "MEMBERSHIP_NOT_FOUND", message: "Membership not found", statusCode: 404 });
|
|
44
|
-
return ok(membership);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async updateMembershipRole(
|
|
48
|
-
orgId: string,
|
|
49
|
-
userId: string,
|
|
50
|
-
role: OrgRole
|
|
51
|
-
): Promise<Result<OrgMembership>> {
|
|
52
|
-
const updated = await this.organizations.updateMembershipRole(orgId, userId, role);
|
|
53
|
-
if (!updated) return err({ code: "MEMBERSHIP_NOT_FOUND", message: "Membership not found", statusCode: 404 });
|
|
54
|
-
return ok(updated);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async removeMembership(orgId: string, userId: string): Promise<Result<boolean>> {
|
|
58
|
-
return ok(await this.organizations.removeMembership(orgId, userId));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async removeOrgMember(orgId: string, userId: string): Promise<Result<{ success: boolean }>> {
|
|
62
|
-
const membership = await this.organizations.findMembership(orgId, userId);
|
|
63
|
-
if (!membership) return err({ code: "MEMBERSHIP_NOT_FOUND", message: "Membership not found", statusCode: 404 });
|
|
64
|
-
|
|
65
|
-
if (membership.role === "owner" && (await this.organizations.countOwners(orgId)) <= 1) {
|
|
66
|
-
return err({ code: "LAST_OWNER", message: "Cannot remove the last owner", statusCode: 400 });
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
await this.organizations.removeMembership(orgId, userId);
|
|
70
|
-
return ok({ success: true });
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async deactivateOrgUser(orgId: string, userId: string): Promise<Result<{ success: boolean }>> {
|
|
74
|
-
const membership = await this.organizations.findMembership(orgId, userId);
|
|
75
|
-
if (!membership) {
|
|
76
|
-
return err({ code: "MEMBERSHIP_NOT_FOUND", message: "User is not a member of this organization", statusCode: 404 });
|
|
77
|
-
}
|
|
78
|
-
if (this.users) {
|
|
79
|
-
await this.users.deactivate(userId);
|
|
80
|
-
}
|
|
81
|
-
await this.organizations.removeMembership(orgId, userId);
|
|
82
|
-
return ok({ success: true });
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async listOrgMembers(orgId: string) {
|
|
86
|
-
return this.organizations.listMembers(orgId);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async createApplication(input: {
|
|
90
|
-
orgId: string;
|
|
91
|
-
name: string;
|
|
92
|
-
redirectUris?: string[];
|
|
93
|
-
allowedOrigins?: string[];
|
|
94
|
-
}): Promise<Result<Application & { clientSecret: string }>> {
|
|
95
|
-
const app = await this.applications.create(input);
|
|
96
|
-
await emit({ type: "application_created", payload: { orgId: input.orgId, appId: app.id } });
|
|
97
|
-
return ok(app);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async listOrganizationApplications(orgId: string): Promise<Application[]> {
|
|
101
|
-
return this.applications.listByOrgId(orgId);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async updateApplication(
|
|
105
|
-
appId: string,
|
|
106
|
-
orgId: string,
|
|
107
|
-
updates: Partial<{ name: string; redirectUris: string[]; allowedOrigins: string[]; allowedIps: string[]; blockedIps: string[]; isActive: boolean; branding: Record<string, unknown> }>
|
|
108
|
-
): Promise<Result<Application>> {
|
|
109
|
-
const updated = await this.applications.update(appId, orgId, updates);
|
|
110
|
-
if (!updated) return err({ code: "APP_NOT_FOUND", message: "Application not found", statusCode: 404 });
|
|
111
|
-
await emit({ type: "application_updated", payload: { orgId, appId: updated.id } });
|
|
112
|
-
return ok(updated);
|
|
113
|
-
}
|
|
114
|
-
}
|