Localize login

This commit is contained in:
Daniil Gentili 2020-09-26 21:57:06 +02:00
parent c9ebdd0fa8
commit 86fc8b6e6e
17 changed files with 341 additions and 261 deletions

View File

@ -23,8 +23,8 @@ use Amp\Ipc\Sync\ChannelledSocket;
use Amp\Loop;
use danog\MadelineProto\Ipc\Client;
use danog\MadelineProto\Ipc\Server;
use danog\MadelineProto\Settings\Ipc as SettingsIpc;
use danog\MadelineProto\Settings\Logger as SettingsLogger;
use danog\MadelineProto\Settings\Serialization as SettingsSerialization;
/**
* Main API wrapper for MadelineProto.
@ -128,7 +128,7 @@ class API extends InternalDoc
/**
* Async constructor function.
*
* @param Settings|SettingsEmpty|SettingsSerialization $settings Settings
* @param Settings|SettingsEmpty|SettingsIpc $settings Settings
*
* @return \Generator
*/
@ -136,13 +136,15 @@ class API extends InternalDoc
{
Logger::constructorFromSettings($settings instanceof Settings
? $settings->getLogger()
: new SettingsLogger);
: ($settings instanceof SettingsLogger ? $settings : new SettingsLogger));
if (yield from $this->connectToMadelineProto($settings)) {
return; // OK
}
if (!$settings instanceof Settings) {
$settings = new Settings;
$newSettings = new Settings;
$newSettings->merge($settings);
$settings = $newSettings;
}
$appInfo = $settings->getAppInfo();
@ -184,7 +186,7 @@ class API extends InternalDoc
*/
protected function connectToMadelineProto(SettingsAbstract $settings, bool $forceFull = false): \Generator
{
if ($settings instanceof SettingsSerialization) {
if ($settings instanceof SettingsIpc) {
$forceFull = $forceFull || $settings->getForceFull();
} elseif ($settings instanceof Settings) {
$forceFull = $forceFull || $settings->getSerialization()->getForceFull();
@ -218,7 +220,7 @@ class API extends InternalDoc
unset($unserialized);
if ($settings instanceof SettingsSerialization) {
if ($settings instanceof SettingsIpc) {
$settings = new SettingsEmpty;
}
yield from $this->API->wakeup($settings, $this->wrapper);

View File

@ -189,7 +189,7 @@ final class APIWrapper
}
yield from $this->session->serialize(
yield from $this->API->serializeSession($this),
$this->API ? yield from $this->API->serializeSession($this) : $this,
$this->session->getSessionPath()
);

View File

@ -19,6 +19,7 @@
namespace danog\MadelineProto\ApiWrappers;
use danog\MadelineProto\Lang;
use danog\MadelineProto\MyTelegramOrgWrapper;
use danog\MadelineProto\Settings;
use danog\MadelineProto\Tools;
@ -41,31 +42,37 @@ trait Start
if (\defined(\MADELINE_WORKER::class)) {
throw new \danog\MadelineProto\Exception('Not inited!');
}
if ($this->getWebAPITemplate() === 'legacy') {
$this->setWebAPITemplate($settings->getTemplates()->getHtmlTemplate());
}
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
$stdout = getStdout();
yield $stdout->write('You did not define a valid API ID/API hash. Do you want to define it now manually, or automatically? (m/a)
Note that you can also provide the API parameters directly in the code using the settings: https://docs.madelineproto.xyz/docs/SETTINGS.html#settingsapp_infoapi_id'.PHP_EOL);
if (\strpos(yield Tools::readLine('Your choice (m/a): '), 'm') !== false) {
yield $stdout->write('1) Login to my.telegram.org
2) Go to API development tools
3) App title: your app\'s name, can be anything
Short name: your app\'s short name, can be anything
URL: your app/website\'s URL, or t.me/yourusername
Platform: anything
Description: Describe your app here
4) Click on create application'.PHP_EOL);
$app['api_id'] = yield Tools::readLine('5) Enter your API ID: ');
$app['api_hash'] = yield Tools::readLine('6) Enter your API hash: ');
$prepare = Lang::$current_lang['apiChooseManualAuto'].PHP_EOL;
$prepare .= \sprintf(Lang::$current_lang['apiChooseManualAutoTip'], 'https://docs.madelineproto.xyz/docs/SETTINGS.html#settingsapp_infoapi_id');
$prepare .= PHP_EOL;
yield $stdout->write($prepare);
if (\strpos(yield Tools::readLine(Lang::$current_lang['apiChoosePrompt']), 'm') !== false) {
yield $stdout->write("1) ".Lang::$current_lang['apiManualInstructions0'].PHP_EOL);
yield $stdout->write("2) ".Lang::$current_lang['apiManualInstructions1'].PHP_EOL);
yield $stdout->write("3) ");
foreach (['App title', 'Short name', 'URL', 'Platform', 'Description'] as $k => $key) {
yield $stdout->write($k ? " $key: " : "$key: ");
yield $stdout->write(Lang::$current_lang["apiAppInstructionsManual$k"].PHP_EOL);
}
yield $stdout->write("4) ".Lang::$current_lang['apiManualInstructions2'].PHP_EOL);
$app['api_id'] = yield Tools::readLine("5) ".Lang::$current_lang['apiManualPrompt0']);
$app['api_hash'] = yield Tools::readLine("6) ".Lang::$current_lang['apiManualPrompt1']);
return $app;
}
$this->myTelegramOrgWrapper = new \danog\MadelineProto\MyTelegramOrgWrapper($settings);
yield from $this->myTelegramOrgWrapper->login(yield Tools::readLine('Enter a phone number that is already registered on Telegram: '));
yield from $this->myTelegramOrgWrapper->completeLogin(yield Tools::readLine('Enter the verification code you received in telegram: '));
yield from $this->myTelegramOrgWrapper->login(yield Tools::readLine(Lang::$current_lang['apiAutoPrompt0']));
yield from $this->myTelegramOrgWrapper->completeLogin(yield Tools::readLine(Lang::$current_lang['apiAutoPrompt1']));
if (!(yield from $this->myTelegramOrgWrapper->hasApp())) {
$app_title = yield Tools::readLine('Enter the app\'s name, can be anything: ');
$short_name = yield Tools::readLine('Enter the app\'s short name, can be anything: ');
$url = yield Tools::readLine('Enter the app/website\'s URL, or t.me/yourusername: ');
$description = yield Tools::readLine('Describe your app: ');
$app_title = yield Tools::readLine(Lang::$current_lang['apiAppInstructionsAuto0']);
$short_name = yield Tools::readLine(Lang::$current_lang['apiAppInstructionsAuto1']);
$url = yield Tools::readLine(Lang::$current_lang['apiAppInstructionsAuto2']);
$description = yield Tools::readLine(Lang::$current_lang['apiAppInstructionsAuto4']);
$app = (yield from $this->myTelegramOrgWrapper->createApp(['app_title' => $app_title, 'app_shortname' => $short_name, 'app_url' => $url, 'app_platform' => 'web', 'app_desc' => $description]));
} else {
$app = (yield from $this->myTelegramOrgWrapper->getApp());
@ -82,7 +89,7 @@ Note that you can also provide the API parameters directly in the code using the
} elseif (isset($_POST['phone_number'])) {
yield from $this->webAPIPhoneLogin($settings);
} else {
yield from $this->webAPIEcho();
yield $this->webAPIEcho();
}
} elseif (!$this->myTelegramOrgWrapper->loggedIn()) {
if (isset($_POST['code'])) {
@ -90,7 +97,7 @@ Note that you can also provide the API parameters directly in the code using the
if (yield from $this->myTelegramOrgWrapper->hasApp()) {
return yield from $this->myTelegramOrgWrapper->getApp();
}
yield from $this->webAPIEcho();
yield $this->webAPIEcho();
} elseif (isset($_POST['api_id']) && isset($_POST['api_hash'])) {
$app['api_id'] = (int) $_POST['api_id'];
$app['api_hash'] = $_POST['api_hash'];
@ -100,7 +107,7 @@ Note that you can also provide the API parameters directly in the code using the
yield from $this->webAPIPhoneLogin($settings);
} else {
$this->myTelegramOrgWrapper = null;
yield from $this->webAPIEcho();
yield $this->webAPIEcho();
}
} else {
if (isset($_POST['app_title'], $_POST['app_shortname'], $_POST['app_url'], $_POST['app_platform'], $_POST['app_desc'])) {
@ -108,7 +115,7 @@ Note that you can also provide the API parameters directly in the code using the
$this->gettingApiId = false;
return $app;
}
yield from $this->webAPIEcho("You didn't provide all of the required parameters!");
yield from $this->webAPIEcho(Lang::$current_lang['apiParamsError']);
}
return null;
}
@ -117,9 +124,9 @@ Note that you can also provide the API parameters directly in the code using the
try {
$this->myTelegramOrgWrapper = new MyTelegramOrgWrapper($settings);
yield from $this->myTelegramOrgWrapper->login($_POST['phone_number']);
yield from $this->webAPIEcho();
yield $this->webAPIEcho();
} catch (\Throwable $e) {
yield from $this->webAPIEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webAPIEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
}
}
private function webAPICompleteLogin(): \Generator
@ -127,9 +134,9 @@ Note that you can also provide the API parameters directly in the code using the
try {
yield from $this->myTelegramOrgWrapper->completeLogin($_POST['code']);
} catch (\danog\MadelineProto\RPCErrorException $e) {
yield from $this->webAPIEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webAPIEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
} catch (\danog\MadelineProto\Exception $e) {
yield from $this->webAPIEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webAPIEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
}
}
private function webAPICreateApp(): \Generator
@ -140,9 +147,9 @@ Note that you can also provide the API parameters directly in the code using the
$app = (yield from $this->myTelegramOrgWrapper->createApp($params));
return $app;
} catch (\danog\MadelineProto\RPCErrorException $e) {
yield from $this->webAPIEcho('ERROR: '.$e->getMessage().' Try again.');
yield from $this->webAPIEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
} catch (\danog\MadelineProto\Exception $e) {
yield from $this->webAPIEcho('ERROR: '.$e->getMessage().' Try again.');
yield from $this->webAPIEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
}
}
}

