Added reserved names management

This commit is contained in:
Pinga 2023-12-11 15:53:12 +02:00
parent 7939db2c4c
commit 15618d44d3
5 changed files with 168 additions and 8 deletions

View file

@ -800,4 +800,90 @@ class SystemController extends Controller
} }
public function manageReserved(Request $request, Response $response)
{
if ($_SESSION["auth_roles"] != 0) {
return $response->withHeader('Location', '/dashboard')->withStatus(302);
}
if ($request->getMethod() === 'POST') {
// Retrieve POST data
$data = $request->getParsedBody();
$db = $this->container->get('db');
$domainCategories = [];
foreach ($data as $key => $value) {
if (strpos($key, 'domains_') === 0) { // Check if the key starts with 'domains_'
$domains = explode("\n", trim($value));
$domains = array_filter(array_map('trim', $domains));
$domainCategories[substr($key, 8)] = $domains;
}
}
try {
// Fetch existing names
$existingDomains = $db->select('SELECT name, type FROM reserved_domain_names');
// Organize existing names by type
$existingByType = [];
foreach ($existingDomains as $domain) {
$existingByType[$domain['type']][] = $domain['name'];
}
$db->beginTransaction();
foreach ($domainCategories as $type => $submittedDomains) {
// Find domains to delete
$domainsToDelete = array_diff($existingByType[$type] ?? [], $submittedDomains);
// Delete domains not in the submitted list
foreach ($domainsToDelete as $domain) {
$db->exec(
"DELETE FROM reserved_domain_names WHERE name = ? AND type = ?",
[$domain, $type]
);
}
// Insert or ignore new domains
foreach ($submittedDomains as $domain) {
$db->exec(
"INSERT IGNORE INTO reserved_domain_names (name, type) VALUES (?, ?)",
[$domain, $type]
);
}
}
$db->commit();
} catch (Exception $e) {
$db->rollBack();
$this->container->get('flash')->addMessage('error', 'Database failure: ' . $e->getMessage());
return $response->withHeader('Location', '/registry/reserved')->withStatus(302);
}
$this->container->get('flash')->addMessage('success', 'Reserved names have been updated successfully');
return $response->withHeader('Location', '/registry/reserved')->withStatus(302);
}
$db = $this->container->get('db');
$types = $db->select("SELECT DISTINCT type FROM reserved_domain_names");
// Get the current URI
$uri = $request->getUri()->getPath();
$categories = [];
foreach ($types as $type) {
$typeNames = $db->select(
'SELECT name FROM reserved_domain_names WHERE type = ?',
[ $type['type'] ]
);
$categories[$type['type']] = array_column($typeNames, 'name');
}
return view($response,'admin/system/manageReserved.twig', [
'categories' => $categories,
'currentUri' => $uri
]);
}
} }

View file

@ -21,7 +21,7 @@
<div class="col-auto ms-auto d-print-none"> <div class="col-auto ms-auto d-print-none">
<div class="btn-list"> <div class="btn-list">
<span class="d-none d-sm-inline"> <span class="d-none d-sm-inline">
<a href="{{route('checkDomain')}}" class="btn btn-secondary"> <a href="{{route('manageReserved')}}" class="btn btn-secondary">
{{ __('Manage Reserved Names') }} {{ __('Manage Reserved Names') }}
</a> </a>
</span> </span>

View file

@ -0,0 +1,74 @@
{% extends "layouts/app.twig" %}
{% block title %}{{ __('Managed Reserved Names') }}{% endblock %}
{% block content %}
<div class="page-wrapper">
<!-- Page header -->
<div class="page-header d-print-none">
<div class="container-xl">
<div class="row g-2 align-items-center">
<div class="col">
<!-- Page pre-title -->
<div class="page-pretitle">
{{ __('Overview') }}
</div>
<h2 class="page-title">
{{ __('Managed Reserved Names') }}
</h2>
</div>
</div>
</div>
</div>
<!-- Page body -->
<div class="page-body">
<div class="container-xl">
<div class="col-12">
{% include 'partials/flash.twig' %}
<div class="card">
<form action="/registry/reserved" method="post">
{{ csrf.field | raw }}
<div class="card-header">
<h4 class="card-title">Manage Reserved Names</h4>
</div>
<div class="card-body">
{% for type, names in categories %}
<div class="card mb-3">
<div class="card-header">{{ type|capitalize }} Names</div>
<div class="card-body">
<textarea class="form-control" name="domains_{{ type }}" rows="4" placeholder="Enter domain names, one per line" required>{{ names|join('\n') }}</textarea>
<small class="form-hint">
<strong>{{ type|capitalize }} Names:</strong> These domain names are subject to special regulations or registration requirements. They might be available for registration but under specific conditions, such as proof of eligibility or additional documentation.
<br><em>Enter each {{ type }} name on a new line, without the extension. For instance, use "example" in place of "example.com".</em>
</small>
</div>
</div>
{% endfor %}
</div>
<div class="card-footer">
<div class="row align-items-center">
<div class="col-auto">
<button type="submit" class="btn btn-primary">Update Reserved Names</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<footer class="footer footer-transparent d-print-none">
<div class="container-xl">
<div class="col-12 col-lg-auto mt-3 mt-lg-0">
<ul class="list-inline list-inline-dots mb-0">
<li class="list-inline-item">
Copyright &copy; 2023
<a href="https://namingo.org" target="_blank" class="link-secondary">Namingo</a>.
</li>
</ul>
</div>
</div>
</div>
</footer>
</div>
{% endblock %}

