1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-26 21:14:43 +01:00
This commit is contained in:
Daniil Gentili 2023-06-18 22:13:12 +02:00
parent 0016c68a7c
commit f532e7d678
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
13 changed files with 79 additions and 76 deletions

View File

@ -238,7 +238,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.setDiscussionGroup.html" name="channels.setDiscussionGroup">Associate a group to a channel as discussion group for that channel: channels.setDiscussionGroup</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.setStickers.html" name="channels.setStickers">Associate a stickerset to the supergroup: channels.setStickers</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#flock-string-file-int-operation-float-polling-amp-cancellation-token-closure-failurecb-mixed" name="flock">Asynchronously lock a file: flock</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#readline-string-prompt-string" name="readLine">Asynchronously read line: readLine</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#readline-string-prompt-amp-cancellation-cancel-string" name="readLine">Asynchronously read line: readLine</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#sleep-float-time-void" name="sleep">Asynchronously sleep: sleep</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#echo-string-string-void" name="echo">Asynchronously write to stdout/browser: echo</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.editBanned.html" name="channels.editBanned">Ban/unban/kick a user in a supergroup/channel: channels.editBanned</a>
@ -431,7 +431,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/API_docs/methods/help.getAppConfig.html" name="help.getAppConfig">Get app-specific configuration, see client configuration for more info on the result: help.getAppConfig</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getdnsclient-amp-dns-dnsresolver" name="getDNSClient">Get async DNS client: getDNSClient</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#gethttpclient-amp-http-client-httpclient" name="getHTTPClient">Get async HTTP client: getHTTPClient</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getauthorization-int" name="getAuthorization">Get authorization info: getAuthorization</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getauthorization-danog-madelineproto-api-not_logged_in-danog-madelineproto-api-waiting_code-danog-madelineproto-api-waiting_signup-danog-madelineproto-api-waiting_password-danog-madelineproto-api-logged_in" name="getAuthorization">Get authorization info: getAuthorization</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.getAutoSaveSettings.html" name="account.getAutoSaveSettings">Get autosave settings: account.getAutoSaveSettings</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getconfig-array-config-array" name="getConfig">Get cached (or eventually re-fetch) server-side config: getConfig</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getcachedconfig-array" name="getCachedConfig">Get cached server-side config: getCachedConfig</a>
@ -543,7 +543,6 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getUnreadReactions.html" name="messages.getUnreadReactions">Get unread reactions to messages you sent: messages.getUnreadReactions</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getupdates-array-offset-int-limit-int-timeout-float-params-list-array-update_id-mixed-update-mixed-" name="getUpdates">Get updates: getUpdates</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.getWebAuthorizations.html" name="account.getWebAuthorizations">Get web login widget authorizations: account.getWebAuthorizations</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getwebtemplate-string" name="getWebTemplate">Get web template: getWebTemplate</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getMessageReadParticipants.html" name="messages.getMessageReadParticipants">Get which users read a specific message: only available for groups and supergroups with less than chat_read_mark_size_threshold members, read receipts will be stored for chat_read_mark_expire_period seconds after the message was sent, see client configuration for more info »: messages.getMessageReadParticipants</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.getNotifySettings.html" name="account.getNotifySettings">Gets current notification settings for a given user/group, from all users/all groups: account.getNotifySettings</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getFeaturedEmojiStickers.html" name="messages.getFeaturedEmojiStickers">Gets featured custom emoji stickersets: messages.getFeaturedEmojiStickers</a>
@ -570,6 +569,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/API_docs/methods/initConnection.html" name="initConnection">Initialize connection: initConnection</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#initselfrestart-void" name="initSelfRestart">Initialize self-restart hack: initSelfRestart</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.resetPassword.html" name="account.resetPassword">Initiate a 2FA password reset: can only be used if the user is already logged-in, see here for more info »: account.resetPassword</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#qrlogin-danog-madelineproto-tl-types-loginqrcode" name="qrLogin">Initiates QR code login: qrLogin</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.installWallPaper.html" name="account.installWallPaper">Install wallpaper: account.installWallPaper</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.installStickerSet.html" name="messages.installStickerSet">Install a stickerset: messages.installStickerSet</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.installTheme.html" name="account.installTheme">Install a theme: account.installTheme</a>
@ -765,7 +765,6 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/API_docs/methods/bots.setBotGroupDefaultAdminRights.html" name="bots.setBotGroupDefaultAdminRights">Set the default suggested admin rights for bots being added as admins to groups, see here for more info on how to handle them »: bots.setBotGroupDefaultAdminRights</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/phone.saveDefaultGroupCallJoinAs.html" name="phone.saveDefaultGroupCallJoinAs">Set the default peer that will be used to join a group call in a specific dialog: phone.saveDefaultGroupCallJoinAs</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.setAuthorizationTTL.html" name="account.setAuthorizationTTL">Set time-to-live of current session: account.setAuthorizationTTL</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#setwebtemplate-string-template-void" name="setWebTemplate">Set web template: setWebTemplate</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#setwebhook-string-webhookurl-void" name="setWebhook">Set webhook update handler: setWebhook</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.toggleJoinToSend.html" name="channels.toggleJoinToSend">Set whether all users should join a discussion group in order to comment on a post »: channels.toggleJoinToSend</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.toggleJoinRequest.html" name="channels.toggleJoinRequest">Set whether all users should request admin approval to join the group »: channels.toggleJoinRequest</a>

