huesos/mirzaev/arming_bot/system/controllers/session.php

190 lines
4.9 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace mirzaev\arming_bot\controllers;
// Files of the project
use mirzaev\arming_bot\controllers\core,
mirzaev\arming_bot\models\session as model,
mirzaev\arming_bot\models\account;
// Framework for ArangoDB
use mirzaev\arangodb\document;
/**
* Controller of session
*
* @package mirzaev\arming_bot\controllers
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class session extends core
{
/**
* Registry of errors
*/
protected array $errors = [
'session' => [],
'account' => []
];
/**
* Connect session to the telegram account
*
* @param array $parameters Parameters of the request (POST + GET)
*/
public function telegram(array $parameters = []): ?string
{
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// POST request
// Declaring variables in the correct scope
$identifier = $domain = $language = null;
if ($connected = isset($this->account)) {
// Found the account
// Initializing identifier of the account
$identifier = $this->account->identifier;
// Initializing language of the account
$language = $this->account->language;
// Initializing domain of the account
$domain = $this->account->domain;
} else {
// Not found the account
if (count($parameters) > 1 && isset($parameters['hash'])) {
$buffer = $parameters;
unset($buffer['hash']);
ksort($buffer);
$prepared = [];
foreach ($buffer as $key => $value) {
if (is_array($value)) {
$prepared[] = $key . '=' . json_encode($value, JSON_UNESCAPED_UNICODE);
} else {
$prepared[] = $key . '=' . $value;
}
}
$key = hash_hmac('sha256', require(SETTINGS . DIRECTORY_SEPARATOR . 'key.php'), 'WebAppData', true);
$hash = bin2hex(hash_hmac('sha256', implode(PHP_EOL, $prepared), $key, true));
if (hash_equals($hash, $parameters['hash'])) {
// Data confirmed (according to telegram documentation)
if (time() - $parameters['auth_date'] < 86400) {
// Authorization date less than 1 day ago
// Initializing data of the account
$data = json_decode($parameters['user']);
// Initializing of the account
$account = account::initialize(
$data->id,
[
'identifier' => $data->id,
'name' => [
'first' => $data->first_name,
'last' => $data->last_name
],
'domain' => $data->username,
'language' => $data->language_code,
'messages' => $data->allows_write_to_pm
],
$this->errors['account']
);
if ($account instanceof account) {
// Initialized the account
// Connecting the account to the session
$connected = $this->session->connect($account, $this->errors['session']);
// Initializing identifier of the account
$identifier = $account->identifier;
// Initializing language of the account
$language = $account->language;
// Initializing domain of the account
$domain = $account->domain;
}
}
}
}
}
// Initializing a response headers
header('Content-Type: application/json');
header('Content-Encoding: none');
header('X-Accel-Buffering: no');
// Initializing of the output buffer
ob_start();
// Generating the reponse
echo json_encode(
[
'connected' => (bool) $connected,
'identifier' => $identifier ?? null,
'domain' => $domain ?? null,
'language' => $language?->name ?? null,
'errors' => $this->errors
]
);
// Initializing a response headers
header('Content-Length: ' . ob_get_length());
// Sending and deinitializing of the output buffer
ob_end_flush();
flush();
// Exit (success)
return null;
}
// Exit (fail)
return null;
}
/**
* Write to the buffer
*
* @param array $parameters Parameters of the request (POST + GET)
*
* @return void
*
* @todo переделать под trait buffer
*/
public function write(array $parameters = []): void
{
if (!empty($parameters) && $this->session instanceof model) {
// Found data of the program and active session
foreach ($parameters as $name => $value) {
// Iterate over parameters
// Validation of the parameter
if (mb_strlen($value) > 4096) continue;
// Convert name to multidimensional array
foreach (array_reverse(explode('_', $name)) as $key) $parameter = [$key => $parameter ?? json_validate($value) ? json_decode($value, true, 10) : $value];
// Write data of to the buffer parameter in the implement object of session document from ArangoDB
$this->session->buffer = $parameter + ($this->session->buffer ?? []);
}
// Write from implement object to session document from ArangoDB
document::update($this->session->__document(), $this->errors['session']);
}
}
}