reg: Delay at unregistration; Display domain history

This commit is contained in:
Miraty 2023-03-25 16:26:05 +01:00
parent ed05d4aab9
commit b9af7fee09
9 changed files with 138 additions and 51 deletions

View file

@ -10,7 +10,7 @@ INSERT INTO "params"("name", "value") VALUES('secret_key', '0');
INSERT INTO "params"("name", "value") VALUES('secret_key_last_change', '0');
INSERT INTO "params"("name", "value") VALUES('username_salt', '00000000000000000000000000000000'); -- Should be unique and secret ; generate one using `openssl rand -hex 16` ; can't be changed without breaking current accounts login
CREATE TABLE IF NOT EXISTS "users" (
"id" TEXT NOT NULL UNIQUE,
"id" TEXT NOT NULL UNIQUE CHECK (LENGTH(id) = 64),
"username" TEXT NOT NULL UNIQUE,
"password" TEXT NOT NULL,
"registration_date" TEXT NOT NULL,
@ -27,10 +27,15 @@ CREATE TABLE IF NOT EXISTS "approval-keys" (
CREATE TABLE IF NOT EXISTS "registry" (
"domain" TEXT NOT NULL UNIQUE,
"username" TEXT NOT NULL,
"last_renewal" TEXT NOT NULL,
"creation" TEXT NOT NULL,
PRIMARY KEY("domain"),
FOREIGN KEY("username") REFERENCES "users"("id")
);
CREATE TABLE IF NOT EXISTS "registry-history" (
"domain" TEXT NOT NULL,
"creation" TEXT NOT NULL,
"expiration" TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS "zones" (
"zone" TEXT NOT NULL UNIQUE,
"username" TEXT NOT NULL,

View file

@ -23,11 +23,27 @@ function regDeleteDomain($domain) {
if (file_put_contents($path, $content) === false)
output(500, 'Failed to write new registry file.');
// Delete from database
query('delete', 'registry', [
try {
DB->beginTransaction();
$conditions = [
'domain' => $domain,
'username' => $_SESSION['id'],
];
insert('registry-history', [
'domain' => $domain,
'creation' => query('select', 'registry', $conditions, 'creation')[0],
'expiration' => date('Y-m'),
]);
query('delete', 'registry', $conditions);
DB->commit();
} catch (Exception $e) {
DB->rollback();
output(500, 'Database error.', [$e->getMessage()]);
}
}
function regParseDomain($domain) {

View file

@ -1,5 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-25 16:16+0100\n"
"Language: fr\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -272,15 +274,15 @@ msgstr "Supprimer un accès"
msgid "Delete an existing HTTP access from a subdirectory of the SFTP space"
msgstr "Retirer un accès HTTP existant d'un sous-dossier de l'espace SFTP"
#: router.php:133 view.php:39
#: router.php:137 view.php:39
msgid "This service is currently under maintenance. No action can be taken on it until an administrator finishes repairing it."
msgstr "Ce service est en cours de maintenance. Aucune action ne peut être effectuée avant qu'ane administrataire termine de le réparer."
#: router.php:144
#: router.php:148
msgid "You need to be logged in to do this."
msgstr "Vous devez être connecté·e à un compte pour faire cela."
#: router.php:146
#: router.php:150
msgid "This account doesn't exist anymore. Log out to end this ghost session."
msgstr "Ce compte n'existe plus. Déconnectez-vous pour terminer cette session fantôme."
@ -485,19 +487,35 @@ msgstr "Zone supprimée."
msgid "This format of subdomain is not allowed."
msgstr "Ce format de sous-domaine n'est pas autorisé."
#: pg-act/reg/register.php:27
msgid "This domain is open to registration!"
msgstr "Ce domaine est disponible à l'enregistrement."
#: pg-act/reg/register.php:29
#: pg-act/reg/register.php:21
msgid "This domain is reserved."
msgstr "Ce domaine est réservé."
#: pg-act/reg/register.php:31
msgid "This domain is already registered."
msgstr "Ce domaine est déjà enregistré."
#: pg-act/reg/register.php:34
#, php-format
msgid "This domain was registered from %s to %s."
msgstr "Ce domaine était enregistré de %s à %s."
#: pg-act/reg/register.php:47
#: pg-act/reg/register.php:38
#, php-format
msgid "This blocks it until %s."
msgstr "Ceci le bloque jusqu'en %s."
#: pg-act/reg/register.php:40
#, php-format
msgid "This had blocked it until %s."
msgstr "Ceci l'avait bloqué jusqu'en %s."
#: pg-act/reg/register.php:48
#, php-format
msgid "This domain is already registered, since %s."
msgstr "Ce domaine est déjà enregistré, depuis %s."
#: pg-act/reg/register.php:54
msgid "This domain is open to registration!"
msgstr "Ce domaine est disponible à l'enregistrement."
#: pg-act/reg/register.php:71
msgid "Domain registered."
msgstr "Domaine enregistré."
@ -1116,8 +1134,8 @@ msgid "Receive the domain"
msgstr "Recevoir le domaine"
#: pg-view/reg/unregister.php:2
msgid "This will unregister the domain, making it registerable by anyone again."
msgstr "Ceci désenregistrera le domaine, ce qui le re-disponibilisera à tout le monde."
msgid "This will unregister the domain, making it registerable by anyone again (after a delay of 1 year plus half the registration period, with a maximum of 8 years)."
msgstr "Ceci désenregistrera le domaine, ce qui le re-disponibilisera à tout le monde (après un délai de 1 an + la moitié de la durée d'enregistrement, avec un maximum de 8 ans)."
#: pg-view/reg/unregister.php:16
msgid "Unregister"

View file

@ -271,15 +271,15 @@ msgstr ""
msgid "Delete an existing HTTP access from a subdirectory of the SFTP space"
msgstr ""
#: router.php:133 view.php:39
#: router.php:137 view.php:39
msgid "This service is currently under maintenance. No action can be taken on it until an administrator finishes repairing it."
msgstr ""
#: router.php:144
#: router.php:148
msgid "You need to be logged in to do this."
msgstr ""
#: router.php:146
#: router.php:150
msgid "This account doesn't exist anymore. Log out to end this ghost session."
msgstr ""
@ -484,19 +484,35 @@ msgstr ""
msgid "This format of subdomain is not allowed."
msgstr ""
#: pg-act/reg/register.php:27
msgid "This domain is open to registration!"
msgstr ""
#: pg-act/reg/register.php:29
#: pg-act/reg/register.php:21
msgid "This domain is reserved."
msgstr ""
#: pg-act/reg/register.php:31
msgid "This domain is already registered."
#: pg-act/reg/register.php:34
#, php-format
msgid "This domain was registered from %s to %s."
msgstr ""
#: pg-act/reg/register.php:47
#: pg-act/reg/register.php:38
#, php-format
msgid "This blocks it until %s."
msgstr ""
#: pg-act/reg/register.php:40
#, php-format
msgid "This had blocked it until %s."
msgstr ""
#: pg-act/reg/register.php:48
#, php-format
msgid "This domain is already registered, since %s."
msgstr ""
#: pg-act/reg/register.php:54
msgid "This domain is open to registration!"
msgstr ""
#: pg-act/reg/register.php:71
msgid "Domain registered."
msgstr ""
@ -1115,7 +1131,7 @@ msgid "Receive the domain"
msgstr ""
#: pg-view/reg/unregister.php:2
msgid "This will unregister the domain, making it registerable by anyone again."
msgid "This will unregister the domain, making it registerable by anyone again (after a delay of 1 year plus half the registration period, with a maximum of 8 years)."
msgstr ""
#: pg-view/reg/unregister.php:16

View file

@ -6,7 +6,7 @@ if (checkPassword($_SESSION['id'], $_POST['current-password']) !== true)
if (!isset($_POST['delete']))
output(403, _('Account deletion must be confirmed.'));
$user_services = explode(',', query('select', 'users', ['username' => $_SESSION['id']], 'services')[0]);
$user_services = explode(',', query('select', 'users', ['id' => $_SESSION['id']], 'services')[0]);
foreach (SERVICES_USER as $service)
if (in_array($service, $user_services, true) AND CONF['common']['services'][$service] !== 'enabled')

View file

@ -17,31 +17,55 @@ match (CONF['reg']['suffixes'][$_POST['suffix']]) {
$domain = formatAbsoluteDomain($_POST['subdomain'] . '.' . $_POST['suffix']);
$registered = query('select', 'registry', ['domain' => $domain], 'domain') !== [];
$reserved = in_array($_POST['subdomain'], explode(LF, file_get_contents(ROOT_PATH . '/pg-act/reg/reserved.txt')));
if (in_array($_POST['subdomain'], explode(LF, file_get_contents(ROOT_PATH . '/pg-act/reg/reserved.txt')), true))
message('❌ ' . _('This domain is reserved.'));
$message = match ($registered) {
false => match ($reserved) {
false => match ($_POST['action']) {
'register' => NULL,
default => '✔️ ' . _('This domain is open to registration!'),
},
default => '❌ ' . _('This domain is reserved.'),
},
default => '❌ ' . _('This domain is already registered.'),
};
if ($message !== NULL)
$message = '<ul>';
$blocked = false;
foreach (query('select', 'registry-history', ['domain' => $domain]) as $data) {
$creation = DateTimeImmutable::createFromFormat('Y-m', $data['creation']);
$expiration = DateTimeImmutable::createFromFormat('Y-m', $data['expiration']);
$registration_duration = intval(round($creation->diff($expiration)->format('%a') / 30.4375));
$expected_expiration_duration = min(intval($registration_duration * 0.5) + 12, 12*8);
$new_registration_date = $expiration->add(new DateInterval('P' . $expected_expiration_duration . 'M'));
$message .= '<li>' . sprintf(_('This domain was registered from %s to %s.'), '<time>' . $data['creation'] . '</time>', '<time>' . $data['expiration'] . '</time>') . ' ';
if (new DateTimeImmutable('now', new DateTimeZone('UTC')) < $new_registration_date) {
$blocked = true;
$message .= sprintf(_('This blocks it until %s.'), '<time>' . $new_registration_date->format('Y-m') . '</time>') . ' ❌';
} else {
$message .= sprintf(_('This had blocked it until %s.'), '<time>' . $new_registration_date->format('Y-m') . '</time>');
}
$message .= '</li>';
}
$message .= '</ul>';
$registration_data = query('select', 'registry', ['domain' => $domain]);
if ($registration_data !== [])
$message .= sprintf(_('This domain is already registered, since %s.'), '<time>' . $registration_data[0]['creation'] . '</time>');
if ($blocked OR $registration_data !== [])
message($message);
if ($_POST['action'] !== 'register')
message($message . ' ✔️ ' . _('This domain is open to registration!'));
function message($message) {
output(200, data: [
'message' => '<p>' . $message . '</p>',
'domain' => htmlspecialchars($_POST['subdomain']),
]);
}
rateLimit();
insert('registry', [
'domain' => $domain,
'username' => $_SESSION['id'],
'last_renewal' => date('Y-m-d H:i:s'),
'creation' => date('Y-m'),
]);
output(200, _('Domain registered.'));
output(200, _('Domain registered.'), ['message' => '<p>' . $message . '</p>']);

View file

@ -25,6 +25,10 @@ foreach (CONF['reg']['suffixes'] as $suffix => $availability) {
</div>
</fieldset>
<button type="submit" name="action" value="check">👁️ <?= _('Check availability') ?></button>
<?= $data['message'] ?? '<br>' ?>
<br>
<button type="submit" name="action" value="register">🔗 <?= _('Register') ?></button>
</form>
<section>
<?= $data['message'] ?? '' ?>
</section>

View file

@ -1,5 +1,5 @@
<p>
<?= _('This will unregister the domain, making it registerable by anyone again.') ?>
<?= _('This will unregister the domain, making it registerable by anyone again (after a delay of 1 year plus half the registration period, with a maximum of 8 years).') ?>
</p>
<form method="post">

View file

@ -3,6 +3,10 @@ const ROOT_PATH = __DIR__;
define('CONF', parse_ini_file(ROOT_PATH . '/config.ini', true, INI_SCANNER_TYPED));
define('DB', new PDO('sqlite:' . ROOT_PATH . '/db/servnest.db'));
DB->exec('PRAGMA foreign_keys = ON;');
DB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
date_default_timezone_set('UTC');
$locale = 'en';
foreach (explode(',', preg_replace('/[A-Z0-9]|q=|;|-|\./', '', $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '')) as $client_locale) {