diff --git a/db/schema.sql b/db/schema.sql index a0a664c..4d253f2 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -46,7 +46,6 @@ CREATE TABLE IF NOT EXISTS "ns-syncs" ( "username" TEXT NOT NULL, "source" TEXT NOT NULL, "destination" TEXT NOT NULL UNIQUE, - UNIQUE("username", "source", "destination"), FOREIGN KEY("username") REFERENCES "users"("id"), FOREIGN KEY("destination") REFERENCES "zones"("zone") ); diff --git a/fn/auth.php b/fn/auth.php index 023bb41..fd3d48f 100644 --- a/fn/auth.php +++ b/fn/auth.php @@ -98,11 +98,9 @@ function authDeleteUser(string $user_id): void { foreach (query('select', 'registry', ['username' => $user_id], 'domain') as $domain) regDeleteDomain($domain, $user_id); - if (in_array('ns', $user_services, true)) { - query('delete', 'ns-syncs', ['username' => $user_id]); + if (in_array('ns', $user_services, true)) foreach (query('select', 'zones', ['username' => $user_id], 'zone') as $zone) nsDeleteZone($zone, $user_id); - } if (in_array('ht', $user_services, true)) { foreach (query('select', 'sites', ['username' => $user_id]) as $site) diff --git a/fn/ns.php b/fn/ns.php index 128fca1..f84b553 100644 --- a/fn/ns.php +++ b/fn/ns.php @@ -17,7 +17,7 @@ const ALLOWED_TYPES = ['AAAA', 'A', 'TXT', 'SRV', 'MX', 'SVCB', 'HTTPS', 'NS', ' const ZONE_MAX_CHARACTERS = 10000; -const SYNC_TTL = 3600; +const SYNC_TTL = 10800; function nsParseCommonRequirements(): array { nsCheckZonePossession($_POST['zone']); @@ -73,6 +73,8 @@ function nsDeleteZone(string $zone, string $user_id): void { if ($code !== 0) output(500, 'Failed to purge zone data.'); + query('delete', 'ns-syncs', ['destination' => $zone]); + // Remove from database query('delete', 'zones', [ 'zone' => $zone, diff --git a/jobs/check.php b/jobs/check.php index ac97876..fb28394 100644 --- a/jobs/check.php +++ b/jobs/check.php @@ -1,6 +1,6 @@ SFTP space" msgstr "Téléverser un site statique dans un espace SFTP" -#: pages.php:173 +#: pages.php:178 #, php-format msgid "%s subpath access" msgstr "Accès par sous-chemin de %s" -#: pages.php:174 pages.php:179 pages.php:184 +#: pages.php:179 pages.php:184 pages.php:189 #, php-format msgid "Its URL will look like %s" msgstr "Son URL ressemblera à %s" -#: pages.php:174 pages.php:179 pages.php:184 +#: pages.php:179 pages.php:184 pages.php:189 msgid "mysite" msgstr "monsite" -#: pages.php:178 +#: pages.php:183 #, php-format msgid "%s subdomain access" msgstr "Accès par sous-domaine de %s" -#: pages.php:183 +#: pages.php:188 msgid "Dedicated domain with Let's Encrypt certificate access" msgstr "Accès par domaine dédié avec certificat Let's Encrypt" -#: pages.php:188 +#: pages.php:193 msgid "Onion service access" msgstr "Accès par service Onion" -#: pages.php:189 +#: pages.php:194 #, php-format msgid "Its URL will look like %s, and work only through the Tor network" msgstr "Son URL ressemblera à %s, et ne fonctionnera que par le réseau Tor" -#: pages.php:193 pg-view/ht/del.php:18 +#: pages.php:198 pg-view/ht/del.php:18 msgid "Delete access" msgstr "Supprimer un accès" -#: pages.php:194 +#: pages.php:199 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" -#: pages.php:197 +#: pages.php:202 msgid "Manage SSH keys" msgstr "Gérer les clés SSH" -#: pages.php:198 +#: pages.php:203 msgid "Choose what SSH key can edit what directory" msgstr "Choisir quelle clé SSH peut modifier quel dossier" @@ -321,11 +330,11 @@ msgstr "%sCode source%s disponible sous %s." msgid "Your account can't be deleted because the %s service is currently unavailable." msgstr "Votre compte ne peut pas être supprimé car le service %s est actuellement indisponible." -#: fn/auth.php:161 +#: fn/auth.php:163 msgid "Account rate limit reached, try again later." msgstr "Limite de taux pour ce compte atteinte, réessayez plus tard." -#: fn/auth.php:186 +#: fn/auth.php:188 msgid "Global rate limit reached, try again later." msgstr "Limite de taux globale atteinte, réessayez plus tard." @@ -341,24 +350,24 @@ msgstr "Erreur de l'utilisataire : " msgid "Server error: " msgstr "Erreur du serveur : " -#: fn/common.php:137 +#: fn/common.php:155 msgid "Wrong proof." msgstr "Preuve incorrecte." -#: fn/dns.php:74 +#: fn/dns.php:77 msgid "IP address malformed." msgstr "Adresse IP malformée." -#: fn/dns.php:79 fn/ht.php:48 +#: fn/dns.php:82 fn/ht.php:48 msgid "Domain malformed." msgstr "Domaine malformé." -#: fn/ns.php:31 pg-act/ns/edit.php:25 +#: fn/ns.php:33 pg-act/ns/edit.php:25 #, php-format msgid "TTLs shorter than %s seconds are forbidden." msgstr "Les TTLs plus courts que %s secondes sont interdits." -#: fn/ns.php:33 pg-act/ns/edit.php:27 +#: fn/ns.php:35 pg-act/ns/edit.php:27 #, php-format msgid "TTLs longer than %s seconds are forbidden." msgstr "Les TTLs plus longs que %s secondes sont interdits." @@ -499,6 +508,14 @@ msgstr "Le type %s n'est pas autorisé." msgid "Sent zone content is not correct (according to kzonecheck)." msgstr "Le contenu de zone envoyé n'est pas correct (selon kzonecheck)." +#: pg-act/ns/sync.php:19 +msgid "Multiple source domains can't be applied to the same target domain." +msgstr "Plusieurs domaines sources ne peuvent pas être appliqués sur un même domaine cible." + +#: pg-act/ns/sync.php:41 +msgid "Synchronized records updated." +msgstr "Enregistrements synchronisés mis à jour." + #: pg-act/ns/zone-add.php:6 msgid "This zone already exists on the service." msgstr "Cette zone existe déjà sur ce service." @@ -858,7 +875,7 @@ msgstr "Clé publique" msgid "Allowed directory" msgstr "Dossier autorisé" -#: pg-view/ht/keys.php:30 +#: pg-view/ht/keys.php:30 pg-view/ns/sync.php:37 msgid "Update" msgstr "Mettre à jour" @@ -1109,6 +1126,35 @@ msgstr "Type de hash" msgid "Fingerprint" msgstr "Empreinte" +#: pg-view/ns/sync.php:2 +#, php-format +msgid "AAAA, A and CAA records are regularly copied from the source domain to the target domain. Their TTLs are set to %s seconds." +msgstr "Les enregistrements AAAA, A et CAA sont régulièrement copiés du domain source vers le domain cible. Leurs TTLs sont définis à %s secondes." + +#: pg-view/ns/sync.php:5 +msgid "Source domains that are not signed with DNSSEC are not synchronized. Synchronizations that remain broken may be deleted." +msgstr "Les domains sources qui ne sont pas signés avec DNSSEC ne sont pas synchronisés. Les synchronisations qui restent cassées peuvent être supprimées." + +#: pg-view/ns/sync.php:8 +msgid "This is meant to be used for apex domains, where CNAME records are not allowed. For non-apex domains, CNAME records should be used instead." +msgstr "Ceci est destiné à être utilisé sur des domaines apex, où les enregistrements CNAME ne sont pas autorisés. Pour des domaines non-apex, les enregistrements CNAME devraient être utilisés à la place." + +#: pg-view/ns/sync.php:16 +msgid "Add new domain records to be synchronized" +msgstr "Ajouter de nouveaux enregistrements de domain à synchroniser" + +#: pg-view/ns/sync.php:16 +msgid "Synchronized domain" +msgstr "Domaine synchronisé" + +#: pg-view/ns/sync.php:18 +msgid "Source domain" +msgstr "Domaine source" + +#: pg-view/ns/sync.php:22 +msgid "Target domain" +msgstr "Domaine cible" + #: pg-view/ns/tlsa.php:4 msgid "Use" msgstr "Utilisation" diff --git a/locales/messages.pot b/locales/messages.pot index 8cf3904..d65ec2c 100644 --- a/locales/messages.pot +++ b/locales/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-20 00:38+0200\n" +"POT-Creation-Date: 2023-06-26 02:14+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -238,59 +238,68 @@ msgstr "" msgid "Store geographic coordinates" msgstr "" -#: pages.php:169 +#: pages.php:167 +#, php-format +msgid "Synchronized records" +msgstr "" + +#: pages.php:168 +msgid "Regularly fetch distant records and update them to a local zone" +msgstr "" + +#: pages.php:174 msgid "Web" msgstr "" -#: pages.php:170 +#: pages.php:175 msgid "Upload a static website into an SFTP space" msgstr "" -#: pages.php:173 -#, php-format -msgid "%s subpath access" -msgstr "" - -#: pages.php:174 pages.php:179 pages.php:184 -#, php-format -msgid "Its URL will look like %s" -msgstr "" - -#: pages.php:174 pages.php:179 pages.php:184 -msgid "mysite" -msgstr "" - #: pages.php:178 #, php-format -msgid "%s subdomain access" +msgid "%s subpath access" +msgstr "" + +#: pages.php:179 pages.php:184 pages.php:189 +#, php-format +msgid "Its URL will look like %s" +msgstr "" + +#: pages.php:179 pages.php:184 pages.php:189 +msgid "mysite" msgstr "" #: pages.php:183 -msgid "Dedicated domain with Let's Encrypt certificate access" +#, php-format +msgid "%s subdomain access" msgstr "" #: pages.php:188 +msgid "Dedicated domain with Let's Encrypt certificate access" +msgstr "" + +#: pages.php:193 msgid "Onion service access" msgstr "" -#: pages.php:189 +#: pages.php:194 #, php-format msgid "Its URL will look like %s, and work only through the Tor network" msgstr "" -#: pages.php:193 pg-view/ht/del.php:18 +#: pages.php:198 pg-view/ht/del.php:18 msgid "Delete access" msgstr "" -#: pages.php:194 +#: pages.php:199 msgid "Delete an existing HTTP access from a subdirectory of the SFTP space" msgstr "" -#: pages.php:197 +#: pages.php:202 msgid "Manage SSH keys" msgstr "" -#: pages.php:198 +#: pages.php:203 msgid "Choose what SSH key can edit what directory" msgstr "" @@ -333,11 +342,11 @@ msgstr "" msgid "Your account can't be deleted because the %s service is currently unavailable." msgstr "" -#: fn/auth.php:161 +#: fn/auth.php:163 msgid "Account rate limit reached, try again later." msgstr "" -#: fn/auth.php:186 +#: fn/auth.php:188 msgid "Global rate limit reached, try again later." msgstr "" @@ -353,24 +362,24 @@ msgstr "" msgid "Server error: " msgstr "" -#: fn/common.php:137 +#: fn/common.php:155 msgid "Wrong proof." msgstr "" -#: fn/dns.php:74 +#: fn/dns.php:77 msgid "IP address malformed." msgstr "" -#: fn/dns.php:79 fn/ht.php:48 +#: fn/dns.php:82 fn/ht.php:48 msgid "Domain malformed." msgstr "" -#: fn/ns.php:31 pg-act/ns/edit.php:25 +#: fn/ns.php:33 pg-act/ns/edit.php:25 #, php-format msgid "TTLs shorter than %s seconds are forbidden." msgstr "" -#: fn/ns.php:33 pg-act/ns/edit.php:27 +#: fn/ns.php:35 pg-act/ns/edit.php:27 #, php-format msgid "TTLs longer than %s seconds are forbidden." msgstr "" @@ -511,6 +520,14 @@ msgstr "" msgid "Sent zone content is not correct (according to kzonecheck)." msgstr "" +#: pg-act/ns/sync.php:19 +msgid "Multiple source domains can't be applied to the same target domain." +msgstr "" + +#: pg-act/ns/sync.php:41 +msgid "Synchronized records updated." +msgstr "" + #: pg-act/ns/zone-add.php:6 msgid "This zone already exists on the service." msgstr "" @@ -870,7 +887,7 @@ msgstr "" msgid "Allowed directory" msgstr "" -#: pg-view/ht/keys.php:30 +#: pg-view/ht/keys.php:30 pg-view/ns/sync.php:37 msgid "Update" msgstr "" @@ -1121,6 +1138,35 @@ msgstr "" msgid "Fingerprint" msgstr "" +#: pg-view/ns/sync.php:2 +#, php-format +msgid "AAAA, A and CAA records are regularly copied from the source domain to the target domain. Their TTLs are set to %s seconds." +msgstr "" + +#: pg-view/ns/sync.php:5 +msgid "Source domains that are not signed with DNSSEC are not synchronized. Synchronizations that remain broken may be deleted." +msgstr "" + +#: pg-view/ns/sync.php:8 +msgid "This is meant to be used for apex domains, where CNAME records are not allowed. For non-apex domains, CNAME records should be used instead." +msgstr "" + +#: pg-view/ns/sync.php:16 +msgid "Add new domain records to be synchronized" +msgstr "" + +#: pg-view/ns/sync.php:16 +msgid "Synchronized domain" +msgstr "" + +#: pg-view/ns/sync.php:18 +msgid "Source domain" +msgstr "" + +#: pg-view/ns/sync.php:22 +msgid "Target domain" +msgstr "" + #: pg-view/ns/tlsa.php:4 msgid "Use" msgstr "" diff --git a/pages.php b/pages.php index ebbc4ac..fadb435 100644 --- a/pages.php +++ b/pages.php @@ -165,7 +165,7 @@ define('PAGES', [ ], 'sync' => [ 'title' => sprintf(_('Synchronized records')), - 'description' => _('Regularly fetch distant record value and update it to a local zone'), + 'description' => _('Regularly fetch distant records and update them to a local zone'), 'tokens_account_cost' => 900, ], ], diff --git a/pg-act/ns/sync.php b/pg-act/ns/sync.php index 9275678..9160350 100644 --- a/pg-act/ns/sync.php +++ b/pg-act/ns/sync.php @@ -4,7 +4,7 @@ $el_nb = count($_POST['syncs']); if ($el_nb < 1 OR $el_nb > 8) output(403, 'Wrong elements number.'); -foreach ($_POST['syncs'] as $i => &$sync) { +foreach ($_POST['syncs'] as $i => $sync) { if (($sync['source'] ?? '') === '') { unset($_POST['syncs'][$i]); continue; @@ -14,6 +14,10 @@ foreach ($_POST['syncs'] as $i => &$sync) { } $syncs = array_values($_POST['syncs']); +$destinations = array_column($syncs, 'destination'); +if (count($destinations) !== count(array_unique($destinations))) + output(403, _('Multiple source domains can\'t be applied to the same target domain.')); + rateLimit(); try { diff --git a/pg-view/ns/sync.php b/pg-view/ns/sync.php index 740ba10..2e52645 100644 --- a/pg-view/ns/sync.php +++ b/pg-view/ns/sync.php @@ -5,7 +5,7 @@

- +

@@ -13,7 +13,7 @@ foreach (array_slice(array_merge(query('select', 'ns-syncs', ['username' => $_SESSION['id'] ?? '']), [['source' => '', 'destination' => '—']]), 0, 8) as $i => $sync) { ?>
- +

@@ -24,7 +24,7 @@ foreach (array_slice(array_merge(query('select', 'ns-syncs', ['username' => $_SE