Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add domain history #1151

Merged
merged 2 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
* Looks up info for a given domain ID from the database, used to dynamically populate modal fields
*/
if (isset($_GET['domain_get_json_details'])) {
validateTechRole();
enforceUserPermission('module_support');

$domain_id = intval($_GET['domain_id']);
$client_id = intval($_GET['client_id']);
Expand All @@ -88,6 +88,24 @@
$response['vendors'][] = $row;
}

// Get domain history
$history_sql = mysqli_query($mysqli, "SELECT * FROM domain_history WHERE domain_history_domain_id = $domain_id");
$history_html = "<table class='table table-borderless'>";
$history_html .= "<tr><th>Date</th><th>Column</th><th>Old Value</th><th>New Value</th></tr>";
while ($row = mysqli_fetch_array($history_sql)) {
// Fetch data from the query and create table rows
$history_html .= "<tr>";
$history_html .= "<td>" . htmlspecialchars(date('Y-m-d', strtotime($row['domain_history_modified_at']))) . "</td>";
$history_html .= "<td>" . htmlspecialchars($row['domain_history_column']) . "</td>";
$history_html .= "<td>" . htmlspecialchars($row['domain_history_old_value']) . "</td>";
$history_html .= "<td>" . htmlspecialchars($row['domain_history_new_value']) . "</td>";
$history_html .= "</tr>";
}
$history_html .= "</table>";

// Return the HTML content to JavaScript
$response['history'] = $history_html;

echo json_encode($response);
}

Expand Down
4 changes: 1 addition & 3 deletions client_domains.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"
$domain_expire = nullable_htmlentities($row['domain_expire']);
$domain_expire_ago = timeAgo($domain_expire);
// Convert the expiry date to a timestamp
$domain_expire_timestamp = strtotime($row['domain_expire']);
$domain_expire_timestamp = strtotime($row['domain_expire'] ?? '');
$current_timestamp = time(); // Get current timestamp

// Calculate the difference in days
Expand Down Expand Up @@ -228,12 +228,10 @@ class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"
<a class="dropdown-item text-info confirm-link" href="post.php?unarchive_domain=<?php echo $domain_id; ?>">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</a>
<?php if ($config_destructive_deletes_enable) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_domain=<?php echo $domain_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } ?>
<?php } else { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_domain=<?php echo $domain_id; ?>">
Expand Down
15 changes: 11 additions & 4 deletions database_updates.php
Original file line number Diff line number Diff line change
Expand Up @@ -2411,16 +2411,23 @@ function processFile($file_path, $file_name, $mysqli) {
}

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

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

// if (CURRENT_DATABASE_VERSION == '1.7.7') {
// // Insert queries here required to update to DB version 1.7.8
if (CURRENT_DATABASE_VERSION == '1.7.7') {
// Domain history
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;");

mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.7.8'");
}

// if (CURRENT_DATABASE_VERSION == '1.7.8') {
// // Insert queries here required to update to DB version 1.7.9
// // Then, update the database to the next sequential version
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.7.8'");
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.7.9'");
// }

} else {
Expand Down
2 changes: 1 addition & 1 deletion database_version.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
* It is used in conjunction with database_updates.php
*/

DEFINE("LATEST_DATABASE_VERSION", "1.7.7");
DEFINE("LATEST_DATABASE_VERSION", "1.7.8");
18 changes: 18 additions & 0 deletions db.sql
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,24 @@ CREATE TABLE `domains` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `domain_history`
--

DROP TABLE IF EXISTS `domain_history`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
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 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `email_queue`
--
Expand Down
53 changes: 47 additions & 6 deletions functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,6 @@ function apiEncryptLoginEntry(#[\SensitiveParameter]$credential_cleartext, $api_
// Get domain general info (whois + NS/A/MX records)
function getDomainRecords($name)
{

$records = array();

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

$domain = escapeshellarg(str_replace('www.', '', $name));
$records['a'] = substr(trim(strip_tags(shell_exec("dig +short $domain"))), 0, 254);
$records['ns'] = substr(trim(strip_tags(shell_exec("dig +short NS $domain"))), 0, 254);
$records['mx'] = substr(trim(strip_tags(shell_exec("dig +short MX $domain"))), 0, 254);
$records['txt'] = substr(trim(strip_tags(shell_exec("dig +short TXT $domain"))), 0, 254);
$records['whois'] = substr(trim(strip_tags(shell_exec("whois -H $domain | sed 's/ //g' | head -30"))), 0, 254);

// Get A, NS, MX, TXT, and WHOIS records
$records['a'] = trim(strip_tags(shell_exec("dig +short $domain")));
$records['ns'] = trim(strip_tags(shell_exec("dig +short NS $domain")));
$records['mx'] = trim(strip_tags(shell_exec("dig +short MX $domain")));
$records['txt'] = trim(strip_tags(shell_exec("dig +short TXT $domain")));
$records['whois'] = substr(trim(strip_tags(shell_exec("whois -H $domain | head -30 | sed 's/ //g'"))), 0, 254);

// Sort A records (if multiple records exist)
if (!empty($records['a'])) {
$a_records = explode("\n", $records['a']);
array_walk($a_records, function(&$record) {
$record = trim($record);
});
sort($a_records);
$records['a'] = implode("\n", $a_records);
}

// Sort NS records (if multiple records exist)
if (!empty($records['ns'])) {
$ns_records = explode("\n", $records['ns']);
array_walk($ns_records, function(&$record) {
$record = trim($record);
});
sort($ns_records);
$records['ns'] = implode("\n", $ns_records);
}

// Sort MX records (if multiple records exist)
if (!empty($records['mx'])) {
$mx_records = explode("\n", $records['mx']);
array_walk($mx_records, function(&$record) {
$record = trim($record);
});
sort($mx_records);
$records['mx'] = implode("\n", $mx_records);
}

// Sort TXT records (if multiple records exist)
if (!empty($records['txt'])) {
$txt_records = explode("\n", $records['txt']);
array_walk($txt_records, function(&$record) {
$record = trim($record);
});
sort($txt_records);
$records['txt'] = implode("\n", $txt_records);
}

return $records;
}
Expand Down
4 changes: 4 additions & 0 deletions js/domain_edit_modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ function populateDomainEditModal(client_id, domain_id) {
// Access the domain info (one), registrars (multiple) and webhosts (multiple)
const domain = response.domain[0];
const vendors = response.vendors;
const history = response.history;

// Populate the domain modal fields
document.getElementById("editDomainHeader").innerText = domain.domain_name;
Expand Down Expand Up @@ -112,6 +113,9 @@ function populateDomainEditModal(client_id, domain_id) {
}
});

// Domain History
document.getElementById('editDomainHistoryContainer').innerHTML = history;

}
);
}
11 changes: 11 additions & 0 deletions modals/client_domain_edit_modal.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pillsEditNotes">Notes</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pillsEditHistory">History</a>
</li>
</ul>

