diff --git a/cp/app/Controllers/DomainsController.php b/cp/app/Controllers/DomainsController.php index 7f3ebf8..e26c7e5 100644 --- a/cp/app/Controllers/DomainsController.php +++ b/cp/app/Controllers/DomainsController.php @@ -1056,7 +1056,61 @@ class DomainsController extends Controller } } - + + public function historyDomain(Request $request, Response $response, $args) + { + $db = $this->container->get('db'); + $db_audit = $this->container->get('db_audit'); + // Get the current URI + $uri = $request->getUri()->getPath(); + + if ($args) { + $args = strtolower(trim($args)); + + if (!preg_match('/^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)*[a-z0-9]([-a-z0-9]*[a-z0-9])?$/', $args)) { + $this->container->get('flash')->addMessage('error', 'Invalid domain name format'); + return $response->withHeader('Location', '/domains')->withStatus(302); + } + + try { + $exists = $db_audit->selectValue('SELECT 1 FROM domain LIMIT 1'); + } catch (\PDOException $e) { + throw new \RuntimeException('Audit table is empty or not configured'); + } + + $domain = $db->selectRow('SELECT id,name FROM domain WHERE name = ?', + [ $args ]); + + if ($domain) { + $history = $db_audit->select( + 'SELECT * FROM domain WHERE name = ? ORDER BY audit_timestamp DESC, audit_rownum ASC', + [$args] + ); + + if (strpos($domain['name'], 'xn--') === 0) { + $domain['name_o'] = $domain['name']; + $domain['name'] = idn_to_utf8($domain['name'], IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46); + } else { + $domain['name_o'] = $domain['name']; + } + + return view($response,'admin/domains/historyDomain.twig', [ + 'domain' => $domain, + 'history' => $history, + 'currentUri' => $uri + ]); + } else { + // Domain does not exist, redirect to the domains view + return $response->withHeader('Location', '/domains')->withStatus(302); + } + + } else { + // Redirect to the domains view + return $response->withHeader('Location', '/domains')->withStatus(302); + } + + } + public function updateDomain(Request $request, Response $response, $args) { $db = $this->container->get('db'); diff --git a/cp/bootstrap/app.php b/cp/bootstrap/app.php index ea1d936..11d85c2 100644 --- a/cp/bootstrap/app.php +++ b/cp/bootstrap/app.php @@ -66,6 +66,14 @@ $container->set('pdo', function () use ($pdo) { return $pdo; }); +$container->set('db_audit', function () use ($db_audit) { + return $db_audit; +}); + +$container->set('pdo_audit', function () use ($pdo_audit) { + return $pdo_audit; +}); + $container->set('auth', function() { //$responseFactory = new \Nyholm\Psr7\Factory\Psr17Factory(); //$response = $responseFactory->createResponse(); diff --git a/cp/bootstrap/database.php b/cp/bootstrap/database.php index fb7aaf4..0922563 100644 --- a/cp/bootstrap/database.php +++ b/cp/bootstrap/database.php @@ -32,4 +32,28 @@ try { } catch (PDOException $e) { $log->alert("Database connection failed: " . $e->getMessage(), ['driver' => $defaultDriver]); +} + +// Audit DB (optional) +try { + $auditDriver = match ($defaultDriver) { + 'mysql' => "{$config['mysql']['driver']}:dbname=registryAudit;host={$config['mysql']['host']};charset={$config['mysql']['charset']}", + 'sqlite' => "{$config['sqlite']['driver']}:{$config['sqlite']['audit_path']}", // assumes audit_path is set for SQLite + 'pgsql' => "{$config['pgsql']['driver']}:dbname=registryAudit;host={$config['pgsql']['host']}", + default => throw new \RuntimeException('Unsupported database driver for audit'), + }; + + if (str_starts_with($auditDriver, "sqlite")) { + $pdo_audit = new \PDO($auditDriver); + } else { + $pdo_audit = new \PDO( + $auditDriver, + $config[$defaultDriver]['username'], + $config[$defaultDriver]['password'] + ); + } + + $db_audit = PdoDatabase::fromPdo($pdo_audit); +} catch (PDOException $e) { + $log->alert("Audit database connection failed: " . $e->getMessage(), ['driver' => 'audit']); } \ No newline at end of file diff --git a/cp/resources/views/admin/domains/historyDomain.twig b/cp/resources/views/admin/domains/historyDomain.twig new file mode 100644 index 0000000..9ba7f40 --- /dev/null +++ b/cp/resources/views/admin/domains/historyDomain.twig @@ -0,0 +1,125 @@ +{% extends "layouts/app.twig" %} + +{% block title %}{{ __('Domain History') }}{% endblock %} + +{% block content %} +
{{ __('Timestamp') }} | +{{ __('Action') }} | +{{ __('User') }} | +{{ __('Session') }} | +{{ __('Changed Field') }} | +{{ __('Old Value') }} | +{{ __('New Value') }} | +
---|---|---|---|---|---|---|
{{ __('No audit history available for this domain.') }} | +||||||
{{ old.audit_timestamp }} | +{{ old.audit_statement }} | +{{ old.audit_usr_id|default('–') }} | +{{ old.audit_ses_id|default('–') }} | +{{ key }} | +{{ old[key]|default('–') }} | +{{ new[key]|default('–') }} | +
{{ entry.audit_timestamp }} | +{{ entry.audit_statement }} | +{{ entry.audit_usr_id|default('–') }} | +{{ entry.audit_ses_id|default('–') }} | +{{ __('New domain inserted.') }} | +||
{{ entry.audit_timestamp }} | +{{ entry.audit_statement }} | +{{ entry.audit_usr_id|default('–') }} | +{{ entry.audit_ses_id|default('–') }} | +{{ __('Domain was deleted.') }} | +