mirror of
https://github.com/formbricks/formbricks.git
synced 2026-03-09 19:30:04 -05:00
Compare commits
5 Commits
pricing-re
...
fix-zod-er
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31373eafbc | ||
|
|
1da92addd2 | ||
|
|
1e4aa5f54b | ||
|
|
96f173c3b1 | ||
|
|
9c9e55fba6 |
@@ -179,7 +179,7 @@
|
||||
"count_contacts": "{count, plural, one {{count} partner} other {{count} partner}}",
|
||||
"count_members": "{count, plural, one {{count} tag} other {{count} tag}}",
|
||||
"count_responses": "{count, plural, one {{count} válasz} other {{count} válasz}}",
|
||||
"count_selections": "{count, plural, one {{count} kijelölés} other {{count} kijelölés}}",
|
||||
"count_selections": "{count, plural, one {{count} kiválasztás} other {{count} kiválasztás}}",
|
||||
"create_new_organization": "Új szervezet létrehozása",
|
||||
"create_segment": "Szakasz létrehozása",
|
||||
"create_survey": "Kérdőív létrehozása",
|
||||
@@ -190,7 +190,7 @@
|
||||
"customer_success": "Ügyfélsiker",
|
||||
"dark_overlay": "Sötét rávetítés",
|
||||
"date": "Dátum",
|
||||
"days": "napok",
|
||||
"days": "nap",
|
||||
"default": "Alapértelmezett",
|
||||
"delete": "Törlés",
|
||||
"delete_what": "{deleteWhat} törlése",
|
||||
@@ -223,7 +223,7 @@
|
||||
"error": "Hiba",
|
||||
"error_component_description": "Ez az erőforrás nem létezik, vagy nem rendelkezik a hozzáféréshez szükséges jogosultságokkal.",
|
||||
"error_component_title": "Hiba az erőforrások betöltésekor",
|
||||
"error_loading_data": "Hiba az adatok betöltése során",
|
||||
"error_loading_data": "Hiba az adatok betöltésekor",
|
||||
"error_rate_limit_description": "A kérések legnagyobb száma elérve. Próbálja meg később újra.",
|
||||
"error_rate_limit_title": "A sebességkorlát elérve",
|
||||
"expand_rows": "Sorok kinyitása",
|
||||
@@ -245,11 +245,11 @@
|
||||
"hidden_field": "Rejtett mező",
|
||||
"hidden_fields": "Rejtett mezők",
|
||||
"hide_column": "Oszlop elrejtése",
|
||||
"id": "ID",
|
||||
"id": "Azonosító",
|
||||
"image": "Kép",
|
||||
"images": "Képek",
|
||||
"import": "Importálás",
|
||||
"impressions": "Benyomások",
|
||||
"impressions": "Megtekintések",
|
||||
"imprint": "Impresszum",
|
||||
"in_progress": "Folyamatban",
|
||||
"inactive_surveys": "Inaktív kérdőívek",
|
||||
@@ -268,9 +268,9 @@
|
||||
"license_expired": "A licenc lejárt",
|
||||
"light_overlay": "Világos rávetítés",
|
||||
"limits_reached": "Korlátok elérve",
|
||||
"link": "Összekapcsolás",
|
||||
"link_survey": "Kérdőív összekapcsolása",
|
||||
"link_surveys": "Kérdőívek összekapcsolása",
|
||||
"link": "Hivatkozás",
|
||||
"link_survey": "Hivatkozás-kérdőív",
|
||||
"link_surveys": "Hivatkozás-kérdőívek",
|
||||
"load_more": "Továbbiak betöltése",
|
||||
"loading": "Betöltés",
|
||||
"logo": "Logó",
|
||||
@@ -285,7 +285,7 @@
|
||||
"mobile_overlay_app_works_best_on_desktop": "A Formbricks nagyobb képernyőn működik a legjobban. A kérdőívek kezeléséhez vagy összeállításához váltson másik eszközre.",
|
||||
"mobile_overlay_surveys_look_good": "Ne aggódjon – a kérdőívei minden eszközön és képernyőméretnél remekül néznek ki!",
|
||||
"mobile_overlay_title": "Hoppá, apró képernyő észlelve!",
|
||||
"months": "hónapok",
|
||||
"months": "hónap",
|
||||
"move_down": "Mozgatás le",
|
||||
"move_up": "Mozgatás fel",
|
||||
"multiple_languages": "Több nyelv",
|
||||
@@ -323,7 +323,7 @@
|
||||
"organization_settings": "Szervezet beállításai",
|
||||
"organization_teams_not_found": "A szervezeti csapatok nem találhatók",
|
||||
"other": "Egyéb",
|
||||
"others": "Egyebek",
|
||||
"others": "Mások",
|
||||
"overlay_color": "Rávetítés színe",
|
||||
"overview": "Áttekintés",
|
||||
"password": "Jelszó",
|
||||
@@ -461,7 +461,7 @@
|
||||
"website_and_app_connection": "Webhely és alkalmazáskapcsolódás",
|
||||
"website_app_survey": "Webhely és alkalmazás-kérdőív",
|
||||
"website_survey": "Webhely kérdőív",
|
||||
"weeks": "hetek",
|
||||
"weeks": "hét",
|
||||
"welcome_card": "Üdvözlő kártya",
|
||||
"workflows": "Munkafolyamatok",
|
||||
"workspace_configuration": "Munkaterület beállítása",
|
||||
@@ -473,7 +473,7 @@
|
||||
"workspace_not_found": "A munkaterület nem található",
|
||||
"workspace_permission_not_found": "A munkaterület-jogosultság nem található",
|
||||
"workspaces": "Munkaterületek",
|
||||
"years": "évek",
|
||||
"years": "év",
|
||||
"you": "Ön",
|
||||
"you_are_downgraded_to_the_community_edition": "Visszaváltott a közösségi kiadásra.",
|
||||
"you_are_not_authorized_to_perform_this_action": "Nincs felhatalmazva ennek a műveletnek a végrehajtásához.",
|
||||
@@ -645,12 +645,12 @@
|
||||
"attribute_updated_successfully": "Az attribútum sikeresen frissítve",
|
||||
"attribute_value": "Érték",
|
||||
"attribute_value_placeholder": "Attribútum értéke",
|
||||
"attributes_msg_attribute_limit_exceeded": "Nem sikerült létrehozni {count} új attribútumot, mivel az meghaladná a maximális {limit} attribútumosztály-korlátot. A meglévő attribútumok sikeresen frissítve lettek.",
|
||||
"attributes_msg_attribute_type_validation_error": "{error} (a(z) '{key}' attribútum adattípusa: {dataType})",
|
||||
"attributes_msg_email_already_exists": "Az e-mail cím már létezik ebben a környezetben, és nem lett frissítve.",
|
||||
"attributes_msg_email_or_userid_required": "E-mail cím vagy felhasználói azonosító megadása kötelező. A meglévő értékek megmaradtak.",
|
||||
"attributes_msg_new_attribute_created": "Új '{key}' attribútum létrehozva '{dataType}' típussal",
|
||||
"attributes_msg_userid_already_exists": "A felhasználói azonosító már létezik ebben a környezetben, és nem lett frissítve.",
|
||||
"attributes_msg_attribute_limit_exceeded": "Nem sikerült létrehozni {count} új attribútumot, mivel túllépte volna a(z) {limit} attribútumosztályból álló legnagyobb korlátot. A meglévő attribútumok sikeresen frissítve lettek.",
|
||||
"attributes_msg_attribute_type_validation_error": "{error} (a(z) “{key}” attribútum a következő adattípussal rendelkezik: {dataType})",
|
||||
"attributes_msg_email_already_exists": "Az e-mail-cím már létezik ennél a környezetnél, és nem lett frissítve.",
|
||||
"attributes_msg_email_or_userid_required": "Vagy e-mail-cím, vagy felhasználó-azonosító szükséges. A meglévő értékek megmaradtak.",
|
||||
"attributes_msg_new_attribute_created": "Az új „{dataType}” típusú „{key}” attribútum létrehozva",
|
||||
"attributes_msg_userid_already_exists": "A felhasználó-azonosító már létezik ennél a környezetnél, és nem lett frissítve.",
|
||||
"contact_deleted_successfully": "A partner sikeresen törölve",
|
||||
"contact_not_found": "Nem található ilyen partner",
|
||||
"contacts_table_refresh": "Partnerek frissítése",
|
||||
@@ -660,9 +660,9 @@
|
||||
"create_new_attribute_description": "Új attribútum létrehozása szakaszolási célokhoz.",
|
||||
"custom_attributes": "Egyéni attribútumok",
|
||||
"data_type": "Adattípus",
|
||||
"data_type_cannot_be_changed": "Az adattípus létrehozás után nem módosítható",
|
||||
"data_type_description": "Válaszd ki, hogyan legyen tárolva és szűrve ez az attribútum",
|
||||
"date_value_required": "Dátum érték megadása kötelező. Használd a törlés gombot az attribútum eltávolításához, ha nem szeretnél dátumot megadni.",
|
||||
"data_type_cannot_be_changed": "Az adattípust nem lehet megváltoztatni a létrehozás után",
|
||||
"data_type_description": "Annak kiválasztása, hogy ezt az attribútumot hogyan kell tárolni és szűrni",
|
||||
"date_value_required": "Dátumérték szükséges. Használja a törlés gombot az attribútum eltávolításához, ha nem szeretne dátumot beállítani.",
|
||||
"delete_attribute_confirmation": "{value, plural, one {Ez törölni fogja a kiválasztott attribútumot. Az ehhez az attribútumhoz hozzárendelt összes partneradat el fog veszni.} other {Ez törölni fogja a kiválasztott attribútumokat. Az ezekhez az attribútumokhoz hozzárendelt összes partneradat el fog veszni.}}",
|
||||
"delete_contact_confirmation": "Ez törölni fogja az ehhez a partnerhez tartozó összes kérdőívválaszt és partnerattribútumot. A partner adatain alapuló bármilyen célzás és személyre szabás el fog veszni.",
|
||||
"delete_contact_confirmation_with_quotas": "{value, plural, one {Ez törölni fogja az ehhez a partnerhez tartozó összes kérdőívválaszt és partnerattribútumot. A partner adatain alapuló bármilyen célzás és személyre szabás el fog veszni. Ha ez a partner olyan válaszokkal rendelkezik, amelyek a kérdőívkvótákba beletartoznak, akkor a kvóta számlálója csökkentve lesz, de a kvóta korlátai változatlanok maradnak.} other {Ez törölni fogja az ezekhez a partnerekhez tartozó összes kérdőívválaszt és partnerattribútumot. A partnerek adatain alapuló bármilyen célzás és személyre szabás el fog veszni. Ha ezek a partnerek olyan válaszokkal rendelkeznek, amelyek a kérdőívkvótákba beletartoznak, akkor a kvóta számlálója csökkentve lesz, de a kvóta korlátai változatlanok maradnak.}}",
|
||||
@@ -675,15 +675,15 @@
|
||||
"edit_attributes_success": "A partner attribútumai sikeresen frissítve",
|
||||
"generate_personal_link": "Személyes hivatkozás előállítása",
|
||||
"generate_personal_link_description": "Válasszon egy közzétett kérdőívet, hogy személyre szabott hivatkozást állítson elő ehhez a partnerhez.",
|
||||
"invalid_csv_column_names": "Érvénytelen CSV oszlopnév(nevek): {columns}. Az új attribútumokká váló oszlopnevek csak kisbetűket, számokat és aláhúzásjeleket tartalmazhatnak, és betűvel kell kezdődniük.",
|
||||
"invalid_date_format": "Érvénytelen dátumformátum. Kérlek, adj meg egy érvényes dátumot.",
|
||||
"invalid_number_format": "Érvénytelen számformátum. Kérlek, adj meg egy érvényes számot.",
|
||||
"no_activity_yet": "Még nincs aktivitás",
|
||||
"invalid_csv_column_names": "Érvénytelen CSV-oszlopnevek: {columns}. Az új attribútumokká váló oszlopnevek csak ékezet nélküli kisbetűket, számokat és aláhúzásjeleket tartalmazhatnak, valamint betűvel kell kezdődniük.",
|
||||
"invalid_date_format": "Érvénytelen dátumformátum. Használjon érvényes dátumot.",
|
||||
"invalid_number_format": "Érvénytelen számformátum. Adjon meg érvényes számot.",
|
||||
"no_activity_yet": "Még nincs tevékenység",
|
||||
"no_published_link_surveys_available": "Nem érhetők el közzétett hivatkozás-kérdőívek. Először tegyen közzé egy hivatkozás-kérdőívet.",
|
||||
"no_published_surveys": "Nincsenek közzétett kérdőívek",
|
||||
"no_responses_found": "Nem találhatók válaszok",
|
||||
"not_provided": "Nincs megadva",
|
||||
"number_value_required": "Szám érték megadása kötelező. Használd a törlés gombot az attribútum eltávolításához.",
|
||||
"number_value_required": "Számérték szükséges. Használja a törlés gombot az attribútum eltávolításához.",
|
||||
"personal_link_generated": "A személyes hivatkozás sikeresen előállítva",
|
||||
"personal_link_generated_but_clipboard_failed": "A személyes hivatkozás előállítva, de nem sikerült a vágólapra másolni: {url}",
|
||||
"personal_survey_link": "Személyes kérdőív-hivatkozás",
|
||||
@@ -692,24 +692,24 @@
|
||||
"search_contact": "Partner keresése",
|
||||
"select_a_survey": "Kérdőív kiválasztása",
|
||||
"select_attribute": "Attribútum kiválasztása",
|
||||
"select_attribute_key": "Attribútum kulcs kiválasztása",
|
||||
"select_attribute_key": "Attribútum kulcsának kiválasztása",
|
||||
"survey_viewed": "Kérdőív megtekintve",
|
||||
"survey_viewed_at": "Megtekintve",
|
||||
"system_attributes": "Rendszer attribútumok",
|
||||
"survey_viewed_at": "Megtekintve ekkor:",
|
||||
"system_attributes": "Rendszerattribútumok",
|
||||
"unlock_contacts_description": "Partnerek kezelése és célzott kérdőívek kiküldése",
|
||||
"unlock_contacts_title": "Partnerek feloldása egy magasabb csomaggal",
|
||||
"upload_contacts_error_attribute_type_mismatch": "A(z) \"{key}\" attribútum típusa \"{dataType}\", de a CSV érvénytelen értékeket tartalmaz: {values}",
|
||||
"upload_contacts_error_duplicate_mappings": "Duplikált leképezések találhatók a következő attribútumokhoz: {attributes}",
|
||||
"upload_contacts_error_file_too_large": "A fájl mérete meghaladja a maximális 800KB-os limitet",
|
||||
"upload_contacts_error_generic": "Hiba történt a kapcsolatok feltöltése során. Kérjük, próbáld újra később.",
|
||||
"upload_contacts_error_invalid_file_type": "Kérjük, tölts fel egy CSV fájlt",
|
||||
"upload_contacts_error_no_valid_contacts": "A feltöltött CSV fájl nem tartalmaz érvényes kapcsolatokat, kérjük, nézd meg a minta CSV fájlt a helyes formátumhoz.",
|
||||
"upload_contacts_modal_attribute_header": "Formbricks attribútum",
|
||||
"upload_contacts_error_attribute_type_mismatch": "A(z) „{key}” attribútum „{dataType}” típusként van megadva, de a CSV érvénytelen értékeket tartalmaz: {values}",
|
||||
"upload_contacts_error_duplicate_mappings": "Kettőzött leképezések találhatók a következő attribútumoknál: {attributes}",
|
||||
"upload_contacts_error_file_too_large": "A fájlméret túllépi a 800 KB-os legnagyobb méretet",
|
||||
"upload_contacts_error_generic": "Hiba történt a partnerek feltöltése során. Próbálja meg később újra.",
|
||||
"upload_contacts_error_invalid_file_type": "Töltsön fel egy CSV-fájlt",
|
||||
"upload_contacts_error_no_valid_contacts": "A feltöltött CSV-fájl nem tartalmaz egyetlen érvényes partnert sem. Nézze meg a példa CSV-fájlt a helyes formátumért.",
|
||||
"upload_contacts_modal_attribute_header": "Formbricks-attribútum",
|
||||
"upload_contacts_modal_attributes_description": "A CSV-ben lévő oszlopok leképezése a Formbricksben lévő attribútumokra.",
|
||||
"upload_contacts_modal_attributes_new": "Új attribútum",
|
||||
"upload_contacts_modal_attributes_search_or_add": "Attribútum keresése vagy hozzáadása",
|
||||
"upload_contacts_modal_attributes_title": "Attribútumok",
|
||||
"upload_contacts_modal_csv_column_header": "CSV oszlop",
|
||||
"upload_contacts_modal_csv_column_header": "CSV-oszlop",
|
||||
"upload_contacts_modal_description": "CSV feltöltése a partnerek attribútumokkal együtt történő gyors importálásához",
|
||||
"upload_contacts_modal_download_example_csv": "Példa CSV letöltése",
|
||||
"upload_contacts_modal_duplicates_description": "Hogyan kell kezelnünk, ha egy partner már szerepel a partnerek között?",
|
||||
@@ -767,11 +767,11 @@
|
||||
"link_new_sheet": "Új táblázat összekapcsolása",
|
||||
"no_integrations_yet": "A Google Táblázatok integrációi itt fognak megjelenni, amint hozzáadja azokat. ⏲️",
|
||||
"reconnect_button": "Újrakapcsolódás",
|
||||
"reconnect_button_description": "A Google Táblázatok kapcsolata lejárt. Kérjük, csatlakozzon újra a válaszok szinkronizálásának folytatásához. A meglévő táblázathivatkozások és adatok megmaradnak.",
|
||||
"reconnect_button_tooltip": "Csatlakoztassa újra az integrációt a hozzáférés frissítéséhez. A meglévő táblázathivatkozások és adatok megmaradnak.",
|
||||
"spreadsheet_permission_error": "Nincs jogosultsága a táblázat eléréséhez. Kérjük, győződjön meg arról, hogy a táblázat meg van osztva a Google-fiókjával, és írási jogosultsággal rendelkezik a táblázathoz.",
|
||||
"reconnect_button_description": "A Google Táblázatok kapcsolata lejárt. Kapcsolódjon újra a válaszok szinkronizálásának folytatásához. A meglévő táblázatok hivatkozásai és adatai megmaradnak.",
|
||||
"reconnect_button_tooltip": "Csatlakoztassa újra az integrációt a hozzáférés frissítéséhez. A meglévő táblázatok hivatkozásai és adatai megmaradnak.",
|
||||
"spreadsheet_permission_error": "Nincs jogosultsága hozzáférni ehhez a táblázathoz. Győződjön meg arról, hogy a táblázat meg van-e osztva a Google-fiókjával, és rendelkezik-e írási hozzáféréssel a táblázathoz.",
|
||||
"spreadsheet_url": "Táblázat URL-e",
|
||||
"token_expired_error": "A Google Táblázatok frissítési tokenje lejárt vagy visszavonásra került. Kérjük, csatlakoztassa újra az integrációt."
|
||||
"token_expired_error": "A Google Táblázatok frissítési tokenje lejárt vagy visszavonásra került. Csatlakoztassa újra az integrációt."
|
||||
},
|
||||
"include_created_at": "Létrehozva felvétele",
|
||||
"include_hidden_fields": "Rejtett mezők felvétele",
|
||||
@@ -900,35 +900,35 @@
|
||||
"operator_ends_with": "ezzel végződik",
|
||||
"operator_is_after": "ez után",
|
||||
"operator_is_before": "ez előtt",
|
||||
"operator_is_between": "között",
|
||||
"operator_is_between": "ezek között",
|
||||
"operator_is_newer_than": "újabb mint",
|
||||
"operator_is_not_set": "nincs beállítva",
|
||||
"operator_is_older_than": "régebbi mint",
|
||||
"operator_is_same_day": "ugyanazon a napon",
|
||||
"operator_is_set": "beállítva",
|
||||
"operator_is_same_day": "ugyanaz a nap",
|
||||
"operator_is_set": "be van állítva",
|
||||
"operator_starts_with": "ezzel kezdődik",
|
||||
"operator_title_contains": "Tartalmazza",
|
||||
"operator_title_does_not_contain": "Nem tartalmazza",
|
||||
"operator_title_ends_with": "Ezzel végződik",
|
||||
"operator_title_equals": "Egyenlő",
|
||||
"operator_title_greater_equal": "Nagyobb vagy egyenlő",
|
||||
"operator_title_greater_equal": "Nagyobb mint vagy egyenlő",
|
||||
"operator_title_greater_than": "Nagyobb mint",
|
||||
"operator_title_is_after": "Ez után",
|
||||
"operator_title_is_before": "Ez előtt",
|
||||
"operator_title_is_between": "Között",
|
||||
"operator_title_is_between": "Ezek között",
|
||||
"operator_title_is_newer_than": "Újabb mint",
|
||||
"operator_title_is_not_set": "Nincs beállítva",
|
||||
"operator_title_is_older_than": "Régebbi mint",
|
||||
"operator_title_is_same_day": "Ugyanazon a napon",
|
||||
"operator_title_is_same_day": "Ugyanaz a nap",
|
||||
"operator_title_is_set": "Beállítva",
|
||||
"operator_title_less_equal": "Kisebb vagy egyenlő",
|
||||
"operator_title_less_equal": "Kisebb mint vagy egyenlő",
|
||||
"operator_title_less_than": "Kisebb mint",
|
||||
"operator_title_not_equals": "Nem egyenlő",
|
||||
"operator_title_not_equals": "Nem egyenlő ezzel",
|
||||
"operator_title_starts_with": "Ezzel kezdődik",
|
||||
"operator_title_user_is_in": "A felhasználó benne van",
|
||||
"operator_title_user_is_not_in": "A felhasználó nincs benne",
|
||||
"operator_user_is_in": "A felhasználó benne van",
|
||||
"operator_user_is_not_in": "A felhasználó nincs benne",
|
||||
"operator_title_user_is_in": "Felhasználó ebben",
|
||||
"operator_title_user_is_not_in": "Felhasználó nem ebben",
|
||||
"operator_user_is_in": "Felhasználó ebben",
|
||||
"operator_user_is_not_in": "Felhasználó nem ebben",
|
||||
"person_and_attributes": "Személy és attribútumok",
|
||||
"phone": "Telefon",
|
||||
"please_remove_the_segment_from_these_surveys_in_order_to_delete_it": "Távolítsa el a szakaszt ezekből a kérdőívekből, hogy törölhesse azt.",
|
||||
@@ -952,7 +952,7 @@
|
||||
"unlock_segments_title": "Szakaszok feloldása egy magasabb csomaggal",
|
||||
"user_targeting_is_currently_only_available_when": "A felhasználók megcélzása jelenleg csak akkor érhető el, ha",
|
||||
"value_cannot_be_empty": "Az érték nem lehet üres.",
|
||||
"value_must_be_a_number": "Az értékének számnak kell lennie.",
|
||||
"value_must_be_a_number": "Az értéknek számnak kell lennie.",
|
||||
"value_must_be_positive": "Az értéknek pozitív számnak kell lennie.",
|
||||
"view_filters": "Szűrők megtekintése",
|
||||
"where": "Ahol",
|
||||
@@ -1086,7 +1086,7 @@
|
||||
"email_customization_preview_email_heading": "Helló {userName}",
|
||||
"email_customization_preview_email_text": "Ez egy e-mail előnézet, amely azt mutatja meg, hogy melyik logó fog megjelenni az e-mailekben.",
|
||||
"error_deleting_organization_please_try_again": "Hiba a szervezet törlésekor. Próbálja meg újra.",
|
||||
"from_your_organization": "{memberName} a szervezetből",
|
||||
"from_your_organization": "{memberName} a szervezetéből",
|
||||
"invitation_sent_once_more": "A meghívó még egyszer elküldve.",
|
||||
"invite_deleted_successfully": "A meghívó sikeresen törölve",
|
||||
"invite_expires_on": "A meghívó lejár ekkor: {date}",
|
||||
@@ -1251,7 +1251,7 @@
|
||||
"add_fallback_placeholder": "Helykitöltő hozzáadása annak megjelenítéshez, hogy nincs visszahívandó érték.",
|
||||
"add_hidden_field_id": "Rejtett mezőazonosító hozzáadása",
|
||||
"add_highlight_border": "Kiemelési szegély hozzáadása",
|
||||
"add_highlight_border_description": "Csak a terméken belüli felmérésekre vonatkozik.",
|
||||
"add_highlight_border_description": "Csak terméken belüli kérdőívekre vonatkozik.",
|
||||
"add_logic": "Logika hozzáadása",
|
||||
"add_none_of_the_above": "„A fentiek közül egyik sem” hozzáadása",
|
||||
"add_option": "Lehetőség hozzáadása",
|
||||
@@ -1622,7 +1622,7 @@
|
||||
"response_limits_redirections_and_more": "Válaszkorlátok, átirányítások és egyebek.",
|
||||
"response_options": "Válasz beállításai",
|
||||
"roundness": "Kerekesség",
|
||||
"roundness_description": "Szabályozza a sarkok lekerekítését.",
|
||||
"roundness_description": "Annak vezérlése, hogy a sarkok mennyire legyenek lekerekítve.",
|
||||
"row_used_in_logic_error": "Ez a sor használatban van a(z) {questionIndex}. kérdés logikájában. Először távolítsa el a logikából.",
|
||||
"rows": "Sorok",
|
||||
"save_and_close": "Mentés és bezárás",
|
||||
@@ -1668,7 +1668,7 @@
|
||||
"survey_completed_subheading": "Ez a szabad és nyílt forráskódú kérdőív le lett zárva",
|
||||
"survey_display_settings": "Kérdőív megjelenítésének beállításai",
|
||||
"survey_placement": "Kérdőív elhelyezése",
|
||||
"survey_styling": "Űrlap stílusának beállítása",
|
||||
"survey_styling": "Kérdőív stílusának beállítása",
|
||||
"survey_trigger": "Kérdőív aktiválója",
|
||||
"switch_multi_language_on_to_get_started": "Kapcsolja be a többnyelvűséget a kezdéshez 👉",
|
||||
"target_block_not_found": "A célblokk nem található",
|
||||
@@ -1813,7 +1813,7 @@
|
||||
"this_response_is_in_progress": "Ez a válasz folyamatban van.",
|
||||
"zip_post_code": "Irányítószám"
|
||||
},
|
||||
"search_by_survey_name": "Keresés kérőívnév alapján",
|
||||
"search_by_survey_name": "Keresés kérdőívnév alapján",
|
||||
"share": {
|
||||
"anonymous_links": {
|
||||
"custom_single_use_id_description": "Ha nem titkosítja az egyszer használatos azonosítókat, akkor a „suid=…” bármilyen értéke működik egy válasznál.",
|
||||
@@ -1965,8 +1965,8 @@
|
||||
"filtered_responses_csv": "Szűrt válaszok (CSV)",
|
||||
"filtered_responses_excel": "Szűrt válaszok (Excel)",
|
||||
"generating_qr_code": "QR-kód előállítása",
|
||||
"impressions": "Benyomások",
|
||||
"impressions_identified_only": "Csak az azonosított kapcsolatok megjelenítései láthatók",
|
||||
"impressions": "Megtekintések",
|
||||
"impressions_identified_only": "Csak azonosított partnerektől származó megtekintések megjelenítése",
|
||||
"impressions_tooltip": "A kérdőív megtekintési alkalmainak száma.",
|
||||
"in_app": {
|
||||
"connection_description": "A kérdőív a webhelye azon felhasználóinak lesz megjelenítve, akik megfelelnek az alább felsorolt feltételeknek",
|
||||
@@ -2009,7 +2009,7 @@
|
||||
"last_quarter": "Elmúlt negyedév",
|
||||
"last_year": "Elmúlt év",
|
||||
"limit": "Korlát",
|
||||
"no_identified_impressions": "Nincsenek megjelenítések azonosított kapcsolatoktól",
|
||||
"no_identified_impressions": "Nincsenek azonosított partnerektől származó megtekintések",
|
||||
"no_responses_found": "Nem találhatók válaszok",
|
||||
"other_values_found": "Más értékek találhatók",
|
||||
"overall": "Összesen",
|
||||
@@ -2175,12 +2175,12 @@
|
||||
"advanced_styling_field_headline_size_description": "Átméretezi a címsor szövegét.",
|
||||
"advanced_styling_field_headline_weight": "Címsor betűvastagsága",
|
||||
"advanced_styling_field_headline_weight_description": "Vékonyabbá vagy vastagabbá teszi a címsor szövegét.",
|
||||
"advanced_styling_field_height": "Minimális magasság",
|
||||
"advanced_styling_field_height": "Legkisebb magasság",
|
||||
"advanced_styling_field_indicator_bg": "Jelző háttere",
|
||||
"advanced_styling_field_indicator_bg_description": "Kiszínezi a sáv kitöltött részét.",
|
||||
"advanced_styling_field_input_border_radius_description": "Lekerekíti a beviteli mező sarkait.",
|
||||
"advanced_styling_field_input_font_size_description": "Átméretezi a beviteli mezőkbe beírt szöveget.",
|
||||
"advanced_styling_field_input_height_description": "Szabályozza a beviteli mező minimális magasságát.",
|
||||
"advanced_styling_field_input_height_description": "A beviteli mező legkisebb magasságát vezérli.",
|
||||
"advanced_styling_field_input_padding_x_description": "Térközt ad hozzá balra és jobbra.",
|
||||
"advanced_styling_field_input_padding_y_description": "Térközt ad hozzá fent és lent.",
|
||||
"advanced_styling_field_input_placeholder_opacity_description": "Elhalványítja a helykitöltő súgószöveget.",
|
||||
@@ -2190,7 +2190,7 @@
|
||||
"advanced_styling_field_option_bg": "Háttér",
|
||||
"advanced_styling_field_option_bg_description": "Kitölti a választási lehetőség elemeit.",
|
||||
"advanced_styling_field_option_border": "Szegély színe",
|
||||
"advanced_styling_field_option_border_description": "A rádiógomb és jelölőnégyzet opciók körvonalát határozza meg.",
|
||||
"advanced_styling_field_option_border_description": "Körberajzolja a rádiógomb és a jelölőnégyzet lehetőségeit.",
|
||||
"advanced_styling_field_option_border_radius_description": "Lekerekíti a választási lehetőség sarkait.",
|
||||
"advanced_styling_field_option_font_size_description": "Átméretezi a választási lehetőség címkéjének szövegét.",
|
||||
"advanced_styling_field_option_label": "Címke színe",
|
||||
@@ -2228,7 +2228,7 @@
|
||||
"formbricks_branding_settings_description": "Nagyra értékeljük a támogatását, de megértjük, ha kikapcsolja.",
|
||||
"formbricks_branding_shown": "A Formbricks márkajel megjelenik.",
|
||||
"generate_theme_btn": "Előállítás",
|
||||
"generate_theme_confirmation": "Szeretne hozzáillő színtémát létrehozni a márkajel színei alapján? Ez felülírja a jelenlegi színbeállításokat.",
|
||||
"generate_theme_confirmation": "Szeretne hozzáillő színtémát előállítani a márkajel színei alapján? Ez felülírja a jelenlegi színbeállításokat.",
|
||||
"generate_theme_header": "Előállítja a színtémát?",
|
||||
"logo_removed_successfully": "A logó sikeresen eltávolítva",
|
||||
"logo_settings_description": "Vállalati logo feltöltése a kérdőívek és hivatkozások előnézeteinek márkaépítéséhez.",
|
||||
@@ -2245,7 +2245,7 @@
|
||||
"show_powered_by_formbricks": "Az „A gépházban: Formbricks” aláírás megjelenítése",
|
||||
"styling_updated_successfully": "A stílus sikeresen frissítve",
|
||||
"suggest_colors": "Színek ajánlása",
|
||||
"suggested_colors_applied_please_save": "A javasolt színek sikeresen generálva. Nyomd meg a \"Mentés\" gombot a változtatások véglegesítéséhez.",
|
||||
"suggested_colors_applied_please_save": "Az ajánlott színek sikeresen előállítva. Nyomja meg a „Mentés” gombot a változtatások mentéséhez.",
|
||||
"theme": "Téma",
|
||||
"theme_settings_description": "Stílustéma létrehozása az összes kérdőívhez. Egyéni stílust engedélyezhet minden egyes kérdőívhez."
|
||||
},
|
||||
@@ -2307,7 +2307,7 @@
|
||||
"mode": {
|
||||
"formbricks_cx": "Formbricks CX",
|
||||
"formbricks_cx_description": "Kérdőívek és jelentések annak megértéséhez, hogy mire van szükségük az ügyfeleknek.",
|
||||
"formbricks_surveys": "Formbricks kérőívek",
|
||||
"formbricks_surveys": "Formbricks kérdőívek",
|
||||
"formbricks_surveys_description": "Többcélú kérdőíves platform web-, alkalmazás- és e-mail-kérdőívekhez.",
|
||||
"what_are_you_here_for": "Miért van itt?"
|
||||
},
|
||||
@@ -3012,7 +3012,7 @@
|
||||
"preview_survey_question_2_subheader": "Ez egy példa a leírásra.",
|
||||
"preview_survey_question_open_text_headline": "Bármi egyéb, amit meg szeretne osztani?",
|
||||
"preview_survey_question_open_text_placeholder": "Írja be ide a válaszát…",
|
||||
"preview_survey_question_open_text_subheader": "A visszajelzése segít nekünk a fejlődésben.",
|
||||
"preview_survey_question_open_text_subheader": "A visszajelzése segít nekünk fejlődni.",
|
||||
"preview_survey_welcome_card_headline": "Üdvözöljük!",
|
||||
"prioritize_features_description": "A felhasználóknak leginkább és legkevésbé szükséges funkciók azonosítása.",
|
||||
"prioritize_features_name": "Funkciók rangsorolása",
|
||||
@@ -3263,16 +3263,16 @@
|
||||
"usability_score_name": "Rendszer-használhatósági pontszám (SUS)"
|
||||
},
|
||||
"workflows": {
|
||||
"coming_soon_description": "Köszönjük, hogy megosztotta velünk a munkafolyamat ötletét! Jelenleg ezen a funkción dolgozunk, és a visszajelzése segít nekünk pontosan azt megépíteni, amire szüksége van.",
|
||||
"coming_soon_title": "Majdnem kész vagyunk!",
|
||||
"follow_up_label": "Van még valami, amit hozzá szeretne tenni?",
|
||||
"follow_up_placeholder": "Milyen konkrét feladatokat szeretne automatizálni? Vannak olyan eszközök vagy integrációk, amelyeket szeretne belevenni?",
|
||||
"generate_button": "Munkafolyamat generálása",
|
||||
"coming_soon_description": "Köszönjük, hogy megosztotta velünk a munkafolyamatra vonatkozó ötletét! Jelenleg a funkció kialakításán dolgozunk, és a visszajelzése segít nekünk abban, hogy pontosan azt alkossuk meg, amire szüksége van.",
|
||||
"coming_soon_title": "Már majdnem kész vagyunk!",
|
||||
"follow_up_label": "Van még bármi egyéb, amit hozzá szeretne fűzni?",
|
||||
"follow_up_placeholder": "Milyen konkrét feladatokat szeretne automatizálni? Van olyan eszköz vagy integráció, amelyet szívesen látna a rendszerben?",
|
||||
"generate_button": "Munkafolyamat előállítása",
|
||||
"heading": "Milyen munkafolyamatot szeretne létrehozni?",
|
||||
"placeholder": "Írja le a munkafolyamatot, amelyet generálni szeretne...",
|
||||
"subheading": "Generálja le a munkafolyamatát másodpercek alatt.",
|
||||
"placeholder": "Mutassa be az előállítani kívánt munkafolyamatot…",
|
||||
"subheading": "Munkafolyamat előállítása másodpercek alatt.",
|
||||
"submit_button": "Részletek hozzáadása",
|
||||
"thank_you_description": "A visszajelzése segít nekünk megépíteni azt a munkafolyamatok funkciót, amelyre tényleg szüksége van. Folyamatosan tájékoztatjuk az előrehaladásról.",
|
||||
"thank_you_description": "A visszajelzése segít nekünk abban, hogy olyan Munkafolyamatok funkciót alakítsunk ki, amelyre valóban szüksége van. Folyamatosan tájékoztatni fogjuk Önt a fejlesztés előrehaladásáról.",
|
||||
"thank_you_title": "Köszönjük a visszajelzését!"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,50 +191,61 @@ export const SurveyMenuBar = ({
|
||||
const validateSurveyWithZod = (): boolean => {
|
||||
const localSurveyValidation = ZSurvey.safeParse(localSurvey);
|
||||
if (!localSurveyValidation.success) {
|
||||
const currentError = localSurveyValidation.error.issues[0];
|
||||
const issues = localSurveyValidation.error.issues;
|
||||
const newInvalidIds: string[] = [];
|
||||
|
||||
if (currentError.path[0] === "blocks") {
|
||||
const blockIdx = currentError.path[1];
|
||||
for (const issue of issues) {
|
||||
if (issue.path[0] === "blocks") {
|
||||
const blockIdx = issue.path[1];
|
||||
|
||||
// Check if this is an element-level error (path includes "elements")
|
||||
// Element errors: ["blocks", blockIdx, "elements", elementIdx, ...]
|
||||
// Block errors: ["blocks", blockIdx, "buttonLabel"] or ["blocks", blockIdx, "logic"]
|
||||
if (currentError.path[2] === "elements" && typeof currentError.path[3] === "number") {
|
||||
const elementIdx = currentError.path[3];
|
||||
const block: TSurveyBlock = localSurvey.blocks?.[blockIdx];
|
||||
const element = block?.elements[elementIdx];
|
||||
if (issue.path[2] === "elements" && typeof issue.path[3] === "number") {
|
||||
const elementIdx = issue.path[3];
|
||||
const block: TSurveyBlock = localSurvey.blocks?.[blockIdx];
|
||||
const element = block?.elements[elementIdx];
|
||||
|
||||
if (element) {
|
||||
setInvalidElements((prevInvalidElements) =>
|
||||
prevInvalidElements ? [...prevInvalidElements, element.id] : [element.id]
|
||||
);
|
||||
if (element && !newInvalidIds.includes(element.id)) {
|
||||
newInvalidIds.push(element.id);
|
||||
}
|
||||
}
|
||||
} else if (issue.path[0] === "welcomeCard") {
|
||||
if (!newInvalidIds.includes("start")) {
|
||||
newInvalidIds.push("start");
|
||||
}
|
||||
} else if (issue.path[0] === "endings") {
|
||||
const endingIdx = typeof issue.path[1] === "number" ? issue.path[1] : -1;
|
||||
const endingId = localSurvey.endings[endingIdx]?.id;
|
||||
if (endingId && !newInvalidIds.includes(endingId)) {
|
||||
newInvalidIds.push(endingId);
|
||||
}
|
||||
}
|
||||
} else if (currentError.path[0] === "welcomeCard") {
|
||||
setInvalidElements((prevInvalidElements) =>
|
||||
prevInvalidElements ? [...prevInvalidElements, "start"] : ["start"]
|
||||
);
|
||||
} else if (currentError.path[0] === "endings") {
|
||||
const endingIdx = typeof currentError.path[1] === "number" ? currentError.path[1] : -1;
|
||||
setInvalidElements((prevInvalidElements) =>
|
||||
prevInvalidElements
|
||||
? [...prevInvalidElements, localSurvey.endings[endingIdx].id]
|
||||
: [localSurvey.endings[endingIdx].id]
|
||||
);
|
||||
}
|
||||
|
||||
if (currentError.code === "custom") {
|
||||
const params = currentError.params ?? ({} as { invalidLanguageCodes: string[] });
|
||||
if (newInvalidIds.length > 0) {
|
||||
setInvalidElements((prev) => {
|
||||
const existing = prev ?? [];
|
||||
const merged = [...existing];
|
||||
for (const id of newInvalidIds) {
|
||||
if (!merged.includes(id)) {
|
||||
merged.push(id);
|
||||
}
|
||||
}
|
||||
return merged;
|
||||
});
|
||||
}
|
||||
|
||||
const firstError = issues[0];
|
||||
if (firstError.code === "custom") {
|
||||
const params = firstError.params ?? ({} as { invalidLanguageCodes: string[] });
|
||||
if (params.invalidLanguageCodes && params.invalidLanguageCodes.length) {
|
||||
const invalidLanguageLabels = params.invalidLanguageCodes.map(
|
||||
(invalidLanguage: string) => getLanguageLabel(invalidLanguage, locale) ?? invalidLanguage
|
||||
);
|
||||
|
||||
const messageSplit = currentError.message.split("-fLang-")[0];
|
||||
const messageSplit = firstError.message.split("-fLang-")[0];
|
||||
|
||||
toast.error(`${messageSplit} ${invalidLanguageLabels.join(", ")}`);
|
||||
} else {
|
||||
toast.error(currentError.message, {
|
||||
toast.error(firstError.message, {
|
||||
className: "w-fit !max-w-md",
|
||||
});
|
||||
}
|
||||
@@ -242,7 +253,7 @@ export const SurveyMenuBar = ({
|
||||
return false;
|
||||
}
|
||||
|
||||
toast.error(currentError.message);
|
||||
toast.error(firstError.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"pages": [
|
||||
"self-hosting/auth-behavior",
|
||||
"self-hosting/configuration/auth-sso/open-id-connect",
|
||||
"self-hosting/configuration/auth-sso/keycloak-oidc",
|
||||
"self-hosting/configuration/auth-sso/azure-ad-oauth",
|
||||
"self-hosting/configuration/auth-sso/google-oauth",
|
||||
"self-hosting/configuration/auth-sso/saml-sso"
|
||||
|
||||
@@ -61,6 +61,7 @@ For more information on SSO setup, see:
|
||||
- [Google OAuth](./configuration/auth-sso/google-oauth)
|
||||
- [Azure AD OAuth](./configuration/auth-sso/azure-ad-oauth)
|
||||
- [Open ID Connect](./configuration/auth-sso/open-id-connect)
|
||||
- [Keycloak OIDC](./configuration/auth-sso/keycloak-oidc)
|
||||
- [SAML SSO](./configuration/auth-sso/saml-sso)
|
||||
|
||||
<Note>
|
||||
|
||||
191
docs/self-hosting/configuration/auth-sso/keycloak-oidc.mdx
Normal file
191
docs/self-hosting/configuration/auth-sso/keycloak-oidc.mdx
Normal file
@@ -0,0 +1,191 @@
|
||||
---
|
||||
title: "Keycloak OIDC"
|
||||
description: "Configure Keycloak as an OpenID Connect (OIDC) provider for secure Single Sign-On with your self-hosted Formbricks instance."
|
||||
icon: "key-skeleton-left-right"
|
||||
---
|
||||
|
||||
<Note>Keycloak OIDC is part of the Formbricks [Enterprise Edition](/self-hosting/advanced/license)</Note>
|
||||
|
||||
Integrating Keycloak with your Formbricks instance allows users to log in using their existing Keycloak credentials via OpenID Connect. This guide walks you through setting up a Keycloak OIDC client and configuring Formbricks to use it, including automatic user provisioning into a default team.
|
||||
|
||||
### Requirements
|
||||
|
||||
- A running Keycloak instance with a configured realm and users.
|
||||
- A self-hosted Formbricks instance with a valid [Enterprise license](/self-hosting/advanced/license).
|
||||
- The Formbricks callback URI: `{WEBAPP_URL}/api/auth/callback/openid`
|
||||
|
||||
## Setting up Keycloak OIDC
|
||||
|
||||
<Steps>
|
||||
<Step title="Create a new client in Keycloak">
|
||||
- Log in to your Keycloak admin console.
|
||||
- Select the realm you want to use (e.g., `production`).
|
||||
- Navigate to **Clients** in the left menu and click **Create client**.
|
||||
- Set **Client type** to `OpenID Connect`.
|
||||
- Choose a **Client ID** (e.g., `formbricks`) and click **Next**.
|
||||
</Step>
|
||||
|
||||
<Step title="Configure client authentication">
|
||||
- Enable **Client authentication** (this makes the client "confidential" and generates a client secret).
|
||||
- Under **Authentication flow**, ensure **Standard flow** is enabled.
|
||||
- Click **Next**.
|
||||
|
||||
<Note>
|
||||
Formbricks uses PKCE (Proof Key for Code Exchange) for added security. Modern Keycloak versions (21+) support PKCE automatically for confidential clients. No additional PKCE configuration is needed.
|
||||
</Note>
|
||||
</Step>
|
||||
|
||||
<Step title="Set the redirect URI">
|
||||
- Under **Valid redirect URIs**, add your Formbricks callback URI:
|
||||
|
||||
```
|
||||
https://your-formbricks-domain.com/api/auth/callback/openid
|
||||
```
|
||||
|
||||
Replace `your-formbricks-domain.com` with your actual Formbricks URL.
|
||||
|
||||
- Click **Save**.
|
||||
</Step>
|
||||
|
||||
<Step title="Copy the client secret">
|
||||
- After saving, go to the **Credentials** tab of your newly created client.
|
||||
- Copy the **Client secret** value — you will need this for the Formbricks configuration.
|
||||
</Step>
|
||||
|
||||
<Step title="Determine the issuer URL">
|
||||
The OIDC issuer URL follows this pattern:
|
||||
|
||||
```
|
||||
https://your-keycloak-domain.com/realms/your-realm-name
|
||||
```
|
||||
|
||||
For example, if your Keycloak runs at `login.example.com` and your realm is called `production`:
|
||||
|
||||
```
|
||||
https://login.example.com/realms/production
|
||||
```
|
||||
|
||||
<Note>
|
||||
You can verify the issuer URL by navigating to `https://your-keycloak-domain.com/realms/your-realm-name/.well-known/openid-configuration` in your browser. It should return a JSON document with the OIDC discovery endpoints.
|
||||
</Note>
|
||||
</Step>
|
||||
|
||||
<Step title="Configure Formbricks environment variables">
|
||||
Add the following environment variables to your Formbricks `.env` file or `docker-compose.yml`:
|
||||
|
||||
```yml Formbricks Env for Keycloak OIDC
|
||||
OIDC_CLIENT_ID=formbricks
|
||||
OIDC_CLIENT_SECRET=your-client-secret-here
|
||||
OIDC_ISSUER=https://your-keycloak-domain.com/realms/your-realm-name
|
||||
OIDC_DISPLAY_NAME="Keycloak Login"
|
||||
OIDC_SIGNING_ALGORITHM=RS256
|
||||
```
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| `OIDC_CLIENT_ID` | The Client ID you chose in Keycloak (e.g., `formbricks`). |
|
||||
| `OIDC_CLIENT_SECRET` | The client secret from the **Credentials** tab. |
|
||||
| `OIDC_ISSUER` | Your Keycloak realm URL (see step above). |
|
||||
| `OIDC_DISPLAY_NAME` | The label shown on the Formbricks login button. |
|
||||
| `OIDC_SIGNING_ALGORITHM` | Optional. Keycloak and Formbricks both default to `RS256`. Only set this if your realm uses a different algorithm. |
|
||||
</Step>
|
||||
|
||||
<Step title="Restart and test">
|
||||
- Restart your Formbricks instance.
|
||||
- The login page should now display a button with your chosen `OIDC_DISPLAY_NAME`.
|
||||
- Click it to authenticate through Keycloak.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
To disable email/password login entirely and force all users through Keycloak, set `EMAIL_AUTH_DISABLED=1`. This hides the email/password form on the login page.
|
||||
</Note>
|
||||
|
||||
## Automatic User Provisioning
|
||||
|
||||
By default, new SSO users must be invited by an organization admin before they can access Formbricks. To allow Keycloak users to join automatically and be assigned to a team, configure the following additional environment variables:
|
||||
|
||||
```yml Automatic User Provisioning
|
||||
AUTH_SKIP_INVITE_FOR_SSO=1
|
||||
AUTH_SSO_DEFAULT_TEAM_ID=your-team-id-here
|
||||
```
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| `AUTH_SKIP_INVITE_FOR_SSO` | Set to `1` to let SSO users create an account without a manual invite. |
|
||||
| `AUTH_SSO_DEFAULT_TEAM_ID` | The ID of the team that new SSO users are automatically added to. The organization is determined from this team. |
|
||||
|
||||
### Finding Your Team ID
|
||||
|
||||
1. Log in to Formbricks as an admin.
|
||||
2. Go to **Organization Settings** → **Teams**.
|
||||
3. Click **Manage Team** on the team you want to use as the default.
|
||||
4. The Team ID is displayed in the modal.
|
||||
|
||||
<Note>
|
||||
The Teams feature requires the **Role-Based Access Control (RBAC)** add-on on your Enterprise license. If you don't see the Teams section in Organization Settings, contact [Formbricks support](mailto:support@formbricks.com) to enable it.
|
||||
</Note>
|
||||
|
||||
### How It Works
|
||||
|
||||
When `AUTH_SKIP_INVITE_FOR_SSO=1` and `AUTH_SSO_DEFAULT_TEAM_ID` are both set:
|
||||
|
||||
1. A user authenticates through Keycloak for the first time.
|
||||
2. Formbricks creates a new user account.
|
||||
3. The user is automatically added as a **member** of the organization that owns the specified team.
|
||||
4. The user is assigned to the default team, granting them access to all projects associated with that team.
|
||||
|
||||
No manual invitation or admin action is required.
|
||||
|
||||
## Full Configuration Example
|
||||
|
||||
A complete `.env` configuration for Keycloak OIDC with automatic user provisioning:
|
||||
|
||||
```yml Complete Keycloak OIDC Configuration
|
||||
OIDC_CLIENT_ID=formbricks
|
||||
OIDC_CLIENT_SECRET=your-client-secret-here
|
||||
OIDC_ISSUER=https://login.example.com/realms/production
|
||||
OIDC_DISPLAY_NAME="Company Login"
|
||||
OIDC_SIGNING_ALGORITHM=RS256
|
||||
AUTH_SKIP_INVITE_FOR_SSO=1
|
||||
AUTH_SSO_DEFAULT_TEAM_ID=your-team-id-here
|
||||
# Optional: disable email/password login to force Keycloak-only authentication
|
||||
# EMAIL_AUTH_DISABLED=1
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Users see 'No access to Workspaces' after login">
|
||||
This means the user was added to the organization but not assigned to a team. Verify that:
|
||||
- `AUTH_SSO_DEFAULT_TEAM_ID` is set correctly (the env variable name is `AUTH_SSO_DEFAULT_TEAM_ID`, not `DEFAULT_TEAM_ID`).
|
||||
- The Team ID is a valid cuid that exists in your database.
|
||||
- The team is linked to a project via **Project Teams** settings.
|
||||
|
||||
You can verify the team exists by checking your database:
|
||||
```sql
|
||||
SELECT id, name, "organizationId" FROM "Team" WHERE id = 'your-team-id';
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Users see 'No membership found' after login">
|
||||
Formbricks determines the organization automatically from the `AUTH_SSO_DEFAULT_TEAM_ID` — you do not need to set a separate organization ID. If this error appears:
|
||||
- Verify the team specified in `AUTH_SSO_DEFAULT_TEAM_ID` exists and belongs to the correct organization.
|
||||
- Confirm your Enterprise license includes the RBAC feature (required for Teams).
|
||||
- Ensure the organization has an active billing plan that supports access control.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="OIDC login button does not appear">
|
||||
- Confirm that `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, and `OIDC_ISSUER` are all set.
|
||||
- Ensure your Formbricks instance has a valid Enterprise license.
|
||||
- Restart the Formbricks container after adding the environment variables.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Authentication fails with a redirect error">
|
||||
- Verify the **Valid redirect URI** in your Keycloak client matches exactly: `{WEBAPP_URL}/api/auth/callback/openid`
|
||||
- Check that the OIDC issuer URL is reachable from your Formbricks server. You can test with:
|
||||
```bash
|
||||
curl https://your-keycloak-domain.com/realms/your-realm-name/.well-known/openid-configuration
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@@ -86,18 +86,19 @@
|
||||
"uuid": "11.1.0",
|
||||
"node-forge": ">=1.3.2",
|
||||
"tar-fs": "2.1.4",
|
||||
"tar": ">=7.5.7",
|
||||
"tar": ">=7.5.11",
|
||||
"minimatch@~9.0": "9.0.9",
|
||||
"typeorm": ">=0.3.26",
|
||||
"systeminformation": "5.27.14",
|
||||
"qs": ">=6.14.1",
|
||||
"preact": ">=10.26.10",
|
||||
"fast-xml-parser": "5.3.5",
|
||||
"fast-xml-parser": "5.4.2",
|
||||
"diff": ">=8.0.3",
|
||||
"@isaacs/brace-expansion": ">=5.0.1",
|
||||
"@microsoft/api-extractor": ">=7.57.6"
|
||||
},
|
||||
"comments": {
|
||||
"overrides": "Security fixes for transitive dependencies. Remove when upstream packages update: axios (CVE-2025-58754) - awaiting @boxyhq/saml-jackson update | node-forge (Dependabot #230) - awaiting @boxyhq/saml-jackson update | tar-fs (Dependabot #205) - awaiting upstream dependency updates | tar (Dependabot #249/#264) - awaiting @boxyhq/saml-jackson/sqlite3 dependency updates | typeorm (Dependabot #223) - awaiting @boxyhq/saml-jackson update | systeminformation (Dependabot #241) - awaiting @opentelemetry/host-metrics update | qs (Dependabot #245) - awaiting googleapis-common and stripe updates | preact (Dependabot #247) - awaiting next-auth update | fast-xml-parser (Dependabot #270) - awaiting @boxyhq/saml-jackson update | diff (Dependabot #269) - awaiting @microsoft/api-extractor update | @isaacs/brace-expansion (Dependabot #271) - awaiting upstream updates | @microsoft/api-extractor - overridden until vite-plugin-dts lock resolution catches up"
|
||||
"overrides": "Security fixes for transitive dependencies. Remove when upstream packages update: axios (CVE-2025-58754) - awaiting @boxyhq/saml-jackson update | node-forge (Dependabot #230) - awaiting @boxyhq/saml-jackson update | tar-fs (Dependabot #205) - awaiting upstream dependency updates | tar (CVE-2026-23745/23950/24842/26960) - awaiting @boxyhq/saml-jackson/sqlite3 dependency updates | typeorm (Dependabot #223) - awaiting @boxyhq/saml-jackson update | systeminformation (Dependabot #241) - awaiting @opentelemetry/host-metrics update | qs (Dependabot #245) - awaiting googleapis-common and stripe updates | preact (Dependabot #247) - awaiting next-auth update | fast-xml-parser (CVE-2026-25896/26278) - awaiting @boxyhq/saml-jackson update | diff (Dependabot #269) - awaiting @microsoft/api-extractor update | @isaacs/brace-expansion (Dependabot #271) - awaiting upstream updates | @microsoft/api-extractor - overridden until vite-plugin-dts lock resolution catches up | minimatch (CVE-2026-26996/27903/27904) - awaiting upstream updates"
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"next-auth@4.24.13": "patches/next-auth@4.24.13.patch"
|
||||
|
||||
@@ -31,6 +31,9 @@ export const stripInlineStyles = (html: string): string => {
|
||||
// This is more secure than regex-based approaches and handles edge cases properly
|
||||
return DOMPurify.sanitize(html, {
|
||||
FORBID_ATTR: ["style"],
|
||||
// Preserve the target attribute (e.g. target="_blank" on links) which is not
|
||||
// in DOMPurify's default allow-list but is explicitly required downstream.
|
||||
ADD_ATTR: ["target"],
|
||||
// Keep other attributes and tags as-is, only remove style attributes
|
||||
KEEP_CONTENT: true,
|
||||
});
|
||||
|
||||
@@ -14,6 +14,9 @@ export const stripInlineStyles = (html: string): string => {
|
||||
// This is more secure than regex-based approaches and handles edge cases properly
|
||||
return DOMPurify.sanitize(html, {
|
||||
FORBID_ATTR: ["style"],
|
||||
// Preserve the target attribute (e.g. target="_blank" on links) which is not
|
||||
// in DOMPurify's default allow-list but is explicitly required downstream.
|
||||
ADD_ATTR: ["target"],
|
||||
// Keep other attributes and tags as-is, only remove style attributes
|
||||
KEEP_CONTENT: true,
|
||||
});
|
||||
|
||||
66
pnpm-lock.yaml
generated
66
pnpm-lock.yaml
generated
@@ -9,12 +9,13 @@ overrides:
|
||||
uuid: 11.1.0
|
||||
node-forge: '>=1.3.2'
|
||||
tar-fs: 2.1.4
|
||||
tar: '>=7.5.7'
|
||||
tar: '>=7.5.11'
|
||||
minimatch@~9.0: 9.0.9
|
||||
typeorm: '>=0.3.26'
|
||||
systeminformation: 5.27.14
|
||||
qs: '>=6.14.1'
|
||||
preact: '>=10.26.10'
|
||||
fast-xml-parser: 5.3.5
|
||||
fast-xml-parser: 5.4.2
|
||||
diff: '>=8.0.3'
|
||||
'@isaacs/brace-expansion': '>=5.0.1'
|
||||
'@microsoft/api-extractor': '>=7.57.6'
|
||||
@@ -7701,8 +7702,11 @@ packages:
|
||||
fast-uri@3.1.0:
|
||||
resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
|
||||
|
||||
fast-xml-parser@5.3.5:
|
||||
resolution: {integrity: sha512-JeaA2Vm9ffQKp9VjvfzObuMCjUYAp5WDYhRYL5LrBPY/jUDlUtOvDfot0vKSkB9tuX885BDHjtw4fZadD95wnA==}
|
||||
fast-xml-builder@1.0.0:
|
||||
resolution: {integrity: sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==}
|
||||
|
||||
fast-xml-parser@5.4.2:
|
||||
resolution: {integrity: sha512-pw/6pIl4k0CSpElPEJhDppLzaixDEuWui2CUQQBH/ECDf7+y6YwA4Gf7Tyb0Rfe4DIMuZipYj4AEL0nACKglvQ==}
|
||||
hasBin: true
|
||||
|
||||
fastest-stable-stringify@2.0.2:
|
||||
@@ -8910,16 +8914,9 @@ packages:
|
||||
resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==}
|
||||
engines: {node: 18 || 20 || >=22}
|
||||
|
||||
minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
|
||||
minimatch@3.1.5:
|
||||
resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minimatch@9.0.9:
|
||||
resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
@@ -10617,8 +10614,8 @@ packages:
|
||||
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
tar@7.5.7:
|
||||
resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==}
|
||||
tar@7.5.11:
|
||||
resolution: {integrity: sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
tarn@3.0.2:
|
||||
@@ -11727,7 +11724,7 @@ snapshots:
|
||||
'@smithy/smithy-client': 4.11.2
|
||||
'@smithy/types': 4.12.0
|
||||
'@smithy/util-middleware': 4.2.8
|
||||
fast-xml-parser: 5.3.5
|
||||
fast-xml-parser: 5.4.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/core@3.973.17':
|
||||
@@ -12355,7 +12352,7 @@ snapshots:
|
||||
'@aws-sdk/xml-builder@3.972.9':
|
||||
dependencies:
|
||||
'@smithy/types': 4.13.0
|
||||
fast-xml-parser: 5.3.5
|
||||
fast-xml-parser: 5.4.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws/lambda-invoke-store@0.2.2': {}
|
||||
@@ -12442,7 +12439,7 @@ snapshots:
|
||||
|
||||
'@azure/core-xml@1.5.0':
|
||||
dependencies:
|
||||
fast-xml-parser: 5.3.5
|
||||
fast-xml-parser: 5.4.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@azure/identity@4.13.0':
|
||||
@@ -13252,7 +13249,7 @@ snapshots:
|
||||
ignore: 5.3.2
|
||||
import-fresh: 3.3.1
|
||||
js-yaml: 4.1.1
|
||||
minimatch: 3.1.2
|
||||
minimatch: 3.1.5
|
||||
strip-json-comments: 3.1.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -13374,7 +13371,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@humanwhocodes/object-schema': 2.0.3
|
||||
debug: 4.4.3
|
||||
minimatch: 3.1.2
|
||||
minimatch: 3.1.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -18041,7 +18038,7 @@ snapshots:
|
||||
'@vue/compiler-vue2': 2.7.16
|
||||
'@vue/shared': 3.5.26
|
||||
alien-signals: 0.4.14
|
||||
minimatch: 9.0.5
|
||||
minimatch: 9.0.9
|
||||
muggle-string: 0.4.1
|
||||
path-browserify: 1.0.1
|
||||
optionalDependencies:
|
||||
@@ -18563,7 +18560,7 @@ snapshots:
|
||||
promise-inflight: 1.0.1
|
||||
rimraf: 3.0.2
|
||||
ssri: 8.0.1
|
||||
tar: 7.5.7
|
||||
tar: 7.5.11
|
||||
unique-filename: 1.1.1
|
||||
transitivePeerDependencies:
|
||||
- bluebird
|
||||
@@ -19458,7 +19455,7 @@ snapshots:
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.16.1
|
||||
is-glob: 4.0.3
|
||||
minimatch: 3.1.2
|
||||
minimatch: 3.1.5
|
||||
object.fromentries: 2.0.8
|
||||
object.groupby: 1.0.3
|
||||
object.values: 1.2.1
|
||||
@@ -19487,7 +19484,7 @@ snapshots:
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.16.1
|
||||
is-glob: 4.0.3
|
||||
minimatch: 3.1.2
|
||||
minimatch: 3.1.5
|
||||
object.fromentries: 2.0.8
|
||||
object.groupby: 1.0.3
|
||||
object.values: 1.2.1
|
||||
@@ -19525,7 +19522,7 @@ snapshots:
|
||||
hasown: 2.0.2
|
||||
jsx-ast-utils: 3.3.5
|
||||
language-tags: 1.0.9
|
||||
minimatch: 3.1.2
|
||||
minimatch: 3.1.5
|
||||
object.fromentries: 2.0.8
|
||||
safe-regex-test: 1.1.0
|
||||
string.prototype.includes: 2.0.1
|
||||
@@ -19565,7 +19562,7 @@ snapshots:
|
||||
estraverse: 5.3.0
|
||||
hasown: 2.0.2
|
||||
jsx-ast-utils: 3.3.5
|
||||
minimatch: 3.1.2
|
||||
minimatch: 3.1.5
|
||||
object.entries: 1.1.9
|
||||
object.fromentries: 2.0.8
|
||||
object.values: 1.2.1
|
||||
@@ -19689,7 +19686,7 @@ snapshots:
|
||||
json-stable-stringify-without-jsonify: 1.0.1
|
||||
levn: 0.4.1
|
||||
lodash.merge: 4.6.2
|
||||
minimatch: 3.1.2
|
||||
minimatch: 3.1.5
|
||||
natural-compare: 1.4.0
|
||||
optionator: 0.9.4
|
||||
strip-ansi: 6.0.1
|
||||
@@ -19773,8 +19770,11 @@ snapshots:
|
||||
|
||||
fast-uri@3.1.0: {}
|
||||
|
||||
fast-xml-parser@5.3.5:
|
||||
fast-xml-builder@1.0.0: {}
|
||||
|
||||
fast-xml-parser@5.4.2:
|
||||
dependencies:
|
||||
fast-xml-builder: 1.0.0
|
||||
strnum: 2.1.2
|
||||
|
||||
fastest-stable-stringify@2.0.2: {}
|
||||
@@ -21043,18 +21043,10 @@ snapshots:
|
||||
dependencies:
|
||||
brace-expansion: 5.0.4
|
||||
|
||||
minimatch@3.1.2:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.12
|
||||
|
||||
minimatch@3.1.5:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.12
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.2
|
||||
|
||||
minimatch@9.0.9:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.2
|
||||
@@ -21317,7 +21309,7 @@ snapshots:
|
||||
npmlog: 6.0.2
|
||||
rimraf: 3.0.2
|
||||
semver: 7.7.3
|
||||
tar: 7.5.7
|
||||
tar: 7.5.11
|
||||
which: 2.0.2
|
||||
transitivePeerDependencies:
|
||||
- bluebird
|
||||
@@ -22744,7 +22736,7 @@ snapshots:
|
||||
bindings: 1.5.0
|
||||
node-addon-api: 7.1.1
|
||||
prebuild-install: 7.1.3
|
||||
tar: 7.5.7
|
||||
tar: 7.5.11
|
||||
optionalDependencies:
|
||||
node-gyp: 8.4.1
|
||||
transitivePeerDependencies:
|
||||
@@ -23019,7 +23011,7 @@ snapshots:
|
||||
inherits: 2.0.4
|
||||
readable-stream: 3.6.2
|
||||
|
||||
tar@7.5.7:
|
||||
tar@7.5.11:
|
||||
dependencies:
|
||||
'@isaacs/fs-minipass': 4.0.1
|
||||
chownr: 3.0.0
|
||||
|
||||
Reference in New Issue
Block a user