2019-05-13 07:36:09 +02:00
< ? php
2020-02-09 15:45:36 +01:00
/**
2021-03-29 08:40:20 +02:00
* @ copyright Copyright ( C ) 2010 - 2021 , the Friendica project
2020-02-09 15:45:36 +01: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 07:36:09 +02:00
2019-12-27 22:19:28 +01:00
namespace Friendica\Module\Security\TwoFactor ;
2019-05-13 07:36:09 +02:00
use Friendica\BaseModule ;
use Friendica\Core\Renderer ;
use Friendica\Core\Session ;
2019-12-15 22:34:11 +01:00
use Friendica\DI ;
2021-08-08 21:30:21 +02:00
use Friendica\Model\User ;
2019-05-13 07:36:09 +02:00
use PragmaRX\Google2FA\Google2FA ;
2021-01-19 05:32:48 +01:00
use Friendica\Security\TwoFactor ;
2019-05-13 07:36:09 +02:00
/**
* Page 1 : Authenticator code verification
*
* @ package Friendica\Module\TwoFactor
*/
class Verify extends BaseModule
{
2019-07-24 02:02:26 +02:00
private static $errors = [];
2021-11-14 23:13:47 +01:00
public function post ()
2019-05-13 07:36:09 +02:00
{
if ( ! local_user ()) {
return ;
}
2019-07-24 02:02:26 +02:00
if (( $_POST [ 'action' ] ? ? '' ) == 'verify' ) {
2019-05-13 07:36:09 +02:00
self :: checkFormSecurityTokenRedirectOnError ( '2fa' , 'twofactor_verify' );
2019-12-15 22:34:11 +01:00
$a = DI :: app ();
2019-05-13 07:36:09 +02:00
2019-07-24 02:02:26 +02:00
$code = $_POST [ 'verify_code' ] ? ? '' ;
2019-05-13 07:36:09 +02:00
2020-01-18 16:50:57 +01:00
$valid = ( new Google2FA ()) -> verifyKey ( DI :: pConfig () -> get ( local_user (), '2fa' , 'secret' ), $code );
2019-05-13 07:36:09 +02:00
// The same code can't be used twice even if it's valid
if ( $valid && Session :: get ( '2fa' ) !== $code ) {
Session :: set ( '2fa' , $code );
2021-01-19 05:32:48 +01:00
// Trust this browser feature
if ( ! empty ( $_REQUEST [ 'trust_browser' ])) {
$trustedBrowserFactory = new TwoFactor\Factory\TrustedBrowser ( DI :: logger ());
$trustedBrowserRepository = new TwoFactor\Repository\TrustedBrowser ( DI :: dba (), DI :: logger (), $trustedBrowserFactory );
$trustedBrowser = $trustedBrowserFactory -> createForUserWithUserAgent ( local_user (), $_SERVER [ 'HTTP_USER_AGENT' ]);
$trustedBrowserRepository -> save ( $trustedBrowser );
// The string is sent to the browser to be sent back with each request
DI :: cookie () -> set ( 'trusted' , $trustedBrowser -> cookie_hash );
}
2019-05-13 07:36:09 +02:00
// Resume normal login workflow
2021-08-09 22:33:46 +02:00
DI :: auth () -> setForUser ( $a , User :: getById ( $a -> getLoggedInUserId ()), true , true );
2019-05-13 07:36:09 +02:00
} else {
2020-01-18 20:52:34 +01:00
self :: $errors [] = DI :: l10n () -> t ( 'Invalid code, please retry.' );
2019-05-13 07:36:09 +02:00
}
}
}
2021-11-14 23:13:47 +01:00
public function content () : string
2019-05-13 07:36:09 +02:00
{
if ( ! local_user ()) {
2019-12-16 00:28:31 +01:00
DI :: baseUrl () -> redirect ();
2019-05-13 07:36:09 +02:00
}
// Already authenticated with 2FA token
if ( Session :: get ( '2fa' )) {
2019-12-16 00:28:31 +01:00
DI :: baseUrl () -> redirect ();
2019-05-13 07:36:09 +02:00
}
return Renderer :: replaceMacros ( Renderer :: getMarkupTemplate ( 'twofactor/verify.tpl' ), [
'$form_security_token' => self :: getFormSecurityToken ( 'twofactor_verify' ),
2019-05-13 19:31:08 +02:00
2020-01-18 20:52:34 +01:00
'$title' => DI :: l10n () -> t ( 'Two-factor authentication' ),
'$message' => DI :: l10n () -> t ( '<p>Open the two-factor authentication app on your device to get an authentication code and verify your identity.</p>' ),
2020-01-18 20:53:01 +01:00
'$errors_label' => DI :: l10n () -> tt ( 'Error' , 'Errors' , count ( self :: $errors )),
2019-07-24 02:02:26 +02:00
'$errors' => self :: $errors ,
2020-01-18 20:52:34 +01:00
'$recovery_message' => DI :: l10n () -> t ( 'Don’ t have your phone? <a href="%s">Enter a two-factor recovery code</a>' , '2fa/recovery' ),
2020-12-21 06:25:21 +01:00
'$verify_code' => [ 'verify_code' , DI :: l10n () -> t ( 'Please enter a code from your authentication app' ), '' , '' , DI :: l10n () -> t ( 'Required' ), 'autofocus autocomplete="off" placeholder="000000"' , 'tel' ],
2021-01-19 05:32:48 +01:00
'$trust_browser' => [ 'trust_browser' , DI :: l10n () -> t ( 'This is my two-factor authenticator app device' ), ! empty ( $_REQUEST [ 'trust_browser' ])],
2020-01-18 20:52:34 +01:00
'$verify_label' => DI :: l10n () -> t ( 'Verify code and complete login' ),
2019-05-13 07:36:09 +02:00
]);
}
}