4 namespace Friendica\Module\Settings\TwoFactor;
7 use BaconQrCode\Renderer\Image\SvgImageBackEnd;
8 use BaconQrCode\Renderer\ImageRenderer;
9 use BaconQrCode\Renderer\RendererStyle\RendererStyle;
10 use BaconQrCode\Writer;
11 use Friendica\BaseModule;
12 use Friendica\Core\L10n;
13 use Friendica\Core\PConfig;
14 use Friendica\Core\Renderer;
15 use Friendica\Core\Session;
16 use Friendica\Module\BaseSettingsModule;
17 use Friendica\Module\Login;
18 use PragmaRX\Google2FA\Google2FA;
21 * // Page 4: 2FA enabled but not verified, QR code and verification
23 * @package Friendica\Module\TwoFactor\Settings
25 class Verify extends BaseSettingsModule
27 public static function init()
33 $secret = PConfig::get(local_user(), '2fa', 'secret');
34 $verified = PConfig::get(local_user(), '2fa', 'verified');
36 if ($secret && $verified) {
37 self::getApp()->internalRedirect('settings/2fa');
40 if (!self::checkFormSecurityToken('settings_2fa_password', 't')) {
41 notice(L10n::t('Please enter your password to access this page.'));
42 self::getApp()->internalRedirect('settings/2fa');
46 public static function post()
52 if (($_POST['action'] ?? '') == 'verify') {
53 self::checkFormSecurityTokenRedirectOnError('settings/2fa/verify', 'settings_2fa_verify');
55 $google2fa = new Google2FA();
57 $valid = $google2fa->verifyKey(PConfig::get(local_user(), '2fa', 'secret'), $_POST['verify_code'] ?? '');
60 PConfig::set(local_user(), '2fa', 'verified', true);
61 Session::set('2fa', true);
63 notice(L10n::t('Two-factor authentication successfully activated.'));
65 self::getApp()->internalRedirect('settings/2fa');
67 notice(L10n::t('Invalid code, please retry.'));
72 public static function content()
75 return Login::form('settings/2fa/verify');
80 $company = 'Friendica';
81 $holder = Session::get('my_address');
82 $secret = PConfig::get(local_user(), '2fa', 'secret');
84 $otpauthUrl = (new Google2FA())->getQRCodeUrl($company, $holder, $secret);
86 $renderer = (new \BaconQrCode\Renderer\Image\Svg())
90 $writer = new Writer($renderer);
92 $qrcode_image = str_replace('<?xml version="1.0" encoding="UTF-8"?>', '', $writer->writeString($otpauthUrl));
94 $shortOtpauthUrl = explode('?', $otpauthUrl)[0];
96 $manual_message = L10n::t('<p>Or you can submit the authentication settings manually:</p>
100 <dt>Account Name</dt>
106 <dt>Number of digits</dt>
108 <dt>Hashing algorithm</dt>
110 </dl>', $company, $holder, $secret);
112 return Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/twofactor/verify.tpl'), [
113 '$form_security_token' => self::getFormSecurityToken('settings_2fa_verify'),
114 '$password_security_token' => self::getFormSecurityToken('settings_2fa_password'),
116 '$title' => L10n::t('Two-factor code verification'),
117 '$help_label' => L10n::t('Help'),
118 '$message' => L10n::t('<p>Please scan this QR Code with your authenticator app and submit the provided code.</p>'),
119 '$qrcode_image' => $qrcode_image,
120 '$qrcode_url_message' => L10n::t('<p>Or you can open the following URL in your mobile devicde:</p><p><a href="%s">%s</a></p>', $otpauthUrl, $shortOtpauthUrl),
121 '$manual_message' => $manual_message,
122 '$company' => $company,
123 '$holder' => $holder,
124 '$secret' => $secret,
126 '$verify_code' => ['verify_code', L10n::t('Please enter a code from your authentication app'), '', '', 'required', 'autofocus placeholder="000000"'],
127 '$verify_label' => L10n::t('Verify code and enable two-factor authentication'),