Fix missing migration when reading TERMS_AND_CONDITIONS required action in legacy store

Closes #17277
This commit is contained in:
Michal Hajas
2023-03-17 10:25:14 +01:00
committed by Hynek Mlnařík
parent 548827b5a3
commit e49dfe534e
50 changed files with 181 additions and 42 deletions

View File

@@ -0,0 +1,9 @@
= Terms and Conditions user attribute migration
The `terms_and_conditions` user attribute was accidentally changed in 21.0.0
to uppercase. This version reverts the user attribute back to lowercase.
The value of the attribute is set when accepting Terms and Conditions page.
If any of your custom extensions relies on this attribute, you may need to
adjust your code to check both attributes `terms_and_conditions` and
`TERMS_AND_CONDITIONS`.

View File

@@ -4,6 +4,10 @@
include::changes-22_0_0.adoc[leveloffset=3]
=== Migrating to 21.0.2
include::changes-21_0_2.adoc[leveloffset=3]
=== Migrating to 21.0.0
include::changes-21_0_0.adoc[leveloffset=3]

View File

@@ -14,7 +14,7 @@ export default class CredentialsPage {
"UPDATE_PROFILE-option",
"CONFIGURE_TOTP-option",
"UPDATE_PASSWORD-option",
"terms_and_conditions-option",
"TERMS_AND_CONDITIONS-option",
];
private readonly confirmationButton = "confirm";
private readonly editLabelBtn = "editUserLabelBtn";

View File

@@ -163,7 +163,7 @@
"UPDATE_PASSWORD": "Update password (UPDATE_PASSWORD)",
"UPDATE_PROFILE": "Update Profile (UPDATE_PROFILE)",
"CONFIGURE_TOTP": "Configure OTP (CONFIGURE_TOTP)",
"terms_and_conditions": "Terms and Conditions (terms_and_conditions)",
"TERMS_AND_CONDITIONS": "Terms and Conditions (TERMS_AND_CONDITIONS)",
"hours": "Hours",
"minutes": "Minutes",
"seconds": "Seconds",

View File

@@ -1448,7 +1448,7 @@
"required-action":{
"internal":true,
"providers":{
"terms_and_conditions":{
"TERMS_AND_CONDITIONS":{
"order":0
},
"update_user_locale":{

View File

@@ -883,7 +883,7 @@
"required-action": {
"internal": true,
"providers": {
"terms_and_conditions": { "order": 0 },
"TERMS_AND_CONDITIONS": { "order": 0 },
"update_user_locale": { "order": 0 },
"CONFIGURE_TOTP": { "order": 0 },
"VERIFY_EMAIL": { "order": 0 },

View File

@@ -7,7 +7,7 @@ export enum RequiredActionAlias {
UPDATE_PROFILE = "UPDATE_PROFILE",
CONFIGURE_TOTP = "CONFIGURE_TOTP",
UPDATE_PASSWORD = "UPDATE_PASSWORD",
terms_and_conditions = "terms_and_conditions",
TERMS_AND_CONDITIONS = "TERMS_AND_CONDITIONS",
}
export default interface RequiredActionProviderRepresentation {

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.connections.jpa.updater.liquibase.custom;
import liquibase.exception.CustomChangeException;
import liquibase.statement.core.UpdateStatement;
import liquibase.structure.core.Table;
import org.keycloak.models.UserModel;
public class JpaUpdate21_0_2_TermsAndConditionsRequiredAction extends CustomKeycloakTask {
private static final String TERMS_AND_CONDITION_LEGACY_ALIAS = "terms_and_conditions";
@Override
protected void generateStatementsImpl() throws CustomChangeException {
statements.add(
new UpdateStatement(null, null, database.correctObjectName("REQUIRED_ACTION_PROVIDER", Table.class))
.addNewColumnValue("ALIAS", UserModel.RequiredAction.TERMS_AND_CONDITIONS.name())
.addNewColumnValue("PROVIDER_ID", UserModel.RequiredAction.TERMS_AND_CONDITIONS.name())
.setWhereClause("ALIAS=?")
.addWhereParameter(TERMS_AND_CONDITION_LEGACY_ALIAS)
);
statements.add(
new UpdateStatement(null, null, database.correctObjectName("USER_REQUIRED_ACTION", Table.class))
.addNewColumnValue("REQUIRED_ACTION", UserModel.RequiredAction.TERMS_AND_CONDITIONS.name())
.setWhereClause("REQUIRED_ACTION=?")
.addWhereParameter(TERMS_AND_CONDITION_LEGACY_ALIAS)
);
}
@Override
protected String getTaskId() {
return "TermsAndConditions required action alias and providerId change (21.0.2)";
}
}

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
~ * Copyright 2022 Red Hat, Inc. and/or its affiliates
~ * and other contributors as indicated by the @author tags.
~ *
~ * Licensed under the Apache License, Version 2.0 (the "License");
~ * you may not use this file except in compliance with the License.
~ * You may obtain a copy of the License at
~ *
~ * http://www.apache.org/licenses/LICENSE-2.0
~ *
~ * Unless required by applicable law or agreed to in writing, software
~ * distributed under the License is distributed on an "AS IS" BASIS,
~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ * See the License for the specific language governing permissions and
~ * limitations under the License.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="keycloak" id="21.0.2-17277">
<customChange class="org.keycloak.connections.jpa.updater.liquibase.custom.JpaUpdate21_0_2_TermsAndConditionsRequiredAction"/>
</changeSet>
</databaseChangeLog>

View File

@@ -75,5 +75,6 @@
<include file="META-INF/jpa-changelog-18.0.0.xml"/>
<include file="META-INF/jpa-changelog-19.0.0.xml"/>
<include file="META-INF/jpa-changelog-20.0.0.xml"/>
<include file="META-INF/jpa-changelog-21.0.2.xml"/>
</databaseChangeLog>

View File

@@ -1428,9 +1428,9 @@ public class LegacyExportImportManager implements ExportImportManager {
model.setPriority(rep.getPriority());
model.setDefaultAction(rep.isDefaultAction());
model.setEnabled(rep.isEnabled());
model.setProviderId(rep.getProviderId());
model.setProviderId(getDefaultRequiredActionCaseInsensitively(rep.getProviderId()));
model.setName(rep.getName());
model.setAlias(rep.getAlias());
model.setAlias(getDefaultRequiredActionCaseInsensitively(rep.getAlias()));
return model;
}

View File

@@ -33,7 +33,7 @@ import java.util.Arrays;
*/
public class TermsAndConditions implements RequiredActionProvider, RequiredActionFactory {
public static final String PROVIDER_ID = UserModel.RequiredAction.TERMS_AND_CONDITIONS.name();
public static final String USER_ATTRIBUTE = PROVIDER_ID;
public static final String USER_ATTRIBUTE = "terms_and_conditions";
@Override
public RequiredActionProvider create(KeycloakSession session) {
@@ -72,6 +72,12 @@ public class TermsAndConditions implements RequiredActionProvider, RequiredActio
@Override
public void processAction(RequiredActionContext context) {
// Keycloak 21.0.0 changed the user attribute name from lowercase to uppercase
// this change was reverted, but it is still possible some attributes created
// in Keycloak 21.0.0 will be present in the database, we need to remove it too.
// See https://github.com/keycloak/keycloak/issues/17277 for more details
context.getUser().removeAttribute(USER_ATTRIBUTE.toUpperCase());
if (context.getHttpRequest().getDecodedFormParameters().containsKey("cancel")) {
context.getUser().removeAttribute(USER_ATTRIBUTE);
context.failure();

View File

@@ -112,7 +112,6 @@ import java.util.stream.Stream;
import static org.keycloak.common.util.ServerCookie.SameSiteAttributeValue;
import static org.keycloak.models.UserSessionModel.CORRESPONDING_SESSION_ID;
import static org.keycloak.models.utils.DefaultRequiredActions.getDefaultRequiredActionCaseInsensitively;
import static org.keycloak.protocol.oidc.grants.device.DeviceGrantType.isOAuth2DeviceVerificationFlow;
import static org.keycloak.services.util.CookieHelper.getCookie;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
@@ -1292,7 +1291,7 @@ public class AuthenticationManager {
private static Response executeAction(KeycloakSession session, AuthenticationSessionModel authSession, RequiredActionProviderModel model,
HttpRequest request, EventBuilder event, RealmModel realm, UserModel user, boolean kcActionExecution) {
RequiredActionFactory factory = (RequiredActionFactory) session.getKeycloakSessionFactory()
.getProviderFactory(RequiredActionProvider.class, getDefaultRequiredActionCaseInsensitively(model.getProviderId()));
.getProviderFactory(RequiredActionProvider.class, model.getProviderId());
if (factory == null) {
throw new RuntimeException("Unable to find factory for Required Action: " + model.getProviderId() + " did you forget to declare it in a META-INF/services file?");
}
@@ -1403,7 +1402,7 @@ public class AuthenticationManager {
private static RequiredActionFactory toRequiredActionFactory(KeycloakSession session, RequiredActionProviderModel model, RealmModel realm) {
RequiredActionFactory factory = (RequiredActionFactory) session.getKeycloakSessionFactory()
.getProviderFactory(RequiredActionProvider.class, getDefaultRequiredActionCaseInsensitively(model.getProviderId()));
.getProviderFactory(RequiredActionProvider.class, model.getProviderId());
if (factory == null) {
if (!DefaultRequiredActions.isActionAvailable(model)) {
logger.warnf("Required action provider factory '%s' configured in the realm '%s' is not available. " +

View File

@@ -59,6 +59,7 @@ import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
@@ -84,12 +85,14 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -320,11 +323,17 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
testPostLogoutRedirectUrisSet(migrationRealm);
}
protected void testMigrationTo20_0_0() {
protected void testMigrationTo20_0_0() {
testViewGroups(masterRealm);
testViewGroups(migrationRealm);
}
protected void testMigrationTo21_0_2() {
testTermsAndConditionsMigrated(masterRealm);
testTermsAndConditionsMigrated(migrationRealm);
testTermsAndConditionsMigrated(migrationRealm2);
}
protected void testDeleteAccount(RealmResource realm) {
ClientRepresentation accountClient = realm.clients().findByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID).get(0);
@@ -505,6 +514,32 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
assertNotNull(viewAppRole);
}
protected void testTermsAndConditionsMigrated(RealmResource realmResource) {
final String legacyTermsAndConditionsAlias = "terms_and_conditions";
// Test realm RequiredAction migrated
RealmRepresentation realm = realmResource.toRepresentation();
List<RequiredActionProviderRepresentation> requiredActions = realm.getRequiredActions();
if (requiredActions != null && !requiredActions.isEmpty()) {
assertThat(requiredActions.stream()
.map(RequiredActionProviderRepresentation::getAlias)
.collect(Collectors.toList()), not(hasItem(legacyTermsAndConditionsAlias)));
assertThat(requiredActions.stream()
.map(RequiredActionProviderRepresentation::getProviderId)
.collect(Collectors.toList()), not(hasItem(legacyTermsAndConditionsAlias)));
}
List<UserRepresentation> users = realmResource.users().list(null, null);
if (users != null && !users.isEmpty()) {
// Test users required actions migrated
assertThat(users.stream()
.flatMap(user -> user.getRequiredActions().stream())
.collect(Collectors.toList()),
not(hasItem(legacyTermsAndConditionsAlias)));
}
}
protected void testRoleManageAccountLinks(RealmResource... realms) {
log.info("testing role manage account links");
for (RealmResource realm : realms) {
@@ -972,6 +1007,10 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
testMigrationTo20_0_0();
}
protected void testMigrationTo21_x() {
testMigrationTo21_0_2();
}
protected void testMigrationTo7_x(boolean supportedAuthzServices) {
if (supportedAuthzServices) {
testDecisionStrategySetOnResourceServer();

View File

@@ -75,6 +75,7 @@ public class JsonFileImport198MigrationTest extends AbstractJsonFileImportMigrat
testMigrationTo12_x(false);
testMigrationTo18_x();
testMigrationTo20_x();
testMigrationTo21_x();
}
@Override

View File

@@ -69,6 +69,7 @@ public class JsonFileImport255MigrationTest extends AbstractJsonFileImportMigrat
testMigrationTo12_x(false);
testMigrationTo18_x();
testMigrationTo20_x();
testMigrationTo21_x();
}
}

View File

@@ -64,6 +64,7 @@ public class JsonFileImport343MigrationTest extends AbstractJsonFileImportMigrat
testMigrationTo12_x(true);
testMigrationTo18_x();
testMigrationTo20_x();
testMigrationTo21_x();
}
}

View File

@@ -58,6 +58,7 @@ public class JsonFileImport483MigrationTest extends AbstractJsonFileImportMigrat
testMigrationTo12_x(true);
testMigrationTo18_x();
testMigrationTo20_x();
testMigrationTo21_x();
}
}

View File

@@ -51,6 +51,7 @@ public class JsonFileImport903MigrationTest extends AbstractJsonFileImportMigrat
testMigrationTo12_x(true);
testMigrationTo18_x();
testMigrationTo20_x();
testMigrationTo21_x();
}
}

View File

@@ -69,5 +69,6 @@ public class MigrationTest extends AbstractMigrationTest {
testExtremelyLongClientAttribute(migrationRealm);
testMigrationTo20_x();
testMigrationTo21_x();
}
}

View File

@@ -32,7 +32,7 @@ eventUpdateTotpBody=تم تحديث حاصية رمز التحقق لحسابك
eventUpdateTotpBodyHtml=<p style="direction: rtl;">تم تحديث حاصية رمز التحقق لحسابك في {0} ومن {1}. إذا لم تكن أنت، يرجى التواصل مع مسؤول النظام.</p>
requiredAction.CONFIGURE_TOTP=إعداد خاصية رمز التحقق
requiredAction.terms_and_conditions=الأحكام والشروط
requiredAction.TERMS_AND_CONDITIONS=الأحكام والشروط
requiredAction.UPDATE_PASSWORD=تحديث كلمة المرور
requiredAction.UPDATE_PROFILE=تحديث الملف التعريفي
requiredAction.VERIFY_EMAIL=التحقق من البريد الإلكتروني

View File

@@ -28,7 +28,7 @@ eventUpdateTotpBody=V účtu {0} bylo změněno nastavení OTP z {1}. Pokud jste
eventUpdateTotpBodyHtml=<p>V účtu {0} bylo změněno nastavení OTP z {1}. Pokud jste to nebyli vy, kontaktujte administrátora.</p>
requiredAction.CONFIGURE_TOTP=Konfigurace OTP
requiredAction.terms_and_conditions=Smluvní podmínky
requiredAction.TERMS_AND_CONDITIONS=Smluvní podmínky
requiredAction.UPDATE_PASSWORD=Aktualizace hesla
requiredAction.UPDATE_PROFILE=Aktualizace profilu
requiredAction.VERIFY_EMAIL=Ověření e-mailu

View File

@@ -28,7 +28,7 @@ eventUpdateTotpBody=OTP blev opdateret på din konto d. {0} fra {1}. Hvis dette
eventUpdateTotpBodyHtml=<p>OTP blev opdateret på din konto d. {0} fra {1}. Hvis dette ikke var dig, bedes du kontakte din administrator omgående.</p>
requiredAction.CONFIGURE_TOTP=Konfigurer OTP
requiredAction.terms_and_conditions=Vilkår og Betingelser
requiredAction.TERMS_AND_CONDITIONS=Vilkår og Betingelser
requiredAction.UPDATE_PASSWORD=Opdater Adgangskode
requiredAction.UPDATE_PROFILE=Opdater Profil
requiredAction.VERIFY_EMAIL=Verificer Email

View File

@@ -27,7 +27,7 @@ eventUpdateTotpBody=OTP wurde am {0} von {1} ge\u00E4ndert. Falls das nicht Sie
eventUpdateTotpBodyHtml=<p>OTP wurde am {0} von {1} ge\u00E4ndert. Falls das nicht Sie waren, dann kontaktieren Sie bitte Ihren Admin.</p>
requiredAction.CONFIGURE_TOTP=Mehrfachauthentifizierung konfigurieren
requiredAction.terms_and_conditions=Bedingungen und Konditionen
requiredAction.TERMS_AND_CONDITIONS=Bedingungen und Konditionen
requiredAction.UPDATE_PASSWORD=Passwort aktualisieren
requiredAction.UPDATE_PROFILE=Profil aktualisieren
requiredAction.VERIFY_EMAIL=E-Mail-Adresse verifizieren

View File

@@ -27,7 +27,7 @@ eventUpdateTotpSubject=Päivitä OTP
eventUpdateTotpBody=OTP on päivitetty tilillesi {0} osoitteesta {1}. Jos et itse tehnyt tätä, ota yhteyttä järjestelmänvalvojaan.
eventUpdateTotpBodyHtml=<p>OTP on päivitetty tilillesi {0} osoitteesta {1}. Jos et itse tehnyt tätä, ota yhteyttä järjestelmänvalvojaan.</p>
requiredAction.CONFIGURE_TOTP=Konfiguroi OTP
requiredAction.terms_and_conditions=Käyttöehdot
requiredAction.TERMS_AND_CONDITIONS=Käyttöehdot
requiredAction.UPDATE_PASSWORD=Päivitä salasana
requiredAction.UPDATE_PROFILE=Päivitä profiili
requiredAction.VERIFY_EMAIL=Vahvista sähköposti

View File

@@ -27,7 +27,7 @@ eventUpdateTotpBody=Le OTP a \u00e9t\u00e9 mis \u00e0 jour pour votre compte {0}
eventUpdateTotpBodyHtml=<p>Le OTP a \u00e9t\u00e9 mis \u00e0 jour pour votre compte {0} depuis {1}. Si vous n''\u00e9tiez pas \u00e0 l''origine de cette requ\u00eate, veuillez contacter votre administrateur.</p>
requiredAction.CONFIGURE_TOTP=Configurer un OTP
requiredAction.terms_and_conditions=Conditions g\u00e9n\u00e9rale d''utilisation
requiredAction.TERMS_AND_CONDITIONS=Conditions g\u00e9n\u00e9rale d''utilisation
requiredAction.UPDATE_PASSWORD=Mise \u00e0 jour du mot de passe
requiredAction.UPDATE_PROFILE=Mise \u00e0 jour du profile
requiredAction.VERIFY_EMAIL=V\u00e9rification de l''adresse courriel

View File

@@ -28,7 +28,7 @@ eventUpdateTotpBody=Az egyszer használatos jelszó (OTP) beállításait {0} id
eventUpdateTotpBodyHtml=<p>Az egyszer használatos jelszó (OTP) beállításait {0} időpontban a(z) {1} címről érkező kérés értelmében módosítottuk a fiókján. Kérem haladéktalanul lépjen kapcsolatba az alkalmazás adminisztrátorral amennyiben nem ön igényelte az OTP beállítások módosítását.</p>
requiredAction.CONFIGURE_TOTP=Egyszer használatos jelszó (OTP) beállítása
requiredAction.terms_and_conditions=Felhasználási feltételek
requiredAction.TERMS_AND_CONDITIONS=Felhasználási feltételek
requiredAction.UPDATE_PASSWORD=Jelszó csere
requiredAction.UPDATE_PROFILE=Fiók adatok módosítása
requiredAction.VERIFY_EMAIL=Email cím megerősítése

View File

@@ -27,7 +27,7 @@ eventUpdateTotpBody=La OTP (password temporanea valida una volta sola) \u00e8 st
eventUpdateTotpBodyHtml=<p>La OTP (password temporanea valida una volta sola) \u00e8 stata aggiornata per il tuo account il {0} da {1}. Se non sei stato tu, per favore contatta l''amministratore.</p>
requiredAction.CONFIGURE_TOTP=Configurazione OTP
requiredAction.terms_and_conditions=Termini e condizioni
requiredAction.TERMS_AND_CONDITIONS=Termini e condizioni
requiredAction.UPDATE_PASSWORD=Aggiornamento password
requiredAction.UPDATE_PROFILE=Aggiornamento profilo
requiredAction.VERIFY_EMAIL=Verifica dell''indirizzo email

View File

@@ -28,7 +28,7 @@ eventUpdateTotpBody={0}に{1}からの操作でOTPが更新されました。心
eventUpdateTotpBodyHtml=<p>{0}に{1}からの操作でOTPが更新されました。心当たりがない場合は、管理者に連絡してください。</p>
requiredAction.CONFIGURE_TOTP=OTPの設定
requiredAction.terms_and_conditions=利用規約
requiredAction.TERMS_AND_CONDITIONS=利用規約
requiredAction.UPDATE_PASSWORD=パスワードの更新
requiredAction.UPDATE_PROFILE=プロファイルの更新
requiredAction.VERIFY_EMAIL=Eメールの確認

View File

@@ -28,7 +28,7 @@ eventUpdateTotpBody=Hasło jednorazowe (OTP) zostało zaktualizowane na Twoim ko
eventUpdateTotpBodyHtml=<p>Hasło jednorazowe (OTP) zostało zaktualizowane na Twoim koncie {0} z {1}. Jeśli to nie Ty, skontaktuj się z administratorem.</p>
requiredAction.CONFIGURE_TOTP=Konfiguracja hasła jednorazowego (OTP)
requiredAction.terms_and_conditions=Regulamin
requiredAction.TERMS_AND_CONDITIONS=Regulamin
requiredAction.UPDATE_PASSWORD=Aktualizacja hasła
requiredAction.UPDATE_PROFILE=Aktualizacja profilu
requiredAction.VERIFY_EMAIL=Weryfikacja adresu e-mail

View File

@@ -27,7 +27,7 @@ eventUpdateTotpBody=A autentica\u00e7\u00e3o de dois fatores foi atualizada para
eventUpdateTotpBodyHtml=<p>A autentica\u00e7\u00e3o de dois fatores foi atualizada para a sua conta em {0} de {1}. Se n\u00E3o foi voc\u00EA, por favor, entre em contato com um administrador.</p>
requiredAction.CONFIGURE_TOTP=Configurar Autentica\u00e7\u00e3o de Dois Fatores
requiredAction.terms_and_conditions=Termos e Condi\u00E7\u00F5es
requiredAction.TERMS_AND_CONDITIONS=Termos e Condi\u00E7\u00F5es
requiredAction.UPDATE_PASSWORD=Atualizar Senha
requiredAction.UPDATE_PROFILE=Atualizar Perfil
requiredAction.VERIFY_EMAIL=Verificar Endere\u00e7o de E-mail

View File

@@ -28,7 +28,7 @@ eventUpdateTotpBody=TOTP bol aktualizovaný pre váš účet na {0} z {1}. Ak st
eventUpdateTotpBodyHtml=<p>TOTP bol aktualizovaný pre váš účet dňa {0} z {1}. Ak ste to neboli vy, kontaktujte administrátora.</p>
requiredAction.CONFIGURE_TOTP=Konfigurácia OTP
requiredAction.terms_and_conditions=Zmluvné podmienky
requiredAction.TERMS_AND_CONDITIONS=Zmluvné podmienky
requiredAction.UPDATE_PASSWORD=Aktualizovať heslo
requiredAction.UPDATE_PROFILE=Aktualizovať profil
requiredAction.VERIFY_EMAIL=Overiť e-mail

View File

@@ -27,7 +27,7 @@ eventUpdateTotpBody=OTP, {0} tarihinden {1} tarihinde hesab\u0131n\u0131z i\u00E
eventUpdateTotpBodyHtml=<p>OTP, {0} tarihinden {1} tarihinde hesab\u0131n\u0131z i\u00E7in g\u00FCncellendi. Bu siz de\u011Filseniz, l\u00FCtfen y\u00F6neticiyle ileti\u015Fime ge\u00E7in.</p>
requiredAction.CONFIGURE_TOTP=OTP''yi yap\u0131land\u0131r
requiredAction.terms_and_conditions=\u015Eartlar ve Ko\u015Fullar
requiredAction.TERMS_AND_CONDITIONS=\u015Eartlar ve Ko\u015Fullar
requiredAction.UPDATE_PASSWORD=\u015Eifre G\u00FCncelleme
requiredAction.UPDATE_PROFILE=Profilleri g\u00FCncelle
requiredAction.VERIFY_EMAIL=E-mail do\u011Frula

View File

@@ -390,7 +390,7 @@ proceedWithAction=&laquo; انقر هنا للمتابعة
acrNotFulfilled=لم يتم استيفاء متطلبات المصادقة
requiredAction.CONFIGURE_TOTP=إعداد خاصية رمز التحقق
requiredAction.terms_and_conditions=الأحكام والشروط
requiredAction.TERMS_AND_CONDITIONS=الأحكام والشروط
requiredAction.UPDATE_PASSWORD=تحديث كلمة المرور
requiredAction.UPDATE_PROFILE=تحديث الملف التعريفي
requiredAction.VERIFY_EMAIL=التحقق من البريد الإلكتروني

View File

@@ -336,7 +336,7 @@ brokerLinkingSessionExpired=Požadované propojení účtu brokerů, ale aktuál
proceedWithAction=&raquo; Klikněte zde pro pokračování
requiredAction.CONFIGURE_TOTP=Konfigurovat OTP
requiredAction.terms_and_conditions=Smluvní podmínky
requiredAction.TERMS_AND_CONDITIONS=Smluvní podmínky
requiredAction.UPDATE_PASSWORD=Aktualizace hesla
requiredAction.UPDATE_PROFILE=Aktualizovat profil
requiredAction.VERIFY_EMAIL=Ověřit e-mail

View File

@@ -287,7 +287,7 @@ brokerLinkingSessionExpired=Har forespørgt kobling mellem mæglerkonti, men den
proceedWithAction=&raquo; Tryk her for at fortsætte
requiredAction.CONFIGURE_TOTP=Konfigurer OTP
requiredAction.terms_and_conditions=Vilkår og betingelser
requiredAction.TERMS_AND_CONDITIONS=Vilkår og betingelser
requiredAction.UPDATE_PASSWORD=Opdater Adgangskode
requiredAction.UPDATE_PROFILE=Opdater Profil
requiredAction.VERIFY_EMAIL=Verificer email adresse

View File

@@ -303,7 +303,7 @@ brokerLinkingSessionExpired=Broker Account Linking angefordert; Ihre Session ist
proceedWithAction=&raquo; Klicken Sie hier um fortzufahren
requiredAction.CONFIGURE_TOTP=Mehrfachauthentifizierung konfigurieren
requiredAction.terms_and_conditions=Bedingungen und Konditionen
requiredAction.TERMS_AND_CONDITIONS=Bedingungen und Konditionen
requiredAction.UPDATE_PASSWORD=Passwort aktualisieren
requiredAction.UPDATE_PROFILE=Profil aktualisieren
requiredAction.VERIFY_EMAIL=E-Mail-Adresse verifizieren

View File

@@ -359,7 +359,7 @@ brokerLinkingSessionExpired=Pyysit tilin yhdistämistä mutta sessio on vanhentu
proceedWithAction=&raquo; Klikkaa tästä jatkaaksesi
requiredAction.CONFIGURE_TOTP=Konfiguroi OTP
requiredAction.terms_and_conditions=Käyttöehdot
requiredAction.TERMS_AND_CONDITIONS=Käyttöehdot
requiredAction.UPDATE_PASSWORD=Päivitä salasana
requiredAction.UPDATE_PROFILE=Päivitä profiili
requiredAction.VERIFY_EMAIL=Vahvista sähköposti

View File

@@ -353,7 +353,7 @@ proceedWithAction=&raquo; Cliquez ici
requiredAction.CONFIGURE_TOTP=Configurer OTP
requiredAction.terms_and_conditions=Termes et conditions
requiredAction.TERMS_AND_CONDITIONS=Termes et conditions
requiredAction.UPDATE_PASSWORD=Mettre \u00e0 jour votre mot de passe
requiredAction.UPDATE_PROFILE=Mettre \u00e0 jour votre profil
requiredAction.VERIFY_EMAIL=Valider votre adresse email

View File

@@ -288,7 +288,7 @@ brokerLinkingSessionExpired=Ügynök fiók összekötést kezdeményezett, de az
proceedWithAction=&raquo; Kattintson ide a folytatáshoz
requiredAction.CONFIGURE_TOTP=Egyszer használatos jelszó (OTP) beállítása
requiredAction.terms_and_conditions=Felhasználási feltételek
requiredAction.TERMS_AND_CONDITIONS=Felhasználási feltételek
requiredAction.UPDATE_PASSWORD=Jelszó csere
requiredAction.UPDATE_PROFILE=Fiók adatok módosítása
requiredAction.VERIFY_EMAIL=Email cím megerősítése

View File

@@ -287,7 +287,7 @@ brokerLinkingSessionExpired=\u00c8 stato richiesta un''associazione a un account
proceedWithAction=&raquo; Clicca qui per continuare
requiredAction.CONFIGURE_TOTP=Configura OTP
requiredAction.terms_and_conditions=Termini e condizioni
requiredAction.TERMS_AND_CONDITIONS=Termini e condizioni
requiredAction.UPDATE_PASSWORD=Aggiornamento password
requiredAction.UPDATE_PROFILE=Aggiornamento profilo
requiredAction.VERIFY_EMAIL=Verifica dell''indirizzo email

View File

@@ -288,7 +288,7 @@ brokerLinkingSessionExpired=要求されたブローカー・アカウントの
proceedWithAction=&raquo; 続行するにはここをクリックしてください
requiredAction.CONFIGURE_TOTP=OTPの設定
requiredAction.terms_and_conditions=利用規約
requiredAction.TERMS_AND_CONDITIONS=利用規約
requiredAction.UPDATE_PASSWORD=パスワードの更新
requiredAction.UPDATE_PROFILE=プロファイルの更新
requiredAction.VERIFY_EMAIL=Eメールの確認

View File

@@ -234,7 +234,7 @@ differentUserAuthenticated=Jūs jau esat pieslēdzies ar citu lietotāju ''{0}''
proceedWithAction=» Spiediet šeit lai turpinātu
requiredAction.CONFIGURE_TOTP=Konfigurēt OTP
requiredAction.terms_and_conditions=Noteikumi un nosacījumi
requiredAction.TERMS_AND_CONDITIONS=Noteikumi un nosacījumi
requiredAction.UPDATE_PASSWORD=Atjaunot paroli
requiredAction.UPDATE_PROFILE=Atjaunot profilu
requiredAction.VERIFY_EMAIL=Apstiprināt e-pastu

View File

@@ -278,7 +278,7 @@ brokerLinkingSessionExpired=Broker account linking aangevraagd, maar de huidige
proceedWithAction=&raquo; Klik hier om verder te gaan
requiredAction.CONFIGURE_TOTP=Configureer OTP
requiredAction.terms_and_conditions=Voorwaarden
requiredAction.TERMS_AND_CONDITIONS=Voorwaarden
requiredAction.UPDATE_PASSWORD=Update wachtwoord
requiredAction.UPDATE_PROFILE=Update profiel
requiredAction.VERIFY_EMAIL=Verifieer e-mail

View File

@@ -291,7 +291,7 @@ brokerLinkingSessionExpired=Żądano łączenia kont brokera, ale bieżąca sesj
proceedWithAction=&raquo; kliknij tutaj, aby przejść
requiredAction.CONFIGURE_TOTP=Skonfiguruj OTP
requiredAction.terms_and_conditions=Regulamin
requiredAction.TERMS_AND_CONDITIONS=Regulamin
requiredAction.UPDATE_PASSWORD=Zaktualizuj hasło
requiredAction.UPDATE_PROFILE=Zaktualizuj profil
requiredAction.VERIFY_EMAIL=Zweryfikuj adres e-mail

View File

@@ -300,7 +300,7 @@ brokerLinkingSessionExpired=A vincul\u00e7\u00e3o de conta do provedor de identi
proceedWithAction=&raquo; Clique aqui para continuar
requiredAction.CONFIGURE_TOTP=Configurar Autentica\u00e7\u00e3o de Dois Fatores
requiredAction.terms_and_conditions=Termos e Condi\u00E7\u00F5es
requiredAction.TERMS_AND_CONDITIONS=Termos e Condi\u00E7\u00F5es
requiredAction.UPDATE_PASSWORD=Atualizar Senha
requiredAction.UPDATE_PROFILE=Atualizar Perfil
requiredAction.VERIFY_EMAIL=Verificar Endere\u00e7o de E-mail

View File

@@ -250,7 +250,7 @@ brokerLinkingSessionExpired=Požadované prepojenie s účtom brokera, ale aktu
proceedWithAction=&raquo; Ak chcete pokračovať, kliknite sem
requiredAction.CONFIGURE_TOTP=Konfigurácia OTP
requiredAction.terms_and_conditions=Zmluvné podmienky
requiredAction.TERMS_AND_CONDITIONS=Zmluvné podmienky
requiredAction.UPDATE_PASSWORD=Aktualizovať heslo
requiredAction.UPDATE_PROFILE=Aktualizovať profil
requiredAction.VERIFY_EMAIL=Overiť e-mail

View File

@@ -269,7 +269,7 @@ brokerLinkingSessionExpired=\u0130stenen broker hesab\u0131 ba\u011Flan\u0131yor
proceedWithAction=&raquo; Devam etmek i\u00E7in buraya t\u0131klay\u0131n
requiredAction.CONFIGURE_TOTP=OTP Ayarla
requiredAction.terms_and_conditions=\u015Eartlar ve Ko\u015Fullar
requiredAction.TERMS_AND_CONDITIONS=\u015Eartlar ve Ko\u015Fullar
requiredAction.UPDATE_PASSWORD=\u015Eifre g\u00FCncelle
requiredAction.UPDATE_PROFILE=Profili G\u00FCncelle
requiredAction.VERIFY_EMAIL=E-mail''i do\u011Frula

View File

@@ -30,7 +30,7 @@ eventUpdateTotpBody=OTP was updated for your account on {0} from {1}. If this wa
eventUpdateTotpBodyHtml=<p>OTP was updated for your account on {0} from {1}. If this was not you, please contact an administrator.</p>
requiredAction.CONFIGURE_TOTP=Configure OTP
requiredAction.terms_and_conditions=Terms and Conditions
requiredAction.TERMS_AND_CONDITIONS=Terms and Conditions
requiredAction.UPDATE_PASSWORD=Update Password
requiredAction.UPDATE_PROFILE=Update Profile
requiredAction.VERIFY_EMAIL=Verify Email

View File

@@ -388,7 +388,7 @@ proceedWithAction=&raquo; Click here to proceed
acrNotFulfilled=Authentication requirements not fulfilled
requiredAction.CONFIGURE_TOTP=Configure OTP
requiredAction.terms_and_conditions=Terms and Conditions
requiredAction.TERMS_AND_CONDITIONS=Terms and Conditions
requiredAction.UPDATE_PASSWORD=Update Password
requiredAction.UPDATE_PROFILE=Update Profile
requiredAction.VERIFY_EMAIL=Verify Email