Skip to content

Commit 99c4f9b

Browse files
author
wrongecho
committed
Add domain history
1 parent e4a4687 commit 99c4f9b

File tree

10 files changed

+178
-17
lines changed

10 files changed

+178
-17
lines changed

ajax.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
* Looks up info for a given domain ID from the database, used to dynamically populate modal fields
7272
*/
7373
if (isset($_GET['domain_get_json_details'])) {
74-
validateTechRole();
74+
enforceUserPermission('module_support');
7575

7676
$domain_id = intval($_GET['domain_id']);
7777
$client_id = intval($_GET['client_id']);
@@ -88,6 +88,24 @@
8888
$response['vendors'][] = $row;
8989
}
9090

91+
// Get domain history
92+
$history_sql = mysqli_query($mysqli, "SELECT * FROM domain_history WHERE domain_history_domain_id = $domain_id");
93+
$history_html = "<table class='table table-borderless'>";
94+
$history_html .= "<tr><th>Date</th><th>Column</th><th>Old Value</th><th>New Value</th></tr>";
95+
while ($row = mysqli_fetch_array($history_sql)) {
96+
// Fetch data from the query and create table rows
97+
$history_html .= "<tr>";
98+
$history_html .= "<td>" . htmlspecialchars(date('Y-m-d', strtotime($row['domain_history_modified_at']))) . "</td>";
99+
$history_html .= "<td>" . htmlspecialchars($row['domain_history_column']) . "</td>";
100+
$history_html .= "<td>" . htmlspecialchars($row['domain_history_old_value']) . "</td>";
101+
$history_html .= "<td>" . htmlspecialchars($row['domain_history_new_value']) . "</td>";
102+
$history_html .= "</tr>";
103+
}
104+
$history_html .= "</table>";
105+
106+
// Return the HTML content to JavaScript
107+
$response['history'] = $history_html;
108+
91109
echo json_encode($response);
92110
}
93111

client_domains.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"
154154
$domain_expire = nullable_htmlentities($row['domain_expire']);
155155
$domain_expire_ago = timeAgo($domain_expire);
156156
// Convert the expiry date to a timestamp
157-
$domain_expire_timestamp = strtotime($row['domain_expire']);
157+
$domain_expire_timestamp = strtotime($row['domain_expire'] ?? '');
158158
$current_timestamp = time(); // Get current timestamp
159159