View file

@ -34,19 +34,19 @@
<div class="mb-3"> <div class="mb-3">
<label for="registryOperator" class="form-label required">Registry Operator Name</label> <label for="registryOperator" class="form-label required">Registry Operator Name</label>
<input type="text" class="form-control" id="registryOperator" name="registryOperator" placeholder="Enter registry operator's name" value="{{ company_name }}" required> <input type="text" class="form-control" id="registryOperator" name="registryOperator" placeholder="Enter registry operator's name" value="{{ company_name }}" required>
<div class="form-text">The official name of the organization operating the registry.</div> <small class="form-hint">The official name of the organization operating the registry.</small>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="contactAddress" class="form-label required">Contact Address</label> <label for="contactAddress" class="form-label required">Contact Address</label>
<input type="text" class="form-control" id="contactAddress" name="contactAddress" placeholder="Enter contact address" value="{{ address }}" required> <input type="text" class="form-control" id="contactAddress" name="contactAddress" placeholder="Enter contact address" value="{{ address }}" required>
<div class="form-text">The contact address of the registry.</div> <small class="form-hint">The contact address of the registry.</small>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="contactAddress2" class="form-label required">Contact Address (Line 2)</label> <label for="contactAddress2" class="form-label required">Contact Address (Line 2)</label>
<input type="text" class="form-control" id="contactAddress2" name="contactAddress2" placeholder="Enter contact address" value="{{ address2 }}" required> <input type="text" class="form-control" id="contactAddress2" name="contactAddress2" placeholder="Enter contact address" value="{{ address2 }}" required>
<div class="form-text">The contact address of the registry. (Line 2)</div> <small class="form-hint">The contact address of the registry. (Line 2)</small>
</div> </div>
</div> </div>
@ -55,19 +55,19 @@
<div class="mb-3"> <div class="mb-3">
<label for="contactEmail" class="form-label required">Contact Email</label> <label for="contactEmail" class="form-label required">Contact Email</label>
<input type="email" class="form-control" id="contactEmail" name="contactEmail" placeholder="Enter contact email" value="{{ email }}" required> <input type="email" class="form-control" id="contactEmail" name="contactEmail" placeholder="Enter contact email" value="{{ email }}" required>
<div class="form-text">The email address for general inquiries to the registry.</div> <small class="form-hint">The email address for general inquiries to the registry.</small>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="contactPhone" class="form-label required">Contact Phone</label> <label for="contactPhone" class="form-label required">Contact Phone</label>
<input type="tel" class="form-control" id="contactPhone" name="contactPhone" placeholder="Enter contact phone" value="{{ phone }}" required> <input type="tel" class="form-control" id="contactPhone" name="contactPhone" placeholder="Enter contact phone" value="{{ phone }}" required>
<div class="form-text">The phone number for general inquiries to the registry.</div> <small class="form-hint">The phone number for general inquiries to the registry.</small>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="registryHandle" class="form-label required">Registry Handle</label> <label for="registryHandle" class="form-label required">Registry Handle</label>
<input type="text" class="form-control" id="registryHandle" name="registryHandle" placeholder="Enter registry handle" value="{{ handle }}" required> <input type="text" class="form-control" id="registryHandle" name="registryHandle" placeholder="Enter registry handle" value="{{ handle }}" required>
<div class="form-text">A unique identifier for the registry which will be appended to each object handle.</div> <small class="form-hint">A unique identifier for the registry which will be appended to each object handle.</small>
</div> </div>
</div> </div>

View file

@ -189,7 +189,7 @@
</a> </a>
</div> </div>
</li> </li>
<li {{ is_current_url('epphistory') or is_current_url('poll') or is_current_url('log') or is_current_url('registry') or is_current_url('reports') or is_current_url('listTlds') or is_current_url('createTld') or 'tld' in currentUri ? 'class="nav-item dropdown active"' : 'class="nav-item dropdown"' }}> <li {{ is_current_url('epphistory') or is_current_url('poll') or is_current_url('log') or is_current_url('registry') or is_current_url('reports') or is_current_url('listTlds') or is_current_url('createTld') or 'tld' in currentUri or 'reserved' in currentUri ? 'class="nav-item dropdown active"' : 'class="nav-item dropdown"' }}>
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" data-bs-auto-close="outside" role="button" aria-expanded="false"> <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" data-bs-auto-close="outside" role="button" aria-expanded="false">
<span class="nav-link-icon d-md-none d-lg-inline-block"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"></path> <path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"></path></svg> <span class="nav-link-icon d-md-none d-lg-inline-block"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"></path> <path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"></path></svg>
</span> </span>