2
docs

@ -1 +1 @@
Subproject commit bb4252786fa6bbd7e03cabff619c42160e359b14
Subproject commit 3ff1c3be3775d398bda6adde3dbd0e5dcd79830b

View File

@ -81,8 +81,8 @@ final class GarbageCollector
$contents = $client->request(new Request("https://phar.madelineproto.xyz/phar.php?v=new".\rand(0, PHP_INT_MAX)))
->getBody()
->buffer();
if (!str_starts_with($contents, '<?php')) {
if (!\str_starts_with($contents, '<?php')) {
throw new AssertionError("phar.php is not a PHP file!");
}

View File

@ -635,6 +635,8 @@ abstract class InternalDoc
}
/**
* Get authorization info.
*
* @return \danog\MadelineProto\API::NOT_LOGGED_IN|\danog\MadelineProto\API::WAITING_CODE|\danog\MadelineProto\API::WAITING_SIGNUP|\danog\MadelineProto\API::WAITING_PASSWORD|\danog\MadelineProto\API::LOGGED_IN
*/
public function getAuthorization(): int
{
@ -1021,13 +1023,6 @@ abstract class InternalDoc
{
return $this->wrapper->getAPI()->getWebMessage($message);
}
/**
* Get web template.
*/
public function getWebTemplate(): string
{
return $this->wrapper->getAPI()->getWebTemplate();
}
/**
* Check if an event handler instance is present.
*/
@ -1242,6 +1237,17 @@ abstract class InternalDoc
{
return \danog\MadelineProto\Tools::posmod($a, $b);
}
/**
* Initiates QR code login.
*
* Returns a QR code login helper object, that can be used to render the QR code, display the link directly, wait for login, QR code expiration and much more.
*
* Returns null if we're already logged in, or if we're waiting for a password (use getAuthorization to distinguish between the two cases).
*/
public function qrLogin(): ?\danog\MadelineProto\TL\Types\LoginQrCode
{
return $this->wrapper->getAPI()->qrLogin();
}
/**
* Get secure random string of specified length.
*
@ -1265,9 +1271,9 @@ abstract class InternalDoc
*
* @param string $prompt Prompt
*/
public static function readLine(string $prompt = ''): string
public static function readLine(string $prompt = '', ?\Amp\Cancellation $cancel = null): string
{
return \danog\MadelineProto\AsyncTools::readLine($prompt);
return \danog\MadelineProto\AsyncTools::readLine($prompt, $cancel);
}
/**
* Refresh full peer cache for a certain peer.
@ -1395,15 +1401,6 @@ abstract class InternalDoc
{
$this->wrapper->getAPI()->setReportPeers($userOrId);
}
/**
* Set web template.
*
* @param string $template Template
*/
public function setWebTemplate(string $template): void
{
$this->wrapper->getAPI()->setWebTemplate($template);
}
/**
* Set webhook update handler.
*

View File

@ -131,7 +131,8 @@ final class Client extends ClientAbstract
}
/** @internal */
public function getQrLoginCancellation(): Cancellation {
public function getQrLoginCancellation(): Cancellation
{
$c = new DeferredCancellation;
async($this->__call(...), 'waitQrLogin', [])->map($c->cancel(...));
return $c->getCancellation();

View File

@ -3,7 +3,6 @@
namespace danog\MadelineProto\Ipc\Wrapper;
use Amp\Cancellation as AmpCancellation;
use danog\MadelineProto\FileCallbackInterface;
/**
* @internal
@ -21,7 +20,8 @@ final class Cancellation extends Obj implements AmpCancellation
*
* @return string Identifier that can be used to cancel the subscription.
*/
public function subscribe(\Closure $callback): string {
public function subscribe(\Closure $callback): string
{
return $this->__call('unsubscribe', [$callback]);
}
@ -30,14 +30,16 @@ final class Cancellation extends Obj implements AmpCancellation
*
* 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]);
public function unsubscribe(string $id): void
{
$this->__call('unsubscribe', [$id]);
}
/**
* Returns whether cancellation has been requested yet.
*/
public function isRequested(): bool {
public function isRequested(): bool
{
return $this->__call('isRequested');
}
@ -46,7 +48,8 @@ final class Cancellation extends Obj implements AmpCancellation
*
* @throws CancelledException
*/
public function throwIfRequested(): void {
public function throwIfRequested(): void
{
$this->__call('throwIfRequested');
}
}

View File

@ -1637,8 +1637,8 @@ final class MTProto implements TLCallback, LoggerGetter
}
/**
* Get authorization info.
*
* @return API::NOT_LOGGED_IN|API::WAITING_CODE|API::WAITING_SIGNUP|API::WAITING_PASSWORD|API::LOGGED_IN
*
* @return \danog\MadelineProto\API::NOT_LOGGED_IN|\danog\MadelineProto\API::WAITING_CODE|\danog\MadelineProto\API::WAITING_SIGNUP|\danog\MadelineProto\API::WAITING_PASSWORD|\danog\MadelineProto\API::LOGGED_IN
*/
public function getAuthorization(): int
{

View File

@ -29,7 +29,6 @@ use danog\MadelineProto\SecurityException;
use danog\MadelineProto\Settings\TLSchema;
use danog\MadelineProto\TL\Types\Button;
use danog\MadelineProto\TL\Types\Bytes;
use danog\MadelineProto\TL\Types\LoginQrCode;
use danog\MadelineProto\Tools;
use Webmozart\Assert\Assert;

View File

@ -58,7 +58,7 @@ final class Button implements JsonSerializable, ArrayAccess
private array|int $peer;
/**
* Constructor function.
*
*
* @internal
*
* @param MTProto $API API instance

View File

@ -25,7 +25,6 @@ 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;
@ -35,13 +34,12 @@ 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 {
final class LoginQrCode implements JsonSerializable
{
private string $session;
/** @internal */
@ -75,8 +73,9 @@ final class LoginQrCode implements JsonSerializable {
/**
* Returns true if the QR code has expired and a new one should be fetched.
*/
public function isExpired(): bool {
return $this->expiry <= time();
public function isExpired(): bool
{
return $this->expiry <= \time();
}
/**
@ -84,34 +83,37 @@ final class LoginQrCode implements JsonSerializable {
*
* @return non-negative-int
*/
public function expiresIn(): int {
return max(0, $this->expiry - time());
public function expiresIn(): int
{
return \max(0, $this->expiry - \time());
}
public function getExpirationCancellation(): Cancellation {
public function getExpirationCancellation(): Cancellation
{
return new TimeoutCancellation((float) $this->expiresIn(), "The QR code expired!");
}
public function getLoginCancellation(): Cancellation {
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 {
public function waitForLoginOrQrCodeExpiration(?Cancellation $customCancellation = null): ?self
{
$expire = $this->getExpirationCancellation();
if ($customCancellation) {
$cancellation = new CompositeCancellation($expire, $customCancellation);
@ -132,9 +134,10 @@ final class LoginQrCode implements JsonSerializable {
/**
* Render and return SVG version of QR code.
*/
public function getQRSvg(): string {
public function getQRSvg(int $size = 400, int $margin = 4): string
{
$writer = new Writer(new ImageRenderer(
new RendererStyle(400),
new RendererStyle($size, $margin),
new SvgImageBackEnd
));
return $writer->writeString($this->link);
@ -142,11 +145,12 @@ final class LoginQrCode implements JsonSerializable {
/**
* Render and return plain text version of QR code.
*
*
* @param non-negative-int $margin Text margin
*/
public function getQRText(int $margin = 2): string {
public function getQRText(int $margin = 2): string
{
$writer = new Writer(new PlainTextRenderer($margin));
return $writer->writeString($this->link);
}
}
}

View File

@ -22,11 +22,9 @@ namespace danog\MadelineProto\Wrappers;
use Amp\Cancellation;
use Amp\CancelledException;
use Amp\CompositeCancellation;
use Amp\DeferredCancellation;
use Amp\DeferredFuture;
use AssertionError;
use BaconQrCode\Encoder\QrCode;
use danog\MadelineProto\Exception;
use danog\MadelineProto\Lang;
use danog\MadelineProto\Logger;
@ -37,7 +35,6 @@ use danog\MadelineProto\RPCErrorException;
use danog\MadelineProto\Settings;
use danog\MadelineProto\TL\Types\LoginQrCode;
use danog\MadelineProto\Tools;
use Webmozart\Assert\Assert;
/**
* Manages logging in and out.
@ -74,12 +71,13 @@ trait Login
private ?DeferredCancellation $qrLoginDeferred = null;
/**
* Initiates QR code login.
*
*
* Returns a QR code login helper object, that can be used to render the QR code, display the link directly, wait for login, QR code expiration and much more.
*
*
* Returns null if we're already logged in, or if we're waiting for a password (use getAuthorization to distinguish between the two cases).
*/
public function qrLogin(): ?LoginQrCode {
public function qrLogin(): ?LoginQrCode
{
if ($this->authorized === MTProto::LOGGED_IN) {
return null;
} elseif ($this->authorized === MTProto::WAITING_PASSWORD) {
@ -134,7 +132,8 @@ trait Login
/**
* @internal
*/
public function getQrLoginCancellation(): Cancellation {
public function getQrLoginCancellation(): Cancellation
{
if ($this->qrLoginDeferred) {
return $this->qrLoginDeferred->getCancellation();
}
@ -143,13 +142,15 @@ trait Login
return $c->getCancellation();
}
/** @internal */
public function waitQrLogin(): void {
public function waitQrLogin(): void
{
if (!$this->qrLoginDeferred) {
return;
}
try {
(new DeferredFuture)->getFuture()->await($this->getQrLoginCancellation());
} catch (CancelledException) {}
} catch (CancelledException) {
}
}
/**
* Login as user.
@ -309,7 +310,8 @@ trait Login
$this->logger->logger(Lang::$current_lang['login_user'], Logger::NOTICE);
return $this->processAuthorization($this->methodCallAsyncRead('auth.checkPassword', ['password' => $password]));
}
private function processAuthorization(array $authorization): array {
private function processAuthorization(array $authorization): array
{
if ($this->authorized === MTProto::LOGGED_IN) {
throw new Exception(Lang::$current_lang['already_loggedIn']);
}

View File

@ -22,8 +22,6 @@ namespace danog\MadelineProto\Wrappers;
use Amp\CancelledException;
use Amp\CompositeCancellation;
use Amp\TimeoutCancellation;
use Amp\TimeoutException;
use danog\MadelineProto\Exception;
use danog\MadelineProto\Ipc\Client;
use danog\MadelineProto\Lang;
@ -33,10 +31,10 @@ use danog\MadelineProto\Settings;
use danog\MadelineProto\TL\Types\LoginQrCode;
use danog\MadelineProto\Tools;
use function Amp\ByteStream\getStdout;
use const PHP_SAPI;
use function Amp\ByteStream\getStdout;
/**
* Manages simple logging in and out.
*
@ -87,7 +85,7 @@ trait Start
$stdout->write(PHP_EOL."The QR code expired, generating a new one...".PHP_EOL);
}
} while (true);
if (str_contains($result, ':')) {
if (\str_contains($result, ':')) {
$this->botLogin($result);
} else {
$this->phoneLogin($result);

View File

@ -55,7 +55,7 @@ trait Templates
$form = "<input type='text' name='token' placeholder='$token' required/>";
}
} elseif (isset($_GET['waitQrCodeOrLogin']) || isset($_GET['getQrCode'])) {
header('Content-type: application/json');
\header('Content-type: application/json');
try {
/** @var ?LoginQrCode */
$qr = $this->qrLogin();
@ -69,14 +69,14 @@ trait Templates
if ($qr) {
$result = [
'logged_in' => false,
'svg' => $qr->getQRSvg()
'svg' => $qr->getQRSvg(400, 2)
];
} else {
$result = [
'logged_in' => true,
];
}
getOutputBufferStream()->write(json_encode($result));
getOutputBufferStream()->write(\json_encode($result));
return;
} else {
$title = Lang::$current_lang['loginChoosePromptWeb'];
@ -84,7 +84,7 @@ trait Templates
$optionUser = \htmlentities(Lang::$current_lang['loginOptionUser']);
$trailer = '
<div id="qr-code-container" style="display: none">
<p>'.htmlentities(Lang::$current_lang['loginWebQr']).'</p>
<p>'.\htmlentities(Lang::$current_lang['loginWebQr']).'</p>
<div id="qr-code"></div>
</div>