View File

@ -19,6 +19,9 @@
namespace danog\MadelineProto\ApiWrappers;
use Amp\Promise;
use danog\MadelineProto\Lang;
use function Amp\ByteStream\getOutputBufferStream;
trait Templates
@ -28,7 +31,7 @@ trait Templates
*
* @var string
*/
private $webApiTemplate = '<!DOCTYPE html><html><head><title>MadelineProto</title></head><body><h1>MadelineProto</h1><p>%s</p><form method="POST">%s<button type="submit"/>Go</button></form></body></html>';
private $webApiTemplate = 'legacy';
/**
* Generate page from template.
*
@ -39,7 +42,7 @@ trait Templates
*/
private function webAPIEchoTemplate(string $message, string $form): string
{
return \sprintf($this->webApiTemplate, $message, $form);
return \sprintf($this->webApiTemplate, $message, $form, Lang::$current_lang['go']);
}
/**
* Get web API login HTML template string.
@ -64,72 +67,86 @@ trait Templates
*
* @param string $message Message to echo
*
* @return \Generator
* @return Promise
*/
private function webAPIEcho(string $message = ''): \Generator
private function webAPIEcho(string $message = ''): Promise
{
$stdout = getOutputBufferStream();
$message = \htmlentities($message);
if (!isset($this->myTelegramOrgWrapper)) {
if (isset($_POST['type'])) {
if ($_POST['type'] === 'manual') {
yield $stdout->write($this->webAPIEchoTemplate('Enter your API ID and API hash<br><b>'.$message.'</b><ol>
<li>Login to my.telegram.org</li>
<li>Go to API development tools</li>
<li>
<ul>
<li>App title: your app&apos;s name, can be anything</li>
<li>Short name: your app&apos;s short name, only numbers and letters</li>
<li>Platform: Web</li>
<li>Description: describe your app here</li>
</ul>
</li>
<li>Click on create application</li>
</ol>', '<input type="string" name="api_id" placeholder="API ID" required/><input type="string" name="api_hash" placeholder="API hash" required/>'));
$title = \htmlentities(Lang::$current_lang['apiManualWeb']);
$title .= "<br><b>$message</b>";
$title .= "<ol>";
$title .= "<li>".\htmlentities(Lang::$current_lang['apiManualInstructions0'])."</li>";
$title .= "<li>".\htmlentities(Lang::$current_lang['apiManualInstructions1'])."</li>";
$title .= "<li><ul>";
foreach (['App title', 'Short name', 'URL', 'Platform', 'Description'] as $k => $key) {
$title .= "<li>$key: ";
$title .= \htmlentities(Lang::$current_lang["apiAppInstructionsManual$k"]);
$title .= "</li>";
}
$title .= "</li></ul>";
$title .= "<li>".\htmlentities(Lang::$current_lang['apiManualInstructions2'])."</li>";
$title .= "</ol>";
$form = '<input type="string" name="api_id" placeholder="API ID" required/>';
$form .= '<input type="string" name="api_hash" placeholder="API hash" required/>';
} else {
yield $stdout->write($this->webAPIEchoTemplate('Enter a phone number that is <b>already registered</b> on telegram to get the API ID<br><b>'.$message.'</b>', '<input type="text" name="phone_number" placeholder="Phone number" required/>'));
$title = Lang::$current_lang['apiAutoWeb'];
$title .= "<br><b>$message</b>";
$phone = \htmlentities(Lang::$current_lang['loginUserPhoneWeb']);
$form = "<input type='text' name='phone_number' placeholder='$phone' required/>";
}
} else {
if ($message) {
$message = '<br><br>'.$message;
}
yield $stdout->write($this->webAPIEchoTemplate('Do you want to enter the API id and the API hash manually or automatically?<br>Note that you can also provide it directly in the code using the <a href="https://docs.madelineproto.xyz/docs/SETTINGS.html#settingsapp_infoapi_id">settings</a>.<b>'.$message.'</b>', '<select name="type"><option value="automatic">Automatically</option><option value="manual">Manually</option></select>'));
$title = \htmlentities(Lang::$current_lang['apiChooseManualAutoWeb']);
$title .= "<br>";
$title .= \sprintf(Lang::$current_lang['apiChooseManualAutoTipWeb'], 'https://docs.madelineproto.xyz/docs/SETTINGS.html#settingsapp_infoapi_id');
$title .= "<b>$message</b>";
$automatically = \htmlentities(Lang::$current_lang['apiChooseAutomaticallyWeb']);
$manually = \htmlentities(Lang::$current_lang['apiChooseManuallyWeb']);
$form = "<select name='type'><option value='automatic'>$automatically</option><option value='manual'>$manually</option></select>";
}
} else {
if (!$this->myTelegramOrgWrapper->loggedIn()) {
yield $stdout->write($this->webAPIEchoTemplate('Enter your code<br><b>'.$message.'</b>', '<input type="text" name="code" placeholder="Code" required/>'));
$title = \htmlentities(Lang::$current_lang['loginUserCode']);
$title .= "<br><b>$message</b>";
$code = \htmlentities(Lang::$current_lang['loginUserPhoneCodeWeb']);
$form = "<input type='text' name='code' placeholder='$code' required/>";
} else {
yield $stdout->write($this->webAPIEchoTemplate('Enter the API info<br><b>'.$message.'</b>', '<input type="hidden" name="creating_app" value="yes" required/>
Enter the app name, can be anything: <br><input type="text" name="app_title" required/><br>
<br>Enter the app&apos;s short name, alphanumeric, 5-32 chars: <br><input type="text" name="app_shortname" required/><br>
<br>Enter the app/website URL, or https://t.me/yourusername: <br><input type="text" name="app_url" required/><br>
<br>Enter the app platform: <br>
<label>
<input type="radio" name="app_platform" value="android" checked> Android
</label>
<label>
<input type="radio" name="app_platform" value="ios"> iOS
</label>
<label>
<input type="radio" name="app_platform" value="wp"> Windows Phone
</label>
<label>
<input type="radio" name="app_platform" value="bb"> BlackBerry
</label>
<label>
<input type="radio" name="app_platform" value="desktop"> Desktop
</label>
<label>
<input type="radio" name="app_platform" value="web"> Web
</label>
<label>
<input type="radio" name="app_platform" value="ubp"> Ubuntu phone
</label>
<label>
<input type="radio" name="app_platform" value="other"> Other (specify in description)
</label>
<br><br>Enter the app description, can be anything: <br><textarea name="app_desc" required></textarea><br><br>
'));
$title = \htmlentities(Lang::$current_lang['apiAppWeb']);
$title .= "<br><b>$message</b>";
$form = '<input type="hidden" name="creating_app" value="yes" required/>';
foreach (['app_title', 'app_shortname', 'app_url', 'app_platform', 'app_desc'] as $field) {
$desc = \htmlentities(Lang::$current_lang["apiAppInstructionsAuto$field"]);
if ($field == 'app_platform') {
$form .= "$desc<br>";
foreach ([
'android' => 'Android',
'ios' => 'iOS',
'wp' => 'Windows Phone',
'bb' => 'BlackBerry',
'desktop' => 'Desktop',
'web' => 'Web',
'ubp' => 'Ubuntu phone',
'other' => \htmlentities(Lang::$current_lang['apiAppInstructionsAutoTypeOther'])
] as $key => $desc) {
$form .= "<label><input type='radio' name='app_platform' value='$key' checked> $desc</label>";
}
} elseif ($field === 'app_desc') {
$form .= "$desc<br><textarea name='$field' required></textarea><br><br>";
} else {
$form .= "$desc<br><input type='text' name='$field' required/><br><br>";
}
}
}
}
return getOutputBufferStream()->write($this->webAPIEchoTemplate($title, $form));
}
}

View File

@ -200,7 +200,7 @@ class DataCenter
{
$this->API = $API;
$changed = [];
$changedSettings = $settings->haveChanged();
$changedSettings = $settings->hasChanged();
if (!$reconnectAll) {
$changed = [];
$test = $API->getCachedConfig()['test_mode'] ?? false ? 'test' : 'main';

View File

@ -30,9 +30,9 @@ class DbPropertiesFactory
$config = $propertyType['config'] ?? [];
$propertyType = \is_array($propertyType) ? $propertyType['type'] : $propertyType;
$propertyType = \strtolower($propertyType);
$class = $config['enableCache'] ?? true && !$dbSettings instanceof Memory
? __NAMESPACE__
: __NAMESPACE__.'\\NullCache';
$class = !($config['enableCache'] ?? true) && !$dbSettings instanceof Memory
? __NAMESPACE__.'\\NullCache'
: __NAMESPACE__;
switch (true) {
case $dbSettings instanceof Memory:

View File

@ -105,7 +105,7 @@ class Lang
'type_extract_error_id' => 'Non sono riuscito ad estrarre il tipo %s con ID %s',
'constructor_not_found' => 'Costruttore non trovato per tipo: ',
'rand_bytes_too_small' => 'random_bytes è troppo corto!',
'botapi_conversion_error' => 'NOn sono risucito a convertire %s in un oggetto bot API',
'botapi_conversion_error' => 'Non sono risucito a convertire %s in un oggetto bot API',
'non_text_conversion' => 'Non posso ancora convertire messaggi media',
'last_byte_invalid' => 'L\'ultimo byte non è valido',
'file_type_invalid' => 'È stato fornito un tipo file errato',
@ -123,42 +123,62 @@ class Lang
'apiAppInstructionsAuto4' => 'Descrivi la tua app: ',
'apiAppInstructionsManual0' => 'titolo dell\'app, può essere qualsiasi cosa',
'apiAppInstructionsManual1' => 'il nome ridotto dell\'app, caratteri alfanumerici: ',
'apiAppInstructionsManual2' => '',
'apiAppInstructionsManual3' => '',
'apiAppInstructionsManual4' => '',
'apiAutoPrompt0' => '',
'apiAutoPrompt1' => '',
'apiChooseManualAuto' => '',
'apiChooseManualAutoTip' => '',
'apiChoosePrompt' => '',
'apiError' => '',
'apiManualInstructions0' => '',
'apiManualInstructions1' => '',
'apiManualInstructions2' => '',
'apiManualPrompt0' => '',
'apiManualPrompt1' => '',
'apiParamsError' => '',
'loginBot' => '',
'loginChoosePrompt' => '',
'loginNoCode' => '',
'loginNoName' => '',
'loginNoPass' => '',
'loginUser' => '',
'loginUser2FA' => '',
'loginUser2FAHint' => '',
'loginUser2FAWeb' => '',
'loginUserCode' => '',
'signupFirstName' => '',
'signupFirstNameWeb' => '',
'signupLastName' => '',
'signupLastNameWeb' => '',
'signupWeb' => '',
'apiAppInstructionsManual2' => 'L\'indirizzo del tuo sito, oppure t.me/username',
'apiAppInstructionsManual3' => 'Qualsiasi',
'apiAppInstructionsManual4' => 'Descrivi la tua app',
'apiAutoPrompt0' => 'Inserisci un numero di telefono che è già registrato su Telegram: ',
'apiAutoPrompt1' => 'Inserisci il codice di verifica che hai ricevuto su Telegram: ',
'apiChooseManualAutoTip' => 'Nota che puoi anche fornire i parametri API direttamente nelle impostazioni: %s',
'apiChoosePrompt' => 'La tua scelta (m/a): ',
'apiError' => 'ERRORE: %s. Prova ancora.',
'apiManualInstructions0' => 'Effettua il login su my.telegram.org',
'apiManualInstructions1' => 'Vai su API development tools',
'apiManualInstructions2' => 'Clicca su create application',
'apiManualPrompt0' => 'Inserisci il tuo API ID: ',
'apiManualPrompt1' => 'Inserisci il tuo API hash: ',
'apiParamsError' => 'Non hai fornito tutti i parametri richiesti!',
'loginBot' => 'Inserisci il tuo bot token: ',
'loginChoosePrompt' => 'Vuoi effettuare il login come utente o come bot (u/b)? ',
'loginNoCode' => 'Non hai fornito un codice di verifica!',
'loginNoName' => 'Non hai fornito un nome!',
'loginNoPass' => 'Non hai fornito la password!',
'loginUser' => 'Inserisci il tuo numero di telefono: ',
'loginUserPass' => 'Inserisci la tua password (suggerimento %s): ',
'loginUserPassHint' => 'Suggerimento: %s',
'loginUserPassWeb' => 'Inserisci la tua password: ',
'loginUserCode' => 'Inserisci il codice di verifica: ',
'signupFirstName' => 'Inserisci il tuo nome: ',
'signupFirstNameWeb' => 'Nome',
'signupLastName' => 'Inserisci il tuo cognome: ',
'signupLastNameWeb' => 'Cognome',
'signupWeb' => 'Registrazione',
'go' => 'Vai',
'loginChoosePromptWeb' => 'Vuoi effettuare il login come utente o come bot?',
'loginOptionBot' => 'Bot',
'loginOptionUser' => 'Utente',
'loginBotTokenWeb' => 'Token del bot',
'loginUserPhoneCodeWeb' => 'Codice di verifica',
'loginUserPhoneWeb' => 'Numero di telefono',
'apiAutoWeb' => 'Inserisci un numero di telefono <b>gi&agrave; registrato su Telegram</b> per ottenere l&apos;API ID',
'apiChooseManualAuto' => 'You did not define a valid API ID/API hash. Do you want to define it now manually, or automatically? (m/a)',
'apiManualWeb' => 'Inserisci il tuo API ID e API hash',
'apiAppInstructionsAutoTypeOther' => 'Altro (specificare nella descrizione)',
'apiAppWeb' => 'Inserire informazioni API',
'apiChooseAutomaticallyWeb' => 'Automaticamente',
'apiChooseManualAutoTipWeb' => 'Nota che puoi anche fornire i parametri API direttamente nelle <a target="_blank" href="%s">impostazioni</a>.',
'apiChooseManualAutoWeb' => 'Vuoi configurare il tuo API ID/hash manualmente o automaticamente?',
'apiChooseManuallyWeb' => 'Manualmente',
],
'en' =>
[
'apiChooseManualAuto' => 'You did not define a valid API ID/API hash. Do you want to define it now manually, or automatically? (m/a)',
'apiChooseManualAutoTip' => 'Note that you can also provide the API parameters directly in the code using the settings: %s',
'go' => 'Go',
'apiChooseManualAuto' => 'Do you want to enter the API id and the API hash manually or automatically? (m/a)',
'apiChooseManualAutoWeb' => 'Do you want to enter the API id and the API hash manually or automatically?',
'apiChooseManualAutoTip' => 'Note that you can also provide them directly in the code using the settings: %s',
'apiChooseManualAutoTipWeb' => 'Note that you can also provide them directly in the code using the <a target="_blank" href="%s">settings</a>.',
'apiChoosePrompt' => 'Your choice (m/a): ',
'apiChooseAutomaticallyWeb' => 'Automatically',
'apiChooseManuallyWeb' => 'Manually',
'apiManualInstructions0' => 'Login to my.telegram.org',
'apiManualInstructions1' => 'Go to API development tools',
'apiManualInstructions2' => 'Click on create application',
@ -167,24 +187,31 @@ class Lang
'apiAppInstructionsManual2' => 'your app/website\'s URL, or t.me/yourusername',
'apiAppInstructionsManual3' => 'anything',
'apiAppInstructionsManual4' => 'Describe your app here',
'apiManualWeb' => 'Enter your API ID and API hash',
'apiManualPrompt0' => 'Enter your API ID: ',
'apiManualPrompt1' => 'Enter your API hash: ',
'apiAutoWeb' => 'Enter a phone number that is <b>already registered</b> on telegram to get the API ID',
'apiAutoPrompt0' => 'Enter a phone number that is already registered on Telegram: ',
'apiAutoPrompt1' => 'Enter the verification code you received in Telegram: ',
'apiAppWeb' => 'Enter API information',
'apiAppInstructionsAuto0' => 'Enter the app\'s name, can be anything: ',
'apiAppInstructionsAuto1' => 'Enter the app\'s short name, alphanumeric: ',
'apiAppInstructionsAuto2' => 'Enter the app/website\'s URL, or t.me/yourusername: ',
'apiAppInstructionsAuto3' => 'Enter the app platform: ',
'apiAppInstructionsAuto4' => 'Describe your app: ',
'apiAppInstructionsAutoTypeOther' => 'Other (specify in description)',
'apiParamsError' => 'You didn\'t provide all of the required parameters!',
'apiError' => 'ERROR: %s. Try again.',
'loginChoosePrompt' => 'Do you want to login as user or bot (u/b)? ',
'loginChoosePromptWeb' => 'Do you want to login as user or bot?',
'loginOptionBot' => 'Bot',
'loginOptionUser' => 'User',
'loginBot' => 'Enter your bot token: ',
'loginUser' => 'Enter your phone number: ',
'loginUserCode' => 'Enter the phone code: ',
'loginUser2FA' => 'Enter your password (hint %s): ',
'loginUser2FAWeb' => 'Enter your password: ',
'loginUser2FAHint' => 'Hint: %s',
'loginUserCode' => 'Enter the code: ',
'loginUserPass' => 'Enter your password (hint %s): ',
'loginUserPassWeb' => 'Enter your password: ',
'loginUserPassHint' => 'Hint: %s',
'signupFirstName' => 'Enter your first name: ',
'signupLastName' => 'Enter your last name (can be empty): ',
'signupWeb' => 'Sign up please',
@ -193,6 +220,9 @@ class Lang
'loginNoCode' => 'You didn\'t provide a phone code!',
'loginNoPass' => 'You didn\'t provide the password!',
'loginNoName' => 'You didn\'t provide the first name!',
'loginBotTokenWeb' => 'Bot token',
'loginUserPhoneWeb' => 'Phone number',
'loginUserPhoneCodeWeb' => 'Code',
'done' => 'Done!',
'cdn_reupload' => 'File is not stored on CDN, requesting reupload!',
'stored_on_cdn' => 'File is stored on CDN!',
@ -292,9 +322,14 @@ class Lang
// THIS WILL BE OVERWRITTEN BY $lang["en"]
public static $current_lang = [
'apiChooseManualAuto' => 'You did not define a valid API ID/API hash. Do you want to define it now manually, or automatically? (m/a)',
'apiChooseManualAutoTip' => 'Note that you can also provide the API parameters directly in the code using the settings: %s',
'go' => 'Go',
'apiChooseManualAuto' => 'Do you want to enter the API id and the API hash manually or automatically? (m/a)',
'apiChooseManualAutoWeb' => 'Do you want to enter the API id and the API hash manually or automatically?',
'apiChooseManualAutoTip' => 'Note that you can also provide them directly in the code using the settings: %s',
'apiChooseManualAutoTipWeb' => 'Note that you can also provide them directly in the code using the <a href="%s">settings</a>.',
'apiChoosePrompt' => 'Your choice (m/a): ',
'apiChooseAutomaticallyWeb' => 'Automatically',
'apiChooseManuallyWeb' => 'Manually',
'apiManualInstructions0' => 'Login to my.telegram.org',
'apiManualInstructions1' => 'Go to API development tools',
'apiManualInstructions2' => 'Click on create application',
@ -303,24 +338,31 @@ class Lang
'apiAppInstructionsManual2' => 'your app/website\'s URL, or t.me/yourusername',
'apiAppInstructionsManual3' => 'anything',
'apiAppInstructionsManual4' => 'Describe your app here',
'apiManualWeb' => 'Enter your API ID and API hash',
'apiManualPrompt0' => 'Enter your API ID: ',
'apiManualPrompt1' => 'Enter your API hash: ',
'apiAutoWeb' => 'Enter a phone number that is <b>already registered</b> on telegram to get the API ID',
'apiAutoPrompt0' => 'Enter a phone number that is already registered on Telegram: ',
'apiAutoPrompt1' => 'Enter the verification code you received in Telegram: ',
'apiAppWeb' => 'Enter API information',
'apiAppInstructionsAuto0' => 'Enter the app\'s name, can be anything: ',
'apiAppInstructionsAuto1' => 'Enter the app\'s short name, alphanumeric: ',
'apiAppInstructionsAuto2' => 'Enter the app/website\'s URL, or t.me/yourusername: ',
'apiAppInstructionsAuto3' => 'Enter the app platform: ',
'apiAppInstructionsAuto4' => 'Describe your app: ',
'apiAppInstructionsAutoTypeOther' => 'Other (specify in description)',
'apiParamsError' => 'You didn\'t provide all of the required parameters!',
'apiError' => 'ERROR: %s. Try again.',
'loginChoosePrompt' => 'Do you want to login as user or bot (u/b)? ',
'loginChoosePromptWeb' => 'Do you want to login as user or bot?',
'loginOptionBot' => 'Bot',
'loginOptionUser' => 'User',
'loginBot' => 'Enter your bot token: ',
'loginUser' => 'Enter your phone number: ',
'loginUserCode' => 'Enter the phone code: ',
'loginUser2FA' => 'Enter your password (hint %s): ',
'loginUser2FAWeb' => 'Enter your password: ',
'loginUser2FAHint' => 'Hint: %s',
'loginUserCode' => 'Enter the code: ',
'loginUserPass' => 'Enter your password (hint %s): ',
'loginUserPassWeb' => 'Enter your password: ',
'loginUserPassHint' => 'Hint: %s',
'signupFirstName' => 'Enter your first name: ',
'signupLastName' => 'Enter your last name (can be empty): ',
'signupWeb' => 'Sign up please',
@ -329,6 +371,9 @@ class Lang
'loginNoCode' => 'You didn\'t provide a phone code!',
'loginNoPass' => 'You didn\'t provide the password!',
'loginNoName' => 'You didn\'t provide the first name!',
'loginBotTokenWeb' => 'Bot token',
'loginUserPhoneWeb' => 'Phone number',
'loginUserPhoneCodeWeb' => 'Code',
'done' => 'Done!',
'cdn_reupload' => 'File is not stored on CDN, requesting reupload!',
'stored_on_cdn' => 'File is stored on CDN!',

View File

@ -505,6 +505,7 @@ class MTProto extends AsyncConstruct implements TLCallback
return $data;
}
yield $this->session['data'] = \serialize($data);
var_dump($this);
return $this->session;
}
@ -614,7 +615,7 @@ class MTProto extends AsyncConstruct implements TLCallback
'hook_url',
// Web login template
'web_template',
'webTemplate',
// Settings
'settings',

View File

@ -193,6 +193,7 @@ abstract class Serialization
if ($isNew) {
$unserialized = yield from $session->unserialize();
if ($unserialized instanceof DriverArray) {
Logger::log("Extracting session from database...");
yield from $unserialized->initConnection($unserialized->dbSettings);
$unserialized = \unserialize(yield $unserialized['data']);
}

View File

@ -18,6 +18,7 @@ use danog\MadelineProto\Settings\Pwr;
use danog\MadelineProto\Settings\RPC;
use danog\MadelineProto\Settings\SecretChats;
use danog\MadelineProto\Settings\Serialization;
use danog\MadelineProto\Settings\Templates;
use danog\MadelineProto\Settings\TLSchema;
class Settings extends SettingsAbstract
@ -74,6 +75,10 @@ class Settings extends SettingsAbstract
* DatabaseAbstract settings.
*/
protected DatabaseAbstract $db;
/**
* Template settings.
*/
protected Templates $templates;
/**
* Create settings object from possibly legacy settings array.
@ -111,6 +116,7 @@ class Settings extends SettingsAbstract
$this->serialization = new Serialization;
$this->schema = new TLSchema;
$this->db = new DatabaseMemory;
$this->templates = new Templates;
$this->ipc = new IPc;
}
/**
@ -185,6 +191,8 @@ class Settings extends SettingsAbstract
$this->schema->merge($settings);
} elseif ($settings instanceof Ipc) {
$this->ipc->merge($settings);
} elseif ($settings instanceof Templates) {
$this->templates->merge($settings);
} elseif ($settings instanceof DatabaseAbstract) {
if (!$this->db instanceof $settings) {
$this->db = $settings;
@ -206,6 +214,7 @@ class Settings extends SettingsAbstract
$this->serialization->merge($settings->serialization);
$this->schema->merge($settings->schema);
$this->ipc->merge($settings->ipc);
$this->templates->merge($settings->templates);
if (!$this->db instanceof $settings->db) {
$this->db = $settings->db;
@ -561,8 +570,34 @@ class Settings extends SettingsAbstract
public function applyChanges(): SettingsAbstract
{
foreach (\get_object_vars($this) as $setting) {
$setting->applyChanges();
if ($setting instanceof SettingsAbstract) {
$setting->applyChanges();
}
}
return $this;
}
/**
* Get template settings.
*
* @return Templates
*/
public function getTemplates(): Templates
{
return $this->templates;
}
/**
* Set template settings.
*
* @param Templates $templates Template settings
*
* @return self
*/
public function setTemplates(Templates $templates): self
{
$this->templates = $templates;
return $this;
}
}

View File

@ -70,6 +70,9 @@ class AppInfo extends SettingsAbstract
{
Magic::classExists(true);
// Detect language pack
if (isset(Lang::$lang[$this->langCode])) {
Lang::$current_lang =& Lang::$lang[$this->langCode];
}
$this->appVersion = MTProto::RELEASE.' ('.MTProto::V.', '.\str_replace(' (AN UPDATE IS REQUIRED)', '', Magic::$revision).')';
}

View File

@ -86,10 +86,6 @@ class Connection extends SettingsAbstract
*/
protected bool $retry = true;
/**
* Whether the connection settings changed.
*/
private bool $changed = true;
/**
* Subdomains of web.telegram.org for https protocol.
*/
@ -217,24 +213,6 @@ class Connection extends SettingsAbstract
$this->addProxy(HttpProxy::class, ['address' => 'localhost', 'port' => 80]);
}
}
/**
* Whether the settings have changed.
*
* @return boolean
*/
public function haveChanged(): bool
{
return $this->changed;
}
/**
* Signal that changes have been applied.
*
* @return void
*/
public function applyChanges(): void
{
$this->changed = false;
}
/**
* Get protocol identifier.
*
@ -257,7 +235,6 @@ class Connection extends SettingsAbstract
if (!isset(\class_implements($protocol)[MTProtoBufferInterface::class])) {
throw new Exception("An invalid protocol was specified!");
}
$this->changed = true;
$this->protocol = $protocol;
return $this;
@ -282,7 +259,6 @@ class Connection extends SettingsAbstract
*/
public function setIpv6(bool $ipv6): self
{
$this->changed = true;
$this->ipv6 = $ipv6;
return $this;
@ -307,7 +283,6 @@ class Connection extends SettingsAbstract
*/
public function setSslSubdomains(array $sslSubdomains): self
{
$this->changed = true;
$this->sslSubdomains = $sslSubdomains;
return $this;
@ -332,7 +307,6 @@ class Connection extends SettingsAbstract
*/
public function setMinMediaSocketCount(int $minMediaSocketCount): self
{
$this->changed = true;
$this->minMediaSocketCount = $minMediaSocketCount;
return $this;
@ -357,7 +331,6 @@ class Connection extends SettingsAbstract
*/
public function setMaxMediaSocketCount(int $maxMediaSocketCount): self
{
$this->changed = true;
$this->maxMediaSocketCount = $maxMediaSocketCount;
return $this;
@ -382,7 +355,6 @@ class Connection extends SettingsAbstract
*/
public function setRobinPeriod(int $robinPeriod): self
{
$this->changed = true;
$this->robinPeriod = $robinPeriod;
return $this;
@ -416,7 +388,6 @@ class Connection extends SettingsAbstract
*/
public function setDefaultDc(int $defaultDc): self
{
$this->changed = true;
$this->defaultDc = $defaultDc;
$this->defaultDcParams = ['datacenter' => $defaultDc];
@ -449,7 +420,6 @@ class Connection extends SettingsAbstract
if (!isset($this->proxy[$proxy])) {
$this->proxy[$proxy] = [];
}
$this->changed = true;
$this->proxy[$proxy][] = $extra;
return $this;
@ -483,7 +453,6 @@ class Connection extends SettingsAbstract
if (false === $index = \array_search($extra, $this->proxy[$proxy])) {
return $this;
}
$this->changed = true;
unset($this->proxy[$proxy][$index]);
if (empty($this->proxy[$proxy])) {
unset($this->proxy[$proxy]);
@ -509,7 +478,6 @@ class Connection extends SettingsAbstract
*/
public function setObfuscated(bool $obfuscated): self
{
$this->changed = true;
$this->obfuscated = $obfuscated;
return $this;
@ -534,7 +502,6 @@ class Connection extends SettingsAbstract
*/
public function setTestMode(bool $testMode): self
{
$this->changed = true;
$this->testMode = $testMode;
return $this;
@ -562,7 +529,6 @@ class Connection extends SettingsAbstract
if (!isset(\class_implements($transport)[RawStreamInterface::class])) {
throw new Exception("An invalid transport was specified!");
}
$this->changed = true;
$this->transport = $transport;
return $this;
@ -587,7 +553,6 @@ class Connection extends SettingsAbstract
*/
public function setRetry(bool $retry): self
{
$this->changed = true;
$this->retry = $retry;
return $this;
@ -612,7 +577,6 @@ class Connection extends SettingsAbstract
*/
public function setTimeout(int $timeout): self
{
$this->changed = true;
$this->timeout = $timeout;
return $this;

View File

@ -100,6 +100,10 @@ class Logger extends SettingsAbstract
$this->type = (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg')
? MadelineProtoLogger::ECHO_LOGGER
: MadelineProtoLogger::FILE_LOGGER;
if (!$this->extra && $this->type === MadelineProtoLogger::FILE_LOGGER) {
$this->extra = Magic::$script_cwd.'/MadelineProto.log';
}
$this->init();
}
/**

View File

@ -2,60 +2,39 @@
namespace danog\MadelineProto\Settings;
use danog\MadelineProto\SettingsAbstract;
/**
* Web and CLI template settings for login.
*/
class Templates
class Templates extends SettingsAbstract
{
/**
* Web template used for querying app information.
*/
protected string $apiHtmlTemplate = '<!DOCTYPE html><html><head><title>MadelineProto</title></head><body><h1>MadelineProto</h1><p>%s</p><form method="POST">%s<button type="submit"/>Go</button></form></body></html>';
protected string $htmlTemplate = '<!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>';
/**
* Prompt user to choose manual or automatic API ID generation.
*/
protected string $apiChooseManualAuto = 'You did not define a valid API ID/API hash. Do you want to define it now manually, or automatically? (m/a)';
/**
* Settings tip for API ID generation.
*/
protected string $apiChooseManualAutoTip = 'Note that you can also provide the API parameters directly in the code using the settings: %s';
/**
* Final prompt to choose mode.
*/
protected string $apiChoosePrompt = 'Your choice (m/a): ';
/**
* Instructions for manual API ID generation.
* Get web template used for querying app information.
*
* @var array{0: string, 1: string, 2: array{0: string, 1: string, 2: string, 3: string, 4: string}, 3: string}
* @return string
*/
protected array $apiManualInstructions = [
'Login to my.telegram.org',
'Go to API development tools',
[
'App title: your app\'s name, can be anything',
'Short name: your app\'s short name, can be anything',
'URL: your app/website\'s URL, or t.me/yourusername',
'Platform: anything',
'Description: Describe your app here',
],
'Click on create application'
];
public function getHtmlTemplate(): string
{
return $this->htmlTemplate;
}
/**
* Manual API ID/hash prompts.
* Set web template used for querying app information.
*
* @param string $htmlTemplate Web template used for querying app information.
*
* @return self
*/
protected array $apiManualPrompts = [
'Enter your API ID: ',
'Enter your API hash: '
];
/**
* Auto API ID/hash prompts.
*/
protected array $apiAutoPrompts = [
'Enter a phone number that is already registered on Telegram: ',
'Enter the verification code you received in Telegram: ',
'Enter the app\'s name, can be anything: ',
'Enter the app\'s short name, can be anything: ',
'Enter the app/website\'s URL, or t.me/yourusername: ',
'Describe your app: ',
];
public function setHtmlTemplate(string $htmlTemplate): self
{
$this->htmlTemplate = $htmlTemplate;
return $this;
}
}

View File

@ -20,7 +20,9 @@ abstract class SettingsAbstract
*
* @return void
*/
abstract public function mergeArray(array $settings): void;
public function mergeArray(array $settings): void
{
}
/**
* Merge with other settings instance.
@ -35,6 +37,9 @@ abstract class SettingsAbstract
$defaults = $class->getDefaultProperties();
foreach ($class->getProperties(ReflectionProperty::IS_PROTECTED|ReflectionProperty::IS_PUBLIC) as $property) {
$name = $property->getName();
if ($name === 'changed') {
continue;
}
$uc = \ucfirst($name);
if (isset($other->{$name})
&& (

View File

@ -19,6 +19,7 @@
namespace danog\MadelineProto\Wrappers;
use danog\MadelineProto\Lang;
use danog\MadelineProto\MTProto;
use danog\MadelineProto\Settings;
@ -41,17 +42,20 @@ trait Start
if ((yield $this->getAuthorization()) === MTProto::LOGGED_IN) {
return $this instanceof \danog\MadelineProto\Ipc\Client ? yield from $this->getSelf() : yield from $this->fullGetSelf();
}
if ($this->getWebTemplate() === 'legacy') {
$this->setWebTemplate((yield $this->getSettings())->getTemplates()->getHtmlTemplate());
}
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
if (\strpos(yield Tools::readLine('Do you want to login as user or bot (u/b)? '), 'b') !== false) {
yield from $this->botLogin(yield Tools::readLine('Enter your bot token: '));
if (\strpos(yield Tools::readLine(Lang::$current_lang['loginChoosePrompt']), 'b') !== false) {
yield from $this->botLogin(yield Tools::readLine(Lang::$current_lang['loginBot']));
} else {
yield from $this->phoneLogin(yield Tools::readLine('Enter your phone number: '));
$authorization = (yield from $this->completePhoneLogin(yield Tools::readLine('Enter the phone code: ')));
yield from $this->phoneLogin(yield Tools::readLine(Lang::$current_lang['loginUser']));
$authorization = (yield from $this->completePhoneLogin(yield Tools::readLine(Lang::$current_lang['loginUserCode'])));
if ($authorization['_'] === 'account.password') {
$authorization = (yield from $this->complete2faLogin(yield Tools::readLine('Please enter your password (hint '.$authorization['hint'].'): ')));
$authorization = (yield from $this->complete2faLogin(yield Tools::readLine(\sprintf(Lang::$current_lang['loginUserPass'], $authorization['hint']))));
}
if ($authorization['_'] === 'account.needSignup') {
$authorization = (yield from $this->completeSignup(yield Tools::readLine('Please enter your first name: '), yield Tools::readLine('Please enter your last name (can be empty): ')));
$authorization = (yield from $this->completeSignup(yield Tools::readLine(Lang::$current_lang['signupFirstName']), yield Tools::readLine(Lang::$current_lang['signupLastName'])));
}
}
$this->serialize();
@ -69,19 +73,19 @@ trait Start
if (isset($_POST['phone_code'])) {
yield from $this->webCompletePhoneLogin();
} else {
yield from $this->webEcho("You didn't provide a phone code!");
yield from $this->webEcho(Lang::$current_lang['loginNoCode']);
}
} elseif ((yield $this->getAuthorization()) === MTProto::WAITING_PASSWORD) {
if (isset($_POST['password'])) {
yield from $this->webComplete2faLogin();
} else {
yield from $this->webEcho("You didn't provide the password!");
yield from $this->webEcho(Lang::$current_lang['loginNoPass']);
}
} elseif ((yield $this->getAuthorization()) === MTProto::WAITING_SIGNUP) {
if (isset($_POST['first_name'])) {
yield from $this->webCompleteSignup();
} else {
yield from $this->webEcho("You didn't provide the first name!");
yield from $this->webEcho(Lang::$current_lang['loginNoName']);
}
}
if ((yield $this->getAuthorization()) === MTProto::LOGGED_IN) {
@ -96,9 +100,9 @@ trait Start
yield from $this->phoneLogin($_POST['phone_number']);
yield from $this->webEcho();
} catch (\danog\MadelineProto\RPCErrorException $e) {
yield from $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
} catch (\danog\MadelineProto\Exception $e) {
yield from $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
}
}
private function webCompletePhoneLogin(): \Generator
@ -107,9 +111,9 @@ trait Start
yield from $this->completePhoneLogin($_POST['phone_code']);
yield from $this->webEcho();
} catch (\danog\MadelineProto\RPCErrorException $e) {
yield from $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
} catch (\danog\MadelineProto\Exception $e) {
yield from $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
}
}
private function webComplete2faLogin(): \Generator
@ -118,9 +122,9 @@ trait Start
yield from $this->complete2faLogin($_POST['password']);
yield from $this->webEcho();
} catch (\danog\MadelineProto\RPCErrorException $e) {
yield from $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
} catch (\danog\MadelineProto\Exception $e) {
yield from $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
}
}
private function webCompleteSignup(): \Generator
@ -129,9 +133,9 @@ trait Start
yield from $this->completeSignup($_POST['first_name'], isset($_POST['last_name']) ? $_POST['last_name'] : '');
yield from $this->webEcho();
} catch (\danog\MadelineProto\RPCErrorException $e) {
yield from $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
} catch (\danog\MadelineProto\Exception $e) {
yield from $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
}
}
private function webBotLogin(): \Generator
@ -140,9 +144,9 @@ trait Start
yield from $this->botLogin($_POST['token']);
yield from $this->webEcho();
} catch (\danog\MadelineProto\RPCErrorException $e) {
yield from $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
} catch (\danog\MadelineProto\Exception $e) {
yield from $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
yield from $this->webEcho(\sprintf(Lang::$current_lang['apiError'], $e->getMessage()));
}
}
}

View File

@ -20,6 +20,7 @@
namespace danog\MadelineProto\Wrappers;
use \danog\MadelineProto\MTProto;
use danog\MadelineProto\Lang;
use function Amp\ByteStream\getOutputBufferStream;
trait Templates
@ -33,36 +34,48 @@ trait Templates
*/
private function webEcho(string $message = ''): \Generator
{
$stdout = getOutputBufferStream();
switch (yield $this->getAuthorization()) {
case MTProto::NOT_LOGGED_IN:
if (isset($_POST['type'])) {
if ($_POST['type'] === 'phone') {
yield $stdout->write($this->webEchoTemplate('Enter your phone number<br><b>'.$message.'</b>', '<input type="text" name="phone_number" placeholder="Phone number" required/>'));
} else {
yield $stdout->write($this->webEchoTemplate('Enter your bot token<br><b>'.$message.'</b>', '<input type="text" name="token" placeholder="Bot token" required/>'));
}
$auth = yield $this->getAuthorization();
if ($auth === MTProto::NOT_LOGGED_IN) {
if (isset($_POST['type'])) {
if ($_POST['type'] === 'phone') {
$title = \str_replace(':', '', Lang::$current_lang['loginUser']);
$phone = \htmlentities(Lang::$current_lang['loginUserPhoneWeb']);
$form = "<input type='text' name='phone_number' placeholder='$phone' required/>";
} else {
yield $stdout->write($this->webEchoTemplate('Do you want to login as user or bot?<br><b>'.$message.'</b>', '<select name="type"><option value="phone">User</option><option value="bot">Bot</option></select>'));
$title = \str_replace(':', '', Lang::$current_lang['loginBot']);
$token = \htmlentities(Lang::$current_lang['loginBotTokenWeb']);
$form = "<input type='text' name='token' placeholder='$token' required/>";
}
break;
case MTProto::WAITING_CODE:
yield $stdout->write($this->webEchoTemplate('Enter your code<br><b>'.$message.'</b>', '<input type="text" name="phone_code" placeholder="Phone code" required/>'));
break;
case MTProto::WAITING_PASSWORD:
yield $stdout->write($this->webEchoTemplate('Enter your password<br><b>'.$message.'</b>', '<input type="password" name="password" placeholder="Hint: '.$this->authorization['hint'].'" required/>'));
break;
case MTProto::WAITING_SIGNUP:
yield $stdout->write($this->webEchoTemplate('Sign up please<br><b>'.$message.'</b>', '<input type="text" name="first_name" placeholder="First name" required/><input type="text" name="last_name" placeholder="Last name"/>'));
break;
} else {
$title = Lang::$current_lang['loginChoosePromptWeb'];
$optionBot = \htmlentities(Lang::$current_lang['loginOptionBot']);
$optionUser = \htmlentities(Lang::$current_lang['loginOptionUser']);
$form = "<select name='type'><option value='phone'>$optionUser</option><option value='bot'>$optionBot</option></select>";
}
} elseif ($auth === MTProto::WAITING_CODE) {
$title = \str_replace(':', '', Lang::$current_lang['loginUserCode']);
$phone = \htmlentities(Lang::$current_lang['loginUserPhoneCodeWeb']);
$form = "<input type='text' name='phone_code' placeholder='$phone' required/>";
} elseif ($auth === MTProto::WAITING_PASSWORD) {
$title = Lang::$current_lang['loginUserPassWeb'];
$hint = \htmlentities(\sprintf(Lang::$current_lang['loginUserPassHint'], $this->authorization['hint']));
$form = "<input type='password' name='password' placeholder='$hint' required/>";
} elseif ($auth === MTProto::WAITING_SIGNUP) {
$title = Lang::$current_lang['signupWeb'];
$firstName = Lang::$current_lang['signupFirstNameWeb'];
$lastName = Lang::$current_lang['signupLastNameWeb'];
$form = "<input type='text' name='first_name' placeholder='$firstName' required/><input type='text' name='last_name' placeholder='$lastName'/>";
}
$title = \htmlentities($title);
$message = \htmlentities($message);
return getOutputBufferStream()->write($this->webEchoTemplate("$title<br><b>$message</b>", $form));
}
/**
* Web template.
*
* @var string
*/
private $web_template = '<!DOCTYPE html><html><head><title>MadelineProto</title></head><body><h1>MadelineProto</h1><form method="POST">%s<button type="submit"/>Go</button></form><p>%s</p></body></html>';
private $webTemplate = 'legacy';
/**
* Format message according to template.
*
@ -73,7 +86,7 @@ trait Templates
*/
private function webEchoTemplate(string $message, string $form): string
{
return \sprintf($this->web_template, $form, $message);
return \sprintf($this->webTemplate, $message, $form, Lang::$current_lang['go']);
}
/**
* Get web template.
@ -82,7 +95,7 @@ trait Templates
*/
public function getWebTemplate(): string
{
return $this->web_template;
return $this->webTemplate;
}
/**
* Set web template.
@ -93,6 +106,6 @@ trait Templates
*/
public function setWebTemplate(string $template): void
{
$this->web_template = $template;
$this->webTemplate = $template;
}
}