mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-27 05:14:39 +01:00
Update
This commit is contained in:
parent
ac06acf704
commit
bd8602c57d
@ -29,7 +29,7 @@ use function Amp\ByteStream\getOutputBufferStream;
|
||||
*/
|
||||
trait Templates
|
||||
{
|
||||
private const TEMPLATE = '<!DOCTYPE html><html><head><title>MadelineProto</title></head><body><h1>MadelineProto</h1><p>%s</p><form method="POST">%s<button type="submit"/>%s</button></form>%s</body></html>';
|
||||
private const TEMPLATE = '<!DOCTYPE html><html><head><title>MadelineProto</title></head><body><h1>MadelineProto</h1><p>%s</p><form method="POST">%s<button type="submit"/>%s</button></form></body></html>';
|
||||
/**
|
||||
* Generate page from template.
|
||||
*
|
||||
|
52
src/Ipc/Wrapper/Cancellation.php
Normal file
52
src/Ipc/Wrapper/Cancellation.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\Ipc\Wrapper;
|
||||
|
||||
use Amp\Cancellation as AmpCancellation;
|
||||
use danog\MadelineProto\FileCallbackInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class Cancellation extends Obj implements AmpCancellation
|
||||
{
|
||||
/**
|
||||
* Subscribes a new handler to be invoked on a cancellation request.
|
||||
*
|
||||
* This handler might be invoked immediately in case the cancellation has already been requested. Any unhandled
|
||||
* exceptions will be thrown into the event loop.
|
||||
*
|
||||
* @param \Closure(CancelledException) $callback Callback to be invoked on a cancellation request. Will receive a
|
||||
* `CancelledException` as first argument that may be used to fail the operation.
|
||||
*
|
||||
* @return string Identifier that can be used to cancel the subscription.
|
||||
*/
|
||||
public function subscribe(\Closure $callback): string {
|
||||
return $this->__call('unsubscribe', [$callback]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribes a previously registered handler.
|
||||
*
|
||||
* The handler will no longer be called as long as this method isn't invoked from a subscribed callback.
|
||||
*/
|
||||
public function unsubscribe(string $id): void {
|
||||
return $this->__call('unsubscribe', [$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether cancellation has been requested yet.
|
||||
*/
|
||||
public function isRequested(): bool {
|
||||
return $this->__call('isRequested');
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws the `CancelledException` if cancellation has been requested, otherwise does nothing.
|
||||
*
|
||||
* @throws CancelledException
|
||||
*/
|
||||
public function throwIfRequested(): void {
|
||||
$this->__call('throwIfRequested');
|
||||
}
|
||||
}
|
@ -174,6 +174,9 @@ final class Lang
|
||||
'en' =>
|
||||
[
|
||||
'go' => 'Go',
|
||||
'loginChoosePromptWeb' => 'Do you want to login as a user or as a bot?',
|
||||
'loginOptionBot' => 'Bot',
|
||||
'loginOptionUser' => 'User',
|
||||
'apiChooseManualAutoTip' => 'Note that you can also provide the API ID/hash directly in the code using the settings: %s',
|
||||
'apiChooseManualAutoTipWeb' => 'Note that you can also provide the API ID/hash directly in the code using the <a target="_blank" href="%s">settings</a>.',
|
||||
'apiChoosePrompt' => 'Your choice (m/a): ',
|
||||
|
@ -715,9 +715,6 @@ final class MTProto implements TLCallback, LoggerGetter
|
||||
|
||||
'updateHandlerType',
|
||||
|
||||
// Web login template
|
||||
'webTemplate',
|
||||
|
||||
// Settings
|
||||
'settings',
|
||||
'config',
|
||||
|
152
src/TL/Types/LoginQrCode.php
Normal file
152
src/TL/Types/LoginQrCode.php
Normal file
@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Login QR code.
|
||||
*
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2023 Daniil Gentili <daniil@daniil.it>
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
|
||||
* @link https://docs.madelineproto.xyz MadelineProto documentation
|
||||
*/
|
||||
|
||||
namespace danog\MadelineProto\TL\Types;
|
||||
|
||||
use Amp\Cancellation;
|
||||
use Amp\CancelledException;
|
||||
use Amp\CompositeCancellation;
|
||||
use Amp\DeferredFuture;
|
||||
use Amp\TimeoutCancellation;
|
||||
use Amp\TimeoutException;
|
||||
use AssertionError;
|
||||
use BaconQrCode\Renderer\Image\SvgImageBackEnd;
|
||||
use BaconQrCode\Renderer\ImageRenderer;
|
||||
use BaconQrCode\Renderer\PlainTextRenderer;
|
||||
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
|
||||
use BaconQrCode\Writer;
|
||||
use danog\MadelineProto\Ipc\Client;
|
||||
use danog\MadelineProto\MTProto;
|
||||
use JsonSerializable;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
/**
|
||||
* Represents a login QR code.
|
||||
*/
|
||||
final class LoginQrCode implements JsonSerializable {
|
||||
|
||||
private string $session;
|
||||
|
||||
/** @internal */
|
||||
public function __construct(
|
||||
private MTProto|Client $API,
|
||||
/** @var non-empty-string The [QR code login link](https://core.telegram.org/api/links#qr-code-login-links) */
|
||||
public readonly string $link,
|
||||
/** @var positive-int The expiry date of the link */
|
||||
public readonly int $expiry
|
||||
) {
|
||||
$this->session = $API->getWrapper()->getSession()->getSessionDirectoryPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __sleep(): array
|
||||
{
|
||||
return ['link', 'expiry', 'session'];
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return [
|
||||
'link' => $this->link,
|
||||
'expiry' => $this->expiry,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the QR code has expired and a new one should be fetched.
|
||||
*/
|
||||
public function isExpired(): bool {
|
||||
return $this->expiry <= time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of seconds until the QR code expires.
|
||||
*
|
||||
* @return non-negative-int
|
||||
*/
|
||||
public function expiresIn(): int {
|
||||
return max(0, $this->expiry - time());
|
||||
}
|
||||
|
||||
public function getExpirationCancellation(): Cancellation {
|
||||
return new TimeoutCancellation((float) $this->expiresIn(), "The QR code expired!");
|
||||
}
|
||||
|
||||
|
||||
public function getLoginCancellation(): Cancellation {
|
||||
$this->API ??= Client::giveInstanceBySession($this->session);
|
||||
return $this->API->getQrLoginCancellation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the user to login or for the QR code to expire.
|
||||
*
|
||||
* If the user logins, null is returned.
|
||||
*
|
||||
* If the QR code expires, the new QR code is returned.
|
||||
*
|
||||
* If cancellation is requested externally through $cancellation, a CancelledException is thrown.
|
||||
*
|
||||
* @throws CancelledException
|
||||
*
|
||||
* @param Cancellation|null $customCancellation Optional additional cancellation
|
||||
*/
|
||||
public function waitForLoginOrQrCodeExpiration(?Cancellation $customCancellation = null): ?self {
|
||||
$expire = $this->getExpirationCancellation();
|
||||
if ($customCancellation) {
|
||||
$cancellation = new CompositeCancellation($expire, $customCancellation);
|
||||
} else {
|
||||
$cancellation = $expire;
|
||||
}
|
||||
$login = $this->getLoginCancellation();
|
||||
$cancellation = new CompositeCancellation($login, $cancellation);
|
||||
try {
|
||||
(new DeferredFuture)->getFuture()->await($cancellation);
|
||||
} catch (CancelledException) {
|
||||
$customCancellation?->throwIfRequested();
|
||||
return $this->API->qrLogin();
|
||||
}
|
||||
throw new AssertionError("Unreachable!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Render and return SVG version of QR code.
|
||||
*/
|
||||
public function getQRSvg(): string {
|
||||
$writer = new Writer(new ImageRenderer(
|
||||
new RendererStyle(400),
|
||||
new SvgImageBackEnd
|
||||
));
|
||||
return $writer->writeString($this->link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render and return plain text version of QR code.
|
||||
*
|
||||
* @param non-negative-int $margin Text margin
|
||||
*/
|
||||
public function getQRText(int $margin = 2): string {
|
||||
$writer = new Writer(new PlainTextRenderer($margin));
|
||||
return $writer->writeString($this->link);
|
||||
}
|
||||
}
|
@ -54,7 +54,7 @@ trait Templates
|
||||
$token = \htmlentities(Lang::$current_lang['loginBotTokenWeb']);
|
||||
$form = "<input type='text' name='token' placeholder='$token' required/>";
|
||||
}
|
||||
} elseif (isset($_POST['waitQrCodeOrLogin'])) {
|
||||
} elseif (isset($_GET['waitQrCodeOrLogin'])) {
|
||||
header('Content-type: application/json');
|
||||
try {
|
||||
/** @var ?LoginQrCode */
|
||||
|
Loading…
Reference in New Issue
Block a user