mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-30 04:08:59 +01:00
Fix logout in case of session termination
This commit is contained in:
parent
50145665cd
commit
a3094016e8
2
docs
2
docs
@ -1 +1 @@
|
||||
Subproject commit a0aae4d1e264c9b56469a47d67780b7c345c4672
|
||||
Subproject commit 07535f4de8d8ee6b845ef36ff572bbc2ff1d6fe5
|
@ -9,7 +9,7 @@
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="true">
|
||||
>
|
||||
<coverage>
|
||||
<include>
|
||||
<directory suffix=".php">src</directory>
|
||||
|
@ -101,6 +101,12 @@ final class API extends AbstractAPI
|
||||
* @var int
|
||||
*/
|
||||
public const LOGGED_IN = 3;
|
||||
/**
|
||||
* We're logged out, the session will be deleted ASAP.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public const LOGGED_OUT = 4;
|
||||
/**
|
||||
* This peer is a user.
|
||||
*
|
||||
|
@ -98,6 +98,10 @@ final class APIWrapper
|
||||
$this->API->waitForInit();
|
||||
$API = $this->API;
|
||||
|
||||
if ($API->authorized === API::LOGGED_OUT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->session->serialize(
|
||||
$API->serializeSession($this),
|
||||
$this->session->getSessionPath(),
|
||||
|
@ -1269,6 +1269,11 @@ abstract class InternalDoc
|
||||
{
|
||||
$this->wrapper->getAPI()->logger($param, $level, $file);
|
||||
}
|
||||
|
||||
public function logout(): void
|
||||
{
|
||||
$this->wrapper->getAPI()->logout();
|
||||
}
|
||||
/**
|
||||
* Start MadelineProto's update handling loop, or run the provided async callable.
|
||||
*
|
||||
|
@ -141,6 +141,11 @@ final class Client extends ClientAbstract
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLogger(): Logger
|
||||
{
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public function getQrLoginCancellation(): Cancellation
|
||||
{
|
||||
|
@ -137,7 +137,10 @@ use Webmozart\Assert\Assert;
|
||||
Logger::log("$e", Logger::FATAL_ERROR);
|
||||
Logger::log('Got exception in IPC server, exiting...', Logger::FATAL_ERROR);
|
||||
$ipc = $session->getIpcState();
|
||||
if (!($ipc && $ipc->getStartupId() === $runnerId && !$ipc->getException())) {
|
||||
if (!($ipc && $ipc->getStartupId() === $runnerId && !$ipc->getException())
|
||||
&& $API
|
||||
&& $API->getAuthorization() !== API::LOGGED_OUT
|
||||
) {
|
||||
Logger::log('Reporting error!');
|
||||
$session->storeIpcState(new IpcState($runnerId, $e));
|
||||
Logger::log('Reported error!');
|
||||
|
@ -475,6 +475,9 @@ final class MTProto implements TLCallback, LoggerGetter
|
||||
if (self::$references) {
|
||||
Logger::log('Prompting final serialization (SHUTDOWN)...');
|
||||
foreach (self::$references as $instance) {
|
||||
if ($instance->authorized === API::LOGGED_OUT) {
|
||||
continue;
|
||||
}
|
||||
$instance->wrapper->serialize();
|
||||
}
|
||||
Logger::log('Done final serialization (SHUTDOWN)!');
|
||||
@ -1122,6 +1125,9 @@ final class MTProto implements TLCallback, LoggerGetter
|
||||
}
|
||||
}
|
||||
$this->logger->logger('Unreferenced instance');
|
||||
if ($this->authorized === API::LOGGED_OUT) {
|
||||
$this->wrapper->getSession()->delete();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Destructor.
|
||||
|
@ -326,6 +326,7 @@ trait ResponseHandler
|
||||
$phone = isset($this->API->authorization['user']['phone']) ? '+' . $this->API->authorization['user']['phone'] : '???';
|
||||
$this->logger->logger(\sprintf(Lang::$current_lang['account_banned'], $phone), Logger::FATAL_ERROR);
|
||||
}
|
||||
$this->API->logout();
|
||||
return fn () => new RPCErrorException($response['error_message'], $response['error_code'], $request->getConstructor());
|
||||
case 'AUTH_KEY_UNREGISTERED':
|
||||
case 'AUTH_KEY_INVALID':
|
||||
@ -345,6 +346,7 @@ trait ResponseHandler
|
||||
$this->logger->logger('Permanent auth key was main authorized key, logging out...', Logger::FATAL_ERROR);
|
||||
$phone = isset($this->API->authorization['user']['phone']) ? '+' . $this->API->authorization['user']['phone'] : 'you are currently using';
|
||||
$this->logger->logger(\sprintf(Lang::$current_lang['account_banned'], $phone), Logger::FATAL_ERROR);
|
||||
$this->API->logout();
|
||||
return fn () => new RPCErrorException($response['error_message'], $response['error_code'], $request->getConstructor());
|
||||
}
|
||||
EventLoop::queue(function () use ($request): void {
|
||||
|
@ -21,6 +21,8 @@ declare(strict_types=1);
|
||||
namespace danog\MadelineProto;
|
||||
|
||||
use danog\MadelineProto\Ipc\IpcState;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
|
||||
use const LOCK_EX;
|
||||
use const LOCK_SH;
|
||||
@ -29,10 +31,12 @@ use const PHP_MINOR_VERSION;
|
||||
use const PHP_VERSION;
|
||||
|
||||
use function Amp\File\createDirectory;
|
||||
use function Amp\File\deleteDirectory;
|
||||
use function Amp\File\deleteFile;
|
||||
use function Amp\File\exists;
|
||||
use function Amp\File\isDirectory;
|
||||
use function Amp\File\isFile;
|
||||
use function Amp\File\listFiles;
|
||||
use function Amp\File\move;
|
||||
use function Amp\File\openFile;
|
||||
use function Amp\File\write;
|
||||
@ -109,6 +113,21 @@ final class SessionPaths
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Deletes session.
|
||||
*/
|
||||
public function delete(): void
|
||||
{
|
||||
if (file_exists($this->sessionDirectoryPath)) {
|
||||
foreach (scandir($this->sessionDirectoryPath) as $f) {
|
||||
if ($f === '.' || $f === '..') {
|
||||
continue;
|
||||
}
|
||||
unlink($this->sessionDirectoryPath.DIRECTORY_SEPARATOR.$f);
|
||||
}
|
||||
rmdir($this->sessionDirectoryPath);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Serialize object to file.
|
||||
*/
|
||||
|
@ -24,15 +24,19 @@ use Amp\Cancellation;
|
||||
use Amp\CancelledException;
|
||||
use Amp\DeferredCancellation;
|
||||
use Amp\DeferredFuture;
|
||||
use Amp\SignalException;
|
||||
use AssertionError;
|
||||
use danog\MadelineProto\API;
|
||||
use danog\MadelineProto\Exception;
|
||||
use danog\MadelineProto\Lang;
|
||||
use danog\MadelineProto\Logger;
|
||||
use danog\MadelineProto\LogoutException;
|
||||
use danog\MadelineProto\Magic;
|
||||
use danog\MadelineProto\MTProto\PermAuthKey;
|
||||
use danog\MadelineProto\MTProtoTools\PasswordCalculator;
|
||||
use danog\MadelineProto\RPCErrorException;
|
||||
use danog\MadelineProto\Settings;
|
||||
use danog\MadelineProto\Shutdown;
|
||||
use danog\MadelineProto\TL\Types\LoginQrCode;
|
||||
use danog\MadelineProto\Tools;
|
||||
|
||||
@ -142,6 +146,19 @@ trait Login
|
||||
$c->cancel();
|
||||
return $c->getCancellation();
|
||||
}
|
||||
public function logout(): void
|
||||
{
|
||||
if ($this->authorized === API::LOGGED_IN) {
|
||||
$this->authorized = API::LOGGED_OUT;
|
||||
$this->methodCallAsyncRead('auth.logOut');
|
||||
}
|
||||
$this->authorized = API::LOGGED_OUT;
|
||||
if ($this->hasEventHandler()) {
|
||||
$this->stop();
|
||||
} else {
|
||||
$this->ipcServer?->stop();
|
||||
}
|
||||
}
|
||||
/** @internal */
|
||||
public function waitQrLogin(): void
|
||||
{
|
||||
|
@ -5,8 +5,8 @@ declare(strict_types=1);
|
||||
namespace danog\MadelineProto\Test;
|
||||
|
||||
use Amp\PHPUnit\AsyncTestCase;
|
||||
use danog\MadelineProto\API;
|
||||
use danog\MadelineProto\Logger;
|
||||
use danog\MadelineProto\MTProto;
|
||||
use danog\MadelineProto\Settings;
|
||||
use danog\MadelineProto\Stream\MTProtoTransport\AbridgedStream;
|
||||
use danog\MadelineProto\Stream\MTProtoTransport\FullStream;
|
||||
@ -36,8 +36,6 @@ final class DataCenterTest extends AsyncTestCase
|
||||
*/
|
||||
public function testCanUseProtocol(string $transport, bool $obfuscated, string $protocol, bool $test_mode, bool $ipv6): void
|
||||
{
|
||||
$this->markTestSkipped();
|
||||
return;/*
|
||||
$settings = new Settings;
|
||||
$settings->getAppInfo()
|
||||
->setApiHash(\getenv('API_HASH'))
|
||||
@ -54,11 +52,17 @@ final class DataCenterTest extends AsyncTestCase
|
||||
->setTransport($transport)
|
||||
->setRetry(false)
|
||||
->setTimeout(10);
|
||||
$API = new MTProto($settings);
|
||||
$API->getLogger()->logger("Testing protocol $protocol using transport $transport, ".($obfuscated ? 'obfuscated ' : 'not obfuscated ').($test_mode ? 'test DC ' : 'main DC ').($ipv6 ? 'IPv6 ' : 'IPv4 '));
|
||||
|
||||
$ping = \random_bytes(8);
|
||||
$this->assertEquals($ping, $API->methodCallAsyncRead('ping', ['ping_id' => $ping])['ping_id']);*/
|
||||
// Init session
|
||||
$API = new API(\sys_get_temp_dir()."/{$transport}_{$obfuscated}_{$protocol}_{$test_mode}_$ipv6", $settings);
|
||||
unset($API);
|
||||
|
||||
// Fork
|
||||
$API = new API(\sys_get_temp_dir()."/{$transport}_{$obfuscated}_{$protocol}_{$test_mode}_$ipv6", $settings);
|
||||
$API->logger("Testing protocol $protocol using transport $transport, ".($obfuscated ? 'obfuscated ' : 'not obfuscated ').($test_mode ? 'test DC ' : 'main DC ').($ipv6 ? 'IPv6 ' : 'IPv4 '));
|
||||
|
||||
$this->assertIsArray($API->help->getConfig());
|
||||
$API->logout();
|
||||
}
|
||||
|
||||
public function protocolProvider(): Generator
|
||||
|
Loading…
Reference in New Issue
Block a user