@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,481 @@
|
|
|
1
|
+
import { v } from "convex/values";
|
|
2
|
+
import type { Id } from "../../_generated/dataModel";
|
|
3
|
+
import { mutation, query } from "../../functions";
|
|
4
|
+
import { vGroupDoc, vPaginated, vTag } from "../../model";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
type TagPair = { key: string; value: string };
|
|
8
|
+
|
|
9
|
+
function normalizeTag(tag: TagPair): TagPair {
|
|
10
|
+
return {
|
|
11
|
+
key: tag.key.trim().toLowerCase(),
|
|
12
|
+
value: tag.value.trim().toLowerCase(),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function normalizeTags(tags: TagPair[]): TagPair[] {
|
|
17
|
+
const seen = new Set<string>();
|
|
18
|
+
const result: TagPair[] = [];
|
|
19
|
+
for (const raw of tags) {
|
|
20
|
+
const t = normalizeTag(raw);
|
|
21
|
+
const composite = `${t.key}\0${t.value}`;
|
|
22
|
+
if (!seen.has(composite)) {
|
|
23
|
+
seen.add(composite);
|
|
24
|
+
result.push(t);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a new group. Groups are hierarchical — set `parentGroupId` to nest
|
|
31
|
+
* under an existing group, or omit it to create a root-level group.
|
|
32
|
+
*
|
|
33
|
+
* Root groups self-reference their own ID as `rootGroupId`. Child groups
|
|
34
|
+
* inherit `rootGroupId` from their parent chain. Tags are normalized
|
|
35
|
+
* (trimmed and lowercased) and deduplicated before storage, and companion
|
|
36
|
+
* `GroupTag` rows are created for indexed lookups.
|
|
37
|
+
*
|
|
38
|
+
* @param args.name - The display name for the group.
|
|
39
|
+
* @param args.slug - An optional URL-friendly identifier for the group (e.g. `"engineering"`).
|
|
40
|
+
* @param args.type - An optional application-defined group type (e.g. `"organization"`, `"team"`).
|
|
41
|
+
* @param args.parentGroupId - The ID of an existing group to nest under. Omit to create a root-level group.
|
|
42
|
+
* @param args.tags - An optional array of `{ key, value }` tag pairs to attach to the group for filtering.
|
|
43
|
+
* @param args.extend - An optional arbitrary payload for application-specific metadata.
|
|
44
|
+
* @returns The `Id<"Group">` of the newly created group document.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const groupId = await ctx.runMutation(components.auth.groups.groupCreate, {
|
|
49
|
+
* name: "Acme Corp",
|
|
50
|
+
* slug: "acme-corp",
|
|
51
|
+
* type: "organization",
|
|
52
|
+
* tags: [{ key: "plan", value: "enterprise" }],
|
|
53
|
+
* });
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export const groupCreate = mutation({
|
|
57
|
+
args: {
|
|
58
|
+
name: v.string(),
|
|
59
|
+
slug: v.optional(v.string()),
|
|
60
|
+
type: v.optional(v.string()),
|
|
61
|
+
parentGroupId: v.optional(v.id("Group")),
|
|
62
|
+
tags: v.optional(v.array(vTag)),
|
|
63
|
+
extend: v.optional(v.any()),
|
|
64
|
+
},
|
|
65
|
+
returns: v.id("Group"),
|
|
66
|
+
handler: async (ctx, args) => {
|
|
67
|
+
const { tags: rawTags, ...rest } = args;
|
|
68
|
+
const normalizedTags = rawTags ? normalizeTags(rawTags) : undefined;
|
|
69
|
+
const isRoot = !args.parentGroupId;
|
|
70
|
+
// Compute rootGroupId: root groups self-reference, children inherit from parent
|
|
71
|
+
let rootGroupId: Id<"Group"> | undefined;
|
|
72
|
+
if (!isRoot && args.parentGroupId) {
|
|
73
|
+
const parent = await ctx.db.get(args.parentGroupId);
|
|
74
|
+
rootGroupId = parent?.rootGroupId ?? args.parentGroupId;
|
|
75
|
+
}
|
|
76
|
+
const groupId = await ctx.db.insert("Group", {
|
|
77
|
+
...rest,
|
|
78
|
+
tags: normalizedTags,
|
|
79
|
+
isRoot,
|
|
80
|
+
rootGroupId: isRoot ? undefined : rootGroupId,
|
|
81
|
+
});
|
|
82
|
+
// Self-reference for root groups (need the ID after insert)
|
|
83
|
+
if (isRoot) {
|
|
84
|
+
await ctx.db.patch(groupId, { rootGroupId: groupId });
|
|
85
|
+
}
|
|
86
|
+
// Sync companion group_tag rows
|
|
87
|
+
if (normalizedTags) {
|
|
88
|
+
for (const tag of normalizedTags) {
|
|
89
|
+
await ctx.db.insert("GroupTag", {
|
|
90
|
+
group_id: groupId,
|
|
91
|
+
key: tag.key,
|
|
92
|
+
value: tag.value,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return groupId;
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Retrieve a group by its document ID.
|
|
102
|
+
*
|
|
103
|
+
* Performs a direct lookup in the `Group` table and returns the full group
|
|
104
|
+
* document, or `null` if no group exists with the given ID.
|
|
105
|
+
*
|
|
106
|
+
* @param args.groupId - The `Id<"Group">` of the group to retrieve.
|
|
107
|
+
* @returns The group document (including `name`, `slug`, `type`, `tags`, hierarchy fields, etc.) or `null` if not found.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* const group = await ctx.runQuery(components.auth.groups.groupGet, {
|
|
112
|
+
* groupId: existingGroupId,
|
|
113
|
+
* });
|
|
114
|
+
* if (group !== null) {
|
|
115
|
+
* console.log(group.name, group.slug);
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
export const groupGet = query({
|
|
120
|
+
args: { groupId: v.id("Group") },
|
|
121
|
+
returns: v.union(vGroupDoc, v.null()),
|
|
122
|
+
handler: async (ctx, { groupId }) => {
|
|
123
|
+
return await ctx.db.get("Group", groupId);
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* List groups with optional filtering, sorting, and pagination.
|
|
129
|
+
*
|
|
130
|
+
* Returns `{ items, nextCursor }`. Empty `where` returns **all** groups.
|
|
131
|
+
* The query engine selects the best database index based on the combination
|
|
132
|
+
* of filter fields provided. Tag filters (`tagsAll`, `tagsAny`) are resolved
|
|
133
|
+
* via the `GroupTag` companion table and intersected/unioned with index results.
|
|
134
|
+
*
|
|
135
|
+
* @param args.where - Optional filter criteria for narrowing results.
|
|
136
|
+
* @param args.where.slug - Match groups with this exact slug.
|
|
137
|
+
* @param args.where.type - Match groups with this exact type.
|
|
138
|
+
* @param args.where.parentGroupId - Match groups that are direct children of the specified parent group.
|
|
139
|
+
* @param args.where.name - Match groups with this exact name.
|
|
140
|
+
* @param args.where.isRoot - When `true`, return only root-level groups; when `false`, only child groups.
|
|
141
|
+
* @param args.where.tagsAll - An array of `{ key, value }` pairs; only groups that have **all** of these tags are returned.
|
|
142
|
+
* @param args.where.tagsAny - An array of `{ key, value }` pairs; groups that have **at least one** of these tags are returned.
|
|
143
|
+
* @param args.limit - Maximum number of items per page (clamped to 1..100, defaults to 50).
|
|
144
|
+
* @param args.cursor - An opaque cursor string from a previous response's `nextCursor` to fetch the next page, or `null` to start from the beginning.
|
|
145
|
+
* @param args.orderBy - The field to sort by: `"_creationTime"`, `"name"`, `"slug"`, or `"type"`.
|
|
146
|
+
* @param args.order - Sort direction: `"asc"` or `"desc"` (defaults to `"desc"`).
|
|
147
|
+
* @returns An object `{ items, nextCursor }` where `items` is an array of group documents and `nextCursor` is `null` when there are no more pages.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* const { items, nextCursor } = await ctx.runQuery(
|
|
152
|
+
* components.auth.groups.groupList,
|
|
153
|
+
* {
|
|
154
|
+
* where: { type: "team", isRoot: false },
|
|
155
|
+
* limit: 20,
|
|
156
|
+
* order: "asc",
|
|
157
|
+
* },
|
|
158
|
+
* );
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
export const groupList = query({
|
|
162
|
+
args: {
|
|
163
|
+
where: v.optional(
|
|
164
|
+
v.object({
|
|
165
|
+
slug: v.optional(v.string()),
|
|
166
|
+
type: v.optional(v.string()),
|
|
167
|
+
parentGroupId: v.optional(v.id("Group")),
|
|
168
|
+
name: v.optional(v.string()),
|
|
169
|
+
isRoot: v.optional(v.boolean()),
|
|
170
|
+
tagsAll: v.optional(v.array(vTag)),
|
|
171
|
+
tagsAny: v.optional(v.array(vTag)),
|
|
172
|
+
}),
|
|
173
|
+
),
|
|
174
|
+
limit: v.optional(v.number()),
|
|
175
|
+
cursor: v.optional(v.union(v.string(), v.null())),
|
|
176
|
+
orderBy: v.optional(
|
|
177
|
+
v.union(
|
|
178
|
+
v.literal("_creationTime"),
|
|
179
|
+
v.literal("name"),
|
|
180
|
+
v.literal("slug"),
|
|
181
|
+
v.literal("type"),
|
|
182
|
+
),
|
|
183
|
+
),
|
|
184
|
+
order: v.optional(v.union(v.literal("asc"), v.literal("desc"))),
|
|
185
|
+
},
|
|
186
|
+
returns: vPaginated(vGroupDoc),
|
|
187
|
+
handler: async (ctx, args) => {
|
|
188
|
+
const where = args.where ?? {};
|
|
189
|
+
const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);
|
|
190
|
+
const order = args.order ?? "desc";
|
|
191
|
+
|
|
192
|
+
// ---- Resolve tag filters into a Set<Id<"Group">> ----
|
|
193
|
+
let tagFilteredIds: Set<string> | null = null;
|
|
194
|
+
|
|
195
|
+
if (where.tagsAll && where.tagsAll.length > 0) {
|
|
196
|
+
// Intersect: group must have ALL specified tags
|
|
197
|
+
let allSet: Set<string> | null = null;
|
|
198
|
+
for (const rawTag of where.tagsAll) {
|
|
199
|
+
const t = normalizeTag(rawTag);
|
|
200
|
+
const rows = await ctx.db
|
|
201
|
+
.query("GroupTag")
|
|
202
|
+
.withIndex("by_key_value", (idx) =>
|
|
203
|
+
idx.eq("key", t.key).eq("value", t.value),
|
|
204
|
+
)
|
|
205
|
+
.collect();
|
|
206
|
+
const ids = new Set(rows.map((r) => r.group_id as string));
|
|
207
|
+
if (allSet === null) {
|
|
208
|
+
allSet = ids;
|
|
209
|
+
} else {
|
|
210
|
+
// Intersect
|
|
211
|
+
for (const id of allSet) {
|
|
212
|
+
if (!ids.has(id)) allSet.delete(id);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Short-circuit: empty intersection
|
|
216
|
+
if (allSet.size === 0) break;
|
|
217
|
+
}
|
|
218
|
+
tagFilteredIds = allSet ?? new Set();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (where.tagsAny && where.tagsAny.length > 0) {
|
|
222
|
+
// Union: group must have at least one of the specified tags
|
|
223
|
+
const anySet = new Set<string>();
|
|
224
|
+
for (const rawTag of where.tagsAny) {
|
|
225
|
+
const t = normalizeTag(rawTag);
|
|
226
|
+
const rows = await ctx.db
|
|
227
|
+
.query("GroupTag")
|
|
228
|
+
.withIndex("by_key_value", (idx) =>
|
|
229
|
+
idx.eq("key", t.key).eq("value", t.value),
|
|
230
|
+
)
|
|
231
|
+
.collect();
|
|
232
|
+
for (const r of rows) {
|
|
233
|
+
anySet.add(r.group_id as string);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (tagFilteredIds !== null) {
|
|
237
|
+
// AND with tagsAll result
|
|
238
|
+
for (const id of tagFilteredIds) {
|
|
239
|
+
if (!anySet.has(id)) tagFilteredIds.delete(id);
|
|
240
|
+
}
|
|
241
|
+
} else {
|
|
242
|
+
tagFilteredIds = anySet;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// ---- Pick best index based on non-tag where fields ----
|
|
247
|
+
let q;
|
|
248
|
+
if (where.type !== undefined && where.parentGroupId !== undefined) {
|
|
249
|
+
q = ctx.db
|
|
250
|
+
.query("Group")
|
|
251
|
+
.withIndex("type_parent_group_id", (idx) =>
|
|
252
|
+
idx.eq("type", where.type!).eq("parentGroupId", where.parentGroupId!),
|
|
253
|
+
);
|
|
254
|
+
} else if (where.slug !== undefined) {
|
|
255
|
+
q = ctx.db
|
|
256
|
+
.query("Group")
|
|
257
|
+
.withIndex("slug", (idx) => idx.eq("slug", where.slug!));
|
|
258
|
+
} else if (where.type !== undefined) {
|
|
259
|
+
q = ctx.db
|
|
260
|
+
.query("Group")
|
|
261
|
+
.withIndex("type", (idx) => idx.eq("type", where.type!));
|
|
262
|
+
} else if (where.parentGroupId !== undefined) {
|
|
263
|
+
q = ctx.db
|
|
264
|
+
.query("Group")
|
|
265
|
+
.withIndex("parent_group_id", (idx) =>
|
|
266
|
+
idx.eq("parentGroupId", where.parentGroupId!),
|
|
267
|
+
);
|
|
268
|
+
} else if (where.isRoot !== undefined) {
|
|
269
|
+
q = ctx.db
|
|
270
|
+
.query("Group")
|
|
271
|
+
.withIndex("is_root", (idx) => idx.eq("isRoot", where.isRoot!));
|
|
272
|
+
} else {
|
|
273
|
+
q = ctx.db.query("Group");
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Apply remaining non-tag filters not covered by index
|
|
277
|
+
if (where.name !== undefined) {
|
|
278
|
+
q = q.filter((f) => f.eq(f.field("name"), where.name!));
|
|
279
|
+
}
|
|
280
|
+
// isRoot filter when not already used as primary index
|
|
281
|
+
if (
|
|
282
|
+
where.isRoot !== undefined &&
|
|
283
|
+
where.parentGroupId === undefined &&
|
|
284
|
+
(where.type !== undefined || where.slug !== undefined)
|
|
285
|
+
) {
|
|
286
|
+
q = q.filter((f) => f.eq(f.field("isRoot"), where.isRoot!));
|
|
287
|
+
}
|
|
288
|
+
// slug filter when not used as index
|
|
289
|
+
if (where.slug !== undefined && where.type !== undefined) {
|
|
290
|
+
q = q.filter((f) => f.eq(f.field("slug"), where.slug!));
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
q = q.order(order);
|
|
294
|
+
|
|
295
|
+
let all = await q.collect();
|
|
296
|
+
|
|
297
|
+
// Apply tag filter (intersect with resolved groupIds)
|
|
298
|
+
if (tagFilteredIds !== null) {
|
|
299
|
+
all = all.filter((doc) => tagFilteredIds!.has(doc._id as string));
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Cursor-based pagination
|
|
303
|
+
let startIdx = 0;
|
|
304
|
+
if (args.cursor) {
|
|
305
|
+
const cursorIdx = all.findIndex((doc) => doc._id === args.cursor);
|
|
306
|
+
if (cursorIdx !== -1) {
|
|
307
|
+
startIdx = cursorIdx + 1;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const page = all.slice(startIdx, startIdx + limit + 1);
|
|
311
|
+
const hasMore = page.length > limit;
|
|
312
|
+
const items = hasMore ? page.slice(0, limit) : page;
|
|
313
|
+
const nextCursor = hasMore ? items[items.length - 1]._id : null;
|
|
314
|
+
return { items, nextCursor };
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Update a group's mutable fields such as `name`, `slug`, `tags`, `extend`,
|
|
320
|
+
* and `parentGroupId`.
|
|
321
|
+
*
|
|
322
|
+
* When `parentGroupId` is changed the mutation automatically recomputes
|
|
323
|
+
* `isRoot` and `rootGroupId` for the target group **and** cascades the new
|
|
324
|
+
* `rootGroupId` to all descendant groups. When `tags` are provided they are
|
|
325
|
+
* normalized, deduplicated, and the companion `GroupTag` rows are fully
|
|
326
|
+
* replaced (delete-then-insert).
|
|
327
|
+
*
|
|
328
|
+
* @param args.groupId - The `Id<"Group">` of the group to update.
|
|
329
|
+
* @param args.data - A partial object of fields to patch. Supported keys include `name`, `slug`, `type`, `parentGroupId`, `tags`, and `extend`.
|
|
330
|
+
* @returns `null` on success.
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* ```ts
|
|
334
|
+
* await ctx.runMutation(components.auth.groups.groupUpdate, {
|
|
335
|
+
* groupId: existingGroupId,
|
|
336
|
+
* data: {
|
|
337
|
+
* name: "Acme Corp (renamed)",
|
|
338
|
+
* tags: [{ key: "plan", value: "pro" }],
|
|
339
|
+
* },
|
|
340
|
+
* });
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
export const groupUpdate = mutation({
|
|
344
|
+
args: { groupId: v.id("Group"), data: v.any() },
|
|
345
|
+
returns: v.null(),
|
|
346
|
+
handler: async (ctx, { groupId, data }) => {
|
|
347
|
+
// If parentGroupId is changing, recompute rootGroupId + isRoot for this group and descendants
|
|
348
|
+
if (data.parentGroupId !== undefined) {
|
|
349
|
+
const oldGroup = await ctx.db.get("Group", groupId);
|
|
350
|
+
const oldRootGroupId = oldGroup?.rootGroupId;
|
|
351
|
+
const newParentGroupId = data.parentGroupId as Id<"Group"> | undefined;
|
|
352
|
+
const newIsRoot = !newParentGroupId;
|
|
353
|
+
let newRootGroupId: Id<"Group">;
|
|
354
|
+
if (newIsRoot) {
|
|
355
|
+
newRootGroupId = groupId;
|
|
356
|
+
} else {
|
|
357
|
+
const parent = await ctx.db.get("Group", newParentGroupId!);
|
|
358
|
+
newRootGroupId = parent?.rootGroupId ?? newParentGroupId!;
|
|
359
|
+
}
|
|
360
|
+
data.isRoot = newIsRoot;
|
|
361
|
+
data.rootGroupId = newRootGroupId;
|
|
362
|
+
// Cascade to descendants if rootGroupId changed
|
|
363
|
+
if (oldRootGroupId && oldRootGroupId !== newRootGroupId) {
|
|
364
|
+
const descendants = await ctx.db
|
|
365
|
+
.query("Group")
|
|
366
|
+
.withIndex("root_group_id", (q) =>
|
|
367
|
+
q.eq("rootGroupId", oldRootGroupId),
|
|
368
|
+
)
|
|
369
|
+
.collect();
|
|
370
|
+
for (const desc of descendants) {
|
|
371
|
+
if (desc._id !== groupId) {
|
|
372
|
+
await ctx.db.patch("Group", desc._id, {
|
|
373
|
+
rootGroupId: newRootGroupId,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// If tags are being updated, normalize and replace the full tag set
|
|
380
|
+
if (data.tags !== undefined) {
|
|
381
|
+
const normalizedTags: TagPair[] = Array.isArray(data.tags)
|
|
382
|
+
? normalizeTags(data.tags as TagPair[])
|
|
383
|
+
: [];
|
|
384
|
+
// Delete existing group_tag rows for this group
|
|
385
|
+
const existingTags = await ctx.db
|
|
386
|
+
.query("GroupTag")
|
|
387
|
+
.withIndex("by_group", (idx) => idx.eq("group_id", groupId))
|
|
388
|
+
.collect();
|
|
389
|
+
for (const existing of existingTags) {
|
|
390
|
+
await ctx.db.delete("GroupTag", existing._id);
|
|
391
|
+
}
|
|
392
|
+
// Insert new normalized group_tag rows
|
|
393
|
+
for (const tag of normalizedTags) {
|
|
394
|
+
await ctx.db.insert("GroupTag", {
|
|
395
|
+
group_id: groupId,
|
|
396
|
+
key: tag.key,
|
|
397
|
+
value: tag.value,
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
// Patch group with normalized tags (empty array = clear all)
|
|
401
|
+
await ctx.db.patch("Group", groupId, {
|
|
402
|
+
...data,
|
|
403
|
+
tags: normalizedTags.length > 0 ? normalizedTags : undefined,
|
|
404
|
+
});
|
|
405
|
+
} else {
|
|
406
|
+
await ctx.db.patch("Group", groupId, data);
|
|
407
|
+
}
|
|
408
|
+
return null;
|
|
409
|
+
},
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Delete a group and all of its descendants. This cascades to:
|
|
414
|
+
* - All child groups (recursively)
|
|
415
|
+
* - All members of this group and its descendants
|
|
416
|
+
* - All invites for this group and its descendants
|
|
417
|
+
* - All companion `GroupTag` rows for this group and its descendants
|
|
418
|
+
*
|
|
419
|
+
* The deletion walks the group tree depth-first, removing leaves before
|
|
420
|
+
* parents, so referential integrity is maintained throughout.
|
|
421
|
+
*
|
|
422
|
+
* @param args.groupId - The `Id<"Group">` of the group to delete. All children are deleted recursively.
|
|
423
|
+
* @returns `null` on success.
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```ts
|
|
427
|
+
* // Delete an organization and everything nested under it
|
|
428
|
+
* await ctx.runMutation(components.auth.groups.groupDelete, {
|
|
429
|
+
* groupId: organizationGroupId,
|
|
430
|
+
* });
|
|
431
|
+
* ```
|
|
432
|
+
*/
|
|
433
|
+
export const groupDelete = mutation({
|
|
434
|
+
args: { groupId: v.id("Group") },
|
|
435
|
+
returns: v.null(),
|
|
436
|
+
handler: async (ctx, { groupId }) => {
|
|
437
|
+
const deleteGroup = async (id: typeof groupId) => {
|
|
438
|
+
const children = await ctx.db
|
|
439
|
+
.query("Group")
|
|
440
|
+
.withIndex("parent_group_id", (q) => q.eq("parentGroupId", id))
|
|
441
|
+
.collect();
|
|
442
|
+
for (const child of children) {
|
|
443
|
+
await deleteGroup(child._id);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
const members = await ctx.db
|
|
447
|
+
.query("GroupMember")
|
|
448
|
+
.withIndex("group_id", (q) => q.eq("groupId", id))
|
|
449
|
+
.collect();
|
|
450
|
+
for (const member of members) {
|
|
451
|
+
await ctx.db.delete("GroupMember", member._id);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
const invites = await ctx.db
|
|
455
|
+
.query("GroupInvite")
|
|
456
|
+
.withIndex("group_id", (q) => q.eq("groupId", id))
|
|
457
|
+
.collect();
|
|
458
|
+
for (const invite of invites) {
|
|
459
|
+
await ctx.db.delete("GroupInvite", invite._id);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Delete companion group_tag rows
|
|
463
|
+
const tags = await ctx.db
|
|
464
|
+
.query("GroupTag")
|
|
465
|
+
.withIndex("by_group", (q) => q.eq("group_id", id))
|
|
466
|
+
.collect();
|
|
467
|
+
for (const tag of tags) {
|
|
468
|
+
await ctx.db.delete("GroupTag", tag._id);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
await ctx.db.delete("Group", id);
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
await deleteGroup(groupId);
|
|
475
|
+
return null;
|
|
476
|
+
},
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
// ============================================================================
|
|
480
|
+
// Members
|
|
481
|
+
// ============================================================================
|