From b9af7fee090015fb0a6cc174f7240dd6f649a981 Mon Sep 17 00:00:00 2001 From: Miraty Date: Sat, 25 Mar 2023 16:26:05 +0100 Subject: [PATCH] reg: Delay at unregistration; Display domain history --- db/schema.sql | 9 +++-- fn/reg.php | 26 +++++++++++--- locales/fr/C/LC_MESSAGES/messages.po | 46 ++++++++++++++++-------- locales/messages.pot | 40 ++++++++++++++------- pg-act/auth/unregister.php | 2 +- pg-act/reg/register.php | 54 ++++++++++++++++++++-------- pg-view/reg/register.php | 6 +++- pg-view/reg/unregister.php | 2 +- router.php | 4 +++ 9 files changed, 138 insertions(+), 51 deletions(-) diff --git a/db/schema.sql b/db/schema.sql index 75c511f..7a60faf 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -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, diff --git a/fn/reg.php b/fn/reg.php index 145eb48..91c8b8d 100644 --- a/fn/reg.php +++ b/fn/reg.php @@ -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', [ - 'domain' => $domain, - 'username' => $_SESSION['id'], - ]); + 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) { diff --git a/locales/fr/C/LC_MESSAGES/messages.po b/locales/fr/C/LC_MESSAGES/messages.po index e4d66d6..dda3dad 100644 --- a/locales/fr/C/LC_MESSAGES/messages.po +++ b/locales/fr/C/LC_MESSAGES/messages.po @@ -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" diff --git a/locales/messages.pot b/locales/messages.pot index f645454..c78957b 100644 --- a/locales/messages.pot +++ b/locales/messages.pot @@ -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 diff --git a/pg-act/auth/unregister.php b/pg-act/auth/unregister.php index 65a5ae5..708da1c 100644 --- a/pg-act/auth/unregister.php +++ b/pg-act/auth/unregister.php @@ -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') diff --git a/pg-act/reg/register.php b/pg-act/reg/register.php index 5d8213b..f516c45 100644 --- a/pg-act/reg/register.php +++ b/pg-act/reg/register.php @@ -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 = ''; + +$registration_data = query('select', 'registry', ['domain' => $domain]); +if ($registration_data !== []) + $message .= sprintf(_('This domain is already registered, since %s.'), ''); + +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' => '

' . $message . '

', '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' => '

' . $message . '

']); diff --git a/pg-view/reg/register.php b/pg-view/reg/register.php index 5182653..74f2ce2 100644 --- a/pg-view/reg/register.php +++ b/pg-view/reg/register.php @@ -25,6 +25,10 @@ foreach (CONF['reg']['suffixes'] as $suffix => $availability) { - ' ?> +
+ +
+ +
diff --git a/pg-view/reg/unregister.php b/pg-view/reg/unregister.php index 7ac771b..0ab31f6 100644 --- a/pg-view/reg/unregister.php +++ b/pg-view/reg/unregister.php @@ -1,5 +1,5 @@

- +

diff --git a/router.php b/router.php index c0fafbc..6ad02be 100644 --- a/router.php +++ b/router.php @@ -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) {