From 46002b1505ef2f68942437194c41c76499727a9f Mon Sep 17 00:00:00 2001 From: Pinga Date: Wed, 21 May 2025 11:46:31 +0300 Subject: [PATCH] Added registrar tech contact; improvements to view registrar --- cp/app/Controllers/RegistrarsController.php | 91 +++++- .../views/admin/registrars/create.twig | 65 ++++- .../admin/registrars/updateRegistrar.twig | 69 ++++- .../admin/registrars/updateRegistrarUser.twig | 69 ++++- .../views/admin/registrars/viewRegistrar.twig | 258 ++++++++++++++++++ 5 files changed, 544 insertions(+), 8 deletions(-) diff --git a/cp/app/Controllers/RegistrarsController.php b/cp/app/Controllers/RegistrarsController.php index cae3eb6..65cc564 100644 --- a/cp/app/Controllers/RegistrarsController.php +++ b/cp/app/Controllers/RegistrarsController.php @@ -47,6 +47,7 @@ class RegistrarsController extends Controller $data['owner']['cc'] = strtoupper($data['owner']['cc']); $data['billing']['cc'] = strtoupper($data['billing']['cc']); + $data['tech']['cc'] = strtoupper($data['tech']['cc']); $data['abuse']['cc'] = strtoupper($data['abuse']['cc']); $phoneValidator = v::regex('/^\+\d{1,3}\.\d{2,12}$/'); @@ -73,9 +74,13 @@ class RegistrarsController extends Controller 'email' => v::email(), 'owner' => v::optional(v::keySet(...$contactValidator)), 'billing' => v::optional(v::keySet(...$contactValidator)), + 'tech' => v::optional(v::keySet(...$contactValidator)), 'abuse' => v::optional(v::keySet(...$contactValidator)), 'whoisServer' => v::domain(false), - 'rdapServer' => v::domain(false), + 'rdapServer' => v::oneOf( + v::domain(false), + v::url()->startsWith('http') + ), 'url' => v::url(), 'abuseEmail' => v::email(), 'abusePhone' => v::optional($phoneValidator), @@ -219,6 +224,24 @@ class RegistrarsController extends Controller ] ); + $db->insert( + 'registrar_contact', + [ + 'registrar_id' => $registrar_id, + 'type' => 'tech', + 'first_name' => $data['tech']['first_name'], + 'last_name' => $data['tech']['last_name'], + 'org' => $data['tech']['org'], + 'street1' => $data['tech']['street1'], + 'city' => $data['tech']['city'], + 'sp' => $data['tech']['sp'], + 'pc' => $data['tech']['pc'], + 'cc' => strtolower($data['tech']['cc']), + 'voice' => $data['tech']['voice'], + 'email' => $data['tech']['email'] + ] + ); + $db->insert( 'registrar_contact', [ @@ -332,6 +355,8 @@ class RegistrarsController extends Controller $db = $this->container->get('db'); // Get the current URI $uri = $request->getUri()->getPath(); + $iso3166 = new ISO3166(); + $countries = $iso3166->all(); if ($args) { $args = trim(preg_replace('/\s+/', ' ', $args)); @@ -359,7 +384,7 @@ class RegistrarsController extends Controller } } - $registrarContact = $db->selectRow('SELECT * FROM registrar_contact WHERE registrar_id = ?', + $contacts = $db->select('SELECT * FROM registrar_contact WHERE registrar_id = ?', [ $registrar['id'] ]); $registrarOte = $db->select('SELECT * FROM registrar_ote WHERE registrar_id = ? ORDER by command', [ $registrar['id'] ]); @@ -392,9 +417,15 @@ class RegistrarsController extends Controller // Check if the user is not an admin $role = $_SESSION['auth_roles'] ?? null; + $countriesAssoc = []; + foreach ($countries as $country) { + $countriesAssoc[strtoupper($country['alpha2'])] = $country['name']; + } + return view($response,'admin/registrars/viewRegistrar.twig', [ 'registrar' => $registrar, - 'registrarContact' => $registrarContact, + 'contacts' => $contacts, + 'countries' => $countriesAssoc, 'firstHalf' => $firstHalf, 'secondHalf' => $secondHalf, 'userEmail' => $userEmail, @@ -664,6 +695,7 @@ class RegistrarsController extends Controller $data['owner']['cc'] = strtoupper($data['owner']['cc']); $data['billing']['cc'] = strtoupper($data['billing']['cc']); + $data['tech']['cc'] = strtoupper($data['tech']['cc']); $data['abuse']['cc'] = strtoupper($data['abuse']['cc']); $phoneValidator = v::regex('/^\+\d{1,3}\.\d{2,12}$/'); @@ -690,9 +722,13 @@ class RegistrarsController extends Controller 'email' => v::email(), 'owner' => v::optional(v::keySet(...$contactValidator)), 'billing' => v::optional(v::keySet(...$contactValidator)), + 'tech' => v::optional(v::keySet(...$contactValidator)), 'abuse' => v::optional(v::keySet(...$contactValidator)), 'whoisServer' => v::domain(false), - 'rdapServer' => v::domain(false), + 'rdapServer' => v::oneOf( + v::domain(false), + v::url()->startsWith('http') + ), 'url' => v::url(), 'abuseEmail' => v::email(), 'abusePhone' => v::optional($phoneValidator), @@ -828,6 +864,26 @@ class RegistrarsController extends Controller ] ); + $db->update( + 'registrar_contact', + [ + 'first_name' => $data['tech']['first_name'], + 'last_name' => $data['tech']['last_name'], + 'org' => $data['tech']['org'], + 'street1' => $data['tech']['street1'], + 'city' => $data['tech']['city'], + 'sp' => $data['tech']['sp'], + 'pc' => $data['tech']['pc'], + 'cc' => strtolower($data['tech']['cc']), + 'voice' => $data['tech']['voice'], + 'email' => $data['tech']['email'] + ], + [ + 'registrar_id' => $registrar_id, + 'type' => 'tech' + ] + ); + $db->update( 'registrar_contact', [ @@ -926,6 +982,7 @@ class RegistrarsController extends Controller $data['owner']['cc'] = strtoupper($data['owner']['cc']); $data['billing']['cc'] = strtoupper($data['billing']['cc']); + $data['tech']['cc'] = strtoupper($data['tech']['cc']); $data['abuse']['cc'] = strtoupper($data['abuse']['cc']); $phoneValidator = v::regex('/^\+\d{1,3}\.\d{2,12}$/'); @@ -951,9 +1008,13 @@ class RegistrarsController extends Controller 'email' => v::email(), 'owner' => v::optional(v::keySet(...$contactValidator)), 'billing' => v::optional(v::keySet(...$contactValidator)), + 'tech' => v::optional(v::keySet(...$contactValidator)), 'abuse' => v::optional(v::keySet(...$contactValidator)), 'whoisServer' => v::domain(false), - 'rdapServer' => v::domain(false), + 'rdapServer' => v::oneOf( + v::domain(false), + v::url()->startsWith('http') + ), 'url' => v::url(), 'abuseEmail' => v::email(), 'abusePhone' => v::optional($phoneValidator), @@ -1079,6 +1140,26 @@ class RegistrarsController extends Controller ] ); + $db->update( + 'registrar_contact', + [ + 'first_name' => $data['tech']['first_name'], + 'last_name' => $data['tech']['last_name'], + 'org' => $data['tech']['org'], + 'street1' => $data['tech']['street1'], + 'city' => $data['tech']['city'], + 'sp' => $data['tech']['sp'], + 'pc' => $data['tech']['pc'], + 'cc' => strtolower($data['tech']['cc']), + 'voice' => $data['tech']['voice'], + 'email' => $data['tech']['email'] + ], + [ + 'registrar_id' => $registrar_id, + 'type' => 'tech' + ] + ); + $db->update( 'registrar_contact', [ diff --git a/cp/resources/views/admin/registrars/create.twig b/cp/resources/views/admin/registrars/create.twig index f1de881..ee50456 100644 --- a/cp/resources/views/admin/registrars/create.twig +++ b/cp/resources/views/admin/registrars/create.twig @@ -172,6 +172,9 @@ + @@ -301,6 +304,65 @@ + + +
+
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
@@ -545,10 +607,11 @@ document.addEventListener('DOMContentLoaded', function() { copyCheckbox.addEventListener('change', function() { if (this.checked) { copyDataToTab('#billing'); + copyDataToTab('#tech'); copyDataToTab('#abuse'); } else { // Clear fields when unchecked, if desired - ['#billing', '#abuse'].forEach(tabId => { + ['#billing', '#tech', '#abuse'].forEach(tabId => { const fields = document.querySelectorAll(`${tabId} input:not([type='checkbox']), ${tabId} select`); fields.forEach(field => { field.value = ''; diff --git a/cp/resources/views/admin/registrars/updateRegistrar.twig b/cp/resources/views/admin/registrars/updateRegistrar.twig index 8cdac2a..e0f23dc 100644 --- a/cp/resources/views/admin/registrars/updateRegistrar.twig +++ b/cp/resources/views/admin/registrars/updateRegistrar.twig @@ -169,6 +169,9 @@ + @@ -306,6 +309,69 @@
+ + +
+
+
+ {% for contact in contacts %} + {% if contact.type == 'tech' %} + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ {% endif %} + {% endfor %} +
+
+
@@ -600,10 +666,11 @@ document.addEventListener('DOMContentLoaded', function() { copyCheckbox.addEventListener('change', function() { if (this.checked) { copyDataToTab('#billing'); + copyDataToTab('#tech'); copyDataToTab('#abuse'); } else { // Clear fields when unchecked, if desired - ['#billing', '#abuse'].forEach(tabId => { + ['#billing', '#tech', '#abuse'].forEach(tabId => { const fields = document.querySelectorAll(`${tabId} input:not([type='checkbox']), ${tabId} select`); fields.forEach(field => { field.value = ''; diff --git a/cp/resources/views/admin/registrars/updateRegistrarUser.twig b/cp/resources/views/admin/registrars/updateRegistrarUser.twig index eb4f5a2..0727d02 100644 --- a/cp/resources/views/admin/registrars/updateRegistrarUser.twig +++ b/cp/resources/views/admin/registrars/updateRegistrarUser.twig @@ -151,6 +151,9 @@ + @@ -289,6 +292,69 @@
+ +
+
+
+ {% for contact in contacts %} + {% if contact.type == 'tech' %} + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ {% endif %} + {% endfor %} +
+
+
+
@@ -560,10 +626,11 @@ document.addEventListener('DOMContentLoaded', function() { copyCheckbox.addEventListener('change', function() { if (this.checked) { copyDataToTab('#billing'); + copyDataToTab('#tech'); copyDataToTab('#abuse'); } else { // Clear fields when unchecked, if desired - ['#billing', '#abuse'].forEach(tabId => { + ['#billing', '#tech', '#abuse'].forEach(tabId => { const fields = document.querySelectorAll(`${tabId} input:not([type='checkbox']), ${tabId} select`); fields.forEach(field => { field.value = ''; diff --git a/cp/resources/views/admin/registrars/viewRegistrar.twig b/cp/resources/views/admin/registrars/viewRegistrar.twig index e3e920e..b138557 100644 --- a/cp/resources/views/admin/registrars/viewRegistrar.twig +++ b/cp/resources/views/admin/registrars/viewRegistrar.twig @@ -121,6 +121,264 @@
+
+
+
{{ __('Registrar Contacts') }}
+ + +
+ +
+
+
+ {% for contact in contacts %} + {% if contact.type == 'owner' %} + +
+
+ +
{{ contact.first_name }}
+
+
+ +
{{ contact.last_name }}
+
+
+ +
{{ contact.org }}
+
+
+ +
{{ contact.street1 }}
+
+
+ +
{{ contact.city }}
+
+
+ + +
+
+ +
{{ contact.sp }}
+
+
+ +
{{ contact.pc }}
+
+
+ +
{{ countries[contact.cc|upper] }}
+
+
+ +
{{ contact.voice }}
+
+
+ +
{{ contact.email }}
+
+
+ {% endif %} + {% endfor %} +
+
+
+ + +
+
+
+ {% for contact in contacts %} + {% if contact.type == 'billing' %} + +
+
+ +
{{ contact.first_name }}
+
+
+ +
{{ contact.last_name }}
+
+
+ +
{{ contact.org }}
+
+
+ +
{{ contact.street1 }}
+
+
+ +
{{ contact.city }}
+
+
+ + +
+
+ +
{{ contact.sp }}
+
+
+ +
{{ contact.pc }}
+
+
+ +
{{ countries[contact.cc|upper] }}
+
+
+ +
{{ contact.voice }}
+
+
+ +
{{ contact.email }}
+
+
+ {% endif %} + {% endfor %} +
+
+
+ + +
+
+
+ {% for contact in contacts %} + {% if contact.type == 'tech' %} + +
+
+ +
{{ contact.first_name }}
+
+
+ +
{{ contact.last_name }}
+
+
+ +
{{ contact.org }}
+
+
+ +
{{ contact.street1 }}
+
+
+ +
{{ contact.city }}
+
+
+ + +
+
+ +
{{ contact.sp }}
+
+
+ +
{{ contact.pc }}
+
+
+ +
{{ countries[contact.cc|upper] }}
+
+
+ +
{{ contact.voice }}
+
+
+ +
{{ contact.email }}
+
+
+ {% endif %} + {% endfor %} +
+
+
+ + +
+
+
+ {% for contact in contacts %} + {% if contact.type == 'abuse' %} + +
+
+ +
{{ contact.first_name }}
+
+
+ +
{{ contact.last_name }}
+
+
+ +
{{ contact.org }}
+
+
+ +
{{ contact.street1 }}
+
+
+ +
{{ contact.city }}
+
+
+ + +
+
+ +
{{ contact.sp }}
+
+
+ +
{{ contact.pc }}
+
+
+ +
{{ countries[contact.cc|upper] }}
+
+
+ +
{{ contact.voice }}
+
+
+ +
{{ contact.email }}
+
+
+ {% endif %} + {% endfor %} +
+
+
+
+
+