aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJeremy Benoist <jeremy.benoist@gmail.com>2019-01-18 22:46:44 +0100
committerJeremy Benoist <jeremy.benoist@gmail.com>2019-01-23 13:28:24 +0100
commita0c5eb003f1cbeef10d5620e98870c7556e17c75 (patch)
tree52660ffe507ac294db3db387842eed43fad1c75a
parent4c0e747940ac39630f1d2a6a14c628ba6729ecfd (diff)
downloadwallabag-a0c5eb003f1cbeef10d5620e98870c7556e17c75.tar.gz
wallabag-a0c5eb003f1cbeef10d5620e98870c7556e17c75.tar.zst
wallabag-a0c5eb003f1cbeef10d5620e98870c7556e17c75.zip
Change the way to enable 2FA
And add a step to validate a generated code from the OTP app
-rw-r--r--src/Wallabag/CoreBundle/Controller/ConfigController.php132
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.da.yml25
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.de.yml16
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.en.yml26
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.es.yml25
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml25
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml26
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.it.yml24
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml24
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml26
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml24
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml24
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.ru.yml24
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.th.yml24
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml24
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig61
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig55
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig65
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Config/otp_app.html.twig63
-rw-r--r--tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php194
20 files changed, 617 insertions, 290 deletions
diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php
index c9fc5702..2643eed0 100644
--- a/src/Wallabag/CoreBundle/Controller/ConfigController.php
+++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php
@@ -81,28 +81,7 @@ class ConfigController extends Controller
81 ]); 81 ]);
82 $userForm->handleRequest($request); 82 $userForm->handleRequest($request);
83 83
84 // `googleTwoFactor` isn't a field within the User entity, we need to define it's value in a different way
85 if ($this->getParameter('twofactor_auth') && true === $user->isGoogleAuthenticatorEnabled() && false === $userForm->isSubmitted()) {
86 $userForm->get('googleTwoFactor')->setData(true);
87 }
88
89 if ($userForm->isSubmitted() && $userForm->isValid()) { 84 if ($userForm->isSubmitted() && $userForm->isValid()) {
90 // handle creation / reset of the OTP secret if checkbox changed from the previous state
91 if ($this->getParameter('twofactor_auth')) {
92 if (true === $userForm->get('googleTwoFactor')->getData() && false === $user->isGoogleAuthenticatorEnabled()) {
93 $secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret();
94
95 $user->setGoogleAuthenticatorSecret($secret);
96 $user->setEmailTwoFactor(false);
97 $user->setBackupCodes((new BackupCodes())->toArray());
98
99 $this->addFlash('OtpQrCode', $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user));
100 } elseif (false === $userForm->get('googleTwoFactor')->getData() && true === $user->isGoogleAuthenticatorEnabled()) {
101 $user->setGoogleAuthenticatorSecret(null);
102 $user->setBackupCodes(null);
103 }
104 }
105
106 $userManager->updateUser($user, true); 85 $userManager->updateUser($user, true);
107 86
108 $this->addFlash( 87 $this->addFlash(
@@ -175,12 +154,119 @@ class ConfigController extends Controller
175 ], 154 ],
176 'twofactor_auth' => $this->getParameter('twofactor_auth'), 155 'twofactor_auth' => $this->getParameter('twofactor_auth'),
177 'wallabag_url' => $this->getParameter('domain_name'), 156 'wallabag_url' => $this->getParameter('domain_name'),
178 'enabled_users' => $this->get('wallabag_user.user_repository') 157 'enabled_users' => $this->get('wallabag_user.user_repository')->getSumEnabledUsers(),
179 ->getSumEnabledUsers(),
180 ]); 158 ]);
181 } 159 }
182 160
183 /** 161 /**
162 * Enable 2FA using email.
163 *
164 * @param Request $request
165 *
166 * @Route("/config/otp/email", name="config_otp_email")
167 */
168 public function otpEmailAction(Request $request)
169 {
170 if (!$this->getParameter('twofactor_auth')) {
171 return $this->createNotFoundException('two_factor not enabled');
172 }
173
174 $user = $this->getUser();
175
176 $user->setGoogleAuthenticatorSecret(null);
177 $user->setBackupCodes(null);
178 $user->setEmailTwoFactor(true);
179
180 $this->container->get('fos_user.user_manager')->updateUser($user, true);
181
182 $this->addFlash(
183 'notice',
184 'flashes.config.notice.otp_enabled'
185 );
186
187 return $this->redirect($this->generateUrl('config') . '#set3');
188 }
189
190 /**
191 * Enable 2FA using OTP app, user will need to confirm the generated code from the app.
192 *
193 * @Route("/config/otp/app", name="config_otp_app")
194 */
195 public function otpAppAction()
196 {
197 if (!$this->getParameter('twofactor_auth')) {
198 return $this->createNotFoundException('two_factor not enabled');
199 }
200
201 $user = $this->getUser();
202
203 if (!$user->isGoogleTwoFactor()) {
204 $secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret();
205
206 $user->setGoogleAuthenticatorSecret($secret);
207 $user->setEmailTwoFactor(false);
208 $user->setBackupCodes((new BackupCodes())->toArray());
209
210 $this->container->get('fos_user.user_manager')->updateUser($user, true);
211 }
212
213 return $this->render('WallabagCoreBundle:Config:otp_app.html.twig', [
214 'qr_code' => $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user),
215 ]);
216 }
217
218 /**
219 * Cancelling 2FA using OTP app.
220 *
221 * @Route("/config/otp/app/cancel", name="config_otp_app_cancel")
222 */
223 public function otpAppCancelAction()
224 {
225 if (!$this->getParameter('twofactor_auth')) {
226 return $this->createNotFoundException('two_factor not enabled');
227 }
228
229 $user = $this->getUser();
230 $user->setGoogleAuthenticatorSecret(null);
231 $user->setBackupCodes(null);
232
233 $this->container->get('fos_user.user_manager')->updateUser($user, true);
234
235 return $this->redirect($this->generateUrl('config') . '#set3');
236 }
237
238 /**
239 * Validate OTP code.
240 *
241 * @param Request $request
242 *
243 * @Route("/config/otp/app/check", name="config_otp_app_check")
244 */
245 public function otpAppCheckAction(Request $request)
246 {
247 $isValid = $this->get('scheb_two_factor.security.google_authenticator')->checkCode(
248 $this->getUser(),
249 $request->get('_auth_code')
250 );
251
252 if (true === $isValid) {
253 $this->addFlash(
254 'notice',
255 'flashes.config.notice.otp_enabled'
256 );
257
258 return $this->redirect($this->generateUrl('config') . '#set3');
259 }
260
261 $this->addFlash(
262 'two_factor',
263 'scheb_two_factor.code_invalid'
264 );
265
266 return $this->redirect($this->generateUrl('config_otp_app'));
267 }
268
269 /**
184 * @param Request $request 270 * @param Request $request
185 * 271 *
186 * @Route("/generate-token", name="generate_token") 272 * @Route("/generate-token", name="generate_token")
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
index ae8f8695..454f547d 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
@@ -102,12 +102,16 @@ config:
102 # 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." 102 # 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."
103 name_label: 'Navn' 103 name_label: 'Navn'
104 email_label: 'Emailadresse' 104 email_label: 'Emailadresse'
105 # emailTwoFactor_label: 'Using email (receive a code by email)' 105 two_factor:
106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 # emailTwoFactor_label: 'Using email (receive a code by email)'
107 # 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. 107 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
108 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 # table_method: Method
109 # two_factor_code_description_3: 'Or use that code:' 109 # table_state: State
110 # 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:' 110 # table_action: Action
111 # state_enabled: Enabled
112 # state_disabled: Disabled
113 # action_email: Use email
114 # action_app: Use OTP App
111 delete: 115 delete:
112 # title: Delete my account (a.k.a danger zone) 116 # title: Delete my account (a.k.a danger zone)
113 # 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. 117 # 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:
165 # and: 'One rule AND another' 169 # and: 'One rule AND another'
166 # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' 170 # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
167 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' 171 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
172 otp:
173 # page_title: Two-factor authentication
174 # app:
175 # 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.
176 # two_factor_code_description_2: 'You can scan that QR Code with your app:'
177 # 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:'
178 # two_factor_code_description_4: 'Test an OTP code from your configured app:'
179 # cancel: Cancel
180 # enable: Enable
168 181
169entry: 182entry:
170 # default_title: 'Title of the entry' 183 # default_title: 'Title of the entry'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
index 7b66e5dc..dc1d4723 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
@@ -102,12 +102,16 @@ config:
102 # 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." 102 # 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."
103 name_label: 'Name' 103 name_label: 'Name'
104 email_label: 'E-Mail-Adresse' 104 email_label: 'E-Mail-Adresse'
105 # emailTwoFactor_label: 'Using email (receive a code by email)' 105 two_factor:
106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 # emailTwoFactor_label: 'Using email (receive a code by email)'
107 # 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. 107 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
108 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 # table_method: Method
109 # two_factor_code_description_3: 'Or use that code:' 109 # table_state: State
110 # 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:' 110 # table_action: Action
111 # state_enabled: Enabled
112 # state_disabled: Disabled
113 # action_email: Use email
114 # action_app: Use OTP App
111 delete: 115 delete:
112 title: 'Lösche mein Konto (a.k.a Gefahrenzone)' 116 title: 'Lösche mein Konto (a.k.a Gefahrenzone)'
113 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.' 117 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.'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
index 567584b2..45145c80 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
@@ -102,12 +102,16 @@ config:
102 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." 102 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."
103 name_label: 'Name' 103 name_label: 'Name'
104 email_label: 'Email' 104 email_label: 'Email'
105 emailTwoFactor_label: 'Using email (receive a code by email)' 105 two_factor:
106 googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 emailTwoFactor_label: 'Using email (receive a code by email)'
107 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. 107 googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
108 two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 table_method: Method
109 two_factor_code_description_3: 'Or use that code:' 109 table_state: State
110 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:' 110 table_action: Action
111 state_enabled: Enabled
112 state_disabled: Disabled
113 action_email: Use email
114 action_app: Use OTP App
111 delete: 115 delete:
112 title: Delete my account (a.k.a danger zone) 116 title: Delete my account (a.k.a danger zone)
113 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. 117 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:
165 and: 'One rule AND another' 169 and: 'One rule AND another'
166 matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' 170 matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
167 notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' 171 notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
172 otp:
173 page_title: Two-factor authentication
174 app:
175 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.
176 two_factor_code_description_2: 'You can scan that QR Code with your app:'
177 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:'
178 two_factor_code_description_4: 'Test an OTP code from your configured app:'
179 cancel: Cancel
180 enable: Enable
168 181
169entry: 182entry:
170 default_title: 'Title of the entry' 183 default_title: 'Title of the entry'
@@ -584,6 +597,7 @@ flashes:
584 tags_reset: Tags reset 597 tags_reset: Tags reset
585 entries_reset: Entries reset 598 entries_reset: Entries reset
586 archived_reset: Archived entries deleted 599 archived_reset: Archived entries deleted
600 otp_enabled: Two-factor authentication enabled
587 entry: 601 entry:
588 notice: 602 notice:
589 entry_already_saved: 'Entry already saved on %date%' 603 entry_already_saved: 'Entry already saved on %date%'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
index 1ba4bce4..c1047e55 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
@@ -102,12 +102,16 @@ config:
102 # 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." 102 # 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."
103 name_label: 'Nombre' 103 name_label: 'Nombre'
104 email_label: 'Dirección de e-mail' 104 email_label: 'Dirección de e-mail'
105 # emailTwoFactor_label: 'Using email (receive a code by email)' 105 two_factor:
106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 # emailTwoFactor_label: 'Using email (receive a code by email)'
107 # 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. 107 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
108 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 # table_method: Method
109 # two_factor_code_description_3: 'Or use that code:' 109 # table_state: State
110 # 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:' 110 # table_action: Action
111 # state_enabled: Enabled
112 # state_disabled: Disabled
113 # action_email: Use email
114 # action_app: Use OTP App
111 delete: 115 delete:
112 title: Eliminar mi cuenta (Zona peligrosa) 116 title: Eliminar mi cuenta (Zona peligrosa)
113 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. 117 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:
165 and: 'Una regla Y la otra' 169 and: 'Una regla Y la otra'
166 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>' 170 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>'
167 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' 171 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
172 otp:
173 # page_title: Two-factor authentication
174 # app:
175 # 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.
176 # two_factor_code_description_2: 'You can scan that QR Code with your app:'
177 # 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:'
178 # two_factor_code_description_4: 'Test an OTP code from your configured app:'
179 # cancel: Cancel
180 # enable: Enable
168 181
169entry: 182entry:
170 default_title: 'Título del artículo' 183 default_title: 'Título del artículo'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
index d20c89d9..3042de2e 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
@@ -102,12 +102,16 @@ config:
102 # 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." 102 # 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."
103 name_label: 'نام' 103 name_label: 'نام'
104 email_label: 'نشانی ایمیل' 104 email_label: 'نشانی ایمیل'
105 # emailTwoFactor_label: 'Using email (receive a code by email)' 105 two_factor:
106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 # emailTwoFactor_label: 'Using email (receive a code by email)'
107 # 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. 107 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
108 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 # table_method: Method
109 # two_factor_code_description_3: 'Or use that code:' 109 # table_state: State
110 # 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:' 110 # table_action: Action
111 # state_enabled: Enabled
112 # state_disabled: Disabled
113 # action_email: Use email
114 # action_app: Use OTP App
111 delete: 115 delete:
112 # title: Delete my account (a.k.a danger zone) 116 # title: Delete my account (a.k.a danger zone)
113 # 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. 117 # 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:
165 # and: 'One rule AND another' 169 # and: 'One rule AND another'
166 # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' 170 # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
167 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' 171 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
172 otp:
173 # page_title: Two-factor authentication
174 # app:
175 # 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.
176 # two_factor_code_description_2: 'You can scan that QR Code with your app:'
177 # 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:'
178 # two_factor_code_description_4: 'Test an OTP code from your configured app:'
179 # cancel: Cancel
180 # enable: Enable
168 181
169entry: 182entry:
170 # default_title: 'Title of the entry' 183 # default_title: 'Title of the entry'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
index fd405059..57740ba2 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
@@ -102,12 +102,16 @@ config:
102 two_factor_description: "Activer l’authentification 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." 102 two_factor_description: "Activer l’authentification 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."
103 name_label: "Nom" 103 name_label: "Nom"
104 email_label: "Adresse courriel" 104 email_label: "Adresse courriel"
105 emailTwoFactor_label: 'En utlisant l’email (recevez un code par email)' 105 two_factor:
106 googleTwoFactor_label: 'En utilisant une application de mot de passe à usage unique (ouvrez l’app, comme Google Authenticator, Authy or FreeOTP, pour obtenir un mot de passe à usage unique)' 106 emailTwoFactor_label: 'En utlisant l’email (recevez un code par email)'
107 two_factor_code_description_1: Vous venez d’activer l’authentification 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. 107 googleTwoFactor_label: 'En utilisant une application de mot de passe à usage unique (ouvrez l’app, comme Google Authenticator, Authy or FreeOTP, pour obtenir un mot de passe à usage unique)'
108 two_factor_code_description_2: 'Vous pouvez scanner le QR code avec votre application :' 108 table_method: Méthode
109 two_factor_code_description_3: 'Ou utiliser le code suivant :' 109 table_state: État
110 two_factor_code_description_4: 'N’oubliez 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 :' 110 table_action: Action
111 state_enabled: Activé
112 state_disabled: Désactivé
113 action_email: Utiliser l'email
114 action_app: Utiliser une app OTP
111 delete: 115 delete:
112 title: "Supprimer mon compte (attention danger !)" 116 title: "Supprimer mon compte (attention danger !)"
113 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é (c’est IRRÉVERSIBLE). Vous serez ensuite déconnecté." 117 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é (c’est IRRÉVERSIBLE). Vous serez ensuite déconnecté."
@@ -165,6 +169,15 @@ config:
165 and: "Une règle ET l’autre" 169 and: "Une règle ET l’autre"
166 matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>" 170 matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>"
167 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>" 171 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>"
172 otp:
173 page_title: Authentification double-facteur
174 app:
175 two_factor_code_description_1: Vous venez d’activer l’authentification 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.
176 two_factor_code_description_2: 'Vous pouvez scanner le QR code avec votre application :'
177 two_factor_code_description_3: 'N’oubliez 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 :'
178 two_factor_code_description_4: 'Testez un code généré par votre application OTP :'
179 cancel: Annuler
180 enable: Activer
168 181
169entry: 182entry:
170 default_title: "Titre de l’article" 183 default_title: "Titre de l’article"
@@ -585,6 +598,7 @@ flashes:
585 tags_reset: "Tags supprimés" 598 tags_reset: "Tags supprimés"
586 entries_reset: "Articles supprimés" 599 entries_reset: "Articles supprimés"
587 archived_reset: "Articles archivés supprimés" 600 archived_reset: "Articles archivés supprimés"
601 otp_enabled: "Authentification à double-facteur activée"
588 entry: 602 entry:
589 notice: 603 notice:
590 entry_already_saved: "Article déjà sauvegardé le %date%" 604 entry_already_saved: "Article déjà sauvegardé le %date%"
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
index 33326231..274e5338 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
@@ -102,12 +102,15 @@ config:
102 # 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." 102 # 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."
103 name_label: 'Nome' 103 name_label: 'Nome'
104 email_label: 'E-mail' 104 email_label: 'E-mail'
105 # emailTwoFactor_label: 'Using email (receive a code by email)' 105 # emailTwoFactor_label: 'Using email (receive a code by email)'
106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
107 # 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. 107 # table_method: Method
108 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 # table_state: State
109 # two_factor_code_description_3: 'Or use that code:' 109 # table_action: Action
110 # 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:' 110 # state_enabled: Enabled
111 # state_disabled: Disabled
112 # action_email: Use email
113 # action_app: Use OTP App
111 delete: 114 delete:
112 title: Cancella il mio account (zona pericolosa) 115 title: Cancella il mio account (zona pericolosa)
113 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. 116 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:
165 and: "Una regola E un'altra" 168 and: "Una regola E un'altra"
166 matches: 'Verifica che un <i>oggetto</i> risulti in una <i>ricerca</i> (case-insensitive).<br />Esempio: <code>titolo contiene "football"</code>' 169 matches: 'Verifica che un <i>oggetto</i> risulti in una <i>ricerca</i> (case-insensitive).<br />Esempio: <code>titolo contiene "football"</code>'
167 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' 170 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
171 otp:
172 # page_title: Two-factor authentication
173 # app:
174 # 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.
175 # two_factor_code_description_2: 'You can scan that QR Code with your app:'
176 # 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:'
177 # two_factor_code_description_4: 'Test an OTP code from your configured app:'
178 # cancel: Cancel
179 # enable: Enable
168 180
169entry: 181entry:
170 default_title: "Titolo del contenuto" 182 default_title: "Titolo del contenuto"
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
index 599490e1..4e5370f9 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
@@ -102,12 +102,15 @@ config:
102 # 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." 102 # 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."
103 name_label: 'Nom' 103 name_label: 'Nom'
104 email_label: 'Adreça de corrièl' 104 email_label: 'Adreça de corrièl'
105 # emailTwoFactor_label: 'Using email (receive a code by email)' 105 # emailTwoFactor_label: 'Using email (receive a code by email)'
106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
107 # 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. 107 # table_method: Method
108 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 # table_state: State
109 # two_factor_code_description_3: 'Or use that code:' 109 # table_action: Action
110 # 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:' 110 # state_enabled: Enabled
111 # state_disabled: Disabled
112 # action_email: Use email
113 # action_app: Use OTP App
111 delete: 114 delete:
112 title: Suprimir mon compte (Mèfi zòna perilhosa) 115 title: Suprimir mon compte (Mèfi zòna perilhosa)
113 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. 116 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:
165 and: "Una règla E l'autra" 168 and: "Una règla E l'autra"
166 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>' 169 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>'
167 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>' 170 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>'
171 otp:
172 # page_title: Two-factor authentication
173 # app:
174 # 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.
175 # two_factor_code_description_2: 'You can scan that QR Code with your app:'
176 # 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:'
177 # two_factor_code_description_4: 'Test an OTP code from your configured app:'
178 # cancel: Cancel
179 # enable: Enable
168 180
169entry: 181entry:
170 default_title: "Títol de l'article" 182 default_title: "Títol de l'article"
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
index 89fd34dc..a7a4d6c3 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
@@ -99,15 +99,18 @@ config:
99 all: 'Wszystkie' 99 all: 'Wszystkie'
100 rss_limit: 'Link do RSS' 100 rss_limit: 'Link do RSS'
101 form_user: 101 form_user:
102 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." 102 # 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."
103 name_label: 'Nazwa' 103 name_label: 'Nazwa'
104 email_label: 'Adres email' 104 email_label: 'Adres email'
105 # emailTwoFactor_label: 'Using email (receive a code by email)' 105 # emailTwoFactor_label: 'Using email (receive a code by email)'
106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
107 # 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. 107 # table_method: Method
108 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 # table_state: State
109 # two_factor_code_description_3: 'Or use that code:' 109 # table_action: Action
110 # 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:' 110 # state_enabled: Enabled
111 # state_disabled: Disabled
112 # action_email: Use email
113 # action_app: Use OTP App
111 delete: 114 delete:
112 title: Usuń moje konto (niebezpieczna strefa !) 115 title: Usuń moje konto (niebezpieczna strefa !)
113 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. 116 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:
165 and: 'Jedna reguła I inna' 168 and: 'Jedna reguła I inna'
166 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>' 169 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>'
167 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>' 170 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>'
171 otp:
172 # page_title: Two-factor authentication
173 # app:
174 # 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.
175 # two_factor_code_description_2: 'You can scan that QR Code with your app:'
176 # 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:'
177 # two_factor_code_description_4: 'Test an OTP code from your configured app:'
178 # cancel: Cancel
179 # enable: Enable
168 180
169entry: 181entry:
170 default_title: 'Tytuł wpisu' 182 default_title: 'Tytuł wpisu'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
index f37aeb91..a5483a6d 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
@@ -102,12 +102,15 @@ config:
102 # 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." 102 # 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."
103 name_label: 'Nome' 103 name_label: 'Nome'
104 email_label: 'E-mail' 104 email_label: 'E-mail'
105 # emailTwoFactor_label: 'Using email (receive a code by email)' 105 # emailTwoFactor_label: 'Using email (receive a code by email)'
106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
107 # 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. 107 # table_method: Method
108 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 # table_state: State
109 # two_factor_code_description_3: 'Or use that code:' 109 # table_action: Action
110 # 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:' 110 # state_enabled: Enabled
111 # state_disabled: Disabled
112 # action_email: Use email
113 # action_app: Use OTP App
111 delete: 114 delete:
112 # title: Delete my account (a.k.a danger zone) 115 # title: Delete my account (a.k.a danger zone)
113 # 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. 116 # 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:
165 and: 'Uma regra E outra' 168 and: 'Uma regra E outra'
166 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>' 169 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>'
167 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' 170 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
171 otp:
172 # page_title: Two-factor authentication
173 # app:
174 # 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.
175 # two_factor_code_description_2: 'You can scan that QR Code with your app:'
176 # 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:'
177 # two_factor_code_description_4: 'Test an OTP code from your configured app:'
178 # cancel: Cancel
179 # enable: Enable
168 180
169entry: 181entry:
170 default_title: 'Título da entrada' 182 default_title: 'Título da entrada'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
index c9d9500d..3b7fbd69 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
@@ -102,12 +102,15 @@ config:
102 # 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." 102 # 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."
103 name_label: 'Nume' 103 name_label: 'Nume'
104 email_label: 'E-mail' 104 email_label: 'E-mail'
105 # emailTwoFactor_label: 'Using email (receive a code by email)' 105 # emailTwoFactor_label: 'Using email (receive a code by email)'
106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
107 # 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. 107 # table_method: Method
108 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 # table_state: State
109 # two_factor_code_description_3: 'Or use that code:' 109 # table_action: Action
110 # 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:' 110 # state_enabled: Enabled
111 # state_disabled: Disabled
112 # action_email: Use email
113 # action_app: Use OTP App
111 delete: 114 delete:
112 # title: Delete my account (a.k.a danger zone) 115 # title: Delete my account (a.k.a danger zone)
113 # 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. 116 # 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:
165 # and: 'One rule AND another' 168 # and: 'One rule AND another'
166 # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' 169 # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
167 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' 170 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
171 otp:
172 # page_title: Two-factor authentication
173 # app:
174 # 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.
175 # two_factor_code_description_2: 'You can scan that QR Code with your app:'
176 # 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:'
177 # two_factor_code_description_4: 'Test an OTP code from your configured app:'
178 # cancel: Cancel
179 # enable: Enable
168 180
169entry: 181entry:
170 # default_title: 'Title of the entry' 182 # default_title: 'Title of the entry'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ru.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ru.yml
index 62a078d4..92746631 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.ru.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ru.yml
@@ -99,12 +99,15 @@ config:
99 # 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." 99 # 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."
100 name_label: 'Имя' 100 name_label: 'Имя'
101 email_label: 'Email' 101 email_label: 'Email'
102 # emailTwoFactor_label: 'Using email (receive a code by email)' 102 # emailTwoFactor_label: 'Using email (receive a code by email)'
103 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 103 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
104 # 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. 104 # table_method: Method
105 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 105 # table_state: State
106 # two_factor_code_description_3: 'Or use that code:' 106 # table_action: Action
107 # 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:' 107 # state_enabled: Enabled
108 # state_disabled: Disabled
109 # action_email: Use email
110 # action_app: Use OTP App
108 delete: 111 delete:
109 title: "Удалить мой аккаунт (или опасная зона)" 112 title: "Удалить мой аккаунт (или опасная зона)"
110 description: "Если Вы удалите ваш аккаунт, ВСЕ ваши записи, теги и другие данные, будут БЕЗВОЗВРАТНО удалены (операция не может быть отменена после). Затем Вы выйдете из системы." 113 description: "Если Вы удалите ваш аккаунт, ВСЕ ваши записи, теги и другие данные, будут БЕЗВОЗВРАТНО удалены (операция не может быть отменена после). Затем Вы выйдете из системы."
@@ -160,6 +163,15 @@ config:
160 or: 'Одно правило ИЛИ другое' 163 or: 'Одно правило ИЛИ другое'
161 and: 'Одно правило И другое' 164 and: 'Одно правило И другое'
162 matches: 'Тесты, в которых <i> тема </i> соответствует <i> поиску </i> (без учета регистра). Пример: <code> title matches "футбол" </code>' 165 matches: 'Тесты, в которых <i> тема </i> соответствует <i> поиску </i> (без учета регистра). Пример: <code> title matches "футбол" </code>'
166 otp:
167 # page_title: Two-factor authentication
168 # app:
169 # 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.
170 # two_factor_code_description_2: 'You can scan that QR Code with your app:'
171 # 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:'
172 # two_factor_code_description_4: 'Test an OTP code from your configured app:'
173 # cancel: Cancel
174 # enable: Enable
163 175
164entry: 176entry:
165 default_title: 'Название записи' 177 default_title: 'Название записи'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.th.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.th.yml
index 78b5727a..1fe4fa0e 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.th.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.th.yml
@@ -102,12 +102,15 @@ config:
102 # 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." 102 # 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."
103 name_label: 'ชื่อ' 103 name_label: 'ชื่อ'
104 email_label: 'อีเมล' 104 email_label: 'อีเมล'
105 # emailTwoFactor_label: 'Using email (receive a code by email)' 105 # emailTwoFactor_label: 'Using email (receive a code by email)'
106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
107 # 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. 107 # table_method: Method
108 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 # table_state: State
109 # two_factor_code_description_3: 'Or use that code:' 109 # table_action: Action
110 # 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:' 110 # state_enabled: Enabled
111 # state_disabled: Disabled
112 # action_email: Use email
113 # action_app: Use OTP App
111 delete: 114 delete:
112 title: ลบบัญชีของฉัน (โซนที่เป็นภัย!) 115 title: ลบบัญชีของฉัน (โซนที่เป็นภัย!)
113 description: ถ้าคุณลบบัญชีของคุณIf , รายการทั้งหมดของคุณ, แท็กทั้งหมดของคุณ, หมายเหตุทั้งหมดของคุณและบัญชีของคุณจะถูกลบอย่างถาวร (มันไม่สามารถยกเลิกได้) คุณจะต้องลงชื่อออก 116 description: ถ้าคุณลบบัญชีของคุณIf , รายการทั้งหมดของคุณ, แท็กทั้งหมดของคุณ, หมายเหตุทั้งหมดของคุณและบัญชีของคุณจะถูกลบอย่างถาวร (มันไม่สามารถยกเลิกได้) คุณจะต้องลงชื่อออก
@@ -165,6 +168,15 @@ config:
165 and: 'หนึ่งข้อบังคับและอื่นๆ' 168 and: 'หนึ่งข้อบังคับและอื่นๆ'
166 matches: 'ทดสอบว่า <i>เรื่อง</i> นี้ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อที่ตรงกับ "football"</code>' 169 matches: 'ทดสอบว่า <i>เรื่อง</i> นี้ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อที่ตรงกับ "football"</code>'
167 notmatches: 'ทดสอบว่า <i>เรื่อง</i> นี้ไม่ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อทีไม่ตรงกับ "football"</code>' 170 notmatches: 'ทดสอบว่า <i>เรื่อง</i> นี้ไม่ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อทีไม่ตรงกับ "football"</code>'
171 otp:
172 # page_title: Two-factor authentication
173 # app:
174 # 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.
175 # two_factor_code_description_2: 'You can scan that QR Code with your app:'
176 # 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:'
177 # two_factor_code_description_4: 'Test an OTP code from your configured app:'
178 # cancel: Cancel
179 # enable: Enable
168 180
169entry: 181entry:
170 default_title: 'หัวข้อรายการ' 182 default_title: 'หัวข้อรายการ'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
index 9f4c01f7..3b8a0d59 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
@@ -102,12 +102,15 @@ config:
102 # 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." 102 # 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."
103 name_label: 'İsim' 103 name_label: 'İsim'
104 email_label: 'E-posta' 104 email_label: 'E-posta'
105 # emailTwoFactor_label: 'Using email (receive a code by email)' 105 # emailTwoFactor_label: 'Using email (receive a code by email)'
106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)' 106 # googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
107 # 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. 107 # table_method: Method
108 # two_factor_code_description_2: 'You can scan that QR Code with your app:' 108 # table_state: State
109 # two_factor_code_description_3: 'Or use that code:' 109 # table_action: Action
110 # 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:' 110 # state_enabled: Enabled
111 # state_disabled: Disabled
112 # action_email: Use email
113 # action_app: Use OTP App
111 delete: 114 delete:
112 # title: Delete my account (a.k.a danger zone) 115 # title: Delete my account (a.k.a danger zone)
113 # 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. 116 # 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:
165 and: 'Bir kural ve diğeri' 168 and: 'Bir kural ve diğeri'
166 # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>' 169 # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
167 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>' 170 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
171 otp:
172 # page_title: Two-factor authentication
173 # app:
174 # 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.
175 # two_factor_code_description_2: 'You can scan that QR Code with your app:'
176 # 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:'
177 # two_factor_code_description_4: 'Test an OTP code from your configured app:'
178 # cancel: Cancel
179 # enable: Enable
168 180
169entry: 181entry:
170 default_title: 'Makalenin başlığı' 182 default_title: 'Makalenin başlığı'
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
index cf439408..93f8ddf8 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
@@ -168,48 +168,41 @@
168 </div> 168 </div>
169 </fieldset> 169 </fieldset>
170 170
171 {{ form_widget(form.user.save) }}
172
171 {% if twofactor_auth %} 173 {% if twofactor_auth %}
174 <h5>{{ 'config.otp.page_title'|trans }}</h5>
175
172 <div class="row"> 176 <div class="row">
173 {{ 'config.form_user.two_factor_description'|trans }} 177 {{ 'config.form_user.two_factor_description'|trans }}
174 </div> 178 </div>
175 179
176 <fieldset class="w500p inline"> 180 <table>
177 <div class="row"> 181 <thead>
178 {{ form_label(form.user.emailTwoFactor) }} 182 <tr>
179 {{ form_errors(form.user.emailTwoFactor) }} 183 <th>{{ 'config.form_user.two_factor.table_method'|trans }}</th>
180 {{ form_widget(form.user.emailTwoFactor) }} 184 <th>{{ 'config.form_user.two_factor.table_state'|trans }}</th>
181 </div> 185 <th>{{ 'config.form_user.two_factor.table_action'|trans }}</th>
182 <br/> 186 </tr>
183 <div class="row"> 187 </thead>
184 {{ form_label(form.user.googleTwoFactor) }} 188
185 {{ form_widget(form.user.googleTwoFactor) }} 189 <tbody>
186 {{ form_errors(form.user.googleTwoFactor) }} 190 <tr>
187 </div> 191 <td>{{ 'config.form_user.two_factor.emailTwoFactor_label'|trans }}</td>
188 {% for OtpQrCode in app.session.flashbag.get('OtpQrCode') %} 192 <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>
189 <div class="row"> 193 <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>
190 {{ 'config.form_user.two_factor_code_description_1'|trans }} 194 </tr>
191 <br/> 195 <tr>
192 {{ 'config.form_user.two_factor_code_description_2'|trans }} 196 <td>{{ 'config.form_user.two_factor.googleTwoFactor_label'|trans }}</td>
193 <br/><br/> 197 <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>
194 <img id="2faQrcode" class="hide-on-med-and-down" /> 198 <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>
195 <script> 199 </tr>
196 document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ OtpQrCode }}'); 200 </tbody>
197 </script> 201 </table>
198 <br/><br/> 202
199 {{ 'config.form_user.two_factor_code_description_3'|trans }}
200 <br/><br/>
201 <strong>{{ app.user.getGoogleAuthenticatorSecret }}</strong>
202 <br/><br/>
203 {{ 'config.form_user.two_factor_code_description_4'|trans }}
204 <br/><br/>
205 <strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong>
206 </div>
207 {% endfor %}
208 </fieldset>
209 {% endif %} 203 {% endif %}
210 204
211 {{ form_widget(form.user._token) }} 205 {{ form_widget(form.user._token) }}
212 {{ form_widget(form.user.save) }}
213 </form> 206 </form>
214 207
215 {% if enabled_users > 1 %} 208 {% if enabled_users > 1 %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig
new file mode 100644
index 00000000..2e4442e3
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig
@@ -0,0 +1,55 @@
1{% extends "WallabagCoreBundle::layout.html.twig" %}
2
3{% block title %}{{ 'config.page_title'|trans }} > {{ 'config.otp.page_title'|trans }}{% endblock %}
4
5{% block content %}
6 <h5>{{ 'config.otp.page_title'|trans }}</h5>
7
8 <ol>
9 <li>
10 <p>{{ 'config.otp.app.two_factor_code_description_1'|trans }}</p>
11 <p>{{ 'config.otp.app.two_factor_code_description_2'|trans }}</p>
12
13 <p>
14 <img id="2faQrcode" class="hide-on-med-and-down" />
15 <script>
16 document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ qr_code }}');
17 </script>
18 </p>
19 </li>
20 <li>
21 <p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p>
22
23 <p><strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong></p>
24 </li>
25 <li>
26 <p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p>
27
28 {% for flashMessage in app.session.flashbag.get("two_factor") %}
29 <div class="card-panel red darken-1 black-text">
30 {{ flashMessage|trans }}
31 </div>
32 {% endfor %}
33
34 <form class="form" action="{{ path("config_otp_app_check") }}" method="post">
35 <div class="card-content">
36 <div class="row">
37 <div class="input-field col s12">
38 <label for="_auth_code">{{ "scheb_two_factor.auth_code"|trans }}</label>
39 <input id="_auth_code" type="text" autocomplete="off" name="_auth_code" />
40 </div>
41 </div>
42 </div>
43 <div class="card-action">
44 <a href="{{ path('config_otp_app_cancel') }}" class="waves-effect waves-light grey btn">
45 {{ 'config.otp.app.cancel'|trans }}
46 </a>
47 <button class="btn waves-effect waves-light" type="submit" name="send">
48 {{ 'config.otp.app.enable'|trans }}
49 <i class="material-icons right">send</i>
50 </button>
51 </div>
52 </form>
53 </li>
54 </ol>
55{% endblock %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
index 5b00eb7b..412c18f4 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
@@ -196,45 +196,40 @@
196 </div> 196 </div>
197 </div> 197 </div>
198 198
199 {{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
200
199 {% if twofactor_auth %} 201 {% if twofactor_auth %}
202 <br/>
203 <br/>
200 <div class="row"> 204 <div class="row">
201 {{ 'config.form_user.two_factor_description'|trans }} 205 <h5>{{ 'config.otp.page_title'|trans }}</h5>
202 206
203 <div class="input-field col s11"> 207 <p>{{ 'config.form_user.two_factor_description'|trans }}</p>
204 {{ form_widget(form.user.emailTwoFactor) }} 208
205 {{ form_label(form.user.emailTwoFactor) }} 209 <table>
206 {{ form_errors(form.user.emailTwoFactor) }} 210 <thead>
207 </div> 211 <tr>
208 <div class="input-field col s11"> 212 <th>{{ 'config.form_user.two_factor.table_method'|trans }}</th>
209 {{ form_widget(form.user.googleTwoFactor) }} 213 <th>{{ 'config.form_user.two_factor.table_state'|trans }}</th>
210 {{ form_label(form.user.googleTwoFactor) }} 214 <th>{{ 'config.form_user.two_factor.table_action'|trans }}</th>
211 {{ form_errors(form.user.googleTwoFactor) }} 215 </tr>
212 </div> 216 </thead>
217
218 <tbody>
219 <tr>
220 <td>{{ 'config.form_user.two_factor.emailTwoFactor_label'|trans }}</td>
221 <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>
222 <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>
223 </tr>
224 <tr>
225 <td>{{ 'config.form_user.two_factor.googleTwoFactor_label'|trans }}</td>
226 <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>
227 <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>
228 </tr>
229 </tbody>
230 </table>
213 </div> 231 </div>
214
215 {% for OtpQrCode in app.session.flashbag.get('OtpQrCode') %}
216 <div class="card-panel yellow darken-1 black-text">
217 {{ 'config.form_user.two_factor_code_description_1'|trans }}
218 <br/>
219 {{ 'config.form_user.two_factor_code_description_2'|trans }}
220 <br/><br/>
221 <img id="2faQrcode" class="hide-on-med-and-down" />
222 <script>
223 document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ OtpQrCode }}');
224 </script>
225 <br/><br/>
226 {{ 'config.form_user.two_factor_code_description_3'|trans }}
227 <br/><br/>
228 <strong>{{ app.user.getGoogleAuthenticatorSecret }}</strong>
229 <br/><br/>
230 {{ 'config.form_user.two_factor_code_description_4'|trans }}
231 <br/><br/>
232 <strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong>
233 </div>
234 {% endfor %}
235 {% endif %} 232 {% endif %}
236
237 {{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
238 {{ form_widget(form.user._token) }} 233 {{ form_widget(form.user._token) }}
239 </form> 234 </form>
240 </div> 235 </div>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/otp_app.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/otp_app.html.twig
new file mode 100644
index 00000000..6aef355e
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/otp_app.html.twig
@@ -0,0 +1,63 @@
1{% extends "WallabagCoreBundle::layout.html.twig" %}
2
3{% block title %}{{ 'config.page_title'|trans }} > {{ 'config.otp.page_title'|trans }}{% endblock %}
4
5{% block content %}
6 <div class="row">
7 <div class="col s12">
8 <div class="card-panel settings">
9 <div class="row">
10 <h5>{{ 'config.otp.page_title'|trans }}</h5>
11
12 <ol>
13 <li>
14 <p>{{ 'config.otp.app.two_factor_code_description_1'|trans }}</p>
15 <p>{{ 'config.otp.app.two_factor_code_description_2'|trans }}</p>
16
17 <p>
18 <img id="2faQrcode" class="hide-on-med-and-down" />
19 <script>
20 document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ qr_code }}');
21 </script>
22 </p>
23 </li>
24 <li>
25 <p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p>
26
27 <p><strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong></p>
28 </li>
29 <li>
30 <p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p>
31
32 {% for flashMessage in app.session.flashbag.get("two_factor") %}
33 <div class="card-panel red darken-1 black-text">
34 {{ flashMessage|trans }}
35 </div>
36 {% endfor %}
37
38 <form class="form" action="{{ path("config_otp_app_check") }}" method="post">
39 <div class="card-content">
40 <div class="row">
41 <div class="input-field col s12">
42 <label for="_auth_code">{{ "scheb_two_factor.auth_code"|trans }}</label>
43 <input id="_auth_code" type="text" autocomplete="off" name="_auth_code" />
44 </div>
45 </div>
46 </div>
47 <div class="card-action">
48 <a href="{{ path('config_otp_app_cancel') }}" class="waves-effect waves-light grey btn">
49 {{ 'config.otp.app.cancel'|trans }}
50 </a>
51 <button class="btn waves-effect waves-light" type="submit" name="send">
52 {{ 'config.otp.app.enable'|trans }}
53 <i class="material-icons right">send</i>
54 </button>
55 </div>
56 </form>
57 </li>
58 </ol>
59 </div>
60 </div>
61 </div>
62 </div>
63{% endblock %}
diff --git a/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php b/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php
index 9ca52c64..1090a686 100644
--- a/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php
+++ b/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php
@@ -297,119 +297,6 @@ class ConfigControllerTest extends WallabagCoreTestCase
297 $this->assertContains('flashes.config.notice.user_updated', $alert[0]); 297 $this->assertContains('flashes.config.notice.user_updated', $alert[0]);
298 } 298 }
299 299
300 public function testUserEnable2faEmail()
301 {
302 $this->logInAs('admin');
303 $client = $this->getClient();
304
305 $crawler = $client->request('GET', '/config');
306
307 $this->assertSame(200, $client->getResponse()->getStatusCode());
308
309 $form = $crawler->filter('button[id=update_user_save]')->form();
310
311 $data = [
312 'update_user[emailTwoFactor]' => '1',
313 ];
314
315 $client->submit($form, $data);
316
317 $this->assertSame(302, $client->getResponse()->getStatusCode());
318
319 $crawler = $client->followRedirect();
320
321 $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
322 $this->assertContains('flashes.config.notice.user_updated', $alert[0]);
323
324 // restore user
325 $em = $this->getEntityManager();
326 $user = $em
327 ->getRepository('WallabagUserBundle:User')
328 ->findOneByUsername('admin');
329
330 $this->assertTrue($user->isEmailTwoFactor());
331
332 $user->setEmailTwoFactor(false);
333 $em->persist($user);
334 $em->flush();
335 }
336
337 public function testUserEnable2faGoogle()
338 {
339 $this->logInAs('admin');
340 $client = $this->getClient();
341
342 $crawler = $client->request('GET', '/config');
343
344 $this->assertSame(200, $client->getResponse()->getStatusCode());
345
346 $form = $crawler->filter('button[id=update_user_save]')->form();
347
348 $data = [
349 'update_user[googleTwoFactor]' => '1',
350 ];
351
352 $client->submit($form, $data);
353
354 $this->assertSame(302, $client->getResponse()->getStatusCode());
355
356 $crawler = $client->followRedirect();
357
358 $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
359 $this->assertContains('flashes.config.notice.user_updated', $alert[0]);
360
361 // restore user
362 $em = $this->getEntityManager();
363 $user = $em
364 ->getRepository('WallabagUserBundle:User')
365 ->findOneByUsername('admin');
366
367 $this->assertTrue($user->isGoogleAuthenticatorEnabled());
368
369 $user->setGoogleAuthenticatorSecret(null);
370 $em->persist($user);
371 $em->flush();
372 }
373
374 public function testUserEnable2faBoth()
375 {
376 $this->logInAs('admin');
377 $client = $this->getClient();
378
379 $crawler = $client->request('GET', '/config');
380
381 $this->assertSame(200, $client->getResponse()->getStatusCode());
382
383 $form = $crawler->filter('button[id=update_user_save]')->form();
384
385 $data = [
386 'update_user[googleTwoFactor]' => '1',
387 'update_user[emailTwoFactor]' => '1',
388 ];
389
390 $client->submit($form, $data);
391
392 $this->assertSame(302, $client->getResponse()->getStatusCode());
393
394 $crawler = $client->followRedirect();
395
396 $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
397 $this->assertContains('flashes.config.notice.user_updated', $alert[0]);
398
399 // restore user
400 $em = $this->getEntityManager();
401 $user = $em
402 ->getRepository('WallabagUserBundle:User')
403 ->findOneByUsername('admin');
404
405 $this->assertTrue($user->isGoogleAuthenticatorEnabled());
406 $this->assertFalse($user->isEmailTwoFactor());
407
408 $user->setGoogleAuthenticatorSecret(null);
409 $em->persist($user);
410 $em->flush();
411 }
412
413 public function testRssUpdateResetToken() 300 public function testRssUpdateResetToken()
414 { 301 {
415 $this->logInAs('admin'); 302 $this->logInAs('admin');
@@ -1113,4 +1000,85 @@ class ConfigControllerTest extends WallabagCoreTestCase
1113 $this->assertNotSame('yuyuyuyu', $client->getRequest()->getLocale()); 1000 $this->assertNotSame('yuyuyuyu', $client->getRequest()->getLocale());
1114 $this->assertNotSame('yuyuyuyu', $client->getContainer()->get('session')->get('_locale')); 1001 $this->assertNotSame('yuyuyuyu', $client->getContainer()->get('session')->get('_locale'));
1115 } 1002 }
1003
1004 public function testUserEnable2faEmail()
1005 {
1006 $this->logInAs('admin');
1007 $client = $this->getClient();
1008
1009 $crawler = $client->request('GET', '/config/otp/email');
1010
1011 $this->assertSame(302, $client->getResponse()->getStatusCode());
1012
1013 $crawler = $client->followRedirect();
1014
1015 $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
1016 $this->assertContains('flashes.config.notice.otp_enabled', $alert[0]);
1017
1018 // restore user
1019 $em = $this->getEntityManager();
1020 $user = $em
1021 ->getRepository('WallabagUserBundle:User')
1022 ->findOneByUsername('admin');
1023
1024 $this->assertTrue($user->isEmailTwoFactor());
1025
1026 $user->setEmailTwoFactor(false);
1027 $em->persist($user);
1028 $em->flush();
1029 }
1030
1031 public function testUserEnable2faGoogle()
1032 {
1033 $this->logInAs('admin');
1034 $client = $this->getClient();
1035
1036 $crawler = $client->request('GET', '/config/otp/app');
1037
1038 $this->assertSame(200, $client->getResponse()->getStatusCode());
1039
1040 // restore user
1041 $em = $this->getEntityManager();
1042 $user = $em
1043 ->getRepository('WallabagUserBundle:User')
1044 ->findOneByUsername('admin');
1045
1046 $this->assertTrue($user->isGoogleTwoFactor());
1047 $this->assertGreaterThan(0, $user->getBackupCodes());
1048
1049 $user->setGoogleAuthenticatorSecret(false);
1050 $user->setBackupCodes(null);
1051 $em->persist($user);
1052 $em->flush();
1053 }
1054
1055 public function testUserEnable2faGoogleCancel()
1056 {
1057 $this->logInAs('admin');
1058 $client = $this->getClient();
1059
1060 $crawler = $client->request('GET', '/config/otp/app');
1061
1062 $this->assertSame(200, $client->getResponse()->getStatusCode());
1063
1064 // restore user
1065 $em = $this->getEntityManager();
1066 $user = $em
1067 ->getRepository('WallabagUserBundle:User')
1068 ->findOneByUsername('admin');
1069
1070 $this->assertTrue($user->isGoogleTwoFactor());
1071 $this->assertGreaterThan(0, $user->getBackupCodes());
1072
1073 $crawler = $client->request('GET', '/config/otp/app/cancel');
1074
1075 $this->assertSame(302, $client->getResponse()->getStatusCode());
1076
1077 $user = $em
1078 ->getRepository('WallabagUserBundle:User')
1079 ->findOneByUsername('admin');
1080
1081 $this->assertFalse($user->isGoogleTwoFactor());
1082 $this->assertEmpty($user->getBackupCodes());
1083 }
1116} 1084}