mirror of
https://github.com/getnamingo/registry.git
synced 2025-07-27 04:48:26 +02:00
Added registrar create functionality
This commit is contained in:
parent
37637714bd
commit
8b74720d33
4 changed files with 327 additions and 71 deletions
|
@ -7,6 +7,7 @@ use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
use League\ISO3166\ISO3166;
|
use League\ISO3166\ISO3166;
|
||||||
|
use Respect\Validation\Validator as v;
|
||||||
|
|
||||||
class RegistrarsController extends Controller
|
class RegistrarsController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -25,9 +26,261 @@ class RegistrarsController extends Controller
|
||||||
// Retrieve POST data
|
// Retrieve POST data
|
||||||
$data = $request->getParsedBody();
|
$data = $request->getParsedBody();
|
||||||
$db = $this->container->get('db');
|
$db = $this->container->get('db');
|
||||||
|
$iso3166 = new ISO3166();
|
||||||
|
$countries = $iso3166->all();
|
||||||
|
|
||||||
var_dump ($data);
|
$ipAddressValidator = v::when(
|
||||||
die();
|
v::arrayType()->notEmpty(), // Condition: If it's a non-empty array
|
||||||
|
v::arrayType()->each(v::ip()), // Then: Each element must be a valid IP address
|
||||||
|
v::equals('') // Else: Allow it to be an empty string
|
||||||
|
);
|
||||||
|
|
||||||
|
$data['owner']['cc'] = strtoupper($data['owner']['cc']);
|
||||||
|
$data['billing']['cc'] = strtoupper($data['billing']['cc']);
|
||||||
|
$data['abuse']['cc'] = strtoupper($data['abuse']['cc']);
|
||||||
|
|
||||||
|
$phoneValidator = v::regex('/^\+\d{1,3}\.\d{2,12}$/');
|
||||||
|
|
||||||
|
// Define validation for nested fields
|
||||||
|
$contactValidator = [
|
||||||
|
v::key('first_name', v::stringType()->notEmpty()->length(1, 255), true),
|
||||||
|
v::key('last_name', v::stringType()->notEmpty()->length(1, 255), true),
|
||||||
|
v::key('org', v::optional(v::stringType()->length(1, 255)), false),
|
||||||
|
v::key('street1', v::optional(v::stringType()), false),
|
||||||
|
v::key('city', v::stringType()->notEmpty(), true),
|
||||||
|
v::key('sp', v::optional(v::stringType()), false),
|
||||||
|
v::key('pc', v::optional(v::stringType()), false),
|
||||||
|
v::key('cc', v::countryCode(), true),
|
||||||
|
v::key('voice', v::optional($phoneValidator), false),
|
||||||
|
v::key('fax', v::optional(v::phone()), false),
|
||||||
|
v::key('email', v::email(), true)
|
||||||
|
];
|
||||||
|
|
||||||
|
$validators = [
|
||||||
|
'name' => v::stringType()->notEmpty()->length(1, 255),
|
||||||
|
'ianaId' => v::optional(v::positive()->length(1, 5)),
|
||||||
|
'email' => v::email(),
|
||||||
|
'owner' => v::optional(v::keySet(...$contactValidator)),
|
||||||
|
'billing' => v::optional(v::keySet(...$contactValidator)),
|
||||||
|
'abuse' => v::optional(v::keySet(...$contactValidator)),
|
||||||
|
'whoisServer' => v::domain(),
|
||||||
|
'rdapServer' => v::domain(),
|
||||||
|
'url' => v::url(),
|
||||||
|
'abuseEmail' => v::email(),
|
||||||
|
'abusePhone' => v::optional($phoneValidator),
|
||||||
|
'accountBalance' => v::numericVal(),
|
||||||
|
'creditLimit' => v::numericVal(),
|
||||||
|
'creditThreshold' => v::numericVal(),
|
||||||
|
'thresholdType' => v::in(['fixed', 'percent']),
|
||||||
|
'ipAddress' => v::optional($ipAddressValidator),
|
||||||
|
'user_name' => v::stringType()->notEmpty()->length(1, 255),
|
||||||
|
'user_email' => v::email(),
|
||||||
|
'eppPassword' => v::stringType()->notEmpty(),
|
||||||
|
'panelPassword' => v::stringType()->notEmpty(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$errors = [];
|
||||||
|
foreach ($validators as $field => $validator) {
|
||||||
|
try {
|
||||||
|
$validator->assert(isset($data[$field]) ? $data[$field] : []);
|
||||||
|
} catch (\Respect\Validation\Exceptions\NestedValidationException $e) {
|
||||||
|
$errors[$field] = $e->getMessages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($errors)) {
|
||||||
|
// Handle errors
|
||||||
|
$errorText = '';
|
||||||
|
|
||||||
|
foreach ($errors as $field => $messages) {
|
||||||
|
$errorText .= ucfirst($field) . ' errors: ' . implode(', ', $messages) . '; ';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim the final semicolon and space
|
||||||
|
$errorText = rtrim($errorText, '; ');
|
||||||
|
|
||||||
|
return view($response, 'admin/registrars/create.twig', [
|
||||||
|
'countries' => $countries,
|
||||||
|
'error' => $errorText,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$currentDateTime = new \DateTime();
|
||||||
|
$crdate = $currentDateTime->format('Y-m-d H:i:s.v');
|
||||||
|
$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
$randomPrefix = '';
|
||||||
|
for ($i = 0; $i < 2; $i++) {
|
||||||
|
$randomPrefix .= $characters[rand(0, strlen($characters) - 1)];
|
||||||
|
}
|
||||||
|
$currency = $_SESSION['_currency'] ?? 'USD';
|
||||||
|
$eppPassword = password_hash($data['eppPassword'], PASSWORD_ARGON2ID, ['memory_cost' => 2048, 'time_cost' => 4, 'threads' => 4]);
|
||||||
|
|
||||||
|
if (empty($data['ianaId']) || !is_numeric($data['ianaId'])) {
|
||||||
|
$data['ianaId'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->insert(
|
||||||
|
'registrar',
|
||||||
|
[
|
||||||
|
'name' => $data['name'],
|
||||||
|
'iana_id' => $data['ianaId'],
|
||||||
|
'clid' => $data['user_name'],
|
||||||
|
'pw' => $eppPassword,
|
||||||
|
'prefix' => $randomPrefix,
|
||||||
|
'email' => $data['email'],
|
||||||
|
'url' => $data['url'],
|
||||||
|
'whois_server' => $data['whoisServer'],
|
||||||
|
'rdap_server' => $data['rdapServer'],
|
||||||
|
'abuse_email' => $data['abuseEmail'],
|
||||||
|
'abuse_phone' => $data['abusePhone'],
|
||||||
|
'accountBalance' => $data['accountBalance'],
|
||||||
|
'creditLimit' => $data['creditLimit'],
|
||||||
|
'creditThreshold' => $data['creditThreshold'],
|
||||||
|
'thresholdType' => $data['thresholdType'],
|
||||||
|
'currency' => $currency,
|
||||||
|
'crdate' => $crdate,
|
||||||
|
'update' => $crdate
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$registrar_id = $db->getLastInsertId();
|
||||||
|
|
||||||
|
$db->exec(
|
||||||
|
'UPDATE registrar SET prefix = ? WHERE id = ?',
|
||||||
|
[
|
||||||
|
'R'.$registrar_id,
|
||||||
|
$registrar_id
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$db->insert(
|
||||||
|
'registrar_contact',
|
||||||
|
[
|
||||||
|
'registrar_id' => $registrar_id,
|
||||||
|
'type' => 'owner',
|
||||||
|
'first_name' => $data['owner']['first_name'],
|
||||||
|
'last_name' => $data['owner']['last_name'],
|
||||||
|
'org' => $data['owner']['org'],
|
||||||
|
'street1' => $data['owner']['street1'],
|
||||||
|
'city' => $data['owner']['city'],
|
||||||
|
'sp' => $data['owner']['sp'],
|
||||||
|
'pc' => $data['owner']['pc'],
|
||||||
|
'cc' => strtolower($data['owner']['cc']),
|
||||||
|
'voice' => $data['owner']['voice'],
|
||||||
|
'email' => $data['owner']['email']
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$db->insert(
|
||||||
|
'registrar_contact',
|
||||||
|
[
|
||||||
|
'registrar_id' => $registrar_id,
|
||||||
|
'type' => 'billing',
|
||||||
|
'first_name' => $data['billing']['first_name'],
|
||||||
|
'last_name' => $data['billing']['last_name'],
|
||||||
|
'org' => $data['billing']['org'],
|
||||||
|
'street1' => $data['billing']['street1'],
|
||||||
|
'city' => $data['billing']['city'],
|
||||||
|
'sp' => $data['billing']['sp'],
|
||||||
|
'pc' => $data['billing']['pc'],
|
||||||
|
'cc' => strtolower($data['billing']['cc']),
|
||||||
|
'voice' => $data['billing']['voice'],
|
||||||
|
'email' => $data['billing']['email']
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$db->insert(
|
||||||
|
'registrar_contact',
|
||||||
|
[
|
||||||
|
'registrar_id' => $registrar_id,
|
||||||
|
'type' => 'abuse',
|
||||||
|
'first_name' => $data['abuse']['first_name'],
|
||||||
|
'last_name' => $data['abuse']['last_name'],
|
||||||
|
'org' => $data['abuse']['org'],
|
||||||
|
'street1' => $data['abuse']['street1'],
|
||||||
|
'city' => $data['abuse']['city'],
|
||||||
|
'sp' => $data['abuse']['sp'],
|
||||||
|
'pc' => $data['abuse']['pc'],
|
||||||
|
'cc' => strtolower($data['abuse']['cc']),
|
||||||
|
'voice' => $data['abuse']['voice'],
|
||||||
|
'email' => $data['abuse']['email']
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!empty($data['ipAddress'])) {
|
||||||
|
foreach ($data['ipAddress'] as $ip) {
|
||||||
|
$db->insert(
|
||||||
|
'registrar_whitelist',
|
||||||
|
[
|
||||||
|
'registrar_id' => $registrar_id,
|
||||||
|
'addr' => $ip
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$panelPassword = password_hash($data['panelPassword'], PASSWORD_ARGON2ID, ['memory_cost' => 2048, 'time_cost' => 4, 'threads' => 4]);
|
||||||
|
|
||||||
|
$db->insert(
|
||||||
|
'users',
|
||||||
|
[
|
||||||
|
'email' => $data['user_email'],
|
||||||
|
'password' => $panelPassword,
|
||||||
|
'username' => $data['user_name'],
|
||||||
|
'verified' => 1,
|
||||||
|
'roles_mask' => 4,
|
||||||
|
'registered' => \time()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$user_id = $db->getLastInsertId();
|
||||||
|
|
||||||
|
$db->insert(
|
||||||
|
'registrar_users',
|
||||||
|
[
|
||||||
|
'registrar_id' => $registrar_id,
|
||||||
|
'user_id' => $user_id
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$eppCommands = [
|
||||||
|
'contact:create',
|
||||||
|
'domain:check',
|
||||||
|
'domain:info',
|
||||||
|
'domain:renew',
|
||||||
|
'domain:transfer',
|
||||||
|
'host:create',
|
||||||
|
'host:info',
|
||||||
|
'contact:update',
|
||||||
|
'domain:delete',
|
||||||
|
'poll:request'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($eppCommands as $command) {
|
||||||
|
$db->insert(
|
||||||
|
'registrar_ote',
|
||||||
|
[
|
||||||
|
'registrar_id' => $registrar_id,
|
||||||
|
'command' => $command,
|
||||||
|
'result' => '9',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->commit();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$db->rollBack();
|
||||||
|
return view($response, 'admin/registrars/create.twig', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'countries' => $countries,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return view($response,'admin/registrars/create.twig', [
|
||||||
|
'registrar' => $data['name'],
|
||||||
|
'countries' => $countries,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$iso3166 = new ISO3166();
|
$iso3166 = new ISO3166();
|
||||||
|
|
|
@ -24,6 +24,31 @@
|
||||||
<div class="page-body">
|
<div class="page-body">
|
||||||
<div class="container-xl">
|
<div class="container-xl">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
{% if registrar is defined %}
|
||||||
|
<div class="alert alert-important alert-success alert-dismissible" role="alert">
|
||||||
|
<div class="d-flex">
|
||||||
|
<div>
|
||||||
|
<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 d="M5 12l5 5l10 -10" /></svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ __('Registrar') }} <strong>{{ registrar }}</strong> {{ __('successfully created and is now active.') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a class="btn-close" data-bs-dismiss="alert" aria-label="close"></a>
|
||||||
|
</div>
|
||||||
|
{% elseif error is defined %}
|
||||||
|
<div class="alert alert-important alert-danger alert-dismissible" role="alert">
|
||||||
|
<div class="d-flex">
|
||||||
|
<div>
|
||||||
|
<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 d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ __('Error creating the registrar') }}: <strong>{{ error }}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a class="btn-close" data-bs-dismiss="alert" aria-label="close"></a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<form action="/registrar/create" method="post" autocomplete="off">
|
<form action="/registrar/create" method="post" autocomplete="off">
|
||||||
{{ csrf.field | raw }}
|
{{ csrf.field | raw }}
|
||||||
<!-- Registrar Details Card -->
|
<!-- Registrar Details Card -->
|
||||||
|
@ -35,7 +60,7 @@
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="name" class="form-label required">Name</label>
|
<label for="name" class="form-label required">Name</label>
|
||||||
<input type="text" class="form-control" id="name" name="name">
|
<input type="text" class="form-control" id="name" name="name" required>
|
||||||
<small class="text-muted">The official name of the registrar.</small>
|
<small class="text-muted">The official name of the registrar.</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
|
@ -43,48 +68,38 @@
|
||||||
<input type="number" class="form-control" id="ianaId" name="ianaId">
|
<input type="number" class="form-control" id="ianaId" name="ianaId">
|
||||||
<small class="text-muted">Unique identifier assigned by IANA.</small>
|
<small class="text-muted">Unique identifier assigned by IANA.</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
|
||||||
<label for="clid" class="form-label required">CLID</label>
|
|
||||||
<input type="text" class="form-control" id="clid" name="clid">
|
|
||||||
<small class="text-muted">Unique client identifier for the registrar.</small>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="prefix" class="form-label required">Prefix</label>
|
|
||||||
<input type="text" class="form-control" id="prefix" name="prefix">
|
|
||||||
<small class="text-muted">Short prefix code representing the registrar.</small>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="email" class="form-label required">Email</label>
|
<label for="email" class="form-label required">Email</label>
|
||||||
<input type="email" class="form-control" id="email" name="email">
|
<input type="email" class="form-control" id="email" name="email" required>
|
||||||
<small class="text-muted">Primary contact email of the registrar.</small>
|
<small class="text-muted">Primary contact email of the registrar.</small>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="url" class="form-label required">URL</label>
|
||||||
|
<input type="url" class="form-control" id="url" name="url" required>
|
||||||
|
<small class="text-muted">Registrar's official website URL.</small>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Second Column -->
|
<!-- Second Column -->
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="whoisServer" class="form-label required">WHOIS Server</label>
|
<label for="whoisServer" class="form-label required">WHOIS Server</label>
|
||||||
<input type="text" class="form-control" id="whoisServer" name="whoisServer">
|
<input type="text" class="form-control" id="whoisServer" name="whoisServer" required>
|
||||||
<small class="text-muted">Address of the registrar's WHOIS server.</small>
|
<small class="text-muted">Address of the registrar's WHOIS server.</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="rdapServer" class="form-label required">RDAP Server</label>
|
<label for="rdapServer" class="form-label required">RDAP Server</label>
|
||||||
<input type="text" class="form-control" id="rdapServer" name="rdapServer">
|
<input type="text" class="form-control" id="rdapServer" name="rdapServer" required>
|
||||||
<small class="text-muted">Address of the registrar's RDAP server.</small>
|
<small class="text-muted">Address of the registrar's RDAP server.</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
|
||||||
<label for="url" class="form-label required">URL</label>
|
|
||||||
<input type="url" class="form-control" id="url" name="url">
|
|
||||||
<small class="text-muted">Registrar's official website URL.</small>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="abuseEmail" class="form-label required">Abuse Email</label>
|
<label for="abuseEmail" class="form-label required">Abuse Email</label>
|
||||||
<input type="email" class="form-control" id="abuseEmail" name="abuseEmail">
|
<input type="email" class="form-control" id="abuseEmail" name="abuseEmail" required>
|
||||||
<small class="text-muted">Email address for reporting abuse.</small>
|
<small class="text-muted">Email address for reporting abuse.</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="abusePhone" class="form-label required">Abuse Phone</label>
|
<label for="abusePhone" class="form-label required">Abuse Phone</label>
|
||||||
<input type="tel" class="form-control" id="abusePhone" name="abusePhone">
|
<input type="tel" class="form-control" id="abusePhone" name="abusePhone" required>
|
||||||
<small class="text-muted">Phone number for reporting abuse.</small>
|
<small class="text-muted">Phone number for reporting abuse.</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -101,12 +116,12 @@
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="accountBalance" class="form-label required">Account Balance</label>
|
<label for="accountBalance" class="form-label required">Account Balance</label>
|
||||||
<input type="text" class="form-control" id="accountBalance" name="accountBalance">
|
<input type="number" class="form-control" id="accountBalance" name="accountBalance" required>
|
||||||
<small class="text-muted">Current balance in the registrar's account.</small>
|
<small class="text-muted">Current balance in the registrar's account.</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="creditLimit" class="form-label required">Credit Limit</label>
|
<label for="creditLimit" class="form-label required">Credit Limit</label>
|
||||||
<input type="text" class="form-control" id="creditLimit" name="creditLimit">
|
<input type="number" class="form-control" id="creditLimit" name="creditLimit" required>
|
||||||
<small class="text-muted">Maximum credit limit for the registrar.</small>
|
<small class="text-muted">Maximum credit limit for the registrar.</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -115,12 +130,12 @@
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="creditThreshold" class="form-label required">Credit Threshold</label>
|
<label for="creditThreshold" class="form-label required">Credit Threshold</label>
|
||||||
<input type="text" class="form-control" id="creditThreshold" name="creditThreshold">
|
<input type="number" class="form-control" id="creditThreshold" name="creditThreshold" required>
|
||||||
<small class="text-muted">Credit threshold triggering alerts or actions.</small>
|
<small class="text-muted">Credit threshold triggering alerts or actions.</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="thresholdType" class="form-label required">Threshold Type</label>
|
<label for="thresholdType" class="form-label required">Threshold Type</label>
|
||||||
<select class="form-select" id="thresholdType" name="thresholdType">
|
<select class="form-select" id="thresholdType" name="thresholdType" required>
|
||||||
<option value="fixed">Fixed</option>
|
<option value="fixed">Fixed</option>
|
||||||
<option value="percent">Percent</option>
|
<option value="percent">Percent</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -155,18 +170,18 @@
|
||||||
<div class="form-check mb-3">
|
<div class="form-check mb-3">
|
||||||
<input class="form-check-input" type="checkbox" value="" id="copyOwnerData">
|
<input class="form-check-input" type="checkbox" value="" id="copyOwnerData">
|
||||||
<label class="form-check-label" for="copyOwnerData">
|
<label class="form-check-label" for="copyOwnerData">
|
||||||
Copy data to other contacts
|
<strong>Copy data to other contacts</strong>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<!-- First Column -->
|
<!-- First Column -->
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="ownerFirstName" class="form-label">First Name</label>
|
<label for="ownerFirstName" class="form-label required">First Name</label>
|
||||||
<input type="text" class="form-control" id="ownerFirstName" name="owner[first_name]" required>
|
<input type="text" class="form-control" id="ownerFirstName" name="owner[first_name]" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="ownerLastName" class="form-label">Last Name</label>
|
<label for="ownerLastName" class="form-label required">Last Name</label>
|
||||||
<input type="text" class="form-control" id="ownerLastName" name="owner[last_name]" required>
|
<input type="text" class="form-control" id="ownerLastName" name="owner[last_name]" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
|
@ -174,11 +189,11 @@
|
||||||
<input type="text" class="form-control" id="ownerOrg" name="owner[org]">
|
<input type="text" class="form-control" id="ownerOrg" name="owner[org]">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="ownerStreet1" class="form-label">Street Addres</label>
|
<label for="ownerStreet1" class="form-label">Street Address</label>
|
||||||
<input type="text" class="form-control" id="ownerStreet1" name="owner[street1]">
|
<input type="text" class="form-control" id="ownerStreet1" name="owner[street1]">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="ownerCity" class="form-label">City</label>
|
<label for="ownerCity" class="form-label required">City</label>
|
||||||
<input type="text" class="form-control" id="ownerCity" name="owner[city]" required>
|
<input type="text" class="form-control" id="ownerCity" name="owner[city]" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -194,7 +209,7 @@
|
||||||
<input type="text" class="form-control" id="ownerPc" name="owner[pc]">
|
<input type="text" class="form-control" id="ownerPc" name="owner[pc]">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="ownerCc" class="form-label">Country</label>
|
<label for="ownerCc" class="form-label required">Country</label>
|
||||||
<select class="form-select" id="ownerCc" name="owner[cc]" required="required">
|
<select class="form-select" id="ownerCc" name="owner[cc]" required="required">
|
||||||
{% for country in countries %}
|
{% for country in countries %}
|
||||||
<option value="{{ country.alpha2|lower }}">{{ country.name }}</option>
|
<option value="{{ country.alpha2|lower }}">{{ country.name }}</option>
|
||||||
|
@ -206,7 +221,7 @@
|
||||||
<input type="tel" class="form-control" id="ownerVoice" name="owner[voice]">
|
<input type="tel" class="form-control" id="ownerVoice" name="owner[voice]">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="ownerEmail" class="form-label">Email</label>
|
<label for="ownerEmail" class="form-label required">Email</label>
|
||||||
<input type="email" class="form-control" id="ownerEmail" name="owner[email]" required>
|
<input type="email" class="form-control" id="ownerEmail" name="owner[email]" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -221,11 +236,11 @@
|
||||||
<!-- First Column -->
|
<!-- First Column -->
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="billingFirstName" class="form-label">First Name</label>
|
<label for="billingFirstName" class="form-label required">First Name</label>
|
||||||
<input type="text" class="form-control" id="billingFirstName" name="billing[first_name]" required>
|
<input type="text" class="form-control" id="billingFirstName" name="billing[first_name]" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="billingLastName" class="form-label">Last Name</label>
|
<label for="billingLastName" class="form-label required">Last Name</label>
|
||||||
<input type="text" class="form-control" id="billingLastName" name="billing[last_name]" required>
|
<input type="text" class="form-control" id="billingLastName" name="billing[last_name]" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
|
@ -237,7 +252,7 @@
|
||||||
<input type="text" class="form-control" id="billingStreet1" name="billing[street1]">
|
<input type="text" class="form-control" id="billingStreet1" name="billing[street1]">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="billingCity" class="form-label">City</label>
|
<label for="billingCity" class="form-label required">City</label>
|
||||||
<input type="text" class="form-control" id="billingCity" name="billing[city]" required>
|
<input type="text" class="form-control" id="billingCity" name="billing[city]" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -253,7 +268,7 @@
|
||||||
<input type="text" class="form-control" id="billingPc" name="billing[pc]">
|
<input type="text" class="form-control" id="billingPc" name="billing[pc]">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="billingCc" class="form-label">Country</label>
|
<label for="billingCc" class="form-label required">Country</label>
|
||||||
<select class="form-select" id="billingCc" name="billing[cc]" required="required">
|
<select class="form-select" id="billingCc" name="billing[cc]" required="required">
|
||||||
{% for country in countries %}
|
{% for country in countries %}
|
||||||
<option value="{{ country.alpha2|lower }}">{{ country.name }}</option>
|
<option value="{{ country.alpha2|lower }}">{{ country.name }}</option>
|
||||||
|
@ -265,7 +280,7 @@
|
||||||
<input type="tel" class="form-control" id="billingVoice" name="billing[voice]">
|
<input type="tel" class="form-control" id="billingVoice" name="billing[voice]">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="billingEmail" class="form-label">Email</label>
|
<label for="billingEmail" class="form-label required">Email</label>
|
||||||
<input type="email" class="form-control" id="billingEmail" name="billing[email]" required>
|
<input type="email" class="form-control" id="billingEmail" name="billing[email]" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -280,11 +295,11 @@
|
||||||
<!-- First Column -->
|
<!-- First Column -->
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="abuseFirstName" class="form-label">First Name</label>
|
<label for="abuseFirstName" class="form-label required">First Name</label>
|
||||||
<input type="text" class="form-control" id="abuseFirstName" name="abuse[first_name]" required>
|
<input type="text" class="form-control" id="abuseFirstName" name="abuse[first_name]" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="abuseLastName" class="form-label">Last Name</label>
|
<label for="abuseLastName" class="form-label required">Last Name</label>
|
||||||
<input type="text" class="form-control" id="abuseLastName" name="abuse[last_name]" required>
|
<input type="text" class="form-control" id="abuseLastName" name="abuse[last_name]" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
|
@ -296,7 +311,7 @@
|
||||||
<input type="text" class="form-control" id="abuseStreet1" name="abuse[street1]">
|
<input type="text" class="form-control" id="abuseStreet1" name="abuse[street1]">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="abuseCity" class="form-label">City</label>
|
<label for="abuseCity" class="form-label required">City</label>
|
||||||
<input type="text" class="form-control" id="abuseCity" name="abuse[city]" required>
|
<input type="text" class="form-control" id="abuseCity" name="abuse[city]" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -312,7 +327,7 @@
|
||||||
<input type="text" class="form-control" id="abusePc" name="abuse[pc]">
|
<input type="text" class="form-control" id="abusePc" name="abuse[pc]">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="abuseCc" class="form-label">Country</label>
|
<label for="abuseCc" class="form-label required">Country</label>
|
||||||
<select class="form-select" id="abuseCc" name="abuse[cc]" required="required">
|
<select class="form-select" id="abuseCc" name="abuse[cc]" required="required">
|
||||||
{% for country in countries %}
|
{% for country in countries %}
|
||||||
<option value="{{ country.alpha2|lower }}">{{ country.name }}</option>
|
<option value="{{ country.alpha2|lower }}">{{ country.name }}</option>
|
||||||
|
@ -324,7 +339,7 @@
|
||||||
<input type="tel" class="form-control" id="abuseVoice" name="abuse[voice]">
|
<input type="tel" class="form-control" id="abuseVoice" name="abuse[voice]">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="abuseEmail" class="form-label">Email</label>
|
<label for="abuseEmail" class="form-label required">Email</label>
|
||||||
<input type="email" class="form-control" id="abuseEmail" name="abuse[email]" required>
|
<input type="email" class="form-control" id="abuseEmail" name="abuse[email]" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -362,31 +377,31 @@
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">Registrar User</h5>
|
<h5 class="card-title">Registrar User</h5>
|
||||||
<p class="card-text">
|
<p class="card-text">
|
||||||
Create a registrar user by specifying the username, email, and passwords for both EPP and panel access.
|
Create a registrar user by specifying the username (also known as CLID), email, and passwords for EPP and panel access.
|
||||||
</p>
|
</p>
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">Username</th>
|
<th scope="col required">Username/CLID <span class="text-red">*</span></th>
|
||||||
<th scope="col">Email</th>
|
<th scope="col">Login Email <span class="text-red">*</span></th>
|
||||||
<th scope="col">EPP User Password</th>
|
<th scope="col">Panel Password <span class="text-red">*</span></th>
|
||||||
<th scope="col">Panel User Password</th>
|
<th scope="col">EPP Password <span class="text-red">*</span></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" class="form-control form-control-sm" name="user_name" placeholder="user1" autocomplete="off">
|
<input type="text" class="form-control form-control-sm" name="user_name" placeholder="user1" autocomplete="off" required>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="email" class="form-control form-control-sm" name="user_email" placeholder="user1@example.com" autocomplete="off">
|
<input type="email" class="form-control form-control-sm" name="user_email" placeholder="user1@example.com" autocomplete="off" required>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="password" class="form-control form-control-sm" name="eppPassword" autocomplete="off">
|
<input type="password" class="form-control form-control-sm" name="panelPassword" autocomplete="off" required>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="password" class="form-control form-control-sm" name="panelPassword" autocomplete="off">
|
<input type="password" class="form-control form-control-sm" name="eppPassword" autocomplete="off" required>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -163,17 +163,13 @@
|
||||||
<a class="dropdown-item" href="{{route('registrarcreate')}}">
|
<a class="dropdown-item" href="{{route('registrarcreate')}}">
|
||||||
{{ __('Create Registrar') }}
|
{{ __('Create Registrar') }}
|
||||||
</a>
|
</a>
|
||||||
|
<a class="dropdown-item" href="#">
|
||||||
|
{{ __('Announcements') }}
|
||||||
|
</a>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<a class="dropdown-item" href="{{route('users')}}">
|
<a class="dropdown-item" href="{{route('users')}}">
|
||||||
{{ __('List Users') }}
|
{{ __('List Users') }}
|
||||||
</a>
|
</a>
|
||||||
<a class="dropdown-item" href="#">
|
|
||||||
{{ __('Create User') }}
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item" href="#">
|
|
||||||
{{ __('Announcements') }}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li {{ is_current_url('pricing') or is_current_url('deposit') or is_current_url('transactions') or is_current_url('overview') ? 'class="nav-item dropdown active"' : 'class="nav-item dropdown"' }}>
|
<li {{ is_current_url('pricing') or is_current_url('deposit') or is_current_url('transactions') or is_current_url('overview') ? 'class="nav-item dropdown active"' : 'class="nav-item dropdown"' }}>
|
||||||
|
|
|
@ -9,9 +9,6 @@
|
||||||
if (e.target.matches('.update-btn')) {
|
if (e.target.matches('.update-btn')) {
|
||||||
let id = e.target.getAttribute('data-id');
|
let id = e.target.getAttribute('data-id');
|
||||||
updateRecord(id);
|
updateRecord(id);
|
||||||
} else if (e.target.matches('.delete-btn')) {
|
|
||||||
let id = e.target.getAttribute('data-id');
|
|
||||||
deleteRecord(id);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,8 +20,7 @@
|
||||||
|
|
||||||
function actionsFormatter(cell, formatterParams, onRendered) {
|
function actionsFormatter(cell, formatterParams, onRendered) {
|
||||||
return `
|
return `
|
||||||
<button class="btn btn-primary btn-icon update-btn" data-id="${cell.getRow().getData().id}"><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="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path><path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"></path><path d="M16 5l3 3"></path></svg></button>
|
<button class="btn btn-outline-primary btn-icon update-btn" data-id="${cell.getRow().getData().id}"><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="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path><path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"></path><path d="M16 5l3 3"></path></svg></button>
|
||||||
<button class="btn btn-danger btn-icon delete-btn" data-id="${cell.getRow().getData().id}"><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="M4 7h16"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path><path d="M10 12l4 4m0 -4l-4 4"></path></svg></button>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,10 +79,6 @@
|
||||||
console.log("Updating record with ID: " + id);
|
console.log("Updating record with ID: " + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteRecord(id) {
|
|
||||||
console.log("Deleting record with ID: " + id);
|
|
||||||
}
|
|
||||||
|
|
||||||
function downloadCSV() {
|
function downloadCSV() {
|
||||||
table.download("csv", "data.csv");
|
table.download("csv", "data.csv");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue