2019-07-22 07:56:00 -04:00
< ? php
2020-02-09 15:45:36 +01:00
/**
2022-01-02 08:27:47 +01:00
* @ copyright Copyright ( C ) 2010 - 2022 , 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-07-22 07:56:00 -04:00
namespace Friendica\Module\Settings\TwoFactor ;
2021-11-20 15:38:03 +01:00
use Friendica\App ;
2021-11-19 20:18:48 +01:00
use Friendica\Core\L10n ;
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues ;
2019-07-22 07:56:00 -04:00
use Friendica\Core\Renderer ;
2022-11-19 13:33:05 -05:00
use Friendica\Core\Session\Capability\IHandleUserSessions ;
2022-10-17 18:55:22 +00:00
use Friendica\DI ;
2021-11-21 20:06:36 +01:00
use Friendica\Module\Response ;
2021-01-18 22:53:06 -05:00
use Friendica\Security\TwoFactor\Model\AppSpecificPassword ;
2020-01-22 23:14:14 -05:00
use Friendica\Module\BaseSettings ;
2019-12-27 22:19:28 +01:00
use Friendica\Module\Security\Login ;
2021-11-20 15:38:03 +01:00
use Friendica\Util\Profiler ;
use Psr\Log\LoggerInterface ;
2019-07-22 07:56:00 -04:00
/**
* // Page 5: 2FA enabled, app-specific password generation
*
* @ package Friendica\Module\TwoFactor
*/
2020-01-22 23:14:14 -05:00
class AppSpecific extends BaseSettings
2019-07-22 07:56:00 -04:00
{
2021-11-19 20:18:48 +01:00
private $appSpecificPassword = null ;
/** @var IManagePersonalConfigValues */
protected $pConfig ;
2021-11-20 15:38:03 +01:00
2022-11-19 13:33:05 -05:00
public function __construct ( IManagePersonalConfigValues $pConfig , IHandleUserSessions $session , App\Page $page , L10n $l10n , App\BaseURL $baseUrl , App\Arguments $args , LoggerInterface $logger , Profiler $profiler , Response $response , array $server , array $parameters = [])
2021-11-19 07:23:23 -05:00
{
2022-11-19 13:33:05 -05:00
parent :: __construct ( $session , $page , $l10n , $baseUrl , $args , $logger , $profiler , $response , $server , $parameters );
2021-11-19 20:18:48 +01:00
$this -> pConfig = $pConfig ;
2022-10-20 22:59:12 +02:00
if ( ! DI :: userSession () -> getLocalUserId ()) {
2019-07-22 07:56:00 -04:00
return ;
}
2022-10-20 22:59:12 +02:00
$verified = $this -> pConfig -> get ( DI :: userSession () -> getLocalUserId (), '2fa' , 'verified' );
2019-07-22 07:56:00 -04:00
if ( ! $verified ) {
2021-11-19 20:18:48 +01:00
$this -> baseUrl -> redirect ( 'settings/2fa' );
2019-07-22 07:56:00 -04:00
}
if ( ! self :: checkFormSecurityToken ( 'settings_2fa_password' , 't' )) {
2022-10-17 18:55:22 +00:00
DI :: sysmsg () -> addNotice ( $this -> t ( 'Please enter your password to access this page.' ));
2021-11-19 20:18:48 +01:00
$this -> baseUrl -> redirect ( 'settings/2fa' );
2019-07-22 07:56:00 -04:00
}
}
2021-11-28 13:44:42 +01:00
protected function post ( array $request = [])
2019-07-22 07:56:00 -04:00
{
2022-10-20 22:59:12 +02:00
if ( ! DI :: userSession () -> getLocalUserId ()) {
2019-07-22 07:56:00 -04:00
return ;
}
if ( ! empty ( $_POST [ 'action' ])) {
self :: checkFormSecurityTokenRedirectOnError ( 'settings/2fa/app_specific' , 'settings_2fa_app_specific' );
switch ( $_POST [ 'action' ]) {
case 'generate' :
$description = $_POST [ 'description' ] ? ? '' ;
if ( empty ( $description )) {
2022-10-17 18:55:22 +00:00
DI :: sysmsg () -> addNotice ( $this -> t ( 'App-specific password generation failed: The description is empty.' ));
2021-11-19 20:18:48 +01:00
$this -> baseUrl -> redirect ( 'settings/2fa/app_specific?t=' . self :: getFormSecurityToken ( 'settings_2fa_password' ));
2022-10-20 22:59:12 +02:00
} elseif ( AppSpecificPassword :: checkDuplicateForUser ( DI :: userSession () -> getLocalUserId (), $description )) {
2022-10-17 18:55:22 +00:00
DI :: sysmsg () -> addNotice ( $this -> t ( 'App-specific password generation failed: This description already exists.' ));
2021-11-19 20:18:48 +01:00
$this -> baseUrl -> redirect ( 'settings/2fa/app_specific?t=' . self :: getFormSecurityToken ( 'settings_2fa_password' ));
2019-07-22 07:56:00 -04:00
} else {
2022-10-20 22:59:12 +02:00
$this -> appSpecificPassword = AppSpecificPassword :: generateForUser ( DI :: userSession () -> getLocalUserId (), $_POST [ 'description' ] ? ? '' );
2022-10-17 18:55:22 +00:00
DI :: sysmsg () -> addInfo ( $this -> t ( 'New app-specific password generated.' ));
2019-07-22 07:56:00 -04:00
}
break ;
case 'revoke_all' :
2022-10-20 22:59:12 +02:00
AppSpecificPassword :: deleteAllForUser ( DI :: userSession () -> getLocalUserId ());
2022-10-17 18:55:22 +00:00
DI :: sysmsg () -> addInfo ( $this -> t ( 'App-specific passwords successfully revoked.' ));
2021-11-19 20:18:48 +01:00
$this -> baseUrl -> redirect ( 'settings/2fa/app_specific?t=' . self :: getFormSecurityToken ( 'settings_2fa_password' ));
2019-07-22 07:56:00 -04:00
break ;
}
}
if ( ! empty ( $_POST [ 'revoke_id' ])) {
self :: checkFormSecurityTokenRedirectOnError ( 'settings/2fa/app_specific' , 'settings_2fa_app_specific' );
2022-10-20 22:59:12 +02:00
if ( AppSpecificPassword :: deleteForUser ( DI :: userSession () -> getLocalUserId (), $_POST [ 'revoke_id' ])) {
2022-10-17 18:55:22 +00:00
DI :: sysmsg () -> addInfo ( $this -> t ( 'App-specific password successfully revoked.' ));
2019-07-22 07:56:00 -04:00
}
2021-11-19 20:18:48 +01:00
$this -> baseUrl -> redirect ( 'settings/2fa/app_specific?t=' . self :: getFormSecurityToken ( 'settings_2fa_password' ));
2019-07-22 07:56:00 -04:00
}
}
2021-11-20 15:38:03 +01:00
protected function content ( array $request = []) : string
2019-07-22 07:56:00 -04:00
{
2022-10-20 22:59:12 +02:00
if ( ! DI :: userSession () -> getLocalUserId ()) {
2019-07-22 07:56:00 -04:00
return Login :: form ( 'settings/2fa/app_specific' );
}
2021-11-14 20:46:25 +01:00
parent :: content ();
2019-07-22 07:56:00 -04:00
2022-10-20 22:59:12 +02:00
$appSpecificPasswords = AppSpecificPassword :: getListForUser ( DI :: userSession () -> getLocalUserId ());
2019-07-22 07:56:00 -04:00
return Renderer :: replaceMacros ( Renderer :: getMarkupTemplate ( 'settings/twofactor/app_specific.tpl' ), [
'$form_security_token' => self :: getFormSecurityToken ( 'settings_2fa_app_specific' ),
'$password_security_token' => self :: getFormSecurityToken ( 'settings_2fa_password' ),
2021-11-19 20:18:48 +01:00
'$title' => $this -> t ( 'Two-factor app-specific passwords' ),
'$help_label' => $this -> t ( 'Help' ),
'$message' => $this -> t ( '<p>App-specific passwords are randomly generated passwords used instead your regular password to authenticate your account on third-party applications that don\'t support two-factor authentication.</p>' ),
'$generated_message' => $this -> t ( 'Make sure to copy your new app-specific password now. You won’ t be able to see it again!' ),
'$generated_app_specific_password' => $this -> appSpecificPassword ,
2019-07-22 07:56:00 -04:00
2021-11-19 20:18:48 +01:00
'$description_label' => $this -> t ( 'Description' ),
'$last_used_label' => $this -> t ( 'Last Used' ),
'$revoke_label' => $this -> t ( 'Revoke' ),
'$revoke_all_label' => $this -> t ( 'Revoke All' ),
2019-07-22 07:56:00 -04:00
'$app_specific_passwords' => $appSpecificPasswords ,
2021-11-19 20:18:48 +01:00
'$generate_message' => $this -> t ( 'When you generate a new app-specific password, you must use it right away, it will be shown to you once after you generate it.' ),
'$generate_title' => $this -> t ( 'Generate new app-specific password' ),
'$description_placeholder_label' => $this -> t ( 'Friendiqa on my Fairphone 2...' ),
'$generate_label' => $this -> t ( 'Generate' ),
2019-07-22 07:56:00 -04:00
]);
}
}