2020-01-11 13:58:02 +00:00
< ? php
2020-01-12 06:35:37 +00:00
namespace Tests\E2E\Services\Account ;
2020-01-11 13:58:02 +00:00
2022-12-22 03:12:45 +00:00
use Appwrite\Tests\Retry ;
2020-01-13 15:15:52 +00:00
use Tests\E2E\Client ;
2020-01-11 13:58:02 +00:00
use Tests\E2E\Scopes\ProjectCustom ;
2024-03-06 17:34:21 +00:00
use Tests\E2E\Scopes\Scope ;
2020-01-11 13:58:02 +00:00
use Tests\E2E\Scopes\SideClient ;
2022-07-12 16:44:58 +00:00
use Utopia\Database\DateTime ;
2022-12-14 15:42:25 +00:00
use Utopia\Database\Helpers\ID ;
2024-01-25 16:53:51 +00:00
use Utopia\Database\Query ;
2023-03-01 12:00:36 +00:00
use Utopia\Database\Validator\Datetime as DatetimeValidator ;
2022-08-14 14:22:38 +00:00
2022-02-04 10:23:06 +00:00
use function sleep ;
2020-01-11 13:58:02 +00:00
class AccountCustomClientTest extends Scope
{
use AccountBase ;
use ProjectCustom ;
use SideClient ;
2020-01-13 15:15:52 +00:00
2023-10-26 08:43:15 +00:00
/**
* @ depends testCreateAccount
*/
public function testCreateAccountSession ( $data ) : array
{
$email = $data [ 'email' ] ? ? '' ;
$password = $data [ 'password' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertNotFalse ( \DateTime :: createFromFormat ( 'Y-m-d\TH:i:s.uP' , $response [ 'body' ][ 'expire' ]));
$sessionId = $response [ 'body' ][ '$id' ];
2023-12-11 16:52:14 +00:00
$session = $response [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2023-10-26 08:43:15 +00:00
// apiKey is only available in custom client test
$apiKey = $this -> getProject ()[ 'apiKey' ];
if ( ! empty ( $apiKey )) {
$userId = $response [ 'body' ][ 'userId' ];
$response = $this -> client -> call ( Client :: METHOD_GET , '/users/' . $userId , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $apiKey ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertArrayHasKey ( 'accessedAt' , $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'accessedAt' ]);
}
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
$this -> assertNotFalse ( \DateTime :: createFromFormat ( 'Y-m-d\TH:i:s.uP' , $response [ 'body' ][ 'expire' ]));
2024-02-25 06:24:06 +00:00
/**
* Test for FAILURE
*/
2023-11-15 11:57:27 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2024-02-25 06:24:06 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-11-15 11:57:27 +00:00
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email . 'x' ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password . 'x' ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => '' ,
'password' => '' ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
return array_merge ( $data , [
'sessionId' => $sessionId ,
'session' => $session ,
]);
}
/**
* @ depends testCreateAccountSession
*/
public function testGetAccount ( $data ) : array
{
$email = $data [ 'email' ] ? ? '' ;
$name = $data [ 'name' ] ? ? '' ;
$session = $data [ 'session' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'registration' ]));
2023-10-26 08:43:15 +00:00
$this -> assertEquals ( $response [ 'body' ][ 'email' ], $email );
$this -> assertEquals ( $response [ 'body' ][ 'name' ], $name );
$this -> assertArrayHasKey ( 'accessedAt' , $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'accessedAt' ]);
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , [
'content-type' => 'application/json' ,
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session . 'xx' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
return $data ;
}
/**
* @ depends testCreateAccountSession
*/
public function testGetAccountPrefs ( $data ) : array
{
$session = $data [ 'session' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/prefs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertEmpty ( $response [ 'body' ]);
$this -> assertCount ( 0 , $response [ 'body' ]);
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/prefs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
return $data ;
}
/**
* @ depends testCreateAccountSession
*/
public function testGetAccountSessions ( $data ) : array
{
$session = $data [ 'session' ] ? ? '' ;
$sessionId = $data [ 'sessionId' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2024-02-25 11:14:27 +00:00
$this -> assertEquals ( 2 , $response [ 'body' ][ 'total' ]);
2023-10-26 08:43:15 +00:00
$this -> assertEquals ( $sessionId , $response [ 'body' ][ 'sessions' ][ 0 ][ '$id' ]);
2024-03-04 08:23:39 +00:00
$this -> assertEmpty ( $response [ 'body' ][ 'sessions' ][ 0 ][ 'secret' ]);
2023-10-26 08:43:15 +00:00
$this -> assertEquals ( 'Windows' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'osName' ]);
$this -> assertEquals ( 'WIN' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'osCode' ]);
$this -> assertEquals ( '10' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'osVersion' ]);
$this -> assertEquals ( 'browser' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'clientType' ]);
$this -> assertEquals ( 'Chrome' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'clientName' ]);
$this -> assertEquals ( 'CH' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'clientCode' ]);
$this -> assertEquals ( '70.0' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'clientVersion' ]);
$this -> assertEquals ( 'Blink' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'clientEngine' ]);
$this -> assertEquals ( 'desktop' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'deviceName' ]);
$this -> assertEquals ( '' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'deviceBrand' ]);
$this -> assertEquals ( '' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'deviceModel' ]);
$this -> assertEquals ( $response [ 'body' ][ 'sessions' ][ 0 ][ 'ip' ], filter_var ( $response [ 'body' ][ 'sessions' ][ 0 ][ 'ip' ], FILTER_VALIDATE_IP ));
$this -> assertEquals ( '--' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'countryCode' ]);
$this -> assertEquals ( 'Unknown' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'countryName' ]);
$this -> assertEquals ( true , $response [ 'body' ][ 'sessions' ][ 0 ][ 'current' ]);
$this -> assertNotFalse ( \DateTime :: createFromFormat ( 'Y-m-d\TH:i:s.uP' , $response [ 'body' ][ 'sessions' ][ 0 ][ 'expire' ]));
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
return $data ;
}
/**
* @ depends testCreateAccountSession
*/
public function testGetAccountLogs ( $data ) : array
{
sleep ( 5 );
$session = $data [ 'session' ] ? ? '' ;
2025-02-25 08:03:37 +00:00
2023-10-26 08:43:15 +00:00
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/logs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertIsArray ( $response [ 'body' ][ 'logs' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'logs' ]);
2024-02-25 11:14:27 +00:00
$this -> assertCount ( 3 , $response [ 'body' ][ 'logs' ]);
2023-10-26 08:43:15 +00:00
$this -> assertIsNumeric ( $response [ 'body' ][ 'total' ]);
2024-02-25 12:05:14 +00:00
$this -> assertEquals ( " user.create " , $response [ 'body' ][ 'logs' ][ 2 ][ 'event' ]);
2023-12-13 11:29:30 +00:00
$this -> assertEquals ( filter_var ( $response [ 'body' ][ 'logs' ][ 2 ][ 'ip' ], FILTER_VALIDATE_IP ), $response [ 'body' ][ 'logs' ][ 2 ][ 'ip' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'logs' ][ 2 ][ 'time' ]));
2023-10-26 08:43:15 +00:00
$this -> assertEquals ( 'Windows' , $response [ 'body' ][ 'logs' ][ 1 ][ 'osName' ]);
$this -> assertEquals ( 'WIN' , $response [ 'body' ][ 'logs' ][ 1 ][ 'osCode' ]);
$this -> assertEquals ( '10' , $response [ 'body' ][ 'logs' ][ 1 ][ 'osVersion' ]);
$this -> assertEquals ( 'browser' , $response [ 'body' ][ 'logs' ][ 1 ][ 'clientType' ]);
$this -> assertEquals ( 'Chrome' , $response [ 'body' ][ 'logs' ][ 1 ][ 'clientName' ]);
$this -> assertEquals ( 'CH' , $response [ 'body' ][ 'logs' ][ 1 ][ 'clientCode' ]);
$this -> assertEquals ( '70.0' , $response [ 'body' ][ 'logs' ][ 1 ][ 'clientVersion' ]);
$this -> assertEquals ( 'Blink' , $response [ 'body' ][ 'logs' ][ 1 ][ 'clientEngine' ]);
$this -> assertEquals ( 'desktop' , $response [ 'body' ][ 'logs' ][ 1 ][ 'deviceName' ]);
$this -> assertEquals ( '' , $response [ 'body' ][ 'logs' ][ 1 ][ 'deviceBrand' ]);
$this -> assertEquals ( '' , $response [ 'body' ][ 'logs' ][ 1 ][ 'deviceModel' ]);
2023-12-13 11:29:30 +00:00
$this -> assertEquals ( filter_var ( $response [ 'body' ][ 'logs' ][ 1 ][ 'ip' ], FILTER_VALIDATE_IP ), $response [ 'body' ][ 'logs' ][ 1 ][ 'ip' ]);
2023-10-26 08:43:15 +00:00
$this -> assertEquals ( '--' , $response [ 'body' ][ 'logs' ][ 1 ][ 'countryCode' ]);
$this -> assertEquals ( 'Unknown' , $response [ 'body' ][ 'logs' ][ 1 ][ 'countryName' ]);
$this -> assertEquals ( 'Windows' , $response [ 'body' ][ 'logs' ][ 2 ][ 'osName' ]);
$this -> assertEquals ( 'WIN' , $response [ 'body' ][ 'logs' ][ 2 ][ 'osCode' ]);
$this -> assertEquals ( '10' , $response [ 'body' ][ 'logs' ][ 2 ][ 'osVersion' ]);
$this -> assertEquals ( 'browser' , $response [ 'body' ][ 'logs' ][ 2 ][ 'clientType' ]);
$this -> assertEquals ( 'Chrome' , $response [ 'body' ][ 'logs' ][ 2 ][ 'clientName' ]);
$this -> assertEquals ( 'CH' , $response [ 'body' ][ 'logs' ][ 2 ][ 'clientCode' ]);
$this -> assertEquals ( '70.0' , $response [ 'body' ][ 'logs' ][ 2 ][ 'clientVersion' ]);
$this -> assertEquals ( 'Blink' , $response [ 'body' ][ 'logs' ][ 2 ][ 'clientEngine' ]);
$this -> assertEquals ( 'desktop' , $response [ 'body' ][ 'logs' ][ 2 ][ 'deviceName' ]);
$this -> assertEquals ( '' , $response [ 'body' ][ 'logs' ][ 2 ][ 'deviceBrand' ]);
$this -> assertEquals ( '' , $response [ 'body' ][ 'logs' ][ 2 ][ 'deviceModel' ]);
$this -> assertEquals ( '--' , $response [ 'body' ][ 'logs' ][ 2 ][ 'countryCode' ]);
$this -> assertEquals ( 'Unknown' , $response [ 'body' ][ 'logs' ][ 2 ][ 'countryName' ]);
$responseLimit = $this -> client -> call ( Client :: METHOD_GET , '/account/logs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
2024-01-25 16:53:51 +00:00
'queries' => [
Query :: limit ( 1 ) -> toString ()
]
2023-10-26 08:43:15 +00:00
]);
2024-06-05 18:23:31 +00:00
$this -> assertEquals ( 200 , $responseLimit [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertIsArray ( $responseLimit [ 'body' ][ 'logs' ]);
$this -> assertNotEmpty ( $responseLimit [ 'body' ][ 'logs' ]);
$this -> assertCount ( 1 , $responseLimit [ 'body' ][ 'logs' ]);
$this -> assertIsNumeric ( $responseLimit [ 'body' ][ 'total' ]);
$this -> assertEquals ( $response [ 'body' ][ 'logs' ][ 0 ], $responseLimit [ 'body' ][ 'logs' ][ 0 ]);
$responseOffset = $this -> client -> call ( Client :: METHOD_GET , '/account/logs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
2024-01-25 16:53:51 +00:00
'queries' => [
Query :: offset ( 1 ) -> toString ()
]
2023-10-26 08:43:15 +00:00
]);
$this -> assertEquals ( $responseOffset [ 'headers' ][ 'status-code' ], 200 );
$this -> assertIsArray ( $responseOffset [ 'body' ][ 'logs' ]);
$this -> assertNotEmpty ( $responseOffset [ 'body' ][ 'logs' ]);
2024-02-25 12:05:14 +00:00
$this -> assertCount ( 2 , $responseOffset [ 'body' ][ 'logs' ]);
2023-10-26 08:43:15 +00:00
$this -> assertIsNumeric ( $responseOffset [ 'body' ][ 'total' ]);
$this -> assertEquals ( $response [ 'body' ][ 'logs' ][ 1 ], $responseOffset [ 'body' ][ 'logs' ][ 0 ]);
$responseLimitOffset = $this -> client -> call ( Client :: METHOD_GET , '/account/logs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
2024-01-25 16:53:51 +00:00
'queries' => [
Query :: offset ( 1 ) -> toString (),
Query :: limit ( 1 ) -> toString ()
]
2023-10-26 08:43:15 +00:00
]);
2024-06-05 18:23:31 +00:00
$this -> assertEquals ( 200 , $responseLimitOffset [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertIsArray ( $responseLimitOffset [ 'body' ][ 'logs' ]);
$this -> assertNotEmpty ( $responseLimitOffset [ 'body' ][ 'logs' ]);
$this -> assertCount ( 1 , $responseLimitOffset [ 'body' ][ 'logs' ]);
$this -> assertIsNumeric ( $responseLimitOffset [ 'body' ][ 'total' ]);
$this -> assertEquals ( $response [ 'body' ][ 'logs' ][ 1 ], $responseLimitOffset [ 'body' ][ 'logs' ][ 0 ]);
2025-10-21 08:41:41 +00:00
/**
2025-10-29 09:08:08 +00:00
* Test for total = false
2025-10-21 08:41:41 +00:00
*/
$logsWithIncludeTotalFalse = $this -> client -> call ( Client :: METHOD_GET , '/account/logs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
2025-10-29 09:08:08 +00:00
'total' => false
2025-10-21 08:41:41 +00:00
]);
$this -> assertEquals ( 200 , $logsWithIncludeTotalFalse [ 'headers' ][ 'status-code' ]);
$this -> assertIsArray ( $logsWithIncludeTotalFalse [ 'body' ]);
$this -> assertIsArray ( $logsWithIncludeTotalFalse [ 'body' ][ 'logs' ]);
$this -> assertIsInt ( $logsWithIncludeTotalFalse [ 'body' ][ 'total' ]);
$this -> assertEquals ( 0 , $logsWithIncludeTotalFalse [ 'body' ][ 'total' ]);
$this -> assertGreaterThan ( 0 , count ( $logsWithIncludeTotalFalse [ 'body' ][ 'logs' ]));
2023-10-26 08:43:15 +00:00
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/logs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
return $data ;
}
// TODO Add tests for OAuth2 session creation
/**
* @ depends testCreateAccountSession
*/
public function testUpdateAccountName ( $data ) : array
{
$email = $data [ 'email' ] ? ? '' ;
$session = $data [ 'session' ] ? ? '' ;
$newName = 'Lorem' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/name' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'name' => $newName
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'registration' ]));
2023-10-26 08:43:15 +00:00
$this -> assertEquals ( $response [ 'body' ][ 'email' ], $email );
$this -> assertEquals ( $response [ 'body' ][ 'name' ], $newName );
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/name' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/name' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), []);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/name' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'name' => 'ocSRq1d3QphHivJyUmYY7WMnrxyjdk5YvVwcDqx2zS0coxESN8RmsQwLWw5Whnf0WbVohuFWTRAaoKgCOO0Y0M7LwgFnZmi8881Y72222222222222222222222222222'
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$data [ 'name' ] = $newName ;
return $data ;
}
/**
* @ depends testUpdateAccountName
*/
#[Retry(count: 1)]
public function testUpdateAccountPassword ( $data ) : array
{
$email = $data [ 'email' ] ? ? '' ;
$password = $data [ 'password' ] ? ? '' ;
$session = $data [ 'session' ] ? ? '' ;
2025-06-18 08:00:24 +00:00
for ( $i = 0 ; $i < 5 ; $i ++ ) {
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
sleep ( 1 );
}
2025-06-18 20:56:58 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
$allSessions = array_map ( fn ( $sessionDetails ) => $sessionDetails [ '$id' ], $response [ 'body' ][ 'sessions' ]);
2023-10-26 08:43:15 +00:00
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'password' => 'new-password' ,
'oldPassword' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'registration' ]));
2023-10-26 08:43:15 +00:00
$this -> assertEquals ( $response [ 'body' ][ 'email' ], $email );
2025-06-18 20:56:58 +00:00
$currentSessionId = $data [ 'sessionId' ] ? ? '' ;
2025-06-18 08:00:24 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 1 , $response [ 'body' ][ 'total' ]);
// checking the current session or not
2025-06-18 20:56:58 +00:00
$this -> assertEquals ( $currentSessionId , $response [ 'body' ][ 'sessions' ][ 0 ][ '$id' ]);
2025-06-18 08:00:24 +00:00
$this -> assertTrue ( $response [ 'body' ][ 'sessions' ][ 0 ][ 'current' ]);
2025-06-18 20:56:58 +00:00
// checking for all non active sessions are cleared
foreach ( $allSessions as $sessionId ) {
if ( $currentSessionId === $sessionId ) {
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/current' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
} else {
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/' . $sessionId , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
$this -> assertEquals ( 404 , $response [ 'headers' ][ 'status-code' ]);
}
}
$newPassword = 'new-password' ;
// updating the invalidateSession to false to check sessions are not invalidated
$this -> updateProjectinvalidateSessionsProperty ( false );
for ( $i = 0 ; $i < 5 ; $i ++ ) {
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $newPassword ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
sleep ( 1 );
}
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions' , array_merge ([
2023-10-26 08:43:15 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-06-18 20:56:58 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
$allSessions = array_map ( fn ( $sessionDetails ) => $sessionDetails [ '$id' ], $response [ 'body' ][ 'sessions' ]);
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2023-10-26 08:43:15 +00:00
]), [
2025-06-18 20:56:58 +00:00
'password' => $newPassword ,
'oldPassword' => $newPassword ,
2023-10-26 08:43:15 +00:00
]);
2025-06-18 20:56:58 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
foreach ( $allSessions as $sessionId ) {
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/' . $sessionId , headers : array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
}
// setting invalidateSession to true to check the sessions are cleared or not
$this -> updateProjectinvalidateSessionsProperty ( true );
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'password' => $newPassword ,
'oldPassword' => $newPassword ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
$allSessions = array_map ( fn ( $sessionDetails ) => $sessionDetails [ '$id' ], $response [ 'body' ][ 'sessions' ]);
foreach ( $allSessions as $sessionId ) {
if ( $currentSessionId !== $sessionId ) {
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/' . $sessionId , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
$this -> assertEquals ( 404 , $response [ 'headers' ][ 'status-code' ]);
}
}
2023-10-26 08:43:15 +00:00
2025-06-18 20:59:21 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $newPassword ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), []);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
/**
* Existing user tries to update password by passing wrong old password -> SHOULD FAIL
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'password' => 'new-password' ,
'oldPassword' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
/**
* Existing user tries to update password without passing old password -> SHOULD FAIL
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'password' => 'new-password'
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$data [ 'password' ] = 'new-password' ;
return $data ;
}
/**
* @ depends testUpdateAccountPassword
*/
public function testUpdateAccountEmail ( $data ) : array
{
$newEmail = uniqid () . 'new@localhost.test' ;
$session = $data [ 'session' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'email' => $newEmail ,
'password' => 'new-password' ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'registration' ]));
2023-10-26 08:43:15 +00:00
$this -> assertEquals ( $response [ 'body' ][ 'email' ], $newEmail );
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), []);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
// Test if we can create a new account with the old email
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2024-12-15 10:49:35 +00:00
'x-appwrite-dev-key' => $this -> getProject ()[ 'devKey' ] ? ? ''
2023-10-26 08:43:15 +00:00
]), [
'userId' => ID :: unique (),
2024-08-01 18:36:21 +00:00
'email' => $data [ 'email' ],
'password' => $data [ 'password' ],
'name' => $data [ 'name' ],
2023-10-26 08:43:15 +00:00
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'registration' ]));
2023-10-26 08:43:15 +00:00
$this -> assertEquals ( $response [ 'body' ][ 'email' ], $data [ 'email' ]);
$this -> assertEquals ( $response [ 'body' ][ 'name' ], $data [ 'name' ]);
$data [ 'email' ] = $newEmail ;
return $data ;
}
/**
* @ depends testUpdateAccountEmail
*/
public function testUpdateAccountPrefs ( $data ) : array
{
$newEmail = uniqid () . 'new@localhost.test' ;
$session = $data [ 'session' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/prefs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'prefs' => [
'prefKey1' => 'prefValue1' ,
'prefKey2' => 'prefValue2' ,
]
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertEquals ( 'prefValue1' , $response [ 'body' ][ 'prefs' ][ 'prefKey1' ]);
$this -> assertEquals ( 'prefValue2' , $response [ 'body' ][ 'prefs' ][ 'prefKey2' ]);
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/prefs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/prefs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'prefs' => '{}'
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/prefs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'prefs' => '[]'
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/prefs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'prefs' => '{"test": "value"}'
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
/**
* Prefs size exceeded
*/
$prefsObject = [ " longValue " => str_repeat ( " 🍰 " , 100000 )];
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/prefs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'prefs' => $prefsObject
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
// Now let's test the same thing, but with normal symbol instead of multi-byte cake emoji
$prefsObject = [ " longValue " => str_repeat ( " - " , 100000 )];
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/prefs' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'prefs' => $prefsObject
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
return $data ;
}
/**
* @ depends testUpdateAccountPrefs
*/
public function testCreateAccountVerification ( $data ) : array
{
$email = $data [ 'email' ] ? ? '' ;
$name = $data [ 'name' ] ? ? '' ;
$session = $data [ 'session' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/verification' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'url' => 'http://localhost/verification' ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'expire' ]));
2023-10-26 08:43:15 +00:00
$lastEmail = $this -> getLastEmail ();
$this -> assertEquals ( $email , $lastEmail [ 'to' ][ 0 ][ 'address' ]);
$this -> assertEquals ( $name , $lastEmail [ 'to' ][ 0 ][ 'name' ]);
2025-10-06 16:44:29 +00:00
$this -> assertEquals ( 'Account Verification for ' . $this -> getProject ()[ 'name' ], $lastEmail [ 'subject' ]);
2025-07-24 14:09:23 +00:00
$this -> assertStringContainsStringIgnoringCase ( 'Verify your email to activate your ' . $this -> getProject ()[ 'name' ] . ' account.' , $lastEmail [ 'text' ]);
2023-10-26 08:43:15 +00:00
2025-03-29 12:52:59 +00:00
$tokens = $this -> extractQueryParamsFromEmailLink ( $lastEmail [ 'html' ]);
2025-03-29 12:51:25 +00:00
$verification = $tokens [ 'secret' ];
2025-07-21 07:59:38 +00:00
$expectedExpire = DateTime :: formatTz ( $response [ 'body' ][ 'expire' ]);
2025-03-29 12:51:25 +00:00
$this -> assertEquals ( $expectedExpire , $tokens [ 'expire' ]);
2023-10-26 08:43:15 +00:00
2025-03-29 12:51:25 +00:00
// Secret check
$this -> assertArrayHasKey ( 'secret' , $tokens );
$this -> assertNotEmpty ( $tokens [ 'secret' ]);
2023-10-26 08:43:15 +00:00
2025-03-29 12:51:25 +00:00
// User ID check
$this -> assertArrayHasKey ( 'userId' , $tokens );
$this -> assertNotEmpty ( $tokens [ 'userId' ]);
2023-10-26 08:43:15 +00:00
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/verification' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'url' => 'localhost/verification' ,
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/verification' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'url' => 'http://remotehost/verification' ,
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
$data [ 'verification' ] = $verification ;
return $data ;
}
/**
* @ depends testCreateAccountVerification
*/
public function testUpdateAccountVerification ( $data ) : array
{
$id = $data [ 'id' ] ? ? '' ;
$session = $data [ 'session' ] ? ? '' ;
$verification = $data [ 'verification' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/verification' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'userId' => $id ,
'secret' => $verification ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/verification' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'userId' => ID :: custom ( 'ewewe' ),
'secret' => $verification ,
]);
$this -> assertEquals ( 404 , $response [ 'headers' ][ 'status-code' ]);
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/verification' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'userId' => $id ,
'secret' => 'sdasdasdasd' ,
]);
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
return $data ;
}
/**
* @ depends testUpdateAccountVerification
*/
public function testDeleteAccountSession ( $data ) : array
{
$email = $data [ 'email' ] ? ? '' ;
$password = $data [ 'password' ] ? ? '' ;
$session = $data [ 'session' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
$sessionNewId = $response [ 'body' ][ '$id' ];
2023-12-11 16:52:14 +00:00
$sessionNew = $response [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2023-10-26 08:43:15 +00:00
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $sessionNew ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/account/sessions/' . $sessionNewId , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $sessionNew ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 204 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $sessionNew ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
return $data ;
}
/**
* @ depends testUpdateAccountVerification
*/
public function testDeleteAccountSessionCurrent ( $data ) : array
{
$email = $data [ 'email' ] ? ? '' ;
$password = $data [ 'password' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2023-12-11 16:52:14 +00:00
$sessionNew = $response [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2023-10-26 08:43:15 +00:00
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $sessionNew ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/account/sessions/current' , [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $sessionNew ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 204 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $sessionNew ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
return $data ;
}
/**
* @ depends testUpdateAccountVerification
*/
public function testDeleteAccountSessions ( $data ) : array
{
$session = $data [ 'session' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/account/sessions' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 204 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
/**
* Create new fallback session
*/
$email = $data [ 'email' ] ? ? '' ;
$password = $data [ 'password' ] ? ? '' ;
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2023-12-11 16:52:14 +00:00
$data [ 'session' ] = $response [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2023-10-26 08:43:15 +00:00
return $data ;
}
/**
* @ depends testDeleteAccountSession
*/
public function testCreateAccountRecovery ( $data ) : array
{
$email = $data [ 'email' ] ? ? '' ;
$name = $data [ 'name' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/recovery' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'url' => 'http://localhost/recovery' ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'expire' ]));
2023-10-26 08:43:15 +00:00
$lastEmail = $this -> getLastEmail ();
$this -> assertEquals ( $email , $lastEmail [ 'to' ][ 0 ][ 'address' ]);
$this -> assertEquals ( $name , $lastEmail [ 'to' ][ 0 ][ 'name' ]);
2025-10-06 16:44:29 +00:00
$this -> assertEquals ( 'Password Reset for ' . $this -> getProject ()[ 'name' ], $lastEmail [ 'subject' ]);
2025-07-24 14:09:23 +00:00
$this -> assertStringContainsStringIgnoringCase ( 'Reset your ' . $this -> getProject ()[ 'name' ] . ' password using the link.' , $lastEmail [ 'text' ]);
2023-10-26 08:43:15 +00:00
2025-03-29 12:52:59 +00:00
$tokens = $this -> extractQueryParamsFromEmailLink ( $lastEmail [ 'html' ]);
2023-10-26 08:43:15 +00:00
2025-03-29 12:51:25 +00:00
// Secret check
$this -> assertArrayHasKey ( 'secret' , $tokens );
$this -> assertNotEmpty ( $tokens [ 'secret' ]);
$this -> assertNotFalse ( $response [ 'body' ][ 'secret' ]);
2023-10-26 08:43:15 +00:00
2025-03-29 12:51:25 +00:00
// User ID check
$this -> assertArrayHasKey ( 'userId' , $tokens );
$this -> assertNotEmpty ( $tokens [ 'userId' ]);
$this -> assertNotFalse ( $response [ 'body' ][ 'userId' ]);
2023-10-26 08:43:15 +00:00
2025-03-29 12:51:25 +00:00
// Expire check
$this -> assertArrayHasKey ( 'expire' , $tokens );
$this -> assertNotEmpty ( $tokens [ 'expire' ]);
$this -> assertEquals (
2025-07-21 07:59:38 +00:00
DateTime :: formatTz ( $response [ 'body' ][ 'expire' ]),
2025-03-29 12:51:25 +00:00
$tokens [ 'expire' ]
);
2023-10-26 08:43:15 +00:00
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/recovery' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'url' => 'localhost/recovery' ,
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/recovery' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'url' => 'http://remotehost/recovery' ,
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/recovery' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => 'not-found@localhost.test' ,
'url' => 'http://localhost/recovery' ,
]);
$this -> assertEquals ( 404 , $response [ 'headers' ][ 'status-code' ]);
2025-03-29 12:51:25 +00:00
$data [ 'recovery' ] = $tokens [ 'secret' ];
2023-10-26 08:43:15 +00:00
return $data ;
}
/**
* @ depends testCreateAccountRecovery
*/
#[Retry(count: 1)]
public function testUpdateAccountRecovery ( $data ) : array
{
$id = $data [ 'id' ] ? ? '' ;
$recovery = $data [ 'recovery' ] ? ? '' ;
2023-12-05 11:00:26 +00:00
$newPassword = 'test-recovery' ;
2023-10-26 08:43:15 +00:00
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/recovery' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => $id ,
'secret' => $recovery ,
2023-12-05 11:00:26 +00:00
'password' => $newPassword ,
2023-10-26 08:43:15 +00:00
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/recovery' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => ID :: custom ( 'ewewe' ),
'secret' => $recovery ,
2023-12-05 11:00:26 +00:00
'password' => $newPassword ,
2023-10-26 08:43:15 +00:00
]);
$this -> assertEquals ( 404 , $response [ 'headers' ][ 'status-code' ]);
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/recovery' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => $id ,
'secret' => 'sdasdasdasd' ,
2023-12-05 11:00:26 +00:00
'password' => $newPassword ,
2023-10-26 08:43:15 +00:00
]);
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
return $data ;
}
2025-10-31 12:22:47 +00:00
public function testSessionAlert () : void
2024-06-24 13:39:47 +00:00
{
2024-06-26 08:42:01 +00:00
$email = uniqid () . 'session-alert@appwrite.io' ;
$password = 'password123' ;
$name = 'Session Alert Tester' ;
2024-06-24 13:39:47 +00:00
2024-06-26 08:42:01 +00:00
// Enable session alerts
2024-06-24 13:39:47 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/projects/' . $this -> getProject ()[ '$id' ] . '/auth/session-alerts' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => 'console' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
]), [
2024-07-03 08:02:16 +00:00
'alerts' => true ,
2024-06-24 13:39:47 +00:00
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2024-06-26 08:42:01 +00:00
// Create a new account
$response = $this -> client -> call ( Client :: METHOD_POST , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2024-12-15 10:49:35 +00:00
'x-appwrite-dev-key' => $this -> getProject ()[ 'devKey' ] ? ? ''
2024-06-26 08:42:01 +00:00
]), [
'userId' => ID :: unique (),
'email' => $email ,
'password' => $password ,
'name' => $name ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2024-07-16 12:31:32 +00:00
// Create first session for the new account
2024-06-24 13:39:47 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2024-06-26 14:46:12 +00:00
'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' ,
2024-06-24 13:39:47 +00:00
]), [
'email' => $email ,
'password' => $password ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2024-07-16 12:31:32 +00:00
// Create second session for the new account
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' ,
]), [
'email' => $email ,
'password' => $password ,
]);
2024-06-26 08:42:01 +00:00
// Check the alert email
2024-06-24 13:39:47 +00:00
$lastEmail = $this -> getLastEmail ();
$this -> assertEquals ( $email , $lastEmail [ 'to' ][ 0 ][ 'address' ]);
2024-07-16 12:31:32 +00:00
$this -> assertStringContainsString ( 'Security alert: new session' , $lastEmail [ 'subject' ]);
2024-06-24 13:39:47 +00:00
$this -> assertStringContainsString ( $response [ 'body' ][ 'ip' ], $lastEmail [ 'text' ]); // IP Address
2024-06-26 14:46:12 +00:00
$this -> assertStringContainsString ( 'Unknown' , $lastEmail [ 'text' ]); // Country
$this -> assertStringContainsString ( $response [ 'body' ][ 'clientName' ], $lastEmail [ 'text' ]); // Client name
2025-10-31 12:22:47 +00:00
$this -> assertStringNotContainsStringIgnoringCase ( 'Appwrite logo' , $lastEmail [ 'html' ]);
2024-08-01 18:36:21 +00:00
// Verify no alert sent in OTP login
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/tokens/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => ID :: unique (),
'email' => 'otpuser2@appwrite.io'
]);
$this -> assertEquals ( $response [ 'headers' ][ 'status-code' ], 201 );
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$createdAt' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'userId' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'expire' ]);
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
$this -> assertEmpty ( $response [ 'body' ][ 'phrase' ]);
2025-07-24 14:09:23 +00:00
$this -> assertStringContainsStringIgnoringCase ( 'New login detected on ' . $this -> getProject ()[ 'name' ], $lastEmail [ 'text' ]);
2024-08-01 18:36:21 +00:00
$userId = $response [ 'body' ][ 'userId' ];
$lastEmail = $this -> getLastEmail ();
$this -> assertEquals ( 'otpuser2@appwrite.io' , $lastEmail [ 'to' ][ 0 ][ 'address' ]);
$this -> assertEquals ( 'OTP for ' . $this -> getProject ()[ 'name' ] . ' Login' , $lastEmail [ 'subject' ]);
2025-03-29 12:51:25 +00:00
// Find 6 concurrent digits in email text - OTP
2024-08-01 18:36:21 +00:00
preg_match_all ( " / \ b \ d { 6} \ b/ " , $lastEmail [ 'text' ], $matches );
$code = ( $matches [ 0 ] ? ? [])[ 0 ] ? ? '' ;
$this -> assertNotEmpty ( $code );
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/token' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => $userId ,
'secret' => $code
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $userId , $response [ 'body' ][ 'userId' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'expire' ]);
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
$lastEmailId = $lastEmail [ 'id' ];
$lastEmail = $this -> getLastEmail ();
$this -> assertEquals ( $lastEmailId , $lastEmail [ 'id' ]);
2024-06-24 13:39:47 +00:00
}
2021-07-17 21:21:33 +00:00
/**
* @ depends testCreateAccountSession
*/
2022-05-16 10:11:37 +00:00
public function testCreateOAuth2AccountSession () : array
2020-01-13 15:15:52 +00:00
{
$provider = 'mock' ;
$appId = '1' ;
$secret = '123456' ;
/**
* Test for SUCCESS
*/
2022-05-16 10:11:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/projects/' . $this -> getProject ()[ '$id' ] . '/oauth2' , array_merge ([
2020-01-13 15:15:52 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => 'console' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
]), [
'provider' => $provider ,
'appId' => $appId ,
'secret' => $secret ,
2023-01-17 01:17:37 +00:00
'enabled' => true ,
2020-01-13 15:15:52 +00:00
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2020-01-13 15:15:52 +00:00
2022-05-16 10:11:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/oauth2/' . $provider , array_merge ([
2020-01-13 15:15:52 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
2020-02-17 07:16:11 +00:00
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2020-01-13 15:15:52 +00:00
]), [
2020-02-16 11:41:03 +00:00
'success' => 'http://localhost/v1/mock/tests/general/oauth2/success' ,
'failure' => 'http://localhost/v1/mock/tests/general/oauth2/failure' ,
2020-01-13 15:15:52 +00:00
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'success' , $response [ 'body' ][ 'result' ]);
2023-02-14 05:56:14 +00:00
/**
* Test for Failure when disabled
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/projects/' . $this -> getProject ()[ '$id' ] . '/oauth2' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => 'console' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
]), [
'provider' => $provider ,
'appId' => $appId ,
'secret' => $secret ,
'enabled' => false ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-02-14 05:56:14 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/oauth2/' . $provider , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'success' => 'http://localhost/v1/mock/tests/general/oauth2/success' ,
'failure' => 'http://localhost/v1/mock/tests/general/oauth2/failure' ,
]);
2023-02-14 06:07:06 +00:00
$this -> assertEquals ( 412 , $response [ 'headers' ][ 'status-code' ]);
2023-02-14 05:56:14 +00:00
2020-01-13 15:15:52 +00:00
return [];
}
2020-12-27 20:32:39 +00:00
2025-10-02 09:28:55 +00:00
public function testCreateOidcOAuth2Token () : array
{
$provider = 'oidc' ;
$appId = '1' ;
// Valid well-known configuration
$secret = ' {
" wellKnownEndpoint " : " https://accounts.google.com/.well-known/openid-configuration " ,
" authorizationEndpoint " : " https://accounts.google.com/o/oauth2/v2/auth " ,
" tokenEndpoint " : " https://oauth2.googleapis.com/token " ,
" userinfoEndpoint " : " https://openidconnect.googleapis.com/v1/userinfo "
} ' ;
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/projects/' . $this -> getProject ()[ '$id' ] . '/oauth2' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => 'console' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
]), [
'provider' => $provider ,
'appId' => $appId ,
'secret' => $secret ,
'enabled' => true ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/tokens/oauth2/' . $provider , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'provider' => $provider ,
'success' => 'http://localhost/v1/mock/tests/general/oauth2/success' ,
'failure' => 'http://localhost/v1/mock/tests/general/oauth2/failure' ,
], true , false );
$this -> assertEquals ( 301 , $response [ 'headers' ][ 'status-code' ]);
// Invalid well-known configuration
$secret = '{}' ;
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/projects/' . $this -> getProject ()[ '$id' ] . '/oauth2' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => 'console' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
]), [
'provider' => $provider ,
'appId' => $appId ,
'secret' => $secret ,
'enabled' => true ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/tokens/oauth2/' . $provider , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'provider' => $provider ,
'success' => 'http://localhost/v1/mock/tests/general/oauth2/success' ,
'failure' => 'http://localhost/v1/mock/tests/general/oauth2/failure' ,
]);
$this -> assertEquals ( 500 , $response [ 'headers' ][ 'status-code' ]);
return [];
}
2022-05-16 10:11:37 +00:00
public function testBlockedAccount () : array
2020-12-27 20:32:39 +00:00
{
2022-05-16 10:11:37 +00:00
$email = uniqid () . 'user@localhost.test' ;
2020-12-27 20:32:39 +00:00
$password = 'password' ;
$name = 'User Name (blocked)' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
2022-08-14 10:33:36 +00:00
'userId' => ID :: unique (),
2020-12-27 20:32:39 +00:00
'email' => $email ,
'password' => $password ,
'name' => $name ,
]);
$id = $response [ 'body' ][ '$id' ];
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2022-05-16 10:11:37 +00:00
2022-06-14 08:17:50 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
2020-12-27 20:32:39 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2020-12-27 20:32:39 +00:00
$sessionId = $response [ 'body' ][ '$id' ];
2023-12-08 23:17:13 +00:00
$session = $response [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2020-12-27 20:32:39 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2020-12-27 20:32:39 +00:00
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2020-12-27 20:32:39 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/users/' . $id . '/status' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
], [
2021-07-14 11:02:12 +00:00
'status' => false ,
2020-12-27 20:32:39 +00:00
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2020-12-27 20:32:39 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2022-05-16 10:11:37 +00:00
2022-06-14 08:17:50 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
2022-05-16 10:11:37 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2022-05-16 10:11:37 +00:00
return [];
}
public function testSelfBlockedAccount () : array
{
$email = uniqid () . 'user55@localhost.test' ;
$password = 'password' ;
$name = 'User Name (self blocked)' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
2022-08-14 10:33:36 +00:00
'userId' => ID :: unique (),
2022-05-16 10:11:37 +00:00
'email' => $email ,
'password' => $password ,
'name' => $name ,
]);
$id = $response [ 'body' ][ '$id' ];
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2022-05-16 10:11:37 +00:00
2022-06-14 08:17:50 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
2022-05-16 10:11:37 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2022-05-16 10:11:37 +00:00
2023-12-08 23:17:13 +00:00
$session = $response [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2022-05-16 10:11:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2022-05-16 10:11:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/status' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
], [
'status' => false ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-05-23 17:40:31 +00:00
$this -> assertStringContainsString ( 'a_session_' . $this -> getProject ()[ '$id' ] . '=deleted' , $response [ 'headers' ][ 'set-cookie' ]);
$this -> assertEquals ( '[]' , $response [ 'headers' ][ 'x-fallback-cookies' ]);
2022-05-16 10:11:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2020-12-27 20:32:39 +00:00
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2020-12-27 20:32:39 +00:00
2022-06-14 08:17:50 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
2020-12-27 20:32:39 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2020-12-27 20:32:39 +00:00
return [];
}
2020-12-28 20:31:55 +00:00
2022-05-16 10:11:37 +00:00
public function testCreateJWT () : array
2020-12-28 20:31:55 +00:00
{
2022-05-16 10:11:37 +00:00
$email = uniqid () . 'user@localhost.test' ;
2020-12-28 20:31:55 +00:00
$password = 'password' ;
$name = 'User Name (JWT)' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
2022-08-14 10:33:36 +00:00
'userId' => ID :: unique (),
2020-12-28 20:31:55 +00:00
'email' => $email ,
'password' => $password ,
'name' => $name ,
]);
$id = $response [ 'body' ][ '$id' ];
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2022-05-16 10:11:37 +00:00
2022-06-14 08:17:50 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
2020-12-28 20:31:55 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2020-12-28 20:31:55 +00:00
$sessionId = $response [ 'body' ][ '$id' ];
2023-12-08 23:17:13 +00:00
$session = $response [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2020-12-28 20:31:55 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2020-12-28 20:31:55 +00:00
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2020-12-28 20:31:55 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/jwt' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2020-12-28 20:31:55 +00:00
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2025-12-23 15:31:17 +00:00
$this -> assertEquals ( 119 , $response [ 'headers' ][ 'x-ratelimit-remaining' ]);
2020-12-28 20:31:55 +00:00
$this -> assertNotEmpty ( $response [ 'body' ][ 'jwt' ]);
$this -> assertIsString ( $response [ 'body' ][ 'jwt' ]);
$jwt = $response [ 'body' ][ 'jwt' ];
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-jwt' => 'wrong-token' ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2020-12-28 20:31:55 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-jwt' => $jwt ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2020-12-28 20:31:55 +00:00
2022-05-16 10:11:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/account/sessions/' . $sessionId , array_merge ([
2020-12-28 20:31:55 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2020-12-28 20:31:55 +00:00
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 204 , $response [ 'headers' ][ 'status-code' ]);
2020-12-28 20:31:55 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-jwt' => $jwt ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2020-12-28 20:31:55 +00:00
2025-12-22 17:19:50 +00:00
// Test JWT with custom duration
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$session = $response [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/jwt' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'duration' => 5
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'jwt' ]);
$jwt = $response [ 'body' ][ 'jwt' ];
// Ensure JWT works before expiration
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-jwt' => $jwt ,
]));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
// Wait for JWT to expire
\sleep ( 6 );
// Ensure JWT no longer works after expiration
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-jwt' => $jwt ,
]));
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2020-12-28 20:31:55 +00:00
return [];
}
2021-02-16 13:49:21 +00:00
public function testCreateAnonymousAccount ()
{
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/anonymous' , [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]);
2021-02-23 22:43:05 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2021-05-20 13:41:55 +00:00
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2023-10-26 08:43:15 +00:00
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
2021-02-16 13:49:21 +00:00
2023-12-08 23:17:13 +00:00
$session = $response [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2021-02-16 13:49:21 +00:00
2023-07-07 00:12:39 +00:00
\usleep ( 1000 * 30 ); // wait for 30ms to let the shutdown update accessedAt
$apiKey = $this -> getProject ()[ 'apiKey' ];
$userId = $response [ 'body' ][ 'userId' ];
$response = $this -> client -> call ( Client :: METHOD_GET , '/users/' . $userId , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $apiKey ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-07-07 00:12:39 +00:00
$this -> assertArrayHasKey ( 'accessedAt' , $response [ 'body' ]);
2023-08-23 01:34:23 +00:00
2023-07-07 00:12:39 +00:00
$this -> assertNotEmpty ( $response [ 'body' ][ 'accessedAt' ]);
2021-02-16 13:49:21 +00:00
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/anonymous' , [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2021-02-16 13:49:21 +00:00
]);
2021-02-23 22:43:05 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2021-02-16 13:49:21 +00:00
return $session ;
}
2025-09-22 08:56:23 +00:00
/**
* @ depends testCreateAnonymousAccount
*/
public function testCreateAnonymousAccountVerification ( $session ) : array
{
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/verification' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'url' => 'http://localhost/verification' ,
]);
2025-10-03 10:59:39 +00:00
$this -> assertEquals ( 400 , $response [ 'body' ][ 'code' ]);
2025-09-22 08:56:23 +00:00
$this -> assertEquals ( 'user_email_not_found' , $response [ 'body' ][ 'type' ]);
return [];
}
2021-02-16 13:49:21 +00:00
/**
* @ depends testCreateAnonymousAccount
*/
2021-04-16 16:50:16 +00:00
public function testUpdateAnonymousAccountPassword ( $session )
2021-02-16 13:49:21 +00:00
{
/**
2021-05-06 13:21:36 +00:00
* Test for FAILURE
2021-02-16 13:49:21 +00:00
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2021-02-16 13:49:21 +00:00
]), [
2021-02-16 14:14:36 +00:00
'oldPassword' => '' ,
2021-02-16 13:49:21 +00:00
]);
2021-05-06 13:21:36 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2021-02-16 13:49:21 +00:00
2021-04-16 16:50:16 +00:00
return $session ;
2021-02-16 13:49:21 +00:00
}
2021-02-16 14:14:36 +00:00
/**
* @ depends testUpdateAnonymousAccountPassword
*/
2021-04-16 16:50:16 +00:00
public function testUpdateAnonymousAccountEmail ( $session )
2021-02-16 14:14:36 +00:00
{
2022-05-16 10:11:37 +00:00
$email = uniqid () . 'new@localhost.test' ;
2021-02-16 14:14:36 +00:00
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2021-02-16 14:14:36 +00:00
]), [
'email' => $email ,
'password' => '' ,
]);
2021-04-16 16:50:16 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2021-02-16 14:14:36 +00:00
return [];
}
2021-04-16 16:50:16 +00:00
public function testConvertAnonymousAccount ()
2021-02-16 13:49:21 +00:00
{
2021-02-16 15:51:08 +00:00
$session = $this -> testCreateAnonymousAccount ();
2022-05-16 10:11:37 +00:00
$email = uniqid () . 'new@localhost.test' ;
2021-02-16 13:49:21 +00:00
$password = 'new-password' ;
2021-02-16 15:01:15 +00:00
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
2022-08-14 10:33:36 +00:00
'userId' => ID :: unique (),
2021-02-16 15:01:15 +00:00
'email' => $email ,
'password' => $password
]);
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2021-02-16 15:01:15 +00:00
]), [
'email' => $email ,
'password' => $password ,
]);
2024-03-04 09:36:02 +00:00
$this -> assertEquals ( 409 , $response [ 'headers' ][ 'status-code' ]);
2021-02-16 15:01:15 +00:00
2021-02-16 13:49:21 +00:00
/**
* Test for SUCCESS
*/
2022-05-16 10:11:37 +00:00
$email = uniqid () . 'new@localhost.test' ;
2021-02-16 15:01:15 +00:00
2021-02-16 13:49:21 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2021-02-16 13:49:21 +00:00
]), [
'email' => $email ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2021-02-16 13:49:21 +00:00
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'registration' ]));
2021-02-16 13:49:21 +00:00
$this -> assertEquals ( $response [ 'body' ][ 'email' ], $email );
2022-06-14 08:17:50 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
2021-02-16 14:20:15 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2023-07-06 18:50:13 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/verification' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2023-07-11 04:03:02 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2023-07-06 18:50:13 +00:00
]), [
'url' => 'http://localhost'
]);
2023-07-11 04:03:02 +00:00
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2021-02-16 14:20:15 +00:00
2021-02-16 13:49:21 +00:00
return [];
}
2021-02-16 15:51:08 +00:00
2021-04-16 16:50:16 +00:00
public function testConvertAnonymousAccountOAuth2 ()
2021-02-16 15:51:08 +00:00
{
$session = $this -> testCreateAnonymousAccount ();
$provider = 'mock' ;
$appId = '1' ;
$secret = '123456' ;
/**
* Test for SUCCESS
*/
2021-07-17 21:21:33 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2021-07-17 21:21:33 +00:00
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2021-07-17 21:21:33 +00:00
$userId = $response [ 'body' ][ '$id' ] ? ? '' ;
2022-05-16 10:11:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/projects/' . $this -> getProject ()[ '$id' ] . '/oauth2' , array_merge ([
2021-02-16 15:51:08 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => 'console' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
]), [
'provider' => $provider ,
'appId' => $appId ,
'secret' => $secret ,
2023-01-17 01:17:37 +00:00
'enabled' => true ,
2021-02-16 15:51:08 +00:00
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2021-02-16 15:51:08 +00:00
2022-05-16 10:11:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/oauth2/' . $provider , array_merge ([
2021-02-16 15:51:08 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2021-02-16 15:51:08 +00:00
]), [
'success' => 'http://localhost/v1/mock/tests/general/oauth2/success' ,
'failure' => 'http://localhost/v1/mock/tests/general/oauth2/failure' ,
]);
2022-02-04 10:23:06 +00:00
2021-02-16 15:51:08 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2025-12-07 20:29:45 +00:00
$sessionCookieKey = 'a_session_' . $this -> getProject ()[ '$id' ];
$this -> assertArrayHasKey (
$sessionCookieKey ,
$response [ 'cookies' ],
" Failed asserting that session cookie ' $sessionCookieKey ' is set. Cookies: " . json_encode ( $response [ 'cookies' ])
);
$session = $response [ 'cookies' ][ $sessionCookieKey ];
2022-05-16 10:11:37 +00:00
2021-02-16 15:51:08 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2021-02-16 15:51:08 +00:00
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2021-07-17 21:21:33 +00:00
$this -> assertEquals ( $response [ 'body' ][ '$id' ], $userId );
2024-06-05 18:23:31 +00:00
$this -> assertEquals ( 'User Name' , $response [ 'body' ][ 'name' ]);
$this -> assertEquals ( 'useroauth@localhost.test' , $response [ 'body' ][ 'email' ]);
2022-02-04 10:23:06 +00:00
// Since we only support one oauth user, let's also check updateSession here
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/current' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2022-02-04 10:23:06 +00:00
]));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2024-03-04 08:23:39 +00:00
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
2022-02-04 10:23:06 +00:00
$this -> assertEquals ( '123456' , $response [ 'body' ][ 'providerAccessToken' ]);
$this -> assertEquals ( 'tuvwxyz' , $response [ 'body' ][ 'providerRefreshToken' ]);
2022-07-13 14:02:49 +00:00
$this -> assertGreaterThan ( DateTime :: addSeconds ( new \DateTime (), 14400 - 5 ), $response [ 'body' ][ 'providerAccessTokenExpiry' ]); // 5 seconds allowed networking delay
2022-02-04 10:23:06 +00:00
$initialExpiry = $response [ 'body' ][ 'providerAccessTokenExpiry' ];
2022-05-16 10:11:37 +00:00
2022-02-04 10:23:06 +00:00
sleep ( 3 );
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/sessions/current' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2022-02-04 10:23:06 +00:00
]));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( '123456' , $response [ 'body' ][ 'providerAccessToken' ]);
$this -> assertEquals ( 'tuvwxyz' , $response [ 'body' ][ 'providerRefreshToken' ]);
$this -> assertNotEquals ( $initialExpiry , $response [ 'body' ][ 'providerAccessTokenExpiry' ]);
2021-02-16 15:51:08 +00:00
2025-12-18 12:44:04 +00:00
// Clean up - delete the user
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/users/' . $userId , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
]));
$this -> assertEquals ( 204 , $response [ 'headers' ][ 'status-code' ]);
return [];
}
public function testOAuthUnverifiedEmailCannotLinkToExistingAccount ()
{
$provider = 'mock-unverified' ;
$appId = '1' ;
$secret = '123456' ;
// First, create a user with the same email that the unverified OAuth will try to use
$email = 'useroauthunverified@localhost.test' ;
$password = 'password' ;
$response = $this -> client -> call ( Client :: METHOD_POST , '/account' , [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], [
'userId' => ID :: unique (),
'email' => $email ,
'password' => $password ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$existingUserId = $response [ 'body' ][ '$id' ];
// Enable the mock-unverified provider
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/projects/' . $this -> getProject ()[ '$id' ] . '/oauth2' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => 'console' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
]), [
'provider' => $provider ,
'appId' => $appId ,
'secret' => $secret ,
'enabled' => true ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
// Attempt OAuth login with unverified email - should fail because existing user has same email
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/oauth2/' . $provider , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'success' => 'http://localhost/v1/mock/tests/general/oauth2/success' ,
'failure' => 'http://localhost/v1/mock/tests/general/oauth2/failure' ,
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'failure' , $response [ 'body' ][ 'result' ]);
// Clean up - delete the user
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/users/' . $existingUserId , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
]));
$this -> assertEquals ( 204 , $response [ 'headers' ][ 'status-code' ]);
return [];
}
public function testOAuthVerifiedEmailCanLinkToExistingAccount ()
{
$provider = 'mock' ;
$appId = '1' ;
$secret = '123456' ;
$email = 'useroauth@localhost.test' ;
// Create a user with the same email that the verified OAuth will try to use
$response = $this -> client -> call ( Client :: METHOD_POST , '/account' , [
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], [
'userId' => ID :: unique (),
'email' => $email ,
'password' => 'password' ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$existingUserId = $response [ 'body' ][ '$id' ];
// Enable the mock provider
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/projects/' . $this -> getProject ()[ '$id' ] . '/oauth2' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => 'console' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
]), [
'provider' => $provider ,
'appId' => $appId ,
'secret' => $secret ,
'enabled' => true ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
// Attempt OAuth login with verified email - should succeed and link to existing account
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/oauth2/' . $provider , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'success' => 'http://localhost/v1/mock/tests/general/oauth2/success' ,
'failure' => 'http://localhost/v1/mock/tests/general/oauth2/failure' ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'success' , $response [ 'body' ][ 'result' ]);
// Verify the OAuth identity was linked to the existing user
$sessionCookieKey = 'a_session_' . $this -> getProject ()[ '$id' ];
$session = $response [ 'cookies' ][ $sessionCookieKey ];
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( $existingUserId , $response [ 'body' ][ '$id' ]);
$this -> assertEquals ( $email , $response [ 'body' ][ 'email' ]);
// Clean up - delete the user
$response = $this -> client -> call ( Client :: METHOD_DELETE , '/users/' . $existingUserId , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
]));
$this -> assertEquals ( 204 , $response [ 'headers' ][ 'status-code' ]);
2021-02-16 15:51:08 +00:00
return [];
}
2021-06-16 10:41:15 +00:00
2022-05-16 10:11:37 +00:00
public function testGetSessionByID ()
{
2021-06-16 10:41:15 +00:00
$session = $this -> testCreateAnonymousAccount ();
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/current' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2021-06-16 10:41:15 +00:00
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2024-03-04 08:23:39 +00:00
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
2024-06-05 18:23:31 +00:00
$this -> assertEquals ( 'anonymous' , $response [ 'body' ][ 'provider' ]);
2021-06-16 10:41:15 +00:00
$sessionID = $response [ 'body' ][ '$id' ];
2022-05-16 10:11:37 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/' . $sessionID , array_merge ([
2021-06-16 10:41:15 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2021-06-16 10:41:15 +00:00
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2024-03-04 08:23:39 +00:00
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
2024-06-05 18:23:31 +00:00
$this -> assertEquals ( 'anonymous' , $response [ 'body' ][ 'provider' ]);
2021-06-16 10:41:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account/sessions/97823askjdkasd80921371980' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2022-05-16 10:11:37 +00:00
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
2021-06-16 10:41:15 +00:00
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 404 , $response [ 'headers' ][ 'status-code' ]);
2021-06-16 10:41:15 +00:00
}
2022-04-26 10:07:33 +00:00
/**
* @ depends testUpdateAccountName
*/
public function testUpdateAccountNameSearch ( $data ) : void
{
$id = $data [ 'id' ] ? ? '' ;
$newName = 'Lorem' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/users' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
], [
2022-08-15 19:35:50 +00:00
'search' => $newName ,
2022-04-26 10:07:33 +00:00
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2022-04-26 10:07:33 +00:00
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'users' ]);
2023-10-26 14:04:47 +00:00
$this -> assertCount ( 2 , $response [ 'body' ][ 'users' ]);
$this -> assertEquals ( $newName , $response [ 'body' ][ 'users' ][ 1 ][ 'name' ]);
2022-04-26 10:07:33 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/users' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
], [
2022-08-15 19:35:50 +00:00
'search' => $id ,
2022-04-26 10:07:33 +00:00
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2022-04-26 10:07:33 +00:00
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'users' ]);
$this -> assertCount ( 1 , $response [ 'body' ][ 'users' ]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( $newName , $response [ 'body' ][ 'users' ][ 0 ][ 'name' ]);
2022-04-26 10:07:33 +00:00
}
/**
* @ depends testUpdateAccountEmail
*/
public function testUpdateAccountEmailSearch ( $data ) : void
{
$id = $data [ 'id' ] ? ? '' ;
$email = $data [ 'email' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_GET , '/users' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
], [
2022-08-15 19:35:50 +00:00
'search' => '"' . $email . '"' ,
2022-04-26 10:07:33 +00:00
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2022-04-26 10:07:33 +00:00
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'users' ]);
$this -> assertCount ( 1 , $response [ 'body' ][ 'users' ]);
$this -> assertEquals ( $response [ 'body' ][ 'users' ][ 0 ][ 'email' ], $email );
$response = $this -> client -> call ( Client :: METHOD_GET , '/users' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
], [
2022-08-15 19:35:50 +00:00
'search' => $id ,
2022-04-26 10:07:33 +00:00
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2022-04-26 10:07:33 +00:00
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'users' ]);
$this -> assertCount ( 1 , $response [ 'body' ][ 'users' ]);
$this -> assertEquals ( $response [ 'body' ][ 'users' ][ 0 ][ 'email' ], $email );
}
2022-06-08 12:50:31 +00:00
public function testCreatePhone () : array
{
$number = '+123456789' ;
/**
* Test for SUCCESS
*/
2023-11-30 11:35:52 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/tokens/phone' , array_merge ([
2022-06-08 12:50:31 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
2022-08-14 10:33:36 +00:00
'userId' => ID :: unique (),
2022-08-14 18:09:24 +00:00
'phone' => $number ,
2022-06-08 12:50:31 +00:00
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2023-10-10 13:36:53 +00:00
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'expire' ]));
2022-06-08 12:50:31 +00:00
$userId = $response [ 'body' ][ 'userId' ];
2025-06-02 16:09:03 +00:00
$smsRequest = $this -> assertLastRequest ( function ( array $request ) use ( $number ) {
$this -> assertEquals ( 'Appwrite Mock Message Sender' , $request [ 'headers' ][ 'User-Agent' ]);
$this -> assertEquals ( 'username' , $request [ 'headers' ][ 'X-Username' ]);
$this -> assertEquals ( 'password' , $request [ 'headers' ][ 'X-Key' ]);
$this -> assertEquals ( 'POST' , $request [ 'method' ]);
$this -> assertEquals ( '+123456789' , $request [ 'data' ][ 'from' ]);
$this -> assertEquals ( $number , $request [ 'data' ][ 'to' ]);
2025-06-26 16:07:59 +00:00
}, Scope :: REQUEST_TYPE_SMS );
2022-09-28 05:45:07 +00:00
$data [ 'token' ] = $smsRequest [ 'data' ][ 'message' ];
2022-06-08 12:50:31 +00:00
$data [ 'id' ] = $userId ;
$data [ 'number' ] = $number ;
2024-02-20 12:54:17 +00:00
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/tokens/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => ID :: unique ()
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2022-06-08 12:50:31 +00:00
return $data ;
}
/**
* @ depends testCreatePhone
*/
public function testCreateSessionWithPhone ( array $data ) : array
{
$id = $data [ 'id' ] ? ? '' ;
2024-01-13 09:55:44 +00:00
$token = explode ( " " , $data [ 'token' ])[ 0 ] ? ? '' ;
2022-06-08 12:50:31 +00:00
$number = $data [ 'number' ] ? ? '' ;
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/sessions/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
2022-08-14 10:33:36 +00:00
'userId' => ID :: custom ( 'ewewe' ),
2022-06-08 12:50:31 +00:00
'secret' => $token ,
]);
2023-10-12 13:38:32 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2022-06-08 12:50:31 +00:00
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/sessions/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => $id ,
'secret' => 'sdasdasdasd' ,
]);
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/sessions/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => $id ,
'secret' => $token ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'userId' ]);
2023-12-08 23:17:13 +00:00
$session = $response [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2022-06-08 12:50:31 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2022-06-08 12:50:31 +00:00
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2023-02-05 20:39:41 +00:00
$this -> assertEquals ( true , ( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'registration' ]));
2022-06-08 12:50:31 +00:00
$this -> assertEquals ( $response [ 'body' ][ 'phone' ], $number );
$this -> assertTrue ( $response [ 'body' ][ 'phoneVerification' ]);
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/sessions/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => $id ,
'secret' => $token ,
]);
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
$data [ 'session' ] = $session ;
return $data ;
}
/**
* @ depends testCreateSessionWithPhone
*/
public function testConvertPhoneToPassword ( array $data ) : array
{
$session = $data [ 'session' ];
$email = uniqid () . 'new@localhost.test' ;
$password = 'new-password' ;
/**
* Test for SUCCESS
*/
$email = uniqid () . 'new@localhost.test' ;
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'email' => $email ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2022-06-08 12:50:31 +00:00
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'registration' ]));
2022-06-08 12:50:31 +00:00
$this -> assertEquals ( $response [ 'body' ][ 'email' ], $email );
2022-06-14 08:17:50 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
2022-06-08 12:50:31 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => $password ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2022-06-08 12:50:31 +00:00
return $data ;
}
/**
* @ depends testConvertPhoneToPassword
*/
public function testUpdatePhone ( array $data ) : array
{
$newPhone = '+45632569856' ;
$session = $data [ 'session' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
2022-08-14 18:09:24 +00:00
'phone' => $newPhone ,
2022-06-08 12:50:31 +00:00
'password' => 'new-password'
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2022-06-08 12:50:31 +00:00
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'registration' ]));
2022-06-08 12:50:31 +00:00
$this -> assertEquals ( $response [ 'body' ][ 'phone' ], $newPhone );
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2022-06-08 12:50:31 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), []);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2022-06-08 12:50:31 +00:00
$data [ 'phone' ] = $newPhone ;
return $data ;
}
2023-10-11 13:21:20 +00:00
/**
* @ depends testGetAccountSessions
* @ depends testGetAccountLogs
*/
2024-01-09 12:44:50 +00:00
public function testCreateSession ( array $data ) : array
2023-10-11 13:21:20 +00:00
{
2023-12-05 11:00:26 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/users/' . $data [ 'id' ] . '/tokens' , [
2023-10-11 13:21:20 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
2023-11-02 13:15:29 +00:00
], [
'expire' => 60
2023-10-11 13:21:20 +00:00
]);
2023-12-05 11:00:26 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2023-10-11 13:21:20 +00:00
$userId = $response [ 'body' ][ 'userId' ];
$secret = $response [ 'body' ][ 'secret' ];
/**
* Test for SUCCESS
*/
2024-01-09 18:05:21 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/token' , [
2023-10-11 13:21:20 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], [
'userId' => $userId ,
2023-12-05 11:00:26 +00:00
'secret' => $secret
2023-10-11 13:21:20 +00:00
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2023-12-05 11:00:26 +00:00
$this -> assertEquals ( $data [ 'id' ], $response [ 'body' ][ 'userId' ]);
2023-10-11 13:21:20 +00:00
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'expire' ]);
2023-10-12 13:38:32 +00:00
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
2025-01-27 13:58:46 +00:00
$this -> assertEquals ( 'browser' , $response [ 'body' ][ 'clientType' ]);
$this -> assertEquals ( 'CH' , $response [ 'body' ][ 'clientCode' ]);
$this -> assertEquals ( 'Chrome' , $response [ 'body' ][ 'clientName' ]);
// Forwarded User Agent with API Key
$response = $this -> client -> call ( Client :: METHOD_POST , '/users/' . $data [ 'id' ] . '/tokens' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
], [
'expire' => 60
]);
$userId = $response [ 'body' ][ 'userId' ];
$secret = $response [ 'body' ][ 'secret' ];
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/token' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
'x-forwarded-user-agent' => 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36'
], [
'userId' => $userId ,
'secret' => $secret
]);
$this -> assertEquals ( 'browser' , $response [ 'body' ][ 'clientType' ]);
$this -> assertEquals ( 'CM' , actual : $response [ 'body' ][ 'clientCode' ]);
$this -> assertEquals ( 'Chrome Mobile' , $response [ 'body' ][ 'clientName' ]);
// Forwarded User Agent without API Key
$response = $this -> client -> call ( Client :: METHOD_POST , '/users/' . $data [ 'id' ] . '/tokens' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-appwrite-key' => $this -> getProject ()[ 'apiKey' ],
], [
'expire' => 60
]);
$userId = $response [ 'body' ][ 'userId' ];
$secret = $response [ 'body' ][ 'secret' ];
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/token' , [
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'x-forwarded-user-agent' => 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36'
], [
'userId' => $userId ,
'secret' => $secret
]);
$this -> assertEquals ( 'browser' , $response [ 'body' ][ 'clientType' ]);
$this -> assertEquals ( 'CH' , $response [ 'body' ][ 'clientCode' ]);
$this -> assertEquals ( 'Chrome' , $response [ 'body' ][ 'clientName' ]);
2023-10-11 13:21:20 +00:00
/**
* Test for FAILURE
*/
// Invalid userId
2024-01-09 18:05:21 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/token' , [
2023-10-11 13:21:20 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], [
'userId' => ID :: custom ( 'ewewe' ),
'secret' => $secret ,
]);
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
// Invalid secret
2024-01-09 18:05:21 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/token' , [
2023-10-11 13:21:20 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
], [
'userId' => $userId ,
'secret' => '123456' ,
]);
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-11 13:21:59 +00:00
2023-10-11 13:21:20 +00:00
return $data ;
}
2022-06-08 12:50:31 +00:00
/**
* @ depends testUpdatePhone
*/
public function testPhoneVerification ( array $data ) : array
{
$session = $data [ 'session' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/verification/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2025-06-26 18:47:59 +00:00
$this -> assertNotEmpty ( $response [ 'body' ][ '$createdAt' ]);
2023-10-13 15:10:55 +00:00
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'expire' ]));
2022-06-08 12:50:31 +00:00
2025-06-26 18:47:59 +00:00
$tokenCreatedAt = $response [ 'body' ][ '$createdAt' ];
$smsRequest = $this -> assertLastRequest ( function ( $request ) use ( $tokenCreatedAt ) {
2025-06-02 16:09:03 +00:00
$this -> assertArrayHasKey ( 'data' , $request );
2025-06-26 18:47:59 +00:00
$this -> assertArrayHasKey ( 'time' , $request );
2025-06-25 13:53:59 +00:00
$this -> assertArrayHasKey ( 'message' , $request [ 'data' ], " Last request missing message: " . \json_encode ( $request ));
2025-06-26 18:47:59 +00:00
// Ensure we are not using token from last sms login
$tokenRecievedAt = $request [ 'time' ];
$this -> assertGreaterThan ( $tokenCreatedAt , $tokenRecievedAt );
2025-06-26 16:07:59 +00:00
}, Scope :: REQUEST_TYPE_SMS );
2024-02-25 12:05:14 +00:00
2025-03-05 18:40:41 +00:00
/**
* Test for FAILURE
*/
// disable phone sessions
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/projects/' . $this -> getProject ()[ '$id' ] . '/auth/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => 'console' ,
'cookie' => 'a_session_console=' . $this -> getRoot ()[ 'session' ],
]), [
'status' => false ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( false , $response [ 'body' ][ 'authPhone' ]);
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/verification/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
$this -> assertEquals ( 501 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( " Phone authentication is disabled for this project " , $response [ 'body' ][ 'message' ]);
2022-09-19 08:09:48 +00:00
return \array_merge ( $data , [
2024-02-25 16:41:37 +00:00
'token' => \substr ( $smsRequest [ 'data' ][ 'message' ], 0 , 6 )
2022-09-19 08:09:48 +00:00
]);
2022-06-08 12:50:31 +00:00
}
/**
* @ depends testPhoneVerification
*/
public function testUpdatePhoneVerification ( $data ) : array
{
$id = $data [ 'id' ] ? ? '' ;
$session = $data [ 'session' ] ? ? '' ;
2022-09-19 08:09:48 +00:00
$secret = $data [ 'token' ] ? ? '' ;
2022-06-08 12:50:31 +00:00
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/verification/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'userId' => $id ,
2022-09-19 08:09:48 +00:00
'secret' => $secret ,
2022-06-08 12:50:31 +00:00
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/verification/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
2022-08-14 10:33:36 +00:00
'userId' => ID :: custom ( 'ewewe' ),
2022-09-19 08:09:48 +00:00
'secret' => $secret ,
2022-06-08 12:50:31 +00:00
]);
$this -> assertEquals ( 404 , $response [ 'headers' ][ 'status-code' ]);
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/verification/phone' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'userId' => $id ,
'secret' => '999999' ,
]);
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
return $data ;
}
2023-10-26 08:43:15 +00:00
public function testCreateMagicUrl () : array
{
$email = \time () . 'user@appwrite.io' ;
/**
* Test for SUCCESS
*/
2023-11-30 11:35:52 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/tokens/magic-url' , array_merge ([
2023-10-26 08:43:15 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => ID :: unique (),
'email' => $email ,
// 'url' => 'http://localhost/magiclogin',
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
2024-02-01 10:41:01 +00:00
$this -> assertEmpty ( $response [ 'body' ][ 'phrase' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'expire' ]));
2023-10-26 08:43:15 +00:00
$userId = $response [ 'body' ][ 'userId' ];
$lastEmail = $this -> getLastEmail ();
$this -> assertEquals ( $email , $lastEmail [ 'to' ][ 0 ][ 'address' ]);
2024-01-10 10:37:27 +00:00
$this -> assertEquals ( $this -> getProject ()[ 'name' ] . ' Login' , $lastEmail [ 'subject' ]);
2025-07-24 14:09:23 +00:00
$this -> assertStringContainsStringIgnoringCase ( 'Sign in to ' . $this -> getProject ()[ 'name' ] . ' with your secure link. Expires in 1 hour.' , $lastEmail [ 'text' ]);
2024-01-13 09:55:44 +00:00
$this -> assertStringNotContainsStringIgnoringCase ( 'security phrase' , $lastEmail [ 'text' ]);
2023-10-26 08:43:15 +00:00
2024-01-10 10:27:38 +00:00
$token = substr ( $lastEmail [ 'text' ], strpos ( $lastEmail [ 'text' ], '&secret=' , 0 ) + 8 , 64 );
2023-10-26 08:43:15 +00:00
$expireTime = strpos ( $lastEmail [ 'text' ], 'expire=' . urlencode ( $response [ 'body' ][ 'expire' ]), 0 );
$this -> assertNotFalse ( $expireTime );
$secretTest = strpos ( $lastEmail [ 'text' ], 'secret=' . $response [ 'body' ][ 'secret' ], 0 );
$this -> assertNotFalse ( $secretTest );
$userIDTest = strpos ( $lastEmail [ 'text' ], 'userId=' . $response [ 'body' ][ 'userId' ], 0 );
$this -> assertNotFalse ( $userIDTest );
/**
* Test for FAILURE
*/
2023-11-30 11:35:52 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/tokens/magic-url' , array_merge ([
2023-10-26 08:43:15 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => ID :: unique (),
'email' => $email ,
'url' => 'localhost/magiclogin' ,
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2023-11-30 11:35:52 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/tokens/magic-url' , array_merge ([
2023-10-26 08:43:15 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => ID :: unique (),
'email' => $email ,
'url' => 'http://remotehost/magiclogin' ,
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2023-11-30 11:35:52 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/tokens/magic-url' , array_merge ([
2023-10-26 08:43:15 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
]);
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2024-01-13 09:55:44 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/magic-url' , array_merge ([
2022-06-08 12:50:31 +00:00
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
2024-01-13 09:55:44 +00:00
'userId' => ID :: unique (),
'email' => $email ,
2024-02-01 10:41:01 +00:00
'phrase' => true
2022-06-08 12:50:31 +00:00
]);
2024-01-13 09:55:44 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-02-01 10:41:01 +00:00
$this -> assertNotEmpty ( $response [ 'body' ][ 'phrase' ]);
2024-01-13 09:55:44 +00:00
$lastEmail = $this -> getLastEmail ();
2024-02-01 10:41:01 +00:00
$this -> assertStringContainsStringIgnoringCase ( $response [ 'body' ][ 'phrase' ], $lastEmail [ 'text' ]);
2024-01-13 09:55:44 +00:00
2023-10-26 08:43:15 +00:00
$data [ 'token' ] = $token ;
$data [ 'id' ] = $userId ;
$data [ 'email' ] = $email ;
return $data ;
}
/**
* @ depends testCreateMagicUrl
*/
public function testCreateSessionWithMagicUrl ( $data ) : array
{
$id = $data [ 'id' ] ? ? '' ;
$token = $data [ 'token' ] ? ? '' ;
$email = $data [ 'email' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/sessions/magic-url' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => $id ,
'secret' => $token ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ 'userId' ]);
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
$sessionId = $response [ 'body' ][ '$id' ];
2023-12-11 19:41:58 +00:00
$session = $response [ 'cookies' ][ 'a_session_' . $this -> getProject ()[ '$id' ]];
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_GET , '/account' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'registration' ]));
2023-10-26 08:43:15 +00:00
$this -> assertEquals ( $response [ 'body' ][ 'email' ], $email );
$this -> assertTrue ( $response [ 'body' ][ 'emailVerification' ]);
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/sessions/magic-url' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => ID :: custom ( 'ewewe' ),
'secret' => $token ,
]);
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/sessions/magic-url' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'userId' => $id ,
'secret' => 'sdasdasdasd' ,
]);
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
$data [ 'sessionId' ] = $sessionId ;
$data [ 'session' ] = $session ;
return $data ;
}
/**
* @ depends testCreateSessionWithMagicUrl
*/
public function testUpdateAccountPasswordWithMagicUrl ( $data ) : array
{
$email = $data [ 'email' ] ? ? '' ;
$session = $data [ 'session' ] ? ? '' ;
/**
* Test for SUCCESS
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'password' => 'new-password'
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertIsArray ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-06-05 18:23:31 +00:00
$this -> assertTrue (( new DatetimeValidator ()) -> isValid ( $response [ 'body' ][ 'registration' ]));
2023-10-26 08:43:15 +00:00
$this -> assertEquals ( $response [ 'body' ][ 'email' ], $email );
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/sessions/email' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]), [
'email' => $email ,
'password' => 'new-password' ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$this -> assertEmpty ( $response [ 'body' ][ 'secret' ]);
/**
* Test for FAILURE
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
]));
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), []);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 400 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
/**
* Existing user tries to update password by passing wrong old password -> SHOULD FAIL
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'password' => 'new-password' ,
'oldPassword' => 'wrong-password' ,
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
/**
* Existing user tries to update password without passing old password -> SHOULD FAIL
*/
$response = $this -> client -> call ( Client :: METHOD_PATCH , '/account/password' , array_merge ([
'origin' => 'http://localhost' ,
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
'cookie' => 'a_session_' . $this -> getProject ()[ '$id' ] . '=' . $session ,
]), [
'password' => 'new-password'
]);
2023-10-26 14:04:47 +00:00
$this -> assertEquals ( 401 , $response [ 'headers' ][ 'status-code' ]);
2023-10-26 08:43:15 +00:00
$data [ 'password' ] = 'new-password' ;
return $data ;
}
2024-10-22 01:35:11 +00:00
public function testCreatePushTarget () : void
{
2024-10-22 01:54:34 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/targets/push' , \array_merge ([
2024-10-22 01:35:11 +00:00
'content-type' => 'application/json' ,
2024-10-22 01:54:34 +00:00
'x-appwrite-project' => $this -> getProject ()[ '$id' ]
], $this -> getHeaders ()), [
2024-10-22 01:35:11 +00:00
'targetId' => ID :: unique (),
'identifier' => 'test-identifier' ,
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
$this -> assertEquals ( 'test-identifier' , $response [ 'body' ][ 'identifier' ]);
}
public function testUpdatePushTarget () : void
{
2024-10-22 01:54:34 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/targets/push' , \array_merge ([
2024-10-22 01:35:11 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2024-10-22 01:54:34 +00:00
], $this -> getHeaders ()), [
2024-10-22 01:35:11 +00:00
'targetId' => ID :: unique (),
2024-10-22 01:54:34 +00:00
'identifier' => 'test-identifier-2' ,
2024-10-22 01:35:11 +00:00
]);
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $response [ 'body' ][ '$id' ]);
2024-10-22 01:54:34 +00:00
$this -> assertEquals ( 'test-identifier-2' , $response [ 'body' ][ 'identifier' ]);
2024-10-22 01:35:11 +00:00
2024-10-22 01:54:34 +00:00
$response = $this -> client -> call ( Client :: METHOD_PUT , '/account/targets/' . $response [ 'body' ][ '$id' ] . '/push' , \array_merge ([
2024-10-22 01:35:11 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2024-10-22 01:54:34 +00:00
], $this -> getHeaders ()), [
2024-10-22 01:35:11 +00:00
'identifier' => 'test-identifier-updated' ,
]);
$this -> assertEquals ( 200 , $response [ 'headers' ][ 'status-code' ]);
$this -> assertEquals ( 'test-identifier-updated' , $response [ 'body' ][ 'identifier' ]);
$this -> assertEquals ( false , $response [ 'body' ][ 'expired' ]);
}
2025-12-08 20:48:40 +00:00
2025-12-10 20:20:52 +00:00
public function testMFARecoveryCodeChallenge () : void
2025-12-10 00:07:43 +00:00
{
2025-12-10 20:20:52 +00:00
// Generate recovery codes using existing authenticated session
2025-12-10 00:07:43 +00:00
$response = $this -> client -> call ( Client :: METHOD_POST , '/account/mfa/recovery-codes' , array_merge ([
2025-12-08 20:48:40 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-12-10 20:20:52 +00:00
], $this -> getHeaders ()), []);
2025-12-08 20:48:40 +00:00
2025-12-10 00:07:43 +00:00
$this -> assertEquals ( 201 , $response [ 'headers' ][ 'status-code' ]);
2025-12-08 20:48:40 +00:00
$this -> assertNotEmpty ( $response [ 'body' ][ 'recoveryCodes' ]);
$recoveryCodes = $response [ 'body' ][ 'recoveryCodes' ];
$this -> assertGreaterThan ( 0 , count ( $recoveryCodes ));
// Create recovery code challenge
2025-12-10 00:07:43 +00:00
$challenge = $this -> client -> call ( Client :: METHOD_POST , '/account/mfa/challenge' , array_merge ([
2025-12-08 20:48:40 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-12-10 20:20:52 +00:00
], $this -> getHeaders ()), [
2025-12-08 20:48:40 +00:00
'factor' => 'recoveryCode'
]);
$this -> assertEquals ( 201 , $challenge [ 'headers' ][ 'status-code' ]);
$this -> assertNotEmpty ( $challenge [ 'body' ][ '$id' ]);
$challengeId = $challenge [ 'body' ][ '$id' ];
// Test SUCCESS: Verify with valid recovery code (this tests the bug fix)
2025-12-10 00:07:43 +00:00
$verification = $this -> client -> call ( Client :: METHOD_PUT , '/account/mfa/challenge' , array_merge ([
2025-12-08 20:48:40 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-12-10 20:20:52 +00:00
], $this -> getHeaders ()), [
2025-12-08 20:48:40 +00:00
'challengeId' => $challengeId ,
'otp' => $recoveryCodes [ 0 ]
]);
$this -> assertEquals ( 200 , $verification [ 'headers' ][ 'status-code' ]);
$this -> assertArrayHasKey ( 'factors' , $verification [ 'body' ]);
$this -> assertContains ( 'recoveryCode' , $verification [ 'body' ][ 'factors' ]);
// Test that the code was consumed (can't use again)
2025-12-10 00:07:43 +00:00
$challenge2 = $this -> client -> call ( Client :: METHOD_POST , '/account/mfa/challenge' , array_merge ([
2025-12-08 20:48:40 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-12-10 20:20:52 +00:00
], $this -> getHeaders ()), [
2025-12-08 20:48:40 +00:00
'factor' => 'recoveryCode'
]);
$this -> assertEquals ( 201 , $challenge2 [ 'headers' ][ 'status-code' ]);
2025-12-10 00:07:43 +00:00
$verification2 = $this -> client -> call ( Client :: METHOD_PUT , '/account/mfa/challenge' , array_merge ([
2025-12-08 20:48:40 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-12-10 20:20:52 +00:00
], $this -> getHeaders ()), [
2025-12-08 20:48:40 +00:00
'challengeId' => $challenge2 [ 'body' ][ '$id' ],
'otp' => $recoveryCodes [ 0 ] // Same code should fail
]);
$this -> assertEquals ( 401 , $verification2 [ 'headers' ][ 'status-code' ]);
// Test FAILURE: Invalid recovery code
2025-12-10 00:07:43 +00:00
$challenge3 = $this -> client -> call ( Client :: METHOD_POST , '/account/mfa/challenge' , array_merge ([
2025-12-08 20:48:40 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-12-10 20:20:52 +00:00
], $this -> getHeaders ()), [
2025-12-08 20:48:40 +00:00
'factor' => 'recoveryCode'
]);
$this -> assertEquals ( 201 , $challenge3 [ 'headers' ][ 'status-code' ]);
2025-12-10 00:07:43 +00:00
$verification3 = $this -> client -> call ( Client :: METHOD_PUT , '/account/mfa/challenge' , array_merge ([
2025-12-08 20:48:40 +00:00
'content-type' => 'application/json' ,
'x-appwrite-project' => $this -> getProject ()[ '$id' ],
2025-12-10 20:20:52 +00:00
], $this -> getHeaders ()), [
2025-12-08 20:48:40 +00:00
'challengeId' => $challenge3 [ 'body' ][ '$id' ],
'otp' => 'invalid-code-123'
]);
$this -> assertEquals ( 401 , $verification3 [ 'headers' ][ 'status-code' ]);
}
2022-04-26 10:07:33 +00:00
}