@robelest/convex-auth 0.0.4-preview.18 → 0.0.4-preview.19
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/README.md +6 -3
- package/dist/authorization/index.d.ts +46 -0
- package/dist/authorization/index.d.ts.map +1 -1
- package/dist/authorization/index.js +46 -0
- package/dist/authorization/index.js.map +1 -1
- package/dist/bin.cjs +21 -13
- package/dist/client/core/types.d.ts +20 -0
- package/dist/client/core/types.d.ts.map +1 -0
- package/dist/client/index.d.ts +2 -16
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +67 -565
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +40 -12
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +1306 -1344
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/client/core/types.d.ts +2 -0
- package/dist/component/client/index.d.ts +2 -2
- package/dist/component/model.d.ts +80 -80
- package/dist/component/model.d.ts.map +1 -1
- package/dist/component/model.js +5 -1
- package/dist/component/model.js.map +1 -1
- package/dist/component/providers/credentials.d.ts +3 -2
- package/dist/component/providers/credentials.d.ts.map +1 -1
- package/dist/component/providers/email.d.ts +30 -0
- package/dist/component/providers/email.d.ts.map +1 -1
- package/dist/component/providers/phone.d.ts +28 -0
- package/dist/component/providers/phone.d.ts.map +1 -1
- package/dist/component/public/enterprise/audit.d.ts +73 -0
- package/dist/component/public/enterprise/audit.d.ts.map +1 -0
- package/dist/component/public/enterprise/audit.js +108 -0
- package/dist/component/public/enterprise/audit.js.map +1 -0
- package/dist/component/public/enterprise/core.d.ts +176 -0
- package/dist/component/public/enterprise/core.d.ts.map +1 -0
- package/dist/component/public/enterprise/core.js +292 -0
- package/dist/component/public/enterprise/core.js.map +1 -0
- package/dist/component/public/enterprise/domains.d.ts +174 -0
- package/dist/component/public/enterprise/domains.d.ts.map +1 -0
- package/dist/component/public/enterprise/domains.js +271 -0
- package/dist/component/public/enterprise/domains.js.map +1 -0
- package/dist/component/public/enterprise/scim.d.ts +245 -0
- package/dist/component/public/enterprise/scim.d.ts.map +1 -0
- package/dist/component/public/enterprise/scim.js +344 -0
- package/dist/component/public/enterprise/scim.js.map +1 -0
- package/dist/component/public/enterprise/secrets.d.ts +78 -0
- package/dist/component/public/enterprise/secrets.d.ts.map +1 -0
- package/dist/component/public/enterprise/secrets.js +118 -0
- package/dist/component/public/enterprise/secrets.js.map +1 -0
- package/dist/component/public/enterprise/webhooks.d.ts +211 -0
- package/dist/component/public/enterprise/webhooks.d.ts.map +1 -0
- package/dist/component/public/enterprise/webhooks.js +300 -0
- package/dist/component/public/enterprise/webhooks.js.map +1 -0
- package/dist/component/public/factors/devices.d.ts +157 -0
- package/dist/component/public/factors/devices.d.ts.map +1 -0
- package/dist/component/public/factors/devices.js +216 -0
- package/dist/component/public/factors/devices.js.map +1 -0
- package/dist/component/public/factors/passkeys.d.ts +175 -0
- package/dist/component/public/factors/passkeys.d.ts.map +1 -0
- package/dist/component/public/factors/passkeys.js +238 -0
- package/dist/component/public/factors/passkeys.js.map +1 -0
- package/dist/component/public/factors/totp.d.ts +189 -0
- package/dist/component/public/factors/totp.d.ts.map +1 -0
- package/dist/component/public/factors/totp.js +254 -0
- package/dist/component/public/factors/totp.js.map +1 -0
- package/dist/component/public/groups/core.d.ts +137 -0
- package/dist/component/public/groups/core.d.ts.map +1 -0
- package/dist/component/public/groups/core.js +321 -0
- package/dist/component/public/groups/core.js.map +1 -0
- package/dist/component/public/groups/invites.d.ts +217 -0
- package/dist/component/public/groups/invites.d.ts.map +1 -0
- package/dist/component/public/groups/invites.js +457 -0
- package/dist/component/public/groups/invites.js.map +1 -0
- package/dist/component/public/groups/members.d.ts +204 -0
- package/dist/component/public/groups/members.d.ts.map +1 -0
- package/dist/component/public/groups/members.js +355 -0
- package/dist/component/public/groups/members.js.map +1 -0
- package/dist/component/public/identity/accounts.d.ts +147 -0
- package/dist/component/public/identity/accounts.d.ts.map +1 -0
- package/dist/component/public/identity/accounts.js +200 -0
- package/dist/component/public/identity/accounts.js.map +1 -0
- package/dist/component/public/identity/codes.d.ts +104 -0
- package/dist/component/public/identity/codes.d.ts.map +1 -0
- package/dist/component/public/identity/codes.js +140 -0
- package/dist/component/public/identity/codes.js.map +1 -0
- package/dist/component/public/identity/sessions.d.ts +128 -0
- package/dist/component/public/identity/sessions.d.ts.map +1 -0
- package/dist/component/public/identity/sessions.js +192 -0
- package/dist/component/public/identity/sessions.js.map +1 -0
- package/dist/component/public/identity/tokens.d.ts +169 -0
- package/dist/component/public/identity/tokens.d.ts.map +1 -0
- package/dist/component/public/identity/tokens.js +227 -0
- package/dist/component/public/identity/tokens.js.map +1 -0
- package/dist/component/public/identity/users.d.ts +212 -0
- package/dist/component/public/identity/users.d.ts.map +1 -0
- package/dist/component/public/identity/users.js +311 -0
- package/dist/component/public/identity/users.js.map +1 -0
- package/dist/component/public/identity/verifiers.d.ts +116 -0
- package/dist/component/public/identity/verifiers.d.ts.map +1 -0
- package/dist/component/public/identity/verifiers.js +154 -0
- package/dist/component/public/identity/verifiers.js.map +1 -0
- package/dist/component/public/security/keys.d.ts +209 -0
- package/dist/component/public/security/keys.d.ts.map +1 -0
- package/dist/component/public/security/keys.js +319 -0
- package/dist/component/public/security/keys.js.map +1 -0
- package/dist/component/public/security/limits.d.ts +114 -0
- package/dist/component/public/security/limits.d.ts.map +1 -0
- package/dist/component/public/security/limits.js +169 -0
- package/dist/component/public/security/limits.js.map +1 -0
- package/dist/component/public.d.ts +22 -7
- package/dist/component/public.js +21 -6
- package/dist/component/schema.d.ts +288 -288
- package/dist/component/server/auth.d.ts +212 -25
- package/dist/component/server/auth.d.ts.map +1 -1
- package/dist/component/server/auth.js +68 -4
- package/dist/component/server/auth.js.map +1 -1
- package/dist/component/server/authError.js +34 -0
- package/dist/component/server/authError.js.map +1 -0
- package/dist/component/server/{providers.js → config.js} +2 -2
- package/dist/component/server/config.js.map +1 -0
- package/dist/component/server/{domains/core.js → core.js} +107 -88
- package/dist/component/server/core.js.map +1 -0
- package/dist/component/server/{provider.js → crypto.js} +3 -3
- package/dist/component/server/crypto.js.map +1 -0
- package/dist/component/server/device.js +1 -1
- package/dist/component/server/device.js.map +1 -1
- package/dist/component/server/enterprise/config.js +46 -0
- package/dist/component/server/enterprise/config.js.map +1 -0
- package/dist/component/server/{domains/sso.js → enterprise/domain.js} +6 -5
- package/dist/component/server/enterprise/domain.js.map +1 -0
- package/dist/component/server/enterprise/http.js +766 -0
- package/dist/component/server/enterprise/http.js.map +1 -0
- package/dist/component/server/enterprise/oidc.js +248 -0
- package/dist/component/server/enterprise/oidc.js.map +1 -0
- package/dist/component/server/enterprise/policy.js +85 -0
- package/dist/component/server/enterprise/policy.js.map +1 -0
- package/dist/component/server/enterprise/saml.js +338 -0
- package/dist/component/server/enterprise/saml.js.map +1 -0
- package/dist/component/server/enterprise/scim.js +97 -0
- package/dist/component/server/enterprise/scim.js.map +1 -0
- package/dist/component/server/enterprise/shared.js +51 -0
- package/dist/component/server/enterprise/shared.js.map +1 -0
- package/dist/component/server/errors.js.map +1 -1
- package/dist/component/server/http.js +2 -1
- package/dist/component/server/http.js.map +1 -1
- package/dist/component/server/identity.js +1 -1
- package/dist/component/server/identity.js.map +1 -1
- package/dist/component/server/{ratelimit.js → limits.js} +3 -3
- package/dist/component/server/limits.js.map +1 -0
- package/dist/component/server/mutations/account.js +3 -3
- package/dist/component/server/mutations/account.js.map +1 -1
- package/dist/component/server/mutations/code.js +2 -2
- package/dist/component/server/mutations/code.js.map +1 -1
- package/dist/component/server/mutations/invalidate.js +1 -1
- package/dist/component/server/mutations/invalidate.js.map +1 -1
- package/dist/component/server/mutations/oauth.js +5 -3
- package/dist/component/server/mutations/oauth.js.map +1 -1
- package/dist/component/server/mutations/refresh.js +1 -1
- package/dist/component/server/mutations/refresh.js.map +1 -1
- package/dist/component/server/mutations/register.js +3 -3
- package/dist/component/server/mutations/register.js.map +1 -1
- package/dist/component/server/mutations/retrieve.js +4 -4
- package/dist/component/server/mutations/retrieve.js.map +1 -1
- package/dist/component/server/mutations/signature.js +2 -2
- package/dist/component/server/mutations/signature.js.map +1 -1
- package/dist/component/server/mutations/signin.js +1 -1
- package/dist/component/server/mutations/signin.js.map +1 -1
- package/dist/component/server/mutations/signout.js +1 -1
- package/dist/component/server/mutations/signout.js.map +1 -1
- package/dist/component/server/mutations/store/refs.js +15 -0
- package/dist/component/server/mutations/store/refs.js.map +1 -0
- package/dist/component/server/mutations/store.js +80 -10
- package/dist/component/server/mutations/store.js.map +1 -1
- package/dist/component/server/mutations/verifier.js +1 -1
- package/dist/component/server/mutations/verifier.js.map +1 -1
- package/dist/component/server/mutations/verify.js +4 -3
- package/dist/component/server/mutations/verify.js.map +1 -1
- package/dist/component/server/oauth.js +1 -1
- package/dist/component/server/oauth.js.map +1 -1
- package/dist/component/server/passkey.js +2 -1
- package/dist/component/server/passkey.js.map +1 -1
- package/dist/component/server/redirects.js +1 -1
- package/dist/component/server/redirects.js.map +1 -1
- package/dist/component/server/refresh.js +1 -1
- package/dist/component/server/refresh.js.map +1 -1
- package/dist/component/server/{factory.d.ts → runtime.d.ts} +2 -2
- package/dist/component/server/runtime.d.ts.map +1 -0
- package/dist/component/server/runtime.js +413 -0
- package/dist/component/server/runtime.js.map +1 -0
- package/dist/component/server/signin.js +2 -1
- package/dist/component/server/signin.js.map +1 -1
- package/dist/component/server/totp.js +2 -1
- package/dist/component/server/totp.js.map +1 -1
- package/dist/component/server/types.d.ts +225 -41
- package/dist/component/server/types.d.ts.map +1 -1
- package/dist/component/server/types.js.map +1 -1
- package/dist/component/server/users.js +1 -1
- package/dist/component/server/users.js.map +1 -1
- package/dist/component/server/utils.js +1 -1
- package/dist/component/server/utils.js.map +1 -1
- package/dist/core/types.d.ts +369 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/factors/device.js +105 -0
- package/dist/factors/device.js.map +1 -0
- package/dist/factors/passkey.js +181 -0
- package/dist/factors/passkey.js.map +1 -0
- package/dist/factors/totp.js +122 -0
- package/dist/factors/totp.js.map +1 -0
- package/dist/providers/credentials.d.ts +5 -2
- package/dist/providers/credentials.d.ts.map +1 -1
- package/dist/providers/credentials.js +2 -0
- package/dist/providers/credentials.js.map +1 -1
- package/dist/providers/email.d.ts +30 -0
- package/dist/providers/email.d.ts.map +1 -1
- package/dist/providers/email.js +24 -0
- package/dist/providers/email.js.map +1 -1
- package/dist/providers/phone.d.ts +28 -0
- package/dist/providers/phone.d.ts.map +1 -1
- package/dist/providers/phone.js +22 -0
- package/dist/providers/phone.js.map +1 -1
- package/dist/runtime/browser.js +68 -0
- package/dist/runtime/browser.js.map +1 -0
- package/dist/runtime/invite.js +51 -0
- package/dist/runtime/invite.js.map +1 -0
- package/dist/runtime/proxy.js +70 -0
- package/dist/runtime/proxy.js.map +1 -0
- package/dist/runtime/storage.js +37 -0
- package/dist/runtime/storage.js.map +1 -0
- package/dist/server/auth.d.ts +218 -28
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +68 -4
- package/dist/server/auth.js.map +1 -1
- package/dist/server/{fx.d.ts → authError.d.ts} +25 -15
- package/dist/server/authError.d.ts.map +1 -0
- package/dist/server/authError.js +34 -0
- package/dist/server/authError.js.map +1 -0
- package/dist/server/{providers.js → config.js} +2 -2
- package/dist/server/config.js.map +1 -0
- package/dist/server/core.d.ts +1436 -0
- package/dist/server/core.d.ts.map +1 -0
- package/dist/server/{domains/core.js → core.js} +107 -88
- package/dist/server/core.js.map +1 -0
- package/dist/server/{provider.d.ts → crypto.d.ts} +2 -2
- package/dist/server/crypto.d.ts.map +1 -0
- package/dist/server/{provider.js → crypto.js} +3 -3
- package/dist/{component/server/provider.js.map → server/crypto.js.map} +1 -1
- package/dist/server/device.js +1 -1
- package/dist/server/device.js.map +1 -1
- package/dist/server/enterprise/config.js +46 -0
- package/dist/server/enterprise/config.js.map +1 -0
- package/dist/server/{domains/sso.d.ts → enterprise/domain.d.ts} +4 -4
- package/dist/server/enterprise/domain.d.ts.map +1 -0
- package/dist/server/{domains/sso.js → enterprise/domain.js} +6 -5
- package/dist/server/enterprise/domain.js.map +1 -0
- package/dist/server/enterprise/http.d.ts +26 -0
- package/dist/server/enterprise/http.d.ts.map +1 -0
- package/dist/server/enterprise/http.js +766 -0
- package/dist/server/enterprise/http.js.map +1 -0
- package/dist/server/enterprise/oidc.js +248 -0
- package/dist/server/enterprise/oidc.js.map +1 -0
- package/dist/server/enterprise/policy.js +85 -0
- package/dist/server/enterprise/policy.js.map +1 -0
- package/dist/server/enterprise/saml.d.ts +1 -0
- package/dist/server/enterprise/saml.js +338 -0
- package/dist/server/enterprise/saml.js.map +1 -0
- package/dist/server/enterprise/scim.d.ts +1 -0
- package/dist/server/enterprise/scim.js +97 -0
- package/dist/server/enterprise/scim.js.map +1 -0
- package/dist/server/enterprise/shared.d.ts +5 -0
- package/dist/server/enterprise/shared.d.ts.map +1 -0
- package/dist/server/enterprise/shared.js +51 -0
- package/dist/server/enterprise/shared.js.map +1 -0
- package/dist/server/enterprise/validators.d.ts +1 -0
- package/dist/server/{enterpriseValidators.js → enterprise/validators.js} +2 -2
- package/dist/server/enterprise/validators.js.map +1 -0
- package/dist/server/errors.d.ts +2 -0
- package/dist/server/errors.d.ts.map +1 -1
- package/dist/server/errors.js +2 -0
- package/dist/server/errors.js.map +1 -1
- package/dist/server/http.d.ts +2 -2
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +2 -1
- package/dist/server/http.js.map +1 -1
- package/dist/server/identity.js +1 -1
- package/dist/server/identity.js.map +1 -1
- package/dist/server/index.d.ts +4 -705
- package/dist/server/index.js +4 -1367
- package/dist/server/limits.d.ts +1 -0
- package/dist/server/{ratelimit.js → limits.js} +3 -3
- package/dist/server/limits.js.map +1 -0
- package/dist/server/mounts.d.ts +647 -0
- package/dist/server/mounts.d.ts.map +1 -0
- package/dist/server/mounts.js +643 -0
- package/dist/server/mounts.js.map +1 -0
- package/dist/server/mutations/account.d.ts +8 -8
- package/dist/server/mutations/account.js +3 -3
- package/dist/server/mutations/account.js.map +1 -1
- package/dist/server/mutations/code.d.ts +13 -13
- package/dist/server/mutations/code.js +2 -2
- package/dist/server/mutations/code.js.map +1 -1
- package/dist/server/mutations/index.d.ts +8 -312
- package/dist/server/mutations/index.js +14 -84
- package/dist/server/mutations/invalidate.d.ts +5 -5
- package/dist/server/mutations/invalidate.d.ts.map +1 -1
- package/dist/server/mutations/invalidate.js +1 -1
- package/dist/server/mutations/invalidate.js.map +1 -1
- package/dist/server/mutations/oauth.d.ts +9 -9
- package/dist/server/mutations/oauth.d.ts.map +1 -1
- package/dist/server/mutations/oauth.js +5 -3
- package/dist/server/mutations/oauth.js.map +1 -1
- package/dist/server/mutations/refresh.d.ts +4 -4
- package/dist/server/mutations/refresh.js +1 -1
- package/dist/server/mutations/refresh.js.map +1 -1
- package/dist/server/mutations/register.d.ts +10 -10
- package/dist/server/mutations/register.d.ts.map +1 -1
- package/dist/server/mutations/register.js +3 -3
- package/dist/server/mutations/register.js.map +1 -1
- package/dist/server/mutations/retrieve.d.ts +8 -10
- package/dist/server/mutations/retrieve.d.ts.map +1 -1
- package/dist/server/mutations/retrieve.js +5 -7
- package/dist/server/mutations/retrieve.js.map +1 -1
- package/dist/server/mutations/signature.d.ts +6 -6
- package/dist/server/mutations/signature.d.ts.map +1 -1
- package/dist/server/mutations/signature.js +2 -2
- package/dist/server/mutations/signature.js.map +1 -1
- package/dist/server/mutations/signin.d.ts +1 -1
- package/dist/server/mutations/signin.js +1 -1
- package/dist/server/mutations/signin.js.map +1 -1
- package/dist/server/mutations/signout.d.ts +1 -1
- package/dist/server/mutations/signout.js +1 -1
- package/dist/server/mutations/signout.js.map +1 -1
- package/dist/server/mutations/store/refs.d.ts +12 -0
- package/dist/server/mutations/store/refs.d.ts.map +1 -0
- package/dist/server/mutations/store/refs.js +15 -0
- package/dist/server/mutations/store/refs.js.map +1 -0
- package/dist/server/mutations/store.d.ts +303 -9
- package/dist/server/mutations/store.d.ts.map +1 -1
- package/dist/server/mutations/store.js +80 -10
- package/dist/server/mutations/store.js.map +1 -1
- package/dist/server/mutations/verifier.d.ts +1 -1
- package/dist/server/mutations/verifier.js +1 -1
- package/dist/server/mutations/verifier.js.map +1 -1
- package/dist/server/mutations/verify.d.ts +8 -8
- package/dist/server/mutations/verify.d.ts.map +1 -1
- package/dist/server/mutations/verify.js +4 -3
- package/dist/server/mutations/verify.js.map +1 -1
- package/dist/server/oauth.js +1 -1
- package/dist/server/oauth.js.map +1 -1
- package/dist/server/passkey.d.ts +2 -2
- package/dist/server/passkey.d.ts.map +1 -1
- package/dist/server/passkey.js +3 -2
- package/dist/server/passkey.js.map +1 -1
- package/dist/server/redirects.js +1 -1
- package/dist/server/redirects.js.map +1 -1
- package/dist/server/refresh.js +1 -1
- package/dist/server/refresh.js.map +1 -1
- package/dist/server/{factory.d.ts → runtime.d.ts} +16 -16
- package/dist/server/runtime.d.ts.map +1 -0
- package/dist/server/runtime.js +413 -0
- package/dist/server/runtime.js.map +1 -0
- package/dist/server/signin.js +3 -2
- package/dist/server/signin.js.map +1 -1
- package/dist/server/ssr.d.ts +226 -0
- package/dist/server/ssr.d.ts.map +1 -0
- package/dist/server/ssr.js +786 -0
- package/dist/server/ssr.js.map +1 -0
- package/dist/server/totp.js +2 -1
- package/dist/server/totp.js.map +1 -1
- package/dist/server/types.d.ts +242 -42
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js +12 -1
- package/dist/server/types.js.map +1 -1
- package/dist/server/users.js +1 -1
- package/dist/server/users.js.map +1 -1
- package/dist/server/utils.js +1 -1
- package/dist/server/utils.js.map +1 -1
- package/package.json +3 -4
- package/src/authorization/index.ts +46 -0
- package/src/cli/index.ts +38 -20
- package/src/client/core/types.ts +437 -0
- package/src/client/factors/device.ts +160 -0
- package/src/client/factors/passkey.ts +282 -0
- package/src/client/factors/totp.ts +150 -0
- package/src/client/index.ts +133 -1267
- package/src/client/runtime/browser.ts +112 -0
- package/src/client/runtime/invite.ts +65 -0
- package/src/client/runtime/proxy.ts +111 -0
- package/src/client/runtime/storage.ts +79 -0
- package/src/component/_generated/api.ts +40 -12
- package/src/component/_generated/component.ts +1772 -1798
- package/src/component/model.ts +6 -0
- package/src/component/public/enterprise/audit.ts +120 -0
- package/src/component/public/enterprise/core.ts +354 -0
- package/src/component/public/enterprise/domains.ts +323 -0
- package/src/component/public/enterprise/scim.ts +396 -0
- package/src/component/public/enterprise/secrets.ts +132 -0
- package/src/component/public/enterprise/webhooks.ts +306 -0
- package/src/component/public/factors/devices.ts +223 -0
- package/src/component/public/factors/passkeys.ts +242 -0
- package/src/component/public/factors/totp.ts +258 -0
- package/src/component/public/groups/core.ts +481 -0
- package/src/component/public/groups/invites.ts +602 -0
- package/src/component/public/groups/members.ts +409 -0
- package/src/component/public/identity/accounts.ts +206 -0
- package/src/component/public/identity/codes.ts +148 -0
- package/src/component/public/identity/sessions.ts +209 -0
- package/src/component/public/identity/tokens.ts +250 -0
- package/src/component/public/identity/users.ts +354 -0
- package/src/component/public/identity/verifiers.ts +157 -0
- package/src/component/public/security/keys.ts +365 -0
- package/src/component/public/security/limits.ts +173 -0
- package/src/component/public.ts +27 -5
- package/src/providers/credentials.ts +4 -5
- package/src/providers/email.ts +30 -0
- package/src/providers/phone.ts +28 -0
- package/src/server/auth.ts +282 -28
- package/src/server/authError.ts +44 -0
- package/src/server/core.ts +2095 -0
- package/src/server/{provider.ts → crypto.ts} +1 -1
- package/src/server/device.ts +1 -1
- package/src/server/enterprise/config.ts +51 -0
- package/src/server/{domains/sso.ts → enterprise/domain.ts} +4 -2
- package/src/server/enterprise/http.ts +1324 -0
- package/src/server/enterprise/oidc.ts +500 -0
- package/src/server/enterprise/policy.ts +128 -0
- package/src/server/enterprise/saml.ts +578 -0
- package/src/server/enterprise/scim.ts +135 -0
- package/src/server/enterprise/shared.ts +134 -0
- package/src/server/errors.ts +2 -0
- package/src/server/http.ts +3 -1
- package/src/server/identity.ts +1 -1
- package/src/server/index.ts +32 -2605
- package/src/server/{ratelimit.ts → limits.ts} +1 -1
- package/src/server/mounts.ts +948 -0
- package/src/server/mutations/account.ts +4 -4
- package/src/server/mutations/code.ts +3 -3
- package/src/server/mutations/index.ts +8 -148
- package/src/server/mutations/invalidate.ts +2 -2
- package/src/server/mutations/oauth.ts +8 -6
- package/src/server/mutations/refresh.ts +3 -3
- package/src/server/mutations/register.ts +3 -3
- package/src/server/mutations/retrieve.ts +4 -8
- package/src/server/mutations/signature.ts +3 -3
- package/src/server/mutations/signin.ts +2 -2
- package/src/server/mutations/signout.ts +2 -2
- package/src/server/mutations/store/refs.ts +10 -0
- package/src/server/mutations/store.ts +137 -9
- package/src/server/mutations/verifier.ts +2 -2
- package/src/server/mutations/verify.ts +5 -5
- package/src/server/oauth.ts +1 -1
- package/src/server/passkey.ts +3 -4
- package/src/server/redirects.ts +1 -1
- package/src/server/refresh.ts +1 -1
- package/src/server/runtime.ts +880 -0
- package/src/server/signin.ts +3 -1
- package/src/server/ssr.ts +1764 -0
- package/src/server/totp.ts +3 -1
- package/src/server/types.ts +254 -43
- package/src/server/users.ts +1 -1
- package/src/server/utils.ts +1 -1
- package/src/test.ts +25 -0
- package/dist/component/public/enterprise.d.ts +0 -54
- package/dist/component/public/enterprise.d.ts.map +0 -1
- package/dist/component/public/enterprise.js +0 -515
- package/dist/component/public/enterprise.js.map +0 -1
- package/dist/component/public/factors.d.ts +0 -52
- package/dist/component/public/factors.d.ts.map +0 -1
- package/dist/component/public/factors.js +0 -285
- package/dist/component/public/factors.js.map +0 -1
- package/dist/component/public/groups.d.ts +0 -124
- package/dist/component/public/groups.d.ts.map +0 -1
- package/dist/component/public/groups.js +0 -680
- package/dist/component/public/groups.js.map +0 -1
- package/dist/component/public/identity.d.ts +0 -93
- package/dist/component/public/identity.d.ts.map +0 -1
- package/dist/component/public/identity.js +0 -426
- package/dist/component/public/identity.js.map +0 -1
- package/dist/component/public/keys.d.ts +0 -41
- package/dist/component/public/keys.d.ts.map +0 -1
- package/dist/component/public/keys.js +0 -157
- package/dist/component/public/keys.js.map +0 -1
- package/dist/component/public/shared.d.ts +0 -26
- package/dist/component/public/shared.d.ts.map +0 -1
- package/dist/component/public/shared.js +0 -32
- package/dist/component/public/shared.js.map +0 -1
- package/dist/component/server/domains/core.js.map +0 -1
- package/dist/component/server/domains/sso.js.map +0 -1
- package/dist/component/server/factory.d.ts.map +0 -1
- package/dist/component/server/factory.js +0 -1134
- package/dist/component/server/factory.js.map +0 -1
- package/dist/component/server/fx.js +0 -66
- package/dist/component/server/fx.js.map +0 -1
- package/dist/component/server/mutations/index.js +0 -85
- package/dist/component/server/mutations/index.js.map +0 -1
- package/dist/component/server/providers.js.map +0 -1
- package/dist/component/server/ratelimit.js.map +0 -1
- package/dist/component/server/sso.js +0 -830
- package/dist/component/server/sso.js.map +0 -1
- package/dist/server/domains/core.d.ts +0 -449
- package/dist/server/domains/core.d.ts.map +0 -1
- package/dist/server/domains/core.js.map +0 -1
- package/dist/server/domains/sso.d.ts.map +0 -1
- package/dist/server/domains/sso.js.map +0 -1
- package/dist/server/enterpriseValidators.js.map +0 -1
- package/dist/server/factory.d.ts.map +0 -1
- package/dist/server/factory.js +0 -1134
- package/dist/server/factory.js.map +0 -1
- package/dist/server/fx.d.ts.map +0 -1
- package/dist/server/fx.js +0 -66
- package/dist/server/fx.js.map +0 -1
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/server/mutations/index.d.ts.map +0 -1
- package/dist/server/mutations/index.js.map +0 -1
- package/dist/server/provider.d.ts.map +0 -1
- package/dist/server/provider.js.map +0 -1
- package/dist/server/providers.js.map +0 -1
- package/dist/server/ratelimit.js.map +0 -1
- package/dist/server/sso.js +0 -830
- package/dist/server/sso.js.map +0 -1
- package/dist/server/version.d.ts +0 -5
- package/dist/server/version.d.ts.map +0 -1
- package/dist/server/version.js +0 -6
- package/dist/server/version.js.map +0 -1
- package/src/component/public/enterprise.ts +0 -753
- package/src/component/public/factors.ts +0 -333
- package/src/component/public/groups.ts +0 -1066
- package/src/component/public/identity.ts +0 -569
- package/src/component/public/keys.ts +0 -209
- package/src/component/public/shared.ts +0 -119
- package/src/server/domains/core.ts +0 -1096
- package/src/server/factory.ts +0 -2181
- package/src/server/fx.ts +0 -152
- package/src/server/sso.ts +0 -1516
- package/src/server/version.ts +0 -2
- /package/dist/server/{enterpriseValidators.d.ts → config.d.ts} +0 -0
- /package/dist/server/{providers.d.ts → enterprise/config.d.ts} +0 -0
- /package/dist/server/{ratelimit.d.ts → enterprise/oidc.d.ts} +0 -0
- /package/dist/server/{sso.d.ts → enterprise/policy.d.ts} +0 -0
- /package/src/server/{providers.ts → config.ts} +0 -0
- /package/src/server/{enterpriseValidators.ts → enterprise/validators.ts} +0 -0
|
@@ -0,0 +1,948 @@
|
|
|
1
|
+
import { actionGeneric, mutationGeneric, queryGeneric } from "convex/server";
|
|
2
|
+
import { ConvexError, v } from "convex/values";
|
|
3
|
+
|
|
4
|
+
import type { AuthApi } from "./auth";
|
|
5
|
+
import {
|
|
6
|
+
enterpriseConnectionWhereValidator,
|
|
7
|
+
enterpriseDomainInputValidator,
|
|
8
|
+
enterpriseDomainVerificationInputValidator,
|
|
9
|
+
enterprisePolicyPatchValidator,
|
|
10
|
+
enterpriseSamlAttributeMappingValidator,
|
|
11
|
+
enterpriseSamlSpValidator,
|
|
12
|
+
enterpriseStatusValidator,
|
|
13
|
+
} from "./enterprise/validators";
|
|
14
|
+
import type { AuthAuthorizationConfig, AuthRoleId } from "./types";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Permission identifiers used by mounted enterprise admin APIs.
|
|
18
|
+
*
|
|
19
|
+
* These permission strings are passed to your {@link EnterpriseAuthorizer}
|
|
20
|
+
* callback so app code can decide whether the current user may perform a
|
|
21
|
+
* specific SSO or SCIM management operation.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const authorized: EnterpriseAuthorizer = async (ctx, input) => {
|
|
26
|
+
* if (input.permission === "sso.connection.create") {
|
|
27
|
+
* // Only org admins may create SSO connections
|
|
28
|
+
* }
|
|
29
|
+
* };
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export type EnterpriseAdminPermission =
|
|
33
|
+
| "sso.connection.create"
|
|
34
|
+
| "sso.connection.read"
|
|
35
|
+
| "sso.connection.manage"
|
|
36
|
+
| "sso.domain.manage"
|
|
37
|
+
| "sso.protocol.manage"
|
|
38
|
+
| "sso.policy.manage"
|
|
39
|
+
| "sso.audit.read"
|
|
40
|
+
| "sso.webhook.manage"
|
|
41
|
+
| "scim.manage";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Input passed to an {@link EnterpriseAuthorizer}.
|
|
45
|
+
*
|
|
46
|
+
* Contains the acting user, the requested permission, and the resolved
|
|
47
|
+
* enterprise/group scope for the operation being authorized.
|
|
48
|
+
*/
|
|
49
|
+
export type EnterpriseAdminAuthorizationInput = {
|
|
50
|
+
/** The signed-in user's ID performing the admin action. */
|
|
51
|
+
userId: string;
|
|
52
|
+
/** The {@link EnterpriseAdminPermission} being requested. */
|
|
53
|
+
permission: EnterpriseAdminPermission;
|
|
54
|
+
/** Enterprise document ID, if the operation targets a specific enterprise. */
|
|
55
|
+
enterpriseId?: string;
|
|
56
|
+
/** Group document ID, if explicitly provided by the caller. */
|
|
57
|
+
groupId?: string;
|
|
58
|
+
/** Resolved group ID from the enterprise record, or `null` when no enterprise context. */
|
|
59
|
+
resolvedGroupId: string | null;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* App-defined authorization hook for mounted enterprise admin APIs.
|
|
64
|
+
*
|
|
65
|
+
* Return `void` (or resolve) to allow the operation, or `{ ok: false }` to deny it.
|
|
66
|
+
*
|
|
67
|
+
* @param ctx - Convex context with `ctx.auth` for identity checks.
|
|
68
|
+
* @param input - The {@link EnterpriseAdminAuthorizationInput} describing who is doing what.
|
|
69
|
+
* @returns `void` to allow, `{ ok: false }` to deny.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* import { EnterpriseAuthorizer } from "@robelest/convex-auth/server";
|
|
74
|
+
*
|
|
75
|
+
* const authorized: EnterpriseAuthorizer = async (ctx, input) => {
|
|
76
|
+
* const identity = await ctx.auth.getUserIdentity();
|
|
77
|
+
* if (!identity) return { ok: false };
|
|
78
|
+
* // Allow all admin ops for the org owner
|
|
79
|
+
* };
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export type EnterpriseAuthorizer = (
|
|
83
|
+
ctx: { auth: import("convex/server").Auth },
|
|
84
|
+
input: EnterpriseAdminAuthorizationInput,
|
|
85
|
+
) => Promise<void | { ok: false }>;
|
|
86
|
+
|
|
87
|
+
type RoleRef<TRoleId extends string> = { id: TRoleId };
|
|
88
|
+
|
|
89
|
+
type MountedEnterpriseOptions<TRoleId extends string = string> = {
|
|
90
|
+
admin?: {
|
|
91
|
+
authorized?: EnterpriseAuthorizer;
|
|
92
|
+
roles?: Array<TRoleId | RoleRef<TRoleId>>;
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Configuration for {@link enterprise}, {@link sso}, and {@link scim}
|
|
98
|
+
* mounted admin APIs.
|
|
99
|
+
*
|
|
100
|
+
* @typeParam TRoleId - Role IDs that may be assigned to enterprise creators.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* import { enterprise, EnterpriseMountOptions } from "@robelest/convex-auth/server";
|
|
105
|
+
*
|
|
106
|
+
* const options: EnterpriseMountOptions = {
|
|
107
|
+
* admin: {
|
|
108
|
+
* authorized: async (ctx, input) => {
|
|
109
|
+
* // Verify the user has permission for `input.permission`
|
|
110
|
+
* },
|
|
111
|
+
* roles: ["admin", "owner"],
|
|
112
|
+
* },
|
|
113
|
+
* };
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export type EnterpriseMountOptions<TRoleId extends string = string> = {
|
|
117
|
+
admin: {
|
|
118
|
+
authorized: EnterpriseAuthorizer;
|
|
119
|
+
roles?: Array<TRoleId | RoleRef<TRoleId>>;
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
type MountedEnterpriseTarget = {
|
|
124
|
+
enterpriseId?: string;
|
|
125
|
+
groupId?: string;
|
|
126
|
+
domain?: string;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
function requireSignedInUser(auth: Pick<AuthApi, "user">) {
|
|
130
|
+
return async (ctx: {
|
|
131
|
+
auth: import("convex/server").Auth;
|
|
132
|
+
}): Promise<string | null> => {
|
|
133
|
+
return await auth.user.id(ctx as never);
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function normalizeCreatorRoleIds<TRoleId extends string>(
|
|
138
|
+
roles?: Array<TRoleId | RoleRef<TRoleId>>,
|
|
139
|
+
) {
|
|
140
|
+
return roles?.map((role) => (typeof role === "string" ? role : role.id));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function resolveMountedEnterpriseTarget(
|
|
144
|
+
auth: Pick<AuthApi, "sso">,
|
|
145
|
+
ctx: { auth: import("convex/server").Auth },
|
|
146
|
+
target: MountedEnterpriseTarget,
|
|
147
|
+
) {
|
|
148
|
+
if (target.groupId !== undefined) {
|
|
149
|
+
return {
|
|
150
|
+
enterpriseId: target.enterpriseId,
|
|
151
|
+
groupId: target.groupId,
|
|
152
|
+
resolvedGroupId: target.groupId,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (target.enterpriseId !== undefined) {
|
|
157
|
+
const enterprise = await auth.sso.admin.connection.get(
|
|
158
|
+
ctx as never,
|
|
159
|
+
target.enterpriseId,
|
|
160
|
+
);
|
|
161
|
+
if (enterprise === null) {
|
|
162
|
+
throw new ConvexError({
|
|
163
|
+
code: "INVALID_PARAMETERS",
|
|
164
|
+
message: "Enterprise not found.",
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
enterpriseId: enterprise._id,
|
|
169
|
+
groupId: enterprise.groupId,
|
|
170
|
+
resolvedGroupId: enterprise.groupId,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (target.domain !== undefined) {
|
|
175
|
+
const resolved = await auth.sso.admin.connection.getByDomain(
|
|
176
|
+
ctx as never,
|
|
177
|
+
target.domain,
|
|
178
|
+
);
|
|
179
|
+
if (resolved?.enterprise === undefined) {
|
|
180
|
+
throw new ConvexError({
|
|
181
|
+
code: "INVALID_PARAMETERS",
|
|
182
|
+
message: "Enterprise not found.",
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
enterpriseId: resolved.enterprise._id,
|
|
187
|
+
groupId: resolved.enterprise.groupId,
|
|
188
|
+
resolvedGroupId: resolved.enterprise.groupId,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
enterpriseId: undefined,
|
|
194
|
+
groupId: undefined,
|
|
195
|
+
resolvedGroupId: null,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function createMountedAdminAuthorizer(
|
|
200
|
+
auth: Pick<AuthApi, "sso" | "user">,
|
|
201
|
+
options?: MountedEnterpriseOptions,
|
|
202
|
+
) {
|
|
203
|
+
const requireUserId = requireSignedInUser(auth);
|
|
204
|
+
|
|
205
|
+
return async (
|
|
206
|
+
ctx: { auth: import("convex/server").Auth },
|
|
207
|
+
permission: EnterpriseAdminPermission,
|
|
208
|
+
target: MountedEnterpriseTarget = {},
|
|
209
|
+
) => {
|
|
210
|
+
const userId = await requireUserId(ctx);
|
|
211
|
+
if (userId === null) {
|
|
212
|
+
return { ok: false as const, code: "NOT_SIGNED_IN" as const };
|
|
213
|
+
}
|
|
214
|
+
if (!options?.admin?.authorized) {
|
|
215
|
+
return { ok: false as const, code: "FORBIDDEN" as const };
|
|
216
|
+
}
|
|
217
|
+
const resolved = await resolveMountedEnterpriseTarget(auth, ctx, target);
|
|
218
|
+
const authResult = await options.admin.authorized(ctx, {
|
|
219
|
+
userId,
|
|
220
|
+
permission,
|
|
221
|
+
enterpriseId: resolved.enterpriseId,
|
|
222
|
+
groupId: resolved.groupId,
|
|
223
|
+
resolvedGroupId: resolved.resolvedGroupId,
|
|
224
|
+
});
|
|
225
|
+
if (authResult && !authResult.ok) {
|
|
226
|
+
return { ok: false as const, code: "FORBIDDEN" as const };
|
|
227
|
+
}
|
|
228
|
+
return { ok: true as const, userId, ...resolved };
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Build optional public SSO management actions that apps can mount under
|
|
234
|
+
* `convex/auth/sso/**` when they want client-callable enterprise APIs.
|
|
235
|
+
*
|
|
236
|
+
* `admin` is for tenant-admin control-plane operations and should be mounted
|
|
237
|
+
* with an explicit authorization policy. `client` is for end-user sign-in
|
|
238
|
+
* helpers and does not require tenant-admin authorization.
|
|
239
|
+
*
|
|
240
|
+
* @param auth - Auth API subset providing `group`, `member`, `sso`, and `user` namespaces.
|
|
241
|
+
* @param options - Optional admin authorization config. See {@link EnterpriseMountOptions}.
|
|
242
|
+
* @typeParam TAuthorization - Optional authorization config for typed role IDs.
|
|
243
|
+
* @returns An object with `admin` (connection CRUD, OIDC/SAML protocol config, policy,
|
|
244
|
+
* audit, webhooks, domain management) and `client` (signIn, metadata) namespaces.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```ts
|
|
248
|
+
* // convex/auth/sso.ts
|
|
249
|
+
* import { sso } from "@robelest/convex-auth/server";
|
|
250
|
+
* import { auth } from "../auth";
|
|
251
|
+
*
|
|
252
|
+
* const mounted = sso(auth, {
|
|
253
|
+
* admin: {
|
|
254
|
+
* authorized: async (ctx, input) => { /* check permissions *\/ },
|
|
255
|
+
* },
|
|
256
|
+
* });
|
|
257
|
+
*
|
|
258
|
+
* export const createConnection = mounted.admin.connection.create;
|
|
259
|
+
* export const signIn = mounted.client.signIn;
|
|
260
|
+
* ```
|
|
261
|
+
*
|
|
262
|
+
* @see {@link scim}
|
|
263
|
+
* @see {@link enterprise}
|
|
264
|
+
*/
|
|
265
|
+
export function sso<
|
|
266
|
+
TAuthorization extends AuthAuthorizationConfig | undefined = undefined,
|
|
267
|
+
>(
|
|
268
|
+
auth: Pick<AuthApi<TAuthorization>, "group" | "member" | "sso" | "user">,
|
|
269
|
+
options?: MountedEnterpriseOptions<AuthRoleId<TAuthorization>>,
|
|
270
|
+
) {
|
|
271
|
+
const authorize = createMountedAdminAuthorizer(auth, options);
|
|
272
|
+
const adminRoleIds = normalizeCreatorRoleIds(options?.admin?.roles);
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
admin: {
|
|
276
|
+
connection: {
|
|
277
|
+
create: mutationGeneric({
|
|
278
|
+
args: {
|
|
279
|
+
groupId: v.optional(v.string()),
|
|
280
|
+
name: v.optional(v.string()),
|
|
281
|
+
slug: v.optional(v.string()),
|
|
282
|
+
status: v.optional(enterpriseStatusValidator),
|
|
283
|
+
domain: v.optional(v.string()),
|
|
284
|
+
},
|
|
285
|
+
handler: async (ctx, args) => {
|
|
286
|
+
const authResult = await authorize(ctx, "sso.connection.create", {
|
|
287
|
+
groupId: args.groupId,
|
|
288
|
+
});
|
|
289
|
+
if (!authResult.ok)
|
|
290
|
+
return { ok: false as const, code: authResult.code };
|
|
291
|
+
const { userId } = authResult;
|
|
292
|
+
const createsGroup = args.groupId === undefined;
|
|
293
|
+
const groupId =
|
|
294
|
+
args.groupId ??
|
|
295
|
+
(
|
|
296
|
+
await auth.group.create(ctx as never, {
|
|
297
|
+
name: args.name?.trim() || args.slug?.trim() || "Enterprise",
|
|
298
|
+
slug: args.slug,
|
|
299
|
+
type: "enterprise",
|
|
300
|
+
})
|
|
301
|
+
).groupId;
|
|
302
|
+
if (createsGroup) {
|
|
303
|
+
await auth.member.create(ctx as never, {
|
|
304
|
+
groupId,
|
|
305
|
+
userId,
|
|
306
|
+
roleIds: adminRoleIds,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
const created = await auth.sso.admin.connection.create(
|
|
310
|
+
ctx as never,
|
|
311
|
+
{
|
|
312
|
+
groupId,
|
|
313
|
+
name: args.name,
|
|
314
|
+
slug: args.slug,
|
|
315
|
+
status: args.status,
|
|
316
|
+
},
|
|
317
|
+
);
|
|
318
|
+
if (args.domain) {
|
|
319
|
+
await auth.sso.admin.connection.domain.set(
|
|
320
|
+
ctx as never,
|
|
321
|
+
created.enterpriseId,
|
|
322
|
+
[{ domain: args.domain, isPrimary: true }],
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
...created,
|
|
327
|
+
groupId,
|
|
328
|
+
createdGroup: createsGroup,
|
|
329
|
+
};
|
|
330
|
+
},
|
|
331
|
+
}),
|
|
332
|
+
get: queryGeneric({
|
|
333
|
+
args: { enterpriseId: v.string() },
|
|
334
|
+
handler: async (ctx, args) => {
|
|
335
|
+
const _auth = await authorize(ctx, "sso.connection.read", {
|
|
336
|
+
enterpriseId: args.enterpriseId,
|
|
337
|
+
});
|
|
338
|
+
if (!_auth.ok) return null;
|
|
339
|
+
return await auth.sso.admin.connection.get(
|
|
340
|
+
ctx as never,
|
|
341
|
+
args.enterpriseId,
|
|
342
|
+
);
|
|
343
|
+
},
|
|
344
|
+
}),
|
|
345
|
+
getByGroup: queryGeneric({
|
|
346
|
+
args: { groupId: v.string() },
|
|
347
|
+
handler: async (ctx, args) => {
|
|
348
|
+
const _auth = await authorize(ctx, "sso.connection.read", {
|
|
349
|
+
groupId: args.groupId,
|
|
350
|
+
});
|
|
351
|
+
if (!_auth.ok) return null;
|
|
352
|
+
return await auth.sso.admin.connection.getByGroup(
|
|
353
|
+
ctx as never,
|
|
354
|
+
args.groupId,
|
|
355
|
+
);
|
|
356
|
+
},
|
|
357
|
+
}),
|
|
358
|
+
getByDomain: queryGeneric({
|
|
359
|
+
args: { domain: v.string() },
|
|
360
|
+
handler: async (ctx, args) => {
|
|
361
|
+
const _auth = await authorize(ctx, "sso.connection.read", {
|
|
362
|
+
domain: args.domain,
|
|
363
|
+
});
|
|
364
|
+
if (!_auth.ok) return null;
|
|
365
|
+
return await auth.sso.admin.connection.getByDomain(
|
|
366
|
+
ctx as never,
|
|
367
|
+
args.domain,
|
|
368
|
+
);
|
|
369
|
+
},
|
|
370
|
+
}),
|
|
371
|
+
list: queryGeneric({
|
|
372
|
+
args: {
|
|
373
|
+
where: v.optional(enterpriseConnectionWhereValidator),
|
|
374
|
+
limit: v.optional(v.number()),
|
|
375
|
+
cursor: v.optional(v.union(v.string(), v.null())),
|
|
376
|
+
orderBy: v.optional(v.string()),
|
|
377
|
+
order: v.optional(v.union(v.literal("asc"), v.literal("desc"))),
|
|
378
|
+
},
|
|
379
|
+
handler: async (ctx, args) => {
|
|
380
|
+
const _auth = await authorize(ctx, "sso.connection.read", {
|
|
381
|
+
groupId: args.where?.groupId,
|
|
382
|
+
});
|
|
383
|
+
if (!_auth.ok) return null;
|
|
384
|
+
return await auth.sso.admin.connection.list(
|
|
385
|
+
ctx as never,
|
|
386
|
+
args as never,
|
|
387
|
+
);
|
|
388
|
+
},
|
|
389
|
+
}),
|
|
390
|
+
update: mutationGeneric({
|
|
391
|
+
args: {
|
|
392
|
+
enterpriseId: v.string(),
|
|
393
|
+
data: v.object({
|
|
394
|
+
name: v.optional(v.string()),
|
|
395
|
+
slug: v.optional(v.string()),
|
|
396
|
+
status: v.optional(enterpriseStatusValidator),
|
|
397
|
+
}),
|
|
398
|
+
},
|
|
399
|
+
handler: async (ctx, args) => {
|
|
400
|
+
const _auth = await authorize(ctx, "sso.connection.manage", {
|
|
401
|
+
enterpriseId: args.enterpriseId,
|
|
402
|
+
});
|
|
403
|
+
if (!_auth.ok) return { ok: false as const, code: _auth.code };
|
|
404
|
+
await auth.sso.admin.connection.update(
|
|
405
|
+
ctx as never,
|
|
406
|
+
args.enterpriseId,
|
|
407
|
+
args.data,
|
|
408
|
+
);
|
|
409
|
+
return { ok: true as const, enterpriseId: args.enterpriseId };
|
|
410
|
+
},
|
|
411
|
+
}),
|
|
412
|
+
delete: mutationGeneric({
|
|
413
|
+
args: { enterpriseId: v.string() },
|
|
414
|
+
handler: async (ctx, args) => {
|
|
415
|
+
const _auth = await authorize(ctx, "sso.connection.manage", {
|
|
416
|
+
enterpriseId: args.enterpriseId,
|
|
417
|
+
});
|
|
418
|
+
if (!_auth.ok) return { ok: false as const, code: _auth.code };
|
|
419
|
+
return await auth.sso.admin.connection.delete(
|
|
420
|
+
ctx as never,
|
|
421
|
+
args.enterpriseId,
|
|
422
|
+
);
|
|
423
|
+
},
|
|
424
|
+
}),
|
|
425
|
+
status: queryGeneric({
|
|
426
|
+
args: { enterpriseId: v.string() },
|
|
427
|
+
handler: async (ctx, args) => {
|
|
428
|
+
const _auth = await authorize(ctx, "sso.connection.read", {
|
|
429
|
+
enterpriseId: args.enterpriseId,
|
|
430
|
+
});
|
|
431
|
+
if (!_auth.ok) return null;
|
|
432
|
+
return await auth.sso.admin.connection.status(
|
|
433
|
+
ctx as never,
|
|
434
|
+
args.enterpriseId,
|
|
435
|
+
);
|
|
436
|
+
},
|
|
437
|
+
}),
|
|
438
|
+
domain: {
|
|
439
|
+
list: queryGeneric({
|
|
440
|
+
args: { enterpriseId: v.string() },
|
|
441
|
+
handler: async (ctx, args) => {
|
|
442
|
+
const _auth = await authorize(ctx, "sso.connection.read", {
|
|
443
|
+
enterpriseId: args.enterpriseId,
|
|
444
|
+
});
|
|
445
|
+
if (!_auth.ok) return null;
|
|
446
|
+
return await auth.sso.admin.connection.domain.list(
|
|
447
|
+
ctx as never,
|
|
448
|
+
args.enterpriseId,
|
|
449
|
+
);
|
|
450
|
+
},
|
|
451
|
+
}),
|
|
452
|
+
validate: queryGeneric({
|
|
453
|
+
args: { enterpriseId: v.string() },
|
|
454
|
+
handler: async (ctx, args) => {
|
|
455
|
+
const _auth = await authorize(ctx, "sso.domain.manage", {
|
|
456
|
+
enterpriseId: args.enterpriseId,
|
|
457
|
+
});
|
|
458
|
+
if (!_auth.ok) return null;
|
|
459
|
+
return await auth.sso.admin.connection.domain.validate(
|
|
460
|
+
ctx as never,
|
|
461
|
+
args.enterpriseId,
|
|
462
|
+
);
|
|
463
|
+
},
|
|
464
|
+
}),
|
|
465
|
+
set: mutationGeneric({
|
|
466
|
+
args: {
|
|
467
|
+
enterpriseId: v.string(),
|
|
468
|
+
domains: v.array(enterpriseDomainInputValidator),
|
|
469
|
+
},
|
|
470
|
+
handler: async (ctx, args) => {
|
|
471
|
+
const _auth = await authorize(ctx, "sso.domain.manage", {
|
|
472
|
+
enterpriseId: args.enterpriseId,
|
|
473
|
+
});
|
|
474
|
+
if (!_auth.ok) return { ok: false as const, code: _auth.code };
|
|
475
|
+
return await auth.sso.admin.connection.domain.set(
|
|
476
|
+
ctx as never,
|
|
477
|
+
args.enterpriseId,
|
|
478
|
+
args.domains,
|
|
479
|
+
);
|
|
480
|
+
},
|
|
481
|
+
}),
|
|
482
|
+
verification: {
|
|
483
|
+
request: mutationGeneric({
|
|
484
|
+
args: enterpriseDomainVerificationInputValidator,
|
|
485
|
+
handler: async (ctx, args) => {
|
|
486
|
+
const _auth = await authorize(ctx, "sso.domain.manage", {
|
|
487
|
+
enterpriseId: args.enterpriseId,
|
|
488
|
+
});
|
|
489
|
+
if (!_auth.ok) return { ok: false as const, code: _auth.code };
|
|
490
|
+
return await auth.sso.admin.connection.domain.verification.request(
|
|
491
|
+
ctx as never,
|
|
492
|
+
args,
|
|
493
|
+
);
|
|
494
|
+
},
|
|
495
|
+
}),
|
|
496
|
+
confirm: actionGeneric({
|
|
497
|
+
args: enterpriseDomainVerificationInputValidator,
|
|
498
|
+
handler: async (ctx, args) => {
|
|
499
|
+
const _auth = await authorize(ctx, "sso.domain.manage", {
|
|
500
|
+
enterpriseId: args.enterpriseId,
|
|
501
|
+
});
|
|
502
|
+
if (!_auth.ok) return { ok: false as const, code: _auth.code };
|
|
503
|
+
return await auth.sso.admin.connection.domain.verification.confirm(
|
|
504
|
+
ctx as never,
|
|
505
|
+
args,
|
|
506
|
+
);
|
|
507
|
+
},
|
|
508
|
+
}),
|
|
509
|
+
},
|
|
510
|
+
},
|
|
511
|
+
},
|
|
512
|
+
oidc: {
|
|
513
|
+
configure: mutationGeneric({
|
|
514
|
+
args: {
|
|
515
|
+
enterpriseId: v.string(),
|
|
516
|
+
issuer: v.optional(v.string()),
|
|
517
|
+
discoveryUrl: v.optional(v.string()),
|
|
518
|
+
clientId: v.string(),
|
|
519
|
+
clientSecret: v.optional(v.string()),
|
|
520
|
+
scopes: v.optional(v.array(v.string())),
|
|
521
|
+
authorizationParams: v.optional(v.record(v.string(), v.string())),
|
|
522
|
+
clockToleranceSeconds: v.optional(v.number()),
|
|
523
|
+
strictIssuer: v.optional(v.boolean()),
|
|
524
|
+
extraFields: v.optional(v.record(v.string(), v.string())),
|
|
525
|
+
},
|
|
526
|
+
handler: async (ctx, args) => {
|
|
527
|
+
const _auth = await authorize(ctx, "sso.protocol.manage", {
|
|
528
|
+
enterpriseId: args.enterpriseId,
|
|
529
|
+
});
|
|
530
|
+
if (!_auth.ok) return { ok: false as const, code: _auth.code };
|
|
531
|
+
return await auth.sso.admin.oidc.configure(ctx as never, args);
|
|
532
|
+
},
|
|
533
|
+
}),
|
|
534
|
+
get: queryGeneric({
|
|
535
|
+
args: { enterpriseId: v.string() },
|
|
536
|
+
handler: async (ctx, args) => {
|
|
537
|
+
const _auth = await authorize(ctx, "sso.connection.read", {
|
|
538
|
+
enterpriseId: args.enterpriseId,
|
|
539
|
+
});
|
|
540
|
+
if (!_auth.ok) return null;
|
|
541
|
+
return await auth.sso.admin.oidc.get(
|
|
542
|
+
ctx as never,
|
|
543
|
+
args.enterpriseId,
|
|
544
|
+
);
|
|
545
|
+
},
|
|
546
|
+
}),
|
|
547
|
+
validate: actionGeneric({
|
|
548
|
+
args: { enterpriseId: v.string() },
|
|
549
|
+
handler: async (ctx, args) => {
|
|
550
|
+
const _auth = await authorize(ctx, "sso.protocol.manage", {
|
|
551
|
+
enterpriseId: args.enterpriseId,
|
|
552
|
+
});
|
|
553
|
+
if (!_auth.ok) return { ok: false as const, code: _auth.code };
|
|
554
|
+
return await auth.sso.admin.oidc.validate(
|
|
555
|
+
ctx as never,
|
|
556
|
+
args.enterpriseId,
|
|
557
|
+
);
|
|
558
|
+
},
|
|
559
|
+
}),
|
|
560
|
+
},
|
|
561
|
+
saml: {
|
|
562
|
+
configure: actionGeneric({
|
|
563
|
+
args: {
|
|
564
|
+
enterpriseId: v.string(),
|
|
565
|
+
metadataXml: v.optional(v.string()),
|
|
566
|
+
metadataUrl: v.optional(v.string()),
|
|
567
|
+
domains: v.optional(v.array(v.string())),
|
|
568
|
+
signAuthnRequests: v.optional(v.boolean()),
|
|
569
|
+
attributeMapping: v.optional(
|
|
570
|
+
enterpriseSamlAttributeMappingValidator,
|
|
571
|
+
),
|
|
572
|
+
sp: v.optional(enterpriseSamlSpValidator),
|
|
573
|
+
},
|
|
574
|
+
handler: async (ctx, args) => {
|
|
575
|
+
const _auth = await authorize(ctx, "sso.protocol.manage", {
|
|
576
|
+
enterpriseId: args.enterpriseId,
|
|
577
|
+
});
|
|
578
|
+
if (!_auth.ok) return { ok: false as const, code: _auth.code };
|
|
579
|
+
return await auth.sso.admin.saml.configure(ctx as never, args);
|
|
580
|
+
},
|
|
581
|
+
}),
|
|
582
|
+
validate: queryGeneric({
|
|
583
|
+
args: { enterpriseId: v.string() },
|
|
584
|
+
handler: async (ctx, args) => {
|
|
585
|
+
const _auth = await authorize(ctx, "sso.protocol.manage", {
|
|
586
|
+
enterpriseId: args.enterpriseId,
|
|
587
|
+
});
|
|
588
|
+
if (!_auth.ok) return null;
|
|
589
|
+
return await auth.sso.admin.saml.validate(
|
|
590
|
+
ctx as never,
|
|
591
|
+
args.enterpriseId,
|
|
592
|
+
);
|
|
593
|
+
},
|
|
594
|
+
}),
|
|
595
|
+
},
|
|
596
|
+
policy: {
|
|
597
|
+
get: queryGeneric({
|
|
598
|
+
args: { enterpriseId: v.string() },
|
|
599
|
+
handler: async (ctx, args) => {
|
|
600
|
+
const _auth = await authorize(ctx, "sso.connection.read", {
|
|
601
|
+
enterpriseId: args.enterpriseId,
|
|
602
|
+
});
|
|
603
|
+
if (!_auth.ok) return null;
|
|
604
|
+
return await auth.sso.admin.policy.get(
|
|
605
|
+
ctx as never,
|
|
606
|
+
args.enterpriseId,
|
|
607
|
+
);
|
|
608
|
+
},
|
|
609
|
+
}),
|
|
610
|
+
update: mutationGeneric({
|
|
611
|
+
args: {
|
|
612
|
+
enterpriseId: v.string(),
|
|
613
|
+
patch: enterprisePolicyPatchValidator,
|
|
614
|
+
},
|
|
615
|
+
handler: async (ctx, args) => {
|
|
616
|
+
const _auth = await authorize(ctx, "sso.policy.manage", {
|
|
617
|
+
enterpriseId: args.enterpriseId,
|
|
618
|
+
});
|
|
619
|
+
if (!_auth.ok) return { ok: false as const, code: _auth.code };
|
|
620
|
+
return await auth.sso.admin.policy.update(
|
|
621
|
+
ctx as never,
|
|
622
|
+
args.enterpriseId,
|
|
623
|
+
args.patch,
|
|
624
|
+
);
|
|
625
|
+
},
|
|
626
|
+
}),
|
|
627
|
+
validate: queryGeneric({
|
|
628
|
+
args: { enterpriseId: v.string() },
|
|
629
|
+
handler: async (ctx, args) => {
|
|
630
|
+
const _auth = await authorize(ctx, "sso.policy.manage", {
|
|
631
|
+
enterpriseId: args.enterpriseId,
|
|
632
|
+
});
|
|
633
|
+
if (!_auth.ok) return null;
|
|
634
|
+
return await auth.sso.admin.policy.validate(
|
|
635
|
+
ctx as never,
|
|
636
|
+
args.enterpriseId,
|
|
637
|
+
);
|
|
638
|
+
},
|
|
639
|
+
}),
|
|
640
|
+
},
|
|
641
|
+
audit: {
|
|
642
|
+
list: queryGeneric({
|
|
643
|
+
args: {
|
|
644
|
+
enterpriseId: v.optional(v.string()),
|
|
645
|
+
groupId: v.optional(v.string()),
|
|
646
|
+
limit: v.optional(v.number()),
|
|
647
|
+
},
|
|
648
|
+
handler: async (ctx, args) => {
|
|
649
|
+
const _auth = await authorize(ctx, "sso.audit.read", {
|
|
650
|
+
enterpriseId: args.enterpriseId,
|
|
651
|
+
groupId: args.groupId,
|
|
652
|
+
});
|
|
653
|
+
if (!_auth.ok) return null;
|
|
654
|
+
return await auth.sso.admin.audit.list(ctx as never, args);
|
|
655
|
+
},
|
|
656
|
+
}),
|
|
657
|
+
},
|
|
658
|
+
webhook: {
|
|
659
|
+
delivery: {
|
|
660
|
+
list: queryGeneric({
|
|
661
|
+
args: {
|
|
662
|
+
enterpriseId: v.string(),
|
|
663
|
+
limit: v.optional(v.number()),
|
|
664
|
+
},
|
|
665
|
+
handler: async (ctx, args) => {
|
|
666
|
+
const _auth = await authorize(ctx, "sso.webhook.manage", {
|
|
667
|
+
enterpriseId: args.enterpriseId,
|
|
668
|
+
});
|
|
669
|
+
if (!_auth.ok) return null;
|
|
670
|
+
return await (auth.sso.admin.webhook as any).delivery.list(
|
|
671
|
+
ctx as never,
|
|
672
|
+
args,
|
|
673
|
+
);
|
|
674
|
+
},
|
|
675
|
+
}),
|
|
676
|
+
},
|
|
677
|
+
endpoint: {
|
|
678
|
+
create: mutationGeneric({
|
|
679
|
+
args: {
|
|
680
|
+
enterpriseId: v.string(),
|
|
681
|
+
url: v.string(),
|
|
682
|
+
secret: v.string(),
|
|
683
|
+
subscriptions: v.array(v.string()),
|
|
684
|
+
createdByUserId: v.optional(v.string()),
|
|
685
|
+
},
|
|
686
|
+
handler: async (ctx, args) => {
|
|
687
|
+
const authResult = await authorize(ctx, "sso.webhook.manage", {
|
|
688
|
+
enterpriseId: args.enterpriseId,
|
|
689
|
+
});
|
|
690
|
+
if (!authResult.ok)
|
|
691
|
+
return { ok: false as const, code: authResult.code };
|
|
692
|
+
const { userId } = authResult;
|
|
693
|
+
const result = await auth.sso.admin.webhook.endpoint.create(
|
|
694
|
+
ctx as never,
|
|
695
|
+
{
|
|
696
|
+
...args,
|
|
697
|
+
createdByUserId: args.createdByUserId ?? userId,
|
|
698
|
+
},
|
|
699
|
+
);
|
|
700
|
+
return {
|
|
701
|
+
_id: result.endpointId,
|
|
702
|
+
enterpriseId: args.enterpriseId,
|
|
703
|
+
url: args.url,
|
|
704
|
+
subscriptions: args.subscriptions,
|
|
705
|
+
createdByUserId: args.createdByUserId ?? userId,
|
|
706
|
+
status: "active",
|
|
707
|
+
failureCount: 0,
|
|
708
|
+
};
|
|
709
|
+
},
|
|
710
|
+
}),
|
|
711
|
+
list: queryGeneric({
|
|
712
|
+
args: { enterpriseId: v.string() },
|
|
713
|
+
handler: async (ctx, args) => {
|
|
714
|
+
const _auth = await authorize(ctx, "sso.webhook.manage", {
|
|
715
|
+
enterpriseId: args.enterpriseId,
|
|
716
|
+
});
|
|
717
|
+
if (!_auth.ok) return null;
|
|
718
|
+
const endpoints = await auth.sso.admin.webhook.endpoint.list(
|
|
719
|
+
ctx as never,
|
|
720
|
+
args.enterpriseId,
|
|
721
|
+
);
|
|
722
|
+
return endpoints.map((endpoint: Record<string, unknown>) => {
|
|
723
|
+
const { secretHash: _secretHash, ...rest } = endpoint;
|
|
724
|
+
return rest;
|
|
725
|
+
});
|
|
726
|
+
},
|
|
727
|
+
}),
|
|
728
|
+
disable: mutationGeneric({
|
|
729
|
+
args: { endpointId: v.string() },
|
|
730
|
+
handler: async (ctx, args) => {
|
|
731
|
+
const endpoint = await auth.sso.admin.webhook.endpoint.get(
|
|
732
|
+
ctx as never,
|
|
733
|
+
args.endpointId,
|
|
734
|
+
);
|
|
735
|
+
if (!endpoint) {
|
|
736
|
+
return {
|
|
737
|
+
ok: false as const,
|
|
738
|
+
code: "INVALID_PARAMETERS" as const,
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
const _auth = await authorize(ctx, "sso.webhook.manage", {
|
|
742
|
+
enterpriseId: endpoint.enterpriseId,
|
|
743
|
+
groupId: endpoint.groupId,
|
|
744
|
+
});
|
|
745
|
+
if (!_auth.ok) return { ok: false as const, code: _auth.code };
|
|
746
|
+
return await auth.sso.admin.webhook.endpoint.disable(
|
|
747
|
+
ctx as never,
|
|
748
|
+
args.endpointId,
|
|
749
|
+
);
|
|
750
|
+
},
|
|
751
|
+
}),
|
|
752
|
+
},
|
|
753
|
+
},
|
|
754
|
+
},
|
|
755
|
+
client: {
|
|
756
|
+
signIn: queryGeneric({
|
|
757
|
+
args: {
|
|
758
|
+
enterpriseId: v.optional(v.string()),
|
|
759
|
+
email: v.optional(v.string()),
|
|
760
|
+
domain: v.optional(v.string()),
|
|
761
|
+
redirectTo: v.optional(v.string()),
|
|
762
|
+
},
|
|
763
|
+
handler: async (ctx, args) => {
|
|
764
|
+
return await auth.sso.client.signIn(ctx as never, args);
|
|
765
|
+
},
|
|
766
|
+
}),
|
|
767
|
+
metadata: queryGeneric({
|
|
768
|
+
args: {
|
|
769
|
+
enterpriseId: v.string(),
|
|
770
|
+
entityId: v.optional(v.string()),
|
|
771
|
+
acsUrl: v.optional(v.string()),
|
|
772
|
+
sloUrl: v.optional(v.string()),
|
|
773
|
+
},
|
|
774
|
+
handler: async (ctx, args) => {
|
|
775
|
+
return await auth.sso.client.metadata(ctx as never, args);
|
|
776
|
+
},
|
|
777
|
+
}),
|
|
778
|
+
},
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Build optional public SCIM management actions that apps can mount under
|
|
784
|
+
* `convex/auth/scim/**` when they want client-callable enterprise admin APIs.
|
|
785
|
+
*
|
|
786
|
+
* @param auth - Auth API subset providing `scim`, `sso`, and `user` namespaces.
|
|
787
|
+
* @param options - Optional admin authorization config. See {@link EnterpriseMountOptions}.
|
|
788
|
+
* @typeParam TAuthorization - Optional authorization config for typed role IDs.
|
|
789
|
+
* @returns An object with `admin.configure`, `admin.get`, and `admin.validate` actions.
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* ```ts
|
|
793
|
+
* // convex/auth/scim.ts
|
|
794
|
+
* import { scim } from "@robelest/convex-auth/server";
|
|
795
|
+
* import { auth } from "../auth";
|
|
796
|
+
*
|
|
797
|
+
* const mounted = scim(auth, {
|
|
798
|
+
* admin: {
|
|
799
|
+
* authorized: async (ctx, input) => { /* check permissions *\/ },
|
|
800
|
+
* },
|
|
801
|
+
* });
|
|
802
|
+
*
|
|
803
|
+
* export const configure = mounted.admin.configure;
|
|
804
|
+
* export const get = mounted.admin.get;
|
|
805
|
+
* export const validate = mounted.admin.validate;
|
|
806
|
+
* ```
|
|
807
|
+
*
|
|
808
|
+
* @see {@link sso}
|
|
809
|
+
* @see {@link enterprise}
|
|
810
|
+
*/
|
|
811
|
+
export function scim<
|
|
812
|
+
TAuthorization extends AuthAuthorizationConfig | undefined = undefined,
|
|
813
|
+
>(
|
|
814
|
+
auth: Pick<AuthApi<TAuthorization>, "scim" | "sso" | "user">,
|
|
815
|
+
options?: MountedEnterpriseOptions<AuthRoleId<TAuthorization>>,
|
|
816
|
+
) {
|
|
817
|
+
const authorize = createMountedAdminAuthorizer(auth, options);
|
|
818
|
+
|
|
819
|
+
return {
|
|
820
|
+
admin: {
|
|
821
|
+
configure: mutationGeneric({
|
|
822
|
+
args: {
|
|
823
|
+
enterpriseId: v.string(),
|
|
824
|
+
basePath: v.optional(v.string()),
|
|
825
|
+
status: v.optional(enterpriseStatusValidator),
|
|
826
|
+
},
|
|
827
|
+
handler: async (ctx, args) => {
|
|
828
|
+
const _auth = await authorize(ctx, "scim.manage", {
|
|
829
|
+
enterpriseId: args.enterpriseId,
|
|
830
|
+
});
|
|
831
|
+
if (!_auth.ok) return { ok: false as const, code: _auth.code };
|
|
832
|
+
return await auth.scim.admin.configure(ctx as never, args);
|
|
833
|
+
},
|
|
834
|
+
}),
|
|
835
|
+
get: queryGeneric({
|
|
836
|
+
args: { enterpriseId: v.string() },
|
|
837
|
+
handler: async (ctx, args) => {
|
|
838
|
+
const _auth = await authorize(ctx, "scim.manage", {
|
|
839
|
+
enterpriseId: args.enterpriseId,
|
|
840
|
+
});
|
|
841
|
+
if (!_auth.ok) return null;
|
|
842
|
+
return await auth.scim.admin.get(ctx as never, args.enterpriseId);
|
|
843
|
+
},
|
|
844
|
+
}),
|
|
845
|
+
validate: queryGeneric({
|
|
846
|
+
args: { enterpriseId: v.string() },
|
|
847
|
+
handler: async (ctx, args) => {
|
|
848
|
+
const _auth = await authorize(ctx, "scim.manage", {
|
|
849
|
+
enterpriseId: args.enterpriseId,
|
|
850
|
+
});
|
|
851
|
+
if (!_auth.ok) return null;
|
|
852
|
+
return await auth.scim.admin.validate(
|
|
853
|
+
ctx as never,
|
|
854
|
+
args.enterpriseId,
|
|
855
|
+
);
|
|
856
|
+
},
|
|
857
|
+
}),
|
|
858
|
+
},
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
/**
|
|
863
|
+
* Build a flat mounted enterprise API surface for app-owned Convex exports.
|
|
864
|
+
*
|
|
865
|
+
* Combines {@link sso} and {@link scim} into a single flat object with
|
|
866
|
+
* all SSO connection, protocol, policy, audit, webhook, and SCIM
|
|
867
|
+
* management functions plus end-user sign-in helpers. The `authorized`
|
|
868
|
+
* callback is required for all admin operations.
|
|
869
|
+
*
|
|
870
|
+
* @param auth - Auth API subset providing `group`, `member`, `scim`, `sso`, and `user` namespaces.
|
|
871
|
+
* @param options - Required {@link EnterpriseMountOptions} with an `admin.authorized` callback.
|
|
872
|
+
* @typeParam TAuthorization - Optional authorization config for typed role IDs.
|
|
873
|
+
* @returns A flat object with all enterprise management functions (e.g. `createConnection`,
|
|
874
|
+
* `configureOidc`, `configureScim`, `signIn`, etc.).
|
|
875
|
+
*
|
|
876
|
+
* @example
|
|
877
|
+
* ```ts
|
|
878
|
+
* // convex/auth/enterprise.ts
|
|
879
|
+
* import { enterprise } from "@robelest/convex-auth/server";
|
|
880
|
+
* import { auth } from "../auth";
|
|
881
|
+
*
|
|
882
|
+
* const api = enterprise(auth, {
|
|
883
|
+
* admin: {
|
|
884
|
+
* authorized: async (ctx, input) => { /* check permissions *\/ },
|
|
885
|
+
* roles: ["admin"],
|
|
886
|
+
* },
|
|
887
|
+
* });
|
|
888
|
+
*
|
|
889
|
+
* export const createConnection = api.createConnection;
|
|
890
|
+
* export const configureOidc = api.configureOidc;
|
|
891
|
+
* export const signIn = api.signIn;
|
|
892
|
+
* ```
|
|
893
|
+
*
|
|
894
|
+
* @see {@link sso}
|
|
895
|
+
* @see {@link scim}
|
|
896
|
+
*/
|
|
897
|
+
export function enterprise<
|
|
898
|
+
TAuthorization extends AuthAuthorizationConfig | undefined = undefined,
|
|
899
|
+
>(
|
|
900
|
+
auth: Pick<
|
|
901
|
+
AuthApi<TAuthorization>,
|
|
902
|
+
"group" | "member" | "scim" | "sso" | "user"
|
|
903
|
+
>,
|
|
904
|
+
options: EnterpriseMountOptions<AuthRoleId<TAuthorization>>,
|
|
905
|
+
) {
|
|
906
|
+
const mountedSso = sso(auth, {
|
|
907
|
+
admin: options.admin,
|
|
908
|
+
});
|
|
909
|
+
const mountedScim = scim(auth, {
|
|
910
|
+
admin: { authorized: options.admin.authorized },
|
|
911
|
+
});
|
|
912
|
+
|
|
913
|
+
return {
|
|
914
|
+
createConnection: mountedSso.admin.connection.create,
|
|
915
|
+
getConnection: mountedSso.admin.connection.get,
|
|
916
|
+
getConnectionByGroup: mountedSso.admin.connection.getByGroup,
|
|
917
|
+
getConnectionByDomain: mountedSso.admin.connection.getByDomain,
|
|
918
|
+
listConnections: mountedSso.admin.connection.list,
|
|
919
|
+
updateConnection: mountedSso.admin.connection.update,
|
|
920
|
+
deleteConnection: mountedSso.admin.connection.delete,
|
|
921
|
+
getConnectionStatus: mountedSso.admin.connection.status,
|
|
922
|
+
listDomains: mountedSso.admin.connection.domain.list,
|
|
923
|
+
validateDomains: mountedSso.admin.connection.domain.validate,
|
|
924
|
+
setDomains: mountedSso.admin.connection.domain.set,
|
|
925
|
+
requestDomainVerification:
|
|
926
|
+
mountedSso.admin.connection.domain.verification.request,
|
|
927
|
+
confirmDomainVerification:
|
|
928
|
+
mountedSso.admin.connection.domain.verification.confirm,
|
|
929
|
+
configureOidc: mountedSso.admin.oidc.configure,
|
|
930
|
+
getOidc: mountedSso.admin.oidc.get,
|
|
931
|
+
validateOidc: mountedSso.admin.oidc.validate,
|
|
932
|
+
configureSaml: mountedSso.admin.saml.configure,
|
|
933
|
+
validateSaml: mountedSso.admin.saml.validate,
|
|
934
|
+
getPolicy: mountedSso.admin.policy.get,
|
|
935
|
+
updatePolicy: mountedSso.admin.policy.update,
|
|
936
|
+
validatePolicy: mountedSso.admin.policy.validate,
|
|
937
|
+
listAudit: mountedSso.admin.audit.list,
|
|
938
|
+
createWebhookEndpoint: mountedSso.admin.webhook.endpoint.create,
|
|
939
|
+
listWebhookEndpoints: mountedSso.admin.webhook.endpoint.list,
|
|
940
|
+
listWebhookDeliveries: mountedSso.admin.webhook.delivery.list,
|
|
941
|
+
disableWebhookEndpoint: mountedSso.admin.webhook.endpoint.disable,
|
|
942
|
+
configureScim: mountedScim.admin.configure,
|
|
943
|
+
getScim: mountedScim.admin.get,
|
|
944
|
+
validateScim: mountedScim.admin.validate,
|
|
945
|
+
signIn: mountedSso.client.signIn,
|
|
946
|
+
metadata: mountedSso.client.metadata,
|
|
947
|
+
};
|
|
948
|
+
}
|