начало работы над сессиями и там дохуя чего ещё
This commit is contained in:
parent
ed5756d065
commit
b2a78519e4
107
composer.json
107
composer.json
|
@ -1,57 +1,56 @@
|
||||||
{
|
{
|
||||||
"name": "mirzaev/site-account",
|
"name": "mirzaev/site-account",
|
||||||
"description": "API for intersite authentication",
|
"description": "API for intersite authentication",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"site",
|
"site",
|
||||||
"api",
|
"api",
|
||||||
"authentication",
|
"authentication"
|
||||||
"auth"
|
],
|
||||||
],
|
"type": "site",
|
||||||
"type": "site",
|
"homepage": "https://git.mirzaev.sexy/mirzaev/site-account",
|
||||||
"homepage": "https://git.mirzaev.sexy/mirzaev/site-account",
|
"license": "WTFPL",
|
||||||
"license": "WTFPL",
|
"authors": [
|
||||||
"authors": [
|
{
|
||||||
{
|
"name": "Arsen Mirzaev Tatyano-Muradovich",
|
||||||
"name": "Arsen Mirzaev Tatyano-Muradovich",
|
"email": "arsen@mirzaev.sexy",
|
||||||
"email": "arsen@mirzaev.sexy",
|
"homepage": "https://mirzaev.sexy",
|
||||||
"homepage": "https://mirzaev.sexy",
|
"role": "Programmer"
|
||||||
"role": "Programmer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"email": "arsen@mirzaev.sexy",
|
|
||||||
"wiki": "https://git.mirzaev.sexy/mirzaev/site-account/wiki",
|
|
||||||
"issues": "https://git.mirzaev.sexy/mirzaev/site-account/issues"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "funding",
|
|
||||||
"url": "https://fund.mirzaev.sexy"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"require": {
|
|
||||||
"php": "~8.1",
|
|
||||||
"ext-sodium": "~8.1",
|
|
||||||
"mirzaev/minimal": "^2.0.x-dev",
|
|
||||||
"mirzaev/accounts": "~1.2.x-dev",
|
|
||||||
"mirzaev/arangodb": "^1.0.0",
|
|
||||||
"mirzaev/vk": "^5.0",
|
|
||||||
"triagens/arangodb": "~3.9.x-dev",
|
|
||||||
"twig/twig": "^3.4",
|
|
||||||
"guzzlehttp/guzzle": "^7.5"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "~9.5"
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"mirzaev\\site\\account\\": "mirzaev/site/account/system"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload-dev": {
|
|
||||||
"psr-4": {
|
|
||||||
"mirzaev\\site\\account\\tests\\": "mirzaev/site/account/tests"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"email": "arsen@mirzaev.sexy",
|
||||||
|
"wiki": "https://git.mirzaev.sexy/mirzaev/site-account/wiki",
|
||||||
|
"issues": "https://git.mirzaev.sexy/mirzaev/site-account/issues"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "funding",
|
||||||
|
"url": "https://fund.mirzaev.sexy"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": "~8.2",
|
||||||
|
"ext-sodium": "~8.2",
|
||||||
|
"mirzaev/minimal": "^2.0.x-dev",
|
||||||
|
"mirzaev/accounts": "~1.2.x-dev",
|
||||||
|
"mirzaev/arangodb": "^1.0.0",
|
||||||
|
"mirzaev/vk": "^5.0",
|
||||||
|
"triagens/arangodb": "~3.9.x-dev",
|
||||||
|
"twig/twig": "^3.4",
|
||||||
|
"guzzlehttp/guzzle": "^7.5"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~9.5"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"mirzaev\\site\\account\\": "mirzaev/site/account/system"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"mirzaev\\site\\account\\tests\\": "mirzaev/site/account/tests"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ class core extends controller
|
||||||
$expires = time() + 604800;
|
$expires = time() + 604800;
|
||||||
|
|
||||||
// Инициализация сессии (без журналирования)
|
// Инициализация сессии (без журналирования)
|
||||||
$this->variables['session'] = session::initialization($_COOKIE["session"] ?? null, $expires) ?? header('Location: https://mirzaev.sexy/error?code=500&text=Не+удалось+инициализировать+сессию');
|
$this->variables['session'] = new session($_COOKIE["session"] ?? null, $expires) ?? header('Location: https://mirzaev.sexy/error?code=500&text=Не+удалось+инициализировать+сессию');
|
||||||
|
|
||||||
if ($_COOKIE["session"] ?? null !== $this->variables['session']->hash) {
|
if ($_COOKIE["session"] ?? null !== $this->variables['session']->hash) {
|
||||||
// Изменился хеш сессии (подразумевается, что сессия устарела)
|
// Изменился хеш сессии (подразумевается, что сессия устарела)
|
||||||
|
@ -78,7 +78,7 @@ class core extends controller
|
||||||
}
|
}
|
||||||
|
|
||||||
// Инициализация аккаунта (без журналирования)
|
// Инициализация аккаунта (без журналирования)
|
||||||
$this->variables['account'] = session::account($this->variables['session']);
|
$this->variables['account'] = $this->variables['session']->account();
|
||||||
|
|
||||||
if ($this->variables['account'] instanceof _document) {
|
if ($this->variables['account'] instanceof _document) {
|
||||||
// Инициализирован аккаунт
|
// Инициализирован аккаунт
|
||||||
|
|
|
@ -15,71 +15,66 @@ use mirzaev\site\account\controllers\core;
|
||||||
*/
|
*/
|
||||||
final class index_controller extends core
|
final class index_controller extends core
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Главная страница
|
* Главная страница
|
||||||
*
|
*
|
||||||
* @param array $parameters Параметры запроса
|
* @param array $parameters Параметры запроса
|
||||||
*/
|
*/
|
||||||
public function index(array $parameters = []): ?string
|
public function index(array $parameters = []): ?string
|
||||||
{
|
{
|
||||||
// Инициализация загружаемых категорий
|
// Инициализация загружаемых категорий
|
||||||
$this->variables['include'] = [
|
$this->variables['include'] = [
|
||||||
'head' => ['self'],
|
'head' => ['self'],
|
||||||
'body' => ['self']
|
'body' => ['self']
|
||||||
];
|
];
|
||||||
|
|
||||||
// Инициализация бегущей строки
|
// Инициализация бегущей строки
|
||||||
$this->variables['hotline'] = [
|
$this->variables['hotline'] = [
|
||||||
'id' => $this->variables['request']['id'] ?? 'hotline'
|
'id' => $this->variables['request']['id'] ?? 'hotline'
|
||||||
];
|
];
|
||||||
|
|
||||||
// Инициализация параметров бегущей строки
|
// Инициализация параметров бегущей строки
|
||||||
$this->variables['hotline']['parameters'] = [
|
$this->variables['hotline']['parameters'] = [
|
||||||
// 'step' => 2
|
// 'step' => 2
|
||||||
];
|
];
|
||||||
|
|
||||||
// Инициализация аттрибутов бегущей строки
|
// Инициализация аттрибутов бегущей строки
|
||||||
$this->variables['hotline']['attributes'] = [
|
$this->variables['hotline']['attributes'] = [];
|
||||||
|
|
||||||
];
|
// Инициализация элементов бегущей строки
|
||||||
|
$this->variables['hotline']['elements'] = [
|
||||||
|
['content' => '1'],
|
||||||
|
[
|
||||||
|
'tag' => 'article',
|
||||||
|
'content' => '2'
|
||||||
|
],
|
||||||
|
['content' => '3'],
|
||||||
|
['content' => '4'],
|
||||||
|
['content' => '5'],
|
||||||
|
['content' => '6'],
|
||||||
|
['content' => '7'],
|
||||||
|
['content' => '8'],
|
||||||
|
['content' => '9'],
|
||||||
|
['content' => '10'],
|
||||||
|
['content' => '11'],
|
||||||
|
['content' => '12'],
|
||||||
|
['content' => '13'],
|
||||||
|
['content' => '14'],
|
||||||
|
['content' => '15']
|
||||||
|
];
|
||||||
|
|
||||||
// Инициализация элементов бегущей строки
|
// Инициализация бегущей строки
|
||||||
$this->variables['hotline']['elements'] = [
|
$this->variables['graph'] = [
|
||||||
['content' => '1'],
|
'id' => $this->variables['request']['id'] ?? 'graph'
|
||||||
[
|
];
|
||||||
'tag' => 'article',
|
|
||||||
'content' => '2'
|
|
||||||
],
|
|
||||||
['content' => '3'],
|
|
||||||
['content' => '4'],
|
|
||||||
['content' => '5'],
|
|
||||||
['content' => '6'],
|
|
||||||
['content' => '7'],
|
|
||||||
['content' => '8'],
|
|
||||||
['content' => '9'],
|
|
||||||
['content' => '10'],
|
|
||||||
['content' => '11'],
|
|
||||||
['content' => '12'],
|
|
||||||
['content' => '13'],
|
|
||||||
['content' => '14'],
|
|
||||||
['content' => '15']
|
|
||||||
];
|
|
||||||
|
|
||||||
// Инициализация бегущей строки
|
// Инициализация аттрибутов бегущей строки
|
||||||
$this->variables['graph'] = [
|
$this->variables['graph']['attributes'] = [];
|
||||||
'id' => $this->variables['request']['id'] ?? 'graph'
|
|
||||||
];
|
|
||||||
|
|
||||||
// Инициализация аттрибутов бегущей строки
|
// Инициализация элементов бегущей строки
|
||||||
$this->variables['graph']['attributes'] = [
|
$this->variables['graph']['elements'] = [];
|
||||||
|
|
||||||
];
|
// Генерация представления
|
||||||
|
return $this->view->render(DIRECTORY_SEPARATOR . 'index.html', $this->variables);
|
||||||
// Инициализация элементов бегущей строки
|
}
|
||||||
$this->variables['graph']['elements'] = [
|
|
||||||
];
|
|
||||||
|
|
||||||
// Генерация представления
|
|
||||||
return $this->view->render(DIRECTORY_SEPARATOR . 'index.html', $this->variables);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use mirzaev\site\account\models\account_model as account;
|
||||||
|
|
||||||
// Фреймворк ArangoDB
|
// Фреймворк ArangoDB
|
||||||
use mirzaev\arangodb\collection,
|
use mirzaev\arangodb\collection,
|
||||||
mirzaev\arangodb\document;
|
mirzaev\arangodb\document;
|
||||||
|
|
||||||
// Библиотека для ArangoDB
|
// Библиотека для ArangoDB
|
||||||
use ArangoDBClient\Document as _document;
|
use ArangoDBClient\Document as _document;
|
||||||
|
@ -25,189 +25,225 @@ use exception;
|
||||||
*/
|
*/
|
||||||
final class session_model extends core
|
final class session_model extends core
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Коллекция
|
* Коллекция
|
||||||
*/
|
*/
|
||||||
public const COLLECTION = 'session';
|
public const COLLECTION = 'session';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Инициализация
|
* Данные сессии из базы данных
|
||||||
*
|
*/
|
||||||
* @param ?string $hash Хеш сессии в базе данных
|
public _document $document;
|
||||||
* @param ?int $expires Дата окончания работы сессии (используется при создании новой сессии)
|
|
||||||
* @param array &$errors Журнал ошибок
|
|
||||||
*
|
|
||||||
* @return ?_document Инстанция сессии, если удалось найти или создать
|
|
||||||
*/
|
|
||||||
public static function initialization(?string $hash = null, ?int $expires = null, array &$errors = []): ?_document
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (collection::init(static::$db->session, self::COLLECTION)) {
|
|
||||||
// Инициализирована коллекция
|
|
||||||
|
|
||||||
if (isset($hash) && $session = collection::search(static::$db->session, sprintf(
|
/**
|
||||||
<<<AQL
|
* Конструктор
|
||||||
FOR d IN %s
|
*
|
||||||
FILTER d.hash == '$hash' && d.expires > %d
|
* Инициализация сессии и запись в свойство $this->document
|
||||||
RETURN d
|
*
|
||||||
AQL,
|
* @param ?string $hash Хеш сессии в базе данных
|
||||||
self::COLLECTION,
|
* @param ?int $expires Дата окончания работы сессии (используется при создании новой сессии)
|
||||||
time()
|
* @param array &$errors Журнал ошибок
|
||||||
))) {
|
*
|
||||||
// Найдена сессия по хешу
|
* @return static Инстанция сессии
|
||||||
|
*/
|
||||||
|
public function __construct(?string $hash = null, ?int $expires = null, array &$errors = [])
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (collection::init(static::$db->session, self::COLLECTION)) {
|
||||||
|
// Инициализирована коллекция
|
||||||
|
|
||||||
// Возврат сессии
|
if (isset($hash) && $session = collection::search(static::$db->session, sprintf(
|
||||||
return $session;
|
<<<AQL
|
||||||
} else if ($session = collection::search(static::$db->session, sprintf(
|
FOR d IN %s
|
||||||
<<<AQL
|
FILTER d.hash == '$hash' && d.expires > %d
|
||||||
FOR d IN %s
|
RETURN d
|
||||||
FILTER d.ip == '%s' && d.expires > %d
|
AQL,
|
||||||
RETURN d
|
self::COLLECTION,
|
||||||
AQL,
|
time()
|
||||||
self::COLLECTION,
|
))) {
|
||||||
$_SERVER['REMOTE_ADDR'],
|
// Найдена сессия по хешу
|
||||||
time()
|
|
||||||
))) {
|
|
||||||
// Найдена сессия по данным пользователя
|
|
||||||
|
|
||||||
// Возврат сессии
|
// Запись в свойство
|
||||||
return $session;
|
$this->document = $session;
|
||||||
} else {
|
} else if ($session = collection::search(static::$db->session, sprintf(
|
||||||
// Не найдена сессия
|
<<<AQL
|
||||||
|
FOR d IN %s
|
||||||
|
FILTER d.ip == '%s' && d.expires > %d
|
||||||
|
RETURN d
|
||||||
|
AQL,
|
||||||
|
self::COLLECTION,
|
||||||
|
$_SERVER['REMOTE_ADDR'],
|
||||||
|
time()
|
||||||
|
))) {
|
||||||
|
// Найдена сессия по данным пользователя
|
||||||
|
|
||||||
// Запись сессии в базу данных
|
// Запись в свойство
|
||||||
$_id = document::write(static::$db->session, self::COLLECTION, [
|
$this->document = $session;
|
||||||
'ip' => $_SERVER['REMOTE_ADDR'],
|
} else {
|
||||||
'expires' => $expires ?? time() + 604800
|
// Не найдена сессия
|
||||||
]);
|
|
||||||
|
|
||||||
if ($session = collection::search(static::$db->session, sprintf(
|
// Запись сессии в базу данных
|
||||||
<<<AQL
|
$_id = document::write(static::$db->session, self::COLLECTION, [
|
||||||
FOR d IN %s
|
'ip' => $_SERVER['REMOTE_ADDR'],
|
||||||
FILTER d._id == '$_id' && d.expires > %d
|
'expires' => $expires ?? time() + 604800
|
||||||
RETURN d
|
]);
|
||||||
AQL,
|
|
||||||
self::COLLECTION,
|
|
||||||
time()
|
|
||||||
))) {
|
|
||||||
// Найдена созданная сессия
|
|
||||||
|
|
||||||
// Запись хеша
|
if ($session = collection::search(static::$db->session, sprintf(
|
||||||
$session->hash = sodium_bin2hex(sodium_crypto_generichash($_id));
|
<<<AQL
|
||||||
|
FOR d IN %s
|
||||||
|
FILTER d._id == '$_id' && d.expires > %d
|
||||||
|
RETURN d
|
||||||
|
AQL,
|
||||||
|
self::COLLECTION,
|
||||||
|
time()
|
||||||
|
))) {
|
||||||
|
// Найдена созданная сессия
|
||||||
|
|
||||||
if (document::update(static::$db->session, $session)) {
|
// Запись хеша
|
||||||
// Записано обновление
|
$session->hash = sodium_bin2hex(sodium_crypto_generichash($_id));
|
||||||
|
|
||||||
return $session;
|
if (document::update(static::$db->session, $session)) {
|
||||||
} else throw new exception('Не удалось записать данные сессии');
|
// Записано обновление
|
||||||
} else throw new exception('Не удалось создать или найти созданную сессию');
|
|
||||||
}
|
// Запись в свойство
|
||||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
$this->document = $session;
|
||||||
} catch (exception $e) {
|
} else throw new exception('Не удалось записать данные сессии');
|
||||||
// Запись в журнал ошибок
|
} else throw new exception('Не удалось создать или найти созданную сессию');
|
||||||
$errors[] = [
|
|
||||||
'text' => $e->getMessage(),
|
|
||||||
'file' => $e->getFile(),
|
|
||||||
'line' => $e->getLine(),
|
|
||||||
'stack' => $e->getTrace()
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||||
|
} catch (exception $e) {
|
||||||
|
// Запись в журнал ошибок
|
||||||
|
$errors[] = [
|
||||||
|
'text' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'stack' => $e->getTrace()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
/**
|
||||||
|
* Связь сессии с аккаунтом
|
||||||
|
*
|
||||||
|
* @param _document $account Инстанция аккаунта
|
||||||
|
* @param array &$errors Журнал ошибок
|
||||||
|
*
|
||||||
|
* @return bool Статус выполнения
|
||||||
|
*/
|
||||||
|
public function connect(_document $account, array &$errors = []): bool
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
collection::init(static::$db->session, self::COLLECTION)
|
||||||
|
&& collection::init(static::$db->session, account::COLLECTION)
|
||||||
|
&& collection::init(static::$db->session, self::COLLECTION . '_edge_' . account::COLLECTION, true)
|
||||||
|
) {
|
||||||
|
// Инициализирована коллекция
|
||||||
|
|
||||||
|
if (document::write(static::$db->session, self::COLLECTION . '_edge_' . account::COLLECTION, [
|
||||||
|
'_from' => $this->document->getId(),
|
||||||
|
'_to' => $account->getId()
|
||||||
|
])) {
|
||||||
|
// Создано ребро: session -> account
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else throw new exception('Не удалось создать ребро: session -> account');
|
||||||
|
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||||
|
} catch (exception $e) {
|
||||||
|
// Запись в журнал ошибок
|
||||||
|
$errors[] = [
|
||||||
|
'text' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'stack' => $e->getTrace()
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return false;
|
||||||
* Связь сессии с аккаунтом
|
}
|
||||||
*
|
|
||||||
* @param _document $session Инстанция сессии
|
|
||||||
* @param _document $account Инстанция аккаунта
|
|
||||||
* @param array &$errors Журнал ошибок
|
|
||||||
*
|
|
||||||
* @return bool Статус выполнения
|
|
||||||
*/
|
|
||||||
public static function connect(_document $session, _document $account, array &$errors = []): bool
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (
|
|
||||||
collection::init(static::$db->session, self::COLLECTION)
|
|
||||||
&& collection::init(static::$db->session, account::COLLECTION)
|
|
||||||
&& collection::init(static::$db->session, self::COLLECTION . '_edge_' . account::COLLECTION, true)
|
|
||||||
) {
|
|
||||||
// Инициализирована коллекция
|
|
||||||
|
|
||||||
if (document::write(static::$db->session, self::COLLECTION . '_edge_' . account::COLLECTION, [
|
/**
|
||||||
'_from' => $session->getId(),
|
* Поиск связанного аккаунта
|
||||||
'_to' => $account->getId()
|
*
|
||||||
])) {
|
* @param array &$errors Журнал ошибок
|
||||||
// Создано ребро: session -> account
|
*
|
||||||
|
* @return ?_document Инстанция аккаунта, если удалось найти
|
||||||
|
*/
|
||||||
|
public function account(array &$errors = []): ?_document
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
collection::init(static::$db->session, self::COLLECTION)
|
||||||
|
&& collection::init(static::$db->session, account::COLLECTION)
|
||||||
|
&& collection::init(static::$db->session, self::COLLECTION . '_edge_' . account::COLLECTION, true)
|
||||||
|
) {
|
||||||
|
// Инициализированы коллекции
|
||||||
|
|
||||||
return true;
|
if ($account = collection::search(static::$db->session, sprintf(
|
||||||
} else throw new exception('Не удалось создать ребро: session -> account');
|
<<<AQL
|
||||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
FOR document IN %s
|
||||||
} catch (exception $e) {
|
LET edge = (
|
||||||
// Запись в журнал ошибок
|
FOR edge IN %s
|
||||||
$errors[] = [
|
FILTER edge._from == '%s'
|
||||||
'text' => $e->getMessage(),
|
SORT edge._key DESC
|
||||||
'file' => $e->getFile(),
|
LIMIT 1
|
||||||
'line' => $e->getLine(),
|
RETURN edge
|
||||||
'stack' => $e->getTrace()
|
)
|
||||||
];
|
FILTER document._id == edge[0]._to
|
||||||
}
|
LIMIT 1
|
||||||
|
RETURN document
|
||||||
|
AQL,
|
||||||
|
account::COLLECTION,
|
||||||
|
self::COLLECTION . '_edge_' . account::COLLECTION,
|
||||||
|
$this->document->getId()
|
||||||
|
))) {
|
||||||
|
// Найден аккаунт
|
||||||
|
|
||||||
return false;
|
return $account;
|
||||||
|
} else throw new exception('Не удалось найти аккаунт');
|
||||||
|
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||||
|
} catch (exception $e) {
|
||||||
|
// Запись в журнал ошибок
|
||||||
|
$errors[] = [
|
||||||
|
'text' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'stack' => $e->getTrace()
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return null;
|
||||||
* Поиск связанного аккаунта
|
}
|
||||||
*
|
|
||||||
* @param _document $session Инстанция сессии
|
|
||||||
* @param array &$errors Журнал ошибок
|
|
||||||
*
|
|
||||||
* @return ?_document Инстанция аккаунта, если удалось найти
|
|
||||||
*/
|
|
||||||
public static function account(_document $session, array &$errors = []): ?_document
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (
|
|
||||||
collection::init(static::$db->session, self::COLLECTION)
|
|
||||||
&& collection::init(static::$db->session, account::COLLECTION)
|
|
||||||
&& collection::init(static::$db->session, self::COLLECTION . '_edge_' . account::COLLECTION, true)
|
|
||||||
) {
|
|
||||||
// Инициализированы коллекции
|
|
||||||
|
|
||||||
if ($account = collection::search(static::$db->session, sprintf(
|
/**
|
||||||
<<<AQL
|
* Записать
|
||||||
FOR document IN %s
|
*
|
||||||
LET edge = (
|
* Ищет свойство, если не находит, то ищет его в инстанции документа сессии из базы данных,
|
||||||
FOR edge IN %s
|
* затем записывает в него переданные данные. Инициализация новых свойств происходит в инстанции
|
||||||
FILTER edge._from == '%s'
|
* документа сессии из базы данных
|
||||||
SORT edge._key DESC
|
*
|
||||||
LIMIT 1
|
* @param string $name Название
|
||||||
RETURN edge
|
* @param mixed $value Содержимое
|
||||||
)
|
*
|
||||||
FILTER document._id == edge[0]._to
|
* @return void
|
||||||
LIMIT 1
|
*/
|
||||||
RETURN document
|
public function __set(string $name, mixed $value = null): void
|
||||||
AQL,
|
{
|
||||||
account::COLLECTION,
|
if (isset($this->{$name})) $this->{$name} = $value;
|
||||||
self::COLLECTION . '_edge_' . account::COLLECTION,
|
else $this->document->{$name} = $value;
|
||||||
$session->getId()
|
}
|
||||||
))) {
|
|
||||||
// Найден аккаунт
|
|
||||||
|
|
||||||
return $account;
|
/**
|
||||||
} else throw new exception('Не удалось найти аккаунт');
|
* Прочитать
|
||||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
*
|
||||||
} catch (exception $e) {
|
* Ищет свойство, если не находит, то ищет его в инстанции документа сессии из базы данных
|
||||||
// Запись в журнал ошибок
|
*
|
||||||
$errors[] = [
|
* @param string $name Название
|
||||||
'text' => $e->getMessage(),
|
*
|
||||||
'file' => $e->getFile(),
|
* @return mixed Данные свойства инстанции сессии или инстанции документа сессии из базы данных
|
||||||
'line' => $e->getLine(),
|
*/
|
||||||
'stack' => $e->getTrace()
|
public function __get(string $name): mixed
|
||||||
];
|
{
|
||||||
}
|
return $this->{$name} ?? $this->document->{$name};
|
||||||
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import url('/fonts/comissioner.ttf');
|
@import url('/fonts/commissioner.ttf');
|
||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
@media (prefers-color-scheme: light) {
|
||||||
:root {
|
:root {
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
{% block css %}
|
|
||||||
<link type="text/css" rel="stylesheet" href="/css/account.css">
|
|
||||||
<link type="text/css" rel="stylesheet" href="/css/gradient.css">
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block body %}
|
|
||||||
<section id="authentication">
|
|
||||||
{% if account %}
|
|
||||||
{{ account.getKey() }}
|
|
||||||
{% if vk %}
|
|
||||||
{{ vk.mail }}
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
<section class="header gradient unselectable">
|
|
||||||
<div class="glare"></div>
|
|
||||||
<img class="avatar unselectable" src="/images/what.png" alt="Пользователь" draggable="false">
|
|
||||||
<a href="https://mirzaev.sexy">Нейрожурнал Мирзаева</a>
|
|
||||||
<div class="red"></div>
|
|
||||||
<div class="green"></div>
|
|
||||||
<div class="blue"></div>
|
|
||||||
<img class="cover unselectable" src="/images/heh.gif" alt="Нейрожурнал Мирзаева" draggable="false"></img>
|
|
||||||
</section>
|
|
||||||
<section class="body">
|
|
||||||
<ul>
|
|
||||||
<li>Подпункт 2.1.</li>
|
|
||||||
<li>Подпункт 2.2.
|
|
||||||
<ul>
|
|
||||||
<li>Подпункт 2.2.1.</li>
|
|
||||||
<li>Подпункт 2.2.2.</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>Подпункт 2.3.</li>
|
|
||||||
</ul>
|
|
||||||
<div class="buttons">
|
|
||||||
<button class="accept">Разрешить</button>
|
|
||||||
<button>Запретить</button>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{% endif %}
|
|
||||||
<svg width="0" height="0">
|
|
||||||
<defs>
|
|
||||||
<clipPath id="authentication-header-mask">
|
|
||||||
<path
|
|
||||||
d="M50,160 L50,130 C22,130 0,107.612 0,80 C0,52 22,30 50,30 L50,3 C50,1.3 51.3,0 53,0 L447,0 C448,0 450,1.5 450,3 L450,160 L50,160 Z" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</section>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block js %}
|
|
||||||
<script type="text/javascript" src="/js/account.js"></script>
|
|
||||||
{% endblock %}
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "core.html" %}
|
{% extends "core.html" %}
|
||||||
|
|
||||||
{% use 'account/element.html' with css as account_css, body as account_body, js as account_js %}
|
{% use 'nodes/account.html' with css as account_css, body as account_body, js as account_js %}
|
||||||
{% use "core.html" with css as core_css, body as core_body, js as core_js, js_init as core_js_init %}
|
{% use "core.html" with css as core_css, body as core_body, js as core_js, js_init as core_js_init %}
|
||||||
{% use "header.html" with css as header_css, body as header_body, js as header_js, js_init as header_js_init %}
|
{% use "header.html" with css as header_css, body as header_body, js as header_js, js_init as header_js_init %}
|
||||||
{% use "aside.html" with css as aside_css, body as aside_body, js as aside_js, js_init as aside_js_init %}
|
{% use "aside.html" with css as aside_css, body as aside_body, js as aside_js, js_init as aside_js_init %}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
{% block css %}
|
||||||
|
<link type="text/css" rel="stylesheet" href="/css/account.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="/css/gradient.css">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<section id="authentication">
|
||||||
|
{% if account %}
|
||||||
|
{{ account.getKey() }}
|
||||||
|
{% if vk %}
|
||||||
|
{{ vk.mail }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<section class="header gradient unselectable">
|
||||||
|
<div class="glare"></div>
|
||||||
|
<img class="avatar unselectable" src="/images/what.png" alt="Пользователь" draggable="false">
|
||||||
|
<a href="https://mirzaev.sexy">{{ name ?? session.ip ?? session.hash ?? 'Ты кто?'}}</a>
|
||||||
|
<div class="red"></div>
|
||||||
|
<div class="green"></div>
|
||||||
|
<div class="blue"></div>
|
||||||
|
<img class="cover unselectable" src="/images/heh.gif" alt="Нейрожурнал Мирзаева" draggable="false"></img>
|
||||||
|
</section>
|
||||||
|
<section class="body">
|
||||||
|
<ul>
|
||||||
|
<li>Подпункт 2.1.</li>
|
||||||
|
<li>Подпункт 2.2.
|
||||||
|
<ul>
|
||||||
|
<li>Подпункт 2.2.1.</li>
|
||||||
|
<li>Подпункт 2.2.2.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>Подпункт 2.3.</li>
|
||||||
|
</ul>
|
||||||
|
<div class="buttons">
|
||||||
|
<button class="accept">Разрешить</button>
|
||||||
|
<button>Запретить</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
<svg width="0" height="0">
|
||||||
|
<defs>
|
||||||
|
<clipPath id="authentication-header-mask">
|
||||||
|
<path
|
||||||
|
d="M50,160 L50,130 C22,130 0,107.612 0,80 C0,52 22,30 50,30 L50,3 C50,1.3 51.3,0 53,0 L447,0 C448,0 450,1.5 450,3 L450,160 L50,160 Z" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
<script type="text/javascript" src="/js/account.js"></script>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,53 @@
|
||||||
|
{% block css %}
|
||||||
|
<link type="text/css" rel="stylesheet" href="/css/account.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="/css/gradient.css">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<section id="authentication">
|
||||||
|
{% if account %}
|
||||||
|
{{ account.getKey() }}
|
||||||
|
{% if vk %}
|
||||||
|
{{ vk.mail }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<section class="header gradient unselectable">
|
||||||
|
<div class="glare"></div>
|
||||||
|
<img class="avatar unselectable" src="/images/what.png" alt="Пользователь" draggable="false">
|
||||||
|
<a href="https://mirzaev.sexy">Нейрожурнал Мирзаева</a>
|
||||||
|
<div class="red"></div>
|
||||||
|
<div class="green"></div>
|
||||||
|
<div class="blue"></div>
|
||||||
|
<img class="cover unselectable" src="/images/heh.gif" alt="Нейрожурнал Мирзаева" draggable="false"></img>
|
||||||
|
</section>
|
||||||
|
<section class="body">
|
||||||
|
<ul>
|
||||||
|
<li>Подпункт 2.1.</li>
|
||||||
|
<li>Подпункт 2.2.
|
||||||
|
<ul>
|
||||||
|
<li>Подпункт 2.2.1.</li>
|
||||||
|
<li>Подпункт 2.2.2.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>Подпункт 2.3.</li>
|
||||||
|
</ul>
|
||||||
|
<div class="buttons">
|
||||||
|
<button class="accept">Разрешить</button>
|
||||||
|
<button>Запретить</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
<svg width="0" height="0">
|
||||||
|
<defs>
|
||||||
|
<clipPath id="authentication-header-mask">
|
||||||
|
<path
|
||||||
|
d="M50,160 L50,130 C22,130 0,107.612 0,80 C0,52 22,30 50,30 L50,3 C50,1.3 51.3,0 53,0 L447,0 C448,0 450,1.5 450,3 L450,160 L50,160 Z" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
<script type="text/javascript" src="/js/account.js"></script>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue