2019-05-13 01:38:15 -04:00
< ? php
2020-02-09 09:45:36 -05:00
/**
2021-03-29 02:40:20 -04:00
* @ copyright Copyright ( C ) 2010 - 2021 , the Friendica project
2020-02-09 09:45:36 -05:00
*
* @ license GNU AGPL version 3 or any later version
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation , either version 3 of the
* License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*
*/
2019-05-13 01:38:15 -04:00
namespace Friendica\Module\Settings\TwoFactor ;
use BaconQrCode\Renderer\Image\SvgImageBackEnd ;
use BaconQrCode\Renderer\ImageRenderer ;
use BaconQrCode\Renderer\RendererStyle\RendererStyle ;
use BaconQrCode\Writer ;
2021-11-20 09:38:03 -05:00
use Friendica\App ;
2021-11-19 14:18:48 -05:00
use Friendica\Core\L10n ;
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues ;
2019-05-13 01:38:15 -04:00
use Friendica\Core\Renderer ;
use Friendica\Core\Session ;
2020-01-22 23:14:14 -05:00
use Friendica\Module\BaseSettings ;
2021-11-21 14:06:36 -05:00
use Friendica\Module\Response ;
2019-12-27 16:19:28 -05:00
use Friendica\Module\Security\Login ;
2021-11-20 09:38:03 -05:00
use Friendica\Util\Profiler ;
2019-05-13 01:38:15 -04:00
use PragmaRX\Google2FA\Google2FA ;
2021-11-20 09:38:03 -05:00
use Psr\Log\LoggerInterface ;
2019-05-13 01:38:15 -04:00
/**
* // Page 4: 2FA enabled but not verified, QR code and verification
*
* @ package Friendica\Module\TwoFactor\Settings
*/
2020-01-22 23:14:14 -05:00
class Verify extends BaseSettings
2019-05-13 01:38:15 -04:00
{
2021-11-19 14:18:48 -05:00
/** @var IManagePersonalConfigValues */
protected $pConfig ;
2021-11-21 14:06:36 -05:00
public function __construct ( L10n $l10n , App\BaseURL $baseUrl , App\Arguments $args , LoggerInterface $logger , Profiler $profiler , Response $response , IManagePersonalConfigValues $pConfig , array $server , array $parameters = [])
2019-05-13 01:38:15 -04:00
{
2021-11-21 14:06:36 -05:00
parent :: __construct ( $l10n , $baseUrl , $args , $logger , $profiler , $response , $server , $parameters );
2021-11-19 14:18:48 -05:00
$this -> pConfig = $pConfig ;
2019-05-13 01:38:15 -04:00
if ( ! local_user ()) {
return ;
}
2021-11-19 14:18:48 -05:00
$secret = $this -> pConfig -> get ( local_user (), '2fa' , 'secret' );
$verified = $this -> pConfig -> get ( local_user (), '2fa' , 'verified' );
2019-05-13 01:38:15 -04:00
if ( $secret && $verified ) {
2021-11-19 14:18:48 -05:00
$this -> baseUrl -> redirect ( 'settings/2fa' );
2019-05-13 01:38:15 -04:00
}
if ( ! self :: checkFormSecurityToken ( 'settings_2fa_password' , 't' )) {
2021-11-19 14:18:48 -05:00
notice ( $this -> t ( 'Please enter your password to access this page.' ));
$this -> baseUrl -> redirect ( 'settings/2fa' );
2019-05-13 01:38:15 -04:00
}
}
2021-11-20 09:38:03 -05:00
protected function post ( array $request = [], array $post = [])
2019-05-13 01:38:15 -04:00
{
if ( ! local_user ()) {
return ;
}
2019-10-15 09:20:32 -04:00
if (( $_POST [ 'action' ] ? ? '' ) == 'verify' ) {
2019-05-13 01:38:15 -04:00
self :: checkFormSecurityTokenRedirectOnError ( 'settings/2fa/verify' , 'settings_2fa_verify' );
$google2fa = new Google2FA ();
2021-11-19 14:18:48 -05:00
$valid = $google2fa -> verifyKey ( $this -> pConfig -> get ( local_user (), '2fa' , 'secret' ), $_POST [ 'verify_code' ] ? ? '' );
2019-05-13 01:38:15 -04:00
if ( $valid ) {
2021-11-19 14:18:48 -05:00
$this -> pConfig -> set ( local_user (), '2fa' , 'verified' , true );
2019-05-13 01:38:15 -04:00
Session :: set ( '2fa' , true );
2021-11-19 14:18:48 -05:00
info ( $this -> t ( 'Two-factor authentication successfully activated.' ));
2019-05-13 01:38:15 -04:00
2021-11-19 14:18:48 -05:00
$this -> baseUrl -> redirect ( 'settings/2fa' );
2019-05-13 01:38:15 -04:00
} else {
2021-11-19 14:18:48 -05:00
notice ( $this -> t ( 'Invalid code, please retry.' ));
2019-05-13 01:38:15 -04:00
}
}
}
2021-11-20 09:38:03 -05:00
protected function content ( array $request = []) : string
2019-05-13 01:38:15 -04:00
{
if ( ! local_user ()) {
return Login :: form ( 'settings/2fa/verify' );
}
2021-11-14 14:46:25 -05:00
parent :: content ();
2019-05-13 01:38:15 -04:00
$company = 'Friendica' ;
$holder = Session :: get ( 'my_address' );
2021-11-19 14:18:48 -05:00
$secret = $this -> pConfig -> get ( local_user (), '2fa' , 'secret' );
2019-05-13 01:38:15 -04:00
$otpauthUrl = ( new Google2FA ()) -> getQRCodeUrl ( $company , $holder , $secret );
$renderer = ( new \BaconQrCode\Renderer\Image\Svg ())
-> setHeight ( 256 )
-> setWidth ( 256 );
$writer = new Writer ( $renderer );
$qrcode_image = str_replace ( '<?xml version="1.0" encoding="UTF-8"?>' , '' , $writer -> writeString ( $otpauthUrl ));
$shortOtpauthUrl = explode ( '?' , $otpauthUrl )[ 0 ];
2021-11-19 14:18:48 -05:00
$manual_message = $this -> t ( ' < p > Or you can submit the authentication settings manually :</ p >
2019-05-13 01:38:15 -04:00
< dl >
< dt > Issuer </ dt >
< dd >% s </ dd >
< dt > Account Name </ dt >
< dd >% s </ dd >
< dt > Secret Key </ dt >
< dd >% s </ dd >
< dt > Type </ dt >
< dd > Time - based </ dd >
< dt > Number of digits </ dt >
< dd > 6 </ dd >
< dt > Hashing algorithm </ dt >
< dd > SHA - 1 </ dd >
</ dl > ' , $company , $holder , $secret );
return Renderer :: replaceMacros ( Renderer :: getMarkupTemplate ( 'settings/twofactor/verify.tpl' ), [
2019-05-13 13:31:08 -04:00
'$form_security_token' => self :: getFormSecurityToken ( 'settings_2fa_verify' ),
2019-05-13 01:38:15 -04:00
'$password_security_token' => self :: getFormSecurityToken ( 'settings_2fa_password' ),
2019-05-13 13:31:08 -04:00
2021-11-19 14:18:48 -05:00
'$title' => $this -> t ( 'Two-factor code verification' ),
'$help_label' => $this -> t ( 'Help' ),
'$message' => $this -> t ( '<p>Please scan this QR Code with your authenticator app and submit the provided code.</p>' ),
2019-05-13 13:31:08 -04:00
'$qrcode_image' => $qrcode_image ,
2021-11-19 14:18:48 -05:00
'$qrcode_url_message' => $this -> t ( '<p>Or you can open the following URL in your mobile device:</p><p><a href="%s">%s</a></p>' , $otpauthUrl , $shortOtpauthUrl ),
2019-05-13 13:31:08 -04:00
'$manual_message' => $manual_message ,
'$company' => $company ,
'$holder' => $holder ,
'$secret' => $secret ,
2019-05-13 01:38:15 -04:00
2021-11-19 14:18:48 -05:00
'$verify_code' => [ 'verify_code' , $this -> t ( 'Please enter a code from your authentication app' ), '' , '' , $this -> t ( 'Required' ), 'autofocus autocomplete="off" placeholder="000000"' ],
'$verify_label' => $this -> t ( 'Verify code and enable two-factor authentication' ),
2019-05-13 01:38:15 -04:00
]);
}
}