@masheev/better-auth 0.0.0-stage → 1.7.5
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/LICENSE.md +20 -0
- package/README.md +31 -2
- package/TYPE-PATCH-NOTICE.md +9 -0
- package/TYPE-PATCH-PROVENANCE.json +267 -0
- package/dist/_virtual/_rolldown/runtime.mjs +27 -0
- package/dist/adapters/drizzle-adapter/index.d.mts +1 -0
- package/dist/adapters/drizzle-adapter/index.mjs +2 -0
- package/dist/adapters/index.d.mts +26 -0
- package/dist/adapters/index.mjs +9 -0
- package/dist/adapters/kysely-adapter/index.d.mts +1 -0
- package/dist/adapters/kysely-adapter/index.mjs +2 -0
- package/dist/adapters/memory-adapter/index.d.mts +1 -0
- package/dist/adapters/memory-adapter/index.mjs +2 -0
- package/dist/adapters/mongodb-adapter/index.d.mts +1 -0
- package/dist/adapters/mongodb-adapter/index.mjs +2 -0
- package/dist/adapters/prisma-adapter/index.d.mts +1 -0
- package/dist/adapters/prisma-adapter/index.mjs +2 -0
- package/dist/api/dispatch.d.mts +34 -0
- package/dist/api/dispatch.mjs +275 -0
- package/dist/api/index.d.mts +4053 -0
- package/dist/api/index.mjs +220 -0
- package/dist/api/middlewares/authorization.d.mts +69 -0
- package/dist/api/middlewares/authorization.mjs +78 -0
- package/dist/api/middlewares/index.d.mts +2 -0
- package/dist/api/middlewares/origin-check.d.mts +17 -0
- package/dist/api/middlewares/origin-check.mjs +155 -0
- package/dist/api/rate-limiter/index.mjs +318 -0
- package/dist/api/routes/account.d.mts +413 -0
- package/dist/api/routes/account.mjs +619 -0
- package/dist/api/routes/callback.d.mts +32 -0
- package/dist/api/routes/callback.mjs +261 -0
- package/dist/api/routes/email-verification.d.mts +160 -0
- package/dist/api/routes/email-verification.mjs +324 -0
- package/dist/api/routes/error.d.mts +27 -0
- package/dist/api/routes/error.mjs +387 -0
- package/dist/api/routes/index.d.mts +12 -0
- package/dist/api/routes/ok.d.mts +35 -0
- package/dist/api/routes/ok.mjs +27 -0
- package/dist/api/routes/password.d.mts +182 -0
- package/dist/api/routes/password.mjs +206 -0
- package/dist/api/routes/session.d.mts +450 -0
- package/dist/api/routes/session.mjs +481 -0
- package/dist/api/routes/sign-in.d.mts +186 -0
- package/dist/api/routes/sign-in.mjs +368 -0
- package/dist/api/routes/sign-out.d.mts +51 -0
- package/dist/api/routes/sign-out.mjs +96 -0
- package/dist/api/routes/sign-up.d.mts +159 -0
- package/dist/api/routes/sign-up.mjs +275 -0
- package/dist/api/routes/update-session.d.mts +74 -0
- package/dist/api/routes/update-session.mjs +57 -0
- package/dist/api/routes/update-user.d.mts +428 -0
- package/dist/api/routes/update-user.mjs +522 -0
- package/dist/api/state/oauth.d.mts +53 -0
- package/dist/api/state/oauth.mjs +38 -0
- package/dist/api/state/should-session-refresh.d.mts +12 -0
- package/dist/api/state/should-session-refresh.mjs +13 -0
- package/dist/api/to-auth-endpoints.mjs +60 -0
- package/dist/auth/base.mjs +66 -0
- package/dist/auth/full.d.mts +28 -0
- package/dist/auth/full.mjs +29 -0
- package/dist/auth/minimal.d.mts +10 -0
- package/dist/auth/minimal.mjs +11 -0
- package/dist/auth/trusted-origins.mjs +106 -0
- package/dist/client/broadcast-channel.d.mts +19 -0
- package/dist/client/broadcast-channel.mjs +44 -0
- package/dist/client/config.d.mts +90 -0
- package/dist/client/config.mjs +113 -0
- package/dist/client/equality.d.mts +19 -0
- package/dist/client/equality.mjs +42 -0
- package/dist/client/fetch-plugins.mjs +17 -0
- package/dist/client/focus-manager.d.mts +10 -0
- package/dist/client/focus-manager.mjs +30 -0
- package/dist/client/index.d.mts +35 -0
- package/dist/client/index.mjs +22 -0
- package/dist/client/lynx/index.d.mts +43 -0
- package/dist/client/lynx/index.mjs +22 -0
- package/dist/client/lynx/lynx-store.d.mts +46 -0
- package/dist/client/lynx/lynx-store.mjs +44 -0
- package/dist/client/online-manager.d.mts +11 -0
- package/dist/client/online-manager.mjs +33 -0
- package/dist/client/parser.d.mts +10 -0
- package/dist/client/parser.mjs +70 -0
- package/dist/client/path-to-object.d.mts +113 -0
- package/dist/client/plugins/index.d.mts +44 -0
- package/dist/client/plugins/index.mjs +30 -0
- package/dist/client/plugins/infer-plugin.d.mts +16 -0
- package/dist/client/plugins/infer-plugin.mjs +11 -0
- package/dist/client/proxy.mjs +78 -0
- package/dist/client/query.d.mts +23 -0
- package/dist/client/query.mjs +124 -0
- package/dist/client/react/index.d.mts +44 -0
- package/dist/client/react/index.mjs +22 -0
- package/dist/client/react/react-store.d.mts +46 -0
- package/dist/client/react/react-store.mjs +44 -0
- package/dist/client/session-atom.d.mts +11 -0
- package/dist/client/session-atom.mjs +178 -0
- package/dist/client/session-refresh.d.mts +20 -0
- package/dist/client/session-refresh.mjs +131 -0
- package/dist/client/solid/index.d.mts +44 -0
- package/dist/client/solid/index.mjs +22 -0
- package/dist/client/solid/solid-store.mjs +21 -0
- package/dist/client/svelte/index.d.mts +44 -0
- package/dist/client/svelte/index.mjs +18 -0
- package/dist/client/types.d.mts +51 -0
- package/dist/client/vanilla.d.mts +42 -0
- package/dist/client/vanilla.mjs +18 -0
- package/dist/client/vue/index.d.mts +67 -0
- package/dist/client/vue/index.mjs +54 -0
- package/dist/client/vue/vue-store.mjs +23 -0
- package/dist/context/create-context.mjs +235 -0
- package/dist/context/helpers.mjs +158 -0
- package/dist/context/init-minimal.mjs +17 -0
- package/dist/context/init.mjs +19 -0
- package/dist/context/secret-utils.mjs +53 -0
- package/dist/context/store-capabilities.mjs +12 -0
- package/dist/cookies/cache.mjs +33 -0
- package/dist/cookies/cookie-utils.d.mts +72 -0
- package/dist/cookies/cookie-utils.mjs +203 -0
- package/dist/cookies/index.d.mts +124 -0
- package/dist/cookies/index.mjs +350 -0
- package/dist/cookies/jwt.mjs +44 -0
- package/dist/cookies/session-store.d.mts +32 -0
- package/dist/cookies/session-store.mjs +183 -0
- package/dist/crypto/buffer.d.mts +7 -0
- package/dist/crypto/buffer.mjs +16 -0
- package/dist/crypto/index.d.mts +32 -0
- package/dist/crypto/index.mjs +69 -0
- package/dist/crypto/jwt.d.mts +9 -0
- package/dist/crypto/jwt.mjs +141 -0
- package/dist/crypto/password.d.mts +13 -0
- package/dist/crypto/password.mjs +14 -0
- package/dist/crypto/random.d.mts +4 -0
- package/dist/crypto/random.mjs +5 -0
- package/dist/db/adapter-base.d.mts +7 -0
- package/dist/db/adapter-base.mjs +25 -0
- package/dist/db/adapter-kysely.d.mts +7 -0
- package/dist/db/adapter-kysely.mjs +17 -0
- package/dist/db/field-converter.d.mts +7 -0
- package/dist/db/field-converter.mjs +19 -0
- package/dist/db/field.d.mts +41 -0
- package/dist/db/get-migration.d.mts +56 -0
- package/dist/db/get-migration.mjs +685 -0
- package/dist/db/get-schema.d.mts +13 -0
- package/dist/db/get-schema.mjs +39 -0
- package/dist/db/index.d.mts +10 -0
- package/dist/db/index.mjs +35 -0
- package/dist/db/internal-adapter.d.mts +14 -0
- package/dist/db/internal-adapter.mjs +951 -0
- package/dist/db/revoke-unproven-account-access.d.mts +21 -0
- package/dist/db/revoke-unproven-account-access.mjs +58 -0
- package/dist/db/schema.d.mts +62 -0
- package/dist/db/schema.mjs +161 -0
- package/dist/db/to-zod.d.mts +35 -0
- package/dist/db/to-zod.mjs +23 -0
- package/dist/db/verification-token-storage.mjs +25 -0
- package/dist/db/with-hooks.d.mts +37 -0
- package/dist/db/with-hooks.mjs +255 -0
- package/dist/index.d.mts +30 -0
- package/dist/index.mjs +17 -0
- package/dist/integrations/cookie-plugin-guard.mjs +18 -0
- package/dist/integrations/next-js.d.mts +29 -0
- package/dist/integrations/next-js.mjs +105 -0
- package/dist/integrations/node.d.mts +11 -0
- package/dist/integrations/node.mjs +13 -0
- package/dist/integrations/solid-start.d.mts +22 -0
- package/dist/integrations/solid-start.mjs +15 -0
- package/dist/integrations/svelte-kit.d.mts +38 -0
- package/dist/integrations/svelte-kit.mjs +57 -0
- package/dist/integrations/tanstack-start-solid.d.mts +33 -0
- package/dist/integrations/tanstack-start-solid.mjs +57 -0
- package/dist/integrations/tanstack-start.d.mts +33 -0
- package/dist/integrations/tanstack-start.mjs +57 -0
- package/dist/oauth2/account-key.mjs +43 -0
- package/dist/oauth2/errors.mjs +49 -0
- package/dist/oauth2/index.d.mts +5 -0
- package/dist/oauth2/index.mjs +5 -0
- package/dist/oauth2/link-account.d.mts +96 -0
- package/dist/oauth2/link-account.mjs +329 -0
- package/dist/oauth2/state.d.mts +54 -0
- package/dist/oauth2/state.mjs +67 -0
- package/dist/oauth2/utils.d.mts +11 -0
- package/dist/oauth2/utils.mjs +33 -0
- package/dist/package.mjs +4 -0
- package/dist/plugins/access/access.d.mts +17 -0
- package/dist/plugins/access/access.mjs +78 -0
- package/dist/plugins/access/index.d.mts +3 -0
- package/dist/plugins/access/index.mjs +2 -0
- package/dist/plugins/access/types.d.mts +24 -0
- package/dist/plugins/additional-fields/client.d.mts +100 -0
- package/dist/plugins/additional-fields/client.mjs +11 -0
- package/dist/plugins/admin/access/index.d.mts +2 -0
- package/dist/plugins/admin/access/index.mjs +2 -0
- package/dist/plugins/admin/access/statement.d.mts +51 -0
- package/dist/plugins/admin/access/statement.mjs +52 -0
- package/dist/plugins/admin/admin.d.mts +911 -0
- package/dist/plugins/admin/admin.mjs +89 -0
- package/dist/plugins/admin/client.d.mts +81 -0
- package/dist/plugins/admin/client.mjs +39 -0
- package/dist/plugins/admin/error-codes.d.mts +30 -0
- package/dist/plugins/admin/error-codes.mjs +29 -0
- package/dist/plugins/admin/has-permission.mjs +12 -0
- package/dist/plugins/admin/index.d.mts +3 -0
- package/dist/plugins/admin/index.mjs +2 -0
- package/dist/plugins/admin/routes.mjs +919 -0
- package/dist/plugins/admin/schema.d.mts +40 -0
- package/dist/plugins/admin/schema.mjs +33 -0
- package/dist/plugins/admin/types.d.mts +88 -0
- package/dist/plugins/anonymous/client.d.mts +32 -0
- package/dist/plugins/anonymous/client.mjs +21 -0
- package/dist/plugins/anonymous/error-codes.d.mts +15 -0
- package/dist/plugins/anonymous/error-codes.mjs +14 -0
- package/dist/plugins/anonymous/index.d.mts +175 -0
- package/dist/plugins/anonymous/index.mjs +219 -0
- package/dist/plugins/anonymous/schema.d.mts +15 -0
- package/dist/plugins/anonymous/schema.mjs +9 -0
- package/dist/plugins/anonymous/types.d.mts +65 -0
- package/dist/plugins/bearer/index.d.mts +45 -0
- package/dist/plugins/bearer/index.mjs +74 -0
- package/dist/plugins/captcha/constants.d.mts +9 -0
- package/dist/plugins/captcha/constants.mjs +27 -0
- package/dist/plugins/captcha/error-codes.mjs +13 -0
- package/dist/plugins/captcha/index.d.mts +27 -0
- package/dist/plugins/captcha/index.mjs +79 -0
- package/dist/plugins/captcha/types.d.mts +52 -0
- package/dist/plugins/captcha/utils.mjs +9 -0
- package/dist/plugins/captcha/verify-handlers/captchafox.mjs +27 -0
- package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs +47 -0
- package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs +32 -0
- package/dist/plugins/captcha/verify-handlers/h-captcha.mjs +27 -0
- package/dist/plugins/custom-session/client.d.mts +17 -0
- package/dist/plugins/custom-session/client.mjs +7 -0
- package/dist/plugins/custom-session/index.d.mts +73 -0
- package/dist/plugins/custom-session/index.mjs +65 -0
- package/dist/plugins/device-authorization/client.d.mts +17 -0
- package/dist/plugins/device-authorization/client.mjs +18 -0
- package/dist/plugins/device-authorization/error-codes.mjs +19 -0
- package/dist/plugins/device-authorization/index.d.mts +558 -0
- package/dist/plugins/device-authorization/index.mjs +87 -0
- package/dist/plugins/device-authorization/routes.d.mts +32 -0
- package/dist/plugins/device-authorization/routes.mjs +725 -0
- package/dist/plugins/device-authorization/schema.d.mts +18 -0
- package/dist/plugins/device-authorization/schema.mjs +63 -0
- package/dist/plugins/email-otp/client.d.mts +21 -0
- package/dist/plugins/email-otp/client.mjs +17 -0
- package/dist/plugins/email-otp/error-codes.d.mts +10 -0
- package/dist/plugins/email-otp/error-codes.mjs +9 -0
- package/dist/plugins/email-otp/index.d.mts +551 -0
- package/dist/plugins/email-otp/index.mjs +145 -0
- package/dist/plugins/email-otp/otp-token.mjs +55 -0
- package/dist/plugins/email-otp/routes.mjs +784 -0
- package/dist/plugins/email-otp/types.d.mts +109 -0
- package/dist/plugins/email-otp/utils.mjs +17 -0
- package/dist/plugins/generic-oauth/error-codes.mjs +8 -0
- package/dist/plugins/generic-oauth/index.d.mts +52 -0
- package/dist/plugins/generic-oauth/index.mjs +279 -0
- package/dist/plugins/generic-oauth/providers/auth0.d.mts +36 -0
- package/dist/plugins/generic-oauth/providers/auth0.mjs +49 -0
- package/dist/plugins/generic-oauth/providers/gumroad.d.mts +31 -0
- package/dist/plugins/generic-oauth/providers/gumroad.mjs +62 -0
- package/dist/plugins/generic-oauth/providers/hubspot.d.mts +36 -0
- package/dist/plugins/generic-oauth/providers/hubspot.mjs +62 -0
- package/dist/plugins/generic-oauth/providers/index.d.mts +10 -0
- package/dist/plugins/generic-oauth/providers/keycloak.d.mts +36 -0
- package/dist/plugins/generic-oauth/providers/keycloak.mjs +47 -0
- package/dist/plugins/generic-oauth/providers/line.d.mts +54 -0
- package/dist/plugins/generic-oauth/providers/line.mjs +93 -0
- package/dist/plugins/generic-oauth/providers/microsoft-entra-id.d.mts +39 -0
- package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs +104 -0
- package/dist/plugins/generic-oauth/providers/okta.d.mts +36 -0
- package/dist/plugins/generic-oauth/providers/okta.mjs +47 -0
- package/dist/plugins/generic-oauth/providers/patreon.d.mts +29 -0
- package/dist/plugins/generic-oauth/providers/patreon.mjs +61 -0
- package/dist/plugins/generic-oauth/providers/slack.d.mts +29 -0
- package/dist/plugins/generic-oauth/providers/slack.mjs +63 -0
- package/dist/plugins/generic-oauth/providers/yandex.d.mts +29 -0
- package/dist/plugins/generic-oauth/providers/yandex.mjs +67 -0
- package/dist/plugins/generic-oauth/types.d.mts +268 -0
- package/dist/plugins/haveibeenpwned/index.d.mts +63 -0
- package/dist/plugins/haveibeenpwned/index.mjs +81 -0
- package/dist/plugins/index.d.mts +69 -0
- package/dist/plugins/index.mjs +49 -0
- package/dist/plugins/jwt/adapter.mjs +68 -0
- package/dist/plugins/jwt/client.d.mts +41 -0
- package/dist/plugins/jwt/client.mjs +19 -0
- package/dist/plugins/jwt/cookie-cache.mjs +77 -0
- package/dist/plugins/jwt/index.d.mts +246 -0
- package/dist/plugins/jwt/index.mjs +214 -0
- package/dist/plugins/jwt/schema.d.mts +33 -0
- package/dist/plugins/jwt/schema.mjs +29 -0
- package/dist/plugins/jwt/sign.d.mts +128 -0
- package/dist/plugins/jwt/sign.mjs +130 -0
- package/dist/plugins/jwt/types.d.mts +256 -0
- package/dist/plugins/jwt/utils.d.mts +41 -0
- package/dist/plugins/jwt/utils.mjs +64 -0
- package/dist/plugins/jwt/verify.d.mts +11 -0
- package/dist/plugins/jwt/verify.mjs +45 -0
- package/dist/plugins/last-login-method/client.d.mts +48 -0
- package/dist/plugins/last-login-method/client.mjs +48 -0
- package/dist/plugins/last-login-method/index.d.mts +127 -0
- package/dist/plugins/last-login-method/index.mjs +98 -0
- package/dist/plugins/magic-link/client.d.mts +10 -0
- package/dist/plugins/magic-link/client.mjs +11 -0
- package/dist/plugins/magic-link/index.d.mts +213 -0
- package/dist/plugins/magic-link/index.mjs +208 -0
- package/dist/plugins/magic-link/utils.mjs +9 -0
- package/dist/plugins/multi-session/client.d.mts +19 -0
- package/dist/plugins/multi-session/client.mjs +19 -0
- package/dist/plugins/multi-session/error-codes.d.mts +8 -0
- package/dist/plugins/multi-session/error-codes.mjs +5 -0
- package/dist/plugins/multi-session/index.d.mts +212 -0
- package/dist/plugins/multi-session/index.mjs +217 -0
- package/dist/plugins/oauth-popup/client.d.mts +82 -0
- package/dist/plugins/oauth-popup/client.mjs +203 -0
- package/dist/plugins/oauth-popup/constants.d.mts +11 -0
- package/dist/plugins/oauth-popup/constants.mjs +11 -0
- package/dist/plugins/oauth-popup/error-codes.d.mts +11 -0
- package/dist/plugins/oauth-popup/error-codes.mjs +10 -0
- package/dist/plugins/oauth-popup/index.d.mts +67 -0
- package/dist/plugins/oauth-popup/index.mjs +232 -0
- package/dist/plugins/oauth-popup/types.d.mts +30 -0
- package/dist/plugins/oauth-proxy/index.d.mts +130 -0
- package/dist/plugins/oauth-proxy/index.mjs +407 -0
- package/dist/plugins/oauth-proxy/utils.mjs +55 -0
- package/dist/plugins/one-tap/client.d.mts +174 -0
- package/dist/plugins/one-tap/client.mjs +208 -0
- package/dist/plugins/one-tap/index.d.mts +82 -0
- package/dist/plugins/one-tap/index.mjs +100 -0
- package/dist/plugins/one-time-token/client.d.mts +10 -0
- package/dist/plugins/one-time-token/client.mjs +11 -0
- package/dist/plugins/one-time-token/index.d.mts +132 -0
- package/dist/plugins/one-time-token/index.mjs +107 -0
- package/dist/plugins/one-time-token/utils.mjs +9 -0
- package/dist/plugins/open-api/generator.d.mts +126 -0
- package/dist/plugins/open-api/generator.mjs +557 -0
- package/dist/plugins/open-api/index.d.mts +97 -0
- package/dist/plugins/open-api/index.mjs +65 -0
- package/dist/plugins/open-api/logo.mjs +13 -0
- package/dist/plugins/organization/access/index.d.mts +2 -0
- package/dist/plugins/organization/access/index.mjs +2 -0
- package/dist/plugins/organization/access/statement.d.mts +113 -0
- package/dist/plugins/organization/access/statement.mjs +77 -0
- package/dist/plugins/organization/adapter.d.mts +815 -0
- package/dist/plugins/organization/adapter.mjs +813 -0
- package/dist/plugins/organization/call.mjs +15 -0
- package/dist/plugins/organization/client.d.mts +375 -0
- package/dist/plugins/organization/client.mjs +104 -0
- package/dist/plugins/organization/error-codes.d.mts +66 -0
- package/dist/plugins/organization/error-codes.mjs +65 -0
- package/dist/plugins/organization/has-permission.d.mts +17 -0
- package/dist/plugins/organization/has-permission.mjs +34 -0
- package/dist/plugins/organization/index.d.mts +6 -0
- package/dist/plugins/organization/index.mjs +4 -0
- package/dist/plugins/organization/organization.d.mts +420 -0
- package/dist/plugins/organization/organization.mjs +886 -0
- package/dist/plugins/organization/permission.d.mts +15 -0
- package/dist/plugins/organization/permission.mjs +14 -0
- package/dist/plugins/organization/routes/crud-access-control.d.mts +511 -0
- package/dist/plugins/organization/routes/crud-access-control.mjs +674 -0
- package/dist/plugins/organization/routes/crud-invites.d.mts +1154 -0
- package/dist/plugins/organization/routes/crud-invites.mjs +602 -0
- package/dist/plugins/organization/routes/crud-members.d.mts +1057 -0
- package/dist/plugins/organization/routes/crud-members.mjs +518 -0
- package/dist/plugins/organization/routes/crud-org.d.mts +918 -0
- package/dist/plugins/organization/routes/crud-org.mjs +455 -0
- package/dist/plugins/organization/routes/crud-team.d.mts +1238 -0
- package/dist/plugins/organization/routes/crud-team.mjs +766 -0
- package/dist/plugins/organization/schema.d.mts +390 -0
- package/dist/plugins/organization/schema.mjs +65 -0
- package/dist/plugins/organization/types.d.mts +691 -0
- package/dist/plugins/phone-number/client.d.mts +31 -0
- package/dist/plugins/phone-number/client.mjs +19 -0
- package/dist/plugins/phone-number/error-codes.d.mts +19 -0
- package/dist/plugins/phone-number/error-codes.mjs +18 -0
- package/dist/plugins/phone-number/index.d.mts +360 -0
- package/dist/plugins/phone-number/index.mjs +57 -0
- package/dist/plugins/phone-number/routes.mjs +529 -0
- package/dist/plugins/phone-number/schema.d.mts +22 -0
- package/dist/plugins/phone-number/schema.mjs +18 -0
- package/dist/plugins/phone-number/types.d.mts +116 -0
- package/dist/plugins/siwe/client.d.mts +14 -0
- package/dist/plugins/siwe/client.mjs +15 -0
- package/dist/plugins/siwe/index.d.mts +62 -0
- package/dist/plugins/siwe/index.mjs +272 -0
- package/dist/plugins/siwe/parse-message.mjs +60 -0
- package/dist/plugins/siwe/schema.d.mts +35 -0
- package/dist/plugins/siwe/schema.mjs +30 -0
- package/dist/plugins/siwe/types.d.mts +43 -0
- package/dist/plugins/test-utils/auth-helpers.mjs +33 -0
- package/dist/plugins/test-utils/cookie-builder.mjs +55 -0
- package/dist/plugins/test-utils/db-helpers.mjs +65 -0
- package/dist/plugins/test-utils/factories.mjs +38 -0
- package/dist/plugins/test-utils/index.d.mts +73 -0
- package/dist/plugins/test-utils/index.mjs +97 -0
- package/dist/plugins/test-utils/otp-sink.mjs +21 -0
- package/dist/plugins/test-utils/types.d.mts +51 -0
- package/dist/plugins/two-factor/backup-codes/index.d.mts +291 -0
- package/dist/plugins/two-factor/backup-codes/index.mjs +341 -0
- package/dist/plugins/two-factor/client.d.mts +76 -0
- package/dist/plugins/two-factor/client.mjs +41 -0
- package/dist/plugins/two-factor/constant.mjs +6 -0
- package/dist/plugins/two-factor/error-code.d.mts +20 -0
- package/dist/plugins/two-factor/error-code.mjs +19 -0
- package/dist/plugins/two-factor/index.d.mts +720 -0
- package/dist/plugins/two-factor/index.mjs +349 -0
- package/dist/plugins/two-factor/otp/index.d.mts +216 -0
- package/dist/plugins/two-factor/otp/index.mjs +252 -0
- package/dist/plugins/two-factor/schema.d.mts +59 -0
- package/dist/plugins/two-factor/schema.mjs +53 -0
- package/dist/plugins/two-factor/totp/index.d.mts +219 -0
- package/dist/plugins/two-factor/totp/index.mjs +230 -0
- package/dist/plugins/two-factor/types.d.mts +111 -0
- package/dist/plugins/two-factor/utils.mjs +9 -0
- package/dist/plugins/two-factor/verify-two-factor.mjs +205 -0
- package/dist/plugins/username/client.d.mts +38 -0
- package/dist/plugins/username/client.mjs +17 -0
- package/dist/plugins/username/error-codes.d.mts +16 -0
- package/dist/plugins/username/error-codes.mjs +15 -0
- package/dist/plugins/username/index.d.mts +326 -0
- package/dist/plugins/username/index.mjs +312 -0
- package/dist/plugins/username/schema.d.mts +50 -0
- package/dist/plugins/username/schema.mjs +25 -0
- package/dist/social-providers/index.d.mts +1 -0
- package/dist/social-providers/index.mjs +2 -0
- package/dist/state.d.mts +48 -0
- package/dist/state.mjs +149 -0
- package/dist/test-utils/headers.d.mts +8 -0
- package/dist/test-utils/headers.mjs +17 -0
- package/dist/test-utils/http-test-instance.d.mts +413 -0
- package/dist/test-utils/http-test-instance.mjs +107 -0
- package/dist/test-utils/index.d.mts +4 -0
- package/dist/test-utils/index.mjs +4 -0
- package/dist/test-utils/test-instance.d.mts +56 -0
- package/dist/test-utils/test-instance.mjs +242 -0
- package/dist/types/adapter.d.mts +2 -0
- package/dist/types/api.d.mts +28 -0
- package/dist/types/auth.d.mts +32 -0
- package/dist/types/helper.d.mts +26 -0
- package/dist/types/index.d.mts +10 -0
- package/dist/types/index.mjs +1 -0
- package/dist/types/models.d.mts +10 -0
- package/dist/types/plugins.d.mts +19 -0
- package/dist/utils/boolean.mjs +6 -0
- package/dist/utils/constants.mjs +4 -0
- package/dist/utils/date.mjs +6 -0
- package/dist/utils/hashing.mjs +18 -0
- package/dist/utils/hide-metadata.d.mts +6 -0
- package/dist/utils/hide-metadata.mjs +4 -0
- package/dist/utils/index.d.mts +4 -0
- package/dist/utils/is-api-error.d.mts +2 -0
- package/dist/utils/is-api-error.mjs +2 -0
- package/dist/utils/is-atom.mjs +6 -0
- package/dist/utils/is-promise.mjs +6 -0
- package/dist/utils/middleware-response.mjs +7 -0
- package/dist/utils/password.mjs +32 -0
- package/dist/utils/plugin-helper.mjs +14 -0
- package/dist/utils/request.mjs +23 -0
- package/dist/utils/shim.mjs +22 -0
- package/dist/utils/time.d.mts +48 -0
- package/dist/utils/time.mjs +98 -0
- package/dist/utils/url.d.mts +78 -0
- package/dist/utils/url.mjs +238 -0
- package/dist/utils/validate-user-info.mjs +44 -0
- package/dist/utils/wildcard.mjs +106 -0
- package/dist/version.mjs +5 -0
- package/package.json +595 -3
|
@@ -0,0 +1,766 @@
|
|
|
1
|
+
import { setSessionCookie } from "../../../cookies/index.mjs";
|
|
2
|
+
import { toZodSchema } from "../../../db/to-zod.mjs";
|
|
3
|
+
import { getSessionFromCtx } from "../../../api/routes/session.mjs";
|
|
4
|
+
import { ORGANIZATION_ERROR_CODES } from "../error-codes.mjs";
|
|
5
|
+
import { getOrgAdapter } from "../adapter.mjs";
|
|
6
|
+
import { orgMiddleware, orgSessionMiddleware } from "../call.mjs";
|
|
7
|
+
import { hasPermission } from "../has-permission.mjs";
|
|
8
|
+
import { teamSchema } from "../schema.mjs";
|
|
9
|
+
import { getCurrentAdapter, runWithTransaction } from "@better-auth/core/context";
|
|
10
|
+
import { APIError } from "@better-auth/core/error";
|
|
11
|
+
import { createAuthEndpoint } from "@better-auth/core/api";
|
|
12
|
+
import * as z from "zod";
|
|
13
|
+
//#region src/plugins/organization/routes/crud-team.ts
|
|
14
|
+
const teamBaseSchema = z.object({
|
|
15
|
+
name: z.string().meta({ description: "The name of the team. Eg: \"my-team\"" }),
|
|
16
|
+
organizationId: z.string().meta({ description: "The organization ID which the team will be created in. Defaults to the active organization. Eg: \"organization-id\"" }).optional()
|
|
17
|
+
});
|
|
18
|
+
const createTeam = (options) => {
|
|
19
|
+
const additionalFieldsSchema = toZodSchema({
|
|
20
|
+
fields: options?.schema?.team?.additionalFields ?? {},
|
|
21
|
+
isClientSide: true
|
|
22
|
+
});
|
|
23
|
+
return createAuthEndpoint("/organization/create-team", {
|
|
24
|
+
method: "POST",
|
|
25
|
+
body: z.object({
|
|
26
|
+
...teamBaseSchema.shape,
|
|
27
|
+
...additionalFieldsSchema.shape
|
|
28
|
+
}),
|
|
29
|
+
use: [orgMiddleware],
|
|
30
|
+
metadata: {
|
|
31
|
+
$Infer: { body: {} },
|
|
32
|
+
openapi: {
|
|
33
|
+
description: "Create a new team within an organization",
|
|
34
|
+
responses: { "200": {
|
|
35
|
+
description: "Team created successfully",
|
|
36
|
+
content: { "application/json": { schema: {
|
|
37
|
+
type: "object",
|
|
38
|
+
properties: {
|
|
39
|
+
id: {
|
|
40
|
+
type: "string",
|
|
41
|
+
description: "Unique identifier of the created team"
|
|
42
|
+
},
|
|
43
|
+
name: {
|
|
44
|
+
type: "string",
|
|
45
|
+
description: "Name of the team"
|
|
46
|
+
},
|
|
47
|
+
organizationId: {
|
|
48
|
+
type: "string",
|
|
49
|
+
description: "ID of the organization the team belongs to"
|
|
50
|
+
},
|
|
51
|
+
createdAt: {
|
|
52
|
+
type: "string",
|
|
53
|
+
format: "date-time",
|
|
54
|
+
description: "Timestamp when the team was created"
|
|
55
|
+
},
|
|
56
|
+
updatedAt: {
|
|
57
|
+
type: "string",
|
|
58
|
+
format: "date-time",
|
|
59
|
+
description: "Timestamp when the team was last updated"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
required: [
|
|
63
|
+
"id",
|
|
64
|
+
"name",
|
|
65
|
+
"organizationId",
|
|
66
|
+
"createdAt",
|
|
67
|
+
"updatedAt"
|
|
68
|
+
]
|
|
69
|
+
} } }
|
|
70
|
+
} }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}, async (ctx) => {
|
|
74
|
+
const session = await getSessionFromCtx(ctx);
|
|
75
|
+
const organizationId = ctx.body.organizationId || session?.session.activeOrganizationId;
|
|
76
|
+
if (!session && (ctx.request || ctx.headers)) throw APIError.fromStatus("UNAUTHORIZED");
|
|
77
|
+
if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
|
|
78
|
+
const adapter = getOrgAdapter(ctx.context, options);
|
|
79
|
+
if (session) {
|
|
80
|
+
const member = await adapter.findMemberByOrgId({
|
|
81
|
+
userId: session.user.id,
|
|
82
|
+
organizationId
|
|
83
|
+
});
|
|
84
|
+
if (!member) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_INVITE_USERS_TO_THIS_ORGANIZATION);
|
|
85
|
+
if (!await hasPermission({
|
|
86
|
+
role: member.role,
|
|
87
|
+
options: ctx.context.orgOptions,
|
|
88
|
+
permissions: { team: ["create"] },
|
|
89
|
+
organizationId
|
|
90
|
+
}, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_CREATE_TEAMS_IN_THIS_ORGANIZATION);
|
|
91
|
+
}
|
|
92
|
+
const existingTeams = await adapter.listTeams(organizationId);
|
|
93
|
+
const maximum = typeof ctx.context.orgOptions.teams?.maximumTeams === "function" ? await ctx.context.orgOptions.teams?.maximumTeams({
|
|
94
|
+
organizationId,
|
|
95
|
+
session
|
|
96
|
+
}, ctx) : ctx.context.orgOptions.teams?.maximumTeams;
|
|
97
|
+
if (maximum ? existingTeams.length >= maximum : false) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_TEAMS);
|
|
98
|
+
const { name, organizationId: _, ...additionalFields } = ctx.body;
|
|
99
|
+
const organization = await adapter.findOrganizationById(organizationId);
|
|
100
|
+
if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
|
|
101
|
+
let teamData = {
|
|
102
|
+
name,
|
|
103
|
+
organizationId,
|
|
104
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
105
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
106
|
+
...additionalFields
|
|
107
|
+
};
|
|
108
|
+
if (options?.organizationHooks?.beforeCreateTeam) {
|
|
109
|
+
const response = await options?.organizationHooks.beforeCreateTeam({
|
|
110
|
+
team: {
|
|
111
|
+
name,
|
|
112
|
+
organizationId,
|
|
113
|
+
...additionalFields
|
|
114
|
+
},
|
|
115
|
+
user: session?.user,
|
|
116
|
+
organization
|
|
117
|
+
});
|
|
118
|
+
if (response && typeof response === "object" && "data" in response) teamData = {
|
|
119
|
+
...teamData,
|
|
120
|
+
...response.data
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const createdTeam = await adapter.createTeam(teamData);
|
|
124
|
+
if (options?.organizationHooks?.afterCreateTeam) await options?.organizationHooks.afterCreateTeam({
|
|
125
|
+
team: createdTeam,
|
|
126
|
+
user: session?.user,
|
|
127
|
+
organization
|
|
128
|
+
});
|
|
129
|
+
return ctx.json(createdTeam);
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
const removeTeamBodySchema = z.object({
|
|
133
|
+
teamId: z.string().meta({ description: `The team ID of the team to remove. Eg: "team-id"` }),
|
|
134
|
+
organizationId: z.string().meta({ description: `The organization ID which the team falls under. If not provided, it will default to the user's active organization. Eg: "organization-id"` }).optional()
|
|
135
|
+
});
|
|
136
|
+
const removeTeam = (options) => createAuthEndpoint("/organization/remove-team", {
|
|
137
|
+
method: "POST",
|
|
138
|
+
body: removeTeamBodySchema,
|
|
139
|
+
use: [orgMiddleware],
|
|
140
|
+
metadata: { openapi: {
|
|
141
|
+
description: "Remove a team from an organization",
|
|
142
|
+
responses: { "200": {
|
|
143
|
+
description: "Team removed successfully",
|
|
144
|
+
content: { "application/json": { schema: {
|
|
145
|
+
type: "object",
|
|
146
|
+
properties: { message: {
|
|
147
|
+
type: "string",
|
|
148
|
+
description: "Confirmation message indicating successful removal",
|
|
149
|
+
enum: ["Team removed successfully."]
|
|
150
|
+
} },
|
|
151
|
+
required: ["message"]
|
|
152
|
+
} } }
|
|
153
|
+
} }
|
|
154
|
+
} }
|
|
155
|
+
}, async (ctx) => {
|
|
156
|
+
const session = await getSessionFromCtx(ctx);
|
|
157
|
+
const organizationId = ctx.body.organizationId || session?.session.activeOrganizationId;
|
|
158
|
+
if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
|
|
159
|
+
if (!session && (ctx.request || ctx.headers)) throw APIError.fromStatus("UNAUTHORIZED");
|
|
160
|
+
const adapter = getOrgAdapter(ctx.context, options);
|
|
161
|
+
if (session) {
|
|
162
|
+
const member = await adapter.findMemberByOrgId({
|
|
163
|
+
userId: session.user.id,
|
|
164
|
+
organizationId
|
|
165
|
+
});
|
|
166
|
+
if (!member || session.session?.activeTeamId === ctx.body.teamId) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_DELETE_THIS_TEAM);
|
|
167
|
+
if (!await hasPermission({
|
|
168
|
+
role: member.role,
|
|
169
|
+
options: ctx.context.orgOptions,
|
|
170
|
+
permissions: { team: ["delete"] },
|
|
171
|
+
organizationId
|
|
172
|
+
}, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_DELETE_TEAMS_IN_THIS_ORGANIZATION);
|
|
173
|
+
}
|
|
174
|
+
const team = await adapter.findTeamById({
|
|
175
|
+
teamId: ctx.body.teamId,
|
|
176
|
+
organizationId
|
|
177
|
+
});
|
|
178
|
+
if (!team || team.organizationId !== organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
|
|
179
|
+
if (!ctx.context.orgOptions.teams?.allowRemovingAllTeams) {
|
|
180
|
+
if ((await adapter.listTeams(organizationId)).length <= 1) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.UNABLE_TO_REMOVE_LAST_TEAM);
|
|
181
|
+
}
|
|
182
|
+
const organization = await adapter.findOrganizationById(organizationId);
|
|
183
|
+
if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
|
|
184
|
+
if (options?.organizationHooks?.beforeDeleteTeam) await options?.organizationHooks.beforeDeleteTeam({
|
|
185
|
+
team,
|
|
186
|
+
user: session?.user,
|
|
187
|
+
organization
|
|
188
|
+
});
|
|
189
|
+
await runWithTransaction(ctx.context.adapter, async () => {
|
|
190
|
+
await adapter.deleteTeam(team.id);
|
|
191
|
+
const pendingInvitations = await adapter.findPendingInvitations({ organizationId });
|
|
192
|
+
const trx = await getCurrentAdapter(ctx.context.adapter);
|
|
193
|
+
for (const invitation of pendingInvitations) {
|
|
194
|
+
if (!("teamId" in invitation) || !invitation.teamId) continue;
|
|
195
|
+
const teamIds = invitation.teamId.split(",");
|
|
196
|
+
if (!teamIds.includes(team.id)) continue;
|
|
197
|
+
const remainingTeamIds = teamIds.filter((id) => id !== team.id);
|
|
198
|
+
await trx.update({
|
|
199
|
+
model: "invitation",
|
|
200
|
+
where: [{
|
|
201
|
+
field: "id",
|
|
202
|
+
value: invitation.id
|
|
203
|
+
}],
|
|
204
|
+
update: { teamId: remainingTeamIds.length > 0 ? remainingTeamIds.join(",") : null }
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
if (options?.organizationHooks?.afterDeleteTeam) await options?.organizationHooks.afterDeleteTeam({
|
|
209
|
+
team,
|
|
210
|
+
user: session?.user,
|
|
211
|
+
organization
|
|
212
|
+
});
|
|
213
|
+
return ctx.json({ message: "Team removed successfully." });
|
|
214
|
+
});
|
|
215
|
+
const updateTeam = (options) => {
|
|
216
|
+
const additionalFieldsSchema = toZodSchema({
|
|
217
|
+
fields: options?.schema?.team?.additionalFields ?? {},
|
|
218
|
+
isClientSide: true
|
|
219
|
+
});
|
|
220
|
+
return createAuthEndpoint("/organization/update-team", {
|
|
221
|
+
method: "POST",
|
|
222
|
+
body: z.object({
|
|
223
|
+
teamId: z.string().meta({ description: `The ID of the team to be updated. Eg: "team-id"` }),
|
|
224
|
+
data: z.object({
|
|
225
|
+
...teamSchema.omit({
|
|
226
|
+
id: true,
|
|
227
|
+
createdAt: true,
|
|
228
|
+
updatedAt: true
|
|
229
|
+
}).shape,
|
|
230
|
+
...additionalFieldsSchema.shape
|
|
231
|
+
}).partial()
|
|
232
|
+
}),
|
|
233
|
+
requireHeaders: true,
|
|
234
|
+
use: [orgMiddleware, orgSessionMiddleware],
|
|
235
|
+
metadata: {
|
|
236
|
+
$Infer: { body: {} },
|
|
237
|
+
openapi: {
|
|
238
|
+
description: "Update an existing team in an organization",
|
|
239
|
+
responses: { "200": {
|
|
240
|
+
description: "Team updated successfully",
|
|
241
|
+
content: { "application/json": { schema: {
|
|
242
|
+
type: "object",
|
|
243
|
+
properties: {
|
|
244
|
+
id: {
|
|
245
|
+
type: "string",
|
|
246
|
+
description: "Unique identifier of the updated team"
|
|
247
|
+
},
|
|
248
|
+
name: {
|
|
249
|
+
type: "string",
|
|
250
|
+
description: "Updated name of the team"
|
|
251
|
+
},
|
|
252
|
+
organizationId: {
|
|
253
|
+
type: "string",
|
|
254
|
+
description: "ID of the organization the team belongs to"
|
|
255
|
+
},
|
|
256
|
+
createdAt: {
|
|
257
|
+
type: "string",
|
|
258
|
+
format: "date-time",
|
|
259
|
+
description: "Timestamp when the team was created"
|
|
260
|
+
},
|
|
261
|
+
updatedAt: {
|
|
262
|
+
type: "string",
|
|
263
|
+
format: "date-time",
|
|
264
|
+
description: "Timestamp when the team was last updated"
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
required: [
|
|
268
|
+
"id",
|
|
269
|
+
"name",
|
|
270
|
+
"organizationId",
|
|
271
|
+
"createdAt",
|
|
272
|
+
"updatedAt"
|
|
273
|
+
]
|
|
274
|
+
} } }
|
|
275
|
+
} }
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}, async (ctx) => {
|
|
279
|
+
const session = ctx.context.session;
|
|
280
|
+
const organizationId = ctx.body.data.organizationId || session.session.activeOrganizationId;
|
|
281
|
+
if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
|
|
282
|
+
const adapter = getOrgAdapter(ctx.context, options);
|
|
283
|
+
const member = await adapter.findMemberByOrgId({
|
|
284
|
+
userId: session.user.id,
|
|
285
|
+
organizationId
|
|
286
|
+
});
|
|
287
|
+
if (!member) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_TEAM);
|
|
288
|
+
if (!await hasPermission({
|
|
289
|
+
role: member.role,
|
|
290
|
+
options: ctx.context.orgOptions,
|
|
291
|
+
permissions: { team: ["update"] },
|
|
292
|
+
organizationId
|
|
293
|
+
}, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_TEAM);
|
|
294
|
+
const team = await adapter.findTeamById({
|
|
295
|
+
teamId: ctx.body.teamId,
|
|
296
|
+
organizationId
|
|
297
|
+
});
|
|
298
|
+
if (!team || team.organizationId !== organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
|
|
299
|
+
const { name, organizationId: __, ...additionalFields } = ctx.body.data;
|
|
300
|
+
const organization = await adapter.findOrganizationById(organizationId);
|
|
301
|
+
if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
|
|
302
|
+
const updates = {
|
|
303
|
+
name,
|
|
304
|
+
...additionalFields
|
|
305
|
+
};
|
|
306
|
+
if (options?.organizationHooks?.beforeUpdateTeam) {
|
|
307
|
+
const response = await options?.organizationHooks.beforeUpdateTeam({
|
|
308
|
+
team,
|
|
309
|
+
updates,
|
|
310
|
+
user: session.user,
|
|
311
|
+
organization
|
|
312
|
+
});
|
|
313
|
+
if (response && typeof response === "object" && "data" in response) {
|
|
314
|
+
const modifiedUpdates = response.data;
|
|
315
|
+
const updatedTeam = await adapter.updateTeam(team.id, modifiedUpdates);
|
|
316
|
+
if (options?.organizationHooks?.afterUpdateTeam) await options?.organizationHooks.afterUpdateTeam({
|
|
317
|
+
team: updatedTeam,
|
|
318
|
+
user: session.user,
|
|
319
|
+
organization
|
|
320
|
+
});
|
|
321
|
+
return ctx.json(updatedTeam);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
const updatedTeam = await adapter.updateTeam(team.id, updates);
|
|
325
|
+
if (options?.organizationHooks?.afterUpdateTeam) await options?.organizationHooks.afterUpdateTeam({
|
|
326
|
+
team: updatedTeam,
|
|
327
|
+
user: session.user,
|
|
328
|
+
organization
|
|
329
|
+
});
|
|
330
|
+
return ctx.json(updatedTeam);
|
|
331
|
+
});
|
|
332
|
+
};
|
|
333
|
+
const listOrganizationTeamsQuerySchema = z.optional(z.object({ organizationId: z.string().meta({ description: `The organization ID which the teams are under to list. Defaults to the users active organization. Eg: "organization-id"` }).optional() }));
|
|
334
|
+
const listOrganizationTeams = (options) => createAuthEndpoint("/organization/list-teams", {
|
|
335
|
+
method: "GET",
|
|
336
|
+
query: listOrganizationTeamsQuerySchema,
|
|
337
|
+
metadata: { openapi: {
|
|
338
|
+
description: "List all teams in an organization",
|
|
339
|
+
responses: { "200": {
|
|
340
|
+
description: "Teams retrieved successfully",
|
|
341
|
+
content: { "application/json": { schema: {
|
|
342
|
+
type: "array",
|
|
343
|
+
items: {
|
|
344
|
+
type: "object",
|
|
345
|
+
properties: {
|
|
346
|
+
id: {
|
|
347
|
+
type: "string",
|
|
348
|
+
description: "Unique identifier of the team"
|
|
349
|
+
},
|
|
350
|
+
name: {
|
|
351
|
+
type: "string",
|
|
352
|
+
description: "Name of the team"
|
|
353
|
+
},
|
|
354
|
+
organizationId: {
|
|
355
|
+
type: "string",
|
|
356
|
+
description: "ID of the organization the team belongs to"
|
|
357
|
+
},
|
|
358
|
+
createdAt: {
|
|
359
|
+
type: "string",
|
|
360
|
+
format: "date-time",
|
|
361
|
+
description: "Timestamp when the team was created"
|
|
362
|
+
},
|
|
363
|
+
updatedAt: {
|
|
364
|
+
type: "string",
|
|
365
|
+
format: "date-time",
|
|
366
|
+
description: "Timestamp when the team was last updated"
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
required: [
|
|
370
|
+
"id",
|
|
371
|
+
"name",
|
|
372
|
+
"organizationId",
|
|
373
|
+
"createdAt",
|
|
374
|
+
"updatedAt"
|
|
375
|
+
]
|
|
376
|
+
},
|
|
377
|
+
description: "Array of team objects within the organization"
|
|
378
|
+
} } }
|
|
379
|
+
} }
|
|
380
|
+
} },
|
|
381
|
+
requireHeaders: true,
|
|
382
|
+
use: [orgMiddleware, orgSessionMiddleware]
|
|
383
|
+
}, async (ctx) => {
|
|
384
|
+
const session = ctx.context.session;
|
|
385
|
+
const organizationId = ctx.query?.organizationId || session?.session.activeOrganizationId;
|
|
386
|
+
if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
|
|
387
|
+
const adapter = getOrgAdapter(ctx.context, options);
|
|
388
|
+
if (!await adapter.findMemberByOrgId({
|
|
389
|
+
userId: session.user.id,
|
|
390
|
+
organizationId: organizationId || ""
|
|
391
|
+
})) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_ACCESS_THIS_ORGANIZATION);
|
|
392
|
+
const teams = await adapter.listTeams(organizationId);
|
|
393
|
+
return ctx.json(teams);
|
|
394
|
+
});
|
|
395
|
+
const setActiveTeamBodySchema = z.object({ teamId: z.string().meta({ description: "The team id to set as active. It can be null to unset the active team" }).nullable().optional() });
|
|
396
|
+
const setActiveTeam = (options) => createAuthEndpoint("/organization/set-active-team", {
|
|
397
|
+
method: "POST",
|
|
398
|
+
body: setActiveTeamBodySchema,
|
|
399
|
+
requireHeaders: true,
|
|
400
|
+
use: [orgSessionMiddleware, orgMiddleware],
|
|
401
|
+
metadata: { openapi: {
|
|
402
|
+
description: "Set the active team for the current active organization",
|
|
403
|
+
responses: { "200": {
|
|
404
|
+
description: "Success",
|
|
405
|
+
content: { "application/json": { schema: {
|
|
406
|
+
type: "object",
|
|
407
|
+
description: "The team",
|
|
408
|
+
$ref: "#/components/schemas/Team"
|
|
409
|
+
} } }
|
|
410
|
+
} }
|
|
411
|
+
} }
|
|
412
|
+
}, async (ctx) => {
|
|
413
|
+
const adapter = getOrgAdapter(ctx.context, ctx.context.orgOptions);
|
|
414
|
+
const session = ctx.context.session;
|
|
415
|
+
if (ctx.body.teamId === null) {
|
|
416
|
+
if (!session.session.activeTeamId) return ctx.json(null);
|
|
417
|
+
await setSessionCookie(ctx, {
|
|
418
|
+
session: await adapter.setActiveTeam(session.session.token, null, ctx),
|
|
419
|
+
user: session.user
|
|
420
|
+
});
|
|
421
|
+
return ctx.json(null);
|
|
422
|
+
}
|
|
423
|
+
let teamId;
|
|
424
|
+
if (!ctx.body.teamId) {
|
|
425
|
+
const sessionTeamId = session.session.activeTeamId;
|
|
426
|
+
if (!sessionTeamId) return ctx.json(null);
|
|
427
|
+
else teamId = sessionTeamId;
|
|
428
|
+
} else teamId = ctx.body.teamId;
|
|
429
|
+
const activeOrganizationId = session.session.activeOrganizationId;
|
|
430
|
+
if (!activeOrganizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
|
|
431
|
+
const team = await adapter.findTeamById({
|
|
432
|
+
teamId,
|
|
433
|
+
organizationId: activeOrganizationId
|
|
434
|
+
});
|
|
435
|
+
if (!team) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
|
|
436
|
+
if (!await adapter.findTeamMember({
|
|
437
|
+
teamId,
|
|
438
|
+
userId: session.user.id
|
|
439
|
+
})) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_TEAM);
|
|
440
|
+
await setSessionCookie(ctx, {
|
|
441
|
+
session: await adapter.setActiveTeam(session.session.token, team.id, ctx),
|
|
442
|
+
user: session.user
|
|
443
|
+
});
|
|
444
|
+
return ctx.json(team);
|
|
445
|
+
});
|
|
446
|
+
const listUserTeams = (options) => createAuthEndpoint("/organization/list-user-teams", {
|
|
447
|
+
method: "GET",
|
|
448
|
+
query: z.object({
|
|
449
|
+
userId: z.string().optional().meta({ description: "The user ID to list teams for. Defaults to the current session user." }),
|
|
450
|
+
organizationId: z.string().optional().meta({ description: "The organization ID to scope the team list to. When omitted on a self-query, teams are returned across every organization the user belongs to. When querying another user, falls back to the session's active organization and is required if there is no active organization." })
|
|
451
|
+
}).optional(),
|
|
452
|
+
metadata: { openapi: {
|
|
453
|
+
description: "List teams for a user. Without parameters, returns teams for the current user across every organization they belong to. Pass `organizationId` to scope the result to a specific organization. Pass `userId` to list teams for another member; this requires `member:update` permission in the target organization (the explicit `organizationId` if provided, otherwise the session's active organization).",
|
|
454
|
+
responses: { "200": {
|
|
455
|
+
description: "Teams retrieved successfully",
|
|
456
|
+
content: { "application/json": { schema: {
|
|
457
|
+
type: "array",
|
|
458
|
+
items: {
|
|
459
|
+
type: "object",
|
|
460
|
+
description: "The team",
|
|
461
|
+
$ref: "#/components/schemas/Team"
|
|
462
|
+
},
|
|
463
|
+
description: "Array of team objects within the organization"
|
|
464
|
+
} } }
|
|
465
|
+
} }
|
|
466
|
+
} },
|
|
467
|
+
requireHeaders: true,
|
|
468
|
+
use: [orgMiddleware, orgSessionMiddleware]
|
|
469
|
+
}, async (ctx) => {
|
|
470
|
+
const session = ctx.context.session;
|
|
471
|
+
const adapter = getOrgAdapter(ctx.context, ctx.context.orgOptions);
|
|
472
|
+
const targetUserId = ctx.query?.userId || session.user.id;
|
|
473
|
+
const isSelf = targetUserId === session.user.id;
|
|
474
|
+
const organizationId = ctx.query?.organizationId || session.session.activeOrganizationId;
|
|
475
|
+
const isExplicitOrg = Boolean(ctx.query?.organizationId);
|
|
476
|
+
if (!isSelf) {
|
|
477
|
+
if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
|
|
478
|
+
const requesterMember = await adapter.findMemberByOrgId({
|
|
479
|
+
userId: session.user.id,
|
|
480
|
+
organizationId
|
|
481
|
+
});
|
|
482
|
+
if (!requesterMember) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION);
|
|
483
|
+
if (!await hasPermission({
|
|
484
|
+
role: requesterMember.role,
|
|
485
|
+
options: ctx.context.orgOptions,
|
|
486
|
+
permissions: { member: ["update"] },
|
|
487
|
+
organizationId
|
|
488
|
+
}, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_MEMBER);
|
|
489
|
+
if (!await adapter.findMemberByOrgId({
|
|
490
|
+
userId: targetUserId,
|
|
491
|
+
organizationId
|
|
492
|
+
})) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION);
|
|
493
|
+
const teams = await adapter.listTeamsByUser({ userId: targetUserId });
|
|
494
|
+
return ctx.json(teams.filter((t) => t.organizationId === organizationId));
|
|
495
|
+
}
|
|
496
|
+
if (isExplicitOrg && organizationId) {
|
|
497
|
+
if (!await adapter.findMemberByOrgId({
|
|
498
|
+
userId: session.user.id,
|
|
499
|
+
organizationId
|
|
500
|
+
})) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION);
|
|
501
|
+
const teams = await adapter.listTeamsByUser({ userId: session.user.id });
|
|
502
|
+
return ctx.json(teams.filter((t) => t.organizationId === organizationId));
|
|
503
|
+
}
|
|
504
|
+
const teams = await adapter.listTeamsByUser({ userId: session.user.id });
|
|
505
|
+
const orgIds = [...new Set(teams.map((team) => team.organizationId))];
|
|
506
|
+
const memberships = await Promise.all(orgIds.map((organizationId) => adapter.checkMembership({
|
|
507
|
+
userId: session.user.id,
|
|
508
|
+
organizationId
|
|
509
|
+
})));
|
|
510
|
+
const memberOrgIds = new Set(orgIds.filter((_, index) => memberships[index]));
|
|
511
|
+
return ctx.json(teams.filter((team) => memberOrgIds.has(team.organizationId)));
|
|
512
|
+
});
|
|
513
|
+
const listTeamMembersQuerySchema = z.optional(z.object({ teamId: z.string().optional().meta({ description: "The team whose members we should return. If this is not provided the members of the current active team get returned." }) }));
|
|
514
|
+
const listTeamMembers = (options) => createAuthEndpoint("/organization/list-team-members", {
|
|
515
|
+
method: "GET",
|
|
516
|
+
query: listTeamMembersQuerySchema,
|
|
517
|
+
metadata: { openapi: {
|
|
518
|
+
description: "List the members of the given team.",
|
|
519
|
+
responses: { "200": {
|
|
520
|
+
description: "Teams retrieved successfully",
|
|
521
|
+
content: { "application/json": { schema: {
|
|
522
|
+
type: "array",
|
|
523
|
+
items: {
|
|
524
|
+
type: "object",
|
|
525
|
+
description: "The team member",
|
|
526
|
+
properties: {
|
|
527
|
+
id: {
|
|
528
|
+
type: "string",
|
|
529
|
+
description: "Unique identifier of the team member"
|
|
530
|
+
},
|
|
531
|
+
userId: {
|
|
532
|
+
type: "string",
|
|
533
|
+
description: "The user ID of the team member"
|
|
534
|
+
},
|
|
535
|
+
teamId: {
|
|
536
|
+
type: "string",
|
|
537
|
+
description: "The team ID of the team the team member is in"
|
|
538
|
+
},
|
|
539
|
+
createdAt: {
|
|
540
|
+
type: "string",
|
|
541
|
+
format: "date-time",
|
|
542
|
+
description: "Timestamp when the team member was created"
|
|
543
|
+
}
|
|
544
|
+
},
|
|
545
|
+
required: [
|
|
546
|
+
"id",
|
|
547
|
+
"userId",
|
|
548
|
+
"teamId",
|
|
549
|
+
"createdAt"
|
|
550
|
+
]
|
|
551
|
+
},
|
|
552
|
+
description: "Array of team member objects within the team"
|
|
553
|
+
} } }
|
|
554
|
+
} }
|
|
555
|
+
} },
|
|
556
|
+
requireHeaders: true,
|
|
557
|
+
use: [orgMiddleware, orgSessionMiddleware]
|
|
558
|
+
}, async (ctx) => {
|
|
559
|
+
const session = ctx.context.session;
|
|
560
|
+
const adapter = getOrgAdapter(ctx.context, ctx.context.orgOptions);
|
|
561
|
+
const teamId = ctx.query?.teamId || session?.session.activeTeamId;
|
|
562
|
+
if (!teamId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.YOU_DO_NOT_HAVE_AN_ACTIVE_TEAM);
|
|
563
|
+
const team = await adapter.findTeamById({ teamId });
|
|
564
|
+
if (!team) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
|
|
565
|
+
if (!await adapter.checkMembership({
|
|
566
|
+
userId: session.user.id,
|
|
567
|
+
organizationId: team.organizationId
|
|
568
|
+
})) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_TEAM);
|
|
569
|
+
if (!await adapter.findTeamMember({
|
|
570
|
+
userId: session.user.id,
|
|
571
|
+
teamId
|
|
572
|
+
})) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_TEAM);
|
|
573
|
+
const members = await adapter.listTeamMembers({ teamId });
|
|
574
|
+
return ctx.json(members);
|
|
575
|
+
});
|
|
576
|
+
const addTeamMemberBodySchema = z.object({
|
|
577
|
+
teamId: z.string().meta({ description: "The team the user should be a member of." }),
|
|
578
|
+
userId: z.coerce.string().meta({ description: "The user Id which represents the user to be added as a member." }),
|
|
579
|
+
organizationId: z.string().meta({ description: "The organization ID which the team falls under. If not provided, it will default to the user's active organization." }).optional()
|
|
580
|
+
});
|
|
581
|
+
const addTeamMember = (options) => createAuthEndpoint("/organization/add-team-member", {
|
|
582
|
+
method: "POST",
|
|
583
|
+
body: addTeamMemberBodySchema,
|
|
584
|
+
metadata: { openapi: {
|
|
585
|
+
description: "The newly created member",
|
|
586
|
+
responses: { "200": {
|
|
587
|
+
description: "Team member created successfully",
|
|
588
|
+
content: { "application/json": { schema: {
|
|
589
|
+
type: "object",
|
|
590
|
+
description: "The team member",
|
|
591
|
+
properties: {
|
|
592
|
+
id: {
|
|
593
|
+
type: "string",
|
|
594
|
+
description: "Unique identifier of the team member"
|
|
595
|
+
},
|
|
596
|
+
userId: {
|
|
597
|
+
type: "string",
|
|
598
|
+
description: "The user ID of the team member"
|
|
599
|
+
},
|
|
600
|
+
teamId: {
|
|
601
|
+
type: "string",
|
|
602
|
+
description: "The team ID of the team the team member is in"
|
|
603
|
+
},
|
|
604
|
+
createdAt: {
|
|
605
|
+
type: "string",
|
|
606
|
+
format: "date-time",
|
|
607
|
+
description: "Timestamp when the team member was created"
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
required: [
|
|
611
|
+
"id",
|
|
612
|
+
"userId",
|
|
613
|
+
"teamId",
|
|
614
|
+
"createdAt"
|
|
615
|
+
]
|
|
616
|
+
} } }
|
|
617
|
+
} }
|
|
618
|
+
} },
|
|
619
|
+
requireHeaders: true,
|
|
620
|
+
use: [orgMiddleware, orgSessionMiddleware]
|
|
621
|
+
}, async (ctx) => {
|
|
622
|
+
const session = ctx.context.session;
|
|
623
|
+
const adapter = getOrgAdapter(ctx.context, ctx.context.orgOptions);
|
|
624
|
+
const organizationId = ctx.body.organizationId || session.session.activeOrganizationId;
|
|
625
|
+
if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
|
|
626
|
+
const currentMember = await adapter.findMemberByOrgId({
|
|
627
|
+
userId: session.user.id,
|
|
628
|
+
organizationId
|
|
629
|
+
});
|
|
630
|
+
if (!currentMember) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION);
|
|
631
|
+
if (!await hasPermission({
|
|
632
|
+
role: currentMember.role,
|
|
633
|
+
options: ctx.context.orgOptions,
|
|
634
|
+
permissions: { member: ["update"] },
|
|
635
|
+
organizationId
|
|
636
|
+
}, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_CREATE_A_NEW_TEAM_MEMBER);
|
|
637
|
+
if (!await adapter.findMemberByOrgId({
|
|
638
|
+
userId: ctx.body.userId,
|
|
639
|
+
organizationId
|
|
640
|
+
})) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION);
|
|
641
|
+
const team = await adapter.findTeamById({
|
|
642
|
+
teamId: ctx.body.teamId,
|
|
643
|
+
organizationId
|
|
644
|
+
});
|
|
645
|
+
if (!team) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
|
|
646
|
+
const organization = await adapter.findOrganizationById(organizationId);
|
|
647
|
+
if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
|
|
648
|
+
const userBeingAdded = await ctx.context.internalAdapter.findUserById(ctx.body.userId);
|
|
649
|
+
if (!userBeingAdded) throw APIError.fromStatus("BAD_REQUEST", { message: "User not found" });
|
|
650
|
+
if (options?.organizationHooks?.beforeAddTeamMember) {
|
|
651
|
+
const response = await options?.organizationHooks.beforeAddTeamMember({
|
|
652
|
+
teamMember: {
|
|
653
|
+
teamId: ctx.body.teamId,
|
|
654
|
+
userId: ctx.body.userId
|
|
655
|
+
},
|
|
656
|
+
team,
|
|
657
|
+
user: userBeingAdded,
|
|
658
|
+
organization
|
|
659
|
+
});
|
|
660
|
+
if (response && typeof response === "object" && "data" in response) {}
|
|
661
|
+
}
|
|
662
|
+
let teamMember;
|
|
663
|
+
if (typeof ctx.context.orgOptions.teams?.maximumMembersPerTeam !== "undefined") {
|
|
664
|
+
const maximumMembersPerTeam = typeof ctx.context.orgOptions.teams.maximumMembersPerTeam === "function" ? await ctx.context.orgOptions.teams.maximumMembersPerTeam({
|
|
665
|
+
teamId: ctx.body.teamId,
|
|
666
|
+
session,
|
|
667
|
+
organizationId
|
|
668
|
+
}) : ctx.context.orgOptions.teams.maximumMembersPerTeam;
|
|
669
|
+
const result = await adapter.addTeamMemberWithLimit({
|
|
670
|
+
teamId: ctx.body.teamId,
|
|
671
|
+
userId: ctx.body.userId,
|
|
672
|
+
maximumMembersPerTeam
|
|
673
|
+
});
|
|
674
|
+
if (result.status === "limitReached") throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.TEAM_MEMBER_LIMIT_REACHED);
|
|
675
|
+
teamMember = result.member;
|
|
676
|
+
} else teamMember = await adapter.findOrCreateTeamMember({
|
|
677
|
+
teamId: ctx.body.teamId,
|
|
678
|
+
userId: ctx.body.userId
|
|
679
|
+
});
|
|
680
|
+
if (options?.organizationHooks?.afterAddTeamMember) await options?.organizationHooks.afterAddTeamMember({
|
|
681
|
+
teamMember,
|
|
682
|
+
team,
|
|
683
|
+
user: userBeingAdded,
|
|
684
|
+
organization
|
|
685
|
+
});
|
|
686
|
+
return ctx.json(teamMember);
|
|
687
|
+
});
|
|
688
|
+
const removeTeamMemberBodySchema = z.object({
|
|
689
|
+
teamId: z.string().meta({ description: "The team the user should be removed from." }),
|
|
690
|
+
userId: z.coerce.string().meta({ description: "The user which should be removed from the team." }),
|
|
691
|
+
organizationId: z.string().meta({ description: "The organization ID which the team falls under. If not provided, it will default to the user's active organization." }).optional()
|
|
692
|
+
});
|
|
693
|
+
const removeTeamMember = (options) => createAuthEndpoint("/organization/remove-team-member", {
|
|
694
|
+
method: "POST",
|
|
695
|
+
body: removeTeamMemberBodySchema,
|
|
696
|
+
metadata: { openapi: {
|
|
697
|
+
description: "Remove a member from a team",
|
|
698
|
+
responses: { "200": {
|
|
699
|
+
description: "Team member removed successfully",
|
|
700
|
+
content: { "application/json": { schema: {
|
|
701
|
+
type: "object",
|
|
702
|
+
properties: { message: {
|
|
703
|
+
type: "string",
|
|
704
|
+
description: "Confirmation message indicating successful removal",
|
|
705
|
+
enum: ["Team member removed successfully."]
|
|
706
|
+
} },
|
|
707
|
+
required: ["message"]
|
|
708
|
+
} } }
|
|
709
|
+
} }
|
|
710
|
+
} },
|
|
711
|
+
requireHeaders: true,
|
|
712
|
+
use: [orgMiddleware, orgSessionMiddleware]
|
|
713
|
+
}, async (ctx) => {
|
|
714
|
+
const session = ctx.context.session;
|
|
715
|
+
const adapter = getOrgAdapter(ctx.context, ctx.context.orgOptions);
|
|
716
|
+
const organizationId = ctx.body.organizationId || session.session.activeOrganizationId;
|
|
717
|
+
if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
|
|
718
|
+
const currentMember = await adapter.findMemberByOrgId({
|
|
719
|
+
userId: session.user.id,
|
|
720
|
+
organizationId
|
|
721
|
+
});
|
|
722
|
+
if (!currentMember) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION);
|
|
723
|
+
if (!await hasPermission({
|
|
724
|
+
role: currentMember.role,
|
|
725
|
+
options: ctx.context.orgOptions,
|
|
726
|
+
permissions: { member: ["delete"] },
|
|
727
|
+
organizationId
|
|
728
|
+
}, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_REMOVE_A_TEAM_MEMBER);
|
|
729
|
+
if (!await adapter.findMemberByOrgId({
|
|
730
|
+
userId: ctx.body.userId,
|
|
731
|
+
organizationId
|
|
732
|
+
})) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION);
|
|
733
|
+
const team = await adapter.findTeamById({
|
|
734
|
+
teamId: ctx.body.teamId,
|
|
735
|
+
organizationId
|
|
736
|
+
});
|
|
737
|
+
if (!team) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
|
|
738
|
+
const organization = await adapter.findOrganizationById(organizationId);
|
|
739
|
+
if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
|
|
740
|
+
const userBeingRemoved = await ctx.context.internalAdapter.findUserById(ctx.body.userId);
|
|
741
|
+
if (!userBeingRemoved) throw APIError.fromStatus("BAD_REQUEST", { message: "User not found" });
|
|
742
|
+
const teamMember = await adapter.findTeamMember({
|
|
743
|
+
teamId: ctx.body.teamId,
|
|
744
|
+
userId: ctx.body.userId
|
|
745
|
+
});
|
|
746
|
+
if (!teamMember) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_TEAM);
|
|
747
|
+
if (options?.organizationHooks?.beforeRemoveTeamMember) await options?.organizationHooks.beforeRemoveTeamMember({
|
|
748
|
+
teamMember,
|
|
749
|
+
team,
|
|
750
|
+
user: userBeingRemoved,
|
|
751
|
+
organization
|
|
752
|
+
});
|
|
753
|
+
await adapter.removeTeamMember({
|
|
754
|
+
teamId: ctx.body.teamId,
|
|
755
|
+
userId: ctx.body.userId
|
|
756
|
+
});
|
|
757
|
+
if (options?.organizationHooks?.afterRemoveTeamMember) await options?.organizationHooks.afterRemoveTeamMember({
|
|
758
|
+
teamMember,
|
|
759
|
+
team,
|
|
760
|
+
user: userBeingRemoved,
|
|
761
|
+
organization
|
|
762
|
+
});
|
|
763
|
+
return ctx.json({ message: "Team member removed successfully." });
|
|
764
|
+
});
|
|
765
|
+
//#endregion
|
|
766
|
+
export { addTeamMember, createTeam, listOrganizationTeams, listTeamMembers, listUserTeams, removeTeam, removeTeamMember, setActiveTeam, updateTeam };
|