Switch PHP views to Twig and add 2FA/UI enhancements
Migrate many view templates from raw PHP to Twig and modernize UI/UX for 2FA and settings. Controllers updated to provide avatar data and two-factor info (ProfileController, UserController) and SettingsController now includes timezone lists, notification preset selection, cron path, cached update state and rollback availability. ErrorHandler now attempts to render error pages via a new Core\TwigService with a safe fallback to raw PHP views. TwoFactorService generation silences deprecated warnings during QR code creation. Numerous .php view files were removed and replaced with .twig equivalents (2fa setup/verify/backup-codes and many auth, dashboard, domains, errors, layout, users, tags, tld-registry, etc.), and core/TwigService was added. These changes move the app toward a Twig-based templating system, improve 2FA flows, surface avatar images in lists/profiles, and make error rendering more robust.
2026-03-03 18:21:32 +02:00
|
|
|
{% extends 'layout/base.twig' %}
|
|
|
|
|
|
|
|
|
|
{% set title = 'TLD Details' %}
|
|
|
|
|
{% set pageTitle = tld.tld %}
|
|
|
|
|
{% set pageDescription = 'TLD registry information and server details' %}
|
|
|
|
|
{% set pageIcon = 'fas fa-globe' %}
|
|
|
|
|
|
|
|
|
|
{% block content %}
|
|
|
|
|
|
|
|
|
|
{# Top Action Bar #}
|
|
|
|
|
<div class="mb-3 flex flex-wrap gap-2 justify-between items-center">
|
|
|
|
|
<div class="flex gap-2">
|
|
|
|
|
<span class="inline-flex items-center px-3 py-1.5 rounded-lg text-xs font-semibold bg-primary text-white">
|
|
|
|
|
<i class="fas fa-globe mr-1.5"></i>
|
|
|
|
|
TLD Registry
|
|
|
|
|
</span>
|
|
|
|
|
<span class="inline-flex items-center px-3 py-1.5 rounded-lg text-xs font-semibold {{ tld.is_active ? 'bg-green-100 dark:bg-green-500/10 text-green-700 dark:text-green-400 border border-green-200 dark:border-green-500/30' : 'bg-gray-100 dark:bg-slate-700 text-gray-700 dark:text-slate-300 border border-gray-200 dark:border-slate-600' }}">
|
|
|
|
|
<i class="fas {{ tld.is_active ? 'fa-check-circle' : 'fa-pause-circle' }} mr-1.5"></i>
|
|
|
|
|
{{ tld.is_active ? 'Active' : 'Inactive' }}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex gap-2 items-center">
|
|
|
|
|
{% if session.role is defined and session.role == 'admin' %}
|
Enhance DNS discovery, validation & transfers
Add comprehensive DNS management and input validation, plus safer transfer and logging behavior.
- Add CronHelper utilities for cron scripts and unify logging/formatting.
- Improve InputValidator: sanitizeDomainInput and validateRootDomain (handles multi-level TLDs) and use throughout domain import/create flows to reject subdomains.
- DomainController: refactor DNS refresh to support quick/deep discovery (background deep scans), add endpoints to discover, add/delete/bulk-delete DNS records, import BIND zone files, enrich IP metadata via enrichIpDetails, and strengthen bulk import/reporting messages.
- DnsRecord model: add source column handling (discovered/manual/imported), avoid auto-deleting manual/imported records, and add helpers for deleting, bulk deleting, manual adding and importing zone records.
- Tag, NotificationGroup and Domain transfer logic: unlink groups when ownership changes, remove tags that belong to other users, add audit logging via Logger and improved bulk transfer reporting. TagController/View: show transferable users for admins and skip global tags on transfer.
- Notification channels (Discord, Mattermost, etc.) and EmailHelper: allow explicit subjects and improve payload fields based on notification type.
- Add new migration 029_add_dns_record_source.sql and wire it into the installer; update migrations detection.
- Add new views/partials for confirm/import/transfer modals, update various domain/group/tag templates, and update cron scripts and routes for discovery.
These changes preserve manual/imported DNS records, improve root-domain validation, enable background deep discovery, and add better logging/audit trails for transfers and imports.
2026-03-10 22:54:28 +02:00
|
|
|
<a href="/tld-registry/{{ tld.id }}/refresh" class="inline-flex items-center justify-center px-3 py-2 bg-green-600 text-white text-xs rounded-lg hover:bg-green-700 transition-colors font-medium min-w-[80px] h-[32px]" onclick="return confirmClick(event, 'Refresh TLD data from IANA?', { title: 'Refresh TLD', icon: 'fa-sync text-green-500', confirmText: 'Refresh', confirmClass: 'bg-green-600 hover:bg-green-700' })">
|
Switch PHP views to Twig and add 2FA/UI enhancements
Migrate many view templates from raw PHP to Twig and modernize UI/UX for 2FA and settings. Controllers updated to provide avatar data and two-factor info (ProfileController, UserController) and SettingsController now includes timezone lists, notification preset selection, cron path, cached update state and rollback availability. ErrorHandler now attempts to render error pages via a new Core\TwigService with a safe fallback to raw PHP views. TwoFactorService generation silences deprecated warnings during QR code creation. Numerous .php view files were removed and replaced with .twig equivalents (2fa setup/verify/backup-codes and many auth, dashboard, domains, errors, layout, users, tags, tld-registry, etc.), and core/TwigService was added. These changes move the app toward a Twig-based templating system, improve 2FA flows, surface avatar images in lists/profiles, and make error rendering more robust.
2026-03-03 18:21:32 +02:00
|
|
|
<i class="fas fa-sync-alt mr-1.5"></i>
|
|
|
|
|
Refresh
|
|
|
|
|
</a>
|
Enhance DNS discovery, validation & transfers
Add comprehensive DNS management and input validation, plus safer transfer and logging behavior.
- Add CronHelper utilities for cron scripts and unify logging/formatting.
- Improve InputValidator: sanitizeDomainInput and validateRootDomain (handles multi-level TLDs) and use throughout domain import/create flows to reject subdomains.
- DomainController: refactor DNS refresh to support quick/deep discovery (background deep scans), add endpoints to discover, add/delete/bulk-delete DNS records, import BIND zone files, enrich IP metadata via enrichIpDetails, and strengthen bulk import/reporting messages.
- DnsRecord model: add source column handling (discovered/manual/imported), avoid auto-deleting manual/imported records, and add helpers for deleting, bulk deleting, manual adding and importing zone records.
- Tag, NotificationGroup and Domain transfer logic: unlink groups when ownership changes, remove tags that belong to other users, add audit logging via Logger and improved bulk transfer reporting. TagController/View: show transferable users for admins and skip global tags on transfer.
- Notification channels (Discord, Mattermost, etc.) and EmailHelper: allow explicit subjects and improve payload fields based on notification type.
- Add new migration 029_add_dns_record_source.sql and wire it into the installer; update migrations detection.
- Add new views/partials for confirm/import/transfer modals, update various domain/group/tag templates, and update cron scripts and routes for discovery.
These changes preserve manual/imported DNS records, improve root-domain validation, enable background deep discovery, and add better logging/audit trails for transfers and imports.
2026-03-10 22:54:28 +02:00
|
|
|
<a href="/tld-registry/{{ tld.id }}/toggle-active" class="inline-flex items-center justify-center px-3 py-2 bg-orange-600 text-white text-xs rounded-lg hover:bg-orange-700 transition-colors font-medium min-w-[80px] h-[32px]" onclick="return confirmClick(event, 'Toggle TLD status?', { title: 'Toggle Status', icon: 'fa-toggle-on text-orange-500', confirmText: 'Toggle', confirmClass: 'bg-orange-600 hover:bg-orange-700' })">
|
Switch PHP views to Twig and add 2FA/UI enhancements
Migrate many view templates from raw PHP to Twig and modernize UI/UX for 2FA and settings. Controllers updated to provide avatar data and two-factor info (ProfileController, UserController) and SettingsController now includes timezone lists, notification preset selection, cron path, cached update state and rollback availability. ErrorHandler now attempts to render error pages via a new Core\TwigService with a safe fallback to raw PHP views. TwoFactorService generation silences deprecated warnings during QR code creation. Numerous .php view files were removed and replaced with .twig equivalents (2fa setup/verify/backup-codes and many auth, dashboard, domains, errors, layout, users, tags, tld-registry, etc.), and core/TwigService was added. These changes move the app toward a Twig-based templating system, improve 2FA flows, surface avatar images in lists/profiles, and make error rendering more robust.
2026-03-03 18:21:32 +02:00
|
|
|
<i class="fas fa-power-off mr-1.5"></i>
|
|
|
|
|
Toggle
|
|
|
|
|
</a>
|
|
|
|
|
{% endif %}
|
|
|
|
|
<a href="/tld-registry" class="inline-flex items-center justify-center px-3 py-2 border border-gray-300 dark:border-slate-600 text-gray-700 dark:text-slate-300 text-xs rounded-lg hover:bg-gray-50 dark:hover:bg-slate-700 transition-colors font-medium min-w-[80px] h-[32px]">
|
|
|
|
|
<i class="fas fa-arrow-left mr-1.5"></i>
|
|
|
|
|
Back
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# Main 2-Column Layout #}
|
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-3">
|
|
|
|
|
|
|
|
|
|
{# LEFT COLUMN #}
|
|
|
|
|
<div class="space-y-3">
|
|
|
|
|
|
|
|
|
|
{# TLD Information #}
|
|
|
|
|
<div class="bg-white dark:bg-slate-800 rounded-lg border border-gray-200 dark:border-slate-700 overflow-hidden">
|
|
|
|
|
<div class="px-4 py-2 border-b border-gray-200 dark:border-slate-700 bg-gray-50 dark:bg-slate-900">
|
|
|
|
|
<h3 class="text-xs font-semibold text-gray-700 dark:text-slate-300 uppercase tracking-wider flex items-center">
|
|
|
|
|
<i class="fas fa-info-circle text-gray-400 dark:text-slate-500 mr-2" style="font-size: 10px;"></i>
|
|
|
|
|
TLD Information
|
|
|
|
|
</h3>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="p-4">
|
|
|
|
|
<div class="grid grid-cols-2 gap-x-4 gap-y-3 text-xs">
|
|
|
|
|
<div>
|
|
|
|
|
<label class="text-gray-500 dark:text-slate-400 font-medium block mb-0.5">TLD</label>
|
|
|
|
|
<p class="text-gray-900 dark:text-white font-semibold">{{ tld.tld }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
{% if tld.registry_url %}
|
|
|
|
|
<div>
|
|
|
|
|
<label class="text-gray-500 dark:text-slate-400 font-medium block mb-0.5">Registry URL</label>
|
Improve security, validation, and isolation checks
Add multiple security and validation improvements across the app:
- Prevent session fixation: regenerate session ID on login and after successful 2FA; tighten session cookie params (Secure, HttpOnly, SameSite=Lax).
- Harden installer: add CSRF checks for install/update flows and use PDO::quote when injecting admin credentials into SQL migration to avoid injection; add csrf_field() to installer templates.
- Template hardening: add safe_url and safe_mailto Twig filters, escape tag names for JS, and add rel="noopener noreferrer" to external links to mitigate XSS/opener risks.
- Domain controller: validate referrer to avoid open redirects, enforce user isolation mode when finding/deleting/updating domains and when assigning notification groups (ensures users only affect their own resources).
- Notification groups: verify channel belongs to group before deleting or toggling to prevent unauthorized access.
- ErrorLog: whitelist allowed sort columns to avoid arbitrary column injection in ORDER BY.
- Routes: move the debug whois route to protected/admin area.
These changes collectively reduce attack surface (XSS, open redirect, session fixation, SQL injection) and enforce proper resource isolation and input validation.
2026-03-11 00:03:54 +02:00
|
|
|
<a href="{{ tld.registry_url|safe_url }}" target="_blank" rel="noopener noreferrer" class="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 flex items-center">
|
Switch PHP views to Twig and add 2FA/UI enhancements
Migrate many view templates from raw PHP to Twig and modernize UI/UX for 2FA and settings. Controllers updated to provide avatar data and two-factor info (ProfileController, UserController) and SettingsController now includes timezone lists, notification preset selection, cron path, cached update state and rollback availability. ErrorHandler now attempts to render error pages via a new Core\TwigService with a safe fallback to raw PHP views. TwoFactorService generation silences deprecated warnings during QR code creation. Numerous .php view files were removed and replaced with .twig equivalents (2fa setup/verify/backup-codes and many auth, dashboard, domains, errors, layout, users, tags, tld-registry, etc.), and core/TwigService was added. These changes move the app toward a Twig-based templating system, improve 2FA flows, surface avatar images in lists/profiles, and make error rendering more robust.
2026-03-03 18:21:32 +02:00
|
|
|
<i class="fas fa-external-link-alt mr-1" style="font-size: 9px;"></i>
|
|
|
|
|
Visit Registry
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% if tld.registration_date %}
|
|
|
|
|
<div>
|
|
|
|
|
<label class="text-gray-500 dark:text-slate-400 font-medium block mb-0.5">Registration Date</label>
|
|
|
|
|
<p class="text-gray-900 dark:text-white">{{ tld.registration_date|date('M j, Y') }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% if tld.record_last_updated %}
|
|
|
|
|
<div>
|
|
|
|
|
<label class="text-gray-500 dark:text-slate-400 font-medium block mb-0.5">Record Last Updated</label>
|
|
|
|
|
<p class="text-gray-900 dark:text-white">{{ tld.record_last_updated|date('M j, Y') }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# RDAP Servers #}
|
|
|
|
|
<div class="bg-white dark:bg-slate-800 rounded-lg border border-gray-200 dark:border-slate-700 overflow-hidden">
|
|
|
|
|
<div class="px-4 py-2 border-b border-gray-200 dark:border-slate-700 bg-gray-50 dark:bg-slate-900 flex items-center justify-between">
|
|
|
|
|
<h3 class="text-xs font-semibold text-gray-700 dark:text-slate-300 uppercase tracking-wider flex items-center">
|
|
|
|
|
<i class="fas fa-database text-gray-400 dark:text-slate-500 mr-2" style="font-size: 10px;"></i>
|
|
|
|
|
RDAP Servers
|
|
|
|
|
{% if tld.rdap_servers %}
|
|
|
|
|
{% set rdapServers = tld.rdap_servers|from_json %}
|
|
|
|
|
{% if rdapServers is iterable and rdapServers is not empty %}
|
|
|
|
|
({{ rdapServers|length }})
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% endif %}
|
|
|
|
|
</h3>
|
|
|
|
|
{% if session.role is defined and session.role == 'admin' %}
|
|
|
|
|
<button onclick="openEditRdapModal()" class="inline-flex items-center px-2 py-1 bg-blue-600 text-white text-xs rounded hover:bg-blue-700 transition-colors font-medium">
|
|
|
|
|
<i class="fas fa-edit mr-1" style="font-size: 9px;"></i>
|
|
|
|
|
Edit
|
|
|
|
|
</button>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
<div class="p-4">
|
|
|
|
|
{% if tld.rdap_servers %}
|
|
|
|
|
{% set rdapServers = tld.rdap_servers|from_json %}
|
|
|
|
|
{% if rdapServers is iterable and rdapServers is not empty %}
|
|
|
|
|
<div class="space-y-1.5">
|
|
|
|
|
{% for server in rdapServers %}
|
|
|
|
|
<div class="flex items-center p-2 bg-gray-50 dark:bg-slate-700 rounded hover:bg-gray-100 dark:hover:bg-slate-600 transition-colors">
|
|
|
|
|
<div class="w-6 h-6 bg-indigo-500 rounded flex items-center justify-center text-white font-bold text-xs mr-2">
|
|
|
|
|
{{ loop.index }}
|
|
|
|
|
</div>
|
|
|
|
|
<p class="font-mono text-xs text-gray-800 dark:text-slate-200">{{ server }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
{% endfor %}
|
|
|
|
|
</div>
|
|
|
|
|
{% else %}
|
|
|
|
|
<p class="text-xs text-gray-400 dark:text-slate-500 italic">No RDAP servers configured</p>
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% else %}
|
|
|
|
|
<p class="text-xs text-gray-400 dark:text-slate-500 italic">No RDAP servers configured</p>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# WHOIS Server #}
|
|
|
|
|
<div class="bg-white dark:bg-slate-800 rounded-lg border border-gray-200 dark:border-slate-700 overflow-hidden">
|
|
|
|
|
<div class="px-4 py-2 border-b border-gray-200 dark:border-slate-700 bg-gray-50 dark:bg-slate-900 flex items-center justify-between">
|
|
|
|
|
<h3 class="text-xs font-semibold text-gray-700 dark:text-slate-300 uppercase tracking-wider flex items-center">
|
|
|
|
|
<i class="fas fa-server text-gray-400 dark:text-slate-500 mr-2" style="font-size: 10px;"></i>
|
|
|
|
|
WHOIS Server
|
|
|
|
|
</h3>
|
|
|
|
|
{% if session.role is defined and session.role == 'admin' %}
|
|
|
|
|
<button onclick="openEditWhoisModal()" class="inline-flex items-center px-2 py-1 bg-blue-600 text-white text-xs rounded hover:bg-blue-700 transition-colors font-medium">
|
|
|
|
|
<i class="fas fa-edit mr-1" style="font-size: 9px;"></i>
|
|
|
|
|
Edit
|
|
|
|
|
</button>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
<div class="p-4">
|
|
|
|
|
{% if tld.whois_server %}
|
|
|
|
|
<div class="flex items-center p-2 bg-gray-50 dark:bg-slate-700 rounded">
|
|
|
|
|
<div class="w-6 h-6 bg-orange-500 rounded flex items-center justify-center text-white font-bold text-xs mr-2">
|
|
|
|
|
<i class="fas fa-server"></i>
|
|
|
|
|
</div>
|
|
|
|
|
<p class="font-mono text-xs text-gray-800 dark:text-slate-200">{{ tld.whois_server }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
{% else %}
|
|
|
|
|
<p class="text-xs text-gray-400 dark:text-slate-500 italic">No WHOIS server configured</p>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# RIGHT COLUMN #}
|
|
|
|
|
<div class="space-y-3">
|
|
|
|
|
|
|
|
|
|
{# Import History #}
|
|
|
|
|
<div class="bg-white dark:bg-slate-800 rounded-lg border border-gray-200 dark:border-slate-700 overflow-hidden">
|
|
|
|
|
<div class="px-4 py-2 border-b border-gray-200 dark:border-slate-700 bg-gray-50 dark:bg-slate-900">
|
|
|
|
|
<h3 class="text-xs font-semibold text-gray-700 dark:text-slate-300 uppercase tracking-wider flex items-center">
|
|
|
|
|
<i class="fas fa-history text-gray-400 dark:text-slate-500 mr-2" style="font-size: 10px;"></i>
|
|
|
|
|
Import History
|
|
|
|
|
</h3>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="p-4">
|
|
|
|
|
<div class="space-y-2">
|
|
|
|
|
<div class="flex items-center p-2 bg-blue-50 dark:bg-blue-500/10 rounded border border-blue-200 dark:border-blue-500/30">
|
|
|
|
|
<div class="w-7 h-7 bg-blue-500 rounded flex items-center justify-center mr-2">
|
|
|
|
|
<i class="fas fa-plus text-white text-xs"></i>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<p class="text-xs text-gray-600 dark:text-slate-400 font-medium">Created</p>
|
|
|
|
|
<p class="text-xs font-semibold text-gray-900 dark:text-white">{{ tld.created_at|date('M j, Y H:i') }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{% if tld.updated_at %}
|
|
|
|
|
<div class="flex items-center p-2 bg-green-50 dark:bg-green-500/10 rounded border border-green-200 dark:border-green-500/30">
|
|
|
|
|
<div class="w-7 h-7 bg-green-500 rounded flex items-center justify-center mr-2">
|
|
|
|
|
<i class="fas fa-sync text-white text-xs"></i>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<p class="text-xs text-gray-600 dark:text-slate-400 font-medium">Last Updated</p>
|
|
|
|
|
<p class="text-xs font-semibold text-gray-900 dark:text-white">{{ tld.updated_at|date('M j, Y H:i') }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
|
|
|
|
{% if tld.iana_publication_date %}
|
|
|
|
|
<div class="flex items-center p-2 bg-indigo-50 dark:bg-indigo-500/10 rounded border border-indigo-200 dark:border-indigo-500/30">
|
|
|
|
|
<div class="w-7 h-7 bg-indigo-500 rounded flex items-center justify-center mr-2">
|
|
|
|
|
<i class="fas fa-calendar text-white text-xs"></i>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<p class="text-xs text-gray-600 dark:text-slate-400 font-medium">IANA Publication</p>
|
|
|
|
|
<p class="text-xs font-semibold text-gray-900 dark:text-white">{{ tld.iana_publication_date|date('M j, Y H:i') }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# Quick Actions #}
|
|
|
|
|
<div class="bg-white dark:bg-slate-800 rounded-lg border border-gray-200 dark:border-slate-700 overflow-hidden">
|
|
|
|
|
<div class="px-4 py-2 border-b border-gray-200 dark:border-slate-700 bg-gray-50 dark:bg-slate-900">
|
|
|
|
|
<h3 class="text-xs font-semibold text-gray-700 dark:text-slate-300 uppercase tracking-wider flex items-center">
|
|
|
|
|
<i class="fas fa-bolt text-gray-400 dark:text-slate-500 mr-2" style="font-size: 10px;"></i>
|
|
|
|
|
Quick Actions
|
|
|
|
|
</h3>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="p-4 space-y-2">
|
|
|
|
|
{% if session.role is defined and session.role == 'admin' %}
|
Enhance DNS discovery, validation & transfers
Add comprehensive DNS management and input validation, plus safer transfer and logging behavior.
- Add CronHelper utilities for cron scripts and unify logging/formatting.
- Improve InputValidator: sanitizeDomainInput and validateRootDomain (handles multi-level TLDs) and use throughout domain import/create flows to reject subdomains.
- DomainController: refactor DNS refresh to support quick/deep discovery (background deep scans), add endpoints to discover, add/delete/bulk-delete DNS records, import BIND zone files, enrich IP metadata via enrichIpDetails, and strengthen bulk import/reporting messages.
- DnsRecord model: add source column handling (discovered/manual/imported), avoid auto-deleting manual/imported records, and add helpers for deleting, bulk deleting, manual adding and importing zone records.
- Tag, NotificationGroup and Domain transfer logic: unlink groups when ownership changes, remove tags that belong to other users, add audit logging via Logger and improved bulk transfer reporting. TagController/View: show transferable users for admins and skip global tags on transfer.
- Notification channels (Discord, Mattermost, etc.) and EmailHelper: allow explicit subjects and improve payload fields based on notification type.
- Add new migration 029_add_dns_record_source.sql and wire it into the installer; update migrations detection.
- Add new views/partials for confirm/import/transfer modals, update various domain/group/tag templates, and update cron scripts and routes for discovery.
These changes preserve manual/imported DNS records, improve root-domain validation, enable background deep discovery, and add better logging/audit trails for transfers and imports.
2026-03-10 22:54:28 +02:00
|
|
|
<a href="/tld-registry/{{ tld.id }}/refresh" class="flex items-center p-3 border border-gray-200 dark:border-slate-700 hover:border-green-500 hover:bg-green-50 dark:hover:bg-green-500/10 rounded-lg transition-all duration-200 group" onclick="return confirmClick(event, 'Refresh TLD data from IANA?', { title: 'Refresh TLD', icon: 'fa-sync text-green-500', confirmText: 'Refresh', confirmClass: 'bg-green-600 hover:bg-green-700' })">
|
Switch PHP views to Twig and add 2FA/UI enhancements
Migrate many view templates from raw PHP to Twig and modernize UI/UX for 2FA and settings. Controllers updated to provide avatar data and two-factor info (ProfileController, UserController) and SettingsController now includes timezone lists, notification preset selection, cron path, cached update state and rollback availability. ErrorHandler now attempts to render error pages via a new Core\TwigService with a safe fallback to raw PHP views. TwoFactorService generation silences deprecated warnings during QR code creation. Numerous .php view files were removed and replaced with .twig equivalents (2fa setup/verify/backup-codes and many auth, dashboard, domains, errors, layout, users, tags, tld-registry, etc.), and core/TwigService was added. These changes move the app toward a Twig-based templating system, improve 2FA flows, surface avatar images in lists/profiles, and make error rendering more robust.
2026-03-03 18:21:32 +02:00
|
|
|
<div class="w-9 h-9 bg-green-50 dark:bg-green-500/10 group-hover:bg-green-500 rounded-lg flex items-center justify-center group-hover:text-white text-green-600 dark:text-green-400 transition-colors duration-200">
|
|
|
|
|
<i class="fas fa-sync-alt text-sm"></i>
|
|
|
|
|
</div>
|
|
|
|
|
<span class="ml-3 text-sm font-medium text-gray-700 dark:text-slate-300 group-hover:text-green-700 dark:group-hover:text-green-400">Refresh from IANA</span>
|
|
|
|
|
</a>
|
Enhance DNS discovery, validation & transfers
Add comprehensive DNS management and input validation, plus safer transfer and logging behavior.
- Add CronHelper utilities for cron scripts and unify logging/formatting.
- Improve InputValidator: sanitizeDomainInput and validateRootDomain (handles multi-level TLDs) and use throughout domain import/create flows to reject subdomains.
- DomainController: refactor DNS refresh to support quick/deep discovery (background deep scans), add endpoints to discover, add/delete/bulk-delete DNS records, import BIND zone files, enrich IP metadata via enrichIpDetails, and strengthen bulk import/reporting messages.
- DnsRecord model: add source column handling (discovered/manual/imported), avoid auto-deleting manual/imported records, and add helpers for deleting, bulk deleting, manual adding and importing zone records.
- Tag, NotificationGroup and Domain transfer logic: unlink groups when ownership changes, remove tags that belong to other users, add audit logging via Logger and improved bulk transfer reporting. TagController/View: show transferable users for admins and skip global tags on transfer.
- Notification channels (Discord, Mattermost, etc.) and EmailHelper: allow explicit subjects and improve payload fields based on notification type.
- Add new migration 029_add_dns_record_source.sql and wire it into the installer; update migrations detection.
- Add new views/partials for confirm/import/transfer modals, update various domain/group/tag templates, and update cron scripts and routes for discovery.
These changes preserve manual/imported DNS records, improve root-domain validation, enable background deep discovery, and add better logging/audit trails for transfers and imports.
2026-03-10 22:54:28 +02:00
|
|
|
<a href="/tld-registry/{{ tld.id }}/toggle-active" class="flex items-center p-3 border border-gray-200 dark:border-slate-700 hover:border-orange-500 hover:bg-orange-50 dark:hover:bg-orange-500/10 rounded-lg transition-all duration-200 group" onclick="return confirmClick(event, 'Toggle TLD status?', { title: 'Toggle Status', icon: 'fa-toggle-on text-orange-500', confirmText: 'Toggle', confirmClass: 'bg-orange-600 hover:bg-orange-700' })">
|
Switch PHP views to Twig and add 2FA/UI enhancements
Migrate many view templates from raw PHP to Twig and modernize UI/UX for 2FA and settings. Controllers updated to provide avatar data and two-factor info (ProfileController, UserController) and SettingsController now includes timezone lists, notification preset selection, cron path, cached update state and rollback availability. ErrorHandler now attempts to render error pages via a new Core\TwigService with a safe fallback to raw PHP views. TwoFactorService generation silences deprecated warnings during QR code creation. Numerous .php view files were removed and replaced with .twig equivalents (2fa setup/verify/backup-codes and many auth, dashboard, domains, errors, layout, users, tags, tld-registry, etc.), and core/TwigService was added. These changes move the app toward a Twig-based templating system, improve 2FA flows, surface avatar images in lists/profiles, and make error rendering more robust.
2026-03-03 18:21:32 +02:00
|
|
|
<div class="w-9 h-9 bg-orange-50 dark:bg-orange-500/10 group-hover:bg-orange-500 rounded-lg flex items-center justify-center group-hover:text-white text-orange-600 dark:text-orange-400 transition-colors duration-200">
|
|
|
|
|
<i class="fas fa-power-off text-sm"></i>
|
|
|
|
|
</div>
|
|
|
|
|
<span class="ml-3 text-sm font-medium text-gray-700 dark:text-slate-300 group-hover:text-orange-700 dark:group-hover:text-orange-400">Toggle Status</span>
|
|
|
|
|
</a>
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% if tld.registry_url %}
|
Improve security, validation, and isolation checks
Add multiple security and validation improvements across the app:
- Prevent session fixation: regenerate session ID on login and after successful 2FA; tighten session cookie params (Secure, HttpOnly, SameSite=Lax).
- Harden installer: add CSRF checks for install/update flows and use PDO::quote when injecting admin credentials into SQL migration to avoid injection; add csrf_field() to installer templates.
- Template hardening: add safe_url and safe_mailto Twig filters, escape tag names for JS, and add rel="noopener noreferrer" to external links to mitigate XSS/opener risks.
- Domain controller: validate referrer to avoid open redirects, enforce user isolation mode when finding/deleting/updating domains and when assigning notification groups (ensures users only affect their own resources).
- Notification groups: verify channel belongs to group before deleting or toggling to prevent unauthorized access.
- ErrorLog: whitelist allowed sort columns to avoid arbitrary column injection in ORDER BY.
- Routes: move the debug whois route to protected/admin area.
These changes collectively reduce attack surface (XSS, open redirect, session fixation, SQL injection) and enforce proper resource isolation and input validation.
2026-03-11 00:03:54 +02:00
|
|
|
<a href="{{ tld.registry_url|safe_url }}" target="_blank" rel="noopener noreferrer" class="flex items-center p-3 border border-gray-200 dark:border-slate-700 hover:border-blue-500 hover:bg-blue-50 dark:hover:bg-blue-500/10 rounded-lg transition-all duration-200 group">
|
Switch PHP views to Twig and add 2FA/UI enhancements
Migrate many view templates from raw PHP to Twig and modernize UI/UX for 2FA and settings. Controllers updated to provide avatar data and two-factor info (ProfileController, UserController) and SettingsController now includes timezone lists, notification preset selection, cron path, cached update state and rollback availability. ErrorHandler now attempts to render error pages via a new Core\TwigService with a safe fallback to raw PHP views. TwoFactorService generation silences deprecated warnings during QR code creation. Numerous .php view files were removed and replaced with .twig equivalents (2fa setup/verify/backup-codes and many auth, dashboard, domains, errors, layout, users, tags, tld-registry, etc.), and core/TwigService was added. These changes move the app toward a Twig-based templating system, improve 2FA flows, surface avatar images in lists/profiles, and make error rendering more robust.
2026-03-03 18:21:32 +02:00
|
|
|
<div class="w-9 h-9 bg-blue-50 dark:bg-blue-500/10 group-hover:bg-blue-500 rounded-lg flex items-center justify-center group-hover:text-white text-blue-600 dark:text-blue-400 transition-colors duration-200">
|
|
|
|
|
<i class="fas fa-external-link-alt text-sm"></i>
|
|
|
|
|
</div>
|
|
|
|
|
<span class="ml-3 text-sm font-medium text-gray-700 dark:text-slate-300 group-hover:text-blue-700 dark:group-hover:text-blue-400">Visit Registry</span>
|
|
|
|
|
</a>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# Raw Data (Collapsible) #}
|
|
|
|
|
<div class="bg-white dark:bg-slate-800 rounded-lg border border-gray-200 dark:border-slate-700 overflow-hidden">
|
|
|
|
|
<button onclick="toggleRawData()" class="w-full px-4 py-2 border-b border-gray-200 dark:border-slate-700 bg-gray-50 dark:bg-slate-900 text-left hover:bg-gray-100 dark:hover:bg-slate-700 transition-colors">
|
|
|
|
|
<h3 class="text-xs font-semibold text-gray-700 dark:text-slate-300 uppercase tracking-wider flex items-center justify-between">
|
|
|
|
|
<span class="flex items-center">
|
|
|
|
|
<i class="fas fa-code text-gray-400 dark:text-slate-500 mr-2" style="font-size: 10px;"></i>
|
|
|
|
|
Raw TLD Data
|
|
|
|
|
</span>
|
|
|
|
|
<i class="fas fa-chevron-down text-gray-400 dark:text-slate-500 text-xs transition-transform" id="raw-data-chevron"></i>
|
|
|
|
|
</h3>
|
|
|
|
|
</button>
|
|
|
|
|
<div id="raw-data" class="hidden p-4 bg-gray-900 max-h-64 overflow-y-auto">
|
|
|
|
|
{% set rawData = {
|
|
|
|
|
tld: tld.tld,
|
|
|
|
|
rdap_servers: tld.rdap_servers ? tld.rdap_servers|from_json : null,
|
|
|
|
|
whois_server: tld.whois_server,
|
|
|
|
|
registry_url: tld.registry_url,
|
|
|
|
|
registration_date: tld.registration_date,
|
|
|
|
|
record_last_updated: tld.record_last_updated,
|
|
|
|
|
iana_publication_date: tld.iana_publication_date,
|
|
|
|
|
is_active: tld.is_active,
|
|
|
|
|
created_at: tld.created_at,
|
|
|
|
|
updated_at: tld.updated_at
|
|
|
|
|
} %}
|
|
|
|
|
<pre class="text-xs text-green-400 font-mono">{{ rawData|json_encode(constant('JSON_PRETTY_PRINT'))|e }}</pre>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# Edit WHOIS Server Modal #}
|
|
|
|
|
{% if session.role is defined and session.role == 'admin' %}
|
|
|
|
|
<div id="editWhoisModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
|
|
|
|
|
<div class="bg-white dark:bg-slate-800 rounded-lg shadow-xl max-w-md w-full max-h-[90vh] overflow-y-auto">
|
|
|
|
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-slate-700 flex items-center justify-between">
|
|
|
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-white flex items-center">
|
|
|
|
|
<i class="fas fa-server text-orange-600 mr-2"></i>
|
|
|
|
|
Edit WHOIS Server
|
|
|
|
|
</h3>
|
|
|
|
|
<button onclick="closeEditWhoisModal()" class="text-gray-400 dark:text-slate-500 hover:text-gray-600 dark:hover:text-slate-300 transition-colors">
|
|
|
|
|
<i class="fas fa-times"></i>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<form method="POST" action="/tld-registry/{{ tld.id }}/update-whois-server" class="p-6">
|
|
|
|
|
{{ csrf_field() }}
|
|
|
|
|
<div class="mb-4">
|
|
|
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-slate-300 mb-2">
|
|
|
|
|
WHOIS Server
|
|
|
|
|
</label>
|
|
|
|
|
<input type="text"
|
|
|
|
|
name="whois_server"
|
|
|
|
|
id="whois_server_input"
|
|
|
|
|
value="{{ tld.whois_server|default('') }}"
|
|
|
|
|
placeholder="whois.example.com"
|
|
|
|
|
class="w-full px-3 py-2.5 border border-gray-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm bg-white dark:bg-slate-900 text-gray-900 dark:text-white">
|
|
|
|
|
<p class="mt-1.5 text-xs text-gray-500 dark:text-slate-400">
|
|
|
|
|
Enter the WHOIS server hostname (e.g., whois.example.com). Leave empty to remove.
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex gap-3">
|
|
|
|
|
<button type="submit"
|
|
|
|
|
class="flex-1 inline-flex items-center justify-center px-4 py-2.5 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-medium transition-colors text-sm">
|
|
|
|
|
<i class="fas fa-save mr-2"></i>
|
|
|
|
|
Save Changes
|
|
|
|
|
</button>
|
|
|
|
|
<button type="button"
|
|
|
|
|
onclick="closeEditWhoisModal()"
|
|
|
|
|
class="flex-1 inline-flex items-center justify-center px-4 py-2.5 border border-gray-300 dark:border-slate-600 text-gray-700 dark:text-slate-300 rounded-lg font-medium hover:bg-gray-50 dark:hover:bg-slate-700 transition-colors text-sm">
|
|
|
|
|
<i class="fas fa-times mr-2"></i>
|
|
|
|
|
Cancel
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{# Edit RDAP Servers Modal #}
|
|
|
|
|
<div id="editRdapModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
|
|
|
|
|
<div class="bg-white dark:bg-slate-800 rounded-lg shadow-xl max-w-md w-full max-h-[90vh] overflow-y-auto">
|
|
|
|
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-slate-700 flex items-center justify-between">
|
|
|
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-white flex items-center">
|
|
|
|
|
<i class="fas fa-database text-indigo-600 mr-2"></i>
|
|
|
|
|
Edit RDAP Servers
|
|
|
|
|
</h3>
|
|
|
|
|
<button onclick="closeEditRdapModal()" class="text-gray-400 dark:text-slate-500 hover:text-gray-600 dark:hover:text-slate-300 transition-colors">
|
|
|
|
|
<i class="fas fa-times"></i>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<form method="POST" action="/tld-registry/{{ tld.id }}/update-rdap-servers" class="p-6">
|
|
|
|
|
{{ csrf_field() }}
|
|
|
|
|
<div class="mb-4">
|
|
|
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-slate-300 mb-2">
|
|
|
|
|
RDAP Servers
|
|
|
|
|
</label>
|
|
|
|
|
{% set rdapTextarea = '' %}
|
|
|
|
|
{% if tld.rdap_servers %}
|
|
|
|
|
{% set rdapServers = tld.rdap_servers|from_json %}
|
|
|
|
|
{% if rdapServers is iterable and rdapServers is not empty %}
|
|
|
|
|
{% set rdapTextarea = rdapServers|join("\n") %}
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% endif %}
|
|
|
|
|
<textarea name="rdap_servers"
|
|
|
|
|
id="rdap_servers_input"
|
|
|
|
|
rows="6"
|
|
|
|
|
placeholder="https://rdap.example.com/ https://rdap2.example.com/"
|
|
|
|
|
class="w-full px-3 py-2.5 border border-gray-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-sm font-mono bg-white dark:bg-slate-900 text-gray-900 dark:text-white">{{ rdapTextarea }}</textarea>
|
|
|
|
|
<p class="mt-1.5 text-xs text-gray-500 dark:text-slate-400">
|
|
|
|
|
Enter RDAP server URLs (one per line or comma-separated). Must start with http:// or https://. Leave empty to remove all servers.
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex gap-3">
|
|
|
|
|
<button type="submit"
|
|
|
|
|
class="flex-1 inline-flex items-center justify-center px-4 py-2.5 bg-primary hover:bg-primary-dark text-white rounded-lg font-medium transition-colors text-sm">
|
|
|
|
|
<i class="fas fa-save mr-2"></i>
|
|
|
|
|
Save Changes
|
|
|
|
|
</button>
|
|
|
|
|
<button type="button"
|
|
|
|
|
onclick="closeEditRdapModal()"
|
|
|
|
|
class="flex-1 inline-flex items-center justify-center px-4 py-2.5 border border-gray-300 dark:border-slate-600 text-gray-700 dark:text-slate-300 rounded-lg font-medium hover:bg-gray-50 dark:hover:bg-slate-700 transition-colors text-sm">
|
|
|
|
|
<i class="fas fa-times mr-2"></i>
|
|
|
|
|
Cancel
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
function toggleRawData() {
|
|
|
|
|
const dataDiv = document.getElementById('raw-data');
|
|
|
|
|
const chevron = document.getElementById('raw-data-chevron');
|
|
|
|
|
dataDiv.classList.toggle('hidden');
|
|
|
|
|
chevron.classList.toggle('rotate-180');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{% if session.role is defined and session.role == 'admin' %}
|
|
|
|
|
function openEditWhoisModal() {
|
|
|
|
|
document.getElementById('editWhoisModal').classList.remove('hidden');
|
|
|
|
|
document.getElementById('whois_server_input').focus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function closeEditWhoisModal() {
|
|
|
|
|
document.getElementById('editWhoisModal').classList.add('hidden');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function openEditRdapModal() {
|
|
|
|
|
document.getElementById('editRdapModal').classList.remove('hidden');
|
|
|
|
|
document.getElementById('rdap_servers_input').focus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function closeEditRdapModal() {
|
|
|
|
|
document.getElementById('editRdapModal').classList.add('hidden');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
document.addEventListener('keydown', function(e) {
|
|
|
|
|
if (e.key === 'Escape') {
|
|
|
|
|
closeEditWhoisModal();
|
|
|
|
|
closeEditRdapModal();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
document.getElementById('editWhoisModal')?.addEventListener('click', function(e) {
|
|
|
|
|
if (e.target === this) {
|
|
|
|
|
closeEditWhoisModal();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
document.getElementById('editRdapModal')?.addEventListener('click', function(e) {
|
|
|
|
|
if (e.target === this) {
|
|
|
|
|
closeEditRdapModal();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
{% endif %}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
{% endblock %}
|