160160
// Calculate the difference in days
@@ -228,12 +228,10 @@ class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"
228228
<a class="dropdown-item text-info confirm-link" href="post.php?unarchive_domain=<?php echo $domain_id; ?>">
229229
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
230230
</a>
231-
<?php if ($config_destructive_deletes_enable) { ?>
232231
<div class="dropdown-divider"></div>
233232
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_domain=<?php echo $domain_id; ?>">
234233
<i class="fas fa-fw fa-trash mr-2"></i>Delete
235234
</a>
236-
<?php } ?>
237235
<?php } else { ?>
238236
<div class="dropdown-divider"></div>
239237
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_domain=<?php echo $domain_id; ?>">

database_updates.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2411,16 +2411,23 @@ function processFile($file_path, $file_name, $mysqli) {
24112411
}
24122412

24132413
if (CURRENT_DATABASE_VERSION == '1.7.6') {
2414-
// Create a field to show connected interfae of a foreign asset
2414+
// Create a field to show connected interface of a foreign asset
24152415
mysqli_query($mysqli, "ALTER TABLE `asset_interfaces` ADD `interface_connected_asset_interface` INT(11) NOT NULL DEFAULT 0 AFTER `interface_network_id`");
24162416

24172417
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.7.7'");
24182418
}
24192419

2420-
// if (CURRENT_DATABASE_VERSION == '1.7.7') {
2421-
// // Insert queries here required to update to DB version 1.7.8
2420+
if (CURRENT_DATABASE_VERSION == '1.7.7') {
2421+
// Domain history
2422+
mysqli_query($mysqli, "CREATE TABLE `domain_history` (`domain_history_id` INT(11) NOT NULL AUTO_INCREMENT , `domain_history_column` VARCHAR(200) NOT NULL , `domain_history_old_value` TEXT NOT NULL , `domain_history_new_value` TEXT NOT NULL , `domain_history_domain_id` INT(11) NOT NULL , `domain_history_modified_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP , PRIMARY KEY (`domain_history_id`)) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;");
2423+
2424+
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.7.8'");
2425+
}
2426+
2427+
// if (CURRENT_DATABASE_VERSION == '1.7.8') {
2428+
// // Insert queries here required to update to DB version 1.7.9
24222429
// // Then, update the database to the next sequential version
2423-
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.7.8'");
2430+
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.7.9'");
24242431
// }
24252432

24262433
} else {

database_version.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
* It is used in conjunction with database_updates.php
66
*/
77

8-
DEFINE("LATEST_DATABASE_VERSION", "1.7.7");
8+
DEFINE("LATEST_DATABASE_VERSION", "1.7.8");

db.sql

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,24 @@ CREATE TABLE `domains` (
682682
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
683683
/*!40101 SET character_set_client = @saved_cs_client */;
684684

685+
--
686+
-- Table structure for table `domain_history`
687+
--
688+
689+
DROP TABLE IF EXISTS `domain_history`;
690+
/*!40101 SET @saved_cs_client = @@character_set_client */;
691+
/*!40101 SET character_set_client = utf8 */;
692+
CREATE TABLE `domain_history` (
693+
`domain_history_id` int(11) NOT NULL AUTO_INCREMENT,
694+
`domain_history_column` varchar(200) NOT NULL,
695+
`domain_history_old_value` text NOT NULL,
696+
`domain_history_new_value` text NOT NULL,
697+
`domain_history_domain_id` int(11) NOT NULL,
698+
`domain_history_modified_at` datetime NOT NULL DEFAULT current_timestamp(),
699+
PRIMARY KEY (`domain_history_id`)
700+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
701+
/*!40101 SET character_set_client = @saved_cs_client */;
702+
685703
--
686704
-- Table structure for table `email_queue`
687705
--

functions.php

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,6 @@ function apiEncryptLoginEntry(#[\SensitiveParameter]$credential_cleartext, $api_
404404
// Get domain general info (whois + NS/A/MX records)
405405
function getDomainRecords($name)
406406
{
407-
408407
$records = array();
409408

410409
// Only run if we think the domain is valid
@@ -417,11 +416,53 @@ function getDomainRecords($name)
417416
}
418417

419418
$domain = escapeshellarg(str_replace('www.', '', $name));
420-
$records['a'] = substr(trim(strip_tags(shell_exec("dig +short $domain"))), 0, 254);
421-
$records['ns'] = substr(trim(strip_tags(shell_exec("dig +short NS $domain"))), 0, 254);
422-
$records['mx'] = substr(trim(strip_tags(shell_exec("dig +short MX $domain"))), 0, 254);
423-
$records['txt'] = substr(trim(strip_tags(shell_exec("dig +short TXT $domain"))), 0, 254);
424-
$records['whois'] = substr(trim(strip_tags(shell_exec("whois -H $domain | sed 's/ //g' | head -30"))), 0, 254);
419+
420+
// Get A, NS, MX, TXT, and WHOIS records
421+
$records['a'] = trim(strip_tags(shell_exec("dig +short $domain")));
422+
$records['ns'] = trim(strip_tags(shell_exec("dig +short NS $domain")));
423+
$records['mx'] = trim(strip_tags(shell_exec("dig +short MX $domain")));
424+
$records['txt'] = trim(strip_tags(shell_exec("dig +short TXT $domain")));
425+
$records['whois'] = substr(trim(strip_tags(shell_exec("whois -H $domain | sed 's/ //g' | head -30"))), 0, 255);
426+
427+
// Sort A records (if multiple records exist)
428+
if (!empty($records['a'])) {
429+
$aRecords = explode("\n", $records['a']);
430+
array_walk($aRecords, function(&$record) {
431+
$record = trim($record);
432+
});
433+
sort($aRecords);
434+
$records['a'] = implode("\n", $aRecords);
435+
}
436+
437+
// Sort NS records (if multiple records exist)
438+
if (!empty($records['ns'])) {
439+
$nsRecords = explode("\n", $records['ns']);
440+
array_walk($nsRecords, function(&$record) {
441+
$record = trim($record);
442+
});
443+
sort($nsRecords);
444+
$records['ns'] = implode("\n", $nsRecords);
445+
}
446+
447+
// Sort MX records (if multiple records exist)
448+
if (!empty($records['mx'])) {
449+
$mxRecords = explode("\n", $records['mx']);
450+
array_walk($mxRecords, function(&$record) {
451+
$record = trim($record);
452+
});
453+
sort($mxRecords);
454+
$records['mx'] = implode("\n", $mxRecords);
455+
}
456+
457+
// Sort TXT records (if multiple records exist)
458+
if (!empty($records['txt'])) {
459+
$txtRecords = explode("\n", $records['txt']);
460+
array_walk($txtRecords, function(&$record) {
461+
$record = trim($record);
462+
});
463+
sort($txtRecords);
464+
$records['txt'] = implode("\n", $txtRecords);
465+
}
425466

426467
return $records;
427468
}

js/domain_edit_modal.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ function populateDomainEditModal(client_id, domain_id) {
1212
// Access the domain info (one), registrars (multiple) and webhosts (multiple)
1313
const domain = response.domain[0];
1414
const vendors = response.vendors;
15+
const history = response.history;
1516

1617
// Populate the domain modal fields
1718
document.getElementById("editDomainHeader").innerText = domain.domain_name;
@@ -112,6 +113,9 @@ function populateDomainEditModal(client_id, domain_id) {
112113
}
113114
});
114115

116+
// Domain History
117+
document.getElementById('editDomainHistoryContainer').innerHTML = history;
118+
115119
}
116120
);
117121
}