<hr>
Expand Down Expand Up @@ -166,6 +169,14 @@
</div>
</div>

<div class="tab-pane fade" id="pillsEditHistory">
<div style="overflow: auto">
<div class="table-responsive-sm">
<div id="editDomainHistoryContainer"></div>
</div>
</div>
</div>

</div>

</div>
Expand Down
57 changes: 49 additions & 8 deletions post/user/domain.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,11 @@
require_once 'domain_model.php';
$domain_id = intval($_POST['domain_id']);


// if (empty($expire) || (new DateTime($expire)) < (new DateTime())) {
// // Update domain expiry date
// $expire = getDomainExpirationDate($name);
// }

// Set/check/lookup expiry date
if (strtotime($expire) && (new DateTime($expire)) > (new DateTime())) {
$expire = "'" . $expire . "'";
}
else {

} else {
$expire = getDomainExpirationDate($name);
if (strtotime($expire)) {
$expire = "'" . $expire . "'";
Expand All @@ -97,8 +91,53 @@
$txt = sanitizeInput($records['txt']);
$whois = sanitizeInput($records['whois']);

// Current domain info
$original_domain_info = mysqli_fetch_assoc(mysqli_query($mysqli,"
SELECT
domains.*,
registrar.vendor_name AS registrar_name,
dnshost.vendor_name AS dnshost_name,
mailhost.vendor_name AS mailhost_name,
webhost.vendor_name AS webhost_name
FROM domains
LEFT JOIN vendors AS registrar ON domains.domain_registrar = registrar.vendor_id
LEFT JOIN vendors AS dnshost ON domains.domain_dnshost = dnshost.vendor_id
LEFT JOIN vendors AS mailhost ON domains.domain_mailhost = mailhost.vendor_id
LEFT JOIN vendors AS webhost ON domains.domain_webhost = webhost.vendor_id
WHERE domain_id = $domain_id
"));

// Update domain
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");

// Fetch updated info
$new_domain_info = mysqli_fetch_assoc(mysqli_query($mysqli,"
SELECT
domains.*,
registrar.vendor_name AS registrar_name,
dnshost.vendor_name AS dnshost_name,
mailhost.vendor_name AS mailhost_name,
webhost.vendor_name AS webhost_name
FROM domains
LEFT JOIN vendors AS registrar ON domains.domain_registrar = registrar.vendor_id
LEFT JOIN vendors AS dnshost ON domains.domain_dnshost = dnshost.vendor_id
LEFT JOIN vendors AS mailhost ON domains.domain_mailhost = mailhost.vendor_id
LEFT JOIN vendors AS webhost ON domains.domain_webhost = webhost.vendor_id
WHERE domain_id = $domain_id
"));

// Compare/log changes
$ignored_columns = ["domain_updated_at", "domain_accessed_at", "domain_registrar", "domain_webhost", "domain_dnshost", "domain_mailhost"];
foreach ($original_domain_info as $column => $old_value) {
$new_value = $new_domain_info[$column];
if ($old_value != $new_value && !in_array($column, $ignored_columns)) {
$column = sanitizeInput($column);
$old_value = sanitizeInput($old_value);
$new_value = sanitizeInput($new_value);
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");
}
}

// Logging
logAction("Domain", "Edit", "$session_name edited domain $name", $client_id, $domain_id);

Expand Down Expand Up @@ -167,6 +206,8 @@

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

mysqli_query($mysqli, "DELETE FROM domain_history WHERE domain_history_domain_id = $domain_id");#

// Logging
logAction("Domain", "Delete", "$session_name deleted domain $domain_name", $client_id);

Expand Down
17 changes: 17 additions & 0 deletions scripts/cron.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,23 @@
// Cleanup old auth logs
mysqli_query($mysqli, "DELETE FROM auth_logs WHERE auth_log_created_at < CURDATE() - INTERVAL $config_log_retention DAY");

// CLeanup old domain history
$sql = mysqli_query($mysqli, "SELECT domain_id FROM domains");
while ($row = mysqli_fetch_array($sql)) {
$domain_id = intval($row['domain_id']);
mysqli_query($mysqli, "
DELETE FROM domain_history
WHERE domain_history_id NOT IN (
SELECT domain_history_id FROM (
SELECT domain_history_id FROM domain_history
WHERE domain_history_domain_id = $domain_id
ORDER BY domain_history_modified_at DESC
LIMIT 25
) AS recent_entries
) AND domain_history_domain_id = $domain_id
");
}

// Logging
// logAction("Cron", "Task", "Cron cleaned up old data");

Expand Down
47 changes: 46 additions & 1 deletion scripts/cron_domain_refresher.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

// REFRESH DOMAIN WHOIS DATA (1 a day/run)
// Get the oldest updated domain (MariaDB shows NULLs first when ordering by default)
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT domain_id, domain_name, domain_expire FROM `domains` ORDER BY domain_updated_at LIMIT 1"));
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT domain_id, domain_name, domain_expire FROM `domains` WHERE domain_archived_at IS NULL ORDER BY domain_updated_at LIMIT 1"));

if ($row) {

Expand Down Expand Up @@ -71,7 +71,52 @@
$expire = 'NULL';
}

// Current domain info
$original_domain_info = mysqli_fetch_assoc(mysqli_query($mysqli,"
SELECT
domains.*,
registrar.vendor_name AS registrar_name,
dnshost.vendor_name AS dnshost_name,
mailhost.vendor_name AS mailhost_name,
webhost.vendor_name AS webhost_name
FROM domains
LEFT JOIN vendors AS registrar ON domains.domain_registrar = registrar.vendor_id
LEFT JOIN vendors AS dnshost ON domains.domain_dnshost = dnshost.vendor_id
LEFT JOIN vendors AS mailhost ON domains.domain_mailhost = mailhost.vendor_id
LEFT JOIN vendors AS webhost ON domains.domain_webhost = webhost.vendor_id
WHERE domain_id = $domain_id
"));

// Update the domain
mysqli_query($mysqli, "UPDATE domains SET domain_name = '$domain_name', domain_expire = $expire, domain_ip = '$a', domain_name_servers = '$ns', domain_mail_servers = '$mx', domain_txt = '$txt', domain_raw_whois = '$whois' WHERE domain_id = $domain_id");
echo "Updated $domain_name.";

// Fetch updated info
$new_domain_info = mysqli_fetch_assoc(mysqli_query($mysqli,"
SELECT
domains.*,
registrar.vendor_name AS registrar_name,
dnshost.vendor_name AS dnshost_name,
mailhost.vendor_name AS mailhost_name,
webhost.vendor_name AS webhost_name
FROM domains
LEFT JOIN vendors AS registrar ON domains.domain_registrar = registrar.vendor_id
LEFT JOIN vendors AS dnshost ON domains.domain_dnshost = dnshost.vendor_id
LEFT JOIN vendors AS mailhost ON domains.domain_mailhost = mailhost.vendor_id
LEFT JOIN vendors AS webhost ON domains.domain_webhost = webhost.vendor_id
WHERE domain_id = $domain_id
"));

// Compare/log changes
$ignored_columns = ["domain_updated_at", "domain_accessed_at", "domain_registrar", "domain_webhost", "domain_dnshost", "domain_mailhost"];
foreach ($original_domain_info as $column => $old_value) {
$new_value = $new_domain_info[$column];
if ($old_value != $new_value && !in_array($column, $ignored_columns)) {
$column = sanitizeInput($column);
$old_value = sanitizeInput($old_value);
$new_value = sanitizeInput($new_value);
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");
}
}

}
Loading