Update auth forms

This commit is contained in:
Miraty 2022-06-10 21:14:47 +02:00
parent 5e6da92d01
commit 6b602eb43f
17 changed files with 108 additions and 146 deletions

View File

@ -2,12 +2,6 @@
root_path = "/srv/php/niver"
; Prefix in URL, if any
prefix =
; From RFC2606: Reserved Top Level DNS Names > 2. TLDs for Testing, & Documentation Examples
domain_example = "example"
; From RFC3849: IPv6 Address Prefix Reserved for Documentation
ipv6_example = "2001:db8::3"
; From RFC5737: IPv4 Address Blocks Reserved for Documentation
ipv4_example = "203.0.113.42"
[dns]
knotc_path = "/usr/sbin/knotc"

View File

@ -3,6 +3,9 @@
define("USERNAME_REGEX", "^[a-z]{4,32}$");
define("PASSWORD_REGEX", "^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]{8,1024}|.{10,1024}$");
define("PLACEHOLDER_USERNAME", "lain");
define("PLACEHOLDER_PASSWORD", "••••••••••••••••••••••••");
// Password storage security
define("ALGO_PASSWORD", PASSWORD_ARGON2ID);
define("OPTIONS_PASSWORD", array(

View File

@ -1,5 +1,9 @@
<?php
define("PLACEHOLDER_DOMAIN", "example"); // From RFC2606: Reserved Top Level DNS Names > 2. TLDs for Testing, & Documentation Examples
define("PLACEHOLDER_IPV6", "2001:db8::3"); // From RFC3849: IPv6 Address Prefix Reserved for Documentation
define("PLACEHOLDER_IPV4", "203.0.113.42"); // From RFC5737: IPv4 Address Blocks Reserved for Documentation
function knotcExec($suffix, $cmd) {
$action = checkAction($_POST['action']);

View File

@ -1,17 +1,22 @@
<?php require "../../common/html.php"; ?>
<?php if (isset($_SESSION['username'])) { ?>
<a class="auth" href="logout">Se déconnecter</a>
<br>
<a class="auth" href="password">Changer la clé de passe</a>
<?php } else { ?>
Vous devez être authentifié·e pour utiliser Niver
<br>
<a class="auth" href="register">Créer un compte</a>
<br>
<a class="auth" href="login">Se connecter</a>
<?php } ?>
<dl>
<dt><a href="register">Créer un compte</a></dt>
<dd>
Créer un nouveau compte Niver
</dd>
<dt><a href="login">Se connecter</a></dt>
<dd>
Démarrer une nouvelle session avec un compte existant
</dd>
<dt><a href="logout">Se déconnecter</a></dt>
<dd>
Terminer la session et effacer ses cookies
</dd>
<dt><a href="password">Changer la clé de passe</a></dt>
<dd>
Changer la chaîne de caractères permettant de vous authentifier.
</dd>
</dl>
<?php closeHTML(); ?>

View File

@ -4,11 +4,11 @@
<form method="post">
<label for="username">Identifiant</label><br>
<input required="" minlength="4" maxlength="32" pattern="<?= USERNAME_REGEX ?>" id="username" name="username" type="text" placeholder="lain">
<input required="" minlength="4" maxlength="32" pattern="<?= USERNAME_REGEX ?>" id="username" name="username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>">
<br>
<label for="password">Clé de passe</label><br>
<input required="" autocomplete="current-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="password" name="password" type="password" placeholder="************************">
<input required="" autocomplete="current-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="password" name="password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>">
<br>
<input type="submit">
@ -16,32 +16,29 @@
<?php
if (isset($_POST['username']) AND isset($_POST['password'])) {
switchToFormProcess(requireLogin: false);
checkPasswordFormat($_POST['password']);
checkPasswordFormat($_POST['password']);
checkUsernameFormat($_POST['username']);
checkUsernameFormat($_POST['username']);
if (userExist($_POST['username']) !== true)
userError("Connexion impossible : ce compte n'existe pas.");
if (userExist($_POST['username']) !== true)
userError("Connexion impossible : ce compte n'existe pas.");
if (checkPassword($_POST['username'], $_POST['password']) !== true)
userError("Connexion impossible : clé de passe invalide.");
if (checkPassword($_POST['username'], $_POST['password']) !== true)
userError("Connexion impossible : clé de passe invalide.");
$_SESSION['username'] = $_POST['username'];
$_SESSION['username'] = $_POST['username'];
if (outdatedPasswordHash($_SESSION['username']))
changePassword($_SESSION['username'], $_POST['password']);
if (outdatedPasswordHash($_SESSION['username']))
changePassword($_SESSION['username'], $_POST['password']);
if (isset($_GET['redir'])) {
if (preg_match("/^[0-9a-z\/-]+$/", $_GET['redir']) !== 1)
userError("Wrong character in <code>redir</code>.");
header("Location: " . CONF['common']['prefix'] . "/" . $_GET['redir']);
} else {
header("Location: " . CONF['common']['prefix'] . "/");
}
if (isset($_GET['redir'])) {
if (preg_match("/^[0-9a-z\/-]+$/", $_GET['redir']) !== 1)
userError("Wrong character in <code>redir</code>.");
header("Location: " . CONF['common']['prefix'] . "/" . $_GET['redir']);
} else {
header("Location: " . CONF['common']['prefix'] . "/");
}
?>
<?php closeHTML(); ?>
success("Connecté·e.");

View File

@ -1,10 +1,10 @@
<?php require "../../common/html.php"; ?>
<?php
session_destroy();
if (session_status() === PHP_SESSION_ACTIVE)
session_destroy();
header('Clear-Site-Data: "*"');
header('Location: ' . CONF['common']['prefix'] . '/');
exit;
?>
<?php closeHTML(); ?>
success("Déconnecté·e.");

View File

@ -1,40 +1,28 @@
<?php require "../../common/html.php"; ?>
<p>
Vous pouvez ici changer le mot de passe permettant d'accéder à votre compte Niver.
Vous pouvez ici changer la clé de passe permettant d'accéder à votre compte Niver.
</p>
<form method="post">
<label for="currentPassword">Mot de passe actuel</label><br>
<input required="" autocomplete="current-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="currentPassword" name="currentPassword" type="password" placeholder="************"><br>
<label for="currentPassword">Clé de passe actuelle</label><br>
<input required="" autocomplete="current-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="currentPassword" name="currentPassword" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>"><br>
<label for="newPassword">Nouveau mot de passe</label><br>
<input required="" autocomplete="new-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="newPassword" name="newPassword" type="password" placeholder="************"><br>
<label for="newPassword">Nouvelle clé de passe</label><br>
<input required="" autocomplete="new-password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" id="newPassword" name="newPassword" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>"><br>
<input type="submit">
</form>
<?php
if (isset($_SESSION['username']) AND isset($_POST['newPassword']) AND isset($_POST['currentPassword'])) {
switchToFormProcess();
checkPasswordFormat($_POST['newPassword']);
checkPasswordFormat($_POST['newPassword']);
if (checkPassword($_SESSION['username'], $_POST['currentPassword']) !== true)
userError("Changement impossible : clé de passe invalide.");
if (checkPassword($_SESSION['username'], $_POST['currentPassword']) !== true)
userError("Changement impossible : clé de passe invalide.");
$newPassword = hashPassword($_POST['newPassword']);
changePassword($_SESSION['username'], $_POST['newPassword']);
$db = new PDO('sqlite:' . DB_PATH);
$stmt = $db->prepare("UPDATE users SET password = :password WHERE username = :username");
$stmt->bindParam(':username', $_SESSION['username']);
$stmt->bindParam(':password', $newPassword);
$stmt->execute();
}
?>
<?php closeHTML(); ?>
success("Clé de passe changée.");

View File

@ -2,63 +2,13 @@
<p>Déjà un compte ? <a class="auth" href="login">Se connecter</a></p>
<?php
if (isset($_POST['username']) AND isset($_POST['password'])) {
checkPasswordFormat($_POST['password']);
checkUsernameFormat($_POST['username']);
$userExist = userExist($_POST['username']);
if ($userExist === false) {
// Setup SFTP directory
umask(0002);
if (mkdir(CONF['ht']['ht_path'] . "/" . $_POST['username'], 0775) !== true)
serverError("Can't create user directory.");
exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['chgrp_path'] . " " . CONF['ht']['sftpgo_group'] . " " . CONF['ht']['ht_path'] . "/" . $_POST['username'] . " --no-dereference", $stdout, $code);
if ($code !== 0)
serverError("Can't change user directory group.");
$password = hashPassword($_POST['password']);
$db = new PDO('sqlite:' . DB_PATH);
$stmt = $db->prepare("INSERT INTO users(username, password, registration_date) VALUES(:username, :password, :registration_date)");
$time = date("Y-m-d H:i:s");
$stmt->bindParam(':username', $_POST['username']);
$stmt->bindParam(':password', $password);
$stmt->bindParam(':registration_date', $time);
$stmt->execute();
$_SESSION['username'] = $_POST['username'];
header('Location: ' . CONF['common']['prefix'] . '/');
exit;
}
}
?>
<form method="post">
<details>
<summary><label for="username">Identifiant</label></summary>
Uniquement composé de lettres minuscules.
</details>
<input id="username" minlength="4" maxlength="32" pattern="<?= USERNAME_REGEX ?>" required="" name="username" type="text" placeholder="lain"><span></span><br>
<?php
if (isset($userExist) AND $userExist === true) {
echo "<br>Cet identifiant est déjà utilisé. Choisissez-en un autre.";
}
?>
<input id="username" minlength="4" maxlength="32" pattern="<?= USERNAME_REGEX ?>" required="" name="username" type="text" placeholder="<?= PLACEHOLDER_USERNAME ?>"><br>
<details>
<summary><label for="password">Clé de passe</label></summary>
@ -66,9 +16,46 @@ if (isset($userExist) AND $userExist === true) {
<p>Minimum 8 caractères si elle contient minuscule, majuscule et chiffre, ou minimum 10 caractères sinon.</p>
</details>
<input autocomplete="new-password" id="password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" required="" name="password" type="password" placeholder="************"><span title="Le format nest pas valide"></span><br>
<input autocomplete="new-password" id="password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" required="" name="password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>"><br>
<input type="submit">
</form>
<?php closeHTML(); ?>
<?php
switchToFormProcess(requireLogin: false);
checkPasswordFormat($_POST['password']);
checkUsernameFormat($_POST['username']);
if (userExist($_POST['username']) !== false)
userError("Ce nom de compte est déjà utilisé.");
// Setup SFTP directory
umask(0002);
if (mkdir(CONF['ht']['ht_path'] . "/" . $_POST['username'], 0775) !== true)
serverError("Can't create user directory.");
exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['chgrp_path'] . " " . CONF['ht']['sftpgo_group'] . " " . CONF['ht']['ht_path'] . "/" . $_POST['username'] . " --no-dereference", $stdout, $code);
if ($code !== 0)
serverError("Can't change user directory group.");
$password = hashPassword($_POST['password']);
$db = new PDO('sqlite:' . DB_PATH);
$stmt = $db->prepare("INSERT INTO users(username, password, registration_date) VALUES(:username, :password, :registration_date)");
$time = date("Y-m-d H:i:s");
$stmt->bindParam(':username', $_POST['username']);
$stmt->bindParam(':password', $password);
$stmt->bindParam(':registration_date', $time);
$stmt->execute();
$_SESSION['username'] = $_POST['username'];
header('Location: ' . CONF['common']['prefix'] . '/');
success("Compte créé.");

View File

@ -35,22 +35,6 @@ input[type=password] {
width: 7ch;
}
input:invalid+span::after {
content: '✖';
}
input:valid+span::after {
content: ''; /* ✓ */
}
input+span::after {
display: inline-block;
width: 20px;
font-size: 30px;
padding-left: 20px;
font-family: monospace;
}
:disabled {
cursor: not-allowed;
}

View File

@ -9,7 +9,7 @@
<form method="post">
<label for="domain">Domaine sur lequel répondre</label><br>
<input required="" placeholder="site.<?= CONF['common']['domain_example'] ?>" id="domain" name="domain" type="text"><br>
<input required="" placeholder="site.<?= PLACEHOLDER_DOMAIN ?>" id="domain" name="domain" type="text"><br>
<label for="dir">Dossier ciblé</label><br>
<select required="" name="dir" id="dir">
<option value="" disabled="" selected="">---</option>

View File

@ -8,7 +8,7 @@
<form method="post">
<?php require "../../form.ns.php"; ?>
<label for="ip">Adresse IP</label><br>
<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="7" maxlength="39" size="40" type="text" placeholder="<?= CONF['common']['ipv6_example'] ?> ou <?= CONF['common']['ipv4_example'] ?>"><br>
<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="7" maxlength="39" size="40" type="text" placeholder="<?= PLACEHOLDER_IPV6 ?> ou <?= PLACEHOLDER_IPV4 ?>"><br>
<input value="Valider" type="submit">
</form>

View File

@ -14,7 +14,7 @@
<label for="host">Hôte</label>
<br>
<input id="host" placeholder="mail.<?= CONF['common']['domain_example'] ?>." name="host" type="text">
<input id="host" placeholder="mail.<?= PLACEHOLDER_DOMAIN ?>." name="host" type="text">
<br>
<input value="Valider" type="submit">

View File

@ -5,7 +5,7 @@
<br>
<label for="ns">Serveur de nom</label>
<br>
<input id="ns" placeholder="ns1.<?= CONF['common']['domain_example'] ?>" name="ns" type="text">
<input id="ns" placeholder="ns1.<?= PLACEHOLDER_DOMAIN ?>" name="ns" type="text">
<br>
<input value="Procéder" type="submit">
</form>

View File

@ -26,7 +26,7 @@
<label for="target">Cible</label>
<br>
<input id="target" minlenght="1" maxlength="128" placeholder="service.<?= CONF['common']['domain_example'] ?>." name="target" type="text">
<input id="target" minlenght="1" maxlength="128" placeholder="service.<?= PLACEHOLDER_DOMAIN ?>." name="target" type="text">
<br>
<input value="Valider" type="submit">

View File

@ -3,7 +3,7 @@
<form method="post">
<h2>Ajouter une zone</h2>
<label for="domain">Domaine</label><br>
<input required="" placeholder="domain.<?= CONF['common']['domain_example'] ?>." id="domain" name="domain" type="text"><br>
<input required="" placeholder="domain.<?= PLACEHOLDER_DOMAIN ?>." id="domain" name="domain" type="text"><br>
<input value="Ajouter" type="submit">
</form>

View File

@ -30,7 +30,7 @@ if (isset($_SESSION['username']))
</div>
</fieldset>
<label for="ip">IP</label><br>
<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="7" maxlength="39" size="40" type="text" placeholder="<?= CONF['common']['ipv4_example'] ?> ou <?= CONF['common']['ipv6_example'] ?>">
<input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="7" maxlength="39" size="40" type="text" placeholder="<?= PLACEHOLDER_IPV4 ?> ou <?= PLACEHOLDER_IPV6 ?>">
<br>
<input value="Valider" type="submit">
</form>

View File

@ -21,7 +21,7 @@ if (isset($_SESSION['username']))
<br>
<label for="ns">Serveur de nom</label>
<br>
<input id="ns" placeholder="ns1.<?= CONF['common']['domain_example'] ?>." name="ns" type="text">
<input id="ns" placeholder="ns1.<?= PLACEHOLDER_DOMAIN ?>." name="ns" type="text">
<br>
<input value="Valider" type="submit">
</form>