modals/client_domain_edit_modal.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
<li class="nav-item">
2323
<a class="nav-link" data-toggle="pill" href="#pillsEditNotes">Notes</a>
2424
</li>
25+
<li class="nav-item">
26+
<a class="nav-link" data-toggle="pill" href="#pillsEditHistory">History</a>
27+
</li>
2528
</ul>
2629

2730
<hr>
@@ -166,6 +169,14 @@
166169
</div>
167170
</div>
168171

172+
<div class="tab-pane fade" id="pillsEditHistory">
173+
<div style="overflow: auto">
174+
<div class="table-responsive-sm">
175+
<div id="editDomainHistoryContainer"></div>
176+
</div>
177+
</div>
178+
</div>
179+
169180
</div>
170181

171182
</div>

post/user/domain.php

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@
7777
// Set/check/lookup expiry date
7878
if (strtotime($expire) && (new DateTime($expire)) > (new DateTime())) {
7979
$expire = "'" . $expire . "'";
80-
}
81-
else {
80+
81+
} else {
8282
$expire = getDomainExpirationDate($name);
8383
if (strtotime($expire)) {
8484
$expire = "'" . $expire . "'";
@@ -97,8 +97,53 @@
9797
$txt = sanitizeInput($records['txt']);
9898
$whois = sanitizeInput($records['whois']);
9999

100+
// Current domain info
101+
$original_domain_info = mysqli_fetch_assoc(mysqli_query($mysqli,"
102+
SELECT
103+
domains.*,
104+
registrar.vendor_name AS registrar_name,
105+
dnshost.vendor_name AS dnshost_name,
106+
mailhost.vendor_name AS mailhost_name,
107+
webhost.vendor_name AS webhost_name
108+
FROM domains
109+
LEFT JOIN vendors AS registrar ON domains.domain_registrar = registrar.vendor_id
110+
LEFT JOIN vendors AS dnshost ON domains.domain_dnshost = dnshost.vendor_id
111+
LEFT JOIN vendors AS mailhost ON domains.domain_mailhost = mailhost.vendor_id
112+
LEFT JOIN vendors AS webhost ON domains.domain_webhost = webhost.vendor_id
113+
WHERE domain_id = $domain_id
114+
"));
115+
116+
// Update domain
100117
mysqli_query($mysqli,"UPDATE domains SET domain_name = '$name', domain_description = '$description', domain_registrar = $registrar, domain_webhost = $webhost, domain_dnshost = $dnshost, domain_mailhost = $mailhost, domain_expire = $expire, domain_ip = '$a', domain_name_servers = '$ns', domain_mail_servers = '$mx', domain_txt = '$txt', domain_raw_whois = '$whois', domain_notes = '$notes' WHERE domain_id = $domain_id");
101118

119+
// Fetch updated info
120+
$new_domain_info = mysqli_fetch_assoc(mysqli_query($mysqli,"
121+
SELECT
122+
domains.*,
123+
registrar.vendor_name AS registrar_name,
124+
dnshost.vendor_name AS dnshost_name,
125+
mailhost.vendor_name AS mailhost_name,
126+
webhost.vendor_name AS webhost_name
127+
FROM domains
128+
LEFT JOIN vendors AS registrar ON domains.domain_registrar = registrar.vendor_id
129+
LEFT JOIN vendors AS dnshost ON domains.domain_dnshost = dnshost.vendor_id
130+
LEFT JOIN vendors AS mailhost ON domains.domain_mailhost = mailhost.vendor_id
131+
LEFT JOIN vendors AS webhost ON domains.domain_webhost = webhost.vendor_id
132+
WHERE domain_id = $domain_id
133+
"));
134+
135+
// Compare/log changes
136+
$ignored_columns = ["domain_updated_at", "domain_accessed_at", "domain_registrar", "domain_webhost", "domain_dnshost", "domain_mailhost"];
137+
foreach ($original_domain_info as $column => $old_value) {
138+
$new_value = $new_domain_info[$column];
139+
if ($old_value != $new_value && !in_array($column, $ignored_columns)) {
140+
$column = sanitizeInput($column);
141+
$old_value = sanitizeInput($old_value);
142+
$new_value = sanitizeInput($new_value);
143+
mysqli_query($mysqli,"INSERT INTO domain_history SET domain_history_column = '$column', domain_history_old_value = '$old_value', domain_history_new_value = '$new_value', domain_history_domain_id = $domain_id");
144+
}
145+
}
146+
102147
// Logging
103148
logAction("Domain", "Edit", "$session_name edited domain $name", $client_id, $domain_id);
104149

@@ -167,6 +212,8 @@
167212

168213
mysqli_query($mysqli,"DELETE FROM domains WHERE domain_id = $domain_id");
169214

215+
mysqli_query($mysqli, "DELETE FROM domain_history WHERE domain_history_domain_id = $domain_id");#
216+
170217
// Logging
171218
logAction("Domain", "Delete", "$session_name deleted domain $domain_name", $client_id);
172219

scripts/cron.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,23 @@
145145
// Cleanup old auth logs
146146
mysqli_query($mysqli, "DELETE FROM auth_logs WHERE auth_log_created_at < CURDATE() - INTERVAL $config_log_retention DAY");
147147

148+
// CLeanup old domain history
149+
$sql = mysqli_query($mysqli, "SELECT domain_id FROM domains");
150+
while ($row = mysqli_fetch_array($sql)) {
151+
$domain_id = intval($row['domain_id']);
152+
mysqli_query($mysqli, "
153+
DELETE FROM domain_history
154+
WHERE domain_history_id NOT IN (
155+
SELECT domain_history_id FROM (
156+
SELECT domain_history_id FROM domain_history
157+
WHERE domain_history_domain_id = $domain_id
158+
ORDER BY domain_history_modified_at DESC
159+
LIMIT 25
160+
) AS recent_entries
161+
) AND domain_history_domain_id = $domain_id
162+
");
163+
}
164+
148165
// Logging
149166
// logAction("Cron", "Task", "Cron cleaned up old data");
150167

0 commit comments

Comments
 (0)