2022-11-24 07:53:52 +00:00
< ? php
2024-03-06 17:34:21 +00:00
use Appwrite\Extend\Exception ;
2025-11-04 06:08:35 +00:00
use Appwrite\Utopia\Database\Documents\User ;
2022-11-24 07:53:52 +00:00
use Appwrite\Utopia\Request ;
2024-03-06 17:34:21 +00:00
use MaxMind\Db\Reader ;
2024-10-08 07:54:40 +00:00
use Utopia\App ;
2025-01-10 03:12:10 +00:00
use Utopia\Config\Config ;
2024-03-06 17:34:21 +00:00
use Utopia\Database\DateTime ;
2022-11-24 07:53:52 +00:00
use Utopia\Database\Document ;
use Utopia\Database\Validator\Authorization ;
2024-04-01 11:02:47 +00:00
use Utopia\System\System ;
2024-03-03 14:18:09 +00:00
2024-10-08 07:54:40 +00:00
App :: init ()
2024-03-03 14:18:09 +00:00
-> groups ([ 'mfaProtected' ])
-> inject ( 'session' )
-> action ( function ( Document $session ) {
2024-03-04 08:50:50 +00:00
$isSessionFresh = false ;
2024-03-03 14:18:09 +00:00
$lastUpdate = $session -> getAttribute ( 'mfaUpdatedAt' );
if ( ! empty ( $lastUpdate )) {
$now = DateTime :: now ();
2025-11-04 06:08:35 +00:00
$maxAllowedDate = DateTime :: addSeconds ( new \DateTime ( $lastUpdate ), MFA_RECENT_DURATION ); // Maximum date until session is considered safe before asking for another challenge
2024-03-03 14:18:09 +00:00
2024-03-04 08:50:50 +00:00
$isSessionFresh = DateTime :: formatTz ( $maxAllowedDate ) >= DateTime :: formatTz ( $now );
2024-03-03 14:18:09 +00:00
}
2024-03-04 08:50:50 +00:00
if ( ! $isSessionFresh ) {
2024-03-03 14:18:09 +00:00
throw new Exception ( Exception :: USER_CHALLENGE_REQUIRED );
}
});
2022-11-24 07:53:52 +00:00
2024-10-08 07:54:40 +00:00
App :: init ()
2022-11-24 07:53:52 +00:00
-> groups ([ 'auth' ])
2024-10-08 07:54:40 +00:00
-> inject ( 'utopia' )
2022-11-24 07:53:52 +00:00
-> inject ( 'request' )
-> inject ( 'project' )
2024-02-01 12:10:41 +00:00
-> inject ( 'geodb' )
2026-01-07 07:04:28 +00:00
-> inject ( 'authorization' )
-> action ( function ( App $utopia , Request $request , Document $project , Reader $geodb , Authorization $authorization ) {
2024-04-01 11:02:47 +00:00
$denylist = System :: getEnv ( '_APP_CONSOLE_COUNTRIES_DENYLIST' , '' );
2024-02-02 14:31:54 +00:00
if ( ! empty ( $denylist && $project -> getId () === 'console' )) {
2024-02-01 12:10:41 +00:00
$countries = explode ( ',' , $denylist );
$record = $geodb -> get ( $request -> getIP ()) ? ? [];
$country = $record [ 'country' ][ 'iso_code' ] ? ? '' ;
if ( in_array ( $country , $countries )) {
throw new Exception ( Exception :: GENERAL_REGION_ACCESS_DENIED );
}
}
2022-11-24 07:53:52 +00:00
2024-10-08 07:54:40 +00:00
$route = $utopia -> match ( $request );
2022-11-24 07:53:52 +00:00
2026-01-07 07:04:28 +00:00
$isPrivilegedUser = User :: isPrivileged ( $authorization -> getRoles ());
$isAppUser = User :: isApp ( $authorization -> getRoles ());
2024-06-11 22:08:40 +00:00
2024-10-08 07:54:40 +00:00
if ( $isAppUser || $isPrivilegedUser ) { // Skip limits for app and console devs
2024-10-01 14:30:47 +00:00
return ;
}
2022-11-24 07:53:52 +00:00
$auths = $project -> getAttribute ( 'auths' , []);
switch ( $route -> getLabel ( 'auth.type' , '' )) {
2025-01-10 03:12:10 +00:00
case 'email-password' :
if (( $auths [ Config :: getParam ( 'auth' )[ 'email-password' ][ 'key' ]] ? ? true ) === false ) {
2022-11-24 07:53:52 +00:00
throw new Exception ( Exception :: USER_AUTH_METHOD_UNSUPPORTED , 'Email / Password authentication is disabled for this project' );
}
break ;
case 'magic-url' :
2025-01-10 03:12:10 +00:00
if (( $auths [ Config :: getParam ( 'auth' )[ 'magic-url' ][ 'key' ]] ? ? true ) === false ) {
2022-11-24 07:53:52 +00:00
throw new Exception ( Exception :: USER_AUTH_METHOD_UNSUPPORTED , 'Magic URL authentication is disabled for this project' );
}
break ;
case 'anonymous' :
2025-01-10 03:12:10 +00:00
if (( $auths [ Config :: getParam ( 'auth' )[ 'anonymous' ][ 'key' ]] ? ? true ) === false ) {
2022-11-24 07:53:52 +00:00
throw new Exception ( Exception :: USER_AUTH_METHOD_UNSUPPORTED , 'Anonymous authentication is disabled for this project' );
}
break ;
2024-02-12 01:18:19 +00:00
case 'phone' :
2025-01-10 03:12:10 +00:00
if (( $auths [ Config :: getParam ( 'auth' )[ 'phone' ][ 'key' ]] ? ? true ) === false ) {
2024-02-12 01:18:19 +00:00
throw new Exception ( Exception :: USER_AUTH_METHOD_UNSUPPORTED , 'Phone authentication is disabled for this project' );
}
break ;
2022-11-24 07:53:52 +00:00
case 'invites' :
2025-01-10 03:12:10 +00:00
if (( $auths [ Config :: getParam ( 'auth' )[ 'invites' ][ 'key' ]] ? ? true ) === false ) {
2022-11-24 07:53:52 +00:00
throw new Exception ( Exception :: USER_AUTH_METHOD_UNSUPPORTED , 'Invites authentication is disabled for this project' );
}
break ;
case 'jwt' :
2025-01-10 03:12:10 +00:00
if (( $auths [ Config :: getParam ( 'auth' )[ 'jwt' ][ 'key' ]] ? ? true ) === false ) {
2022-11-24 07:53:52 +00:00
throw new Exception ( Exception :: USER_AUTH_METHOD_UNSUPPORTED , 'JWT authentication is disabled for this project' );
}
break ;
2024-02-02 08:33:20 +00:00
case 'email-otp' :
2025-01-10 03:12:10 +00:00
if (( $auths [ Config :: getParam ( 'auth' )[ 'email-otp' ][ 'key' ]] ? ? true ) === false ) {
2024-02-02 08:33:20 +00:00
throw new Exception ( Exception :: USER_AUTH_METHOD_UNSUPPORTED , 'Email OTP authentication is disabled for this project' );
}
break ;
2022-11-24 07:53:52 +00:00
default :
throw new Exception ( Exception :: USER_AUTH_METHOD_UNSUPPORTED , 'Unsupported authentication route' );
}
2022-12-19 08:25:49 +00:00
});