diff --git a/.env.example b/.env.example index 8945ac9d7c..66d650023b 100644 --- a/.env.example +++ b/.env.example @@ -111,8 +111,8 @@ PASSWORD_RESET_DISABLED=1 ########################################### # Danger: skips the SSO identity confirmation redirect for passwordless account deletion. -# Users can delete SSO accounts with email confirmation only. Keep unset unless you accept the risk. -# DISABLE_ACCOUNT_DELETION_SSO_REAUTH=1 +# Users can delete SSO accounts with only the in-app email text confirmation. Keep unset unless you accept the risk. +# DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION=1 ########## diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(account)/profile/components/DeleteAccount.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(account)/profile/components/DeleteAccount.tsx index 68b6b9bc1d..3bff058747 100644 --- a/apps/web/app/(app)/environments/[environmentId]/settings/(account)/profile/components/DeleteAccount.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/settings/(account)/profile/components/DeleteAccount.tsx @@ -7,7 +7,10 @@ import { useTranslation } from "react-i18next"; import { TOrganization } from "@formbricks/types/organizations"; import { TUser } from "@formbricks/types/user"; import { DeleteAccountModal } from "@/modules/account/components/DeleteAccountModal"; -import { ACCOUNT_DELETION_SSO_REAUTH_ERROR_QUERY_PARAM } from "@/modules/account/constants"; +import { + ACCOUNT_DELETION_SSO_REAUTH_ERROR_QUERY_PARAM, + ACCOUNT_DELETION_SSO_REAUTH_FAILED_ERROR_CODE, +} from "@/modules/account/constants"; import { Button } from "@/modules/ui/components/button"; import { TooltipRenderer } from "@/modules/ui/components/tooltip"; @@ -39,7 +42,10 @@ export const DeleteAccount = ({ const hasShownAccountDeletionError = useRef(false); useEffect(() => { - if (!accountDeletionErrorCode || hasShownAccountDeletionError.current) { + if ( + accountDeletionErrorCode !== ACCOUNT_DELETION_SSO_REAUTH_FAILED_ERROR_CODE || + hasShownAccountDeletionError.current + ) { return; } diff --git a/apps/web/lib/constants.ts b/apps/web/lib/constants.ts index e56c66ba9c..0019e4e830 100644 --- a/apps/web/lib/constants.ts +++ b/apps/web/lib/constants.ts @@ -26,7 +26,8 @@ export const TERMS_URL = env.TERMS_URL; export const IMPRINT_URL = env.IMPRINT_URL; export const IMPRINT_ADDRESS = env.IMPRINT_ADDRESS; -export const DISABLE_ACCOUNT_DELETION_SSO_REAUTH = env.DISABLE_ACCOUNT_DELETION_SSO_REAUTH === "1"; +export const DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION = + env.DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION === "1"; export const DANGEROUSLY_ALLOW_WEBHOOK_INTERNAL_URLS = env.DANGEROUSLY_ALLOW_WEBHOOK_INTERNAL_URLS === "1"; export const DEBUG_SHOW_RESET_LINK = !IS_PRODUCTION && env.DEBUG_SHOW_RESET_LINK === "1"; export const PASSWORD_RESET_DISABLED = env.PASSWORD_RESET_DISABLED === "1"; diff --git a/apps/web/lib/env.ts b/apps/web/lib/env.ts index d8720ce4ed..4cafaa7be3 100644 --- a/apps/web/lib/env.ts +++ b/apps/web/lib/env.ts @@ -123,7 +123,7 @@ const parsedEnv = createEnv({ BREVO_API_KEY: z.string().optional(), BREVO_LIST_ID: z.string().optional(), DATABASE_URL: z.url(), - DISABLE_ACCOUNT_DELETION_SSO_REAUTH: z.enum(["1", "0"]).optional(), + DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION: z.enum(["1", "0"]).optional(), DANGEROUSLY_ALLOW_WEBHOOK_INTERNAL_URLS: z.enum(["1", "0"]).optional(), DEBUG: z.enum(["1", "0"]).optional(), DEBUG_SHOW_RESET_LINK: z.enum(["1", "0"]).optional(), @@ -268,7 +268,7 @@ const parsedEnv = createEnv({ BREVO_LIST_ID: process.env.BREVO_LIST_ID, CRON_SECRET: process.env.CRON_SECRET, DATABASE_URL: process.env.DATABASE_URL, - DISABLE_ACCOUNT_DELETION_SSO_REAUTH: process.env.DISABLE_ACCOUNT_DELETION_SSO_REAUTH, + DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION: process.env.DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION, DANGEROUSLY_ALLOW_WEBHOOK_INTERNAL_URLS: process.env.DANGEROUSLY_ALLOW_WEBHOOK_INTERNAL_URLS, DEBUG: process.env.DEBUG, DEBUG_SHOW_RESET_LINK: process.env.DEBUG_SHOW_RESET_LINK, diff --git a/apps/web/modules/account/lib/account-deletion.ts b/apps/web/modules/account/lib/account-deletion.ts index d5fa14c243..ce12a3c783 100644 --- a/apps/web/modules/account/lib/account-deletion.ts +++ b/apps/web/modules/account/lib/account-deletion.ts @@ -2,7 +2,7 @@ import "server-only"; import type { IdentityProvider } from "@prisma/client"; import { logger } from "@formbricks/logger"; import { AuthorizationError, InvalidInputError, OperationNotAllowedError } from "@formbricks/types/errors"; -import { DISABLE_ACCOUNT_DELETION_SSO_REAUTH } from "@/lib/constants"; +import { DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION } from "@/lib/constants"; import { getOrganizationsWhereUserIsSingleOwner } from "@/lib/organization/service"; import { getUserAuthenticationData, verifyUserPassword } from "@/lib/user/password"; import { deleteUser, getUser } from "@/lib/user/service"; @@ -30,7 +30,7 @@ const assertConfirmationEmailMatches = (confirmationEmail: string, expectedEmail }; const canBypassSsoIdentityConfirmation = (identityProvider: IdentityProvider) => - DISABLE_ACCOUNT_DELETION_SSO_REAUTH && identityProvider !== "email"; + DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION && identityProvider !== "email"; const assertAccountDeletionSsoIdentityConfirmation = async ({ identityProvider, diff --git a/docs/self-hosting/configuration/auth-sso/google-oauth.mdx b/docs/self-hosting/configuration/auth-sso/google-oauth.mdx index f88e27c3aa..353709687f 100644 --- a/docs/self-hosting/configuration/auth-sso/google-oauth.mdx +++ b/docs/self-hosting/configuration/auth-sso/google-oauth.mdx @@ -23,9 +23,9 @@ For SSO-only users, Formbricks asks the user to type their email address and the This confirms the Google identity for the current deletion attempt, but it does not guarantee that Google will ask for a password or MFA every time. If the browser already has an active Google session, Google may silently return the same account. - If you set `DISABLE_ACCOUNT_DELETION_SSO_REAUTH=1`, Formbricks skips this SSO identity confirmation - redirect for passwordless SSO accounts. Users can delete their account with email confirmation only. Keep it - unset unless you accept this security trade-off. + If you set `DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION=1`, Formbricks skips this SSO identity confirmation + redirect for passwordless SSO accounts. Users can delete their account with only the in-app email text + confirmation. Keep it unset unless you accept this security trade-off. ### How to connect your Formbricks instance to Google @@ -69,7 +69,7 @@ This confirms the Google identity for the current deletion attempt, but it does GOOGLE_CLIENT_ID=your-client-id-here GOOGLE_CLIENT_SECRET=your-client-secret-here # Optional: dangerous fallback that skips SSO identity confirmation for account deletion. - # DISABLE_ACCOUNT_DELETION_SSO_REAUTH=1 + # DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION=1 ``` - Alternatively, you can add the environment variables directly to the running container using the following commands (replace `container_id` with your actual Docker container ID): diff --git a/docs/self-hosting/configuration/environment-variables.mdx b/docs/self-hosting/configuration/environment-variables.mdx index 6dc8d6d184..ca5454fb9b 100644 --- a/docs/self-hosting/configuration/environment-variables.mdx +++ b/docs/self-hosting/configuration/environment-variables.mdx @@ -34,7 +34,7 @@ These variables are present inside your machine's docker-compose file. Restart t | PASSWORD_RESET_DISABLED | Disables password reset functionality if set to 1. | optional | | | PASSWORD_RESET_TOKEN_LIFETIME_MINUTES | Configures how long password reset links remain valid in minutes. Accepted values are integers from 5 to 120. | optional | 30 | | EMAIL_VERIFICATION_DISABLED | Disables email verification if set to 1. | optional | | -| DISABLE_ACCOUNT_DELETION_SSO_REAUTH | Skips the SSO identity confirmation redirect for passwordless SSO account deletion if set to 1. Users can delete SSO accounts with email confirmation only. Keep unset unless you accept this security trade-off. | optional | | +| DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION | Skips the SSO identity confirmation redirect for passwordless SSO account deletion if set to 1. Users can delete SSO accounts with only the in-app email text confirmation. Keep unset unless you accept this security trade-off. | optional | | | RATE_LIMITING_DISABLED | Disables rate limiting if set to 1. | optional | | | TELEMETRY_DISABLED | Disables telemetry reporting if set to 1. Ignored when an Enterprise License is active. | optional | | | DANGEROUSLY_ALLOW_WEBHOOK_INTERNAL_URLS | Allows webhook URLs to point to internal/private network addresses (e.g. localhost, 192.168.x.x) if set to 1. Useful for self-hosted instances that need to send webhooks to internal services. | optional | | diff --git a/turbo.json b/turbo.json index c547b11ae4..31e9be1fda 100644 --- a/turbo.json +++ b/turbo.json @@ -190,7 +190,7 @@ "BREVO_API_KEY", "BREVO_LIST_ID", "CRON_SECRET", - "DISABLE_ACCOUNT_DELETION_SSO_REAUTH", + "DISABLE_ACCOUNT_DELETION_SSO_CONFIRMATION", "DANGEROUSLY_ALLOW_WEBHOOK_INTERNAL_URLS", "DATABASE_URL", "DEBUG",