2019-05-13 05:36:09 +00:00
< ? php
2020-02-09 14:45:36 +00:00
/**
2021-03-29 06:40:20 +00:00
* @ copyright Copyright ( C ) 2010 - 2021 , the Friendica project
2020-02-09 14:45:36 +00: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 05:36:09 +00:00
2019-12-27 21:19:28 +00:00
namespace Friendica\Module\Security\TwoFactor ;
2019-05-13 05:36:09 +00:00
use Friendica\BaseModule ;
use Friendica\Core\Renderer ;
use Friendica\Core\Session ;
2019-12-15 21:34:11 +00:00
use Friendica\DI ;
2021-08-08 19:30:21 +00:00
use Friendica\Model\User ;
2019-05-13 05:36:09 +00:00
use PragmaRX\Google2FA\Google2FA ;
2021-01-19 04:32:48 +00:00
use Friendica\Security\TwoFactor ;
2019-05-13 05:36:09 +00:00
/**
* Page 1 : Authenticator code verification
*
* @ package Friendica\Module\TwoFactor
*/
class Verify extends BaseModule
{
2019-07-24 00:02:26 +00:00
private static $errors = [];
2019-11-05 21:48:54 +00:00
public static function post ( array $parameters = [])
2019-05-13 05:36:09 +00:00
{
if ( ! local_user ()) {
return ;
}
2019-07-24 00:02:26 +00:00
if (( $_POST [ 'action' ] ? ? '' ) == 'verify' ) {
2019-05-13 05:36:09 +00:00
self :: checkFormSecurityTokenRedirectOnError ( '2fa' , 'twofactor_verify' );
2019-12-15 21:34:11 +00:00
$a = DI :: app ();
2019-05-13 05:36:09 +00:00
2019-07-24 00:02:26 +00:00
$code = $_POST [ 'verify_code' ] ? ? '' ;
2019-05-13 05:36:09 +00:00
2020-01-18 15:50:57 +00:00
$valid = ( new Google2FA ()) -> verifyKey ( DI :: pConfig () -> get ( local_user (), '2fa' , 'secret' ), $code );
2019-05-13 05:36:09 +00: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 04:32:48 +00: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 05:36:09 +00:00
// Resume normal login workflow
2021-08-08 19:30:21 +00:00
DI :: auth () -> setForUser ( $a , User :: getById ( $a -> getUserId ()), true , true );
2019-05-13 05:36:09 +00:00
} else {
2020-01-18 19:52:34 +00:00
self :: $errors [] = DI :: l10n () -> t ( 'Invalid code, please retry.' );
2019-05-13 05:36:09 +00:00
}
}
}
2019-11-05 21:48:54 +00:00
public static function content ( array $parameters = [])
2019-05-13 05:36:09 +00:00
{
if ( ! local_user ()) {
2019-12-15 23:28:31 +00:00
DI :: baseUrl () -> redirect ();
2019-05-13 05:36:09 +00:00
}
// Already authenticated with 2FA token
if ( Session :: get ( '2fa' )) {
2019-12-15 23:28:31 +00:00
DI :: baseUrl () -> redirect ();
2019-05-13 05:36:09 +00:00
}
return Renderer :: replaceMacros ( Renderer :: getMarkupTemplate ( 'twofactor/verify.tpl' ), [
'$form_security_token' => self :: getFormSecurityToken ( 'twofactor_verify' ),
2019-05-13 17:31:08 +00:00
2020-01-18 19:52:34 +00: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 19:53:01 +00:00
'$errors_label' => DI :: l10n () -> tt ( 'Error' , 'Errors' , count ( self :: $errors )),
2019-07-24 00:02:26 +00:00
'$errors' => self :: $errors ,
2020-01-18 19:52:34 +00: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 05:25:21 +00: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 04:32:48 +00:00
'$trust_browser' => [ 'trust_browser' , DI :: l10n () -> t ( 'This is my two-factor authenticator app device' ), ! empty ( $_REQUEST [ 'trust_browser' ])],
2020-01-18 19:52:34 +00:00
'$verify_label' => DI :: l10n () -> t ( 'Verify code and complete login' ),
2019-05-13 05:36:09 +00:00
]);
}
}