From a31e7bfaa5038b9799a60c7176f5fc3f4d488e50 Mon Sep 17 00:00:00 2001 From: Anshuman Pandey <54475686+pandeymangg@users.noreply.github.com> Date: Wed, 14 Jan 2026 22:15:21 +0530 Subject: [PATCH] feat: security signup ui (#7088) Co-authored-by: Johannes --- .../general/components/SecurityListTip.tsx | 26 +++ .../settings/(organization)/general/page.tsx | 2 + apps/web/i18n.lock | 6 + apps/web/locales/de-DE.json | 6 + apps/web/locales/en-US.json | 6 + apps/web/locales/es-ES.json | 6 + apps/web/locales/fr-FR.json | 6 + apps/web/locales/ja-JP.json | 6 + apps/web/locales/nl-NL.json | 6 + apps/web/locales/pt-BR.json | 6 + apps/web/locales/pt-PT.json | 6 + apps/web/locales/ro-RO.json | 6 + apps/web/locales/ru-RU.json | 6 + apps/web/locales/sv-SE.json | 6 + apps/web/locales/zh-Hans-CN.json | 6 + apps/web/locales/zh-Hant-TW.json | 6 + apps/web/modules/auth/signup/actions.ts | 11 + .../auth/signup/components/signup-form.tsx | 45 ++++ apps/web/modules/auth/signup/page.tsx | 2 + .../modules/ee/license-check/lib/license.ts | 1 + .../mailing/lib/mailing-subscription.test.ts | 205 ++++++++++++++++++ .../ee/mailing/lib/mailing-subscription.ts | 91 ++++++++ .../setup/(fresh-instance)/signup/page.tsx | 2 + packages/database/package.json | 2 +- 24 files changed, 470 insertions(+), 1 deletion(-) create mode 100644 apps/web/app/(app)/environments/[environmentId]/settings/(organization)/general/components/SecurityListTip.tsx create mode 100644 apps/web/modules/ee/mailing/lib/mailing-subscription.test.ts create mode 100644 apps/web/modules/ee/mailing/lib/mailing-subscription.ts diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/general/components/SecurityListTip.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/general/components/SecurityListTip.tsx new file mode 100644 index 0000000000..536ea6d1c8 --- /dev/null +++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/general/components/SecurityListTip.tsx @@ -0,0 +1,26 @@ +"use client"; + +import { ShieldCheckIcon } from "lucide-react"; +import Link from "next/link"; +import { useTranslation } from "react-i18next"; + +export const SecurityListTip = () => { + const { t } = useTranslation(); + return ( +
+
+ +

+ {t("environments.settings.general.security_list_tip")}{" "} + + {t("environments.settings.general.security_list_tip_link")} + +

+
+
+ ); +}; diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/general/page.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/general/page.tsx index 2d3089a8bd..4c106cbeaa 100644 --- a/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/general/page.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/general/page.tsx @@ -12,6 +12,7 @@ import { PageHeader } from "@/modules/ui/components/page-header"; import { SettingsCard } from "../../components/SettingsCard"; import { DeleteOrganization } from "./components/DeleteOrganization"; import { EditOrganizationNameForm } from "./components/EditOrganizationNameForm"; +import { SecurityListTip } from "./components/SecurityListTip"; const Page = async (props: { params: Promise<{ environmentId: string }> }) => { const params = await props.params; @@ -48,6 +49,7 @@ const Page = async (props: { params: Promise<{ environmentId: string }> }) => { )} + {!IS_FORMBRICKS_CLOUD && } diff --git a/apps/web/i18n.lock b/apps/web/i18n.lock index 5d51b35871..048d01841e 100644 --- a/apps/web/i18n.lock +++ b/apps/web/i18n.lock @@ -61,6 +61,10 @@ checksums: auth/signup/password_validation_uppercase_and_lowercase: ae98b485024dbff1022f6048e22443cd auth/signup/please_verify_captcha: 12938ca7ca13e3f933737dd5436fa1c0 auth/signup/privacy_policy: 7459744a63ef8af4e517a09024bd7c08 + auth/signup/product_updates_description: f20eedb2cf42d2235b1fe0294086695b + auth/signup/product_updates_title: 31e099ba18abb0a49f8a75fece1f1791 + auth/signup/security_updates_description: 4643df07f13cec619e7fd91c8f14d93b + auth/signup/security_updates_title: de5127f5847cdd412906607e1402f48d auth/signup/terms_of_service: 5add91f519e39025708e54a7eb7a9fc5 auth/signup/title: 96addc349f834eaa5d14c786d5478b1c auth/signup_without_verification_success/user_successfully_created: ff849ebedc5dacb36493d7894f16edc7 @@ -954,6 +958,8 @@ checksums: environments/settings/general/remove_logo: f60f1803e6fc8017b1eae7c30089107f environments/settings/general/replace_logo: e3c8bec7574a670607e88771164e272f environments/settings/general/resend_invitation_email: 6305d1ffa015c377ef59fe9c2661cf02 + environments/settings/general/security_list_tip: 0bbed89fa5265da7e07767087f87c736 + environments/settings/general/security_list_tip_link: ccdb1a21610ebf5a626d813b155be4ba environments/settings/general/share_invite_link: b40b7ffbcf02d7464be52fb562df5e3a environments/settings/general/share_this_link_to_let_your_organization_member_join_your_organization: 6eb43d5b1c855572b7ab35f527ba953c environments/settings/general/test_email_sent_successfully: aa68214f5e0707c9615e01343640ab32 diff --git a/apps/web/locales/de-DE.json b/apps/web/locales/de-DE.json index 00eef58be1..45f77f04d7 100644 --- a/apps/web/locales/de-DE.json +++ b/apps/web/locales/de-DE.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "Mix aus Groß- und Kleinbuchstaben", "please_verify_captcha": "Bitte bestätige reCAPTCHA", "privacy_policy": "Datenschutzerklärung", + "product_updates_description": "Monatliche Produktneuigkeiten und Feature-Updates, es gilt die Datenschutzerklärung.", + "product_updates_title": "Produkt-Updates", + "security_updates_description": "Nur sicherheitsrelevante Informationen, es gilt die Datenschutzerklärung.", + "security_updates_title": "Sicherheits-Updates", "terms_of_service": "Nutzungsbedingungen", "title": "Erstelle dein Formbricks-Konto" }, @@ -1015,6 +1019,8 @@ "remove_logo": "Logo entfernen", "replace_logo": "Logo ersetzen", "resend_invitation_email": "Einladungsemail erneut senden", + "security_list_tip": "Haben Sie sich für unsere Sicherheitsliste angemeldet? Bleiben Sie informiert, um Ihre Instanz sicher zu halten!", + "security_list_tip_link": "Hier registrieren.", "share_invite_link": "Einladungslink teilen", "share_this_link_to_let_your_organization_member_join_your_organization": "Teile diesen Link, damit dein Organisationsmitglied deiner Organisation beitreten kann:", "test_email_sent_successfully": "Test-E-Mail erfolgreich gesendet", diff --git a/apps/web/locales/en-US.json b/apps/web/locales/en-US.json index 8ed860aa93..e81e264acb 100644 --- a/apps/web/locales/en-US.json +++ b/apps/web/locales/en-US.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "Mix of uppercase and lowercase", "please_verify_captcha": "Please verify reCAPTCHA", "privacy_policy": "Privacy Policy", + "product_updates_description": "Monthly product news and feature updates, Privacy Policy applies.", + "product_updates_title": "Product updates", + "security_updates_description": "Security relevant information only, Privacy Policy applies.", + "security_updates_title": "Security updates", "terms_of_service": "Terms of Service", "title": "Create your Formbricks account" }, @@ -1015,6 +1019,8 @@ "remove_logo": "Remove logo", "replace_logo": "Replace logo", "resend_invitation_email": "Resend Invitation Email", + "security_list_tip": "Are you signed up for our Security List? Stay informed to keep your instance secure!", + "security_list_tip_link": "Sign up here.", "share_invite_link": "Share Invite Link", "share_this_link_to_let_your_organization_member_join_your_organization": "Share this link to let your organization member join your organization:", "test_email_sent_successfully": "Test email sent successfully", diff --git a/apps/web/locales/es-ES.json b/apps/web/locales/es-ES.json index 9f47c5b00a..4693ac2915 100644 --- a/apps/web/locales/es-ES.json +++ b/apps/web/locales/es-ES.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "Mezcla de mayúsculas y minúsculas", "please_verify_captcha": "Por favor, verifica el reCAPTCHA", "privacy_policy": "Política de privacidad", + "product_updates_description": "Noticias mensuales del producto y actualizaciones de funciones, se aplica la política de privacidad.", + "product_updates_title": "Actualizaciones del producto", + "security_updates_description": "Solo información relevante sobre seguridad, se aplica la política de privacidad.", + "security_updates_title": "Actualizaciones de seguridad", "terms_of_service": "Términos de servicio", "title": "Crea tu cuenta de Formbricks" }, @@ -1015,6 +1019,8 @@ "remove_logo": "Eliminar logotipo", "replace_logo": "Reemplazar logotipo", "resend_invitation_email": "Reenviar correo electrónico de invitación", + "security_list_tip": "¿Estás suscrito a nuestra lista de seguridad? ¡Mantente informado para mantener tu instancia segura!", + "security_list_tip_link": "Regístrate aquí.", "share_invite_link": "Compartir enlace de invitación", "share_this_link_to_let_your_organization_member_join_your_organization": "Comparte este enlace para permitir que los miembros de tu organización se unan a tu organización:", "test_email_sent_successfully": "Correo electrónico de prueba enviado correctamente", diff --git a/apps/web/locales/fr-FR.json b/apps/web/locales/fr-FR.json index 9fcfae9581..15bff62aba 100644 --- a/apps/web/locales/fr-FR.json +++ b/apps/web/locales/fr-FR.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "Mélange de majuscules et de minuscules", "please_verify_captcha": "Veuillez vérifier reCAPTCHA", "privacy_policy": "Politique de confidentialité", + "product_updates_description": "Actualités mensuelles du produit et mises à jour des fonctionnalités, la politique de confidentialité s'applique.", + "product_updates_title": "Mises à jour du produit", + "security_updates_description": "Informations relatives à la sécurité uniquement, la politique de confidentialité s'applique.", + "security_updates_title": "Mises à jour de sécurité", "terms_of_service": "Conditions d'utilisation", "title": "Créez votre compte Formbricks" }, @@ -1015,6 +1019,8 @@ "remove_logo": "Supprimer le logo", "replace_logo": "Remplacer le logo", "resend_invitation_email": "Renvoyer l'e-mail d'invitation", + "security_list_tip": "Êtes-vous inscrit à notre liste de sécurité ? Restez informé pour maintenir votre instance sécurisée !", + "security_list_tip_link": "Inscrivez-vous ici.", "share_invite_link": "Partager le lien d'invitation", "share_this_link_to_let_your_organization_member_join_your_organization": "Partagez ce lien pour permettre à un membre de votre organisation de rejoindre votre organisation :", "test_email_sent_successfully": "E-mail de test envoyé avec succès", diff --git a/apps/web/locales/ja-JP.json b/apps/web/locales/ja-JP.json index bbaac593ce..9f83ec638c 100644 --- a/apps/web/locales/ja-JP.json +++ b/apps/web/locales/ja-JP.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "大文字と小文字を混ぜる", "please_verify_captcha": "reCAPTCHAを認証してください", "privacy_policy": "プライバシーポリシー", + "product_updates_description": "毎月の製品ニュースと機能アップデート、プライバシーポリシーが適用されます。", + "product_updates_title": "製品アップデート", + "security_updates_description": "セキュリティ関連情報のみ、プライバシーポリシーが適用されます。", + "security_updates_title": "セキュリティアップデート", "terms_of_service": "利用規約", "title": "Formbricksアカウントを作成" }, @@ -1015,6 +1019,8 @@ "remove_logo": "ロゴを削除", "replace_logo": "ロゴを交換", "resend_invitation_email": "招待メールを再送信", + "security_list_tip": "セキュリティリストに登録していますか?インスタンスを安全に保つために最新情報を入手しましょう!", + "security_list_tip_link": "こちらからサインアップしてください。", "share_invite_link": "招待リンクを共有", "share_this_link_to_let_your_organization_member_join_your_organization": "このリンクを共有して、組織メンバーを招待できます:", "test_email_sent_successfully": "テストメールを正常に送信しました", diff --git a/apps/web/locales/nl-NL.json b/apps/web/locales/nl-NL.json index 8e3f5382dc..5ffe543d75 100644 --- a/apps/web/locales/nl-NL.json +++ b/apps/web/locales/nl-NL.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "Mix van hoofdletters en kleine letters", "please_verify_captcha": "Controleer reCAPTCHA", "privacy_policy": "Privacybeleid", + "product_updates_description": "Maandelijks productnieuws en feature-updates, privacybeleid is van toepassing.", + "product_updates_title": "Product-updates", + "security_updates_description": "Alleen beveiligingsrelevante informatie, privacybeleid is van toepassing.", + "security_updates_title": "Beveiligingsupdates", "terms_of_service": "Servicevoorwaarden", "title": "Maak uw Formbricks-account aan" }, @@ -1015,6 +1019,8 @@ "remove_logo": "Logo verwijderen", "replace_logo": "Logo vervangen", "resend_invitation_email": "Uitnodigings-e-mail opnieuw verzenden", + "security_list_tip": "Ben je aangemeld voor onze beveiligingslijst? Blijf op de hoogte om je instantie veilig te houden!", + "security_list_tip_link": "Meld je hier aan.", "share_invite_link": "Deel de uitnodigingslink", "share_this_link_to_let_your_organization_member_join_your_organization": "Deel deze link om uw organisatielid lid te laten worden van uw organisatie:", "test_email_sent_successfully": "Test-e-mail succesvol verzonden", diff --git a/apps/web/locales/pt-BR.json b/apps/web/locales/pt-BR.json index 87393a0d41..5a35f10f38 100644 --- a/apps/web/locales/pt-BR.json +++ b/apps/web/locales/pt-BR.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "mistura de maiúsculas e minúsculas", "please_verify_captcha": "Por favor, verifique o reCAPTCHA", "privacy_policy": "Política de Privacidade", + "product_updates_description": "Novidades mensais do produto e atualizações de recursos, a Política de Privacidade se aplica.", + "product_updates_title": "Atualizações do produto", + "security_updates_description": "Apenas informações relevantes sobre segurança, a Política de Privacidade se aplica.", + "security_updates_title": "Atualizações de segurança", "terms_of_service": "Termos de Serviço", "title": "Crie sua conta no Formbricks" }, @@ -1015,6 +1019,8 @@ "remove_logo": "Remover logo", "replace_logo": "Substituir logo", "resend_invitation_email": "Reenviar E-mail de Convite", + "security_list_tip": "Você está inscrito na nossa Lista de Segurança? Mantenha-se informado para manter sua instância segura!", + "security_list_tip_link": "Cadastre-se aqui.", "share_invite_link": "Compartilhar Link de Convite", "share_this_link_to_let_your_organization_member_join_your_organization": "Compartilhe esse link para que o membro da sua organização possa entrar na sua organização:", "test_email_sent_successfully": "E-mail de teste enviado com sucesso", diff --git a/apps/web/locales/pt-PT.json b/apps/web/locales/pt-PT.json index 5ad8f7f370..3c47d31f4b 100644 --- a/apps/web/locales/pt-PT.json +++ b/apps/web/locales/pt-PT.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "Mistura de maiúsculas e minúsculas", "please_verify_captcha": "Por favor, verifique o reCAPTCHA", "privacy_policy": "Política de Privacidade", + "product_updates_description": "Notícias mensais sobre o produto e atualizações de funcionalidades, aplica-se a Política de Privacidade.", + "product_updates_title": "Atualizações do produto", + "security_updates_description": "Apenas informações relevantes sobre segurança, aplica-se a Política de Privacidade.", + "security_updates_title": "Atualizações de segurança", "terms_of_service": "Termos de Serviço", "title": "Crie a sua conta Formbricks" }, @@ -1015,6 +1019,8 @@ "remove_logo": "Remover logótipo", "replace_logo": "Substituir logotipo", "resend_invitation_email": "Reenviar Email de Convite", + "security_list_tip": "Está inscrito na nossa Lista de Segurança? Mantenha-se informado para manter a sua instância segura!", + "security_list_tip_link": "Inscreva-se aqui.", "share_invite_link": "Partilhar Link de Convite", "share_this_link_to_let_your_organization_member_join_your_organization": "Partilhe este link para permitir que o membro da sua organização se junte à sua organização:", "test_email_sent_successfully": "Email de teste enviado com sucesso", diff --git a/apps/web/locales/ro-RO.json b/apps/web/locales/ro-RO.json index ac2a47d734..03950ec71a 100644 --- a/apps/web/locales/ro-RO.json +++ b/apps/web/locales/ro-RO.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "Amestec de majuscule și minuscule", "please_verify_captcha": "Vă rugăm să verificați CAPTCHA", "privacy_policy": "Politica de confidențialitate", + "product_updates_description": "Noutăți lunare despre produse și actualizări de funcționalități; se aplică Politica de confidențialitate.", + "product_updates_title": "Actualizări de produs", + "security_updates_description": "Doar informații relevante pentru securitate; se aplică Politica de confidențialitate.", + "security_updates_title": "Actualizări de securitate", "terms_of_service": "Termeni de utilizare a serviciului", "title": "Creați-vă contul Formbricks" }, @@ -1015,6 +1019,8 @@ "remove_logo": "Înlătură siglă", "replace_logo": "Înlocuiește sigla", "resend_invitation_email": "Retrimite emailul de invitație", + "security_list_tip": "Ești abonat la lista noastră de securitate? Rămâi informat pentru a-ți menține instanța în siguranță!", + "security_list_tip_link": "Înscrie-te aici.", "share_invite_link": "Distribuie link-ul de invitație", "share_this_link_to_let_your_organization_member_join_your_organization": "Distribuie acest link pentru a permite membrului organizației să se alăture organizației tale:", "test_email_sent_successfully": "Email de test trimis cu succes", diff --git a/apps/web/locales/ru-RU.json b/apps/web/locales/ru-RU.json index d4e881bc6c..3c50bb5932 100644 --- a/apps/web/locales/ru-RU.json +++ b/apps/web/locales/ru-RU.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "Сочетание заглавных и строчных букв", "please_verify_captcha": "Пожалуйста, подтвердите reCAPTCHA", "privacy_policy": "Политика конфиденциальности", + "product_updates_description": "Ежемесячные новости о продукте и обновления функций. Применяется Политика конфиденциальности.", + "product_updates_title": "Обновления продукта", + "security_updates_description": "Только важная информация по безопасности. Применяется Политика конфиденциальности.", + "security_updates_title": "Обновления безопасности", "terms_of_service": "Условия использования", "title": "Создайте аккаунт Formbricks" }, @@ -1015,6 +1019,8 @@ "remove_logo": "Удалить логотип", "replace_logo": "Заменить логотип", "resend_invitation_email": "Отправить приглашение повторно", + "security_list_tip": "Вы подписаны на нашу рассылку по безопасности? Будьте в курсе, чтобы обезопасить свой экземпляр!", + "security_list_tip_link": "Зарегистрируйтесь здесь.", "share_invite_link": "Поделиться ссылкой-приглашением", "share_this_link_to_let_your_organization_member_join_your_organization": "Поделитесь этой ссылкой, чтобы участник вашей организации мог присоединиться к ней:", "test_email_sent_successfully": "Тестовое письмо успешно отправлено", diff --git a/apps/web/locales/sv-SE.json b/apps/web/locales/sv-SE.json index 1468d0758c..f3a8be9411 100644 --- a/apps/web/locales/sv-SE.json +++ b/apps/web/locales/sv-SE.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "Blandning av stora och små bokstäver", "please_verify_captcha": "Vänligen verifiera reCAPTCHA", "privacy_policy": "Integritetspolicy", + "product_updates_description": "Månatliga produktnyheter och funktionsuppdateringar. Integritetspolicyn gäller.", + "product_updates_title": "Produktuppdateringar", + "security_updates_description": "Endast säkerhetsrelaterad information. Integritetspolicyn gäller.", + "security_updates_title": "Säkerhetsuppdateringar", "terms_of_service": "Användarvillkor", "title": "Skapa ditt Formbricks-konto" }, @@ -1015,6 +1019,8 @@ "remove_logo": "Ta bort logotyp", "replace_logo": "Ersätt logotyp", "resend_invitation_email": "Skicka inbjudningsmejl igen", + "security_list_tip": "Är du med på vår säkerhetslista? Håll dig informerad för att skydda din instans!", + "security_list_tip_link": "Registrera dig här.", "share_invite_link": "Dela inbjudningslänk", "share_this_link_to_let_your_organization_member_join_your_organization": "Dela denna länk för att låta din organisationsmedlem gå med i din organisation:", "test_email_sent_successfully": "Test-e-post skickat", diff --git a/apps/web/locales/zh-Hans-CN.json b/apps/web/locales/zh-Hans-CN.json index 1edf51f331..55797e497e 100644 --- a/apps/web/locales/zh-Hans-CN.json +++ b/apps/web/locales/zh-Hans-CN.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "大小写混合", "please_verify_captcha": "请 验证 reCAPTCHA", "privacy_policy": "隐私政策", + "product_updates_description": "每月产品新闻和功能更新,适用隐私政策。", + "product_updates_title": "产品更新", + "security_updates_description": "仅限安全相关信息,适用隐私政策。", + "security_updates_title": "安全更新", "terms_of_service": "服务条款", "title": "创建你的 Formbricks 账户" }, @@ -1015,6 +1019,8 @@ "remove_logo": "移除 logo", "replace_logo": "替换 logo", "resend_invitation_email": "重新发送邀请邮件", + "security_list_tip": "您已订阅我们的安全列表了吗?保持关注,保障您的实例安全!", + "security_list_tip_link": "点击此处注册。", "share_invite_link": "分享邀请链接", "share_this_link_to_let_your_organization_member_join_your_organization": "分享 这个 链接 以 让 你的 组织 成员 加入 你的 组织:", "test_email_sent_successfully": "测试 邮件 发送 成功", diff --git a/apps/web/locales/zh-Hant-TW.json b/apps/web/locales/zh-Hant-TW.json index a5336866e5..7119476d5e 100644 --- a/apps/web/locales/zh-Hant-TW.json +++ b/apps/web/locales/zh-Hant-TW.json @@ -75,6 +75,10 @@ "password_validation_uppercase_and_lowercase": "混合使用大小寫字母", "please_verify_captcha": "請驗證 reCAPTCHA", "privacy_policy": "隱私權政策", + "product_updates_description": "每月產品新聞與功能更新,適用隱私權政策。", + "product_updates_title": "產品更新", + "security_updates_description": "僅限安全相關資訊,適用隱私權政策。", + "security_updates_title": "安全更新", "terms_of_service": "服務條款", "title": "建立您的 Formbricks 帳戶" }, @@ -1015,6 +1019,8 @@ "remove_logo": "移除標誌", "replace_logo": "取代標誌", "resend_invitation_email": "重新發送邀請電子郵件", + "security_list_tip": "您已訂閱我們的安全名單了嗎?保持關注,確保您的實例安全!", + "security_list_tip_link": "請在此註冊。", "share_invite_link": "分享邀請連結", "share_this_link_to_let_your_organization_member_join_your_organization": "分享此連結以讓您的組織成員加入您的組織:", "test_email_sent_successfully": "測試電子郵件已成功發送", diff --git a/apps/web/modules/auth/signup/actions.ts b/apps/web/modules/auth/signup/actions.ts index f52965fc23..c3c4f3745a 100644 --- a/apps/web/modules/auth/signup/actions.ts +++ b/apps/web/modules/auth/signup/actions.ts @@ -18,6 +18,7 @@ import { applyIPRateLimit } from "@/modules/core/rate-limit/helpers"; import { rateLimitConfigs } from "@/modules/core/rate-limit/rate-limit-configs"; import { withAuditLogging } from "@/modules/ee/audit-logs/lib/handler"; import { getIsMultiOrgEnabled } from "@/modules/ee/license-check/lib/utils"; +import { subscribeUserToMailingList } from "@/modules/ee/mailing/lib/mailing-subscription"; import { sendInviteAcceptedEmail, sendVerificationEmail } from "@/modules/email"; const ZCreatedUser = ZUser.pick({ @@ -44,6 +45,9 @@ const ZCreateUserAction = z.object({ (token) => !IS_TURNSTILE_CONFIGURED || (IS_TURNSTILE_CONFIGURED && token), "CAPTCHA verification required" ), + isFormbricksCloud: z.boolean(), + subscribeToSecurityUpdates: z.boolean().optional(), + subscribeToProductUpdates: z.boolean().optional(), }); async function verifyTurnstileIfConfigured(turnstileToken: string | undefined): Promise { @@ -191,6 +195,13 @@ export const createUserAction = actionClient.schema(ZCreateUserAction).action( parsedInput.inviteToken, parsedInput.emailVerificationDisabled ); + + await subscribeUserToMailingList({ + email: user.email, + isFormbricksCloud: parsedInput.isFormbricksCloud, + subscribeToSecurityUpdates: parsedInput.subscribeToSecurityUpdates, + subscribeToProductUpdates: parsedInput.subscribeToProductUpdates, + }); } if (user) { diff --git a/apps/web/modules/auth/signup/components/signup-form.tsx b/apps/web/modules/auth/signup/components/signup-form.tsx index 0aa419892e..34baef82de 100644 --- a/apps/web/modules/auth/signup/components/signup-form.tsx +++ b/apps/web/modules/auth/signup/components/signup-form.tsx @@ -15,6 +15,7 @@ import { createUserAction } from "@/modules/auth/signup/actions"; import { TermsPrivacyLinks } from "@/modules/auth/signup/components/terms-privacy-links"; import { SSOOptions } from "@/modules/ee/sso/components/sso-options"; import { Button } from "@/modules/ui/components/button"; +import { Checkbox } from "@/modules/ui/components/checkbox"; import { FormControl, FormError, FormField, FormItem } from "@/modules/ui/components/form"; import { Input } from "@/modules/ui/components/input"; import { PasswordInput } from "@/modules/ui/components/password-input"; @@ -48,6 +49,7 @@ interface SignupFormProps { samlTenant: string; samlProduct: string; turnstileSiteKey?: string; + isFormbricksCloud: boolean; } export const SignupForm = ({ @@ -69,6 +71,7 @@ export const SignupForm = ({ samlTenant, samlProduct, turnstileSiteKey, + isFormbricksCloud, }: SignupFormProps) => { const [showLogin, setShowLogin] = useState(false); const searchParams = useSearchParams(); @@ -76,6 +79,8 @@ export const SignupForm = ({ const inviteToken = searchParams?.get("inviteToken"); const router = useRouter(); const [turnstileToken, setTurnstileToken] = useState(); + const [subscribeToSecurityUpdates, setSubscribeToSecurityUpdates] = useState(false); + const [subscribeToProductUpdates, setSubscribeToProductUpdates] = useState(false); const turnstile = useTurnstile(); @@ -110,6 +115,9 @@ export const SignupForm = ({ inviteToken: inviteToken ?? "", emailVerificationDisabled, turnstileToken, + isFormbricksCloud, + subscribeToSecurityUpdates, + subscribeToProductUpdates, }); const emailTokenActionResponse = await createEmailTokenAction({ email: data.email }); @@ -239,6 +247,43 @@ export const SignupForm = ({ /> )} + {showLogin && + (isFormbricksCloud ? ( + + ) : ( + + ))} + {showLogin && (