2022-05-31 17:12:14 +00:00
|
|
|
<?php
|
|
|
|
|
2023-03-19 21:22:34 +00:00
|
|
|
function output($code, $msg = '', $logs = [''], $data = []) {
|
2022-12-20 20:17:03 +00:00
|
|
|
http_response_code($code);
|
2023-02-07 21:25:16 +00:00
|
|
|
$shortCode = intval($code / 100);
|
2022-12-20 20:17:03 +00:00
|
|
|
if ($shortCode === 5)
|
2023-01-29 20:09:00 +00:00
|
|
|
error_log('Internal error: ' . strip_tags($msg) . implode(LF, $logs));
|
2022-09-15 17:17:48 +00:00
|
|
|
$final_message = match ($shortCode) {
|
2023-01-21 00:27:52 +00:00
|
|
|
2 => ($msg === '') ? '' : '<p><output>' . _('<strong>Success</strong>: ') . '<em>' . $msg . '</em></output></p>' . LF,
|
|
|
|
4 => '<p><output>' . _('<strong>User error</strong>: ') . '<em>' . $msg . '</em></output></p>' . LF,
|
|
|
|
5 => '<p><output>' . _('<strong>Server error</strong>: ') . '<em>' . $msg . '</em></output></p>' . LF,
|
2022-09-15 17:17:48 +00:00
|
|
|
};
|
2023-06-08 15:36:44 +00:00
|
|
|
if (is_callable('displayPage'))
|
|
|
|
displayPage(array_merge(['final_message' => $final_message], $data));
|
|
|
|
echo $final_message;
|
|
|
|
exit();
|
2022-05-31 17:12:14 +00:00
|
|
|
}
|
2022-06-11 21:42:48 +00:00
|
|
|
|
2023-06-19 00:15:43 +00:00
|
|
|
function exescape(array $args, array &$output = NULL, int &$result_code = NULL): int {
|
|
|
|
exec('2>&1 ' . implode(' ', array_map('escapeshellarg', $args)), $output, $result_code);
|
|
|
|
return $result_code;
|
|
|
|
}
|
|
|
|
|
2022-09-14 15:19:17 +00:00
|
|
|
function insert($table, $values) {
|
2022-12-10 17:19:37 +00:00
|
|
|
$query = 'INSERT INTO "' . $table . '"(';
|
2022-09-14 15:19:17 +00:00
|
|
|
|
|
|
|
foreach ($values as $key => $val) {
|
|
|
|
if ($key === array_key_last($values))
|
|
|
|
$query .= "$key";
|
|
|
|
else
|
|
|
|
$query .= "$key, ";
|
|
|
|
}
|
|
|
|
|
2022-11-20 14:11:54 +00:00
|
|
|
$query .= ') VALUES(';
|
2022-09-14 15:19:17 +00:00
|
|
|
foreach ($values as $key => $val) {
|
|
|
|
if ($key === array_key_last($values))
|
|
|
|
$query .= ":$key";
|
|
|
|
else
|
|
|
|
$query .= ":$key, ";
|
|
|
|
}
|
2022-11-20 14:11:54 +00:00
|
|
|
$query .= ')';
|
2022-09-14 15:19:17 +00:00
|
|
|
|
2022-12-13 16:38:54 +00:00
|
|
|
DB->prepare($query)
|
|
|
|
->execute($values);
|
2022-09-14 15:19:17 +00:00
|
|
|
}
|
|
|
|
|
2022-06-11 21:42:48 +00:00
|
|
|
function query($action, $table, $conditions = [], $column = NULL) {
|
|
|
|
|
|
|
|
$query = match ($action) {
|
|
|
|
'select' => 'SELECT *',
|
|
|
|
'delete' => 'DELETE',
|
|
|
|
};
|
|
|
|
|
2022-12-10 17:19:37 +00:00
|
|
|
$query .= ' FROM "' . $table . '"';
|
2022-06-11 21:42:48 +00:00
|
|
|
|
|
|
|
foreach ($conditions as $key => $val) {
|
|
|
|
if ($key === array_key_first($conditions))
|
|
|
|
$query .= " WHERE $key = :$key";
|
|
|
|
else
|
|
|
|
$query .= " AND $key = :$key";
|
|
|
|
}
|
|
|
|
|
2022-12-10 17:19:37 +00:00
|
|
|
$stmt = DB->prepare($query);
|
2022-12-13 16:38:54 +00:00
|
|
|
$stmt->execute($conditions);
|
2022-06-11 21:42:48 +00:00
|
|
|
|
2022-12-13 16:38:54 +00:00
|
|
|
return array_column($stmt->fetchAll(PDO::FETCH_ASSOC), $column);
|
2022-06-11 21:42:48 +00:00
|
|
|
}
|
2022-06-14 16:21:09 +00:00
|
|
|
|
|
|
|
function displayIndex() { ?>
|
2022-08-11 14:39:31 +00:00
|
|
|
<nav>
|
|
|
|
<dl>
|
2022-09-15 19:23:49 +00:00
|
|
|
<?php foreach (PAGES[SERVICE] as $pageId => $page) {
|
2022-06-14 16:21:09 +00:00
|
|
|
if ($pageId === 'index') continue;
|
|
|
|
?>
|
2022-09-15 19:23:49 +00:00
|
|
|
<dt><a href="<?= $pageId ?>"><?= $page['title'] ?></a></dt>
|
2022-08-11 14:39:31 +00:00
|
|
|
<dd>
|
2022-09-15 19:23:49 +00:00
|
|
|
<?= $page['description'] ?>
|
2022-08-11 14:39:31 +00:00
|
|
|
</dd>
|
|
|
|
<?php } ?>
|
|
|
|
</dl>
|
|
|
|
</nav>
|
2022-06-14 16:21:09 +00:00
|
|
|
<?php
|
|
|
|
}
|
2022-06-15 10:42:30 +00:00
|
|
|
|
|
|
|
function redirUrl($pageId) {
|
2022-09-12 23:09:40 +00:00
|
|
|
return CONF['common']['prefix'] . '/' . $pageId . '?redir=' . PAGE_URL;
|
2022-06-15 10:42:30 +00:00
|
|
|
}
|
2022-06-17 13:45:52 +00:00
|
|
|
|
2023-01-07 22:11:44 +00:00
|
|
|
function redir($redir_to = NULL) {
|
|
|
|
$redir_to ??= $_GET['redir'] ?? NULL;
|
|
|
|
|
|
|
|
if ($redir_to === NULL) {
|
2022-06-17 13:45:52 +00:00
|
|
|
header('Location: ' . CONF['common']['prefix'] . '/');
|
2023-01-07 22:11:44 +00:00
|
|
|
exit();
|
2022-06-17 13:45:52 +00:00
|
|
|
}
|
2023-01-07 22:11:44 +00:00
|
|
|
if (preg_match('/^[0-9a-z\/-]{0,128}$/D', $redir_to) !== 1)
|
|
|
|
output(403, 'Wrong character in <code>redir</code>.');
|
|
|
|
header('Location: ' . CONF['common']['prefix'] . '/' . $redir_to);
|
2022-09-15 17:17:48 +00:00
|
|
|
exit();
|
2022-06-17 13:45:52 +00:00
|
|
|
}
|
2022-06-21 22:37:06 +00:00
|
|
|
|
|
|
|
// PHP rmdir() only works on empty directories
|
|
|
|
function removeDirectory($dir) {
|
|
|
|
$dirObj = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
|
|
|
|
$files = new RecursiveIteratorIterator($dirObj, RecursiveIteratorIterator::CHILD_FIRST);
|
|
|
|
foreach ($files as $file)
|
|
|
|
$file->isDir() && !$file->isLink() ? rmdir($file->getPathname()) : unlink($file->getPathname());
|
|
|
|
if (rmdir($dir) !== true)
|
2022-09-15 17:17:48 +00:00
|
|
|
output(500, 'Unable to remove directory.');
|
2022-06-21 22:37:06 +00:00
|
|
|
}
|
2022-07-20 18:03:45 +00:00
|
|
|
|
2022-09-03 16:12:49 +00:00
|
|
|
function equalArrays($a, $b) {
|
|
|
|
return array_diff($a, $b) === [] AND array_diff($b, $a) === [];
|
|
|
|
}
|
|
|
|
|
2022-10-06 11:12:04 +00:00
|
|
|
/*
|
|
|
|
This token authenticates the user to the server through a public communication (the DNS).
|
|
|
|
It is therefore also designed to keep private:
|
|
|
|
- the user's id
|
|
|
|
- that a same user used a token multiple times (by using a unique salt for each token)
|
|
|
|
*/
|
2022-12-20 23:14:55 +00:00
|
|
|
if (time() - query('select', 'params', ['name' => 'secret_key_last_change'], 'value')[0] >= 86400 * 20) {
|
|
|
|
DB->prepare("UPDATE params SET value = :secret_key WHERE name = 'secret_key';")
|
|
|
|
->execute([':secret_key' => bin2hex(random_bytes(32))]);
|
|
|
|
DB->prepare("UPDATE params SET value = :last_change WHERE name = 'secret_key_last_change';")
|
|
|
|
->execute([':last_change' => time()]);
|
2022-10-06 11:12:04 +00:00
|
|
|
}
|
2022-12-20 23:14:55 +00:00
|
|
|
define('SECRET_KEY', hex2bin(query('select', 'params', ['name' => 'secret_key'], 'value')[0]));
|
2022-10-06 11:12:04 +00:00
|
|
|
function getAuthToken() {
|
|
|
|
$salt = bin2hex(random_bytes(4));
|
2022-11-30 22:12:42 +00:00
|
|
|
$hash = hash_hmac('sha256', $salt . ($_SESSION['id'] ?? ''), SECRET_KEY);
|
2022-10-06 11:12:04 +00:00
|
|
|
return $salt . '-' . substr($hash, 0, 32);
|
|
|
|
}
|
|
|
|
function checkAuthToken($salt, $hash) {
|
2022-11-30 22:12:42 +00:00
|
|
|
$correctProof = substr(hash_hmac('sha256', $salt . $_SESSION['id'], SECRET_KEY), 0, 32);
|
2022-10-06 11:12:04 +00:00
|
|
|
if (hash_equals($correctProof, $hash) !== true)
|
2023-01-21 00:27:52 +00:00
|
|
|
output(403, _('Wrong proof.'));
|
2022-10-06 11:12:04 +00:00
|
|
|
}
|