diff --git a/app/config/collections.php b/app/config/collections.php index d48b009ef6..da11ce1c92 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -1420,50 +1420,6 @@ $collections = [ 'array' => true, 'filters' => [], ], - [ - '$id' => ID::custom('hotp'), - 'type' => Database::VAR_BOOLEAN, - 'format' => '', - 'size' => 0, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('hotpVerification'), - 'type' => Database::VAR_BOOLEAN, - 'format' => '', - 'size' => 0, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('hotpSecret'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 256, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('hotpBackup'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 6, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => true, - 'filters' => [], - ], [ '$id' => ID::custom('sessions'), 'type' => Database::VAR_STRING, diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index ed7a6cbed2..996c15ff8a 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -4,7 +4,6 @@ use Ahc\Jwt\JWT; use Appwrite\Auth\Auth; use Appwrite\Auth\MFA\Challenge; use Appwrite\Auth\MFA\Provider; -use Appwrite\Auth\MFA\Provider\HOTP; use Appwrite\Auth\MFA\Provider\TOTP; use Appwrite\Auth\Validator\Password; use Appwrite\Auth\Validator\Phone; @@ -2585,7 +2584,6 @@ App::get('/v1/account/mfa/providers') $providers = new Document([ 'totp' => $user->getAttribute('totp', false) && $user->getAttribute('totpVerification', false), - 'hotp' => $user->getAttribute('hotp', false) && $user->getAttribute('hotpVerification', false), 'email' => $user->getAttribute('email', false) && $user->getAttribute('emailVerification', false), 'phone' => $user->getAttribute('phone', false) && $user->getAttribute('phoneVerification', false) ]); @@ -2611,7 +2609,7 @@ App::post('/v1/account/mfa/:provider') ->label('sdk.response.model', Response::MODEL_USER) ->label('sdk.offline.model', '/account') ->label('sdk.offline.key', 'current') - ->param('provider', null, new WhiteList(['totp', 'hotp']), 'Provider.') + ->param('provider', null, new WhiteList(['totp']), 'Provider.') ->inject('requestTimestamp') ->inject('response') ->inject('project') @@ -2622,7 +2620,6 @@ App::post('/v1/account/mfa/:provider') $otp = match ($provider) { 'totp' => new TOTP(), - 'hotp' => new HOTP(), default => throw new Exception(Exception::GENERAL_UNKNOWN, 'Unknown provider.') }; @@ -2632,16 +2629,6 @@ App::post('/v1/account/mfa/:provider') $backups = Provider::generateBackupCodes(); switch ($provider) { - case 'hotp': - if ($user->getAttribute('hotp') && $user->getAttribute('hotpVerification')) { - throw new Exception(Exception::GENERAL_UNKNOWN, 'HOTP already exists.'); - } - $user - ->setAttribute('hotp', true) - ->setAttribute('hotpVerification', false) - ->setAttribute('hotpBackup', $backups) - ->setAttribute('hotpSecret', $otp->getSecret()); - break; case 'totp': if ($user->getAttribute('totp') && $user->getAttribute('totpVerification')) { throw new Exception(Exception::GENERAL_UNKNOWN, 'TOTP already exists.'); @@ -2685,7 +2672,7 @@ App::put('/v1/account/mfa/:provider') ->label('sdk.response.model', Response::MODEL_USER) ->label('sdk.offline.model', '/account') ->label('sdk.offline.key', 'current') - ->param('provider', null, new WhiteList(['totp', 'hotp']), 'Provider.') + ->param('provider', null, new WhiteList(['totp']), 'Provider.') ->param('otp', '', new Text(256), 'Valid verification token.') ->inject('requestTimestamp') ->inject('response') @@ -2697,32 +2684,23 @@ App::put('/v1/account/mfa/:provider') $success = match ($provider) { 'totp' => Challenge\TOTP::verify($user, $otp), - 'hotp' => Challenge\HOTP::verify($user, $otp), default => false }; - if (!$success) { - throw new Exception(Exception::USER_INVALID_TOKEN); - } + if (!$success) { + throw new Exception(Exception::USER_INVALID_TOKEN); + } - switch ($provider) { - case 'hotp': - if (!$user->getAttribute('hotp')) { - throw new Exception(Exception::GENERAL_UNKNOWN, 'HOTP not added.'); - } elseif ($user->getAttribute('hotpVerification')) { - throw new Exception(Exception::GENERAL_UNKNOWN, 'HOTP already verified.'); - } - $user->setAttribute('hotpVerification', true); - break; - case 'totp': - if (!$user->getAttribute('totp')) { - throw new Exception(Exception::GENERAL_UNKNOWN, 'TOTP not added.'); - } elseif ($user->getAttribute('totpVerification')) { - throw new Exception(Exception::GENERAL_UNKNOWN, 'TOTP already verified.'); - } - $user->setAttribute('totpVerification', true); - break; - } + switch ($provider) { + case 'totp': + if (!$user->getAttribute('totp')) { + throw new Exception(Exception::GENERAL_UNKNOWN, 'TOTP not added.'); + } elseif ($user->getAttribute('totpVerification')) { + throw new Exception(Exception::GENERAL_UNKNOWN, 'TOTP already verified.'); + } + $user->setAttribute('totpVerification', true); + break; + } $user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user)); @@ -2749,7 +2727,7 @@ App::post('/v1/account/mfa/challenge') ->label('sdk.response.model', Response::MODEL_MFA_CHALLENGE) ->label('abuse-limit', 10) ->label('abuse-key', 'url:{url},token:{param-token}') - ->param('provider', '', new WhiteList(['totp', 'hotp', 'phone', 'email']), 'provider.') + ->param('provider', '', new WhiteList(['totp', 'phone', 'email']), 'provider.') ->inject('response') ->inject('dbForProject') ->inject('user') @@ -2860,7 +2838,6 @@ App::put('/v1/account/mfa/challenge') $success = match ($challenge->getAttribute('provider')) { 'totp' => Challenge\TOTP::challenge($challenge, $user, $otp), - 'hotp' => Challenge\HOTP::challenge($challenge, $user, $otp), 'phone' => Challenge\Phone::challenge($challenge, $user, $otp), 'email' => Challenge\Email::challenge($challenge, $user, $otp), default => false diff --git a/src/Appwrite/Auth/Auth.php b/src/Appwrite/Auth/Auth.php index fb88da1820..f0aef7057e 100644 --- a/src/Appwrite/Auth/Auth.php +++ b/src/Appwrite/Auth/Auth.php @@ -9,9 +9,6 @@ use Appwrite\Auth\Hash\Phpass; use Appwrite\Auth\Hash\Scrypt; use Appwrite\Auth\Hash\Scryptmodified; use Appwrite\Auth\Hash\Sha; -use OTPHP\HOTP; -use OTPHP\TOTP; -use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\DateTime; use Utopia\Database\Helpers\Role; diff --git a/src/Appwrite/Auth/MFA/Challenge/HOTP.php b/src/Appwrite/Auth/MFA/Challenge/HOTP.php deleted file mode 100644 index da123f0c26..0000000000 --- a/src/Appwrite/Auth/MFA/Challenge/HOTP.php +++ /dev/null @@ -1,29 +0,0 @@ -getAttribute('totpSecret')); - - return false; - } - - public static function challenge(Document $challenge, Document $user, string $otp): bool - { - if ( - $challenge->isSet('provider') && - $challenge->getAttribute('provider') === 'hotp' - ) { - return self::verify($user, $otp); - } - - return false; - } -} diff --git a/src/Appwrite/Auth/MFA/Provider/HOTP.php b/src/Appwrite/Auth/MFA/Provider/HOTP.php deleted file mode 100644 index 8a97c78153..0000000000 --- a/src/Appwrite/Auth/MFA/Provider/HOTP.php +++ /dev/null @@ -1,14 +0,0 @@ -instance = HOTPLibrary::create($secret); - } -} diff --git a/src/Appwrite/Utopia/Response/Model/MFAProviders.php b/src/Appwrite/Utopia/Response/Model/MFAProviders.php index 7af49e8de6..acba916de8 100644 --- a/src/Appwrite/Utopia/Response/Model/MFAProviders.php +++ b/src/Appwrite/Utopia/Response/Model/MFAProviders.php @@ -16,12 +16,6 @@ class MFAProviders extends Model 'default' => false, 'example' => true ]) - ->addRule('hotp', [ - 'type' => self::TYPE_BOOLEAN, - 'description' => 'HOTP', - 'default' => false, - 'example' => true - ]) ->addRule('phone', [ 'type' => self::TYPE_BOOLEAN, 'description' => 'Phone',