($msg === '') ? '' : '
' . LF, 4 => '' . LF, 5 => '' . LF, }; http_response_code($code); if ($shortCode === 5) error_log('Niver internal error: ' . strip_tags($msg) . implode(LF, $logs)); if ($code !== 200) executePage(); } function processForm($requireLogin = true) { if (http_response_code() !== 200) return false; if (empty($_POST) AND $requireLogin AND !isset($_SESSION['id'])) echo 'Ce formulaire ne sera pas accepté car il faut se connecter avant.
'; if (empty($_POST)) return false; if ($requireLogin AND !isset($_SESSION['id'])) output(403, 'Vous devez être connecté·e pour effectuer cette action.'); return true; } function insert($table, $values) { $query = 'INSERT INTO ' . $table . '('; foreach ($values as $key => $val) { if ($key === array_key_last($values)) $query .= "$key"; else $query .= "$key, "; } $query .= ') VALUES('; foreach ($values as $key => $val) { if ($key === array_key_last($values)) $query .= ":$key"; else $query .= ":$key, "; } $query .= ')'; $db = new PDO('sqlite:' . DB_PATH); $op = $db->prepare($query); foreach ($values as $key => $val) $op->bindValue(":$key", $val); $op->execute(); } function query($action, $table, $conditions = [], $column = NULL) { $query = match ($action) { 'select' => 'SELECT *', 'delete' => 'DELETE', }; $query .= ' FROM ' . $table; foreach ($conditions as $key => $val) { if ($key === array_key_first($conditions)) $query .= " WHERE $key = :$key"; else $query .= " AND $key = :$key"; } $db = new PDO('sqlite:' . DB_PATH); $op = $db->prepare($query); foreach ($conditions as $key => $val) $op->bindValue(":$key", $val); $op->execute(); if (isset($column)) return array_column($op->fetchAll(PDO::FETCH_ASSOC), $column); return $op->fetchAll(PDO::FETCH_ASSOC); } function displayIndex() { ?> redir.'); header('Location: ' . CONF['common']['prefix'] . '/' . $_GET['redir']); } else { header('Location: ' . CONF['common']['prefix'] . '/'); } exit(); } // 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) output(500, 'Unable to remove directory.'); } function equalArrays($a, $b) { return array_diff($a, $b) === [] AND array_diff($b, $a) === []; } function linkToDocs($ref, $title) { return '' . $title . ''; } /* 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) */ define('SECRET_KEY_FILE', sys_get_temp_dir() . '/Niver.key'); if (!file_exists(SECRET_KEY_FILE)) { $original_umask = umask(0077); file_put_contents(SECRET_KEY_FILE, random_bytes(32)); umask($original_umask); } define('SECRET_KEY', file_get_contents(SECRET_KEY_FILE)); function getAuthToken() { $salt = bin2hex(random_bytes(4)); $hash = hash_hmac('sha256', $salt . ($_SESSION['id'] ?? ''), SECRET_KEY); return $salt . '-' . substr($hash, 0, 32); } function checkAuthToken($salt, $hash) { $correctProof = substr(hash_hmac('sha256', $salt . $_SESSION['id'], SECRET_KEY), 0, 32); if (hash_equals($correctProof, $hash) !== true) output(403, 'Preuve incorrecte'); }