Big work on domain applications in panel

This commit is contained in:
Pinga 2023-12-19 02:35:07 +02:00
parent 58c8f8f01a
commit e9ed61cfa9
11 changed files with 2059 additions and 76 deletions

View file

@ -148,6 +148,10 @@
"audit": true, "audit": true,
"skip": null "skip": null
}, },
"application_contact_map": {
"audit": true,
"skip": null
},
"domain_authInfo": { "domain_authInfo": {
"audit": true, "audit": true,
"skip": null "skip": null
@ -156,6 +160,10 @@
"audit": true, "audit": true,
"skip": null "skip": null
}, },
"application_status": {
"audit": true,
"skip": null
},
"secdns": { "secdns": {
"audit": true, "audit": true,
"skip": null "skip": null
@ -168,6 +176,10 @@
"audit": true, "audit": true,
"skip": null "skip": null
}, },
"application_host_map": {
"audit": true,
"skip": null
},
"host_addr": { "host_addr": {
"audit": true, "audit": true,
"skip": null "skip": null

File diff suppressed because it is too large Load diff

View file

@ -14,11 +14,6 @@ class DomainsController extends Controller
return view($response,'admin/domains/listDomains.twig'); return view($response,'admin/domains/listDomains.twig');
} }
public function listApplications(Request $request, Response $response)
{
return view($response,'admin/domains/listApplications.twig');
}
public function checkDomain(Request $request, Response $response) public function checkDomain(Request $request, Response $response)
{ {
if ($request->getMethod() === 'POST') { if ($request->getMethod() === 'POST') {

View file

@ -0,0 +1,245 @@
{% extends "layouts/app.twig" %}
{% block title %}{{ __('Create Application') }}{% 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">
{{ __('Create Application') }}
</h2>
</div>
</div>
</div>
</div>
<!-- Page body -->
<div class="page-body">
<div class="container-xl">
<div class="col-12">
{% if domainName is defined and crdate 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>
&nbsp;{{ __('Application') }} <strong>{{ domainName }}</strong> {{ __('has been created successfully on') }} <strong>{{ crdate|date("Y-m-d H:i:s") }}!</strong>
</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>
&nbsp;{{ __('Application') }} <strong>{{ domainName }}</strong> {{ __('can not be created') }}: <strong>{{ error }}</strong>
</div>
</div>
<a class="btn-close" data-bs-dismiss="alert" aria-label="close"></a>
</div>
{% endif %}
<div class="card">
<div class="card-body">
<form id="domainCreateForm" action="/application/create" method="post">
{{ csrf.field | raw }}
<div class="mb-3">
<label for="domainName" class="form-label required">{{ __('Your Domain Name') }}</label>
<input type="text" class="form-control mb-2" placeholder="example.com" name="domainName" id="domainName" required="required" autocapitalize="none">
</div>
<div class="mb-3">
<label for="phaseType" class="form-label required">Phase Type</label>
<select class="form-select" id="phaseType" name="phaseType" required>
<option value="sunrise">Sunrise</option>
<option value="landrush">Landrush</option>
<option value="claims">Claims</option>
<option value="open">Open</option>
<option value="custom">Custom</option>
</select>
</div>
<div class="mb-3">
<label for="phaseName" class="form-label">Phase Name</label>
<input type="text" class="form-control" id="phaseName" name="phaseName" placeholder="Enter phase name">
<small class="form-hint">The "Phase name" field is required only if the "Type" is set to "Custom".</small>
</div>
{% if registrars and not registrar %}
<div class="form-group mb-3">
<label for="registrarDropdown" class="form-label required">{{ __('Select Registrar') }}:</label>
<select id="registrarDropdown" name="registrar" class="form-control">
{% for registrar in registrars %}
<option value="{{ registrar.id }}">{{ registrar.name }}</option>
{% endfor %}
</select>
</div>
{% endif %}
<!-- Fields for 4 contacts with roles -->
<div class="mb-3">
<label for="contactRegistrant" class="form-label required">{{ __('Contacts') }}</label>
<input type="text" class="form-control mb-2" placeholder="{{ __('Registrant Contact') }}" name="contactRegistrant" id="contactRegistrant" required="required">
<input type="text" class="form-control mb-2" placeholder="{{ __('Admin Contact') }}" name="contactAdmin">
<input type="text" class="form-control mb-2" placeholder="{{ __('Tech Contact') }}" name="contactTech">
<input type="text" class="form-control mb-2" placeholder="{{ __('Billing Contact') }}" name="contactBilling">
</div>
<!-- Fields for nameservers -->
<div id="nameserverFields">
<label class="form-label">{{ __('Nameservers') }} <button type="button" id="addNameserver" class="btn btn-success btn-sm mb-2">+</button> <button type="button" id="removeNameserver" class="btn btn-danger btn-sm mb-2">-</button></label>
<div class="nameserver-group mb-1 row">
<div class="col-md-4">
<input type="text" class="form-control mb-1" placeholder="{{ __('Nameserver') }} 1" name="nameserver[]" autocapitalize="none">
</div>
<div class="col-md-4">
<input type="text" class="form-control mb-1" placeholder="{{ __('Nameserver') }} 1 - IPv4" name="nameserver_ipv4[]">
</div>
<div class="col-md-4">
<input type="text" class="form-control mb-1" placeholder="{{ __('Nameserver') }} 1 - IPv6" name="nameserver_ipv6[]" autocapitalize="none">
</div>
</div>
<div class="nameserver-group mb-1 row">
<div class="col-md-4">
<input type="text" class="form-control mb-1" placeholder="{{ __('Nameserver') }} 2" name="nameserver[]" autocapitalize="none">
</div>
<div class="col-md-4">
<input type="text" class="form-control mb-1" placeholder="{{ __('Nameserver') }} 2 - IPv4" name="nameserver_ipv4[]">
</div>
<div class="col-md-4">
<input type="text" class="form-control mb-1" placeholder="{{ __('Nameserver') }} 2 - IPv6" name="nameserver_ipv6[]" autocapitalize="none">
</div>
</div>
</div>
<!-- AuthInfo -->
<div class="mb-3">
<label for="authInfo" class="form-label required">{{ __('Auth Info') }}</label>
<input type="text" class="form-control" id="authInfo" name="authInfo" required>
</div>
<div class="mb-3">
<label class="form-label">Signed Mark Information</label>
<textarea class="form-control" data-bs-toggle="autosize" name="smd" placeholder="Paste SMD contents…"></textarea>
</div>
</div>
<div class="card-footer">
<div class="row align-items-center">
<div class="col-auto">
<button type="submit" class="btn btn-primary">{{ __('Create Application') }}</button>
</div>
</div>
</div>
</form>
</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>
<script>
document.addEventListener("DOMContentLoaded", function() {
const addNameserverBtn = document.getElementById('addNameserver');
const removeNameserverBtn = document.getElementById('removeNameserver');
const nameserverFields = document.getElementById('nameserverFields');
const authInfoField = document.getElementById('authInfo');
function createNameserverGroup(count) {
const group = document.createElement('div');
group.className = 'nameserver-group mb-1 row';
const nameserverCol = document.createElement('div');
nameserverCol.className = 'col-md-4';
const nameserverField = document.createElement('input');
nameserverField.type = 'text';
nameserverField.className = 'form-control mb-1';
nameserverField.placeholder = `{{ __('Nameserver') }} ${count}`;
nameserverField.name = `nameserver[]`;
nameserverCol.appendChild(nameserverField);
const ipv4Col = document.createElement('div');
ipv4Col.className = 'col-md-4';
const ipv4Field = document.createElement('input');
ipv4Field.type = 'text';
ipv4Field.className = 'form-control mb-1';
ipv4Field.placeholder = `{{ __('Nameserver') }} ${count} - IPv4`;
ipv4Field.name = `nameserver_ipv4[]`;
ipv4Col.appendChild(ipv4Field);
const ipv6Col = document.createElement('div');
ipv6Col.className = 'col-md-4';
const ipv6Field = document.createElement('input');
ipv6Field.type = 'text';
ipv6Field.className = 'form-control mb-1';
ipv6Field.placeholder = `{{ __('Nameserver') }} ${count} - IPv6`;
ipv6Field.name = `nameserver_ipv6[]`;
ipv6Col.appendChild(ipv6Field);
group.appendChild(nameserverCol);
group.appendChild(ipv4Col);
group.appendChild(ipv6Col);
return group;
}
// Add nameserver fields
let nameserverCount = 2;
addNameserverBtn.addEventListener('click', function() {
if (nameserverCount < 13) {
nameserverCount++;
const nameserverGroup = createNameserverGroup(nameserverCount);
nameserverFields.appendChild(nameserverGroup);
}
});
// Remove nameserver group
removeNameserverBtn.addEventListener('click', function() {
if (nameserverCount > 2) {
const lastGroup = nameserverFields.querySelector('.nameserver-group:last-child');
if (lastGroup) {
nameserverFields.removeChild(lastGroup);
nameserverCount--;
}
}
});
// Generate random AuthInfo and set it to the field
function generateAuthInfo() {
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
for (let i = 0; i < 16; i++) {
result += charset.charAt(Math.floor(Math.random() * charset.length));
}
return result;
}
authInfoField.value = generateAuthInfo();
});
</script>
{% endblock %}

View file

@ -25,11 +25,11 @@
{{ __('Check Domain') }} {{ __('Check Domain') }}
</a> </a>
</span> </span>
<a href="{{route('createDomain')}}" class="btn btn-primary d-none d-sm-inline-block"> <a href="{{route('createApplication')}}" class="btn btn-primary d-none d-sm-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"/><line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" /></svg> <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"/><line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" /></svg>
{{ __('Create Domain') }} {{ __('Create Application') }}
</a> </a>
<a href="{{route('createDomain')}}" class="btn btn-primary d-sm-none btn-icon" aria-label="{{ __('Create Domain') }}"> <a href="{{route('createApplication')}}" class="btn btn-primary d-sm-none btn-icon" aria-label="{{ __('Create Application') }}">
<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"/><line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" /></svg> <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"/><line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" /></svg>
</a> </a>
</div> </div>

View file

@ -0,0 +1,148 @@
{% extends "layouts/app.twig" %}
{% block title %}{{ __('Application Details') }}{% 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">
{{ __('Application Details') }}
</h2>
</div>
</div>
</div>
</div>
<!-- Page body -->
<div class="page-body">
<div class="container-xl">
<div class="col-12">
<div class="card mb-3">
<div class="card-header">
<h3 class="card-title">
Application for {{ domain.name }}&nbsp;
{% if domain.status %}
{% if domain is iterable %}
{% for status in domainStatus %}
<span class="status status-green" title="Status">{{ status.status }}</span>&nbsp;
{% endfor %}
{% else %}
{% if domain.status %}
<span class="status status-green" title="Status">{{ domain.status }}</span>&nbsp;
{% endif %}
{% endif %}
{% else %}
<span class="status status-info" title="Status">ok</span>
{% endif %}
</h3>
</div>
<div class="card-body">
<div class="datagrid">
<div class="datagrid-item">
<div class="datagrid-title">Registered On</div>
<div class="datagrid-content">{{ domain.crdate }}</div>
</div>
<div class="datagrid-item">
<div class="datagrid-title">Launch Phase</div>
<div class="datagrid-content">{{ domain.phase_type }}</div>
</div>
<div class="datagrid-item">
<div class="datagrid-title">Expiration Date</div>
<div class="datagrid-content">{{ domain.exdate }}</div>
</div>
<div class="datagrid-item">
<div class="datagrid-title">Registrar</div>
<div class="datagrid-content">{{ registrars.name }}</div>
</div>
<div class="datagrid-item">
<div class="datagrid-title">Registrant</div>
<div class="datagrid-content">{{ domainRegistrant.identifier }}</div>
</div>
{% for contact in domainContacts %}
<div class="datagrid-item">
<div class="datagrid-title">{{ contact.type }} contact</div>
<div class="datagrid-content">{{ contact.identifier }}</div>
</div>
{% endfor %}
<div class="datagrid-item">
<div class="datagrid-title">Auth Type</div>
<div class="datagrid-content">
{% if domain.authtype == 'pw' %}
Regular
{% elseif domain.authtype == 'ext' %}
HSM
{% else %}
{{ domain.authtype }} {# Fallback in case there are other types #}
{% endif %}
</div>
</div>
<div class="datagrid-item">
<div class="datagrid-title">Auth Info</div>
<div class="datagrid-content blur" id="authInfo" onclick="toggleBlur()">
{{ domain.authinfo }}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-md-12">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">Nameservers</h5>
<div class="datagrid">
{% for host in domainHosts %}
<div class="datagrid-item">
<div class="datagrid-title">Nameserver {{ loop.index }}</div>
<div class="datagrid-content">
{{ host.name }}
</div>
</div>
{% endfor %}
</div>
</div>
</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>
<style>
.blur {
filter: blur(5px);
cursor: pointer;
}
.blur:hover {
filter: blur(2px); /* Slightly clearer on hover for a hint to the user */
}
</style>
<script>
function toggleBlur() {
var authInfo = document.getElementById("authInfo");
authInfo.classList.toggle("blur");
}
</script>
{% endblock %}

View file

@ -83,7 +83,7 @@
</span> </span>
</a> </a>
</li> </li>
<li {{ is_current_url('listDomains') or is_current_url('listApplications') or is_current_url('checkDomain') or is_current_url('createDomain') or is_current_url('listTransfers') or is_current_url('requestTransfer') or 'domain' in currentUri ? 'class="nav-item dropdown active"' : 'class="nav-item dropdown"' }}> <li {{ is_current_url('listDomains') or is_current_url('listApplications') or is_current_url('checkDomain') or is_current_url('createDomain') or is_current_url('createApplication') or is_current_url('listTransfers') or is_current_url('requestTransfer') or 'domain' 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="M19.5 7a9 9 0 0 0 -7.5 -4a8.991 8.991 0 0 0 -7.484 4"></path><path d="M11.5 3a16.989 16.989 0 0 0 -1.826 4"></path><path d="M12.5 3a16.989 16.989 0 0 1 1.828 4"></path><path d="M19.5 17a9 9 0 0 1 -7.5 4a8.991 8.991 0 0 1 -7.484 -4"></path><path d="M11.5 21a16.989 16.989 0 0 1 -1.826 -4"></path><path d="M12.5 21a16.989 16.989 0 0 0 1.828 -4"></path><path d="M2 10l1 4l1.5 -4l1.5 4l1 -4"></path><path d="M17 10l1 4l1.5 -4l1.5 4l1 -4"></path><path d="M9.5 10l1 4l1.5 -4l1.5 4l1 -4"></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="M19.5 7a9 9 0 0 0 -7.5 -4a8.991 8.991 0 0 0 -7.484 4"></path><path d="M11.5 3a16.989 16.989 0 0 0 -1.826 4"></path><path d="M12.5 3a16.989 16.989 0 0 1 1.828 4"></path><path d="M19.5 17a9 9 0 0 1 -7.5 4a8.991 8.991 0 0 1 -7.484 -4"></path><path d="M11.5 21a16.989 16.989 0 0 1 -1.826 -4"></path><path d="M12.5 21a16.989 16.989 0 0 0 1.828 -4"></path><path d="M2 10l1 4l1.5 -4l1.5 4l1 -4"></path><path d="M17 10l1 4l1.5 -4l1.5 4l1 -4"></path><path d="M9.5 10l1 4l1.5 -4l1.5 4l1 -4"></path></svg>
</span> </span>
@ -105,6 +105,9 @@
<a class="dropdown-item" href="{{route('listApplications')}}"> <a class="dropdown-item" href="{{route('listApplications')}}">
{{ __('List Applications') }} {{ __('List Applications') }}
</a> </a>
<a class="dropdown-item" href="{{route('createApplication')}}">
{{ __('Create Application') }}
</a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" href="{{route('listTransfers')}}"> <a class="dropdown-item" href="{{route('listTransfers')}}">
{{ __('Transfers') }} {{ __('Transfers') }}

View file

@ -9,32 +9,21 @@
document.addEventListener("DOMContentLoaded", function(){ document.addEventListener("DOMContentLoaded", function(){
function domainLinkFormatter(cell){ function domainLinkFormatter(cell){
var value = cell.getValue(); var value = cell.getValue();
return `<a href="/domain/view/${value}" style="font-weight:bold;">${value}</a>`; return `<a href="/application/view/${value}" style="font-weight:bold;">${value}</a>`;
} }
function actionsFormatter(cell, formatterParams, onRendered) { function actionsFormatter(cell, formatterParams, onRendered) {
var rowData = cell.getRow().getData(); var rowData = cell.getRow().getData();
var actionButtons = ''; var actionButtons = '';
var hasPendingDelete = rowData.domain_status.some(statusObj => statusObj.status && statusObj.status.includes('pendingDelete'));
var hasPendingRestore = rowData.rgpstatus ? rowData.rgpstatus.includes('pendingRestore') : false;
// Common action button for all statuses // Common action button for all statuses
actionButtons += `<a class="btn btn-info btn-icon" href="domain/update/${cell.getRow().getData().name}" title="Update Domain"><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></a> `; actionButtons += `<a class="btn btn-info btn-icon" href="application/update/${cell.getRow().getData().name}" title="Update Application"><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></a> `;
actionButtons += `<a class="btn btn-danger btn-icon" href="application/delete/${cell.getRow().getData().name}" title="Delete Application"><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></a>`;
if (hasPendingRestore) {
actionButtons += `<a class="btn btn-outline-dark btn-icon" href="domain/report/${cell.getRow().getData().name}" title="Submit Report"><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.06 13a9 9 0 1 0 .49 -4.087" /><path d="M3 4.001v5h5" /><path d="M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /></svg></a>`;
} else if (hasPendingDelete) {
actionButtons += `<a class="btn btn-outline-warning btn-icon" href="domain/restore/${cell.getRow().getData().name}" title="Restore Domain"><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="M15 4.55a8 8 0 0 0 -6 14.9m0 -4.45v5h-5" /><path d="M18.37 7.16l0 .01" /><path d="M13 19.94l0 .01" /><path d="M16.84 18.37l0 .01" /><path d="M19.37 15.1l0 .01" /><path d="M19.94 11l0 .01" /></svg></a>`;
} else {
actionButtons += `<a class="btn btn-success btn-icon" href="domain/renew/${cell.getRow().getData().name}" title="Renew Domain"><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="M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4"></path><path d="M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4"></path></svg></a> `;
actionButtons += `<a class="btn btn-danger btn-icon" href="domain/delete/${cell.getRow().getData().name}" title="Delete Domain"><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></a>`;
}
return actionButtons; return actionButtons;
} }
function statusFormatter(cell) { function phaseFormatter(cell) {
var statusArray = cell.getValue(); var statusArray = cell.getValue();
var rowData = cell.getRow().getData(); // Get the entire row data var rowData = cell.getRow().getData(); // Get the entire row data
@ -44,15 +33,7 @@
} }
// Check if statusArray is empty or not // Check if statusArray is empty or not
if (statusArray && Array.isArray(statusArray) && statusArray.length > 0) { return createBadge(statusArray, 'info');
return statusArray.map(item => createBadge(item.status, 'azure')).join(' ');
} else if (rowData.rgpstatus) {
// Fallback to rgpstatus column if statusArray is empty
return createBadge(rowData.rgpstatus, 'lime');
} else {
// Display 'ok' status with info badge if both statusArray and rgpstatus are empty
return createBadge('ok', 'info');
}
} }
var searchTerm = ""; // global variable to hold the search term var searchTerm = ""; // global variable to hold the search term
@ -112,7 +93,7 @@
{title:"Name", field:"name", width:200, headerSort:false, formatter: domainLinkFormatter, responsive:0}, {title:"Name", field:"name", width:200, headerSort:false, formatter: domainLinkFormatter, responsive:0},
{title:"Applicant", width:200, field:"registrant.identifier", headerSort:false, responsive:2}, {title:"Applicant", width:200, field:"registrant.identifier", headerSort:false, responsive:2},
{title:"Creation Date", width:250, minWidth:150, field:"crdate", headerSort:false, responsive:2}, {title:"Creation Date", width:250, minWidth:150, field:"crdate", headerSort:false, responsive:2},
{title:"Phase", width:250, minWidth:150, field:"tm_phase", headerSort:false, responsive:2}, {title:"Phase", width:250, minWidth:150, field:"phase_type", formatter: phaseFormatter, headerSort:false, responsive:2},
{title: "Actions", formatter: actionsFormatter, headerSort: false, download:false, hozAlign: "center", responsive:0, cellClick:function(e, cell){ e.stopPropagation(); }}, {title: "Actions", formatter: actionsFormatter, headerSort: false, download:false, hozAlign: "center", responsive:0, cellClick:function(e, cell){ e.stopPropagation(); }},
], ],
placeholder:function(){ placeholder:function(){

View file

@ -3,6 +3,7 @@ use App\Controllers\Auth\AuthController;
use App\Controllers\Auth\PasswordController; use App\Controllers\Auth\PasswordController;
use App\Controllers\HomeController; use App\Controllers\HomeController;
use App\Controllers\DomainsController; use App\Controllers\DomainsController;
use App\Controllers\ApplicationsController;
use App\Controllers\ContactsController; use App\Controllers\ContactsController;
use App\Controllers\HostsController; use App\Controllers\HostsController;
use App\Controllers\LogsController; use App\Controllers\LogsController;
@ -51,7 +52,13 @@ $app->group('', function ($route) {
$route->map(['GET', 'POST'], '/domain/restore/{domain}', DomainsController::class . ':restoreDomain')->setName('restoreDomain'); $route->map(['GET', 'POST'], '/domain/restore/{domain}', DomainsController::class . ':restoreDomain')->setName('restoreDomain');
$route->map(['GET', 'POST'], '/domain/report/{domain}', DomainsController::class . ':reportDomain')->setName('reportDomain'); $route->map(['GET', 'POST'], '/domain/report/{domain}', DomainsController::class . ':reportDomain')->setName('reportDomain');
$route->get('/applications', DomainsController::class .':listApplications')->setName('listApplications'); $route->get('/applications', ApplicationsController::class .':listApplications')->setName('listApplications');
$route->map(['GET', 'POST'], '/application/create', ApplicationsController::class . ':createApplication')->setName('createApplication');
$route->get('/application/view/{application}', ApplicationsController::class . ':viewApplication')->setName('viewApplication');
$route->get('/application/update/{application}', ApplicationsController::class . ':updateApplication')->setName('updateApplication');
$route->post('/application/update', ApplicationsController::class . ':updateApplicationProcess')->setName('updateApplicationProcess');
$route->post('/application/deletehost', ApplicationsController::class . ':applicationDeleteHost')->setName('applicationDeleteHost');
$route->map(['GET', 'POST'], '/application/delete/{application}', ApplicationsController::class . ':deleteApplication')->setName('deleteApplication');
$route->get('/transfers', DomainsController::class . ':listTransfers')->setName('listTransfers'); $route->get('/transfers', DomainsController::class . ':listTransfers')->setName('listTransfers');
$route->map(['GET', 'POST'], '/transfer/request', DomainsController::class . ':requestTransfer')->setName('requestTransfer'); $route->map(['GET', 'POST'], '/transfer/request', DomainsController::class . ':requestTransfer')->setName('requestTransfer');
@ -173,6 +180,7 @@ $app->any('/api[/{params:.*}]', function (
$columnMap = [ $columnMap = [
'contact' => 'clid', 'contact' => 'clid',
'domain' => 'clid', 'domain' => 'clid',
'application' => 'clid',
'host' => 'clid', 'host' => 'clid',
'poll' => 'registrar_id', 'poll' => 'registrar_id',
'registrar' => 'id', 'registrar' => 'id',

View file

@ -373,25 +373,11 @@ CREATE TABLE IF NOT EXISTS `registry`.`application` (
`transfer_exdate` datetime(3) default NULL, `transfer_exdate` datetime(3) default NULL,
`idnlang` varchar(16) default NULL, `idnlang` varchar(16) default NULL,
`delTime` datetime(3) default NULL, `delTime` datetime(3) default NULL,
`resTime` datetime(3) default NULL, `authtype` enum('pw','ext') NOT NULL default 'pw',
`rgpstatus` enum('addPeriod','autoRenewPeriod','renewPeriod','transferPeriod','pendingDelete','pendingRestore','redemptionPeriod') default NULL, `authinfo` varchar(64) NOT NULL,
`rgppostData` text default NULL, `phase_name` VARCHAR(75) DEFAULT NULL,
`rgpdelTime` datetime(3) default NULL, `phase_type` VARCHAR(50) NOT NULL,
`rgpresTime` datetime(3) default NULL, `smd` text default NULL,
`rgpresReason` text default NULL,
`rgpstatement1` text default NULL,
`rgpstatement2` text default NULL,
`rgpother` text default NULL,
`addPeriod` tinyint(3) unsigned default NULL,
`autoRenewPeriod` tinyint(3) unsigned default NULL,
`renewPeriod` tinyint(3) unsigned default NULL,
`transferPeriod` tinyint(3) unsigned default NULL,
`renewedDate` datetime(3) default NULL,
`agp_exempted` tinyint(1) DEFAULT 0,
`agp_request` datetime(3) default NULL,
`agp_grant` datetime(3) default NULL,
`agp_reason` text default NULL,
`agp_status` varchar(30) default NULL,
`tm_notice_accepted` datetime(3) default NULL, `tm_notice_accepted` datetime(3) default NULL,
`tm_notice_expires` datetime(3) default NULL, `tm_notice_expires` datetime(3) default NULL,
`tm_notice_id` varchar(150) default NULL, `tm_notice_id` varchar(150) default NULL,
@ -417,7 +403,18 @@ CREATE TABLE IF NOT EXISTS `registry`.`domain_contact_map` (
UNIQUE KEY `uniquekey` (`domain_id`,`contact_id`,`type`), UNIQUE KEY `uniquekey` (`domain_id`,`contact_id`,`type`),
CONSTRAINT `domain_contact_map_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domain` (`id`) ON DELETE RESTRICT, CONSTRAINT `domain_contact_map_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domain` (`id`) ON DELETE RESTRICT,
CONSTRAINT `domain_contact_map_ibfk_2` FOREIGN KEY (`contact_id`) REFERENCES `contact` (`id`) ON DELETE RESTRICT CONSTRAINT `domain_contact_map_ibfk_2` FOREIGN KEY (`contact_id`) REFERENCES `contact` (`id`) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='contact map'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='contact map for domains';
CREATE TABLE IF NOT EXISTS `registry`.`application_contact_map` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`domain_id` int(10) unsigned NOT NULL,
`contact_id` int(10) unsigned NOT NULL,
`type` enum('admin','billing','tech') NOT NULL default 'admin',
PRIMARY KEY (`id`),
UNIQUE KEY `uniquekey` (`domain_id`,`contact_id`,`type`),
CONSTRAINT `application_contact_map_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `application` (`id`) ON DELETE RESTRICT,
CONSTRAINT `application_contact_map_ibfk_2` FOREIGN KEY (`contact_id`) REFERENCES `contact` (`id`) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='contact map for applications';
CREATE TABLE IF NOT EXISTS `registry`.`domain_authInfo` ( CREATE TABLE IF NOT EXISTS `registry`.`domain_authInfo` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
@ -438,6 +435,15 @@ CREATE TABLE IF NOT EXISTS `registry`.`domain_status` (
CONSTRAINT `domain_status_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domain` (`id`) ON DELETE RESTRICT CONSTRAINT `domain_status_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domain` (`id`) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='domain:status'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='domain:status';
CREATE TABLE IF NOT EXISTS `registry`.`application_status` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`domain_id` int(10) unsigned NOT NULL,
`status` enum('pendingValidation','validated','invalid','pendingAllocation','allocated','rejected','custom') NOT NULL default 'pendingValidation',
PRIMARY KEY (`id`),
UNIQUE KEY `uniquekey` (`domain_id`,`status`),
CONSTRAINT `application_status_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `application` (`id`) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='application:status';
CREATE TABLE IF NOT EXISTS `registry`.`secdns` ( CREATE TABLE IF NOT EXISTS `registry`.`secdns` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`domain_id` int(10) unsigned NOT NULL, `domain_id` int(10) unsigned NOT NULL,
@ -482,7 +488,17 @@ CREATE TABLE IF NOT EXISTS `registry`.`domain_host_map` (
UNIQUE KEY `domain_host_map_id` (`domain_id`,`host_id`), UNIQUE KEY `domain_host_map_id` (`domain_id`,`host_id`),
CONSTRAINT `domain_host_map_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domain` (`id`) ON DELETE RESTRICT, CONSTRAINT `domain_host_map_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domain` (`id`) ON DELETE RESTRICT,
CONSTRAINT `domain_host_map_ibfk_2` FOREIGN KEY (`host_id`) REFERENCES `host` (`id`) ON DELETE RESTRICT CONSTRAINT `domain_host_map_ibfk_2` FOREIGN KEY (`host_id`) REFERENCES `host` (`id`) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='contact map'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='host map for domains';
CREATE TABLE IF NOT EXISTS `registry`.`application_host_map` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`domain_id` int(10) unsigned NOT NULL,
`host_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `application_host_map_id` (`domain_id`,`host_id`),
CONSTRAINT `application_host_map_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `application` (`id`) ON DELETE RESTRICT,
CONSTRAINT `application_host_map_ibfk_2` FOREIGN KEY (`host_id`) REFERENCES `host` (`id`) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='host map for applications';
CREATE TABLE IF NOT EXISTS `registry`.`host_addr` ( CREATE TABLE IF NOT EXISTS `registry`.`host_addr` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id` int(10) unsigned NOT NULL AUTO_INCREMENT,

View file

@ -371,25 +371,11 @@ CREATE TABLE registry.application (
"transfer_exdate" timestamp(3) without time zone default NULL, "transfer_exdate" timestamp(3) without time zone default NULL,
"idnlang" varchar(16) default NULL, "idnlang" varchar(16) default NULL,
"deltime" timestamp(3) without time zone default NULL, "deltime" timestamp(3) without time zone default NULL,
"restime" timestamp(3) without time zone default NULL, "authtype" varchar CHECK ("authtype" IN ( 'pw','ext' )) NOT NULL default 'pw',
"rgpstatus" varchar CHECK ("rgpstatus" IN ( 'addPeriod','autoRenewPeriod','renewPeriod','transferPeriod','pendingDelete','pendingRestore','redemptionPeriod' )) default NULL, "authinfo" varchar(64) NOT NULL,
"rgppostdata" text default NULL, "phase_name" VARCHAR(75) DEFAULT NULL,
"rgpdeltime" timestamp(3) without time zone default NULL, "phase_type" VARCHAR(50) NOT NULL,
"rgprestime" timestamp(3) without time zone default NULL, "smd" TEXT DEFAULT NULL,
"rgpresreason" text default NULL,
"rgpstatement1" text default NULL,
"rgpstatement2" text default NULL,
"rgpother" text default NULL,
"addperiod" smallint CHECK ("addperiod" >= 0) default NULL,
"autorenewperiod" smallint CHECK ("autorenewperiod" >= 0) default NULL,
"renewperiod" smallint CHECK ("renewperiod" >= 0) default NULL,
"transferperiod" smallint CHECK ("transferperiod" >= 0) default NULL,
"reneweddate" timestamp(3) without time zone default NULL,
"agp_exempted" BOOLEAN DEFAULT FALSE,
"agp_request" TIMESTAMP(3) DEFAULT NULL,
"agp_grant" TIMESTAMP(3) DEFAULT NULL,
"agp_reason" TEXT DEFAULT NULL,
"agp_status" VARCHAR(30) DEFAULT NULL,
"tm_notice_accepted" TIMESTAMP(3) DEFAULT NULL, "tm_notice_accepted" TIMESTAMP(3) DEFAULT NULL,
"tm_notice_expires" TIMESTAMP(3) DEFAULT NULL, "tm_notice_expires" TIMESTAMP(3) DEFAULT NULL,
"tm_notice_id" VARCHAR(150) DEFAULT NULL, "tm_notice_id" VARCHAR(150) DEFAULT NULL,
@ -408,6 +394,15 @@ CREATE TABLE registry.domain_contact_map (
unique ("domain_id", "contact_id", "type") unique ("domain_id", "contact_id", "type")
); );
CREATE TABLE registry.application_contact_map (
"id" serial8,
"domain_id" int CHECK ("domain_id" >= 0) NOT NULL,
"contact_id" int CHECK ("contact_id" >= 0) NOT NULL,
"type" varchar CHECK ("type" IN ( 'admin','billing','tech' )) NOT NULL default 'admin',
primary key ("id"),
unique ("domain_id", "contact_id", "type")
);
CREATE TABLE registry.domain_authinfo ( CREATE TABLE registry.domain_authinfo (
"id" serial8, "id" serial8,
"domain_id" int CHECK ("domain_id" >= 0) NOT NULL, "domain_id" int CHECK ("domain_id" >= 0) NOT NULL,
@ -425,6 +420,14 @@ CREATE TABLE registry.domain_status (
unique ("domain_id", "status") unique ("domain_id", "status")
); );
CREATE TABLE registry.application_status (
"id" serial8,
"domain_id" int CHECK ("domain_id" >= 0) NOT NULL,
"status" varchar CHECK ("status" IN ( 'pendingValidation','validated','invalid','pendingAllocation','allocated','rejected','custom' )) NOT NULL default 'pendingValidation',
primary key ("id"),
unique ("domain_id", "status")
);
CREATE TABLE registry.secdns ( CREATE TABLE registry.secdns (
"id" serial8, "id" serial8,
"domain_id" int CHECK ("domain_id" >= 0) NOT NULL, "domain_id" int CHECK ("domain_id" >= 0) NOT NULL,
@ -464,6 +467,14 @@ CREATE TABLE registry.domain_host_map (
unique ("domain_id", "host_id") unique ("domain_id", "host_id")
); );
CREATE TABLE registry.application_host_map (
"id" serial8,
"domain_id" int CHECK ("domain_id" >= 0) NOT NULL,
"host_id" int CHECK ("host_id" >= 0) NOT NULL,
primary key ("id"),
unique ("domain_id", "host_id")
);
CREATE TABLE registry.host_addr ( CREATE TABLE registry.host_addr (
"id" serial8, "id" serial8,
"host_id" int CHECK ("host_id" >= 0) NOT NULL, "host_id" int CHECK ("host_id" >= 0) NOT NULL,
@ -836,8 +847,11 @@ ALTER TABLE registry.domain ADD FOREIGN KEY ("acid") REFERENCES registry.registr
ALTER TABLE registry.domain ADD FOREIGN KEY ("tldid") REFERENCES registry.domain_tld ("id"); ALTER TABLE registry.domain ADD FOREIGN KEY ("tldid") REFERENCES registry.domain_tld ("id");
ALTER TABLE registry.domain_contact_map ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id"); ALTER TABLE registry.domain_contact_map ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id");
ALTER TABLE registry.domain_contact_map ADD FOREIGN KEY ("contact_id") REFERENCES registry.contact ("id"); ALTER TABLE registry.domain_contact_map ADD FOREIGN KEY ("contact_id") REFERENCES registry.contact ("id");
ALTER TABLE registry.application_contact_map ADD FOREIGN KEY ("domain_id") REFERENCES registry.application ("id");
ALTER TABLE registry.application_contact_map ADD FOREIGN KEY ("contact_id") REFERENCES registry.contact ("id");
ALTER TABLE registry.domain_authinfo ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id"); ALTER TABLE registry.domain_authinfo ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id");
ALTER TABLE registry.domain_status ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id"); ALTER TABLE registry.domain_status ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id");
ALTER TABLE registry.application_status ADD FOREIGN KEY ("domain_id") REFERENCES registry.application ("id");
ALTER TABLE registry.secdns ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id"); ALTER TABLE registry.secdns ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id");
ALTER TABLE registry.host ADD FOREIGN KEY ("clid") REFERENCES registry.registrar ("id"); ALTER TABLE registry.host ADD FOREIGN KEY ("clid") REFERENCES registry.registrar ("id");
ALTER TABLE registry.host ADD FOREIGN KEY ("crid") REFERENCES registry.registrar ("id"); ALTER TABLE registry.host ADD FOREIGN KEY ("crid") REFERENCES registry.registrar ("id");
@ -845,6 +859,8 @@ ALTER TABLE registry.host ADD FOREIGN KEY ("upid") REFERENCES registry.registrar
ALTER TABLE registry.host ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id"); ALTER TABLE registry.host ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id");
ALTER TABLE registry.domain_host_map ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id"); ALTER TABLE registry.domain_host_map ADD FOREIGN KEY ("domain_id") REFERENCES registry.domain ("id");
ALTER TABLE registry.domain_host_map ADD FOREIGN KEY ("host_id") REFERENCES registry.host ("id"); ALTER TABLE registry.domain_host_map ADD FOREIGN KEY ("host_id") REFERENCES registry.host ("id");
ALTER TABLE registry.application_host_map ADD FOREIGN KEY ("domain_id") REFERENCES registry.application ("id");
ALTER TABLE registry.application_host_map ADD FOREIGN KEY ("host_id") REFERENCES registry.host ("id");
ALTER TABLE registry.host_addr ADD FOREIGN KEY ("host_id") REFERENCES registry.host ("id"); ALTER TABLE registry.host_addr ADD FOREIGN KEY ("host_id") REFERENCES registry.host ("id");
ALTER TABLE registry.host_status ADD FOREIGN KEY ("host_id") REFERENCES registry.host ("id"); ALTER TABLE registry.host_status ADD FOREIGN KEY ("host_id") REFERENCES registry.host ("id");