Change the way to enable 2FA

And add a step to validate a generated code from the OTP app
This commit is contained in:
Jeremy Benoist 2019-01-18 22:46:44 +01:00
parent 4c0e747940
commit a0c5eb003f
No known key found for this signature in database
GPG key ID: BCA73962457ACC3C
20 changed files with 620 additions and 293 deletions

View file

@ -81,28 +81,7 @@ class ConfigController extends Controller
]); ]);
$userForm->handleRequest($request); $userForm->handleRequest($request);
// `googleTwoFactor` isn't a field within the User entity, we need to define it's value in a different way
if ($this->getParameter('twofactor_auth') && true === $user->isGoogleAuthenticatorEnabled() && false === $userForm->isSubmitted()) {
$userForm->get('googleTwoFactor')->setData(true);
}
if ($userForm->isSubmitted() && $userForm->isValid()) { if ($userForm->isSubmitted() && $userForm->isValid()) {
// handle creation / reset of the OTP secret if checkbox changed from the previous state
if ($this->getParameter('twofactor_auth')) {
if (true === $userForm->get('googleTwoFactor')->getData() && false === $user->isGoogleAuthenticatorEnabled()) {
$secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret();
$user->setGoogleAuthenticatorSecret($secret);
$user->setEmailTwoFactor(false);
$user->setBackupCodes((new BackupCodes())->toArray());
$this->addFlash('OtpQrCode', $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user));
} elseif (false === $userForm->get('googleTwoFactor')->getData() && true === $user->isGoogleAuthenticatorEnabled()) {
$user->setGoogleAuthenticatorSecret(null);
$user->setBackupCodes(null);
}
}
$userManager->updateUser($user, true); $userManager->updateUser($user, true);
$this->addFlash( $this->addFlash(
@ -175,11 +154,118 @@ class ConfigController extends Controller
], ],
'twofactor_auth' => $this->getParameter('twofactor_auth'), 'twofactor_auth' => $this->getParameter('twofactor_auth'),
'wallabag_url' => $this->getParameter('domain_name'), 'wallabag_url' => $this->getParameter('domain_name'),
'enabled_users' => $this->get('wallabag_user.user_repository') 'enabled_users' => $this->get('wallabag_user.user_repository')->getSumEnabledUsers(),
->getSumEnabledUsers(),
]); ]);
} }
/**
* Enable 2FA using email.
*
* @param Request $request
*
* @Route("/config/otp/email", name="config_otp_email")
*/
public function otpEmailAction(Request $request)
{
if (!$this->getParameter('twofactor_auth')) {
return $this->createNotFoundException('two_factor not enabled');
}
$user = $this->getUser();
$user->setGoogleAuthenticatorSecret(null);
$user->setBackupCodes(null);
$user->setEmailTwoFactor(true);
$this->container->get('fos_user.user_manager')->updateUser($user, true);
$this->addFlash(
'notice',
'flashes.config.notice.otp_enabled'
);
return $this->redirect($this->generateUrl('config') . '#set3');
}
/**
* Enable 2FA using OTP app, user will need to confirm the generated code from the app.
*
* @Route("/config/otp/app", name="config_otp_app")
*/
public function otpAppAction()
{
if (!$this->getParameter('twofactor_auth')) {
return $this->createNotFoundException('two_factor not enabled');
}
$user = $this->getUser();
if (!$user->isGoogleTwoFactor()) {
$secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret();
$user->setGoogleAuthenticatorSecret($secret);
$user->setEmailTwoFactor(false);
$user->setBackupCodes((new BackupCodes())->toArray());
$this->container->get('fos_user.user_manager')->updateUser($user, true);
}
return $this->render('WallabagCoreBundle:Config:otp_app.html.twig', [
'qr_code' => $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user),
]);
}
/**
* Cancelling 2FA using OTP app.
*
* @Route("/config/otp/app/cancel", name="config_otp_app_cancel")
*/
public function otpAppCancelAction()
{
if (!$this->getParameter('twofactor_auth')) {
return $this->createNotFoundException('two_factor not enabled');
}
$user = $this->getUser();
$user->setGoogleAuthenticatorSecret(null);
$user->setBackupCodes(null);
$this->container->get('fos_user.user_manager')->updateUser($user, true);
return $this->redirect($this->generateUrl('config') . '#set3');
}
/**
* Validate OTP code.
*
* @param Request $request
*
* @Route("/config/otp/app/check", name="config_otp_app_check")
*/
public function otpAppCheckAction(Request $request)
{
$isValid = $this->get('scheb_two_factor.security.google_authenticator')->checkCode(
$this->getUser(),
$request->get('_auth_code')
);
if (true === $isValid) {
$this->addFlash(
'notice',
'flashes.config.notice.otp_enabled'
);
return $this->redirect($this->generateUrl('config') . '#set3');
}
$this->addFlash(
'two_factor',
'scheb_two_factor.code_invalid'
);
return $this->redirect($this->generateUrl('config_otp_app'));
}
/** /**
* @param Request $request * @param Request $request
* *

View file

@ -102,12 +102,16 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Navn' name_label: 'Navn'
email_label: 'Emailadresse' email_label: 'Emailadresse'
# emailTwoFactor_label: 'Using email (receive a code by email)' two_factor:
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_method: Method
# two_factor_code_description_3: 'Or use that code:' # table_state: State
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
# title: Delete my account (a.k.a danger zone) # title: Delete my account (a.k.a danger zone)
# description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +169,15 @@ config:
# and: 'One rule AND another' # and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry: entry:
# default_title: 'Title of the entry' # default_title: 'Title of the entry'

View file

@ -102,12 +102,16 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Name' name_label: 'Name'
email_label: 'E-Mail-Adresse' email_label: 'E-Mail-Adresse'
# emailTwoFactor_label: 'Using email (receive a code by email)' two_factor:
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_method: Method
# two_factor_code_description_3: 'Or use that code:' # table_state: State
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
title: 'Lösche mein Konto (a.k.a Gefahrenzone)' title: 'Lösche mein Konto (a.k.a Gefahrenzone)'
description: 'Wenn du dein Konto löschst, werden ALL deine Artikel, ALL deine Tags, ALL deine Anmerkungen und dein Konto dauerhaft gelöscht (kann NICHT RÜCKGÄNGIG gemacht werden). Du wirst anschließend ausgeloggt.' description: 'Wenn du dein Konto löschst, werden ALL deine Artikel, ALL deine Tags, ALL deine Anmerkungen und dein Konto dauerhaft gelöscht (kann NICHT RÜCKGÄNGIG gemacht werden). Du wirst anschließend ausgeloggt.'

View file

@ -102,12 +102,16 @@ config:
two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Name' name_label: 'Name'
email_label: 'Email' email_label: 'Email'
emailTwoFactor_label: 'Using email (receive a code by email)' two_factor:
googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' emailTwoFactor_label: 'Using email (receive a code by email)'
two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
two_factor_code_description_2: 'You can scan that QR Code with your app:' table_method: Method
two_factor_code_description_3: 'Or use that code:' table_state: State
two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' table_action: Action
state_enabled: Enabled
state_disabled: Disabled
action_email: Use email
action_app: Use OTP App
delete: delete:
title: Delete my account (a.k.a danger zone) title: Delete my account (a.k.a danger zone)
description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +169,15 @@ config:
and: 'One rule AND another' and: 'One rule AND another'
matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
page_title: Two-factor authentication
app:
two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
two_factor_code_description_2: 'You can scan that QR Code with your app:'
two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
two_factor_code_description_4: 'Test an OTP code from your configured app:'
cancel: Cancel
enable: Enable
entry: entry:
default_title: 'Title of the entry' default_title: 'Title of the entry'
@ -584,6 +597,7 @@ flashes:
tags_reset: Tags reset tags_reset: Tags reset
entries_reset: Entries reset entries_reset: Entries reset
archived_reset: Archived entries deleted archived_reset: Archived entries deleted
otp_enabled: Two-factor authentication enabled
entry: entry:
notice: notice:
entry_already_saved: 'Entry already saved on %date%' entry_already_saved: 'Entry already saved on %date%'

View file

@ -102,12 +102,16 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Nombre' name_label: 'Nombre'
email_label: 'Dirección de e-mail' email_label: 'Dirección de e-mail'
# emailTwoFactor_label: 'Using email (receive a code by email)' two_factor:
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_method: Method
# two_factor_code_description_3: 'Or use that code:' # table_state: State
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
title: Eliminar mi cuenta (Zona peligrosa) title: Eliminar mi cuenta (Zona peligrosa)
description: Si eliminas tu cuenta, TODOS tus artículos, TODAS tus etiquetas, TODAS tus anotaciones y tu cuenta serán eliminadas de forma PERMANENTE (no se puede deshacer). Después serás desconectado. description: Si eliminas tu cuenta, TODOS tus artículos, TODAS tus etiquetas, TODAS tus anotaciones y tu cuenta serán eliminadas de forma PERMANENTE (no se puede deshacer). Después serás desconectado.
@ -165,6 +169,15 @@ config:
and: 'Una regla Y la otra' and: 'Una regla Y la otra'
matches: 'Prueba si un <i>sujeto</i> corresponde a una <i>búsqueda</i> (insensible a mayusculas).<br />Ejemplo : <code>title matches "fútbol"</code>' matches: 'Prueba si un <i>sujeto</i> corresponde a una <i>búsqueda</i> (insensible a mayusculas).<br />Ejemplo : <code>title matches "fútbol"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry: entry:
default_title: 'Título del artículo' default_title: 'Título del artículo'

View file

@ -102,12 +102,16 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'نام' name_label: 'نام'
email_label: 'نشانی ایمیل' email_label: 'نشانی ایمیل'
# emailTwoFactor_label: 'Using email (receive a code by email)' two_factor:
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_method: Method
# two_factor_code_description_3: 'Or use that code:' # table_state: State
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
# title: Delete my account (a.k.a danger zone) # title: Delete my account (a.k.a danger zone)
# description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +169,15 @@ config:
# and: 'One rule AND another' # and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry: entry:
# default_title: 'Title of the entry' # default_title: 'Title of the entry'

View file

@ -102,12 +102,16 @@ config:
two_factor_description: "Activer lauthentification double-facteur veut dire que vous allez recevoir un code par courriel OU que vous devriez utiliser une application de mot de passe à usage unique (comme Google Authenticator, Authy or FreeOTP) pour obtenir un code temporaire à chaque nouvelle connexion non approuvée. Vous ne pouvez pas choisir les deux options." two_factor_description: "Activer lauthentification double-facteur veut dire que vous allez recevoir un code par courriel OU que vous devriez utiliser une application de mot de passe à usage unique (comme Google Authenticator, Authy or FreeOTP) pour obtenir un code temporaire à chaque nouvelle connexion non approuvée. Vous ne pouvez pas choisir les deux options."
name_label: "Nom" name_label: "Nom"
email_label: "Adresse courriel" email_label: "Adresse courriel"
emailTwoFactor_label: 'En utlisant lemail (recevez un code par email)' two_factor:
googleTwoFactor_label: 'En utilisant une application de mot de passe à usage unique (ouvrez lapp, comme Google Authenticator, Authy or FreeOTP, pour obtenir un mot de passe à usage unique)' emailTwoFactor_label: 'En utlisant lemail (recevez un code par email)'
two_factor_code_description_1: Vous venez dactiver lauthentification double-facteur, ouvrez votre application OTP pour configurer la génération du mot de passe à usage unique. Ces informations disparaîtront après un rechargement de la page. googleTwoFactor_label: 'En utilisant une application de mot de passe à usage unique (ouvrez lapp, comme Google Authenticator, Authy or FreeOTP, pour obtenir un mot de passe à usage unique)'
two_factor_code_description_2: 'Vous pouvez scanner le QR code avec votre application :' table_method: Méthode
two_factor_code_description_3: 'Ou utiliser le code suivant :' table_state: État
two_factor_code_description_4: 'Noubliez pas de sauvegarder ces codes de secours dans un endroit sûr, vous pourrez les utiliser si vous ne pouvez plus accéder à votre application OTP :' table_action: Action
state_enabled: Activé
state_disabled: Désactivé
action_email: Utiliser l'email
action_app: Utiliser une app OTP
delete: delete:
title: "Supprimer mon compte (attention danger !)" title: "Supprimer mon compte (attention danger !)"
description: "Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (cest IRRÉVERSIBLE). Vous serez ensuite déconnecté." description: "Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (cest IRRÉVERSIBLE). Vous serez ensuite déconnecté."
@ -165,6 +169,15 @@ config:
and: "Une règle ET lautre" and: "Une règle ET lautre"
matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>" matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>"
notmatches: "Teste si un <i>sujet</i> ne correspond pas à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title notmatches \"football\"</code>" notmatches: "Teste si un <i>sujet</i> ne correspond pas à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title notmatches \"football\"</code>"
otp:
page_title: Authentification double-facteur
app:
two_factor_code_description_1: Vous venez dactiver lauthentification double-facteur, ouvrez votre application OTP pour configurer la génération du mot de passe à usage unique. Ces informations disparaîtront après un rechargement de la page.
two_factor_code_description_2: 'Vous pouvez scanner le QR code avec votre application :'
two_factor_code_description_3: 'Noubliez pas de sauvegarder ces codes de secours dans un endroit sûr, vous pourrez les utiliser si vous ne pouvez plus accéder à votre application OTP :'
two_factor_code_description_4: 'Testez un code généré par votre application OTP :'
cancel: Annuler
enable: Activer
entry: entry:
default_title: "Titre de larticle" default_title: "Titre de larticle"
@ -585,6 +598,7 @@ flashes:
tags_reset: "Tags supprimés" tags_reset: "Tags supprimés"
entries_reset: "Articles supprimés" entries_reset: "Articles supprimés"
archived_reset: "Articles archivés supprimés" archived_reset: "Articles archivés supprimés"
otp_enabled: "Authentification à double-facteur activée"
entry: entry:
notice: notice:
entry_already_saved: "Article déjà sauvegardé le %date%" entry_already_saved: "Article déjà sauvegardé le %date%"

View file

@ -102,12 +102,15 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Nome' name_label: 'Nome'
email_label: 'E-mail' email_label: 'E-mail'
# emailTwoFactor_label: 'Using email (receive a code by email)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # table_method: Method
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_state: State
# two_factor_code_description_3: 'Or use that code:' # table_action: Action
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
title: Cancella il mio account (zona pericolosa) title: Cancella il mio account (zona pericolosa)
description: Rimuovendo il tuo account, TUTTI i tuoi articoli, TUTTE le tue etichette, TUTTE le tue annotazioni ed il tuo account verranno rimossi PERMANENTEMENTE (impossibile da ANNULLARE). Verrai poi disconnesso. description: Rimuovendo il tuo account, TUTTI i tuoi articoli, TUTTE le tue etichette, TUTTE le tue annotazioni ed il tuo account verranno rimossi PERMANENTEMENTE (impossibile da ANNULLARE). Verrai poi disconnesso.
@ -165,6 +168,15 @@ config:
and: "Una regola E un'altra" and: "Una regola E un'altra"
matches: 'Verifica che un <i>oggetto</i> risulti in una <i>ricerca</i> (case-insensitive).<br />Esempio: <code>titolo contiene "football"</code>' matches: 'Verifica che un <i>oggetto</i> risulti in una <i>ricerca</i> (case-insensitive).<br />Esempio: <code>titolo contiene "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry: entry:
default_title: "Titolo del contenuto" default_title: "Titolo del contenuto"

View file

@ -102,12 +102,15 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Nom' name_label: 'Nom'
email_label: 'Adreça de corrièl' email_label: 'Adreça de corrièl'
# emailTwoFactor_label: 'Using email (receive a code by email)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # table_method: Method
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_state: State
# two_factor_code_description_3: 'Or use that code:' # table_action: Action
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
title: Suprimir mon compte (Mèfi zòna perilhosa) title: Suprimir mon compte (Mèfi zòna perilhosa)
description: Se confirmatz la supression de vòstre compte, TOTES vòstres articles, TOTAS vòstras etiquetas, TOTAS vòstras anotacions e vòstre compte seràn suprimits per totjorn. E aquò es IRREVERSIBLE. Puèi seretz desconnectat. description: Se confirmatz la supression de vòstre compte, TOTES vòstres articles, TOTAS vòstras etiquetas, TOTAS vòstras anotacions e vòstre compte seràn suprimits per totjorn. E aquò es IRREVERSIBLE. Puèi seretz desconnectat.
@ -165,6 +168,15 @@ config:
and: "Una règla E l'autra" and: "Una règla E l'autra"
matches: 'Teste se un <i>subjècte</i> correspond a una <i>recèrca</i> (non sensibla a la cassa).<br />Exemple:<code>title matches \"football\"</code>' matches: 'Teste se un <i>subjècte</i> correspond a una <i>recèrca</i> (non sensibla a la cassa).<br />Exemple:<code>title matches \"football\"</code>'
notmatches: 'Teste se <i>subjècte</i> correspond pas a una <i>recèrca</i> (sensibla a la cassa).<br />Example:<code>title notmatches "football"</code>' notmatches: 'Teste se <i>subjècte</i> correspond pas a una <i>recèrca</i> (sensibla a la cassa).<br />Example:<code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry: entry:
default_title: "Títol de l'article" default_title: "Títol de l'article"

View file

@ -99,15 +99,18 @@ config:
all: 'Wszystkie' all: 'Wszystkie'
rss_limit: 'Link do RSS' rss_limit: 'Link do RSS'
form_user: form_user:
two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Nazwa' name_label: 'Nazwa'
email_label: 'Adres email' email_label: 'Adres email'
# emailTwoFactor_label: 'Using email (receive a code by email)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # table_method: Method
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_state: State
# two_factor_code_description_3: 'Or use that code:' # table_action: Action
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
title: Usuń moje konto (niebezpieczna strefa !) title: Usuń moje konto (niebezpieczna strefa !)
description: Jeżeli usuniesz swoje konto, wszystkie twoje artykuły, tagi, adnotacje, oraz konto zostaną trwale usunięte (operacja jest NIEODWRACALNA). Następnie zostaniesz wylogowany. description: Jeżeli usuniesz swoje konto, wszystkie twoje artykuły, tagi, adnotacje, oraz konto zostaną trwale usunięte (operacja jest NIEODWRACALNA). Następnie zostaniesz wylogowany.
@ -165,6 +168,15 @@ config:
and: 'Jedna reguła I inna' and: 'Jedna reguła I inna'
matches: 'Sprawdź czy <i>temat</i> pasuje <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł zawiera "piłka nożna"</code>' matches: 'Sprawdź czy <i>temat</i> pasuje <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł zawiera "piłka nożna"</code>'
notmatches: 'Sprawdź czy <i>temat</i> nie zawiera <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł nie zawiera "piłka nożna"</code>' notmatches: 'Sprawdź czy <i>temat</i> nie zawiera <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł nie zawiera "piłka nożna"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry: entry:
default_title: 'Tytuł wpisu' default_title: 'Tytuł wpisu'

View file

@ -102,12 +102,15 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Nome' name_label: 'Nome'
email_label: 'E-mail' email_label: 'E-mail'
# emailTwoFactor_label: 'Using email (receive a code by email)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # table_method: Method
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_state: State
# two_factor_code_description_3: 'Or use that code:' # table_action: Action
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
# title: Delete my account (a.k.a danger zone) # title: Delete my account (a.k.a danger zone)
# description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +168,15 @@ config:
and: 'Uma regra E outra' and: 'Uma regra E outra'
matches: 'Testa que um <i>assunto</i> corresponde a uma <i>pesquisa</i> (maiúscula ou minúscula).<br />Exemplo: <code>título corresponde a "futebol"</code>' matches: 'Testa que um <i>assunto</i> corresponde a uma <i>pesquisa</i> (maiúscula ou minúscula).<br />Exemplo: <code>título corresponde a "futebol"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry: entry:
default_title: 'Título da entrada' default_title: 'Título da entrada'

View file

@ -102,12 +102,15 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Nume' name_label: 'Nume'
email_label: 'E-mail' email_label: 'E-mail'
# emailTwoFactor_label: 'Using email (receive a code by email)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # table_method: Method
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_state: State
# two_factor_code_description_3: 'Or use that code:' # table_action: Action
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
# title: Delete my account (a.k.a danger zone) # title: Delete my account (a.k.a danger zone)
# description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +168,15 @@ config:
# and: 'One rule AND another' # and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry: entry:
# default_title: 'Title of the entry' # default_title: 'Title of the entry'

View file

@ -99,12 +99,15 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Имя' name_label: 'Имя'
email_label: 'Email' email_label: 'Email'
# emailTwoFactor_label: 'Using email (receive a code by email)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # table_method: Method
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_state: State
# two_factor_code_description_3: 'Or use that code:' # table_action: Action
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
title: "Удалить мой аккаунт (или опасная зона)" title: "Удалить мой аккаунт (или опасная зона)"
description: "Если Вы удалите ваш аккаунт, ВСЕ ваши записи, теги и другие данные, будут БЕЗВОЗВРАТНО удалены (операция не может быть отменена после). Затем Вы выйдете из системы." description: "Если Вы удалите ваш аккаунт, ВСЕ ваши записи, теги и другие данные, будут БЕЗВОЗВРАТНО удалены (операция не может быть отменена после). Затем Вы выйдете из системы."
@ -160,6 +163,15 @@ config:
or: 'Одно правило ИЛИ другое' or: 'Одно правило ИЛИ другое'
and: 'Одно правило И другое' and: 'Одно правило И другое'
matches: 'Тесты, в которых <i> тема </i> соответствует <i> поиску </i> (без учета регистра). Пример: <code> title matches "футбол" </code>' matches: 'Тесты, в которых <i> тема </i> соответствует <i> поиску </i> (без учета регистра). Пример: <code> title matches "футбол" </code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry: entry:
default_title: 'Название записи' default_title: 'Название записи'

View file

@ -102,12 +102,15 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'ชื่อ' name_label: 'ชื่อ'
email_label: 'อีเมล' email_label: 'อีเมล'
# emailTwoFactor_label: 'Using email (receive a code by email)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # table_method: Method
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_state: State
# two_factor_code_description_3: 'Or use that code:' # table_action: Action
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
title: ลบบัญชีของฉัน (โซนที่เป็นภัย!) title: ลบบัญชีของฉัน (โซนที่เป็นภัย!)
description: ถ้าคุณลบบัญชีของคุณIf , รายการทั้งหมดของคุณ, แท็กทั้งหมดของคุณ, หมายเหตุทั้งหมดของคุณและบัญชีของคุณจะถูกลบอย่างถาวร (มันไม่สามารถยกเลิกได้) คุณจะต้องลงชื่อออก description: ถ้าคุณลบบัญชีของคุณIf , รายการทั้งหมดของคุณ, แท็กทั้งหมดของคุณ, หมายเหตุทั้งหมดของคุณและบัญชีของคุณจะถูกลบอย่างถาวร (มันไม่สามารถยกเลิกได้) คุณจะต้องลงชื่อออก
@ -165,6 +168,15 @@ config:
and: 'หนึ่งข้อบังคับและอื่นๆ' and: 'หนึ่งข้อบังคับและอื่นๆ'
matches: 'ทดสอบว่า <i>เรื่อง</i> นี้ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อที่ตรงกับ "football"</code>' matches: 'ทดสอบว่า <i>เรื่อง</i> นี้ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อที่ตรงกับ "football"</code>'
notmatches: 'ทดสอบว่า <i>เรื่อง</i> นี้ไม่ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อทีไม่ตรงกับ "football"</code>' notmatches: 'ทดสอบว่า <i>เรื่อง</i> นี้ไม่ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อทีไม่ตรงกับ "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry: entry:
default_title: 'หัวข้อรายการ' default_title: 'หัวข้อรายการ'

View file

@ -102,12 +102,15 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option." # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'İsim' name_label: 'İsim'
email_label: 'E-posta' email_label: 'E-posta'
# emailTwoFactor_label: 'Using email (receive a code by email)' # emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload. # table_method: Method
# two_factor_code_description_2: 'You can scan that QR Code with your app:' # table_state: State
# two_factor_code_description_3: 'Or use that code:' # table_action: Action
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:' # state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete: delete:
# title: Delete my account (a.k.a danger zone) # title: Delete my account (a.k.a danger zone)
# description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +168,15 @@ config:
and: 'Bir kural ve diğeri' and: 'Bir kural ve diğeri'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry: entry:
default_title: 'Makalenin başlığı' default_title: 'Makalenin başlığı'

View file

@ -168,48 +168,41 @@
</div> </div>
</fieldset> </fieldset>
{{ form_widget(form.user.save) }}
{% if twofactor_auth %} {% if twofactor_auth %}
<h5>{{ 'config.otp.page_title'|trans }}</h5>
<div class="row"> <div class="row">
{{ 'config.form_user.two_factor_description'|trans }} {{ 'config.form_user.two_factor_description'|trans }}
</div> </div>
<fieldset class="w500p inline"> <table>
<div class="row"> <thead>
{{ form_label(form.user.emailTwoFactor) }} <tr>
{{ form_errors(form.user.emailTwoFactor) }} <th>{{ 'config.form_user.two_factor.table_method'|trans }}</th>
{{ form_widget(form.user.emailTwoFactor) }} <th>{{ 'config.form_user.two_factor.table_state'|trans }}</th>
</div> <th>{{ 'config.form_user.two_factor.table_action'|trans }}</th>
<br/> </tr>
<div class="row"> </thead>
{{ form_label(form.user.googleTwoFactor) }}
{{ form_widget(form.user.googleTwoFactor) }} <tbody>
{{ form_errors(form.user.googleTwoFactor) }} <tr>
</div> <td>{{ 'config.form_user.two_factor.emailTwoFactor_label'|trans }}</td>
{% for OtpQrCode in app.session.flashbag.get('OtpQrCode') %} <td>{% if app.user.isEmailTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
<div class="row"> <td><a href="{{ path('config_otp_email') }}" class="waves-effect waves-light btn{% if app.user.isEmailTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_email'|trans }}</a></td>
{{ 'config.form_user.two_factor_code_description_1'|trans }} </tr>
<br/> <tr>
{{ 'config.form_user.two_factor_code_description_2'|trans }} <td>{{ 'config.form_user.two_factor.googleTwoFactor_label'|trans }}</td>
<br/><br/> <td>{% if app.user.isGoogleTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
<img id="2faQrcode" class="hide-on-med-and-down" /> <td><a href="{{ path('config_otp_app') }}" class="waves-effect waves-light btn{% if app.user.isGoogleTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_app'|trans }}</a></td>
<script> </tr>
document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ OtpQrCode }}'); </tbody>
</script> </table>
<br/><br/>
{{ 'config.form_user.two_factor_code_description_3'|trans }}
<br/><br/>
<strong>{{ app.user.getGoogleAuthenticatorSecret }}</strong>
<br/><br/>
{{ 'config.form_user.two_factor_code_description_4'|trans }}
<br/><br/>
<strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong>
</div>
{% endfor %}
</fieldset>
{% endif %} {% endif %}
{{ form_widget(form.user._token) }} {{ form_widget(form.user._token) }}
{{ form_widget(form.user.save) }}
</form> </form>
{% if enabled_users > 1 %} {% if enabled_users > 1 %}

View file

@ -0,0 +1,55 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{{ 'config.page_title'|trans }} > {{ 'config.otp.page_title'|trans }}{% endblock %}
{% block content %}
<h5>{{ 'config.otp.page_title'|trans }}</h5>
<ol>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_1'|trans }}</p>
<p>{{ 'config.otp.app.two_factor_code_description_2'|trans }}</p>
<p>
<img id="2faQrcode" class="hide-on-med-and-down" />
<script>
document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ qr_code }}');
</script>
</p>
</li>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p>
<p><strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong></p>
</li>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p>
{% for flashMessage in app.session.flashbag.get("two_factor") %}
<div class="card-panel red darken-1 black-text">
{{ flashMessage|trans }}
</div>
{% endfor %}
<form class="form" action="{{ path("config_otp_app_check") }}" method="post">
<div class="card-content">
<div class="row">
<div class="input-field col s12">
<label for="_auth_code">{{ "scheb_two_factor.auth_code"|trans }}</label>
<input id="_auth_code" type="text" autocomplete="off" name="_auth_code" />
</div>
</div>
</div>
<div class="card-action">
<a href="{{ path('config_otp_app_cancel') }}" class="waves-effect waves-light grey btn">
{{ 'config.otp.app.cancel'|trans }}
</a>
<button class="btn waves-effect waves-light" type="submit" name="send">
{{ 'config.otp.app.enable'|trans }}
<i class="material-icons right">send</i>
</button>
</div>
</form>
</li>
</ol>
{% endblock %}

View file

@ -196,45 +196,40 @@
</div> </div>
</div> </div>
{% if twofactor_auth %}
<div class="row">
{{ 'config.form_user.two_factor_description'|trans }}
<div class="input-field col s11">
{{ form_widget(form.user.emailTwoFactor) }}
{{ form_label(form.user.emailTwoFactor) }}
{{ form_errors(form.user.emailTwoFactor) }}
</div>
<div class="input-field col s11">
{{ form_widget(form.user.googleTwoFactor) }}
{{ form_label(form.user.googleTwoFactor) }}
{{ form_errors(form.user.googleTwoFactor) }}
</div>
</div>
{% for OtpQrCode in app.session.flashbag.get('OtpQrCode') %}
<div class="card-panel yellow darken-1 black-text">
{{ 'config.form_user.two_factor_code_description_1'|trans }}
<br/>
{{ 'config.form_user.two_factor_code_description_2'|trans }}
<br/><br/>
<img id="2faQrcode" class="hide-on-med-and-down" />
<script>
document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ OtpQrCode }}');
</script>
<br/><br/>
{{ 'config.form_user.two_factor_code_description_3'|trans }}
<br/><br/>
<strong>{{ app.user.getGoogleAuthenticatorSecret }}</strong>
<br/><br/>
{{ 'config.form_user.two_factor_code_description_4'|trans }}
<br/><br/>
<strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong>
</div>
{% endfor %}
{% endif %}
{{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} {{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
{% if twofactor_auth %}
<br/>
<br/>
<div class="row">
<h5>{{ 'config.otp.page_title'|trans }}</h5>
<p>{{ 'config.form_user.two_factor_description'|trans }}</p>
<table>
<thead>
<tr>
<th>{{ 'config.form_user.two_factor.table_method'|trans }}</th>
<th>{{ 'config.form_user.two_factor.table_state'|trans }}</th>
<th>{{ 'config.form_user.two_factor.table_action'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ 'config.form_user.two_factor.emailTwoFactor_label'|trans }}</td>
<td>{% if app.user.isEmailTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
<td><a href="{{ path('config_otp_email') }}" class="waves-effect waves-light btn{% if app.user.isEmailTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_email'|trans }}</a></td>
</tr>
<tr>
<td>{{ 'config.form_user.two_factor.googleTwoFactor_label'|trans }}</td>
<td>{% if app.user.isGoogleTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
<td><a href="{{ path('config_otp_app') }}" class="waves-effect waves-light btn{% if app.user.isGoogleTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_app'|trans }}</a></td>
</tr>
</tbody>
</table>
</div>
{% endif %}
{{ form_widget(form.user._token) }} {{ form_widget(form.user._token) }}
</form> </form>
</div> </div>

View file

@ -0,0 +1,63 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{{ 'config.page_title'|trans }} > {{ 'config.otp.page_title'|trans }}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel settings">
<div class="row">
<h5>{{ 'config.otp.page_title'|trans }}</h5>
<ol>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_1'|trans }}</p>
<p>{{ 'config.otp.app.two_factor_code_description_2'|trans }}</p>
<p>
<img id="2faQrcode" class="hide-on-med-and-down" />
<script>
document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ qr_code }}');
</script>
</p>
</li>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p>
<p><strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong></p>
</li>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p>
{% for flashMessage in app.session.flashbag.get("two_factor") %}
<div class="card-panel red darken-1 black-text">
{{ flashMessage|trans }}
</div>
{% endfor %}
<form class="form" action="{{ path("config_otp_app_check") }}" method="post">
<div class="card-content">
<div class="row">
<div class="input-field col s12">
<label for="_auth_code">{{ "scheb_two_factor.auth_code"|trans }}</label>
<input id="_auth_code" type="text" autocomplete="off" name="_auth_code" />
</div>
</div>
</div>
<div class="card-action">
<a href="{{ path('config_otp_app_cancel') }}" class="waves-effect waves-light grey btn">
{{ 'config.otp.app.cancel'|trans }}
</a>
<button class="btn waves-effect waves-light" type="submit" name="send">
{{ 'config.otp.app.enable'|trans }}
<i class="material-icons right">send</i>
</button>
</div>
</form>
</li>
</ol>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -297,119 +297,6 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertContains('flashes.config.notice.user_updated', $alert[0]); $this->assertContains('flashes.config.notice.user_updated', $alert[0]);
} }
public function testUserEnable2faEmail()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[id=update_user_save]')->form();
$data = [
'update_user[emailTwoFactor]' => '1',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
$this->assertContains('flashes.config.notice.user_updated', $alert[0]);
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isEmailTwoFactor());
$user->setEmailTwoFactor(false);
$em->persist($user);
$em->flush();
}
public function testUserEnable2faGoogle()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[id=update_user_save]')->form();
$data = [
'update_user[googleTwoFactor]' => '1',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
$this->assertContains('flashes.config.notice.user_updated', $alert[0]);
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isGoogleAuthenticatorEnabled());
$user->setGoogleAuthenticatorSecret(null);
$em->persist($user);
$em->flush();
}
public function testUserEnable2faBoth()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[id=update_user_save]')->form();
$data = [
'update_user[googleTwoFactor]' => '1',
'update_user[emailTwoFactor]' => '1',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
$this->assertContains('flashes.config.notice.user_updated', $alert[0]);
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isGoogleAuthenticatorEnabled());
$this->assertFalse($user->isEmailTwoFactor());
$user->setGoogleAuthenticatorSecret(null);
$em->persist($user);
$em->flush();
}
public function testRssUpdateResetToken() public function testRssUpdateResetToken()
{ {
$this->logInAs('admin'); $this->logInAs('admin');
@ -1113,4 +1000,85 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertNotSame('yuyuyuyu', $client->getRequest()->getLocale()); $this->assertNotSame('yuyuyuyu', $client->getRequest()->getLocale());
$this->assertNotSame('yuyuyuyu', $client->getContainer()->get('session')->get('_locale')); $this->assertNotSame('yuyuyuyu', $client->getContainer()->get('session')->get('_locale'));
} }
public function testUserEnable2faEmail()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config/otp/email');
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
$this->assertContains('flashes.config.notice.otp_enabled', $alert[0]);
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isEmailTwoFactor());
$user->setEmailTwoFactor(false);
$em->persist($user);
$em->flush();
}
public function testUserEnable2faGoogle()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config/otp/app');
$this->assertSame(200, $client->getResponse()->getStatusCode());
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isGoogleTwoFactor());
$this->assertGreaterThan(0, $user->getBackupCodes());
$user->setGoogleAuthenticatorSecret(false);
$user->setBackupCodes(null);
$em->persist($user);
$em->flush();
}
public function testUserEnable2faGoogleCancel()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config/otp/app');
$this->assertSame(200, $client->getResponse()->getStatusCode());
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isGoogleTwoFactor());
$this->assertGreaterThan(0, $user->getBackupCodes());
$crawler = $client->request('GET', '/config/otp/app/cancel');
$this->assertSame(302, $client->getResponse()->getStatusCode());
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertFalse($user->isGoogleTwoFactor());
$this->assertEmpty($user->getBackupCodes());
}
} }