2019-05-13 05:38:15 +00:00
< ? php
2020-02-09 14:45:36 +00:00
/**
2022-01-02 07:27:47 +00:00
* @ copyright Copyright ( C ) 2010 - 2022 , 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:38:15 +00:00
namespace Friendica\Module\Settings\TwoFactor ;
use Friendica\Core\Renderer ;
use Friendica\Core\Session ;
2019-12-15 21:34:11 +00:00
use Friendica\DI ;
2022-06-25 12:45:33 +00:00
use Friendica\Network\HTTPException\FoundException ;
2021-01-19 03:53:06 +00:00
use Friendica\Security\TwoFactor\Model\AppSpecificPassword ;
use Friendica\Security\TwoFactor\Model\RecoveryCode ;
2019-05-13 05:38:15 +00:00
use Friendica\Model\User ;
2020-01-23 04:14:14 +00:00
use Friendica\Module\BaseSettings ;
2019-12-27 21:19:28 +00:00
use Friendica\Module\Security\Login ;
2019-05-13 05:38:15 +00:00
use PragmaRX\Google2FA\Google2FA ;
2020-01-23 04:14:14 +00:00
class Index extends BaseSettings
2019-05-13 05:38:15 +00:00
{
2021-11-28 12:44:42 +00:00
protected function post ( array $request = [])
2019-05-13 05:38:15 +00:00
{
if ( ! local_user ()) {
return ;
}
self :: checkFormSecurityTokenRedirectOnError ( 'settings/2fa' , 'settings_2fa' );
try {
2019-10-15 13:20:32 +00:00
User :: getIdFromPasswordAuthentication ( local_user (), $_POST [ 'password' ] ? ? '' );
2019-05-13 05:38:15 +00:00
2020-01-18 15:50:57 +00:00
$has_secret = ( bool ) DI :: pConfig () -> get ( local_user (), '2fa' , 'secret' );
$verified = DI :: pConfig () -> get ( local_user (), '2fa' , 'verified' );
2019-05-13 05:38:15 +00:00
2019-10-15 13:20:32 +00:00
switch ( $_POST [ 'action' ] ? ? '' ) {
2019-05-13 05:38:15 +00:00
case 'enable' :
if ( ! $has_secret && ! $verified ) {
$Google2FA = new Google2FA ();
2020-01-18 15:54:50 +00:00
DI :: pConfig () -> set ( local_user (), '2fa' , 'secret' , $Google2FA -> generateSecretKey ( 32 ));
2019-05-13 05:38:15 +00:00
2019-12-15 23:28:31 +00:00
DI :: baseUrl () -> redirect ( 'settings/2fa/recovery?t=' . self :: getFormSecurityToken ( 'settings_2fa_password' ));
2019-05-13 05:38:15 +00:00
}
break ;
case 'disable' :
if ( $has_secret ) {
2019-07-22 11:41:01 +00:00
RecoveryCode :: deleteForUser ( local_user ());
2020-01-18 15:56:46 +00:00
DI :: pConfig () -> delete ( local_user (), '2fa' , 'secret' );
DI :: pConfig () -> delete ( local_user (), '2fa' , 'verified' );
2019-05-13 05:38:15 +00:00
Session :: remove ( '2fa' );
2020-09-07 10:17:42 +00:00
info ( DI :: l10n () -> t ( 'Two-factor authentication successfully disabled.' ));
2019-12-15 23:28:31 +00:00
DI :: baseUrl () -> redirect ( 'settings/2fa' );
2019-05-13 05:38:15 +00:00
}
break ;
case 'recovery' :
if ( $has_secret ) {
2019-12-15 23:28:31 +00:00
DI :: baseUrl () -> redirect ( 'settings/2fa/recovery?t=' . self :: getFormSecurityToken ( 'settings_2fa_password' ));
2019-05-13 05:38:15 +00:00
}
break ;
2019-07-22 11:56:00 +00:00
case 'app_specific' :
if ( $has_secret ) {
2019-12-15 23:28:31 +00:00
DI :: baseUrl () -> redirect ( 'settings/2fa/app_specific?t=' . self :: getFormSecurityToken ( 'settings_2fa_password' ));
2019-07-22 11:56:00 +00:00
}
break ;
2021-01-20 04:44:19 +00:00
case 'trusted' :
if ( $has_secret ) {
DI :: baseUrl () -> redirect ( 'settings/2fa/trusted?t=' . self :: getFormSecurityToken ( 'settings_2fa_password' ));
}
break ;
2019-05-13 05:38:15 +00:00
case 'configure' :
if ( ! $verified ) {
2019-12-15 23:28:31 +00:00
DI :: baseUrl () -> redirect ( 'settings/2fa/verify?t=' . self :: getFormSecurityToken ( 'settings_2fa_password' ));
2019-05-13 05:38:15 +00:00
}
break ;
}
} catch ( \Exception $e ) {
2022-06-25 12:45:33 +00:00
if ( ! ( $e instanceof FoundException )) {
notice ( DI :: l10n () -> t ( $e -> getMessage ()));
}
2019-05-13 05:38:15 +00:00
}
}
2021-11-20 14:38:03 +00:00
protected function content ( array $request = []) : string
2019-05-13 05:38:15 +00:00
{
if ( ! local_user ()) {
return Login :: form ( 'settings/2fa' );
}
2021-11-14 19:46:25 +00:00
parent :: content ();
2019-05-13 05:38:15 +00:00
2020-01-18 15:50:57 +00:00
$has_secret = ( bool ) DI :: pConfig () -> get ( local_user (), '2fa' , 'secret' );
$verified = DI :: pConfig () -> get ( local_user (), '2fa' , 'verified' );
2019-05-13 05:38:15 +00:00
return Renderer :: replaceMacros ( Renderer :: getMarkupTemplate ( 'settings/twofactor/index.tpl' ), [
'$form_security_token' => self :: getFormSecurityToken ( 'settings_2fa' ),
2020-01-18 19:52:34 +00:00
'$title' => DI :: l10n () -> t ( 'Two-factor authentication' ),
'$help_label' => DI :: l10n () -> t ( 'Help' ),
'$status_title' => DI :: l10n () -> t ( 'Status' ),
'$message' => DI :: l10n () -> t ( '<p>Use an application on a mobile device to get two-factor authentication codes when prompted on login.</p>' ),
2019-05-13 17:31:08 +00:00
'$has_secret' => $has_secret ,
'$verified' => $verified ,
2020-01-18 19:52:34 +00:00
'$auth_app_label' => DI :: l10n () -> t ( 'Authenticator app' ),
'$app_status' => $has_secret ? $verified ? DI :: l10n () -> t ( 'Configured' ) : DI :: l10n () -> t ( 'Not Configured' ) : DI :: l10n () -> t ( 'Disabled' ),
'$not_configured_message' => DI :: l10n () -> t ( '<p>You haven\'t finished configuring your authenticator app.</p>' ),
'$configured_message' => DI :: l10n () -> t ( '<p>Your authenticator app is correctly configured.</p>' ),
2019-05-13 05:38:15 +00:00
2020-01-18 19:52:34 +00:00
'$recovery_codes_title' => DI :: l10n () -> t ( 'Recovery codes' ),
'$recovery_codes_remaining' => DI :: l10n () -> t ( 'Remaining valid codes' ),
2019-07-22 11:41:01 +00:00
'$recovery_codes_count' => RecoveryCode :: countValidForUser ( local_user ()),
2020-01-18 19:52:34 +00:00
'$recovery_codes_message' => DI :: l10n () -> t ( '<p>These one-use codes can replace an authenticator app code in case you have lost access to it.</p>' ),
2019-05-13 05:38:15 +00:00
2020-01-18 19:52:34 +00:00
'$app_specific_passwords_title' => DI :: l10n () -> t ( 'App-specific passwords' ),
'$app_specific_passwords_remaining' => DI :: l10n () -> t ( 'Generated app-specific passwords' ),
2019-07-22 11:56:00 +00:00
'$app_specific_passwords_count' => AppSpecificPassword :: countForUser ( local_user ()),
2020-01-18 19:52:34 +00:00
'$app_specific_passwords_message' => DI :: l10n () -> t ( '<p>These randomly generated passwords allow you to authenticate on apps not supporting two-factor authentication.</p>' ),
'$action_title' => DI :: l10n () -> t ( 'Actions' ),
2020-12-20 03:41:42 +00:00
'$password' => [ 'password' , DI :: l10n () -> t ( 'Current password:' ), '' , DI :: l10n () -> t ( 'You need to provide your current password to change two-factor authentication settings.' ), DI :: l10n () -> t ( 'Required' ), 'autofocus' ],
2020-01-18 19:52:34 +00:00
'$enable_label' => DI :: l10n () -> t ( 'Enable two-factor authentication' ),
'$disable_label' => DI :: l10n () -> t ( 'Disable two-factor authentication' ),
'$recovery_codes_label' => DI :: l10n () -> t ( 'Show recovery codes' ),
'$app_specific_passwords_label' => DI :: l10n () -> t ( 'Manage app-specific passwords' ),
2021-01-20 04:44:19 +00:00
'$trusted_browsers_label' => DI :: l10n () -> t ( 'Manage trusted browsers' ),
2020-01-18 19:52:34 +00:00
'$configure_label' => DI :: l10n () -> t ( 'Finish app configuration' ),
2019-05-13 05:38:15 +00:00
]);
}
}