mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-27 08:50:38 -06:00
Compare commits
5 Commits
feat/datab
...
feat/secur
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0233541287 | ||
|
|
adf12f551d | ||
|
|
3f2bddc358 | ||
|
|
ae6d1ac133 | ||
|
|
7c4569cd50 |
@@ -18,7 +18,8 @@
|
||||
"zh-Hant-TW",
|
||||
"nl-NL",
|
||||
"es-ES",
|
||||
"sv-SE"
|
||||
"sv-SE",
|
||||
"ru-RU"
|
||||
]
|
||||
},
|
||||
"version": 1.8
|
||||
|
||||
@@ -446,14 +446,12 @@ checksums:
|
||||
emails/forgot_password_email_text: 5100fa2fe2180ded9cb2d89b4f77d2e0
|
||||
emails/hidden_field: 3ed5c58d0ed359e558cdf7bd33606d2d
|
||||
emails/imprint: c4e5f2a1994d3cc5896b200709cc499c
|
||||
emails/invite_accepted_email_heading: 6ff6dff269b0f1ac1b73912c9e344343
|
||||
emails/invite_accepted_email_heading: 80763c6e4585cd57fa58e4d2d82e6500
|
||||
emails/invite_accepted_email_subject: 4f5f2a68c98dd1dd01143fcae3be5562
|
||||
emails/invite_accepted_email_text_par1: b27eadc4779c9fa477103d136a6acab9
|
||||
emails/invite_accepted_email_text_par2: c77209b510baf0415264fdb5ab8076a8
|
||||
emails/invite_accepted_email_text: 48d792826ab9a97eed27599c17ec70d5
|
||||
emails/invite_email_button_label: 02099d40cd11e717c0431fa43e68272c
|
||||
emails/invite_email_heading: 6ff6dff269b0f1ac1b73912c9e344343
|
||||
emails/invite_email_text_par1: 70b976a3d4a5509f6d905f9f3f962ada
|
||||
emails/invite_email_text_par2: 14da6da9fdbc21a1cb38988abac7932d
|
||||
emails/invite_email_heading: d9f9b18e4de575980de3cde3e4ed08bf
|
||||
emails/invite_email_text: 1499fa615105121a133440929b039a64
|
||||
emails/invite_member_email_subject: 295e329b1642339dc7cc2b49a687e1f8
|
||||
emails/new_email_verification_text: b7f00f47d04afa9e872176d9933f2d93
|
||||
emails/number_variable: d4f2bbb1965c791cf9921a5112914f3f
|
||||
@@ -1101,6 +1099,13 @@ checksums:
|
||||
environments/settings/teams/please_fill_all_project_fields: 6712059df63c432ecd31f3c52b8e4d87
|
||||
environments/settings/teams/read: 2494ca23d10e5b6381eb271aceeb5270
|
||||
environments/settings/teams/read_write: 278a90dade128198d4c93ac00c345320
|
||||
environments/settings/teams/security_updates_description: 17c49b565a7dde28b810f67af2e8db07
|
||||
environments/settings/teams/security_updates_enroll: edcc8815899ece9209ce981c26c44df3
|
||||
environments/settings/teams/security_updates_enrolled: 98863ec2d846b7a13ff1ed38ce1038fe
|
||||
environments/settings/teams/security_updates_enrolled_description: d9c7605767af8f4d7265cba7dfba5f11
|
||||
environments/settings/teams/security_updates_enrolled_successfully: 3bbb41fac1c04effec3af8ffbd8b72c5
|
||||
environments/settings/teams/security_updates_enrolling: 15ca7daa32fb57e18a0a6357de26eb4b
|
||||
environments/settings/teams/security_updates_title: 2f5f5f55bb9a325b5c8228bcad4f2784
|
||||
environments/settings/teams/select_member: 7f4a38312aabbbe3fe92756b57bd5d75
|
||||
environments/settings/teams/select_project: 6e4f4a24178660851d9ae0874706be9f
|
||||
environments/settings/teams/team_admin: 5df68214685738029af678ae1d5912bb
|
||||
|
||||
@@ -177,6 +177,7 @@ export const AVAILABLE_LOCALES: TUserLocale[] = [
|
||||
"zh-Hans-CN",
|
||||
"es-ES",
|
||||
"sv-SE",
|
||||
"ru-RU",
|
||||
];
|
||||
|
||||
// Billing constants
|
||||
|
||||
@@ -141,6 +141,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Engels (VS)",
|
||||
"es-ES": "Inglés (EE.UU.)",
|
||||
"sv-SE": "Engelska (USA)",
|
||||
"ru-RU": "Английский (США)",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -158,6 +159,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Duits",
|
||||
"es-ES": "Alemán",
|
||||
"sv-SE": "Tyska",
|
||||
"ru-RU": "Немецкий",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -175,6 +177,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Portugees (Brazilië)",
|
||||
"es-ES": "Portugués (Brasil)",
|
||||
"sv-SE": "Portugisiska (Brasilien)",
|
||||
"ru-RU": "Португальский (Бразилия)",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -192,6 +195,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Frans",
|
||||
"es-ES": "Francés",
|
||||
"sv-SE": "Franska",
|
||||
"ru-RU": "Французский",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -209,6 +213,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Chinees (Traditioneel)",
|
||||
"es-ES": "Chino (Tradicional)",
|
||||
"sv-SE": "Kinesiska (traditionell)",
|
||||
"ru-RU": "Китайский (традиционный)",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -226,6 +231,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Portugees (Portugal)",
|
||||
"es-ES": "Portugués (Portugal)",
|
||||
"sv-SE": "Portugisiska (Portugal)",
|
||||
"ru-RU": "Португальский (Португалия)",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -243,6 +249,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Roemeens",
|
||||
"es-ES": "Rumano",
|
||||
"sv-SE": "Rumänska",
|
||||
"ru-RU": "Румынский",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -260,6 +267,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Japans",
|
||||
"es-ES": "Japonés",
|
||||
"sv-SE": "Japanska",
|
||||
"ru-RU": "Японский",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -277,6 +285,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Chinees (Vereenvoudigd)",
|
||||
"es-ES": "Chino (Simplificado)",
|
||||
"sv-SE": "Kinesiska (förenklad)",
|
||||
"ru-RU": "Китайский (упрощенный)",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -294,6 +303,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Nederlands",
|
||||
"es-ES": "Neerlandés",
|
||||
"sv-SE": "Nederländska",
|
||||
"ru-RU": "Голландский",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -311,6 +321,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Spaans",
|
||||
"es-ES": "Español",
|
||||
"sv-SE": "Spanska",
|
||||
"ru-RU": "Испанский",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -328,6 +339,7 @@ export const appLanguages = [
|
||||
"nl-NL": "Zweeds",
|
||||
"es-ES": "Sueco",
|
||||
"sv-SE": "Svenska",
|
||||
"ru-RU": "Шведский",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { formatDistance, intlFormat } from "date-fns";
|
||||
import { de, enUS, es, fr, ja, nl, pt, ptBR, ro, sv, zhCN, zhTW } from "date-fns/locale";
|
||||
import { de, enUS, es, fr, ja, nl, pt, ptBR, ro, ru, sv, zhCN, zhTW } from "date-fns/locale";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
export const convertDateString = (dateString: string | null) => {
|
||||
@@ -107,6 +107,8 @@ const getLocaleForTimeSince = (locale: TUserLocale) => {
|
||||
return zhCN;
|
||||
case "es-ES":
|
||||
return es;
|
||||
case "ru-RU":
|
||||
return ru;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -475,14 +475,12 @@
|
||||
"forgot_password_email_text": "Du hast einen Link angefordert, um dein Passwort zu ändern. Du kannst dies tun, indem Du auf den untenstehenden Link klickst:",
|
||||
"hidden_field": "Verstecktes Feld",
|
||||
"imprint": "Impressum",
|
||||
"invite_accepted_email_heading": "Hey",
|
||||
"invite_accepted_email_heading": "Hey {inviterName}",
|
||||
"invite_accepted_email_subject": "Du hast einen neuen Organisation-Mitglied!",
|
||||
"invite_accepted_email_text_par1": "Wollte dir nur Bescheid geben, dass",
|
||||
"invite_accepted_email_text_par2": "deine Einladung angenommen hat. Viel Spaß bei der Zusammenarbeit!",
|
||||
"invite_accepted_email_text": "Nur zur Info: {inviteeName} hat deine Einladung angenommen. Viel Spaß bei der Zusammenarbeit!",
|
||||
"invite_email_button_label": "Organisation beitreten",
|
||||
"invite_email_heading": "Hey",
|
||||
"invite_email_text_par1": "Dein Kollege",
|
||||
"invite_email_text_par2": "hat Dich eingeladen, Formbricks zu nutzen. Um die Einladung anzunehmen, klicke bitte auf den untenstehenden Link:",
|
||||
"invite_email_heading": "Hey {inviteeName}",
|
||||
"invite_email_text": "Dein Kollege {inviterName} hat dich eingeladen, bei Formbricks mitzumachen. Um die Einladung anzunehmen, klicke bitte auf den Link unten:",
|
||||
"invite_member_email_subject": "Du wurdest eingeladen, Formbricks zu nutzen!",
|
||||
"new_email_verification_text": "Um Ihre neue E-Mail-Adresse zu bestätigen, klicken Sie bitte auf die Schaltfläche unten:",
|
||||
"number_variable": "Zahlenvariable",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "Bitte fülle alle Felder aus, um ein neues Projekt hinzuzufügen.",
|
||||
"read": "Lesen",
|
||||
"read_write": "Lesen & Schreiben",
|
||||
"security_updates_description": "Melden Sie sich für unsere Sicherheits-Mailingliste an, um informiert zu bleiben, falls Sicherheitslücken gefunden werden.",
|
||||
"security_updates_enroll": "Jetzt anmelden",
|
||||
"security_updates_enrolled": "Angemeldet",
|
||||
"security_updates_enrolled_description": "Sie sind angemeldet, um Sicherheitsupdates unter {email} zu erhalten.",
|
||||
"security_updates_enrolled_successfully": "Erfolgreich für Sicherheitsupdates angemeldet!",
|
||||
"security_updates_enrolling": "Wird angemeldet...",
|
||||
"security_updates_title": "Sicherheitsupdates",
|
||||
"select_member": "Mitglied auswählen",
|
||||
"select_project": "Projekt auswählen",
|
||||
"team_admin": "Team-Admin",
|
||||
|
||||
@@ -475,14 +475,12 @@
|
||||
"forgot_password_email_text": "You have requested a link to change your password. You can do this by clicking the link below:",
|
||||
"hidden_field": "Hidden field",
|
||||
"imprint": "Imprint",
|
||||
"invite_accepted_email_heading": "Hey",
|
||||
"invite_accepted_email_heading": "Hey {inviterName}",
|
||||
"invite_accepted_email_subject": "You've got a new organization member!",
|
||||
"invite_accepted_email_text_par1": "Just letting you know that",
|
||||
"invite_accepted_email_text_par2": "accepted your invitation. Have fun collaborating!",
|
||||
"invite_accepted_email_text": "Just letting you know that {inviteeName} accepted your invitation. Have fun collaborating!",
|
||||
"invite_email_button_label": "Join organization",
|
||||
"invite_email_heading": "Hey",
|
||||
"invite_email_text_par1": "Your colleague",
|
||||
"invite_email_text_par2": "invited you to join them at Formbricks. To accept the invitation, please click the link below:",
|
||||
"invite_email_heading": "Hey {inviteeName}",
|
||||
"invite_email_text": "Your colleague {inviterName} invited you to join them at Formbricks. To accept the invitation, please click the link below:",
|
||||
"invite_member_email_subject": "You're invited to collaborate on Formbricks!",
|
||||
"new_email_verification_text": "To verify your new email address, please click the button below:",
|
||||
"number_variable": "Number variable",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "Please fill all the fields to add a new project.",
|
||||
"read": "Read",
|
||||
"read_write": "Read & Write",
|
||||
"security_updates_description": "Enroll to our Security Mailing List to stay informed if vulnerabilities are found.",
|
||||
"security_updates_enroll": "Enroll now",
|
||||
"security_updates_enrolled": "Enrolled",
|
||||
"security_updates_enrolled_description": "You're enrolled to receive security updates at {email}.",
|
||||
"security_updates_enrolled_successfully": "Successfully enrolled for security updates!",
|
||||
"security_updates_enrolling": "Enrolling...",
|
||||
"security_updates_title": "Security Updates",
|
||||
"select_member": "Select member",
|
||||
"select_project": "Select project",
|
||||
"team_admin": "Team Admin",
|
||||
|
||||
@@ -475,14 +475,12 @@
|
||||
"forgot_password_email_text": "Has solicitado un enlace para cambiar tu contraseña. Puedes hacerlo haciendo clic en el enlace a continuación:",
|
||||
"hidden_field": "Campo oculto",
|
||||
"imprint": "Aviso legal",
|
||||
"invite_accepted_email_heading": "Hola",
|
||||
"invite_accepted_email_heading": "Hola, {inviterName}",
|
||||
"invite_accepted_email_subject": "¡Tienes un nuevo miembro en la organización!",
|
||||
"invite_accepted_email_text_par1": "Solo para informarte que",
|
||||
"invite_accepted_email_text_par2": "ha aceptado tu invitación. ¡Diviértete colaborando!",
|
||||
"invite_accepted_email_text": "Te informamos que {inviteeName} ha aceptado tu invitación. ¡Que disfrutéis colaborando!",
|
||||
"invite_email_button_label": "Unirse a la organización",
|
||||
"invite_email_heading": "Hola",
|
||||
"invite_email_text_par1": "Tu colega",
|
||||
"invite_email_text_par2": "te ha invitado a unirte a Formbricks. Para aceptar la invitación, por favor haz clic en el enlace a continuación:",
|
||||
"invite_email_heading": "Hola, {inviteeName}",
|
||||
"invite_email_text": "Tu compañero {inviterName} te ha invitado a unirte a Formbricks. Para aceptar la invitación, haz clic en el enlace que aparece a continuación:",
|
||||
"invite_member_email_subject": "¡Estás invitado a colaborar en Formbricks!",
|
||||
"new_email_verification_text": "Para verificar tu nueva dirección de correo electrónico, por favor haz clic en el botón a continuación:",
|
||||
"number_variable": "Variable numérica",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "Por favor, rellena todos los campos para añadir un nuevo proyecto.",
|
||||
"read": "Lectura",
|
||||
"read_write": "Lectura y escritura",
|
||||
"security_updates_description": "Inscríbete en nuestra lista de correo de seguridad para mantenerte informado si se encuentran vulnerabilidades.",
|
||||
"security_updates_enroll": "Inscribirse ahora",
|
||||
"security_updates_enrolled": "Inscrito",
|
||||
"security_updates_enrolled_description": "Estás inscrito para recibir actualizaciones de seguridad en {email}.",
|
||||
"security_updates_enrolled_successfully": "Te has inscrito correctamente para recibir actualizaciones de seguridad.",
|
||||
"security_updates_enrolling": "Inscribiendo...",
|
||||
"security_updates_title": "Actualizaciones de seguridad",
|
||||
"select_member": "Seleccionar miembro",
|
||||
"select_project": "Seleccionar proyecto",
|
||||
"team_admin": "Administrador de equipo",
|
||||
|
||||
@@ -474,15 +474,13 @@
|
||||
"forgot_password_email_subject": "Réinitialise ton mot de passe Formbricks",
|
||||
"forgot_password_email_text": "Vous avez demandé un lien pour changer votre mot de passe. Vous pouvez le faire en cliquant sur le lien ci-dessous :",
|
||||
"hidden_field": "Champ caché",
|
||||
"imprint": "Empreinte",
|
||||
"invite_accepted_email_heading": "Salut",
|
||||
"imprint": "Impressum",
|
||||
"invite_accepted_email_heading": "Salut {inviterName}",
|
||||
"invite_accepted_email_subject": "Vous avez un nouveau membre dans votre organisation !",
|
||||
"invite_accepted_email_text_par1": "Je te fais savoir que",
|
||||
"invite_accepted_email_text_par2": "accepté votre invitation. Amusez-vous bien à collaborer !",
|
||||
"invite_accepted_email_text": "Juste pour te faire savoir que {inviteeName} a accepté ton invitation. Amusez-vous bien à collaborer !",
|
||||
"invite_email_button_label": "Rejoindre l'organisation",
|
||||
"invite_email_heading": "Salut",
|
||||
"invite_email_text_par1": "Votre collègue",
|
||||
"invite_email_text_par2": "vous a invité à les rejoindre sur Formbricks. Pour accepter l'invitation, veuillez cliquer sur le lien ci-dessous :",
|
||||
"invite_email_heading": "Salut {inviteeName}",
|
||||
"invite_email_text": "Ton collègue {inviterName} t'a invité à le rejoindre sur Formbricks. Pour accepter l'invitation, clique sur le lien ci-dessous :",
|
||||
"invite_member_email_subject": "Vous avez été invité à collaborer sur Formbricks !",
|
||||
"new_email_verification_text": "Pour confirmer votre nouvelle adresse e-mail, veuillez cliquer sur le bouton ci-dessous :",
|
||||
"number_variable": "Variable numérique",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "Veuillez remplir tous les champs pour ajouter un nouveau projet.",
|
||||
"read": "Lire",
|
||||
"read_write": "Lire et Écrire",
|
||||
"security_updates_description": "Inscrivez-vous à notre liste de diffusion sécurité pour être informé si des vulnérabilités sont découvertes.",
|
||||
"security_updates_enroll": "S'inscrire maintenant",
|
||||
"security_updates_enrolled": "Inscrit",
|
||||
"security_updates_enrolled_description": "Vous êtes inscrit pour recevoir les mises à jour de sécurité à {email}.",
|
||||
"security_updates_enrolled_successfully": "Inscription aux mises à jour de sécurité réussie !",
|
||||
"security_updates_enrolling": "Inscription en cours...",
|
||||
"security_updates_title": "Mises à jour de sécurité",
|
||||
"select_member": "Sélectionner membre",
|
||||
"select_project": "Sélectionner projet",
|
||||
"team_admin": "Administrateur d'équipe",
|
||||
|
||||
@@ -475,14 +475,12 @@
|
||||
"forgot_password_email_text": "パスワード変更のリンクがリクエストされました。以下のリンクをクリックして変更できます。",
|
||||
"hidden_field": "非表示フィールド",
|
||||
"imprint": "企業情報",
|
||||
"invite_accepted_email_heading": "こんにちは",
|
||||
"invite_accepted_email_heading": "{inviterName}さん",
|
||||
"invite_accepted_email_subject": "新しい組織メンバーが加わりました!",
|
||||
"invite_accepted_email_text_par1": "お知らせですが、",
|
||||
"invite_accepted_email_text_par2": "があなたの招待を承認しました。コラボレーションを楽しんでください!",
|
||||
"invite_accepted_email_text": "{inviteeName}さんがあなたの招待を承認しました。コラボレーションをお楽しみください!",
|
||||
"invite_email_button_label": "組織に参加",
|
||||
"invite_email_heading": "こんにちは",
|
||||
"invite_email_text_par1": "あなたの同僚の",
|
||||
"invite_email_text_par2": "が、Formbricksへの参加をあなたに招待しました。招待を承認するには、以下のリンクをクリックしてください。",
|
||||
"invite_email_heading": "{inviteeName}さん",
|
||||
"invite_email_text": "同僚の{inviterName}さんがFormbricksへの参加を招待しています。招待を承認するには、以下のリンクをクリックしてください:",
|
||||
"invite_member_email_subject": "Formbricksでのコラボレーションに招待されました!",
|
||||
"new_email_verification_text": "新しいメールアドレスを認証するには、以下のボタンをクリックしてください。",
|
||||
"number_variable": "数値変数",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "新しいプロジェクトを追加するには、すべてのフィールドを記入してください。",
|
||||
"read": "読み取り",
|
||||
"read_write": "読み書き",
|
||||
"security_updates_description": "脆弱性が発見された際に通知を受け取るため、セキュリティメーリングリストに登録してください。",
|
||||
"security_updates_enroll": "今すぐ登録",
|
||||
"security_updates_enrolled": "登録済み",
|
||||
"security_updates_enrolled_description": "{email}でセキュリティアップデートを受信するよう登録されています。",
|
||||
"security_updates_enrolled_successfully": "セキュリティアップデートの登録が完了しました",
|
||||
"security_updates_enrolling": "登録中...",
|
||||
"security_updates_title": "セキュリティアップデート",
|
||||
"select_member": "メンバーを選択",
|
||||
"select_project": "プロジェクトを選択",
|
||||
"team_admin": "チーム管理者",
|
||||
|
||||
@@ -475,14 +475,12 @@
|
||||
"forgot_password_email_text": "U heeft een link aangevraagd om uw wachtwoord te wijzigen. Dit kunt u doen door op onderstaande link te klikken:",
|
||||
"hidden_field": "Verborgen veld",
|
||||
"imprint": "Afdruk",
|
||||
"invite_accepted_email_heading": "Hoi",
|
||||
"invite_accepted_email_heading": "Hé {inviterName}",
|
||||
"invite_accepted_email_subject": "Je hebt een nieuw organisatielid!",
|
||||
"invite_accepted_email_text_par1": "Laat het je gewoon weten",
|
||||
"invite_accepted_email_text_par2": "heeft uw uitnodiging geaccepteerd. Veel plezier met samenwerken!",
|
||||
"invite_accepted_email_text": "We wilden je even laten weten dat {inviteeName} je uitnodiging heeft geaccepteerd. Veel plezier met samenwerken!",
|
||||
"invite_email_button_label": "Sluit je aan bij de organisatie",
|
||||
"invite_email_heading": "Hoi",
|
||||
"invite_email_text_par1": "Jouw collega",
|
||||
"invite_email_text_par2": "nodigde je uit om je bij Formbricks aan te sluiten. Om de uitnodiging te accepteren, klikt u op de onderstaande link:",
|
||||
"invite_email_heading": "Hé {inviteeName}",
|
||||
"invite_email_text": "Je collega {inviterName} heeft je uitgenodigd om samen te werken bij Formbricks. Klik op onderstaande link om de uitnodiging te accepteren:",
|
||||
"invite_member_email_subject": "Je bent uitgenodigd om samen te werken aan Formbricks!",
|
||||
"new_email_verification_text": "Om uw nieuwe e-mailadres te verifiëren, klikt u op de onderstaande knop:",
|
||||
"number_variable": "Numerieke variabele",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "Vul alle velden in om een nieuw project toe te voegen.",
|
||||
"read": "Lezen",
|
||||
"read_write": "Lezen en schrijven",
|
||||
"security_updates_description": "Schrijf je in voor onze beveiligingsmailinglijst om op de hoogte te blijven als er kwetsbaarheden worden gevonden.",
|
||||
"security_updates_enroll": "Nu inschrijven",
|
||||
"security_updates_enrolled": "Ingeschreven",
|
||||
"security_updates_enrolled_description": "Je bent ingeschreven om beveiligingsupdates te ontvangen op {email}.",
|
||||
"security_updates_enrolled_successfully": "Succesvol ingeschreven voor beveiligingsupdates!",
|
||||
"security_updates_enrolling": "Bezig met inschrijven...",
|
||||
"security_updates_title": "Beveiligingsupdates",
|
||||
"select_member": "Selecteer lid",
|
||||
"select_project": "Selecteer project",
|
||||
"team_admin": "Teambeheerder",
|
||||
|
||||
@@ -474,15 +474,13 @@
|
||||
"forgot_password_email_subject": "Redefinir sua senha Formbricks",
|
||||
"forgot_password_email_text": "Você pediu um link pra trocar sua senha. Você pode fazer isso clicando no link abaixo:",
|
||||
"hidden_field": "Campo oculto",
|
||||
"imprint": "impressão",
|
||||
"invite_accepted_email_heading": "E aí",
|
||||
"imprint": "Impressum",
|
||||
"invite_accepted_email_heading": "Olá, {inviterName}",
|
||||
"invite_accepted_email_subject": "Você tem um novo membro na sua organização!",
|
||||
"invite_accepted_email_text_par1": "Só pra te avisar que",
|
||||
"invite_accepted_email_text_par2": "aceitou seu convite. Divirta-se colaborando!",
|
||||
"invite_accepted_email_text": "Só para você saber que {inviteeName} aceitou seu convite. Divirta-se colaborando!",
|
||||
"invite_email_button_label": "Entrar na organização",
|
||||
"invite_email_heading": "E aí",
|
||||
"invite_email_text_par1": "Seu colega",
|
||||
"invite_email_text_par2": "te convidou para se juntar a eles na Formbricks. Para aceitar o convite, por favor clique no link abaixo:",
|
||||
"invite_email_heading": "Olá, {inviteeName}",
|
||||
"invite_email_text": "Seu colega {inviterName} convidou você para se juntar a ele no Formbricks. Para aceitar o convite, clique no link abaixo:",
|
||||
"invite_member_email_subject": "Você foi convidado a colaborar no Formbricks!",
|
||||
"new_email_verification_text": "Para verificar seu novo endereço de e-mail, clique no botão abaixo:",
|
||||
"number_variable": "Variável numérica",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "Por favor, preencha todos os campos para adicionar um novo projeto.",
|
||||
"read": "Leitura",
|
||||
"read_write": "Leitura & Escrita",
|
||||
"security_updates_description": "Inscreva-se na nossa lista de e-mails de segurança para ser informado caso vulnerabilidades sejam encontradas.",
|
||||
"security_updates_enroll": "Inscrever-se agora",
|
||||
"security_updates_enrolled": "Inscrito",
|
||||
"security_updates_enrolled_description": "Você está inscrito para receber atualizações de segurança em {email}.",
|
||||
"security_updates_enrolled_successfully": "Inscrito com sucesso para atualizações de segurança!",
|
||||
"security_updates_enrolling": "Inscrevendo...",
|
||||
"security_updates_title": "Atualizações de segurança",
|
||||
"select_member": "Selecionar membro",
|
||||
"select_project": "Selecionar projeto",
|
||||
"team_admin": "Administrador da equipe",
|
||||
|
||||
@@ -475,14 +475,12 @@
|
||||
"forgot_password_email_text": "Solicitou um link para alterar a sua palavra-passe. Pode fazê-lo clicando no link abaixo:",
|
||||
"hidden_field": "Campo oculto",
|
||||
"imprint": "Impressão",
|
||||
"invite_accepted_email_heading": "Olá",
|
||||
"invite_accepted_email_heading": "Olá {inviterName}",
|
||||
"invite_accepted_email_subject": "Tem um novo membro na organização!",
|
||||
"invite_accepted_email_text_par1": "Só para te informar que",
|
||||
"invite_accepted_email_text_par2": "aceitou o seu convite. Divirta-se a colaborar!",
|
||||
"invite_accepted_email_text": "Só para informar que {inviteeName} aceitou o teu convite. Divirtam-se a colaborar!",
|
||||
"invite_email_button_label": "Junte-se à organização",
|
||||
"invite_email_heading": "Olá",
|
||||
"invite_email_text_par1": "O seu colega",
|
||||
"invite_email_text_par2": "convidou-o a juntar-se a eles no Formbricks. Para aceitar o convite, por favor clique no link abaixo:",
|
||||
"invite_email_heading": "Olá {inviteeName}",
|
||||
"invite_email_text": "O teu colega {inviterName} convidou-te para te juntares a ele no Formbricks. Para aceitar o convite, clica na ligação abaixo:",
|
||||
"invite_member_email_subject": "Está convidado a colaborar no Formbricks!",
|
||||
"new_email_verification_text": "Para verificar o seu novo endereço de email, por favor clique no botão abaixo:",
|
||||
"number_variable": "Variável numérica",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "Por favor, preencha todos os campos para adicionar um novo projeto.",
|
||||
"read": "Ler",
|
||||
"read_write": "Ler e Escrever",
|
||||
"security_updates_description": "Inscreva-se na nossa lista de correio de segurança para se manter informado caso sejam encontradas vulnerabilidades.",
|
||||
"security_updates_enroll": "Inscrever agora",
|
||||
"security_updates_enrolled": "Inscrito",
|
||||
"security_updates_enrolled_description": "Está inscrito para receber atualizações de segurança em {email}.",
|
||||
"security_updates_enrolled_successfully": "Inscrito com sucesso para atualizações de segurança!",
|
||||
"security_updates_enrolling": "A inscrever...",
|
||||
"security_updates_title": "Atualizações de segurança",
|
||||
"select_member": "Selecionar membro",
|
||||
"select_project": "Selecionar projeto",
|
||||
"team_admin": "Administrador da Equipa",
|
||||
|
||||
@@ -475,14 +475,12 @@
|
||||
"forgot_password_email_text": "Ați solicitat un link pentru a vă schimba parola. Puteți face acest lucru făcând clic pe linkul de mai jos:",
|
||||
"hidden_field": "Câmp ascuns",
|
||||
"imprint": "Amprentă",
|
||||
"invite_accepted_email_heading": "Salut",
|
||||
"invite_accepted_email_heading": "Salut, {inviterName}",
|
||||
"invite_accepted_email_subject": "Ai un nou membru în organizație!",
|
||||
"invite_accepted_email_text_par1": "Doar te anunț că",
|
||||
"invite_accepted_email_text_par2": "a acceptat invitația ta. Distracție plăcută colaborând!",
|
||||
"invite_accepted_email_text": "Vrem doar să te anunțăm că {inviteeName} a acceptat invitația ta. Spor la colaborare!",
|
||||
"invite_email_button_label": "Alătură-te organizației",
|
||||
"invite_email_heading": "Hei",
|
||||
"invite_email_text_par1": "Colegul tău",
|
||||
"invite_email_text_par2": "te-a invitat să li te alături la Formbricks. Pentru a accepta invitația, te rugăm să dai click pe linkul de mai jos:",
|
||||
"invite_email_heading": "Salut, {inviteeName}",
|
||||
"invite_email_text": "Colegul tău, {inviterName}, te-a invitat să i te alături pe Formbricks. Pentru a accepta invitația, te rugăm să dai click pe linkul de mai jos:",
|
||||
"invite_member_email_subject": "Ești invitat să colaborezi pe Formbricks!",
|
||||
"new_email_verification_text": "Pentru a verifica noua dumneavoastră adresă de email, vă rugăm să faceți clic pe butonul de mai jos:",
|
||||
"number_variable": "Variabilă numerică",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "Vă rugăm să completați toate câmpurile pentru a adăuga un proiect nou.",
|
||||
"read": "Citește",
|
||||
"read_write": "Citire & Scriere",
|
||||
"security_updates_description": "Înscrie-te la lista noastră de e-mailuri de securitate pentru a fi informat dacă sunt descoperite vulnerabilități.",
|
||||
"security_updates_enroll": "Înscrie-te acum",
|
||||
"security_updates_enrolled": "Înscris",
|
||||
"security_updates_enrolled_description": "Ești înscris pentru a primi actualizări de securitate la {email}.",
|
||||
"security_updates_enrolled_successfully": "Înscriere reușită pentru actualizările de securitate!",
|
||||
"security_updates_enrolling": "Se înscrie...",
|
||||
"security_updates_title": "Actualizări de securitate",
|
||||
"select_member": "Selectează membrul",
|
||||
"select_project": "Selectează proiectul",
|
||||
"team_admin": "Administrator Echipe",
|
||||
|
||||
2960
apps/web/locales/ru-RU.json
Normal file
2960
apps/web/locales/ru-RU.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -475,14 +475,12 @@
|
||||
"forgot_password_email_text": "Du har begärt en länk för att ändra ditt lösenord. Du kan göra detta genom att klicka på länken nedan:",
|
||||
"hidden_field": "Dolt fält",
|
||||
"imprint": "Impressum",
|
||||
"invite_accepted_email_heading": "Hej",
|
||||
"invite_accepted_email_heading": "Hej {inviterName}",
|
||||
"invite_accepted_email_subject": "Du har fått en ny organisationsmedlem!",
|
||||
"invite_accepted_email_text_par1": "Vi vill bara meddela dig att",
|
||||
"invite_accepted_email_text_par2": "accepterade din inbjudan. Ha kul med samarbetet!",
|
||||
"invite_accepted_email_text": "Vi vill bara meddela att {inviteeName} har accepterat din inbjudan. Ha det så kul med samarbetet!",
|
||||
"invite_email_button_label": "Gå med i organisation",
|
||||
"invite_email_heading": "Hej",
|
||||
"invite_email_text_par1": "Din kollega",
|
||||
"invite_email_text_par2": "bjöd in dig att gå med dem på Formbricks. För att acceptera inbjudan, vänligen klicka på länken nedan:",
|
||||
"invite_email_heading": "Hej {inviteeName}",
|
||||
"invite_email_text": "Din kollega {inviterName} har bjudit in dig att gå med dem på Formbricks. För att acceptera inbjudan, klicka på länken nedan:",
|
||||
"invite_member_email_subject": "Du är inbjuden att samarbeta på Formbricks!",
|
||||
"new_email_verification_text": "För att verifiera din nya e-postadress, vänligen klicka på knappen nedan:",
|
||||
"number_variable": "Nummervariabel",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "Vänligen fyll i alla fält för att lägga till ett nytt projekt.",
|
||||
"read": "Läs",
|
||||
"read_write": "Läs och skriv",
|
||||
"security_updates_description": "Anmäl dig till vår säkerhetsmejllista för att hålla dig informerad om sårbarheter upptäcks.",
|
||||
"security_updates_enroll": "Anmäl dig nu",
|
||||
"security_updates_enrolled": "Anmäld",
|
||||
"security_updates_enrolled_description": "Du är anmäld för att ta emot säkerhetsuppdateringar på {email}.",
|
||||
"security_updates_enrolled_successfully": "Du har anmälts för säkerhetsuppdateringar!",
|
||||
"security_updates_enrolling": "Anmäler...",
|
||||
"security_updates_title": "Säkerhetsuppdateringar",
|
||||
"select_member": "Välj medlem",
|
||||
"select_project": "Välj projekt",
|
||||
"team_admin": "Teamadministratör",
|
||||
|
||||
@@ -475,14 +475,12 @@
|
||||
"forgot_password_email_text": "您 已 请求 一个 链接 来 更改 您的 密码。 您 可以 点击 下方 链接 完成 这个 操作:",
|
||||
"hidden_field": "隐藏字段",
|
||||
"imprint": "印记",
|
||||
"invite_accepted_email_heading": "嗨",
|
||||
"invite_accepted_email_heading": "你好,{inviterName}",
|
||||
"invite_accepted_email_subject": "你 有 一个 新 成员 进入 组织 了!",
|
||||
"invite_accepted_email_text_par1": "只是 告诉 你",
|
||||
"invite_accepted_email_text_par2": "接受了 你的 邀请。 合作 愉快!",
|
||||
"invite_accepted_email_text": "{inviteeName} 已接受了你的邀请。祝你们合作愉快!",
|
||||
"invite_email_button_label": "加入 组织",
|
||||
"invite_email_heading": "嗨",
|
||||
"invite_email_text_par1": "您的 同事",
|
||||
"invite_email_text_par2": "邀请您加入他们在 Formbricks 。要接受邀请,请点击下面的链接:",
|
||||
"invite_email_heading": "你好,{inviteeName}",
|
||||
"invite_email_text": "你的同事 {inviterName} 邀请你加入 Formbricks。要接受邀请,请点击下方链接:",
|
||||
"invite_member_email_subject": "您 被 邀请 来 协作 于 Formbricks!",
|
||||
"new_email_verification_text": "要 验证 您 的 新 邮箱 地址 ,请 点击 下方 的 按钮 :",
|
||||
"number_variable": "数字变量",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "请 填写 所有 字段 以 添加 新 项目。",
|
||||
"read": "阅读",
|
||||
"read_write": "读 & 写",
|
||||
"security_updates_description": "加入我们的安全邮件列表,及时了解发现的安全漏洞信息。",
|
||||
"security_updates_enroll": "立即加入",
|
||||
"security_updates_enrolled": "已加入",
|
||||
"security_updates_enrolled_description": "您已加入安全更新通知,相关信息将发送至 {email}。",
|
||||
"security_updates_enrolled_successfully": "已成功加入安全更新通知!",
|
||||
"security_updates_enrolling": "正在加入...",
|
||||
"security_updates_title": "安全更新",
|
||||
"select_member": "选择成员",
|
||||
"select_project": "选择项目",
|
||||
"team_admin": "团队管理员",
|
||||
|
||||
@@ -475,14 +475,12 @@
|
||||
"forgot_password_email_text": "您已請求變更密碼的連結。您可以點擊以下連結來執行此操作:",
|
||||
"hidden_field": "隱藏欄位",
|
||||
"imprint": "版本訊息",
|
||||
"invite_accepted_email_heading": "嗨",
|
||||
"invite_accepted_email_heading": "嗨,{inviterName}",
|
||||
"invite_accepted_email_subject": "您有一位新的組織成員!",
|
||||
"invite_accepted_email_text_par1": "通知您,",
|
||||
"invite_accepted_email_text_par2": "接受了您的邀請。合作愉快!",
|
||||
"invite_accepted_email_text": "通知你,{inviteeName} 已經接受了你的邀請。祝你們合作愉快!",
|
||||
"invite_email_button_label": "加入組織",
|
||||
"invite_email_heading": "嗨",
|
||||
"invite_email_text_par1": "您的同事",
|
||||
"invite_email_text_par2": "邀請您加入 Formbricks。若要接受邀請,請點擊以下連結:",
|
||||
"invite_email_heading": "嗨,{inviteeName}",
|
||||
"invite_email_text": "你的同事 {inviterName} 邀請你加入他們在 Formbricks。請點擊下方連結以接受邀請:",
|
||||
"invite_member_email_subject": "您被邀請協作 Formbricks!",
|
||||
"new_email_verification_text": "要驗證您的新電子郵件地址,請點擊下面的按鈕:",
|
||||
"number_variable": "數字變數",
|
||||
@@ -1182,6 +1180,13 @@
|
||||
"please_fill_all_project_fields": "請填寫所有欄位以新增新專案。",
|
||||
"read": "讀取",
|
||||
"read_write": "讀取和寫入",
|
||||
"security_updates_description": "加入我們的安全郵件名單,隨時掌握漏洞相關資訊。",
|
||||
"security_updates_enroll": "立即加入",
|
||||
"security_updates_enrolled": "已加入",
|
||||
"security_updates_enrolled_description": "您已加入安全更新通知,將會寄送至 {email}。",
|
||||
"security_updates_enrolled_successfully": "已成功加入安全更新通知!",
|
||||
"security_updates_enrolling": "正在加入...",
|
||||
"security_updates_title": "安全更新",
|
||||
"select_member": "選擇成員",
|
||||
"select_project": "選擇專案",
|
||||
"team_admin": "團隊管理員",
|
||||
|
||||
@@ -183,7 +183,7 @@ export async function PreviewEmailTemplate({
|
||||
{ctaElement.buttonExternal && ctaElement.ctaButtonLabel && ctaElement.buttonUrl && (
|
||||
<Container className="mx-0 mt-4 flex max-w-none items-center justify-end">
|
||||
<EmailButton
|
||||
className="text-question-color flex items-center rounded-md border-0 bg-transparent px-3 py-3 text-base font-medium leading-4 no-underline shadow-none"
|
||||
className="text-question-color flex items-center rounded-md border-0 bg-transparent px-3 py-3 text-base leading-4 font-medium no-underline shadow-none"
|
||||
href={ctaElement.buttonUrl}>
|
||||
<Text className="inline">
|
||||
{getLocalizedValue(ctaElement.ctaButtonLabel, defaultLanguageCode)}{" "}
|
||||
@@ -306,13 +306,13 @@ export async function PreviewEmailTemplate({
|
||||
{firstQuestion.choices.map((choice) =>
|
||||
firstQuestion.allowMulti ? (
|
||||
<Img
|
||||
className="rounded-custom mb-3 mr-3 inline-block h-[150px] w-[250px]"
|
||||
className="rounded-custom mr-3 mb-3 inline-block h-[150px] w-[250px]"
|
||||
key={choice.id}
|
||||
src={choice.imageUrl}
|
||||
/>
|
||||
) : (
|
||||
<Link
|
||||
className="rounded-custom mb-3 mr-3 inline-block h-[150px] w-[250px]"
|
||||
className="rounded-custom mr-3 mb-3 inline-block h-[150px] w-[250px]"
|
||||
href={`${urlWithPrefilling}${firstQuestion.id}=${choice.id}`}
|
||||
key={choice.id}
|
||||
target="_blank">
|
||||
@@ -360,11 +360,11 @@ export async function PreviewEmailTemplate({
|
||||
<Container className="mx-0">
|
||||
<Section className="w-full table-auto">
|
||||
<Row>
|
||||
<Column className="w-40 break-words px-4 py-2" />
|
||||
<Column className="w-40 px-4 py-2 break-words" />
|
||||
{firstQuestion.columns.map((column) => {
|
||||
return (
|
||||
<Column
|
||||
className="text-question-color max-w-40 break-words px-4 py-2 text-center"
|
||||
className="text-question-color max-w-40 px-4 py-2 text-center break-words"
|
||||
key={column.id}>
|
||||
{getLocalizedValue(column.label, "default")}
|
||||
</Column>
|
||||
@@ -376,7 +376,7 @@ export async function PreviewEmailTemplate({
|
||||
<Row
|
||||
className={`${rowIndex % 2 === 0 ? "bg-input-color" : ""} rounded-custom`}
|
||||
key={row.id}>
|
||||
<Column className="w-40 break-words px-4 py-2">
|
||||
<Column className="w-40 px-4 py-2 break-words">
|
||||
{getLocalizedValue(row.label, "default")}
|
||||
</Column>
|
||||
{firstQuestion.columns.map((column) => {
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
getOrganizationOwnerCount,
|
||||
} from "@/modules/organization/settings/teams/lib/membership";
|
||||
import { deleteInvite, getInvite, inviteUser, resendInvite } from "./lib/invite";
|
||||
import { enrollInSecurityUpdates } from "./lib/security-updates";
|
||||
|
||||
const ZDeleteInviteAction = z.object({
|
||||
inviteId: ZUuid,
|
||||
@@ -387,3 +388,39 @@ export const leaveOrganizationAction = authenticatedActionClient.schema(ZLeaveOr
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
const ZEnrollSecurityUpdatesAction = z.object({
|
||||
organizationId: ZId,
|
||||
});
|
||||
|
||||
export const enrollSecurityUpdatesAction = authenticatedActionClient
|
||||
.schema(ZEnrollSecurityUpdatesAction)
|
||||
.action(async ({ ctx, parsedInput }) => {
|
||||
// Ensure this is only called for self-hosted instances
|
||||
if (IS_FORMBRICKS_CLOUD) {
|
||||
throw new OperationNotAllowedError(
|
||||
"Security updates enrollment is only available for self-hosted instances"
|
||||
);
|
||||
}
|
||||
|
||||
// Only owners can enroll in security updates
|
||||
await checkAuthorizationUpdated({
|
||||
userId: ctx.user.id,
|
||||
organizationId: parsedInput.organizationId,
|
||||
access: [
|
||||
{
|
||||
type: "organization",
|
||||
roles: ["owner"],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Enroll with the current user's email
|
||||
const result = await enrollInSecurityUpdates(ctx.user.email);
|
||||
|
||||
if (!result.success) {
|
||||
throw new Error("Failed to enroll in security updates");
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
});
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
"use client";
|
||||
|
||||
import { ShieldCheckIcon } from "lucide-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { cn } from "@/lib/cn";
|
||||
import { getFormattedErrorMessage } from "@/lib/utils/helper";
|
||||
import { enrollSecurityUpdatesAction } from "@/modules/organization/settings/teams/actions";
|
||||
import { TSecurityUpdatesStatus } from "@/modules/organization/settings/teams/lib/security-updates";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { H4, P } from "@/modules/ui/components/typography";
|
||||
|
||||
interface SecurityUpdatesCardProps {
|
||||
organizationId: string;
|
||||
userEmail: string;
|
||||
securityUpdatesStatus: TSecurityUpdatesStatus;
|
||||
}
|
||||
|
||||
export const SecurityUpdatesCard = ({
|
||||
organizationId,
|
||||
userEmail,
|
||||
securityUpdatesStatus,
|
||||
}: SecurityUpdatesCardProps) => {
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
const [isEnrolling, setIsEnrolling] = useState(false);
|
||||
|
||||
const handleEnroll = async () => {
|
||||
setIsEnrolling(true);
|
||||
try {
|
||||
const result = await enrollSecurityUpdatesAction({ organizationId });
|
||||
|
||||
if (result?.data?.success) {
|
||||
toast.success(t("environments.settings.teams.security_updates_enrolled_successfully"));
|
||||
router.refresh();
|
||||
} else {
|
||||
const errorMessage = getFormattedErrorMessage(result);
|
||||
toast.error(errorMessage);
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error(t("common.something_went_wrong_please_try_again"));
|
||||
console.error(error);
|
||||
} finally {
|
||||
setIsEnrolling(false);
|
||||
}
|
||||
};
|
||||
|
||||
const isEnrolled = securityUpdatesStatus.enrolled;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"relative my-4 w-full max-w-4xl rounded-xl border bg-white shadow-sm",
|
||||
isEnrolled ? "border-green-200 bg-green-50" : "border-slate-200"
|
||||
)}>
|
||||
<div className="flex items-start justify-between p-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<div
|
||||
className={cn(
|
||||
"flex h-10 w-10 items-center justify-center rounded-full",
|
||||
isEnrolled ? "bg-green-100" : "bg-slate-100"
|
||||
)}>
|
||||
<ShieldCheckIcon className={cn("h-5 w-5", isEnrolled ? "text-green-600" : "text-slate-600")} />
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<H4 className="font-medium tracking-normal">
|
||||
{t("environments.settings.teams.security_updates_title")}
|
||||
</H4>
|
||||
<P className="!mt-0 text-sm text-slate-500">
|
||||
{isEnrolled
|
||||
? t("environments.settings.teams.security_updates_enrolled_description", {
|
||||
email: securityUpdatesStatus.email || userEmail,
|
||||
})
|
||||
: t("environments.settings.teams.security_updates_description")}
|
||||
</P>
|
||||
</div>
|
||||
</div>
|
||||
{!isEnrolled && (
|
||||
<Button onClick={handleEnroll} disabled={isEnrolling} className="shrink-0">
|
||||
{isEnrolling
|
||||
? t("environments.settings.teams.security_updates_enrolling")
|
||||
: t("environments.settings.teams.security_updates_enroll")}
|
||||
</Button>
|
||||
)}
|
||||
{isEnrolled && (
|
||||
<div className="flex items-center gap-2 rounded-full bg-green-100 px-3 py-1">
|
||||
<div className="h-2 w-2 rounded-full bg-green-500" />
|
||||
<span className="text-sm font-medium text-green-700">
|
||||
{t("environments.settings.teams.security_updates_enrolled")}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
"use server";
|
||||
|
||||
import { getInstanceId } from "@/lib/instance";
|
||||
|
||||
export type TSecurityUpdatesStatus = {
|
||||
enrolled: boolean;
|
||||
email?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the current instance is enrolled in security updates.
|
||||
*
|
||||
* TODO: Replace with actual EE server call
|
||||
* GET /security-updates/status?instanceId=xxx
|
||||
*
|
||||
* @returns The enrollment status and email if enrolled
|
||||
*/
|
||||
export const getSecurityUpdatesStatus = async (): Promise<TSecurityUpdatesStatus> => {
|
||||
const instanceId = await getInstanceId();
|
||||
|
||||
if (!instanceId) {
|
||||
return { enrolled: false };
|
||||
}
|
||||
|
||||
// TODO: Replace with actual EE server call
|
||||
// const response = await fetch(`${EE_SERVER_URL}/instances/${instanceId}/security-updates`);
|
||||
// if (!response.ok) {
|
||||
// return { enrolled: false };
|
||||
// }
|
||||
// return await response.json();
|
||||
|
||||
// Mock: Always return not enrolled for now
|
||||
return { enrolled: false };
|
||||
};
|
||||
|
||||
/**
|
||||
* Enrolls the current instance in security updates.
|
||||
*
|
||||
* TODO: Replace with actual EE server call
|
||||
* POST /security-updates/enroll { instanceId, email }
|
||||
*
|
||||
* @param email - The email address to receive security updates
|
||||
* @returns Success status
|
||||
*/
|
||||
export const enrollInSecurityUpdates = async (email: string): Promise<{ success: boolean }> => {
|
||||
const instanceId = await getInstanceId();
|
||||
|
||||
if (!instanceId) {
|
||||
throw new Error("Instance ID not found");
|
||||
}
|
||||
|
||||
// TODO: Replace with actual EE server call
|
||||
// const response = await fetch(`${EE_SERVER_URL}/instances/${instanceId}/security-updates`, {
|
||||
// method: "POST",
|
||||
// headers: { "Content-Type": "application/json" },
|
||||
// body: JSON.stringify({ instanceId, email }),
|
||||
// });
|
||||
//
|
||||
// if (!response.ok) {
|
||||
// throw new Error("Failed to enroll in security updates");
|
||||
// }
|
||||
//
|
||||
// return await response.json();
|
||||
|
||||
// Mock: Always succeed for now
|
||||
console.log(`[Mock] Enrolling instance ${instanceId} with email ${email}`);
|
||||
return { success: true };
|
||||
};
|
||||
@@ -1,20 +1,25 @@
|
||||
import { OrganizationSettingsNavbar } from "@/app/(app)/environments/[environmentId]/settings/(organization)/components/OrganizationSettingsNavbar";
|
||||
import { IS_FORMBRICKS_CLOUD, USER_MANAGEMENT_MINIMUM_ROLE } from "@/lib/constants";
|
||||
import { getUserManagementAccess } from "@/lib/membership/utils";
|
||||
import { getUser } from "@/lib/user/service";
|
||||
import { getTranslate } from "@/lingodotdev/server";
|
||||
import { getAccessControlPermission } from "@/modules/ee/license-check/lib/utils";
|
||||
import { getTeamsWhereUserIsAdmin } from "@/modules/ee/teams/lib/roles";
|
||||
import { TeamsView } from "@/modules/ee/teams/team-list/components/teams-view";
|
||||
import { getEnvironmentAuth } from "@/modules/environments/lib/utils";
|
||||
import { MembersView } from "@/modules/organization/settings/teams/components/members-view";
|
||||
import { SecurityUpdatesCard } from "@/modules/organization/settings/teams/components/security-updates-card";
|
||||
import { getSecurityUpdatesStatus } from "@/modules/organization/settings/teams/lib/security-updates";
|
||||
import { PageContentWrapper } from "@/modules/ui/components/page-content-wrapper";
|
||||
import { PageHeader } from "@/modules/ui/components/page-header";
|
||||
|
||||
export const TeamsPage = async (props) => {
|
||||
export const TeamsPage = async (props: { params: Promise<{ environmentId: string }> }) => {
|
||||
const params = await props.params;
|
||||
const t = await getTranslate();
|
||||
|
||||
const { session, currentUserMembership, organization } = await getEnvironmentAuth(params.environmentId);
|
||||
const { session, currentUserMembership, organization, isOwner } = await getEnvironmentAuth(
|
||||
params.environmentId
|
||||
);
|
||||
|
||||
const isAccessControlAllowed = await getAccessControlPermission(organization.billing.plan);
|
||||
|
||||
@@ -32,6 +37,12 @@ export const TeamsPage = async (props) => {
|
||||
const hasUserManagementAccess =
|
||||
hasStandardUserManagementAccess || (isAccessControlAllowed && isTeamAdminUser);
|
||||
|
||||
// Fetch security updates status for self-hosted instances only (owners only)
|
||||
const shouldShowSecurityUpdates = !IS_FORMBRICKS_CLOUD && isOwner;
|
||||
const [securityUpdatesStatus, user] = shouldShowSecurityUpdates
|
||||
? await Promise.all([getSecurityUpdatesStatus(), getUser(session.user.id)])
|
||||
: [null, null];
|
||||
|
||||
return (
|
||||
<PageContentWrapper>
|
||||
<PageHeader pageTitle={t("environments.settings.general.organization_settings")}>
|
||||
@@ -42,6 +53,15 @@ export const TeamsPage = async (props) => {
|
||||
activeId="teams"
|
||||
/>
|
||||
</PageHeader>
|
||||
|
||||
{securityUpdatesStatus && user && (
|
||||
<SecurityUpdatesCard
|
||||
organizationId={organization.id}
|
||||
userEmail={user.email}
|
||||
securityUpdatesStatus={securityUpdatesStatus}
|
||||
/>
|
||||
)}
|
||||
|
||||
<MembersView
|
||||
membershipRole={currentUserMembership?.role}
|
||||
organization={organization}
|
||||
|
||||
@@ -442,7 +442,4 @@ const sentryOptions = {
|
||||
// Runtime Sentry reporting still depends on DSN being set via environment variables
|
||||
const exportConfig = process.env.SENTRY_AUTH_TOKEN ? withSentryConfig(nextConfig, sentryOptions) : nextConfig;
|
||||
|
||||
console.log("BASE PATH", nextConfig.basePath);
|
||||
|
||||
|
||||
export default exportConfig;
|
||||
|
||||
@@ -221,6 +221,7 @@ vi.mock("@/lib/constants", () => ({
|
||||
"zh-Hans-CN",
|
||||
"es-ES",
|
||||
"sv-SE",
|
||||
"ru-RU",
|
||||
],
|
||||
DEFAULT_LOCALE: "en-US",
|
||||
BREVO_API_KEY: "mock-brevo-api-key",
|
||||
|
||||
@@ -21,13 +21,8 @@ export function InviteAcceptedEmail({
|
||||
return (
|
||||
<EmailTemplate t={t} {...legalProps}>
|
||||
<Container>
|
||||
<Heading>
|
||||
{t("emails.invite_accepted_email_heading", { inviterName })} {inviterName}
|
||||
</Heading>
|
||||
<Text className="text-sm">
|
||||
{t("emails.invite_accepted_email_text_par1", { inviteeName })} {inviteeName}{" "}
|
||||
{t("emails.invite_accepted_email_text_par2")}
|
||||
</Text>
|
||||
<Heading>{t("emails.invite_accepted_email_heading", { inviterName })}</Heading>
|
||||
<Text className="text-sm">{t("emails.invite_accepted_email_text", { inviteeName })}</Text>
|
||||
<EmailFooter t={t} />
|
||||
</Container>
|
||||
</EmailTemplate>
|
||||
|
||||
@@ -24,13 +24,8 @@ export function InviteEmail({
|
||||
return (
|
||||
<EmailTemplate t={t} {...legalProps}>
|
||||
<Container>
|
||||
<Heading>
|
||||
{t("emails.invite_email_heading", { inviteeName })} {inviteeName}
|
||||
</Heading>
|
||||
<Text className="text-sm">
|
||||
{t("emails.invite_email_text_par1", { inviterName })} {inviterName}{" "}
|
||||
{t("emails.invite_email_text_par2")}
|
||||
</Text>
|
||||
<Heading>{t("emails.invite_email_heading", { inviteeName })}</Heading>
|
||||
<Text className="text-sm">{t("emails.invite_email_text", { inviterName })}</Text>
|
||||
<EmailButton href={verifyLink} label={t("emails.invite_email_button_label")} />
|
||||
<EmailFooter t={t} />
|
||||
</Container>
|
||||
|
||||
@@ -10,11 +10,11 @@ interface ElementHeaderProps {
|
||||
export function ElementHeader({ headline, subheader, className }: ElementHeaderProps): React.JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<Container className={cn("text-question-color m-0 block text-base font-semibold leading-6", className)}>
|
||||
<Container className={cn("text-question-color m-0 block text-base leading-6 font-semibold", className)}>
|
||||
<div dangerouslySetInnerHTML={{ __html: headline }} />
|
||||
</Container>
|
||||
{subheader && (
|
||||
<Container className="text-question-color m-0 mt-2 block p-0 text-sm font-normal leading-6">
|
||||
<Container className="text-question-color m-0 mt-2 block p-0 text-sm leading-6 font-normal">
|
||||
<div dangerouslySetInnerHTML={{ __html: subheader }} />
|
||||
</Container>
|
||||
)}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -145,6 +145,7 @@ interface UploadAreaProps {
|
||||
onDragOver: (e: React.DragEvent<HTMLLabelElement>) => void;
|
||||
onDrop: (e: React.DragEvent<HTMLLabelElement>) => void;
|
||||
showUploader: boolean;
|
||||
uploadedFiles: UploadedFile[];
|
||||
}
|
||||
|
||||
function UploadArea({
|
||||
@@ -160,6 +161,7 @@ function UploadArea({
|
||||
onDragOver,
|
||||
onDrop,
|
||||
showUploader,
|
||||
uploadedFiles,
|
||||
}: Readonly<UploadAreaProps>): React.JSX.Element | null {
|
||||
if (!showUploader) {
|
||||
return null;
|
||||
@@ -201,7 +203,7 @@ function UploadArea({
|
||||
accept={acceptAttribute}
|
||||
onChange={onFileChange}
|
||||
disabled={disabled}
|
||||
required={required}
|
||||
required={uploadedFiles.length > 0 ? false : required}
|
||||
dir={dir}
|
||||
aria-label="File upload"
|
||||
aria-describedby={`${inputId}-label`}
|
||||
@@ -323,6 +325,7 @@ function FileUpload({
|
||||
onDragOver={handleDragOver}
|
||||
onDrop={handleDrop}
|
||||
showUploader={showUploader}
|
||||
uploadedFiles={uploadedFiles}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,6 +13,7 @@ export const ZUserLocale = z.enum([
|
||||
"zh-Hans-CN",
|
||||
"es-ES",
|
||||
"sv-SE",
|
||||
"ru-RU",
|
||||
]);
|
||||
|
||||
export type TUserLocale = z.infer<typeof ZUserLocale>;
|
||||
|
||||
Reference in New Issue
Block a user