Merge branch 'develop' into ticket-redaction

This commit is contained in:
wrongecho 2025-03-18 09:42:29 +00:00 committed by GitHub
commit 21dc26b06f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
185 changed files with 4202 additions and 2975 deletions

View File

@ -2,6 +2,16 @@
This file documents all notable changes made to ITFlow. This file documents all notable changes made to ITFlow.
## [25.02.4]
### Fixed
- Resolved issue preventing the addition or editing of licenses when no vendor was selected.
- Fixed several undeclared variables in AJAX contact details.
- Corrected the contact ticket count display.
- Addressed an issue where clicking "More Details" in AJAX contact/asset details failed to include the `client_id` in the URL.
- Fixed an issue with recurring invoices in the client URL: clicking "Inactive" or "Active" would unexpectedly navigate away from the client section.
- Added new php function getFieldById() to return a record using just an id and sanitized as well.
## [25.02.3] ## [25.02.3]
### Fixed ### Fixed

View File

@ -1,7 +1,7 @@
<?php <?php
// Default Column Sortby Filter // Default Column Sortby Filter
$sort = "user_role_is_admin"; $sort = "role_is_admin";
$order = "DESC"; $order = "DESC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
@ -13,8 +13,8 @@ $url_query_strings_sort = http_build_query($get_copy);
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM user_roles "SELECT SQL_CALC_FOUND_ROWS * FROM user_roles
WHERE (user_roles.user_role_name LIKE '%$q%' OR user_roles.user_role_description LIKE '%$q%') WHERE (role_name LIKE '%$q%' OR role_description LIKE '%$q%')
AND user_roles.user_role_archived_at IS NULL AND role_archived_at IS NULL
ORDER BY $sort $order LIMIT $record_from, $record_to" ORDER BY $sort $order LIMIT $record_from, $record_to"
); );
@ -53,14 +53,14 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>"> <thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr> <tr>
<th> <th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_role_name&order=<?php echo $disp; ?>"> <a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=role_name&order=<?php echo $disp; ?>">
Role <?php if ($sort == 'user_role_name') { echo $order_icon; } ?> Role <?php if ($sort == 'role_name') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th>Members</th> <th>Members</th>
<th> <th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_role_is_admin&order=<?php echo $disp; ?>"> <a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=role_is_admin&order=<?php echo $disp; ?>">
Admin <?php if ($sort == 'user_role_is_admin') { echo $order_icon; } ?> Admin <?php if ($sort == 'role_is_admin') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th class="text-center">Action</th> <th class="text-center">Action</th>
@ -70,17 +70,17 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php <?php
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$role_id = intval($row['user_role_id']); $role_id = intval($row['role_id']);
$role_name = nullable_htmlentities($row['user_role_name']); $role_name = nullable_htmlentities($row['role_name']);
$role_description = nullable_htmlentities($row['user_role_description']); $role_description = nullable_htmlentities($row['role_description']);
$role_admin = intval($row['user_role_is_admin']); $role_admin = intval($row['role_is_admin']);
$role_archived_at = nullable_htmlentities($row['user_role_archived_at']); $role_archived_at = nullable_htmlentities($row['role_archived_at']);
// Count number of users that have each role // Count number of users that have each role
$sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(users.user_id) FROM users LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role = $role_id AND user_archived_at IS NULL"); $sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(user_id) FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
$role_user_count = mysqli_fetch_row($sql_role_user_count)[0]; $role_user_count = mysqli_fetch_row($sql_role_user_count)[0];
$sql_users = mysqli_query($mysqli, "SELECT * FROM users LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role = $role_id AND user_archived_at IS NULL"); $sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
// Initialize an empty array to hold user names // Initialize an empty array to hold user names
$user_names = []; $user_names = [];
@ -90,7 +90,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
} }
// Convert the array of user names to a comma-separated string // Convert the array of user names to a comma-separated string
$user_names_string = implode(",", $user_names) ; $user_names_string = implode(",", $user_names);
if (empty($user_names_string)) { if (empty($user_names_string)) {
$user_names_string = "-"; $user_names_string = "-";

View File

@ -77,7 +77,7 @@ require_once "includes/inc_all_admin.php";
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div> </div>
<input type="text" class="form-control" name="config_recurring_prefix" placeholder="Recurring Prefix" value="<?php echo nullable_htmlentities($config_recurring_prefix); ?>" required> <input type="text" class="form-control" name="config_recurring_invoice_prefix" placeholder="Recurring Invoice Prefix" value="<?php echo nullable_htmlentities($config_recurring_invoice_prefix); ?>" required>
</div> </div>
</div> </div>
@ -87,7 +87,7 @@ require_once "includes/inc_all_admin.php";
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-barcode"></i></span>
</div> </div>
<input type="number" min="0" class="form-control" name="config_recurring_next_number" placeholder="Next Recurring Number" value="<?php echo intval($config_recurring_next_number); ?>" required> <input type="number" min="0" class="form-control" name="config_recurring_invoice_next_number" placeholder="Next Recurring Invoice Number" value="<?php echo intval($config_recurring_invoice_next_number); ?>" required>
</div> </div>
</div> </div>

View File

@ -19,7 +19,7 @@ require_once "includes/inc_all_admin.php";
?> ?>
<div class="col-3 text-center mb-3"> <div class="col-4 text-center mb-3">
<div class="form-group"> <div class="form-group">
<div class="custom-control custom-radio"> <div class="custom-control custom-radio">
<input class="custom-control-input" type="radio" onchange="this.form.submit()" id="customRadio<?php echo $theme_color; ?>" name="edit_theme_settings" value="<?php echo $theme_color; ?>" <?php if ($config_theme == $theme_color) { echo "checked"; } ?>> <input class="custom-control-input" type="radio" onchange="this.form.submit()" id="customRadio<?php echo $theme_color; ?>" name="edit_theme_settings" value="<?php echo $theme_color; ?>" <?php if ($config_theme == $theme_color) { echo "checked"; } ?>>

View File

@ -6,17 +6,25 @@ $order = "ASC";
require_once "includes/inc_all_admin.php"; require_once "includes/inc_all_admin.php";
// User Type Filter
//Rebuild URL if (isset($_GET['type']) && $_GET['type'] == "client") {
$url_query_strings_sort = http_build_query($get_copy); $type_filter = "client";
$type_query = "AND user_type = 2";
} else {
$type_filter = "user";
$type_query = "AND user_type = 1";
}
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS * FROM users, user_settings, user_roles "SELECT SQL_CALC_FOUND_ROWS * FROM users
WHERE users.user_id = user_settings.user_id LEFT JOIN user_roles ON user_role_id = role_id
AND user_settings.user_role = user_roles.user_role_id LEFT JOIN user_settings ON users.user_id = user_settings.user_id
AND (user_name LIKE '%$q%' OR user_email LIKE '%$q%') LEFT JOIN contacts ON users.user_id = contact_user_id
LEFT JOIN clients ON contact_client_id = client_id
WHERE (user_name LIKE '%$q%' OR user_email LIKE '%$q%')
AND user_archived_at IS NULL AND user_archived_at IS NULL
$type_query
ORDER BY $sort $order LIMIT $record_from, $record_to" ORDER BY $sort $order LIMIT $record_from, $record_to"
); );
@ -36,6 +44,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="dropdown-menu"> <div class="dropdown-menu">
<!--<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#userInviteModal"><i class="fas fa-paper-plane mr-2"></i>Invite User</a>--> <!--<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#userInviteModal"><i class="fas fa-paper-plane mr-2"></i>Invite User</a>-->
<?php if ($num_rows[0] > 1) { ?> <?php if ($num_rows[0] > 1) { ?>
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportUserModal"><i class="fa fa-fw fa-download mr-2"></i>Export</a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="#" data-toggle="modal" data-target="#resetAllUserPassModal"><i class="fas fa-skull-crossbones mr-2"></i>IR</a> <a class="dropdown-item text-danger" href="#" data-toggle="modal" data-target="#resetAllUserPassModal"><i class="fas fa-skull-crossbones mr-2"></i>IR</a>
<?php } ?> <?php } ?>
@ -55,8 +64,11 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<div class="float-right"> <div class="btn-toolbar float-right">
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#exportUserModal"><i class="fa fa-fw fa-download mr-2"></i>Export</button> <div class="btn-group mr-2">
<a href="?type=user" class="btn btn-<?php if ($type_filter == "user"){ echo "primary"; } else { echo "default"; } ?>"><i class="fa fa-fw fa-user-shield mr-2"></i>User</a>
<a href="?type=client" class="btn btn-<?php if ($type_filter == "client"){ echo "primary"; } else { echo "default"; } ?>"><i class="fa fa-fw fa-user mr-2"></i>Client</a>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -77,8 +89,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</a> </a>
</th> </th>
<th> <th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=user_role&order=<?php echo $disp; ?>"> <a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=role_name&order=<?php echo $disp; ?>">
Role <?php if ($sort == 'user_role') { echo $order_icon; } ?> Role <?php if ($sort == 'role_name') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th> <th>
@ -90,6 +102,13 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<th> <th>
Last Login Last Login
</th> </th>
<?php if ($type_filter === "client") { ?>
<th>
<a class="text-dark" href="?<?php echo $url_query_strings_sort; ?>&sort=client_name&order=<?php echo $disp; ?>">
Client <?php if ($sort == 'client_name') { echo $order_icon; } ?>
</a>
</th>
<?php } ?>
<th class="text-center">Action</th> <th class="text-center">Action</th>
</tr> </tr>
</thead> </thead>
@ -116,10 +135,14 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$mfa_status_display = "<i class='fas fa-fw fa-lock text-success'></i>"; $mfa_status_display = "<i class='fas fa-fw fa-lock text-success'></i>";
} }
$user_config_force_mfa = intval($row['user_config_force_mfa']); $user_config_force_mfa = intval($row['user_config_force_mfa']);
$user_role = $row['user_role']; $user_role = intval($row['user_role_id']);
$user_role_display = nullable_htmlentities($row['user_role_name']); $user_role_display = nullable_htmlentities($row['role_name']);
$user_initials = nullable_htmlentities(initials($user_name)); $user_initials = nullable_htmlentities(initials($user_name));
$contact_id = intval($row['contact_id']);
$client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']);
$sql_last_login = mysqli_query( $sql_last_login = mysqli_query(
$mysqli, $mysqli,
"SELECT * FROM logs "SELECT * FROM logs
@ -139,7 +162,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
} }
// Get User Client Access Permissions // Get User Client Access Permissions
$user_client_access_sql = mysqli_query($mysqli,"SELECT client_id FROM user_permissions WHERE user_id = $user_id"); $user_client_access_sql = mysqli_query($mysqli,"SELECT client_id FROM user_client_permissions WHERE user_id = $user_id");
$client_access_array = []; $client_access_array = [];
while ($row = mysqli_fetch_assoc($user_client_access_sql)) { while ($row = mysqli_fetch_assoc($user_client_access_sql)) {
$client_access_array[] = intval($row['client_id']); $client_access_array[] = intval($row['client_id']);
@ -178,6 +201,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<td><?php echo $user_status_display; ?></td> <td><?php echo $user_status_display; ?></td>
<td class="text-center"><?php echo $mfa_status_display; ?></td> <td class="text-center"><?php echo $mfa_status_display; ?></td>
<td><?php echo $last_login; ?></td> <td><?php echo $last_login; ?></td>
<?php if ($type_filter === "client") { ?>
<td><?php echo $client_name; ?></td>
<?php } ?>
<td> <td>
<?php if ($user_id !== $session_user_id) { // Prevent modifying self ?> <?php if ($user_id !== $session_user_id) { // Prevent modifying self ?>
<div class="dropdown dropleft text-center"> <div class="dropdown dropleft text-center">

View File

@ -8,7 +8,7 @@
require_once "config.php"; require_once "config.php";
require_once "functions.php"; require_once "functions.php";
require_once "check_login.php"; require_once "includes/check_login.php";
require_once "plugins/totp/totp.php"; require_once "plugins/totp/totp.php";
/* /*
@ -165,7 +165,7 @@ if (isset($_GET['ticket_query_views'])) {
} }
/* /*
* Generates public/guest links for sharing logins/docs * Generates public/guest links for sharing credentials/docs
*/ */
if (isset($_GET['share_generate_link'])) { if (isset($_GET['share_generate_link'])) {
enforceUserPermission('module_support', 2); enforceUserPermission('module_support', 2);
@ -207,23 +207,23 @@ if (isset($_GET['share_generate_link'])) {
$item_name = sanitizeInput($row['file_name']); $item_name = sanitizeInput($row['file_name']);
} }
if ($item_type == "Login") { if ($item_type == "Credential") {
$login = mysqli_query($mysqli, "SELECT login_name, login_username, login_password FROM logins WHERE login_id = $item_id AND login_client_id = $client_id LIMIT 1"); $credential = mysqli_query($mysqli, "SELECT credential_name, credential_username, credential_password FROM credentials WHERE credential_id = $item_id AND credential_client_id = $client_id LIMIT 1");
$row = mysqli_fetch_array($login); $row = mysqli_fetch_array($credential);
$item_name = sanitizeInput($row['login_name']); $item_name = sanitizeInput($row['credential_name']);
// Decrypt & re-encrypt username/password for sharing // Decrypt & re-encrypt username/password for sharing
$login_encryption_key = randomString(); $credential_encryption_key = randomString();
$login_username_cleartext = decryptLoginEntry($row['login_username']); $credential_username_cleartext = decryptCredentialEntry($row['credential_username']);
$iv = randomString(); $iv = randomString();
$username_ciphertext = openssl_encrypt($login_username_cleartext, 'aes-128-cbc', $login_encryption_key, 0, $iv); $username_ciphertext = openssl_encrypt($credential_username_cleartext, 'aes-128-cbc', $credential_encryption_key, 0, $iv);
$item_encrypted_username = $iv . $username_ciphertext; $item_encrypted_username = $iv . $username_ciphertext;
$login_password_cleartext = decryptLoginEntry($row['login_password']); $credential_password_cleartext = decryptCredentialEntry($row['credential_password']);
$iv = randomString(); $iv = randomString();
$password_ciphertext = openssl_encrypt($login_password_cleartext, 'aes-128-cbc', $login_encryption_key, 0, $iv); $password_ciphertext = openssl_encrypt($credential_password_cleartext, 'aes-128-cbc', $credential_encryption_key, 0, $iv);
$item_encrypted_credential = $iv . $password_ciphertext; $item_encrypted_credential = $iv . $password_ciphertext;
} }
@ -232,8 +232,8 @@ if (isset($_GET['share_generate_link'])) {
$share_id = $mysqli->insert_id; $share_id = $mysqli->insert_id;
// Return URL // Return URL
if ($item_type == "Login") { if ($item_type == "Credential") {
$url = "https://$config_base_url/guest/guest_view_item.php?id=$share_id&key=$item_key&ek=$login_encryption_key"; $url = "https://$config_base_url/guest/guest_view_item.php?id=$share_id&key=$item_key&ek=$credential_encryption_key";
} }
else { else {
$url = "https://$config_base_url/guest/guest_view_item.php?id=$share_id&key=$item_key"; $url = "https://$config_base_url/guest/guest_view_item.php?id=$share_id&key=$item_key";
@ -333,24 +333,24 @@ if (isset($_GET['get_client_contacts'])) {
if (isset($_GET['get_totp_token_via_id'])) { if (isset($_GET['get_totp_token_via_id'])) {
enforceUserPermission('module_credential'); enforceUserPermission('module_credential');
$login_id = intval($_GET['login_id']); $credential_id = intval($_GET['credential_id']);
$sql = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT login_name, login_otp_secret, login_client_id FROM logins WHERE login_id = $login_id")); $sql = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT credential_name, credential_otp_secret, credential_client_id FROM credentials WHERE credential_id = $credential_id"));
$name = sanitizeInput($sql['login_name']); $name = sanitizeInput($sql['credential_name']);
$totp_secret = $sql['login_otp_secret']; $totp_secret = $sql['credential_otp_secret'];
$client_id = intval($sql['login_client_id']); $client_id = intval($sql['credential_client_id']);
$otp = TokenAuth6238::getTokenCode(strtoupper($totp_secret)); $otp = TokenAuth6238::getTokenCode(strtoupper($totp_secret));
echo json_encode($otp); echo json_encode($otp);
// Logging // Logging
// Only log the TOTP view if the user hasn't already viewed this specific login entry recently, this prevents logs filling if a user hovers across an entry a few times // Only log the TOTP view if the user hasn't already viewed this specific login entry recently, this prevents logs filling if a user hovers across an entry a few times
$check_recent_totp_view_logged_sql = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(log_id) AS recent_totp_view FROM logs WHERE log_type = 'Login' AND log_action = 'View TOTP' AND log_user_id = $session_user_id AND log_entity_id = $login_id AND log_client_id = $client_id AND log_created_at > (NOW() - INTERVAL 5 MINUTE)")); $check_recent_totp_view_logged_sql = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT(log_id) AS recent_totp_view FROM logs WHERE log_type = 'Credential' AND log_action = 'View TOTP' AND log_user_id = $session_user_id AND log_entity_id = $credential_id AND log_client_id = $client_id AND log_created_at > (NOW() - INTERVAL 5 MINUTE)"));
$recent_totp_view_logged_count = intval($check_recent_totp_view_logged_sql['recent_totp_view']); $recent_totp_view_logged_count = intval($check_recent_totp_view_logged_sql['recent_totp_view']);
if ($recent_totp_view_logged_count == 0) { if ($recent_totp_view_logged_count == 0) {
// Logging // Logging
logAction("Credential", "View TOTP", "$session_name viewed credential TOTP code for $name", $client_id, $login_id); logAction("Credential", "View TOTP", "$session_name viewed credential TOTP code for $name", $client_id, $credential_id);
} }
} }

View File

@ -50,6 +50,7 @@ $device_icon = getAssetIcon($asset_type);
$contact_name = nullable_htmlentities($row['contact_name']); $contact_name = nullable_htmlentities($row['contact_name']);
$contact_email = nullable_htmlentities($row['contact_email']); $contact_email = nullable_htmlentities($row['contact_email']);
$contact_phone = nullable_htmlentities($row['contact_phone']); $contact_phone = nullable_htmlentities($row['contact_phone']);
$contact_extension = nullable_htmlentities($row['contact_extension']);
$contact_mobile = nullable_htmlentities($row['contact_mobile']); $contact_mobile = nullable_htmlentities($row['contact_mobile']);
$contact_archived_at = nullable_htmlentities($row['contact_archived_at']); $contact_archived_at = nullable_htmlentities($row['contact_archived_at']);
if ($contact_archived_at) { if ($contact_archived_at) {
@ -111,46 +112,53 @@ $interface_count = mysqli_num_rows($sql_related_interfaces);
// Related Credentials Query // Related Credentials Query
$sql_related_credentials = mysqli_query($mysqli, " $sql_related_credentials = mysqli_query($mysqli, "
SELECT SELECT
logins.login_id AS login_id, credentials.credential_id AS credential_id,
logins.login_name, credentials.credential_name,
logins.login_description, credentials.credential_description,
logins.login_uri, credentials.credential_uri,
logins.login_username, credentials.credential_username,
logins.login_password, credentials.credential_password,
logins.login_otp_secret, credentials.credential_otp_secret,
logins.login_note, credentials.credential_note,
logins.login_important, credentials.credential_important,
logins.login_contact_id, credentials.credential_contact_id,
logins.login_asset_id credentials.credential_asset_id
FROM logins FROM credentials
LEFT JOIN login_tags ON login_tags.login_id = logins.login_id LEFT JOIN credential_tags ON credential_tags.credential_id = credentials.credential_id
LEFT JOIN tags ON tags.tag_id = login_tags.tag_id LEFT JOIN tags ON tags.tag_id = credential_tags.tag_id
WHERE login_asset_id = $asset_id WHERE credential_asset_id = $asset_id
AND login_archived_at IS NULL AND credential_archived_at IS NULL
GROUP BY logins.login_id GROUP BY credentials.credential_id
ORDER BY login_name DESC ORDER BY credential_name DESC
"); ");
$credential_count = mysqli_num_rows($sql_related_credentials); $credential_count = mysqli_num_rows($sql_related_credentials);
// Related Tickets Query // Related Tickets Query
$sql_related_tickets = mysqli_query($mysqli, "SELECT * FROM tickets $sql_related_tickets = mysqli_query($mysqli, "
LEFT JOIN users on ticket_assigned_to = user_id SELECT tickets.*, users.*, ticket_statuses.*
FROM tickets
LEFT JOIN users ON ticket_assigned_to = user_id
LEFT JOIN ticket_statuses ON ticket_status_id = ticket_status LEFT JOIN ticket_statuses ON ticket_status_id = ticket_status
WHERE ticket_asset_id = $asset_id LEFT JOIN ticket_assets ON tickets.ticket_id = ticket_assets.ticket_id
ORDER BY ticket_number DESC" WHERE ticket_asset_id = $asset_id OR ticket_assets.asset_id = $asset_id
); GROUP BY tickets.ticket_id
ORDER BY ticket_number DESC
");
$ticket_count = mysqli_num_rows($sql_related_tickets); $ticket_count = mysqli_num_rows($sql_related_tickets);
// Related Recurring Tickets Query // Related Recurring Tickets Query
$sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM scheduled_tickets $sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM recurring_tickets
WHERE scheduled_ticket_asset_id = $asset_id LEFT JOIN recurring_ticket_assets ON recurring_tickets.recurring_ticket_id = recurring_ticket_assets.recurring_ticket_id
ORDER BY scheduled_ticket_next_run DESC" WHERE recurring_ticket_asset_id = $asset_id OR recurring_ticket_assets.asset_id = $asset_id
GROUP BY recurring_tickets.recurring_ticket_id
ORDER BY recurring_ticket_next_run DESC"
); );
$recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets); $recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets);
// Related Documents // Related Documents
$sql_related_documents = mysqli_query($mysqli, "SELECT * FROM asset_documents $sql_related_documents = mysqli_query($mysqli, "SELECT * FROM asset_documents
LEFT JOIN documents ON asset_documents.document_id = documents.document_id LEFT JOIN documents ON asset_documents.document_id = documents.document_id
LEFT JOIN users ON user_id = document_created_by
WHERE asset_documents.asset_id = $asset_id WHERE asset_documents.asset_id = $asset_id
AND document_archived_at IS NULL AND document_archived_at IS NULL
ORDER BY document_name DESC" ORDER BY document_name DESC"
@ -446,68 +454,69 @@ ob_start();
<?php <?php
while ($row = mysqli_fetch_array($sql_related_credentials)) { while ($row = mysqli_fetch_array($sql_related_credentials)) {
$login_id = intval($row['login_id']); $credential_id = intval($row['credential_id']);
$login_name = nullable_htmlentities($row['login_name']); $credential_name = nullable_htmlentities($row['credential_name']);
$login_description = nullable_htmlentities($row['login_description']); $credential_description = nullable_htmlentities($row['credential_description']);
$login_uri = nullable_htmlentities($row['login_uri']); $credential_uri = nullable_htmlentities($row['credential_uri']);
if (empty($login_uri)) { if (empty($credential_uri)) {
$login_uri_display = "-"; $credential_uri_display = "-";
} else { } else {
$login_uri_display = "$login_uri"; $credential_uri_display = "$credential_uri";
} }
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username'])); $credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
if (empty($login_username)) { if (empty($credential_username)) {
$login_username_display = "-"; $credential_username_display = "-";
} else { } else {
$login_username_display = "$login_username"; $credential_username_display = "$credential_username <button type='button' class='btn btn-sm clipboardjs' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
} }
$login_password = nullable_htmlentities(decryptLoginEntry($row['login_password'])); $credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$login_otp_secret = nullable_htmlentities($row['login_otp_secret']); $credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']);
$login_id_with_secret = '"' . $row['login_id'] . '","' . $row['login_otp_secret'] . '"'; $credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
if (empty($login_otp_secret)) { if (empty($credential_otp_secret)) {
$otp_display = "-"; $otp_display = "-";
} else { } else {
$otp_display = "<span onmouseenter='showOTPViaLoginID($login_id)'><i class='far fa-clock'></i> <span id='otp_$login_id'><i>Hover..</i></span></span>"; $otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
} }
$login_note = nullable_htmlentities($row['login_note']); $credential_note = nullable_htmlentities($row['credential_note']);
$login_important = intval($row['login_important']); $credential_important = intval($row['credential_important']);
$login_contact_id = intval($row['login_contact_id']); $credential_contact_id = intval($row['credential_contact_id']);
$login_asset_id = intval($row['login_asset_id']); $credential_asset_id = intval($row['credential_asset_id']);
// Tags // Tags
$login_tag_name_display_array = array(); $credential_tag_name_display_array = array();
$login_tag_id_array = array(); $credential_tag_id_array = array();
$sql_login_tags = mysqli_query($mysqli, "SELECT * FROM login_tags LEFT JOIN tags ON login_tags.tag_id = tags.tag_id WHERE login_id = $login_id ORDER BY tag_name ASC"); $sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_login_tags)) { while ($row = mysqli_fetch_array($sql_credential_tags)) {
$login_tag_id = intval($row['tag_id']); $credential_tag_id = intval($row['tag_id']);
$login_tag_name = nullable_htmlentities($row['tag_name']); $credential_tag_name = nullable_htmlentities($row['tag_name']);
$login_tag_color = nullable_htmlentities($row['tag_color']); $credential_tag_color = nullable_htmlentities($row['tag_color']);
if (empty($login_tag_color)) { if (empty($credential_tag_color)) {
$login_tag_color = "dark"; $credential_tag_color = "dark";
} }
$login_tag_icon = nullable_htmlentities($row['tag_icon']); $credential_tag_icon = nullable_htmlentities($row['tag_icon']);
if (empty($login_tag_icon)) { if (empty($credential_tag_icon)) {
$login_tag_icon = "tag"; $credential_tag_icon = "tag";
} }
$login_tag_id_array[] = $login_tag_id; $credential_tag_id_array[] = $credential_tag_id;
$login_tag_name_display_array[] = "<a href='client_logins.php?client_id=$client_id&tags[]=$login_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $login_tag_color;'><i class='fa fa-fw fa-$login_tag_icon mr-2'></i>$login_tag_name</span></a>"; $credential_tag_name_display_array[] = "<a href='credentials.php?client_id=$client_id&tags[]=$credential_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $credential_tag_color;'><i class='fa fa-fw fa-$credential_tag_icon mr-2'></i>$credential_tag_name</span></a>";
} }
$login_tags_display = implode('', $login_tag_name_display_array); $credential_tags_display = implode('', $credential_tag_name_display_array);
?> ?>
<tr> <tr>
<td> <td>
<i class="fa fa-fw fa-key text-secondary"></i> <i class="fa fa-fw fa-key text-secondary"></i>
<?php echo $login_name; ?> <?php echo $credential_name; ?>
</td> </td>
<td><?php echo $login_username_display; ?></td> <td><?php echo $credential_username_display; ?></td>
<td> <td>
<button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $login_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button> <button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $credential_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button>
<button type='button' class='btn btn-sm clipboardjs' data-clipboard-text='<?php echo $credential_password; ?>'><i class='far fa-copy text-secondary'></i></button>
</td> </td>
<td><?php echo $otp_display; ?></td> <td><?php echo $otp_display; ?></td>
<td><?php echo $login_uri_display; ?></td> <td><?php echo $credential_uri_display; ?></td>
</tr> </tr>
<?php <?php
@ -520,7 +529,7 @@ ob_start();
</table> </table>
</div> </div>
</div> </div>
<!-- Include script to get TOTP code via the login ID --> <!-- Include script to get TOTP code via the credentials ID -->
<script src="js/credential_show_otp_via_id.js"></script> <script src="js/credential_show_otp_via_id.js"></script>
<?php } ?> <?php } ?>
@ -547,12 +556,13 @@ ob_start();
$ticket_number = intval($row['ticket_number']); $ticket_number = intval($row['ticket_number']);
$ticket_subject = nullable_htmlentities($row['ticket_subject']); $ticket_subject = nullable_htmlentities($row['ticket_subject']);
$ticket_priority = nullable_htmlentities($row['ticket_priority']); $ticket_priority = nullable_htmlentities($row['ticket_priority']);
$ticket_status_id = intval($row['ticket_status_id']);
$ticket_status_name = nullable_htmlentities($row['ticket_status_name']); $ticket_status_name = nullable_htmlentities($row['ticket_status_name']);
$ticket_status_color = nullable_htmlentities($row['ticket_status_color']); $ticket_status_color = nullable_htmlentities($row['ticket_status_color']);
$ticket_created_at = nullable_htmlentities($row['ticket_created_at']); $ticket_created_at = nullable_htmlentities($row['ticket_created_at']);
$ticket_updated_at = nullable_htmlentities($row['ticket_updated_at']); $ticket_updated_at = nullable_htmlentities($row['ticket_updated_at']);
if (empty($ticket_updated_at)) { if (empty($ticket_updated_at)) {
if ($ticket_status == "Closed") { if ($ticket_status_name == "Closed") {
$ticket_updated_at_display = "<p>Never</p>"; $ticket_updated_at_display = "<p>Never</p>";
} else { } else {
$ticket_updated_at_display = "<p class='text-danger'>Never</p>"; $ticket_updated_at_display = "<p class='text-danger'>Never</p>";
@ -573,7 +583,7 @@ ob_start();
} }
$ticket_assigned_to = intval($row['ticket_assigned_to']); $ticket_assigned_to = intval($row['ticket_assigned_to']);
if (empty($ticket_assigned_to)) { if (empty($ticket_assigned_to)) {
if ($ticket_status == 5) { if ($ticket_status_id == 5) {
$ticket_assigned_to_display = "<p>Not Assigned</p>"; $ticket_assigned_to_display = "<p>Not Assigned</p>";
} else { } else {
$ticket_assigned_to_display = "<p class='text-danger'>Not Assigned</p>"; $ticket_assigned_to_display = "<p class='text-danger'>Not Assigned</p>";
@ -628,18 +638,18 @@ ob_start();
<?php <?php
while ($row = mysqli_fetch_array($sql_related_recurring_tickets)) { while ($row = mysqli_fetch_array($sql_related_recurring_tickets)) {
$scheduled_ticket_id = intval($row['scheduled_ticket_id']); $recurring_ticket_id = intval($row['recurring_ticket_id']);
$scheduled_ticket_subject = nullable_htmlentities($row['scheduled_ticket_subject']); $recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']);
$scheduled_ticket_priority = nullable_htmlentities($row['scheduled_ticket_priority']); $recurring_ticket_priority = nullable_htmlentities($row['recurring_ticket_priority']);
$scheduled_ticket_frequency = nullable_htmlentities($row['scheduled_ticket_frequency']); $recurring_ticket_frequency = nullable_htmlentities($row['recurring_ticket_frequency']);
$scheduled_ticket_next_run = nullable_htmlentities($row['scheduled_ticket_next_run']); $recurring_ticket_next_run = nullable_htmlentities($row['recurring_ticket_next_run']);
?> ?>
<tr> <tr>
<td class="text-bold"><?php echo $scheduled_ticket_subject ?></td> <td class="text-bold"><?php echo $recurring_ticket_subject ?></td>
<td><?php echo $scheduled_ticket_priority ?></td> <td><?php echo $recurring_ticket_priority ?></td>
<td><?php echo $scheduled_ticket_frequency ?></td> <td><?php echo $recurring_ticket_frequency ?></td>
<td><?php echo $scheduled_ticket_next_run ?></td> <td><?php echo $recurring_ticket_next_run ?></td>
</tr> </tr>
<?php } ?> <?php } ?>
@ -679,11 +689,6 @@ ob_start();
$seat_count = 0; $seat_count = 0;
// Get Login
$login_id = intval($row['login_id']);
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username']));
$login_password = nullable_htmlentities(decryptLoginEntry($row['login_password']));
// Asset Licenses // Asset Licenses
$asset_licenses_sql = mysqli_query($mysqli, "SELECT asset_id FROM software_assets WHERE software_id = $software_id"); $asset_licenses_sql = mysqli_query($mysqli, "SELECT asset_id FROM software_assets WHERE software_id = $software_id");
$asset_licenses_array = array(); $asset_licenses_array = array();
@ -848,7 +853,7 @@ ob_start();
</div> </div>
<div class="modal-footer bg-white"> <div class="modal-footer bg-white">
<a href="asset_details.php?<?php echo $client_url; ?>asset_id=<?php echo $asset_id; ?>" class="btn btn-primary text-bold"><span class="text-white"><i class="fas fa-info-circle mr-2"></i>More Details</span></a> <a href="asset_details.php?client_id=<?php echo $client_id; ?>&asset_id=<?php echo $asset_id; ?>" class="btn btn-primary text-bold"><span class="text-white"><i class="fas fa-info-circle mr-2"></i>More Details</span></a>
<a href="#" class="btn btn-secondary" <a href="#" class="btn btn-secondary"
data-toggle="ajax-modal" data-ajax-url="ajax/ajax_asset_edit.php" data-ajax-id="<?php echo $asset_id; ?>"> data-toggle="ajax-modal" data-ajax-url="ajax/ajax_asset_edit.php" data-ajax-id="<?php echo $asset_id; ?>">
<span class="text-white"><i class="fas fa-edit mr-2"></i>Edit</span> <span class="text-white"><i class="fas fa-edit mr-2"></i>Edit</span>

View File

@ -4,7 +4,7 @@ require_once '../includes/ajax_header.php';
$event_id = intval($_GET['id']); $event_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM events LEFT JOIN calendars ON event_calendar_id = calendar_id WHERE event_id = $event_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id WHERE event_id = $event_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
$event_title = nullable_htmlentities($row['event_title']); $event_title = nullable_htmlentities($row['event_title']);

View File

@ -9,7 +9,7 @@ $sql = mysqli_query($mysqli, "SELECT * FROM contacts
LEFT JOIN locations ON location_id = contact_location_id LEFT JOIN locations ON location_id = contact_location_id
LEFT JOIN users ON user_id = contact_user_id LEFT JOIN users ON user_id = contact_user_id
WHERE contact_id = $contact_id WHERE contact_id = $contact_id
$client_query LIMIT 1
"); ");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
@ -51,21 +51,21 @@ $software_count = mysqli_num_rows($sql_linked_software);
$linked_software = array(); $linked_software = array();
// Related Logins Query 1 to 1 relationship // Related Credentials Query 1 to 1 relationship
$sql_related_logins = mysqli_query($mysqli, " $sql_related_credentials = mysqli_query($mysqli, "
SELECT SELECT
logins.login_id AS logins_login_id, -- Alias for logins.login_id credentials.credential_id AS credentials_credential_id, -- Alias for credentials.credential_id
logins.*, -- All other columns from logins credentials.*, -- All other columns from credentials
login_tags.*, -- All columns from login_tags credential_tags.*, -- All columns from credential_tags
tags.* -- All columns from tags tags.* -- All columns from tags
FROM logins FROM credentials
LEFT JOIN login_tags ON login_tags.login_id = logins.login_id LEFT JOIN credential_tags ON credential_tags.credential_id = credentials.credential_id
LEFT JOIN tags ON tags.tag_id = login_tags.tag_id LEFT JOIN tags ON tags.tag_id = credential_tags.tag_id
WHERE login_contact_id = $contact_id WHERE credential_contact_id = $contact_id
GROUP BY logins.login_id GROUP BY credentials.credential_id
ORDER BY login_name DESC ORDER BY credential_name DESC
"); ");
$credential_count = mysqli_num_rows($sql_related_logins); $credential_count = mysqli_num_rows($sql_related_credentials);
// Related Tickets Query - 1 to 1 relationship // Related Tickets Query - 1 to 1 relationship
$sql_related_tickets = mysqli_query($mysqli, "SELECT * FROM tickets $sql_related_tickets = mysqli_query($mysqli, "SELECT * FROM tickets
@ -75,9 +75,9 @@ $sql_related_tickets = mysqli_query($mysqli, "SELECT * FROM tickets
$ticket_count = mysqli_num_rows($sql_related_tickets); $ticket_count = mysqli_num_rows($sql_related_tickets);
// Related Recurring Tickets Query // Related Recurring Tickets Query
$sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM scheduled_tickets $sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM recurring_tickets
WHERE scheduled_ticket_contact_id = $contact_id WHERE recurring_ticket_contact_id = $contact_id
ORDER BY scheduled_ticket_next_run DESC" ORDER BY recurring_ticket_next_run DESC"
); );
$recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets); $recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets);
@ -114,7 +114,7 @@ $sql_linked_services = mysqli_query($mysqli, "SELECT * FROM service_contacts, se
AND service_contacts.service_id = services.service_id AND service_contacts.service_id = services.service_id
ORDER BY service_name ASC" ORDER BY service_name ASC"
); );
$service_count = mysqli_num_rows($sql_linked_services); $services_count = mysqli_num_rows($sql_linked_services);
$linked_services = array(); $linked_services = array();
@ -189,11 +189,6 @@ ob_start();
<a class="nav-link" data-toggle="pill" href="#pills-contact-recurring-tickets<?php echo $contact_id; ?>"><i class="fas fa-fw fa-redo-alt fa-2x"></i><br>Rcr Tickets (<?php echo $recurring_ticket_count; ?>)</a> <a class="nav-link" data-toggle="pill" href="#pills-contact-recurring-tickets<?php echo $contact_id; ?>"><i class="fas fa-fw fa-redo-alt fa-2x"></i><br>Rcr Tickets (<?php echo $recurring_ticket_count; ?>)</a>
</li> </li>
<?php } ?> <?php } ?>
<?php if ($services_count) { ?>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-contact-services<?php echo $contact_id; ?>"><i class="fas fa-fw fa-stream fa-2x"></i><br>Services (<?php echo $services_count; ?>)</a>
</li>
<?php } ?>
<?php if ($document_count) { ?> <?php if ($document_count) { ?>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-contact-documents<?php echo $contact_id; ?>"><i class="fas fa-fw fa-file-alt fa-2x"></i><br>Documents (<?php echo $document_count; ?>)</a> <a class="nav-link" data-toggle="pill" href="#pills-contact-documents<?php echo $contact_id; ?>"><i class="fas fa-fw fa-file-alt fa-2x"></i><br>Documents (<?php echo $document_count; ?>)</a>
@ -244,7 +239,7 @@ ob_start();
<div><i class="fa fa-fw fa-map-marker-alt text-secondary mr-2"></i><?php echo $location_name; ?></div> <div><i class="fa fa-fw fa-map-marker-alt text-secondary mr-2"></i><?php echo $location_name; ?></div>
<?php } <?php }
if ($contact_email) { ?> if ($contact_email) { ?>
<div class="mt-2"><i class="fa fa-fw fa-envelope text-secondary mr-2"></i><a href='mailto:<?php echo $contact_email; ?>'><?php echo $contact_email; ?></a><button class='btn btn-sm clipboardjs' data-clipboard-text='<?php echo $contact_email; ?>'><i class='far fa-copy text-secondary'></i></button></div> <div class="mt-2"><i class="fa fa-fw fa-envelope text-secondary mr-2"></i><a href='mailto:<?php echo $contact_email; ?>'><?php echo $contact_email; ?></a><button type="button" class='btn btn-sm clipboardjs' data-clipboard-text='<?php echo $contact_email; ?>'><i class='far fa-copy text-secondary'></i></button></div>
<?php } <?php }
if ($contact_phone) { ?> if ($contact_phone) { ?>
<div class="mt-2"><i class="fa fa-fw fa-phone text-secondary mr-2"></i><a href="tel:<?php echo "$contact_phone"?>"><?php echo $contact_phone; ?></a></div> <div class="mt-2"><i class="fa fa-fw fa-phone text-secondary mr-2"></i><a href="tel:<?php echo "$contact_phone"?>"><?php echo $contact_phone; ?></a></div>
@ -404,7 +399,7 @@ ob_start();
<?php if ($credential_count) { ?> <?php if ($credential_count) { ?>
<div class="tab-pane fade" id="pills-contact-credentials<?php echo $contact_id; ?>"> <div class="tab-pane fade" id="pills-contact-credentials<?php echo $contact_id; ?>">
<div class="table-responsive-sm"> <div class="table-responsive-sm">
<table class="table table-striped table-borderless table-hover table-sm"> <table class="table table-striped table-borderless table-hover table-sm dataTables" style="width:100%">
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>Name</th>
@ -418,68 +413,70 @@ ob_start();
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_logins)) { while ($row = mysqli_fetch_array($sql_related_credentials)) {
$login_id = intval($row['logins_login_id']); $credential_id = intval($row['credentials_credential_id']);
$login_name = nullable_htmlentities($row['login_name']); $credential_name = nullable_htmlentities($row['credential_name']);
$login_description = nullable_htmlentities($row['login_description']); $credential_description = nullable_htmlentities($row['credential_description']);
$login_uri = nullable_htmlentities($row['login_uri']); $credential_uri = nullable_htmlentities($row['credential_uri']);
if (empty($login_uri)) { if (empty($credential_uri)) {
$login_uri_display = "-"; $credential_uri_display = "-";
} else { } else {
$login_uri_display = "$login_uri"; $credential_uri_display = "$credential_uri";
} }
$login_uri_2 = nullable_htmlentities($row['login_uri_2']); $credential_uri_2 = nullable_htmlentities($row['credential_uri_2']);
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username'])); $credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
if (empty($login_username)) { if (empty($credential_username)) {
$login_username_display = "-"; $credential_username_display = "-";
} else { } else {
$login_username_display = "$login_username"; $credential_username_display = "$credential_username <button type='button' class='btn btn-sm clipboardjs' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
} }
$login_password = nullable_htmlentities(decryptLoginEntry($row['login_password'])); $credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$login_otp_secret = nullable_htmlentities($row['login_otp_secret']); $credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']);
$login_id_with_secret = '"' . $row['login_id'] . '","' . $row['login_otp_secret'] . '"'; $credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
if (empty($login_otp_secret)) { if (empty($credential_otp_secret)) {
$otp_display = "-"; $otp_display = "-";
} else { } else {
$otp_display = "<span onmouseenter='showOTPViaLoginID($login_id)'><i class='far fa-clock'></i> <span id='otp_$login_id'><i>Hover..</i></span></span>"; $otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
} }
$login_note = nullable_htmlentities($row['login_note']); $credential_note = nullable_htmlentities($row['credential_note']);
$login_important = intval($row['login_important']); $credential_important = intval($row['credential_important']);
$login_contact_id = intval($row['login_contact_id']); $credential_contact_id = intval($row['credential_contact_id']);
$login_asset_id = intval($row['login_asset_id']); $credential_asset_id = intval($row['credential_asset_id']);
// Tags // Tags
$login_tag_name_display_array = array(); $credential_tag_name_display_array = array();
$login_tag_id_array = array(); $credential_tag_id_array = array();
$sql_login_tags = mysqli_query($mysqli, "SELECT * FROM login_tags LEFT JOIN tags ON login_tags.tag_id = tags.tag_id WHERE login_id = $login_id ORDER BY tag_name ASC"); $sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_login_tags)) { while ($row = mysqli_fetch_array($sql_credential_tags)) {
$login_tag_id = intval($row['tag_id']); $credential_tag_id = intval($row['tag_id']);
$login_tag_name = nullable_htmlentities($row['tag_name']); $credential_tag_name = nullable_htmlentities($row['tag_name']);
$login_tag_color = nullable_htmlentities($row['tag_color']); $credential_tag_color = nullable_htmlentities($row['tag_color']);
if (empty($login_tag_color)) { if (empty($credential_tag_color)) {
$login_tag_color = "dark"; $credential_tag_color = "dark";
} }
$login_tag_icon = nullable_htmlentities($row['tag_icon']); $credential_tag_icon = nullable_htmlentities($row['tag_icon']);
if (empty($login_tag_icon)) { if (empty($credential_tag_icon)) {
$login_tag_icon = "tag"; $credential_tag_icon = "tag";
} }
$login_tag_id_array[] = $login_tag_id; $credential_tag_id_array[] = $credential_tag_id;
$login_tag_name_display_array[] = "<a href='client_logins.php?client_id=$client_id&tags[]=$login_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $login_tag_color;'><i class='fa fa-fw fa-$login_tag_icon mr-2'></i>$login_tag_name</span></a>"; $credential_tag_name_display_array[] = "<a href='credentials.php?client_id=$client_id&tags[]=$credential_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $credential_tag_color;'><i class='fa fa-fw fa-$credential_tag_icon mr-2'></i>$credential_tag_name</span></a>";
} }
$login_tags_display = implode('', $login_tag_name_display_array); $credential_tags_display = implode('', $credential_tag_name_display_array);
?> ?>
<tr> <tr>
<td><i class="fa fa-fw fa-key text-secondary mr-2"></i><?php echo $login_name; ?></td> <td><i class="fa fa-fw fa-key text-secondary mr-2"></i><?php echo $credential_name; ?></td>
<td><?php echo $login_description; ?></td> <td><?php echo $credential_description; ?></td>
<td><?php echo $login_username_display; ?></td> <td><?php echo $credential_username_display; ?></td>
<td> <td>
<button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $login_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button> <button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $credential_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button>
<button type="button" class='btn btn-sm clipboardjs' data-clipboard-text='<?php echo $credential_password; ?>'><i class='far fa-copy text-secondary'></i></button>
</td> </td>
<td><?php echo $otp_display; ?></td> <td><?php echo $otp_display; ?></td>
<td><?php echo $login_uri_display; ?></td> <td><?php echo $credential_uri_display; ?></td>
</tr> </tr>
<?php <?php
@ -492,7 +489,7 @@ ob_start();
</table> </table>
</div> </div>
</div> </div>
<!-- Include script to get TOTP code via the login ID --> <!-- Include script to get TOTP code via the credential ID -->
<script src="js/credential_show_otp_via_id.js"></script> <script src="js/credential_show_otp_via_id.js"></script>
<?php } ?> <?php } ?>
@ -597,18 +594,18 @@ ob_start();
<?php <?php
while ($row = mysqli_fetch_array($sql_related_recurring_tickets)) { while ($row = mysqli_fetch_array($sql_related_recurring_tickets)) {
$scheduled_ticket_id = intval($row['scheduled_ticket_id']); $recurring_ticket_id = intval($row['recurring_ticket_id']);
$scheduled_ticket_subject = nullable_htmlentities($row['scheduled_ticket_subject']); $recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']);
$scheduled_ticket_priority = nullable_htmlentities($row['scheduled_ticket_priority']); $recurring_ticket_priority = nullable_htmlentities($row['recurring_ticket_priority']);
$scheduled_ticket_frequency = nullable_htmlentities($row['scheduled_ticket_frequency']); $recurring_ticket_frequency = nullable_htmlentities($row['recurring_ticket_frequency']);
$scheduled_ticket_next_run = nullable_htmlentities($row['scheduled_ticket_next_run']); $recurring_ticket_next_run = nullable_htmlentities($row['recurring_ticket_next_run']);
?> ?>
<tr> <tr>
<td class="text-bold"><?php echo $scheduled_ticket_subject ?></td> <td class="text-bold"><?php echo $recurring_ticket_subject ?></td>
<td><?php echo $scheduled_ticket_priority ?></td> <td><?php echo $recurring_ticket_priority ?></td>
<td><?php echo $scheduled_ticket_frequency ?></td> <td><?php echo $recurring_ticket_frequency ?></td>
<td><?php echo $scheduled_ticket_next_run ?></td> <td><?php echo $recurring_ticket_next_run ?></td>
</tr> </tr>
<?php } ?> <?php } ?>
@ -846,7 +843,7 @@ ob_start();
</div> </div>
<div class="modal-footer bg-white"> <div class="modal-footer bg-white">
<a href="contact_details.php?<?php echo $client_url; ?>contact_id=<?php echo $contact_id; ?>" class="btn btn-primary text-bold"> <a href="contact_details.php?client_id=<?php echo $client_id; ?>&contact_id=<?php echo $contact_id; ?>" class="btn btn-primary text-bold">
<span class="text-white"><i class="fas fa-info-circle mr-2"></i>More Details</span> <span class="text-white"><i class="fas fa-info-circle mr-2"></i>More Details</span>
</a> </a>
<a href="#" class="btn btn-secondary" <a href="#" class="btn btn-secondary"

View File

@ -2,33 +2,32 @@
require_once '../includes/ajax_header.php'; require_once '../includes/ajax_header.php';
$login_id = intval($_GET['id']); $credential_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM logins WHERE login_id = $login_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM credentials WHERE credential_id = $credential_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
$client_id = intval($row['login_client_id']); $client_id = intval($row['credential_client_id']);
$login_id = intval($row['login_id']); $credential_name = nullable_htmlentities($row['credential_name']);
$login_name = nullable_htmlentities($row['login_name']); $credential_description = nullable_htmlentities($row['credential_description']);
$login_description = nullable_htmlentities($row['login_description']); $credential_uri = nullable_htmlentities($row['credential_uri']);
$login_uri = nullable_htmlentities($row['login_uri']); $credential_uri_2 = nullable_htmlentities($row['credential_uri_2']);
$login_uri_2 = nullable_htmlentities($row['login_uri_2']); $credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username'])); $credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$login_password = nullable_htmlentities(decryptLoginEntry($row['login_password'])); $credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']);
$login_otp_secret = nullable_htmlentities($row['login_otp_secret']); $credential_note = nullable_htmlentities($row['credential_note']);
$login_note = nullable_htmlentities($row['login_note']); $credential_created_at = nullable_htmlentities($row['credential_created_at']);
$login_created_at = nullable_htmlentities($row['login_created_at']); $credential_archived_at = nullable_htmlentities($row['credential_archived_at']);
$login_archived_at = nullable_htmlentities($row['login_archived_at']); $credential_important = intval($row['credential_important']);
$login_important = intval($row['login_important']); $credential_contact_id = intval($row['credential_contact_id']);
$login_contact_id = intval($row['login_contact_id']); $credential_asset_id = intval($row['credential_asset_id']);
$login_asset_id = intval($row['login_asset_id']);
// Tags // Tags
$login_tag_id_array = array(); $credential_tag_id_array = array();
$sql_login_tags = mysqli_query($mysqli, "SELECT tag_id FROM login_tags WHERE login_id = $login_id"); $sql_credential_tags = mysqli_query($mysqli, "SELECT tag_id FROM credential_tags WHERE credential_id = $credential_id");
while ($row = mysqli_fetch_array($sql_login_tags)) { while ($row = mysqli_fetch_array($sql_credential_tags)) {
$login_tag_id = intval($row['tag_id']); $credential_tag_id = intval($row['tag_id']);
$login_tag_id_array[] = $login_tag_id; $credential_tag_id_array[] = $credential_tag_id;
} }
// Generate the HTML form content using output buffering. // Generate the HTML form content using output buffering.
@ -36,26 +35,26 @@ ob_start();
?> ?>
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title"><i class='fas fa-fw fa-key mr-2'></i>Editing credential: <strong><?php echo $login_name; ?></strong></h5> <h5 class="modal-title"><i class='fas fa-fw fa-key mr-2'></i>Editing credential: <strong><?php echo $credential_name; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span> <span>&times;</span>
</button> </button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="login_id" value="<?php echo $login_id; ?>"> <input type="hidden" name="credential_id" value="<?php echo $credential_id; ?>">
<input type="hidden" name="client_id" value="<?php echo $client_id; ?>"> <input type="hidden" name="client_id" value="<?php echo $client_id; ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-login-details<?php echo $login_id; ?>">Details</a> <a class="nav-link active" data-toggle="pill" href="#pills-credential-details<?php echo $credential_id; ?>">Details</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-login-relation<?php echo $login_id; ?>">Relation</a> <a class="nav-link" data-toggle="pill" href="#pills-credential-relation<?php echo $credential_id; ?>">Relation</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-login-notes<?php echo $login_id; ?>">Notes</a> <a class="nav-link" data-toggle="pill" href="#pills-credential-notes<?php echo $credential_id; ?>">Notes</a>
</li> </li>
</ul> </ul>
@ -63,7 +62,7 @@ ob_start();
<div class="tab-content" <?php if (lookupUserPermission('module_credential') <= 1) { echo 'inert'; } ?>> <div class="tab-content" <?php if (lookupUserPermission('module_credential') <= 1) { echo 'inert'; } ?>>
<div class="tab-pane fade show active" id="pills-login-details<?php echo $login_id; ?>"> <div class="tab-pane fade show active" id="pills-credential-details<?php echo $credential_id; ?>">
<div class="form-group"> <div class="form-group">
<label>Name <strong class="text-danger">*</strong> / <span class="text-secondary">Important?</span></label> <label>Name <strong class="text-danger">*</strong> / <span class="text-secondary">Important?</span></label>
@ -71,10 +70,10 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div> </div>
<input type="text" class="form-control" name="name" placeholder="Name of Login" maxlength="200" value="<?php echo $login_name; ?>" required> <input type="text" class="form-control" name="name" placeholder="Name of Credential" maxlength="200" value="<?php echo $credential_name; ?>" required>
<div class="input-group-append"> <div class="input-group-append">
<div class="input-group-text"> <div class="input-group-text">
<input type="checkbox" name="important" value="1" <?php if ($login_important == 1) { echo "checked"; } ?>> <input type="checkbox" name="important" value="1" <?php if ($credential_important == 1) { echo "checked"; } ?>>
</div> </div>
</div> </div>
</div> </div>
@ -86,7 +85,7 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-angle-right"></i></span>
</div> </div>
<input type="text" class="form-control" name="description" placeholder="Description" value="<?php echo $login_description; ?>"> <input type="text" class="form-control" name="description" placeholder="Description" value="<?php echo $credential_description; ?>">
</div> </div>
</div> </div>
@ -96,7 +95,7 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div> </div>
<input type="text" class="form-control" name="username" placeholder="Username or ID" maxlength="350" value="<?php echo $login_username; ?>"> <input type="text" class="form-control" name="username" placeholder="Username or ID" maxlength="350" value="<?php echo $credential_username; ?>">
</div> </div>
</div> </div>
@ -106,12 +105,12 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
</div> </div>
<input type="password" class="form-control" data-toggle="password" name="password" placeholder="Password or Key" maxlength="350" value="<?php echo $login_password; ?>" required autocomplete="new-password"> <input type="password" class="form-control" data-toggle="password" name="password" placeholder="Password or Key" maxlength="350" value="<?php echo $credential_password; ?>" required autocomplete="new-password">
<div class="input-group-append"> <div class="input-group-append">
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
</div> </div>
<div class="input-group-append"> <div class="input-group-append">
<button class="btn btn-default clipboardjs" type="button" data-clipboard-text="<?php echo $login_password; ?>"><i class="fa fa-fw fa-copy"></i></button> <button class="btn btn-default clipboardjs" type="button" data-clipboard-text="<?php echo $credential_password; ?>"><i class="fa fa-fw fa-copy"></i></button>
</div> </div>
</div> </div>
</div> </div>
@ -122,7 +121,7 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div> </div>
<input type="password" class="form-control" data-toggle="password" name="otp_secret" maxlength="200" value="<?php echo $login_otp_secret; ?>" placeholder="Insert secret key"> <input type="password" class="form-control" data-toggle="password" name="otp_secret" maxlength="200" value="<?php echo $credential_otp_secret; ?>" placeholder="Insert secret key">
<div class="input-group-append"> <div class="input-group-append">
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
</div> </div>
@ -135,13 +134,13 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-link"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-link"></i></span>
</div> </div>
<input type="text" class="form-control" name="uri" placeholder="ex. http://192.168.1.1" maxlength="500" value="<?php echo $login_uri; ?>"> <input type="text" class="form-control" name="uri" placeholder="ex. http://192.168.1.1" maxlength="500" value="<?php echo $credential_uri; ?>">
<div class="input-group-append"> <div class="input-group-append">
<a href="<?php echo $login_uri; ?>" class="input-group-text"><i class="fa fa-fw fa-link"></i></a> <a href="<?php echo $credential_uri; ?>" class="input-group-text"><i class="fa fa-fw fa-link"></i></a>
</div> </div>
<div class="input-group-append"> <div class="input-group-append">
<button class="input-group-text clipboardjs" type="button" data-clipboard-text="<?php echo $login_uri; ?>"><i class="fa fa-fw fa-copy"></i></button> <button class="input-group-text clipboardjs" type="button" data-clipboard-text="<?php echo $credential_uri; ?>"><i class="fa fa-fw fa-copy"></i></button>
</div> </div>
</div> </div>
</div> </div>
@ -152,19 +151,19 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-link"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-link"></i></span>
</div> </div>
<input type="text" class="form-control" name="uri_2" placeholder="ex. https://server.company.com:5001" maxlength="500" value="<?php echo $login_uri_2; ?>"> <input type="text" class="form-control" name="uri_2" placeholder="ex. https://server.company.com:5001" maxlength="500" value="<?php echo $credential_uri_2; ?>">
<div class="input-group-append"> <div class="input-group-append">
<a href="<?php echo $login_uri_2; ?>" class="input-group-text"><i class="fa fa-fw fa-link"></i></a> <a href="<?php echo $credential_uri_2; ?>" class="input-group-text"><i class="fa fa-fw fa-link"></i></a>
</div> </div>
<div class="input-group-append"> <div class="input-group-append">
<button class="input-group-text clipboardjs" type="button" data-clipboard-text="<?php echo $login_uri_2; ?>"><i class="fa fa-fw fa-copy"></i></button> <button class="input-group-text clipboardjs" type="button" data-clipboard-text="<?php echo $credential_uri_2; ?>"><i class="fa fa-fw fa-copy"></i></button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="tab-pane fade" id="pills-login-relation<?php echo $login_id; ?>"> <div class="tab-pane fade" id="pills-credential-relation<?php echo $credential_id; ?>">
<div class="form-group"> <div class="form-group">
<label>Contact</label> <label>Contact</label>
@ -173,7 +172,7 @@ ob_start();
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
</div> </div>
<select class="form-control select2" name="contact"> <select class="form-control select2" name="contact">
<option value="">- Contact -</option> <option value="">- Select Contact -</option>
<?php <?php
$sql_contacts = mysqli_query($mysqli, "SELECT contact_id, contact_name FROM contacts WHERE contact_client_id = $client_id ORDER BY contact_name ASC"); $sql_contacts = mysqli_query($mysqli, "SELECT contact_id, contact_name FROM contacts WHERE contact_client_id = $client_id ORDER BY contact_name ASC");
@ -181,7 +180,7 @@ ob_start();
$contact_id_select = intval($row['contact_id']); $contact_id_select = intval($row['contact_id']);
$contact_name_select = nullable_htmlentities($row['contact_name']); $contact_name_select = nullable_htmlentities($row['contact_name']);
?> ?>
<option <?php if ($login_contact_id == $contact_id_select) { echo "selected"; } ?> value="<?php echo $contact_id_select; ?>"><?php echo $contact_name_select; ?></option> <option <?php if ($credential_contact_id == $contact_id_select) { echo "selected"; } ?> value="<?php echo $contact_id_select; ?>"><?php echo $contact_name_select; ?></option>
<?php } ?> <?php } ?>
</select> </select>
</div> </div>
@ -194,7 +193,7 @@ ob_start();
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div> </div>
<select class="form-control select2" name="asset"> <select class="form-control select2" name="asset">
<option value="0">- None -</option> <option value="0">- Select Asset -</option>
<?php <?php
$sql_assets = mysqli_query($mysqli, "SELECT asset_id, asset_name, location_name FROM assets LEFT JOIN locations on asset_location_id = location_id WHERE asset_client_id = $client_id AND asset_archived_at IS NULL ORDER BY asset_name ASC"); $sql_assets = mysqli_query($mysqli, "SELECT asset_id, asset_name, location_name FROM assets LEFT JOIN locations on asset_location_id = location_id WHERE asset_client_id = $client_id AND asset_archived_at IS NULL ORDER BY asset_name ASC");
@ -209,7 +208,7 @@ ob_start();
} }
?> ?>
<option <?php if ($login_asset_id == $asset_id_select) { echo "selected"; } ?> value="<?php echo $asset_id_select; ?>"><?php echo $asset_select_display_string; ?></option> <option <?php if ($credential_asset_id == $asset_id_select) { echo "selected"; } ?> value="<?php echo $asset_id_select; ?>"><?php echo $asset_select_display_string; ?></option>
<?php } ?> <?php } ?>
</select> </select>
@ -218,10 +217,10 @@ ob_start();
</div> </div>
<div class="tab-pane fade" id="pills-login-notes<?php echo $login_id; ?>"> <div class="tab-pane fade" id="pills-credential-notes<?php echo $credential_id; ?>">
<div class="form-group"> <div class="form-group">
<textarea class="form-control" rows="12" placeholder="Enter some notes" name="note"><?php echo $login_note; ?></textarea> <textarea class="form-control" rows="12" placeholder="Enter some notes" name="note"><?php echo $credential_note; ?></textarea>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -238,7 +237,7 @@ ob_start();
$tag_id_select = intval($row['tag_id']); $tag_id_select = intval($row['tag_id']);
$tag_name_select = nullable_htmlentities($row['tag_name']); $tag_name_select = nullable_htmlentities($row['tag_name']);
?> ?>
<option value="<?php echo $tag_id_select; ?>" <?php if (in_array($tag_id_select, $login_tag_id_array)) { echo "selected"; } ?>><?php echo $tag_name_select; ?></option> <option value="<?php echo $tag_id_select; ?>" <?php if (in_array($tag_id_select, $credential_tag_id_array)) { echo "selected"; } ?>><?php echo $tag_name_select; ?></option>
<?php } ?> <?php } ?>
</select> </select>
@ -259,7 +258,7 @@ ob_start();
</div> </div>
</div> </div>
<div class="modal-footer bg-white"> <div class="modal-footer bg-white">
<button type="submit" name="edit_login" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button> <button type="submit" name="edit_credential" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@ -2,26 +2,26 @@
require_once '../includes/ajax_header.php'; require_once '../includes/ajax_header.php';
$login_id = intval($_GET['id']); $credential_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM logins WHERE login_id = $login_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM credentials WHERE credential_id = $credential_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
$login_name = nullable_htmlentities($row['login_name']); $credential_name = nullable_htmlentities($row['credential_name']);
$login_description = nullable_htmlentities($row['login_description']); $credential_description = nullable_htmlentities($row['credential_description']);
$login_uri = nullable_htmlentities($row['login_uri']); $credential_uri = nullable_htmlentities($row['credential_uri']);
$login_uri_2 = nullable_htmlentities($row['login_uri_2']); $credential_uri_2 = nullable_htmlentities($row['credential_uri_2']);
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username'])); $credential_username = nullable_htmlentities(decryptLoginEntry($row['credential_username']));
$login_password = nullable_htmlentities(decryptLoginEntry($row['login_password'])); $credential_password = nullable_htmlentities(decryptLoginEntry($row['credential_password']));
$login_otp_secret = nullable_htmlentities($row['login_otp_secret']); $credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']);
$login_id_with_secret = '"' . $row['login_id'] . '","' . $row['login_otp_secret'] . '"'; $credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
if (empty($login_otp_secret)) { if (empty($credential_otp_secret)) {
$otp_display = "-"; $otp_display = "-";
} else { } else {
$otp_display = "<span onmouseenter='showOTPViaLoginID($login_id)'><i class='far fa-clock'></i> <span id='otp_$login_id'><i>Hover..</i></span></span>"; $otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
} }
$login_note = nullable_htmlentities($row['login_note']); $credential_note = nullable_htmlentities($row['credential_note']);
$login_created_at = nullable_htmlentities($row['login_created_at']); $credential_created_at = nullable_htmlentities($row['credential_created_at']);
// Generate the HTML form content using output buffering. // Generate the HTML form content using output buffering.
ob_start(); ob_start();

View File

@ -74,9 +74,8 @@ ob_start();
<?php <?php
$sql_project_managers_select = mysqli_query( $sql_project_managers_select = mysqli_query(
$mysqli, $mysqli,
"SELECT users.user_id, user_name FROM users "SELECT user_id, user_name FROM users
LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role_id > 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
WHERE user_role > 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
); );
while ($row = mysqli_fetch_array($sql_project_managers_select)) { while ($row = mysqli_fetch_array($sql_project_managers_select)) {
$user_id_select = intval($row['user_id']); $user_id_select = intval($row['user_id']);

View File

@ -2,33 +2,33 @@
require_once '../includes/ajax_header.php'; require_once '../includes/ajax_header.php';
$recurring_id = intval($_GET['id']); $recurring_invoice_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM recurring WHERE recurring_id = $recurring_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM recurring_invoices WHERE recurring_invoice_id = $recurring_invoice_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
$recurring_prefix = nullable_htmlentities($row['recurring_prefix']); $recurring_invoice_prefix = nullable_htmlentities($row['recurring_invoice_prefix']);
$recurring_number = intval($row['recurring_number']); $recurring_invoice_number = intval($row['recurring_invoice_number']);
$recurring_scope = nullable_htmlentities($row['recurring_scope']); $recurring_invoice_scope = nullable_htmlentities($row['recurring_invoice_scope']);
$recurring_frequency = nullable_htmlentities($row['recurring_frequency']); $recurring_invoice_frequency = nullable_htmlentities($row['recurring_invoice_frequency']);
$recurring_status = nullable_htmlentities($row['recurring_status']); $recurring_invoice_status = nullable_htmlentities($row['recurring_invoice_status']);
$recurring_created_at = date('Y-m-d', strtotime($row['recurring_created_at'])); $recurring_invoice_created_at = date('Y-m-d', strtotime($row['recurring_invoice_created_at']));
$recurring_next_date = nullable_htmlentities($row['recurring_next_date']); $recurring_invoice_next_date = nullable_htmlentities($row['recurring_invoice_next_date']);
$recurring_discount = floatval($row['recurring_discount_amount']); $recurring_invoice_discount = floatval($row['recurring_invoice_discount_amount']);
$category_id = intval($row['recurring_category_id']); $category_id = intval($row['recurring_invoice_category_id']);
// Generate the HTML form content using output buffering. // Generate the HTML form content using output buffering.
ob_start(); ob_start();
?> ?>
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title"><i class="fas fa-fw fa-redo-alt mr-2"></i>Editing Recur Invoice: <strong><?php echo "$recurring_prefix$recurring_number"; ?></strong></h5> <h5 class="modal-title"><i class="fas fa-fw fa-redo-alt mr-2"></i>Editing Recur Invoice: <strong><?php echo "$recurring_invoice_prefix$recurring_invoice_number"; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span> <span>&times;</span>
</button> </button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="recurring_id" value="<?php echo $recurring_id; ?>"> <input type="hidden" name="recurring_invoice_id" value="<?php echo $recurring_invoice_id; ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">
@ -38,7 +38,7 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-comment"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-comment"></i></span>
</div> </div>
<input type="text" class="form-control" name="scope" placeholder="Quick description" maxlength="255" value="<?php echo $recurring_scope; ?>"> <input type="text" class="form-control" name="scope" placeholder="Quick description" maxlength="255" value="<?php echo $recurring_invoice_scope; ?>">
</div> </div>
</div> </div>
@ -50,8 +50,8 @@ ob_start();
</div> </div>
<select class="form-control select2" name="frequency" required> <select class="form-control select2" name="frequency" required>
<option value="">- Frequency -</option> <option value="">- Frequency -</option>
<option <?php if ($recurring_frequency == 'month') { echo "selected"; } ?> value="month">Monthly</option> <option <?php if ($recurring_invoice_frequency == 'month') { echo "selected"; } ?> value="month">Monthly</option>
<option <?php if ($recurring_frequency == 'year') { echo "selected"; } ?> value="year">Yearly</option> <option <?php if ($recurring_invoice_frequency == 'year') { echo "selected"; } ?> value="year">Yearly</option>
</select> </select>
</div> </div>
</div> </div>
@ -62,7 +62,7 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div> </div>
<input type="date" class="form-control" name="next_date" max="2999-12-31" value="<?php echo $recurring_next_date; ?>" required> <input type="date" class="form-control" name="next_date" max="2999-12-31" value="<?php echo $recurring_invoice_next_date; ?>" required>
</div> </div>
</div> </div>
@ -76,7 +76,7 @@ ob_start();
<option value="">- Category -</option> <option value="">- Category -</option>
<?php <?php
$sql_income_category = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Income' AND (category_archived_at > '$recurring_created_at' OR category_archived_at IS NULL) ORDER BY category_name ASC"); $sql_income_category = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Income' AND (category_archived_at > '$recurring_invoice_created_at' OR category_archived_at IS NULL) ORDER BY category_name ASC");
while ($row = mysqli_fetch_array($sql_income_category)) { while ($row = mysqli_fetch_array($sql_income_category)) {
$category_id_select = intval($row['category_id']); $category_id_select = intval($row['category_id']);
$category_name_select = nullable_htmlentities($row['category_name']); $category_name_select = nullable_htmlentities($row['category_name']);
@ -104,7 +104,7 @@ ob_start();
<div class='input-group-prepend'> <div class='input-group-prepend'>
<span class='input-group-text'><i class='fa fa-fw fa-dollar-sign'></i></span> <span class='input-group-text'><i class='fa fa-fw fa-dollar-sign'></i></span>
</div> </div>
<input type='text' class='form-control' inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" name='recurring_discount' placeholder='0.00' value="<?php echo number_format($recurring_discount, 2, '.', ''); ?>"> <input type='text' class='form-control' inputmode="numeric" pattern="-?[0-9]*\.?[0-9]{0,2}" name='recurring_invoice_discount' placeholder='0.00' value="<?php echo number_format($recurring_invoice_discount, 2, '.', ''); ?>">
</div> </div>
</div> </div>
@ -115,10 +115,10 @@ ob_start();
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
</div> </div>
<select class="form-control select2" name="status" required> <select class="form-control select2" name="status" required>
<option <?php if ($recurring_status == 1) { <option <?php if ($recurring_invoice_status == 1) {
echo "selected"; echo "selected";
} ?> value="1">Active</option> } ?> value="1">Active</option>
<option <?php if ($recurring_status == 0) { <option <?php if ($recurring_invoice_status == 0) {
echo "selected"; echo "selected";
} ?> value="0">InActive</option> } ?> value="0">InActive</option>
</select> </select>
@ -127,7 +127,7 @@ ob_start();
</div> </div>
<div class="modal-footer bg-white"> <div class="modal-footer bg-white">
<button type="submit" name="edit_recurring" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="edit_recurring_invoice" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@ -2,56 +2,64 @@
require_once '../includes/ajax_header.php'; require_once '../includes/ajax_header.php';
$scheduled_ticket_id = intval($_GET['id']); $recurring_ticket_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM scheduled_tickets WHERE scheduled_ticket_id = $scheduled_ticket_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM recurring_tickets WHERE recurring_ticket_id = $recurring_ticket_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
$client_id = intval($row['scheduled_ticket_client_id']); $client_id = intval($row['recurring_ticket_client_id']);
$scheduled_ticket_subject = nullable_htmlentities($row['scheduled_ticket_subject']); $recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']);
$scheduled_ticket_details = nullable_htmlentities($row['scheduled_ticket_details']); $recurring_ticket_details = nullable_htmlentities($row['recurring_ticket_details']);
$scheduled_ticket_priority = nullable_htmlentities($row['scheduled_ticket_priority']); $recurring_ticket_priority = nullable_htmlentities($row['recurring_ticket_priority']);
$scheduled_ticket_frequency = nullable_htmlentities($row['scheduled_ticket_frequency']); $recurring_ticket_frequency = nullable_htmlentities($row['recurring_ticket_frequency']);
$scheduled_ticket_next_run = nullable_htmlentities($row['scheduled_ticket_next_run']); $recurring_ticket_next_run = nullable_htmlentities($row['recurring_ticket_next_run']);
$scheduled_ticket_assigned_to = intval($row['scheduled_ticket_assigned_to']); $recurring_ticket_assigned_to = intval($row['recurring_ticket_assigned_to']);
$scheduled_ticket_contact_id = intval($row['scheduled_ticket_contact_id']); $recurring_ticket_contact_id = intval($row['recurring_ticket_contact_id']);
$scheduled_ticket_asset_id = intval($row['scheduled_ticket_asset_id']); $recurring_ticket_asset_id = intval($row['recurring_ticket_asset_id']);
$scheduled_ticket_billable = intval($row['scheduled_ticket_billable']); $recurring_ticket_billable = intval($row['recurring_ticket_billable']);
// Additional Assets Selected
$additional_assets_array = array();
$sql_additional_assets = mysqli_query($mysqli, "SELECT asset_id FROM recurring_ticket_assets WHERE recurring_ticket_id = $recurring_ticket_id");
while ($row = mysqli_fetch_array($sql_additional_assets)) {
$additional_asset_id = intval($row['asset_id']);
$additional_assets_array[] = $additional_asset_id;
}
// Generate the HTML form content using output buffering. // Generate the HTML form content using output buffering.
ob_start(); ob_start();
?> ?>
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title"><i class="fas fa-fw fa-calendar-check mr-2"></i>Editing Recurring Ticket: <strong><?php echo $scheduled_ticket_subject; ?></strong></h5> <h5 class="modal-title"><i class="fas fa-fw fa-calendar-check mr-2"></i>Editing Recurring Ticket: <strong><?php echo $recurring_ticket_subject; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span> <span>&times;</span>
</button> </button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="scheduled_ticket_id" value="<?php echo $scheduled_ticket_id; ?>"> <input type="hidden" name="recurring_ticket_id" value="<?php echo $recurring_ticket_id; ?>">
<input type="hidden" name="client" value="<?php echo $client_id; ?>"> <input type="hidden" name="client" value="<?php echo $client_id; ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">
<ul class="nav nav-pills nav-justified mb-3"> <ul class="nav nav-pills nav-justified mb-3">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#pills-edit-details<?php echo $scheduled_ticket_id; ?>"><i class="fa fa-fw fa-life-ring mr-2"></i>Details</a> <a class="nav-link active" data-toggle="pill" href="#pills-edit-details<?php echo $recurring_ticket_id; ?>"><i class="fa fa-fw fa-life-ring mr-2"></i>Details</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-edit-contacts<?php echo $scheduled_ticket_id; ?>"><i class="fa fa-fw fa-users mr-2"></i>Contacts</a> <a class="nav-link" data-toggle="pill" href="#pills-edit-contacts<?php echo $recurring_ticket_id; ?>"><i class="fa fa-fw fa-users mr-2"></i>Contacts</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-edit-schedule<?php echo $scheduled_ticket_id; ?>"><i class="fa fa-fw fa-building mr-2"></i>Schedule</a> <a class="nav-link" data-toggle="pill" href="#pills-edit-schedule<?php echo $recurring_ticket_id; ?>"><i class="fa fa-fw fa-building mr-2"></i>Schedule</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#pills-edit-assets<?php echo $scheduled_ticket_id; ?>"><i class="fa fa-fw fa-desktop mr-2"></i>Assets</a> <a class="nav-link" data-toggle="pill" href="#pills-edit-assets<?php echo $recurring_ticket_id; ?>"><i class="fa fa-fw fa-desktop mr-2"></i>Assets</a>
</li> </li>
</ul> </ul>
<div class="tab-content" <?php if (lookupUserPermission('module_support') <= 1) { echo 'inert'; } ?>> <div class="tab-content" <?php if (lookupUserPermission('module_support') <= 1) { echo 'inert'; } ?>>
<div class="tab-pane fade show active" id="pills-edit-details<?php echo $scheduled_ticket_id; ?>"> <div class="tab-pane fade show active" id="pills-edit-details<?php echo $recurring_ticket_id; ?>">
<div class="form-group"> <div class="form-group">
<label>Subject <strong class="text-danger">*</strong></label> <label>Subject <strong class="text-danger">*</strong></label>
@ -59,12 +67,12 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
</div> </div>
<input type="text" class="form-control" name="subject" placeholder="Subject" maxlength="500" value="<?php echo $scheduled_ticket_subject; ?>" required > <input type="text" class="form-control" name="subject" placeholder="Subject" maxlength="500" value="<?php echo $recurring_ticket_subject; ?>" required >
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<textarea class="form-control tinymce" name="details"><?php echo $scheduled_ticket_details; ?></textarea> <textarea class="form-control tinymce" name="details"><?php echo $recurring_ticket_details; ?></textarea>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -74,9 +82,9 @@ ob_start();
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
</div> </div>
<select class="form-control select2" name="priority" required> <select class="form-control select2" name="priority" required>
<option <?php if ($scheduled_ticket_priority == "Low") { echo "selected"; } ?> >Low</option> <option <?php if ($recurring_ticket_priority == "Low") { echo "selected"; } ?> >Low</option>
<option <?php if ($scheduled_ticket_priority == "Medium") { echo "selected"; } ?> >Medium</option> <option <?php if ($recurring_ticket_priority == "Medium") { echo "selected"; } ?> >Medium</option>
<option <?php if ($scheduled_ticket_priority == "High") { echo "selected"; } ?> >High</option> <option <?php if ($recurring_ticket_priority == "High") { echo "selected"; } ?> >High</option>
</select> </select>
</div> </div>
</div> </div>
@ -100,7 +108,7 @@ ob_start();
$user_name_select = nullable_htmlentities($row['user_name']); $user_name_select = nullable_htmlentities($row['user_name']);
?> ?>
<option value="<?php echo $user_id_select; ?>" <?php if ($scheduled_ticket_assigned_to == $user_id_select) { echo "selected"; } ?>><?php echo $user_name_select; ?></option> <option value="<?php echo $user_id_select; ?>" <?php if ($recurring_ticket_assigned_to == $user_id_select) { echo "selected"; } ?>><?php echo $user_name_select; ?></option>
<?php } ?> <?php } ?>
</select> </select>
</div> </div>
@ -109,7 +117,7 @@ ob_start();
<div class="form-group <?php if (!$config_module_enable_accounting) { echo 'd-none'; } ?>"> <div class="form-group <?php if (!$config_module_enable_accounting) { echo 'd-none'; } ?>">
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="editTicketBillable" name="billable" <input type="checkbox" class="custom-control-input" id="editTicketBillable" name="billable"
<?php if ($scheduled_ticket_billable == 1) { echo "checked"; } ?> value="1" <?php if ($recurring_ticket_billable == 1) { echo "checked"; } ?> value="1"
> >
<label class="custom-control-label" for="editTicketBillable">Mark Billable</label> <label class="custom-control-label" for="editTicketBillable">Mark Billable</label>
</div> </div>
@ -117,7 +125,7 @@ ob_start();
</div> </div>
<div class="tab-pane fade" id="pills-edit-contacts<?php echo $scheduled_ticket_id; ?>"> <div class="tab-pane fade" id="pills-edit-contacts<?php echo $recurring_ticket_id; ?>">
<div class="form-group"> <div class="form-group">
<label>Contact</label> <label>Contact</label>
@ -152,7 +160,7 @@ ob_start();
} }
?> ?>
<option value="<?php echo $contact_id_select; ?>" <?php if ($contact_id_select == $scheduled_ticket_contact_id) { echo "selected"; } ?>><?php echo "$contact_name_select$contact_title_display_select$contact_primary_display_select$contact_technical_display_select"; ?></option> <option value="<?php echo $contact_id_select; ?>" <?php if ($contact_id_select == $recurring_ticket_contact_id) { echo "selected"; } ?>><?php echo "$contact_name_select$contact_title_display_select$contact_primary_display_select$contact_technical_display_select"; ?></option>
<?php } ?> <?php } ?>
</select> </select>
</div> </div>
@ -160,7 +168,7 @@ ob_start();
</div> </div>
<div class="tab-pane fade" id="pills-edit-schedule<?php echo $scheduled_ticket_id; ?>"> <div class="tab-pane fade" id="pills-edit-schedule<?php echo $recurring_ticket_id; ?>">
<div class="form-group"> <div class="form-group">
<label>Frequency <strong class="text-danger">*</strong></label> <label>Frequency <strong class="text-danger">*</strong></label>
@ -169,11 +177,11 @@ ob_start();
<span class="input-group-text"><i class="fa fa-fw fa-recycle"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-recycle"></i></span>
</div> </div>
<select class="form-control select2" name="frequency"> <select class="form-control select2" name="frequency">
<option <?php if ($scheduled_ticket_frequency == "Weekly") { echo "selected"; } ?>>Weekly</option> <option <?php if ($recurring_ticket_frequency == "Weekly") { echo "selected"; } ?>>Weekly</option>
<option <?php if ($scheduled_ticket_frequency == "Monthly") { echo "selected"; } ?>>Monthly</option> <option <?php if ($recurring_ticket_frequency == "Monthly") { echo "selected"; } ?>>Monthly</option>
<option <?php if ($scheduled_ticket_frequency == "Quarterly") { echo "selected"; } ?>>Quarterly</option> <option <?php if ($recurring_ticket_frequency == "Quarterly") { echo "selected"; } ?>>Quarterly</option>
<option <?php if ($scheduled_ticket_frequency == "Biannually") { echo "selected"; } ?>>Biannually</option> <option <?php if ($recurring_ticket_frequency == "Biannually") { echo "selected"; } ?>>Biannually</option>
<option <?php if ($scheduled_ticket_frequency == "Annually") { echo "selected"; } ?>>Annually</option> <option <?php if ($recurring_ticket_frequency == "Annually") { echo "selected"; } ?>>Annually</option>
</select> </select>
</div> </div>
</div> </div>
@ -184,13 +192,13 @@ ob_start();
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-calendar-day"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-calendar-day"></i></span>
</div> </div>
<input class="form-control" type="date" name="next_date" max="2999-12-31" value="<?php echo $scheduled_ticket_next_run; ?>"> <input class="form-control" type="date" name="next_date" max="2999-12-31" value="<?php echo $recurring_ticket_next_run; ?>">
</div> </div>
</div> </div>
</div> </div>
<div class="tab-pane fade" id="pills-edit-assets<?php echo $scheduled_ticket_id; ?>"> <div class="tab-pane fade" id="pills-edit-assets<?php echo $recurring_ticket_id; ?>">
<div class="form-group"> <div class="form-group">
<label>Asset</label> <label>Asset</label>
@ -208,7 +216,7 @@ ob_start();
$asset_name_select = nullable_htmlentities($row['asset_name']); $asset_name_select = nullable_htmlentities($row['asset_name']);
$asset_contact_name_select = nullable_htmlentities($row['contact_name']); $asset_contact_name_select = nullable_htmlentities($row['contact_name']);
?> ?>
<option <?php if ($scheduled_ticket_asset_id == $asset_id_select) { echo "selected"; } ?> value="<?php echo $asset_id_select; ?>"><?php echo "$asset_name_select - $asset_contact_name_select"; ?></option> <option <?php if ($recurring_ticket_asset_id == $asset_id_select) { echo "selected"; } ?> value="<?php echo $asset_id_select; ?>"><?php echo "$asset_name_select - $asset_contact_name_select"; ?></option>
<?php <?php
} }
@ -217,6 +225,31 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group">
<label>Additional Assets</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span>
</div>
<select class="form-control select2" name="additional_assets[]" data-tags="true" data-placeholder="- Select Additional Assets -" multiple>
<option value=""></option>
<?php
$sql_assets = mysqli_query($mysqli, "SELECT asset_id, asset_name, contact_name FROM assets LEFT JOIN contacts ON contact_id = asset_contact_id WHERE asset_client_id = $client_id AND asset_id != $recurring_ticket_asset_id AND asset_archived_at IS NULL ORDER BY asset_name ASC");
while ($row = mysqli_fetch_array($sql_assets)) {
$asset_id_select = intval($row['asset_id']);
$asset_name_select = nullable_htmlentities($row['asset_name']);
$asset_contact_name_select = nullable_htmlentities($row['contact_name']);
?>
<option value="<?php echo $asset_id_select; ?>"
<?php if (in_array($asset_id_select, $additional_assets_array)) { echo "selected"; } ?>
><?php echo "$asset_name_select - $asset_contact_name_select"; ?></option>
<?php } ?>
</select>
</div>
</div>
</div> </div>
</div> </div>

View File

@ -4,18 +4,18 @@ require_once '../includes/ajax_header.php';
$role_id = intval($_GET['id']); $role_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE user_role_id = $role_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_id = $role_id LIMIT 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
$role_name = nullable_htmlentities($row['user_role_name']); $role_name = nullable_htmlentities($row['role_name']);
$role_description = nullable_htmlentities($row['user_role_description']); $role_description = nullable_htmlentities($row['role_description']);
$role_admin = intval($row['user_role_is_admin']); $role_admin = intval($row['role_is_admin']);
// Count number of users that have each role // Count number of users that have each role
$sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(users.user_id) FROM users LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role = $role_id AND user_archived_at IS NULL"); $sql_role_user_count = mysqli_query($mysqli, "SELECT COUNT(user_id) FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
$role_user_count = mysqli_fetch_row($sql_role_user_count)[0]; $role_user_count = mysqli_fetch_row($sql_role_user_count)[0];
$sql_users = mysqli_query($mysqli, "SELECT * FROM users LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role = $role_id AND user_archived_at IS NULL"); $sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE user_role_id = $role_id AND user_archived_at IS NULL");
// Initialize an empty array to hold user names // Initialize an empty array to hold user names
$user_names = []; $user_names = [];

View File

@ -28,23 +28,23 @@ if ($service_importance == "High") {
$service_importance_display = "-"; $service_importance_display = "-";
} }
// Associated Assets (and their logins/networks/locations) // Associated Assets (and their credentials/networks/locations)
$sql_assets = mysqli_query( $sql_assets = mysqli_query(
$mysqli, $mysqli,
"SELECT * FROM service_assets "SELECT * FROM service_assets
LEFT JOIN assets ON service_assets.asset_id = assets.asset_id LEFT JOIN assets ON service_assets.asset_id = assets.asset_id
LEFT JOIN asset_interfaces ON interface_asset_id = assets.asset_id AND interface_primary = 1 LEFT JOIN asset_interfaces ON interface_asset_id = assets.asset_id AND interface_primary = 1
LEFT JOIN logins ON service_assets.asset_id = logins.login_asset_id LEFT JOIN credentials ON service_assets.asset_id = credentials.credential_asset_id
LEFT JOIN networks ON interface_network_id = networks.network_id LEFT JOIN networks ON interface_network_id = networks.network_id
LEFT JOIN locations ON assets.asset_location_id = locations.location_id LEFT JOIN locations ON assets.asset_location_id = locations.location_id
WHERE service_id = $service_id" WHERE service_id = $service_id"
); );
// Associated logins // Associated credentials
$sql_logins = mysqli_query( $sql_credentials = mysqli_query(
$mysqli, $mysqli,
"SELECT * FROM service_logins "SELECT * FROM service_credentials
LEFT JOIN logins ON service_logins.login_id = logins.login_id LEFT JOIN credentials ON service_credentials.credential_id = credentials.credential_id
WHERE service_id = $service_id" WHERE service_id = $service_id"
); );
@ -318,27 +318,27 @@ ob_start();
} }
?> ?>
<!-- Logins --> <!-- Credentials -->
<?php <?php
if (mysqli_num_rows($sql_assets) > 0 || mysqli_num_rows($sql_logins) > 0) { ?> if (mysqli_num_rows($sql_assets) > 0 || mysqli_num_rows($sql_credentials) > 0) { ?>
<h5><i class="fas fa-fw fa-key mr-2"></i>Logins</h5> <h5><i class="fas fa-fw fa-key mr-2"></i>Credentials</h5>
<ul> <ul>
<?php <?php
// Reset the $sql_assets/logins pointer to the start // Reset the $sql_assets/credentials pointer to the start
mysqli_data_seek($sql_assets, 0); mysqli_data_seek($sql_assets, 0);
mysqli_data_seek($sql_logins, 0); mysqli_data_seek($sql_credentials, 0);
// Showing logins linked to assets // Showing credentials linked to assets
while ($row = mysqli_fetch_array($sql_assets)) { while ($row = mysqli_fetch_array($sql_assets)) {
if (!empty($row['login_name'])) { if (!empty($row['credential_name'])) {
echo "<li><a href=\"credentials.php?client_id=$client_id&q=$row[login_name]\">$row[login_name]</a></li>"; echo "<li><a href=\"credentials.php?client_id=$client_id&q=$row[credential_name]\">$row[credential_name]</a></li>";
} }
} }
// Showing explicitly linked logins // Showing explicitly linked credentials
while ($row = mysqli_fetch_array($sql_logins)) { while ($row = mysqli_fetch_array($sql_credentials)) {
if (!empty($row['login_name'])) { if (!empty($row['credential_name'])) {
echo "<li><a href=\"credentials.php?client_id=$client_id&q=$row[login_name]\">$row[login_name]</a></li>"; echo "<li><a href=\"credentials.php?client_id=$client_id&q=$row[credential_name]\">$row[credential_name]</a></li>";
} }
} }
?> ?>
@ -349,27 +349,27 @@ ob_start();
<!-- URLs --> <!-- URLs -->
<?php <?php
if ($sql_logins || $sql_assets) { ?> if ($sql_credentials || $sql_assets) { ?>
<h5><i class="fas fa-fw fa-link mr-2"></i>URLs</h5> <h5><i class="fas fa-fw fa-link mr-2"></i>URLs</h5>
<ul> <ul>
<?php <?php
// Reset the $sql_logins pointer to the start // Reset the $sql_credentials pointer to the start
mysqli_data_seek($sql_logins, 0); mysqli_data_seek($sql_credentials, 0);
// Showing URLs linked to logins // Showing URLs linked to credentials
while ($row = mysqli_fetch_array($sql_logins)) { while ($row = mysqli_fetch_array($sql_credentials)) {
if (!empty($row['login_uri'])) { if (!empty($row['credential_uri'])) {
echo "<li><a href=\"https://$row[login_uri]\">$row[login_uri]</a></li>"; echo "<li><a href=\"https://$row[credential_uri]\">$row[credential_uri]</a></li>";
} }
} }
// Reset the $sql_assets pointer to the start // Reset the $sql_assets pointer to the start
mysqli_data_seek($sql_assets, 0); mysqli_data_seek($sql_assets, 0);
// Show URLs linked to assets, that also have logins // Show URLs linked to assets, that also have credentials
while ($row = mysqli_fetch_array($sql_assets)) { while ($row = mysqli_fetch_array($sql_assets)) {
if (!empty($row['login_uri'])) { if (!empty($row['credential_uri'])) {
echo "<li><a href=\"https://$row[login_uri]\">$row[login_uri]</a></li>"; echo "<li><a href=\"https://$row[credential_uri]\">$row[credential_uri]</a></li>";
} }
} }
?> ?>

View File

@ -18,23 +18,23 @@ $service_updated_at = nullable_htmlentities($row['service_updated_at']);
$service_review_due = nullable_htmlentities($row['service_review_due']); $service_review_due = nullable_htmlentities($row['service_review_due']);
$client_id = intval($row['service_client_id']); $client_id = intval($row['service_client_id']);
// Associated Assets (and their logins/networks/locations) // Associated Assets (and their credentials/networks/locations)
$sql_assets = mysqli_query( $sql_assets = mysqli_query(
$mysqli, $mysqli,
"SELECT * FROM service_assets "SELECT * FROM service_assets
LEFT JOIN assets ON service_assets.asset_id = assets.asset_id LEFT JOIN assets ON service_assets.asset_id = assets.asset_id
LEFT JOIN asset_interfaces ON interface_asset_id = assets.asset_id AND interface_primary = 1 LEFT JOIN asset_interfaces ON interface_asset_id = assets.asset_id AND interface_primary = 1
LEFT JOIN logins ON service_assets.asset_id = logins.login_asset_id LEFT JOIN credentials ON service_assets.asset_id = credentials.credential_asset_id
LEFT JOIN networks ON interface_network_id = networks.network_id LEFT JOIN networks ON interface_network_id = networks.network_id
LEFT JOIN locations ON assets.asset_location_id = locations.location_id LEFT JOIN locations ON assets.asset_location_id = locations.location_id
WHERE service_id = $service_id" WHERE service_id = $service_id"
); );
// Associated logins // Associated credentials
$sql_logins = mysqli_query( $sql_credentials = mysqli_query(
$mysqli, $mysqli,
"SELECT * FROM service_logins "SELECT * FROM service_credentials
LEFT JOIN logins ON service_logins.login_id = logins.login_id LEFT JOIN credentials ON service_credentials.credential_id = credentials.credential_id
WHERE service_id = $service_id" WHERE service_id = $service_id"
); );
@ -280,21 +280,21 @@ ob_start();
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="logins">Logins</label> <label for="credentials">Credentials</label>
<select multiple class="form-control select2" name="logins[]"> <select multiple class="form-control select2" name="credentials[]">
<?php <?php
$selected_ids = array_column(mysqli_fetch_all($sql_logins, MYSQLI_ASSOC), "login_id"); $selected_ids = array_column(mysqli_fetch_all($sql_credentials, MYSQLI_ASSOC), "credential_id");
$sql_all = mysqli_query($mysqli, "SELECT * FROM logins WHERE (login_archived_at > '$service_created_at' OR login_archived_at IS NULL) AND login_client_id = $client_id"); $sql_all = mysqli_query($mysqli, "SELECT * FROM credentials WHERE (credential_archived_at > '$service_created_at' OR credential_archived_at IS NULL) AND credential_client_id = $client_id");
while ($row_all = mysqli_fetch_array($sql_all)) { while ($row_all = mysqli_fetch_array($sql_all)) {
$login_id = intval($row_all['login_id']); $credential_id = intval($row_all['credential_id']);
$login_name = nullable_htmlentities($row_all['login_name']); $credential_name = nullable_htmlentities($row_all['credential_name']);
if (in_array($login_id, $selected_ids)) { if (in_array($credential_id, $selected_ids)) {
echo "<option value=\"$login_id\" selected>$login_name</option>"; echo "<option value=\"$credential_id\" selected>$credential_name</option>";
} }
else{ else{
echo "<option value=\"$login_id\">$login_name</option>"; echo "<option value=\"$credential_id\">$credential_name</option>";
} }
} }
?> ?>

View File

@ -24,6 +24,14 @@ $location_id = intval($row['ticket_location_id']);
$vendor_id = intval($row['ticket_vendor_id']); $vendor_id = intval($row['ticket_vendor_id']);
$project_id = intval($row['ticket_project_id']); $project_id = intval($row['ticket_project_id']);
// Additional Assets Selected
$additional_assets_array = array();
$sql_additional_assets = mysqli_query($mysqli, "SELECT asset_id FROM ticket_assets WHERE ticket_id = $ticket_id");
while ($row = mysqli_fetch_array($sql_additional_assets)) {
$additional_asset_id = intval($row['asset_id']);
$additional_assets_array[] = $additional_asset_id;
}
// Generate the HTML form content using output buffering. // Generate the HTML form content using output buffering.
ob_start(); ob_start();
?> ?>
@ -212,6 +220,31 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group">
<label>Additional Assets</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span>
</div>
<select class="form-control select2" name="additional_assets[]" data-tags="true" data-placeholder="- Select Additional Assets -" multiple>
<option value=""></option>
<?php
$sql_assets = mysqli_query($mysqli, "SELECT asset_id, asset_name, contact_name FROM assets LEFT JOIN contacts ON contact_id = asset_contact_id WHERE asset_client_id = $client_id AND asset_id != $asset_id AND asset_archived_at IS NULL ORDER BY asset_name ASC");
while ($row = mysqli_fetch_array($sql_assets)) {
$asset_id_select = intval($row['asset_id']);
$asset_name_select = nullable_htmlentities($row['asset_name']);
$asset_contact_name_select = nullable_htmlentities($row['contact_name']);
?>
<option value="<?php echo $asset_id_select; ?>"
<?php if (in_array($asset_id_select, $additional_assets_array)) { echo "selected"; } ?>
><?php echo "$asset_name_select - $asset_contact_name_select"; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label>Location</label> <label>Location</label>
<div class="input-group"> <div class="input-group">

View File

@ -4,7 +4,10 @@ require_once '../includes/ajax_header.php';
$user_id = intval($_GET['id']); $user_id = intval($_GET['id']);
$sql = mysqli_query($mysqli, "SELECT * FROM users, user_settings WHERE users.user_id = user_settings.user_id AND users.user_id = $user_id LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM users
LEFT JOIN user_settings ON users.user_id = user_settings.user_id
WHERE users.user_id = $user_id LIMIT 1"
);
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
$user_name = nullable_htmlentities($row['user_name']); $user_name = nullable_htmlentities($row['user_name']);
@ -12,11 +15,11 @@ $user_email = nullable_htmlentities($row['user_email']);
$user_avatar = nullable_htmlentities($row['user_avatar']); $user_avatar = nullable_htmlentities($row['user_avatar']);
$user_token = nullable_htmlentities($row['user_token']); $user_token = nullable_htmlentities($row['user_token']);
$user_config_force_mfa = intval($row['user_config_force_mfa']); $user_config_force_mfa = intval($row['user_config_force_mfa']);
$user_role = intval($row['user_role']); $user_role_id = intval($row['user_role_id']);
$user_initials = nullable_htmlentities(initials($user_name)); $user_initials = nullable_htmlentities(initials($user_name));
// Get User Client Access Permissions // Get User Client Access Permissions
$user_client_access_sql = mysqli_query($mysqli,"SELECT client_id FROM user_permissions WHERE user_id = $user_id"); $user_client_access_sql = mysqli_query($mysqli,"SELECT client_id FROM user_client_permissions WHERE user_id = $user_id");
$client_access_array = []; $client_access_array = [];
while ($row = mysqli_fetch_assoc($user_client_access_sql)) { while ($row = mysqli_fetch_assoc($user_client_access_sql)) {
$client_access_array[] = intval($row['client_id']); $client_access_array[] = intval($row['client_id']);
@ -107,13 +110,13 @@ ob_start();
</div> </div>
<select class="form-control select2" name="role" required> <select class="form-control select2" name="role" required>
<?php <?php
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE user_role_archived_at IS NULL"); $sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL");
while ($row = mysqli_fetch_array($sql_user_roles)) { while ($row = mysqli_fetch_array($sql_user_roles)) {
$user_role_id = intval($row['user_role_id']); $role_id = intval($row['role_id']);
$user_role_name = nullable_htmlentities($row['user_role_name']); $role_name = nullable_htmlentities($row['role_name']);
?> ?>
<option <?php if ($user_role == $user_role_id) {echo "selected";} ?> value="<?php echo $user_role_id; ?>"><?php echo $user_role_name; ?></option> <option <?php if ($role_id == $user_role_id) {echo "selected";} ?> value="<?php echo $role_id; ?>"><?php echo $role_name; ?></option>
<?php } ?> <?php } ?>
</select> </select>

View File

@ -13,7 +13,7 @@ $insert_id = false;
if (!empty($api_key_decrypt_password) && !empty($name) && !(empty($password))) { if (!empty($api_key_decrypt_password) && !empty($name) && !(empty($password))) {
// Add credential // Add credential
$insert_sql = mysqli_query($mysqli,"INSERT INTO logins SET login_name = '$name', login_description = '$description', login_uri = '$uri', login_uri_2 = '$uri_2', login_username = '$username', login_password = '$password', login_otp_secret = '$otp_secret', login_note = '$note', login_important = $important, login_contact_id = $contact_id, login_vendor_id = $vendor_id, login_asset_id = $asset_id, login_software_id = $software_id, login_client_id = $client_id"); $insert_sql = mysqli_query($mysqli,"INSERT INTO credentials SET credential_name = '$name', credential_description = '$description', credential_uri = '$uri', credential_uri_2 = '$uri_2', credential_username = '$username', credential_password = '$password', credential_otp_secret = '$otp_secret', credential_note = '$note', credential_important = $important, credential_contact_id = $contact_id, credential_vendor_id = $vendor_id, credential_asset_id = $asset_id, credential_software_id = $software_id, credential_client_id = $client_id");
// Check insert & get insert ID // Check insert & get insert ID
if ($insert_sql) { if ($insert_sql) {

View File

@ -8,53 +8,53 @@ if (isset($_POST['api_key_decrypt_password'])) {
$api_key_decrypt_password = $_POST['api_key_decrypt_password']; // No sanitization $api_key_decrypt_password = $_POST['api_key_decrypt_password']; // No sanitization
} }
if (isset($_POST['login_name'])) { if (isset($_POST['credential_name'])) {
$name = sanitizeInput($_POST['login_name']); $name = sanitizeInput($_POST['credential_name']);
} elseif (isset($credential_row) && isset($credential_row['login_name'])) { } elseif (isset($credential_row) && isset($credential_row['credential_name'])) {
$name = $credential_row['login_name']; $name = $credential_row['credential_name'];
} else { } else {
$name = ''; $name = '';
} }
if (isset($_POST['login_description'])) { if (isset($_POST['credential_description'])) {
$description = sanitizeInput($_POST['login_description']); $description = sanitizeInput($_POST['credential_description']);
} elseif (isset($credential_row) && isset($credential_row['login_description'])) { } elseif (isset($credential_row) && isset($credential_row['credential_description'])) {
$description = $credential_row['login_description']; $description = $credential_row['credential_description'];
} else { } else {
$description = ''; $description = '';
} }
if (isset($_POST['login_uri'])) { if (isset($_POST['credential_uri'])) {
$uri = sanitizeInput($_POST['login_uri']); $uri = sanitizeInput($_POST['credential_uri']);
} elseif (isset($credential_row) && isset($credential_row['login_uri'])) { } elseif (isset($credential_row) && isset($credential_row['credential_uri'])) {
$uri = $credential_row['login_uri']; $uri = $credential_row['credential_uri'];
} else { } else {
$uri = ''; $uri = '';
} }
if (isset($_POST['login_uri_2'])) { if (isset($_POST['credential_uri_2'])) {
$uri_2 = sanitizeInput($_POST['login_uri_2']); $uri_2 = sanitizeInput($_POST['credential_uri_2']);
} elseif (isset($credential_row) && isset($credential_row['login_uri_2'])) { } elseif (isset($credential_row) && isset($credential_row['credential_uri_2'])) {
$uri_2 = $credential_row['login_uri_2']; $uri_2 = $credential_row['credential_uri_2'];
} else { } else {
$uri_2 = ''; $uri_2 = '';
} }
if (isset($_POST['login_username'])) { if (isset($_POST['credential_username'])) {
$username = $_POST['login_username']; $username = $_POST['credential_username'];
$username = apiEncryptLoginEntry($username, $api_key_decrypt_hash, $api_key_decrypt_password); $username = apiEncryptLoginEntry($username, $api_key_decrypt_hash, $api_key_decrypt_password);
} elseif (isset($credential_row) && isset($credential_row['login_username'])) { } elseif (isset($credential_row) && isset($credential_row['credential_username'])) {
$username = $credential_row['login_username']; $username = $credential_row['credential_username'];
} else { } else {
$username = ''; $username = '';
} }
if (isset($_POST['login_password'])) { if (isset($_POST['credential_password'])) {
$password = $_POST['login_password']; $password = $_POST['credential_password'];
$password = apiEncryptLoginEntry($password, $api_key_decrypt_hash, $api_key_decrypt_password); $password = apiEncryptLoginEntry($password, $api_key_decrypt_hash, $api_key_decrypt_password);
$password_changed = true; $password_changed = true;
} elseif (isset($credential_row) && isset($credential_row['login_password'])) { } elseif (isset($credential_row) && isset($credential_row['credential_password'])) {
$password = $credential_row['login_password']; $password = $credential_row['credential_password'];
$password_changed = false; $password_changed = false;
} else { } else {
$password = ''; $password = '';
@ -63,58 +63,58 @@ if (isset($_POST['login_password'])) {
if (isset($_POST['login_otp_secret'])) { if (isset($_POST['credential_otp_secret'])) {
$otp_secret = sanitizeInput($_POST['login_otp_secret']); $otp_secret = sanitizeInput($_POST['credential_otp_secret']);
} elseif (isset($credential_row) && isset($credential_row['login_otp_secret'])) { } elseif (isset($credential_row) && isset($credential_row['credential_otp_secret'])) {
$otp_secret = $credential_row['login_otp_secret']; $otp_secret = $credential_row['credential_otp_secret'];
} else { } else {
$otp_secret = ''; $otp_secret = '';
} }
if (isset($_POST['login_note'])) { if (isset($_POST['credential_note'])) {
$note = sanitizeInput($_POST['login_note']); $note = sanitizeInput($_POST['credential_note']);
} elseif (isset($credential_row) && isset($credential_row['login_note'])) { } elseif (isset($credential_row) && isset($credential_row['credential_note'])) {
$note = $credential_row['login_note']; $note = $credential_row['credential_note'];
} else { } else {
$note = ''; $note = '';
} }
if (isset($_POST['login_important'])) { if (isset($_POST['credential_important'])) {
$important = intval($_POST['login_important']); $important = intval($_POST['credential_important']);
} elseif (isset($credential_row) && isset($credential_row['login_important'])) { } elseif (isset($credential_row) && isset($credential_row['credential_important'])) {
$important = $credential_row['login_important']; $important = $credential_row['credential_important'];
} else { } else {
$important = ''; $important = '';
} }
if (isset($_POST['login_contact_id'])) { if (isset($_POST['credential_contact_id'])) {
$contact_id = intval($_POST['login_contact_id']); $contact_id = intval($_POST['credential_contact_id']);
} elseif (isset($credential_row) && isset($credential_row['login_contact_id'])) { } elseif (isset($credential_row) && isset($credential_row['credential_contact_id'])) {
$contact_id = $credential_row['login_contact_id']; $contact_id = $credential_row['credential_contact_id'];
} else { } else {
$contact_id = ''; $contact_id = '';
} }
if (isset($_POST['login_vendor_id'])) { if (isset($_POST['credential_vendor_id'])) {
$vendor_id = intval($_POST['login_vendor_id']); $vendor_id = intval($_POST['credential_vendor_id']);
} elseif (isset($credential_row) && isset($credential_row['login_vendor_id'])) { } elseif (isset($credential_row) && isset($credential_row['credential_vendor_id'])) {
$vendor_id = $credential_row['login_vendor_id']; $vendor_id = $credential_row['credential_vendor_id'];
} else { } else {
$vendor_id = ''; $vendor_id = '';
} }
if (isset($_POST['login_asset_id'])) { if (isset($_POST['credential_asset_id'])) {
$asset_id = intval($_POST['login_asset_id']); $asset_id = intval($_POST['credential_asset_id']);
} elseif (isset($credential_row) && isset($credential_row['login_asset_id'])) { } elseif (isset($credential_row) && isset($credential_row['credential_asset_id'])) {
$asset_id = $credential_row['login_asset_id']; $asset_id = $credential_row['credential_asset_id'];
} else { } else {
$asset_id = ''; $asset_id = '';
} }
if (isset($_POST['login_software_id'])) { if (isset($_POST['credential_software_id'])) {
$software_id = intval($_POST['login_software_id']); $software_id = intval($_POST['credential_software_id']);
} elseif (isset($credential_row) && isset($credential_row['login_software_id'])) { } elseif (isset($credential_row) && isset($credential_row['credential_software_id'])) {
$software_id = $credential_row['login_software_id']; $software_id = $credential_row['credential_software_id'];
} else { } else {
$software_id = ''; $software_id = '';
} }

View File

@ -13,17 +13,17 @@ if (isset($_GET['api_key_decrypt_password'])) {
} }
// Specific credential/login via ID (single) // Specific credential/login via ID (single)
if (isset($_GET['login_id']) && !empty($api_key_decrypt_password)) { if (isset($_GET['credential_id']) && !empty($api_key_decrypt_password)) {
$id = intval($_GET['login_id']); $id = intval($_GET['credential_id']);
$sql = mysqli_query($mysqli, "SELECT * FROM logins WHERE login_id = '$id' AND login_client_id LIKE '$client_id' LIMIT 1"); $sql = mysqli_query($mysqli, "SELECT * FROM credentials WHERE credential_id = '$id' AND credential_client_id LIKE '$client_id' LIMIT 1");
} elseif (!empty($api_key_decrypt_password)) { } elseif (!empty($api_key_decrypt_password)) {
// All credentials ("logins") // All credentials ("credentials")
$sql = mysqli_query($mysqli, "SELECT * FROM logins WHERE login_client_id LIKE '$client_id' ORDER BY login_id LIMIT $limit OFFSET $offset"); $sql = mysqli_query($mysqli, "SELECT * FROM credentials WHERE credential_client_id LIKE '$client_id' ORDER BY credential_id LIMIT $limit OFFSET $offset");
} }
@ -37,8 +37,8 @@ if ($sql && mysqli_num_rows($sql) > 0) {
$row = array(); $row = array();
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$row['login_username'] = apiDecryptLoginEntry($row['login_username'], $api_key_decrypt_hash, $api_key_decrypt_password); $row['credential_username'] = apiDecryptCredentialEntry($row['credential_username'], $api_key_decrypt_hash, $api_key_decrypt_password);
$row['login_password'] = apiDecryptLoginEntry($row['login_password'], $api_key_decrypt_hash, $api_key_decrypt_password); $row['credential_password'] = apiDecryptCredentialEntry($row['credential_password'], $api_key_decrypt_hash, $api_key_decrypt_password);
$return_arr['data'][] = $row; $return_arr['data'][] = $row;
} }

View File

@ -5,30 +5,30 @@ require_once '../validate_api_key.php';
require_once '../require_post_method.php'; require_once '../require_post_method.php';
// Parse ID // Parse ID
$login_id = intval($_POST['login_id']); $credential_id = intval($_POST['credential_id']);
// Default // Default
$update_count = false; $update_count = false;
if (!empty($_POST['api_key_decrypt_password']) && !empty($login_id)) { if (!empty($_POST['api_key_decrypt_password']) && !empty($credential_id)) {
$credential_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM logins WHERE login_id = '$login_id' AND login_client_id = $client_id LIMIT 1")); $credential_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM credentials WHERE credential_id = '$credential_id' AND credential_client_id = $client_id LIMIT 1"));
// Variable assignment from POST - assigning the current database value if a value is not provided // Variable assignment from POST - assigning the current database value if a value is not provided
require_once 'credential_model.php'; require_once 'credential_model.php';
$update_sql = mysqli_query($mysqli,"UPDATE logins SET login_name = '$name', login_description = '$description', login_uri = '$uri', login_uri_2 = '$uri_2', login_username = '$username', login_password = '$password', login_otp_secret = '$otp_secret', login_note = '$note', login_important = $important, login_contact_id = $contact_id, login_vendor_id = $vendor_id, login_asset_id = $asset_id, login_software_id = $software_id, login_client_id = $client_id WHERE login_id = '$login_id' AND login_client_id = $client_id LIMIT 1"); $update_sql = mysqli_query($mysqli,"UPDATE credentials SET credential_name = '$name', credential_description = '$description', credential_uri = '$uri', credential_uri_2 = '$uri_2', credential_username = '$username', credential_password = '$password', credential_otp_secret = '$otp_secret', credential_note = '$note', credential_important = $important, credential_contact_id = $contact_id, credential_vendor_id = $vendor_id, credential_asset_id = $asset_id, credential_software_id = $software_id, credential_client_id = $client_id WHERE credential_id = '$credential_id' AND credential_client_id = $client_id LIMIT 1");
// Check insert & get insert ID // Check insert & get insert ID
if ($update_sql) { if ($update_sql) {
$update_count = mysqli_affected_rows($mysqli); $update_count = mysqli_affected_rows($mysqli);
if ($password_changed) { if ($password_changed) {
mysqli_query($mysqli, "UPDATE logins SET login_password_changed_at = NOW() WHERE login_id = $login_id LIMIT 1"); mysqli_query($mysqli, "UPDATE credentials SET credential_password_changed_at = NOW() WHERE credential_id = $credential_id LIMIT 1");
} }
// Logging // Logging
logAction("Credential", "Edit", "$name via API ($api_key_name)", $client_id, $login_id); logAction("Credential", "Edit", "$name via API ($api_key_name)", $client_id, $credential_id);
logAction("API", "Success", "Updated credential $name via API ($api_key_name)", $client_id); logAction("API", "Success", "Updated credential $name via API ($api_key_name)", $client_id);
} }

View File

@ -81,19 +81,24 @@ if (isset($_GET['asset_id'])) {
// Override Tab Title // No Sanitizing needed as this var will opnly be used in the tab title // Override Tab Title // No Sanitizing needed as this var will opnly be used in the tab title
$page_title = $row['asset_name']; $page_title = $row['asset_name'];
// Related Tickets Query $sql_related_tickets = mysqli_query($mysqli, "
$sql_related_tickets = mysqli_query($mysqli, "SELECT * FROM tickets SELECT tickets.*, users.*, ticket_statuses.*
LEFT JOIN users on ticket_assigned_to = user_id FROM tickets
LEFT JOIN users ON ticket_assigned_to = user_id
LEFT JOIN ticket_statuses ON ticket_status_id = ticket_status LEFT JOIN ticket_statuses ON ticket_status_id = ticket_status
WHERE ticket_asset_id = $asset_id LEFT JOIN ticket_assets ON tickets.ticket_id = ticket_assets.ticket_id
ORDER BY ticket_number DESC" WHERE ticket_asset_id = $asset_id OR ticket_assets.asset_id = $asset_id
); GROUP BY tickets.ticket_id
ORDER BY ticket_number DESC
");
$ticket_count = mysqli_num_rows($sql_related_tickets); $ticket_count = mysqli_num_rows($sql_related_tickets);
// Related Recurring Tickets Query // Related Recurring Tickets Query
$sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM scheduled_tickets $sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM recurring_tickets
WHERE scheduled_ticket_asset_id = $asset_id LEFT JOIN recurring_ticket_assets ON recurring_tickets.recurring_ticket_id = recurring_ticket_assets.recurring_ticket_id
ORDER BY scheduled_ticket_next_run DESC" WHERE recurring_ticket_asset_id = $asset_id OR recurring_ticket_assets.asset_id = $asset_id
GROUP BY recurring_tickets.recurring_ticket_id
ORDER BY recurring_ticket_next_run DESC"
); );
$recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets); $recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets);
@ -179,29 +184,29 @@ if (isset($_GET['asset_id'])) {
$document_count = mysqli_num_rows($sql_related_documents); $document_count = mysqli_num_rows($sql_related_documents);
// Related Logins Query // Related Credentials Query
$sql_related_logins = mysqli_query($mysqli, " $sql_related_credentials = mysqli_query($mysqli, "
SELECT SELECT
logins.login_id AS login_id, credentials.credential_id AS credential_id,
logins.login_name, credentials.credential_name,
logins.login_description, credentials.credential_description,
logins.login_uri, credentials.credential_uri,
logins.login_username, credentials.credential_username,
logins.login_password, credentials.credential_password,
logins.login_otp_secret, credentials.credential_otp_secret,
logins.login_note, credentials.credential_note,
logins.login_important, credentials.credential_important,
logins.login_contact_id, credentials.credential_contact_id,
logins.login_asset_id credentials.credential_asset_id
FROM logins FROM credentials
LEFT JOIN login_tags ON login_tags.login_id = logins.login_id LEFT JOIN credential_tags ON credential_tags.credential_id = credentials.credential_id
LEFT JOIN tags ON tags.tag_id = login_tags.tag_id LEFT JOIN tags ON tags.tag_id = credential_tags.tag_id
WHERE login_asset_id = $asset_id WHERE credential_asset_id = $asset_id
AND login_archived_at IS NULL AND credential_archived_at IS NULL
GROUP BY logins.login_id GROUP BY credentials.credential_id
ORDER BY login_name DESC ORDER BY credential_name DESC
"); ");
$login_count = mysqli_num_rows($sql_related_logins); $credential_count = mysqli_num_rows($sql_related_credentials);
// Related Software Query // Related Software Query
$sql_related_software = mysqli_query( $sql_related_software = mysqli_query(
@ -518,7 +523,7 @@ if (isset($_GET['asset_id'])) {
</div> </div>
</div> </div>
<div class="card card-dark <?php if ($login_count == 0) { echo "d-none"; } ?>"> <div class="card card-dark <?php if ($credential_count == 0) { echo "d-none"; } ?>">
<div class="card-header"> <div class="card-header">
<h3 class="card-title"><i class="fa fa-fw fa-key mr-2"></i>Credentials</h3> <h3 class="card-title"><i class="fa fa-fw fa-key mr-2"></i>Credentials</h3>
</div> </div>
@ -539,56 +544,56 @@ if (isset($_GET['asset_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_logins)) { while ($row = mysqli_fetch_array($sql_related_credentials)) {
$login_id = intval($row['login_id']); $credential_id = intval($row['credential_id']);
$login_name = nullable_htmlentities($row['login_name']); $credential_name = nullable_htmlentities($row['credential_name']);
$login_description = nullable_htmlentities($row['login_description']); $credential_description = nullable_htmlentities($row['credential_description']);
$login_uri = nullable_htmlentities($row['login_uri']); $credential_uri = nullable_htmlentities($row['credential_uri']);
if (empty($login_uri)) { if (empty($credential_uri)) {
$login_uri_display = "-"; $credential_uri_display = "-";
} else { } else {
$login_uri_display = "$login_uri<button class='btn btn-sm clipboardjs' data-clipboard-text='$login_uri'><i class='far fa-copy text-secondary'></i></button><a href='$login_uri' target='_blank'><i class='fa fa-external-link-alt text-secondary'></i></a>"; $credential_uri_display = "$credential_uri<button class='btn btn-sm clipboardjs' data-clipboard-text='$credential_uri'><i class='far fa-copy text-secondary'></i></button><a href='$credential_uri' target='_blank'><i class='fa fa-external-link-alt text-secondary'></i></a>";
} }
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username'])); $credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
if (empty($login_username)) { if (empty($credential_username)) {
$login_username_display = "-"; $credential_username_display = "-";
} else { } else {
$login_username_display = "$login_username<button class='btn btn-sm clipboardjs' data-clipboard-text='$login_username'><i class='far fa-copy text-secondary'></i></button>"; $credential_username_display = "$credential_username<button class='btn btn-sm clipboardjs' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
} }
$login_password = nullable_htmlentities(decryptLoginEntry($row['login_password'])); $credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$login_otp_secret = nullable_htmlentities($row['login_otp_secret']); $credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']);
$login_id_with_secret = '"' . $row['login_id'] . '","' . $row['login_otp_secret'] . '"'; $credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
if (empty($login_otp_secret)) { if (empty($credential_otp_secret)) {
$otp_display = "-"; $otp_display = "-";
} else { } else {
$otp_display = "<span onmouseenter='showOTPViaLoginID($login_id)'><i class='far fa-clock'></i> <span id='otp_$login_id'><i>Hover..</i></span></span>"; $otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
} }
$login_note = nullable_htmlentities($row['login_note']); $credential_note = nullable_htmlentities($row['credential_note']);
$login_important = intval($row['login_important']); $credential_important = intval($row['credential_important']);
$login_contact_id = intval($row['login_contact_id']); $credential_contact_id = intval($row['credential_contact_id']);
$login_asset_id = intval($row['login_asset_id']); $credential_asset_id = intval($row['credential_asset_id']);
// Tags // Tags
$login_tag_name_display_array = array(); $credential_tag_name_display_array = array();
$login_tag_id_array = array(); $credential_tag_id_array = array();
$sql_login_tags = mysqli_query($mysqli, "SELECT * FROM login_tags LEFT JOIN tags ON login_tags.tag_id = tags.tag_id WHERE login_id = $login_id ORDER BY tag_name ASC"); $sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_login_tags)) { while ($row = mysqli_fetch_array($sql_credential_tags)) {
$login_tag_id = intval($row['tag_id']); $credential_tag_id = intval($row['tag_id']);
$login_tag_name = nullable_htmlentities($row['tag_name']); $credential_tag_name = nullable_htmlentities($row['tag_name']);
$login_tag_color = nullable_htmlentities($row['tag_color']); $credential_tag_color = nullable_htmlentities($row['tag_color']);
if (empty($login_tag_color)) { if (empty($credential_tag_color)) {
$login_tag_color = "dark"; $credential_tag_color = "dark";
} }
$login_tag_icon = nullable_htmlentities($row['tag_icon']); $credential_tag_icon = nullable_htmlentities($row['tag_icon']);
if (empty($login_tag_icon)) { if (empty($credential_tag_icon)) {
$login_tag_icon = "tag"; $credential_tag_icon = "tag";
} }
$login_tag_id_array[] = $login_tag_id; $credential_tag_id_array[] = $credential_tag_id;
$login_tag_name_display_array[] = "<a href='client_logins.php?client_id=$client_id&tags[]=$login_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $login_tag_color;'><i class='fa fa-fw fa-$login_tag_icon mr-2'></i>$login_tag_name</span></a>"; $credential_tag_name_display_array[] = "<a href='credentials.php?client_id=$client_id&tags[]=$credential_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $credential_tag_color;'><i class='fa fa-fw fa-$credential_tag_icon mr-2'></i>$credential_tag_name</span></a>";
} }
$login_tags_display = implode('', $login_tag_name_display_array); $credential_tags_display = implode('', $credential_tag_name_display_array);
?> ?>
<tr> <tr>
@ -597,18 +602,18 @@ if (isset($_GET['asset_id'])) {
<a class="text-dark" href="#" <a class="text-dark" href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-ajax-url="ajax/ajax_credential_edit.php" data-ajax-url="ajax/ajax_credential_edit.php"
data-ajax-id="<?php echo $login_id; ?>" data-ajax-id="<?php echo $credential_id; ?>"
> >
<?php echo $login_name; ?> <?php echo $credential_name; ?>
</a> </a>
</td> </td>
<td><?php echo $login_description; ?></td> <td><?php echo $credential_description; ?></td>
<td><?php echo $login_username_display; ?></td> <td><?php echo $credential_username_display; ?></td>
<td> <td>
<button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $login_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button><button class="btn btn-sm clipboardjs" data-clipboard-text="<?php echo $login_password; ?>"><i class="far fa-copy text-secondary"></i></button> <button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $credential_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button><button class="btn btn-sm clipboardjs" data-clipboard-text="<?php echo $credential_password; ?>"><i class="far fa-copy text-secondary"></i></button>
</td> </td>
<td><?php echo $otp_display; ?></td> <td><?php echo $otp_display; ?></td>
<td><?php echo $login_uri_display; ?></td> <td><?php echo $credential_uri_display; ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
@ -618,20 +623,20 @@ if (isset($_GET['asset_id'])) {
<a class="dropdown-item" href="#" <a class="dropdown-item" href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-ajax-url="ajax/ajax_credential_edit.php" data-ajax-url="ajax/ajax_credential_edit.php"
data-ajax-id="<?php echo $login_id; ?>" data-ajax-id="<?php echo $credential_id; ?>"
> >
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit mr-2"></i>Edit
</a> </a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'Login', $login_id"; ?>)"> <a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'Credential', $credential_id"; ?>)">
<i class="fas fa-fw fa-share-alt mr-2"></i>Share <i class="fas fa-fw fa-share-alt mr-2"></i>Share
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" href="post.php?unlink_credential_from_asset&asset_id=<?php echo $asset_id; ?>&login_id=<?php echo $login_id; ?>"> <a class="dropdown-item" href="post.php?unlink_credential_from_asset&asset_id=<?php echo $asset_id; ?>&credential_id=<?php echo $credential_id; ?>">
<i class="fas fa-fw fa-unlink mr-2"></i>Unlink <i class="fas fa-fw fa-unlink mr-2"></i>Unlink
</a> </a>
<?php if ($session_user_role == 3) { ?> <?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold" href="post.php?delete_login=<?php echo $login_id; ?>"> <a class="dropdown-item text-danger text-bold" href="post.php?delete_credential=<?php echo $credential_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
<?php } ?> <?php } ?>
@ -686,11 +691,6 @@ if (isset($_GET['asset_id'])) {
$seat_count = 0; $seat_count = 0;
// Get Login
$login_id = intval($row['login_id']);
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username']));
$login_password = nullable_htmlentities(decryptLoginEntry($row['login_password']));
// Asset Licenses // Asset Licenses
$asset_licenses_sql = mysqli_query($mysqli, "SELECT asset_id FROM software_assets WHERE software_id = $software_id"); $asset_licenses_sql = mysqli_query($mysqli, "SELECT asset_id FROM software_assets WHERE software_id = $software_id");
$asset_licenses_array = array(); $asset_licenses_array = array();
@ -917,29 +917,30 @@ if (isset($_GET['asset_id'])) {
<?php <?php
while ($row = mysqli_fetch_array($sql_related_recurring_tickets)) { while ($row = mysqli_fetch_array($sql_related_recurring_tickets)) {
$scheduled_ticket_id = intval($row['scheduled_ticket_id']); $recurring_ticket_id = intval($row['recurring_ticket_id']);
$scheduled_ticket_subject = nullable_htmlentities($row['scheduled_ticket_subject']); $recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']);
$scheduled_ticket_priority = nullable_htmlentities($row['scheduled_ticket_priority']); $recurring_ticket_priority = nullable_htmlentities($row['recurring_ticket_priority']);
$scheduled_ticket_frequency = nullable_htmlentities($row['scheduled_ticket_frequency']); $recurring_ticket_frequency = nullable_htmlentities($row['recurring_ticket_frequency']);
$scheduled_ticket_next_run = nullable_htmlentities($row['scheduled_ticket_next_run']); $recurring_ticket_next_run = nullable_htmlentities($row['recurring_ticket_next_run']);
?> ?>
<tr> <tr>
<td class="text-bold"> <td class="text-bold">
<a href="#" <a href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-modal-size="lg"
data-ajax-url="ajax/ajax_recurring_ticket_edit.php" data-ajax-url="ajax/ajax_recurring_ticket_edit.php"
data-ajax-id="<?php echo $scheduled_ticket_id; ?>" data-ajax-id="<?php echo $recurring_ticket_id; ?>"
> >
<?php echo $scheduled_ticket_subject ?> <?php echo $recurring_ticket_subject ?>
</a> </a>
</td> </td>
<td><?php echo $scheduled_ticket_priority ?></td> <td><?php echo $recurring_ticket_priority ?></td>
<td><?php echo $scheduled_ticket_frequency ?></td> <td><?php echo $recurring_ticket_frequency ?></td>
<td><?php echo $scheduled_ticket_next_run ?></td> <td><?php echo $recurring_ticket_next_run ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropleft text-center">
@ -949,19 +950,20 @@ if (isset($_GET['asset_id'])) {
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item" href="#" <a class="dropdown-item" href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-modal-size="lg"
data-ajax-url="ajax/ajax_recurring_ticket_edit.php" data-ajax-url="ajax/ajax_recurring_ticket_edit.php"
data-ajax-id="<?php echo $scheduled_ticket_id; ?>" data-ajax-id="<?php echo $recurring_ticket_id; ?>"
> >
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit mr-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" href="post.php?force_recurring_ticket=<?php echo $scheduled_ticket_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>"> <a class="dropdown-item" href="post.php?force_recurring_ticket=<?php echo $recurring_ticket_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fa fa-fw fa-paper-plane text-secondary mr-2"></i>Force Reoccur <i class="fa fa-fw fa-paper-plane text-secondary mr-2"></i>Force Reoccur
</a> </a>
<?php <?php
if ($session_user_role == 3) { ?> if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_recurring_ticket=<?php echo $scheduled_ticket_id; ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_recurring_ticket=<?php echo $recurring_ticket_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
</div> </div>
@ -1005,12 +1007,13 @@ if (isset($_GET['asset_id'])) {
$ticket_number = intval($row['ticket_number']); $ticket_number = intval($row['ticket_number']);
$ticket_subject = nullable_htmlentities($row['ticket_subject']); $ticket_subject = nullable_htmlentities($row['ticket_subject']);
$ticket_priority = nullable_htmlentities($row['ticket_priority']); $ticket_priority = nullable_htmlentities($row['ticket_priority']);
$ticket_status_id = intval($row['ticket_status_id']);
$ticket_status_name = nullable_htmlentities($row['ticket_status_name']); $ticket_status_name = nullable_htmlentities($row['ticket_status_name']);
$ticket_status_color = nullable_htmlentities($row['ticket_status_color']); $ticket_status_color = nullable_htmlentities($row['ticket_status_color']);
$ticket_created_at = nullable_htmlentities($row['ticket_created_at']); $ticket_created_at = nullable_htmlentities($row['ticket_created_at']);
$ticket_updated_at = nullable_htmlentities($row['ticket_updated_at']); $ticket_updated_at = nullable_htmlentities($row['ticket_updated_at']);
if (empty($ticket_updated_at)) { if (empty($ticket_updated_at)) {
if ($ticket_status == "Closed") { if ($ticket_status_name == "Closed") {
$ticket_updated_at_display = "<p>Never</p>"; $ticket_updated_at_display = "<p>Never</p>";
} else { } else {
$ticket_updated_at_display = "<p class='text-danger'>Never</p>"; $ticket_updated_at_display = "<p class='text-danger'>Never</p>";
@ -1031,7 +1034,7 @@ if (isset($_GET['asset_id'])) {
} }
$ticket_assigned_to = intval($row['ticket_assigned_to']); $ticket_assigned_to = intval($row['ticket_assigned_to']);
if (empty($ticket_assigned_to)) { if (empty($ticket_assigned_to)) {
if ($ticket_status == 5) { if ($ticket_status_id == 5) {
$ticket_assigned_to_display = "<p>Not Assigned</p>"; $ticket_assigned_to_display = "<p>Not Assigned</p>";
} else { } else {
$ticket_assigned_to_display = "<p class='text-danger'>Not Assigned</p>"; $ticket_assigned_to_display = "<p class='text-danger'>Not Assigned</p>";
@ -1167,7 +1170,7 @@ if (isset($_GET['asset_id'])) {
}); });
</script> </script>
<!-- Include script to get TOTP code via the login ID --> <!-- Include script to get TOTP code via the credential ID -->
<script src="js/credential_show_otp_via_id.js"></script> <script src="js/credential_show_otp_via_id.js"></script>
<?php <?php

View File

@ -298,6 +298,11 @@ if (mysqli_num_rows($os_sql) > 0) {
type="submit" form="bulkActions" name="bulk_unarchive_assets"> type="submit" form="bulkActions" name="bulk_unarchive_assets">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive <i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</button> </button>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_assets">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</button>
<?php } else { ?> <?php } else { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<button class="dropdown-item text-danger confirm-link" <button class="dropdown-item text-danger confirm-link"
@ -519,8 +524,8 @@ if (mysqli_num_rows($os_sql) > 0) {
$location_name_display = $location_name; $location_name_display = $location_name;
} }
$sql_logins = mysqli_query($mysqli, "SELECT * FROM logins WHERE login_asset_id = $asset_id"); $sql_credentials = mysqli_query($mysqli, "SELECT * FROM credentials WHERE credential_asset_id = $asset_id");
$login_count = mysqli_num_rows($sql_logins); $credential_count = mysqli_num_rows($sql_credentials);
?> ?>
<tr> <tr>
@ -664,14 +669,6 @@ if (mysqli_num_rows($os_sql) > 0) {
<script src="js/bulk_actions.js"></script> <script src="js/bulk_actions.js"></script>
<?php
require_once "modals/asset_add_modal.php";
require_once "modals/asset_import_modal.php";
require_once "modals/asset_export_modal.php";
require_once "includes/footer.php";
?>
<!-- JSON Autocomplete / type ahead --> <!-- JSON Autocomplete / type ahead -->
<link rel="stylesheet" href="plugins/jquery-ui/jquery-ui.min.css"> <link rel="stylesheet" href="plugins/jquery-ui/jquery-ui.min.css">
<script src="plugins/jquery-ui/jquery-ui.min.js"></script> <script src="plugins/jquery-ui/jquery-ui.min.js"></script>
@ -687,3 +684,9 @@ require_once "includes/footer.php";
}); });
}); });
</script> </script>
<?php
require_once "modals/asset_add_modal.php";
require_once "modals/asset_import_modal.php";
require_once "modals/asset_export_modal.php";
require_once "includes/footer.php";

View File

@ -12,6 +12,8 @@
<h1>Blank Page</h1> <h1>Blank Page</h1>
<hr> <hr>
<p>This is a great starting point for new custom pages.</p> <p>This is a great starting point for new custom pages.</p>
<h1><?php echo $session_user_role; ?></h1>
<?php validateAdminRole(); ?>
<?php <?php

View File

@ -89,7 +89,7 @@ require_once "modals/calendar_add_modal.php";
//loop through IDs and create a modal for each //loop through IDs and create a modal for each
$sql = mysqli_query($mysqli, "SELECT * FROM events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query"); $sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['event_id']); $event_id = intval($row['event_id']);
$event_title = nullable_htmlentities($row['event_title']); $event_title = nullable_htmlentities($row['event_title']);
@ -170,7 +170,7 @@ while ($row = mysqli_fetch_array($sql)) {
}, },
events: [ events: [
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query"); $sql = mysqli_query($mysqli, "SELECT * FROM calendar_events LEFT JOIN calendars ON event_calendar_id = calendar_id $client_event_query");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['event_id']); $event_id = intval($row['event_id']);
$event_title = json_encode($row['event_title']); $event_title = json_encode($row['event_title']);
@ -245,15 +245,15 @@ while ($row = mysqli_fetch_array($sql)) {
// Recurring Tickets // Recurring Tickets
$sql = mysqli_query($mysqli, "SELECT * FROM clients $sql = mysqli_query($mysqli, "SELECT * FROM clients
LEFT JOIN scheduled_tickets ON client_id = scheduled_ticket_client_id LEFT JOIN recurring_tickets ON client_id = recurring_ticket_client_id
LEFT JOIN users ON scheduled_ticket_assigned_to = user_id LEFT JOIN users ON recurring_ticket_assigned_to = user_id
$client_query" $client_query"
); );
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$event_id = intval($row['scheduled_ticket_id']); $event_id = intval($row['recurring_ticket_id']);
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$username = $row['user_name']; $username = $row['user_name'];
$frequency = $row['scheduled_ticket_frequency']; $frequency = $row['recurring_ticket_frequency'];
if (empty($username)) { if (empty($username)) {
$username = ""; $username = "";
} else { } else {
@ -261,8 +261,8 @@ while ($row = mysqli_fetch_array($sql)) {
$username = "[". substr($row['user_name'], 0, 9) . "...]"; $username = "[". substr($row['user_name'], 0, 9) . "...]";
} }
$event_title = json_encode("R Ticket ($frequency) - " . $row['scheduled_ticket_subject'] . " " . $username); $event_title = json_encode("R Ticket ($frequency) - " . $row['recurring_ticket_subject'] . " " . $username);
$event_start = json_encode($row['scheduled_ticket_next_run']); $event_start = json_encode($row['recurring_ticket_next_run']);
echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'recurring_tickets.php?client_id=$client_id$client_url' },"; echo "{ id: $event_id, title: $event_title, start: $event_start, color: '$event_color', url: 'recurring_tickets.php?client_id=$client_id$client_url' },";
} }

View File

@ -27,7 +27,7 @@ if ($_SESSION['user_type'] !== 2) {
} }
// Set Timezone // Set Timezone
require_once "../inc_set_timezone.php"; require_once "../includes/inc_set_timezone.php";
// User IP & UA // User IP & UA
$session_ip = sanitizeInput(getIP()); $session_ip = sanitizeInput(getIP());

View File

@ -5,7 +5,7 @@
*/ */
require_once '../config.php'; require_once '../config.php';
require_once '../get_settings.php'; require_once '../includes/get_settings.php';
require_once '../functions.php'; require_once '../functions.php';
require_once 'check_login.php'; require_once 'check_login.php';
require_once 'functions.php'; require_once 'functions.php';

View File

@ -10,7 +10,7 @@ require_once '../config.php';
require_once '../functions.php'; require_once '../functions.php';
require_once '../get_settings.php'; require_once '../includes/get_settings.php';
if (!isset($_SESSION)) { if (!isset($_SESSION)) {
// HTTP Only cookies // HTTP Only cookies
@ -23,7 +23,7 @@ if (!isset($_SESSION)) {
} }
// Set Timezone after session_start // Set Timezone after session_start
require_once "../inc_set_timezone.php"; require_once "../includes/inc_set_timezone.php";
// Check to see if client portal is enabled // Check to see if client portal is enabled
if($config_client_portal_enable == 0) { if($config_client_portal_enable == 0) {

View File

@ -18,7 +18,7 @@ if (!isset($_SESSION)) {
} }
// Set Timezone after session starts // Set Timezone after session starts
require_once "../inc_set_timezone.php"; require_once "../includes/inc_set_timezone.php";
$session_ip = sanitizeInput(getIP()); $session_ip = sanitizeInput(getIP());
$session_user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']); $session_user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']);

View File

@ -8,7 +8,7 @@ header("Content-Security-Policy: default-src 'self'");
require_once '../config.php'; require_once '../config.php';
require_once '../functions.php'; require_once '../functions.php';
require_once '../get_settings.php'; require_once '../includes/get_settings.php';
if (empty($config_smtp_host)) { if (empty($config_smtp_host)) {
@ -33,7 +33,7 @@ if (!isset($_SESSION)) {
} }
// Set Timezone after session // Set Timezone after session
require_once "../inc_set_timezone.php"; require_once "../includes/inc_set_timezone.php";
$ip = sanitizeInput(getIP()); $ip = sanitizeInput(getIP());
$user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']); $user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']);

View File

@ -5,9 +5,9 @@
*/ */
require_once '../config.php'; require_once '../config.php';
require_once '../get_settings.php'; require_once '../includes/get_settings.php';
require_once '../functions.php'; require_once '../functions.php';
require_once 'check_login.php'; require_once 'includes/check_login.php';
require_once 'functions.php'; require_once 'functions.php';
if (isset($_POST['add_ticket'])) { if (isset($_POST['add_ticket'])) {

View File

@ -83,14 +83,16 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
</ol> </ol>
<div class="card"> <div class="card">
<div class="card-header bg-dark text-center"> <div class="card-header bg-dark my-2">
<h4 class="mt-1"> <h4 class="card-title mt-1">
Ticket <?php echo $ticket_prefix, $ticket_number ?> Ticket <?php echo $ticket_prefix, $ticket_number ?>
</h4>
<div class="card-tools">
<?php <?php
if (empty($ticket_resolved_at) && $task_count == $completed_task_count) { ?> if (empty($ticket_resolved_at) && $task_count == $completed_task_count) { ?>
<a href="post.php?resolve_ticket=<?php echo $ticket_id; ?>" class="btn btn-sm btn-outline-success float-right text-white confirm-link"><i class="fas fa-fw fa-check text-success"></i> Resolve ticket</a> <a href="post.php?resolve_ticket=<?php echo $ticket_id; ?>" class="btn btn-sm btn-outline-success float-right text-white confirm-link"><i class="fas fa-fw fa-check text-success"></i> Resolve ticket</a>
<?php } ?> <?php } ?>
</h4> </div>
</div> </div>
<div class="card-body prettyContent"> <div class="card-body prettyContent">
@ -122,7 +124,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
while ($ticket_attachment = mysqli_fetch_array($sql_ticket_attachments)) { while ($ticket_attachment = mysqli_fetch_array($sql_ticket_attachments)) {
$name = nullable_htmlentities($ticket_attachment['ticket_attachment_name']); $name = nullable_htmlentities($ticket_attachment['ticket_attachment_name']);
$ref_name = nullable_htmlentities($ticket_attachment['ticket_attachment_reference_name']); $ref_name = nullable_htmlentities($ticket_attachment['ticket_attachment_reference_name']);
echo "<hr class=''><i class='fas fa-fw fa-paperclip text-secondary mr-1'></i>$name | <a target='_blank' href='https://$config_base_url/uploads/tickets/$ticket_id/$ref_name'><i class='fas fa-fw fa-external-link-alt mr-1'></i>View</a>"; echo "<hr><i class='fas fa-fw fa-paperclip text-secondary mr-1'></i>$name | <a href='../uploads/tickets/$ticket_id/$ref_name' download='$name'><i class='fas fa-fw fa-download mr-1'></i>Download</a> | <a target='_blank' href='../uploads/tickets/$ticket_id/$ref_name'><i class='fas fa-fw fa-external-link-alt mr-1'></i>View</a>";
} }
?> ?>
</div> </div>
@ -259,7 +261,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
while ($ticket_attachment = mysqli_fetch_array($sql_ticket_reply_attachments)) { while ($ticket_attachment = mysqli_fetch_array($sql_ticket_reply_attachments)) {
$name = nullable_htmlentities($ticket_attachment['ticket_attachment_name']); $name = nullable_htmlentities($ticket_attachment['ticket_attachment_name']);
$ref_name = nullable_htmlentities($ticket_attachment['ticket_attachment_reference_name']); $ref_name = nullable_htmlentities($ticket_attachment['ticket_attachment_reference_name']);
echo "<hr><i class='fas fa-fw fa-paperclip text-secondary mr-1'></i>$name | <a target='_blank' href='https://$config_base_url/uploads/tickets/$ticket_id/$ref_name'><i class='fas fa-fw fa-external-link-alt mr-1'></i>View</a>"; echo "<hr><i class='fas fa-fw fa-paperclip text-secondary mr-1'></i>$name | <a href='../uploads/tickets/$ticket_id/$ref_name' download='$name'><i class='fas fa-fw fa-download mr-1'></i>Download</a> | <a target='_blank' href='../uploads/tickets/$ticket_id/$ref_name'><i class='fas fa-fw fa-external-link-alt mr-1'></i>View</a>";
} }
?> ?>
</div> </div>

View File

@ -32,12 +32,12 @@ $sql_recent_tickets = mysqli_query(
LIMIT 5" LIMIT 5"
); );
$sql_recent_logins = mysqli_query( $sql_recent_credentials = mysqli_query(
$mysqli, $mysqli,
"SELECT * FROM logins "SELECT * FROM credentials
WHERE login_client_id = $client_id WHERE credential_client_id = $client_id
AND login_archived_at IS NULL AND credential_archived_at IS NULL
ORDER BY login_updated_at ASC ORDER BY credential_updated_at ASC
LIMIT 5" LIMIT 5"
); );
@ -286,10 +286,10 @@ $sql_asset_retired = mysqli_query(
$item_expire_at = nullable_htmlentities($row['item_expire_at']); $item_expire_at = nullable_htmlentities($row['item_expire_at']);
$item_expire_at_human = timeAgo($row['item_expire_at']); $item_expire_at_human = timeAgo($row['item_expire_at']);
if ($item_type == 'Login') { if ($item_type == 'Credential') {
$share_item_sql = mysqli_query($mysqli, "SELECT login_name FROM logins WHERE login_id = $item_related_id AND login_client_id = $client_id"); $share_item_sql = mysqli_query($mysqli, "SELECT credential_name FROM credentials WHERE credential_id = $item_related_id AND credential_client_id = $client_id");
$share_item = mysqli_fetch_array($share_item_sql); $share_item = mysqli_fetch_array($share_item_sql);
$item_name = nullable_htmlentities($share_item['login_name']); $item_name = nullable_htmlentities($share_item['credential_name']);
$item_icon = "fas fa-key"; $item_icon = "fas fa-key";
} elseif ($item_type == 'Document') { } elseif ($item_type == 'Document') {
$share_item_sql = mysqli_query($mysqli, "SELECT document_name FROM documents WHERE document_id = $item_related_id AND document_client_id = $client_id"); $share_item_sql = mysqli_query($mysqli, "SELECT document_name FROM documents WHERE document_id = $item_related_id AND document_client_id = $client_id");

View File

@ -362,13 +362,13 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
} }
//Get Monthly Recurring Total //Get Monthly Recurring Total
$sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_amount) AS recurring_monthly_total FROM recurring WHERE recurring_status = 1 AND recurring_frequency = 'month' AND recurring_client_id = $client_id"); $sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_monthly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'month' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_monthly_total); $row = mysqli_fetch_array($sql_recurring_monthly_total);
$recurring_monthly_total = floatval($row['recurring_monthly_total']); $recurring_monthly_total = floatval($row['recurring_monthly_total']);
//Get Yearly Recurring Total //Get Yearly Recurring Total
$sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_amount) AS recurring_yearly_total FROM recurring WHERE recurring_status = 1 AND recurring_frequency = 'year' AND recurring_client_id = $client_id"); $sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_yearly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'year' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_yearly_total); $row = mysqli_fetch_array($sql_recurring_yearly_total);
$recurring_yearly_total = floatval($row['recurring_yearly_total']) / 12; $recurring_yearly_total = floatval($row['recurring_yearly_total']) / 12;

View File

@ -69,21 +69,21 @@ if (isset($_GET['contact_id'])) {
$linked_software = array(); $linked_software = array();
// Related Logins Query 1 to 1 relationship // Related Credentials Query 1 to 1 relationship
$sql_related_logins = mysqli_query($mysqli, " $sql_related_credentials = mysqli_query($mysqli, "
SELECT SELECT
logins.login_id AS logins_login_id, -- Alias for logins.login_id credentials.credential_id AS credentials_credential_id, -- Alias for credentials.credential_id
logins.*, -- All other columns from logins credentials.*, -- All other columns from credentials
login_tags.*, -- All columns from login_tags credential_tags.*, -- All columns from credential_tags
tags.* -- All columns from tags tags.* -- All columns from tags
FROM logins FROM credentials
LEFT JOIN login_tags ON login_tags.login_id = logins.login_id LEFT JOIN credential_tags ON credential_tags.credential_id = credentials.credential_id
LEFT JOIN tags ON tags.tag_id = login_tags.tag_id LEFT JOIN tags ON tags.tag_id = credential_tags.tag_id
WHERE login_contact_id = $contact_id WHERE credential_contact_id = $contact_id
GROUP BY logins.login_id GROUP BY credentials.credential_id
ORDER BY login_name DESC ORDER BY credential_name DESC
"); ");
$login_count = mysqli_num_rows($sql_related_logins); $credential_count = mysqli_num_rows($sql_related_credentials);
// Related Tickets Query - 1 to 1 relationship // Related Tickets Query - 1 to 1 relationship
$sql_related_tickets = mysqli_query($mysqli, "SELECT * FROM tickets $sql_related_tickets = mysqli_query($mysqli, "SELECT * FROM tickets
@ -93,9 +93,9 @@ if (isset($_GET['contact_id'])) {
$ticket_count = mysqli_num_rows($sql_related_tickets); $ticket_count = mysqli_num_rows($sql_related_tickets);
// Related Recurring Tickets Query // Related Recurring Tickets Query
$sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM scheduled_tickets $sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM recurring_tickets
WHERE scheduled_ticket_contact_id = $contact_id WHERE recurring_ticket_contact_id = $contact_id
ORDER BY scheduled_ticket_next_run DESC" ORDER BY recurring_ticket_next_run DESC"
); );
$recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets); $recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets);
@ -446,7 +446,7 @@ if (isset($_GET['contact_id'])) {
</div> </div>
</div> </div>
<div class="card card-dark <?php if ($login_count == 0) { echo "d-none"; } ?>"> <div class="card card-dark <?php if ($credential_count == 0) { echo "d-none"; } ?>">
<div class="card-header"> <div class="card-header">
<h3 class="card-title"><i class="fa fa-fw fa-key mr-2"></i>Credentials</h3> <h3 class="card-title"><i class="fa fa-fw fa-key mr-2"></i>Credentials</h3>
</div> </div>
@ -467,57 +467,57 @@ if (isset($_GET['contact_id'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_related_logins)) { while ($row = mysqli_fetch_array($sql_related_credentials)) {
$login_id = intval($row['logins_login_id']); $credential_id = intval($row['credentials_credential_id']);
$login_name = nullable_htmlentities($row['login_name']); $credential_name = nullable_htmlentities($row['credential_name']);
$login_description = nullable_htmlentities($row['login_description']); $credential_description = nullable_htmlentities($row['credential_description']);
$login_uri = nullable_htmlentities($row['login_uri']); $credential_uri = nullable_htmlentities($row['credential_uri']);
if (empty($login_uri)) { if (empty($credential_uri)) {
$login_uri_display = "-"; $credential_uri_display = "-";
} else { } else {
$login_uri_display = "$login_uri<button class='btn btn-sm clipboardjs' data-clipboard-text='$login_uri'><i class='far fa-copy text-secondary'></i></button><a href='$login_uri' target='_blank'><i class='fa fa-external-link-alt text-secondary'></i></a>"; $credential_uri_display = "$credential_uri<button class='btn btn-sm clipboardjs' data-clipboard-text='$credential_uri'><i class='far fa-copy text-secondary'></i></button><a href='$credential_uri' target='_blank'><i class='fa fa-external-link-alt text-secondary'></i></a>";
} }
$login_uri_2 = nullable_htmlentities($row['login_uri_2']); $credential_uri_2 = nullable_htmlentities($row['credential_uri_2']);
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username'])); $credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
if (empty($login_username)) { if (empty($credential_username)) {
$login_username_display = "-"; $credential_username_display = "-";
} else { } else {
$login_username_display = "$login_username<button class='btn btn-sm clipboardjs' data-clipboard-text='$login_username'><i class='far fa-copy text-secondary'></i></button>"; $credential_username_display = "$credential_username<button class='btn btn-sm clipboardjs' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
} }
$login_password = nullable_htmlentities(decryptLoginEntry($row['login_password'])); $credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$login_otp_secret = nullable_htmlentities($row['login_otp_secret']); $credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']);
$login_id_with_secret = '"' . $row['login_id'] . '","' . $row['login_otp_secret'] . '"'; $credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
if (empty($login_otp_secret)) { if (empty($credential_otp_secret)) {
$otp_display = "-"; $otp_display = "-";
} else { } else {
$otp_display = "<span onmouseenter='showOTPViaLoginID($login_id)'><i class='far fa-clock'></i> <span id='otp_$login_id'><i>Hover..</i></span></span>"; $otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
} }
$login_note = nullable_htmlentities($row['login_note']); $credential_note = nullable_htmlentities($row['credential_note']);
$login_important = intval($row['login_important']); $credential_important = intval($row['credential_important']);
$login_contact_id = intval($row['login_contact_id']); $credential_contact_id = intval($row['credential_contact_id']);
$login_asset_id = intval($row['login_asset_id']); $credential_asset_id = intval($row['credential_asset_id']);
// Tags // Tags
$login_tag_name_display_array = array(); $credential_tag_name_display_array = array();
$login_tag_id_array = array(); $credential_tag_id_array = array();
$sql_login_tags = mysqli_query($mysqli, "SELECT * FROM login_tags LEFT JOIN tags ON login_tags.tag_id = tags.tag_id WHERE login_id = $login_id ORDER BY tag_name ASC"); $sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_login_tags)) { while ($row = mysqli_fetch_array($sql_credential_tags)) {
$login_tag_id = intval($row['tag_id']); $credential_tag_id = intval($row['tag_id']);
$login_tag_name = nullable_htmlentities($row['tag_name']); $credential_tag_name = nullable_htmlentities($row['tag_name']);
$login_tag_color = nullable_htmlentities($row['tag_color']); $credential_tag_color = nullable_htmlentities($row['tag_color']);
if (empty($login_tag_color)) { if (empty($credential_tag_color)) {
$login_tag_color = "dark"; $credential_tag_color = "dark";
} }
$login_tag_icon = nullable_htmlentities($row['tag_icon']); $credential_tag_icon = nullable_htmlentities($row['tag_icon']);
if (empty($login_tag_icon)) { if (empty($credential_tag_icon)) {
$login_tag_icon = "tag"; $credential_tag_icon = "tag";
} }
$login_tag_id_array[] = $login_tag_id; $credential_tag_id_array[] = $credential_tag_id;
$login_tag_name_display_array[] = "<a href='client_logins.php?client_id=$client_id&tags[]=$login_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $login_tag_color;'><i class='fa fa-fw fa-$login_tag_icon mr-2'></i>$login_tag_name</span></a>"; $credential_tag_name_display_array[] = "<a href='credentials.php?client_id=$client_id&tags[]=$credential_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $credential_tag_color;'><i class='fa fa-fw fa-$credential_tag_icon mr-2'></i>$credential_tag_name</span></a>";
} }
$login_tags_display = implode('', $login_tag_name_display_array); $credential_tags_display = implode('', $credential_tag_name_display_array);
?> ?>
<tr> <tr>
@ -526,18 +526,18 @@ if (isset($_GET['contact_id'])) {
<a class="text-dark" href="#" <a class="text-dark" href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-ajax-url="ajax/ajax_credential_edit.php" data-ajax-url="ajax/ajax_credential_edit.php"
data-ajax-id="<?php echo $login_id; ?>" data-ajax-id="<?php echo $credential_id; ?>"
> >
<?php echo $login_name; ?> <?php echo $credential_name; ?>
</a> </a>
</td> </td>
<td><?php echo $login_description; ?></td> <td><?php echo $credential_description; ?></td>
<td><?php echo $login_username_display; ?></td> <td><?php echo $credential_username_display; ?></td>
<td> <td>
<button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $login_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button><button class="btn btn-sm clipboardjs" data-clipboard-text="<?php echo $login_password; ?>"><i class="far fa-copy text-secondary"></i></button> <button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $credential_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button><button class="btn btn-sm clipboardjs" data-clipboard-text="<?php echo $credential_password; ?>"><i class="far fa-copy text-secondary"></i></button>
</td> </td>
<td><?php echo $otp_display; ?></td> <td><?php echo $otp_display; ?></td>
<td><?php echo $login_uri_display; ?></td> <td><?php echo $credential_uri_display; ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
@ -547,21 +547,21 @@ if (isset($_GET['contact_id'])) {
<a class="dropdown-item" href="#" <a class="dropdown-item" href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-ajax-url="ajax/ajax_credential_edit.php" data-ajax-url="ajax/ajax_credential_edit.php"
data-ajax-id="<?php echo $login_id; ?>"> data-ajax-id="<?php echo $credential_id; ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit mr-2"></i>Edit
</a> </a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'Login', $login_id"; ?>)"> <a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'Credential', $credential_id"; ?>)">
<i class="fas fa-fw fa-share-alt mr-2"></i>Share <i class="fas fa-fw fa-share-alt mr-2"></i>Share
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" <a class="dropdown-item"
href="post.php?unlink_credential_from_contact&contact_id=<?php echo $contact_id; ?>&login_id=<?php echo $login_id; ?>" href="post.php?unlink_credential_from_contact&contact_id=<?php echo $contact_id; ?>&credential_id=<?php echo $credential_id; ?>"
class="btn btn-secondary btn-sm" title="Unlink"> class="btn btn-secondary btn-sm" title="Unlink">
<i class="fas fa-fw fa-unlink mr-2"></i>Unlink <i class="fas fa-fw fa-unlink mr-2"></i>Unlink
</a> </a>
<?php if ($session_user_role == 3) { ?> <?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold" href="post.php?delete_login=<?php echo $login_id; ?>"> <a class="dropdown-item text-danger text-bold" href="post.php?delete_credential=<?php echo $credential_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
<?php } ?> <?php } ?>
@ -683,11 +683,11 @@ if (isset($_GET['contact_id'])) {
<?php <?php
while ($row = mysqli_fetch_array($sql_related_recurring_tickets)) { while ($row = mysqli_fetch_array($sql_related_recurring_tickets)) {
$scheduled_ticket_id = intval($row['scheduled_ticket_id']); $recurring_ticket_id = intval($row['recurring_ticket_id']);
$scheduled_ticket_subject = nullable_htmlentities($row['scheduled_ticket_subject']); $recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']);
$scheduled_ticket_priority = nullable_htmlentities($row['scheduled_ticket_priority']); $recurring_ticket_priority = nullable_htmlentities($row['recurring_ticket_priority']);
$scheduled_ticket_frequency = nullable_htmlentities($row['scheduled_ticket_frequency']); $recurring_ticket_frequency = nullable_htmlentities($row['recurring_ticket_frequency']);
$scheduled_ticket_next_run = nullable_htmlentities($row['scheduled_ticket_next_run']); $recurring_ticket_next_run = nullable_htmlentities($row['recurring_ticket_next_run']);
?> ?>
<tr> <tr>
@ -695,14 +695,14 @@ if (isset($_GET['contact_id'])) {
<a href="#" <a href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-ajax-url="ajax/ajax_recurring_ticket_edit.php" data-ajax-url="ajax/ajax_recurring_ticket_edit.php"
data-ajax-id="<?php echo $scheduled_ticket_id; ?>" data-ajax-id="<?php echo $recurring_ticket_id; ?>"
> >
<?php echo $scheduled_ticket_subject ?> <?php echo $recurring_ticket_subject ?>
</a> </a>
</td> </td>
<td><?php echo $scheduled_ticket_priority ?></td> <td><?php echo $recurring_ticket_priority ?></td>
<td><?php echo $scheduled_ticket_frequency ?></td> <td><?php echo $recurring_ticket_frequency ?></td>
<td><?php echo $scheduled_ticket_next_run ?></td> <td><?php echo $recurring_ticket_next_run ?></td>
<td> <td>
<div class="dropdown dropleft text-center"> <div class="dropdown dropleft text-center">
<button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-secondary btn-sm" type="button" data-toggle="dropdown">
@ -712,18 +712,18 @@ if (isset($_GET['contact_id'])) {
<a class="dropdown-item" href="#" <a class="dropdown-item" href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-ajax-url="ajax/ajax_recurring_ticket_edit.php" data-ajax-url="ajax/ajax_recurring_ticket_edit.php"
data-ajax-id="<?php echo $scheduled_ticket_id; ?>" data-ajax-id="<?php echo $recurring_ticket_id; ?>"
> >
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit mr-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" href="post.php?force_recurring_ticket=<?php echo $scheduled_ticket_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>"> <a class="dropdown-item" href="post.php?force_recurring_ticket=<?php echo $recurring_ticket_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
<i class="fa fa-fw fa-paper-plane text-secondary mr-2"></i>Force Reoccur <i class="fa fa-fw fa-paper-plane text-secondary mr-2"></i>Force Reoccur
</a> </a>
<?php <?php
if ($session_user_role == 3) { ?> if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_recurring_ticket=<?php echo $scheduled_ticket_id; ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_recurring_ticket=<?php echo $recurring_ticket_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</a> </a>
</div> </div>
@ -1162,7 +1162,7 @@ if (isset($_GET['contact_id'])) {
}); });
</script> </script>
<!-- Include script to get TOTP code via the login ID --> <!-- Include script to get TOTP code via the Credential ID -->
<script src="js/credential_show_otp_via_id.js"></script> <script src="js/credential_show_otp_via_id.js"></script>
<?php <?php

View File

@ -351,6 +351,11 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
} }
$auth_method = nullable_htmlentities($row['user_auth_method']); $auth_method = nullable_htmlentities($row['user_auth_method']);
$contact_user_id = intval($row['contact_user_id']); $contact_user_id = intval($row['contact_user_id']);
if ($contact_user_id) {
$user_exists_display = "<span class='badge badge-pill badge-dark p-1' title='User: $auth_method'><i class='fas fa-fw fa-user'></i></span>";
} else {
$user_exists_display = "";
}
// Related Assets Query // Related Assets Query
$sql_related_assets = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_contact_id = $contact_id ORDER BY asset_id DESC"); $sql_related_assets = mysqli_query($mysqli, "SELECT * FROM assets WHERE asset_contact_id = $contact_id ORDER BY asset_id DESC");
@ -361,13 +366,13 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$asset_count_display = ''; $asset_count_display = '';
} }
// Related Logins Query // Related Credentials Query
$sql_related_logins = mysqli_query($mysqli, "SELECT * FROM logins WHERE login_contact_id = $contact_id ORDER BY login_id DESC"); $sql_related_credentials = mysqli_query($mysqli, "SELECT * FROM credentials WHERE credential_contact_id = $contact_id ORDER BY credential_id DESC");
$login_count = mysqli_num_rows($sql_related_logins); $credential_count = mysqli_num_rows($sql_related_credentials);
if ($login_count) { if ($credential_count) {
$login_count_display = "<span class='mr-2 badge badge-pill badge-secondary p-2' title='$login_count Credentials'><i class='fas fa-fw fa-key mr-2'></i>$login_count</span>"; $credential_count_display = "<span class='mr-2 badge badge-pill badge-secondary p-2' title='$credential_count Credentials'><i class='fas fa-fw fa-key mr-2'></i>$credential_count</span>";
} else { } else {
$login_count_display = ''; $credential_count_display = '';
} }
// Related Software Query // Related Software Query
@ -385,7 +390,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
if ($ticket_count) { if ($ticket_count) {
$ticket_count_display = "<span class='mr-2 badge badge-pill badge-secondary p-2' title='$ticket_count Tickets'><i class='fas fa-fw fa-life-ring mr-2'></i>$ticket_count</span>"; $ticket_count_display = "<span class='mr-2 badge badge-pill badge-secondary p-2' title='$ticket_count Tickets'><i class='fas fa-fw fa-life-ring mr-2'></i>$ticket_count</span>";
} else { } else {
$software_count_display = ''; $ticket_count_display = '';
} }
// Related Documents Query // Related Documents Query
@ -445,7 +450,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php } ?> <?php } ?>
<div class="media-body"> <div class="media-body">
<div class="<?php if($contact_important) { echo "text-bold"; } ?>"><?php echo $contact_name; ?></div> <div class="<?php if($contact_important) { echo "text-bold"; } ?>"><?php echo $contact_name; ?> <?php echo $user_exists_display; ?></div>
<?php echo $contact_title_display; ?> <?php echo $contact_title_display; ?>
<div><?php echo $contact_primary_display; ?></div> <div><?php echo $contact_primary_display; ?></div>
<?php <?php
@ -463,7 +468,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<td><?php echo $contact_info_display; ?></td> <td><?php echo $contact_info_display; ?></td>
<td><?php echo $location_name_display; ?></td> <td><?php echo $location_name_display; ?></td>
<td> <td>
<?php echo "$asset_count_display$login_count_display$software_count_display$ticket_count_display$document_count_display"; ?> <?php echo "$asset_count_display$credential_count_display$software_count_display$ticket_count_display$document_count_display"; ?>
</td> </td>
<?php if (!$client_url) { ?> <?php if (!$client_url) { ?>
<td><a href="contacts.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td> <td><a href="contacts.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>

View File

@ -1,21 +1,21 @@
<?php <?php
// Default Column Sortby Filter // Default Column Sortby Filter
$sort = "login_name"; $sort = "credential_name";
$order = "ASC"; $order = "ASC";
// If client_id is in URI then show client Side Bar and client header // If client_id is in URI then show client Side Bar and client header
if (isset($_GET['client_id'])) { if (isset($_GET['client_id'])) {
require_once "includes/inc_all_client.php"; require_once "includes/inc_all_client.php";
$client_query = "AND login_client_id = $client_id"; $client_query = "AND credential_client_id = $client_id";
$client_url = "client_id=$client_id&"; $client_url = "client_id=$client_id&";
// Log when users load the Credentials/Logins page // Log when users load the Credentials page
logAction("Credential", "View", "$session_name viewed the Credentials page for client", $client_id); logAction("Credential", "View", "$session_name viewed the Credentials page for client", $client_id);
} else { } else {
require_once "includes/inc_client_overview_all.php"; require_once "includes/inc_client_overview_all.php";
$client_query = ''; $client_query = '';
$client_url = ''; $client_url = '';
// Log when users load the Credentials/Logins page // Log when users load the Credentials page
logAction("Credential", "View", "$session_name viewed the All Credentials page"); logAction("Credential", "View", "$session_name viewed the All Credentials page");
} }
@ -41,7 +41,7 @@ if (isset($_GET['tags']) && is_array($_GET['tags']) && !empty($_GET['tags'])) {
if (!$client_url) { if (!$client_url) {
// Client Filter // Client Filter
if (isset($_GET['client']) & !empty($_GET['client'])) { if (isset($_GET['client']) & !empty($_GET['client'])) {
$client_query = 'AND (login_client_id = ' . intval($_GET['client']) . ')'; $client_query = 'AND (credential_client_id = ' . intval($_GET['client']) . ')';
$client = intval($_GET['client']); $client = intval($_GET['client']);
} else { } else {
// Default - any // Default - any
@ -53,7 +53,7 @@ if (!$client_url) {
// Location Filter // Location Filter
if ($client_url && isset($_GET['location']) && !empty($_GET['location'])) { if ($client_url && isset($_GET['location']) && !empty($_GET['location'])) {
$location_query = 'AND (a.asset_location_id = ' . intval($_GET['location']) . ')'; $location_query = 'AND (a.asset_location_id = ' . intval($_GET['location']) . ')';
$location_query_innerjoin = 'INNER JOIN assets a on a.asset_id = l.login_asset_id '; $location_query_innerjoin = 'INNER JOIN assets a on a.asset_id = c.credential_asset_id ';
$location_filter = intval($_GET['location']); $location_filter = intval($_GET['location']);
} else { } else {
// Default - any // Default - any
@ -64,22 +64,22 @@ if ($client_url && isset($_GET['location']) && !empty($_GET['location'])) {
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT SQL_CALC_FOUND_ROWS l.login_id AS l_login_id, l.*, login_tags.*, tags.*, clients.*, contacts.*, assets.* "SELECT SQL_CALC_FOUND_ROWS c.credential_id AS c_credential_id, c.*, credential_tags.*, tags.*, clients.*, contacts.*, assets.*
FROM logins l FROM credentials c
LEFT JOIN login_tags ON login_tags.login_id = l.login_id LEFT JOIN credential_tags ON credential_tags.credential_id = c.credential_id
LEFT JOIN tags ON tags.tag_id = login_tags.tag_id LEFT JOIN tags ON tags.tag_id = credential_tags.tag_id
LEFT JOIN clients ON client_id = login_client_id LEFT JOIN clients ON client_id = credential_client_id
LEFT JOIN contacts ON contact_id = login_contact_id LEFT JOIN contacts ON contact_id = credential_contact_id
LEFT JOIN assets ON asset_id = login_asset_id LEFT JOIN assets ON asset_id = credential_asset_id
$location_query_innerjoin $location_query_innerjoin
WHERE l.login_$archive_query WHERE c.credential_$archive_query
$tag_query $tag_query
AND (l.login_name LIKE '%$q%' OR l.login_description LIKE '%$q%' OR l.login_uri LIKE '%$q%' OR tag_name LIKE '%$q%' OR client_name LIKE '%$q%') AND (c.credential_name LIKE '%$q%' OR c.credential_description LIKE '%$q%' OR c.credential_uri LIKE '%$q%' OR tag_name LIKE '%$q%' OR client_name LIKE '%$q%')
$location_query $location_query
$access_permission_query $access_permission_query
$client_query $client_query
GROUP BY l.login_id GROUP BY c.credential_id
ORDER BY l.login_important DESC, $sort $order LIMIT $record_from, $record_to" ORDER BY c.credential_important DESC, $sort $order LIMIT $record_from, $record_to"
); );
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
@ -92,17 +92,17 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="card-tools"> <div class="card-tools">
<?php if (lookupUserPermission("module_credential") >= 2) { ?> <?php if (lookupUserPermission("module_credential") >= 2) { ?>
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addLoginModal" <?php if (!isset($_COOKIE['user_encryption_session_key'])) { echo "disabled"; } ?>> <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addCredentialModal" <?php if (!isset($_COOKIE['user_encryption_session_key'])) { echo "disabled"; } ?>>
<i class="fas fa-plus mr-2"></i>New Credential <i class="fas fa-plus mr-2"></i>New Credential
</button> </button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button> <button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#importLoginModal"> <a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#importCredentialModal">
<i class="fa fa-fw fa-upload mr-2"></i>Import <i class="fa fa-fw fa-upload mr-2"></i>Import
</a> </a>
<?php if ($num_rows[0] > 0) { ?> <?php if ($num_rows[0] > 0) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportLoginModal"> <a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#exportCredentialModal">
<i class="fa fa-fw fa-download mr-2"></i>Export <i class="fa fa-fw fa-download mr-2"></i>Export
</a> </a>
<?php } ?> <?php } ?>
@ -207,12 +207,12 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<div class="dropdown-menu"> <div class="dropdown-menu">
<?php if ($archived) { ?> <?php if ($archived) { ?>
<button class="dropdown-item text-info" <button class="dropdown-item text-info"
type="submit" form="bulkActions" name="bulk_unarchive_logins"> type="submit" form="bulkActions" name="bulk_unarchive_credentials">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive <i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</button> </button>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold" <button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_logins"> type="submit" form="bulkActions" name="bulk_delete_credentials">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
</button> </button>
<?php } else { ?> <?php } else { ?>
@ -221,7 +221,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<button class="dropdown-item text-danger confirm-link" <button class="dropdown-item text-danger confirm-link"
type="submit" form="bulkActions" name="bulk_archive_logins"> type="submit" form="bulkActions" name="bulk_archive_credentials">
<i class="fas fa-fw fa-archive mr-2"></i>Archive <i class="fas fa-fw fa-archive mr-2"></i>Archive
</button> </button>
<?php } ?> <?php } ?>
@ -246,16 +246,16 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</div> </div>
</td> </td>
<th> <th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=login_name&order=<?php echo $disp; ?>"> <a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=credential_name&order=<?php echo $disp; ?>">
Name <?php if ($sort == 'login_name') { echo $order_icon; } ?> Name <?php if ($sort == 'credential_name') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th>Username / ID</th> <th>Username / ID</th>
<th>Password / Key</th> <th>Password / Key</th>
<th>OTP</th> <th>OTP</th>
<th> <th>
<a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=login_uri&order=<?php echo $disp; ?>"> <a class="text-secondary" href="?<?php echo $url_query_strings_sort; ?>&sort=credential_uri&order=<?php echo $disp; ?>">
URI <?php if ($sort == 'login_uri') { echo $order_icon; } ?> URI <?php if ($sort == 'credential_uri') { echo $order_icon; } ?>
</a> </a>
</th> </th>
<th></th> <th></th>
@ -275,80 +275,80 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$login_id = intval($row['l_login_id']); $credential_id = intval($row['c_credential_id']);
$login_name = nullable_htmlentities($row['login_name']); $credential_name = nullable_htmlentities($row['credential_name']);
$login_description = nullable_htmlentities($row['login_description']); $credential_description = nullable_htmlentities($row['credential_description']);
$login_uri = nullable_htmlentities($row['login_uri']); $credential_uri = nullable_htmlentities($row['credential_uri']);
if (empty($login_uri)) { if (empty($credential_uri)) {
$login_uri_display = "-"; $credential_uri_display = "-";
} else { } else {
$login_uri_display = truncate($login_uri,40) . "<button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$login_uri'><i class='far fa-copy text-secondary'></i></button>"; $credential_uri_display = truncate($credential_uri,40) . "<button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$credential_uri'><i class='far fa-copy text-secondary'></i></button>";
} }
$login_uri_2 = nullable_htmlentities($row['login_uri_2']); $credential_uri_2 = nullable_htmlentities($row['credential_uri_2']);
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username'])); $credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
if (empty($login_username)) { if (empty($credential_username)) {
$login_username_display = "-"; $credential_username_display = "-";
} else { } else {
$login_username_display = "$login_username<button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$login_username'><i class='far fa-copy text-secondary'></i></button>"; $credential_username_display = "$credential_username<button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
} }
$login_password = nullable_htmlentities(decryptLoginEntry($row['login_password'])); $credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$login_otp_secret = nullable_htmlentities($row['login_otp_secret']); $credential_otp_secret = nullable_htmlentities($row['credential_otp_secret']);
$login_id_with_secret = '"' . $row['login_id'] . '","' . $row['login_otp_secret'] . '"'; $credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
if (empty($login_otp_secret)) { if (empty($credential_otp_secret)) {
$otp_display = "-"; $otp_display = "-";
} else { } else {
$otp_display = "<span onmouseenter='showOTPViaLoginID($login_id)'><i class='far fa-clock'></i> <span id='otp_$login_id'><i>Hover..</i></span></span>"; $otp_display = "<span onmouseenter='showOTPViaCredentialID($credential_id)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
} }
$login_note = nullable_htmlentities($row['login_note']); $credential_note = nullable_htmlentities($row['credential_note']);
$login_created_at = nullable_htmlentities($row['login_created_at']); $credential_created_at = nullable_htmlentities($row['credential_created_at']);
$login_archived_at = nullable_htmlentities($row['login_archived_at']); $credential_archived_at = nullable_htmlentities($row['credential_archived_at']);
$login_important = intval($row['login_important']); $credential_important = intval($row['credential_important']);
$login_contact_id = intval($row['login_contact_id']); $credential_contact_id = intval($row['credential_contact_id']);
$contact_name = nullable_htmlentities($row['contact_name']); $contact_name = nullable_htmlentities($row['contact_name']);
$login_asset_id = intval($row['login_asset_id']); $credential_asset_id = intval($row['credential_asset_id']);
$asset_name = nullable_htmlentities($row['asset_name']); $asset_name = nullable_htmlentities($row['asset_name']);
// Tags // Tags
$login_tag_name_display_array = array(); $credential_tag_name_display_array = array();
$login_tag_id_array = array(); $credential_tag_id_array = array();
$sql_login_tags = mysqli_query($mysqli, "SELECT * FROM login_tags LEFT JOIN tags ON login_tags.tag_id = tags.tag_id WHERE login_id = $login_id ORDER BY tag_name ASC"); $sql_credential_tags = mysqli_query($mysqli, "SELECT * FROM credential_tags LEFT JOIN tags ON credential_tags.tag_id = tags.tag_id WHERE credential_id = $credential_id ORDER BY tag_name ASC");
while ($row = mysqli_fetch_array($sql_login_tags)) { while ($row = mysqli_fetch_array($sql_credential_tags)) {
$login_tag_id = intval($row['tag_id']); $credential_tag_id = intval($row['tag_id']);
$login_tag_name = nullable_htmlentities($row['tag_name']); $credential_tag_name = nullable_htmlentities($row['tag_name']);
$login_tag_color = nullable_htmlentities($row['tag_color']); $credential_tag_color = nullable_htmlentities($row['tag_color']);
if (empty($login_tag_color)) { if (empty($credential_tag_color)) {
$login_tag_color = "dark"; $credential_tag_color = "dark";
} }
$login_tag_icon = nullable_htmlentities($row['tag_icon']); $credential_tag_icon = nullable_htmlentities($row['tag_icon']);
if (empty($login_tag_icon)) { if (empty($credential_tag_icon)) {
$login_tag_icon = "tag"; $credential_tag_icon = "tag";
} }
$login_tag_id_array[] = $login_tag_id; $credential_tag_id_array[] = $credential_tag_id;
$login_tag_name_display_array[] = "<a href='credentials.php?$client_url tags[]=$login_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $login_tag_color;'><i class='fa fa-fw fa-$login_tag_icon mr-2'></i>$login_tag_name</span></a>"; $credential_tag_name_display_array[] = "<a href='credentials.php?$client_url tags[]=$credential_tag_id'><span class='badge text-light p-1 mr-1' style='background-color: $credential_tag_color;'><i class='fa fa-fw fa-$credential_tag_icon mr-2'></i>$credential_tag_name</span></a>";
} }
$login_tags_display = implode('', $login_tag_name_display_array); $credential_tags_display = implode('', $credential_tag_name_display_array);
if ($login_contact_id) { if ($credential_contact_id) {
$login_contact_display = "<a href='#' class='mr-2 badge badge-pill badge-dark p-2' title='$contact_name' $credential_contact_display = "<a href='#' class='mr-2 badge badge-pill badge-dark p-2' title='$contact_name'
data-toggle='ajax-modal' data-toggle='ajax-modal'
data-modal-size='lg' data-modal-size='lg'
data-ajax-url='ajax/ajax_contact_details.php' data-ajax-url='ajax/ajax_contact_details.php'
data-ajax-id='$login_contact_id'> data-ajax-id='$credential_contact_id'>
<i class='fas fa-fw fa-user'></i></a>"; <i class='fas fa-fw fa-user'></i></a>";
} else { } else {
$login_contact_display = ''; $credential_contact_display = '';
} }
if ($login_asset_id) { if ($credential_asset_id) {
$login_asset_display = "<a href='#' class='mr-2 badge badge-pill badge-secondary p-2' title='$asset_name' data-toggle='ajax-modal' $credential_asset_display = "<a href='#' class='mr-2 badge badge-pill badge-secondary p-2' title='$asset_name' data-toggle='ajax-modal'
data-modal-size='lg' data-modal-size='lg'
data-ajax-url='ajax/ajax_asset_details.php' data-ajax-url='ajax/ajax_asset_details.php'
data-ajax-id='$login_asset_id'> data-ajax-id='$credential_asset_id'>
<i class='fas fa-fw fa-desktop'></i></a>"; <i class='fas fa-fw fa-desktop'></i></a>";
} else { } else {
$login_asset_display = ''; $credential_asset_display = '';
} }
// Check if shared // Check if shared
@ -359,8 +359,8 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
AND item_active = 1 AND item_active = 1
AND item_views != item_view_limit AND item_views != item_view_limit
AND item_expire_at > NOW() AND item_expire_at > NOW()
AND item_type = 'Login' AND item_type = 'Credential'
AND item_related_id = $login_id AND item_related_id = $credential_id
LIMIT 1" LIMIT 1"
); );
if (mysqli_num_rows($sql_shared) > 0) { if (mysqli_num_rows($sql_shared) > 0) {
@ -381,41 +381,41 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
?> ?>
<tr class="<?php if (!empty($login_important)) { echo "text-bold"; } ?>"> <tr class="<?php if (!empty($credential_important)) { echo "text-bold"; } ?>">
<td class="pr-0"> <td class="pr-0">
<div class="form-check"> <div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="login_ids[]" value="<?php echo $login_id ?>"> <input class="form-check-input bulk-select" type="checkbox" name="credential_ids[]" value="<?php echo $credential_id ?>">
</div> </div>
</td> </td>
<td> <td>
<a class="text-dark" href="#" <a class="text-dark" href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-ajax-url="ajax/ajax_credential_edit.php" data-ajax-url="ajax/ajax_credential_edit.php"
data-ajax-id="<?php echo $login_id; ?>" data-ajax-id="<?php echo $credential_id; ?>"
> >
<div class="media"> <div class="media">
<i class="fa fa-fw fa-2x fa-key mr-3"></i> <i class="fa fa-fw fa-2x fa-key mr-3"></i>
<div class="media-body"> <div class="media-body">
<div><?php echo $login_name; ?></div> <div><?php echo $credential_name; ?></div>
<div><small class="text-secondary"><?php echo $login_description; ?></small></div> <div><small class="text-secondary"><?php echo $credential_description; ?></small></div>
<?php <?php
if (!empty($login_tags_display)) { ?> if (!empty($credential_tags_display)) { ?>
<div class="mt-1"> <div class="mt-1">
<?php echo $login_tags_display; ?> <?php echo $credential_tags_display; ?>
</div> </div>
<?php } ?> <?php } ?>
</div> </div>
</div> </div>
</a> </a>
</td> </td>
<td><?php echo $login_username_display; ?></td> <td><?php echo $credential_username_display; ?></td>
<td> <td>
<button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $login_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button><button class="btn btn-sm clipboardjs" type="button" data-clipboard-text="<?php echo $login_password; ?>"><i class="far fa-copy text-secondary"></i></button> <button class="btn p-0" type="button" data-toggle="popover" data-trigger="focus" data-placement="top" data-content="<?php echo $credential_password; ?>"><i class="fas fa-2x fa-ellipsis-h text-secondary"></i><i class="fas fa-2x fa-ellipsis-h text-secondary"></i></button><button class="btn btn-sm clipboardjs" type="button" data-clipboard-text="<?php echo $credential_password; ?>"><i class="far fa-copy text-secondary"></i></button>
</td> </td>
<td><?php echo $otp_display; ?></td> <td><?php echo $otp_display; ?></td>
<td><?php echo $login_uri_display; ?></td> <td><?php echo $credential_uri_display; ?></td>
<td> <td>
<?php echo "$login_contact_display$login_asset_display"; ?> <?php echo "$credential_contact_display$credential_asset_display"; ?>
<?php if (mysqli_num_rows($sql_shared) > 0) { ?> <?php if (mysqli_num_rows($sql_shared) > 0) { ?>
<div class="media" title="Expires <?php echo $item_expire_at_human; ?>"> <div class="media" title="Expires <?php echo $item_expire_at_human; ?>">
<i class="fas fa-link mr-2 mt-1"></i> <i class="fas fa-link mr-2 mt-1"></i>
@ -431,21 +431,21 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<?php } ?> <?php } ?>
<td class="text-center"> <td class="text-center">
<div class="btn-group"> <div class="btn-group">
<?php if ( !empty($login_uri) || !empty($login_uri_2) ) { ?> <?php if ( !empty($credential_uri) || !empty($credential_uri_2) ) { ?>
<div class="dropdown dropleft text-center"> <div class="dropdown dropleft text-center">
<button class="btn btn-default btn-sm" type="button" data-toggle="dropdown"> <button class="btn btn-default btn-sm" type="button" data-toggle="dropdown">
<i class="fa fa-fw fa-external-link-alt"></i> <i class="fa fa-fw fa-external-link-alt"></i>
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<?php if ($login_uri) { ?> <?php if ($credential_uri) { ?>
<a href="<?php echo $login_uri; ?>" alt="<?php echo $login_uri; ?>" target="_blank" class="dropdown-item" > <a href="<?php echo $credential_uri; ?>" alt="<?php echo $credential_uri; ?>" target="_blank" class="dropdown-item" >
<i class="fa fa-fw fa-external-link-alt"></i> <?php echo truncate($login_uri,40); ?> <i class="fa fa-fw fa-external-link-alt"></i> <?php echo truncate($credential_uri,40); ?>
</a> </a>
<?php } ?> <?php } ?>
<?php if ($login_uri_2) { ?> <?php if ($credential_uri_2) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a href="<?php echo $login_uri_2; ?>" target="_blank" class="dropdown-item" > <a href="<?php echo $credential_uri_2; ?>" target="_blank" class="dropdown-item" >
<i class="fa fa-fw fa-external-link-alt"></i> <?php echo truncate($login_uri_2,40); ?> <i class="fa fa-fw fa-external-link-alt"></i> <?php echo truncate($credential_uri_2,40); ?>
</a> </a>
<?php } ?> <?php } ?>
</div> </div>
@ -459,29 +459,29 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<a class="dropdown-item" href="#" <a class="dropdown-item" href="#"
data-toggle="ajax-modal" data-toggle="ajax-modal"
data-ajax-url="ajax/ajax_credential_edit.php" data-ajax-url="ajax/ajax_credential_edit.php"
data-ajax-id="<?php echo $login_id; ?>" data-ajax-id="<?php echo $credential_id; ?>"
> >
<i class="fas fa-fw fa-edit mr-2"></i>Edit <i class="fas fa-fw fa-edit mr-2"></i>Edit
</a> </a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'Login', $login_id"; ?>)"> <a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'Credential', $credential_id"; ?>)">
<i class="fas fa-fw fa-share mr-2"></i>Share <i class="fas fa-fw fa-share mr-2"></i>Share
</a> </a>
<?php if (lookupUserPermission("module_credential") >= 2) { ?> <?php if (lookupUserPermission("module_credential") >= 2) { ?>
<?php if ($login_archived_at) { ?> <?php if ($credential_archived_at) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-info confirm-link" href="post.php?unarchive_login=<?php echo $login_id; ?>"> <a class="dropdown-item text-info confirm-link" href="post.php?unarchive_credential=<?php echo $credential_id; ?>">
<i class="fas fa-fw fa-redo mr-2"></i>Unarchive <i class="fas fa-fw fa-redo mr-2"></i>Unarchive
</a> </a>
<?php if (lookupUserPermission("module_credential") >= 3) { ?> <?php if (lookupUserPermission("module_credential") >= 3) { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_login=<?php echo $login_id; ?>"> <a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_credential=<?php echo $credential_id; ?>">
<i class="fas fa-fw fa-trash mr-2"></i>Delete <i class="fas fa-fw fa-trash mr-2"></i>Delete
<?php } ?> <?php } ?>
</a> </a>
<?php } else { ?> <?php } else { ?>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_login=<?php echo $login_id; ?>"> <a class="dropdown-item text-danger confirm-link" href="post.php?archive_credential=<?php echo $credential_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive <i class="fas fa-fw fa-archive mr-2"></i>Archive
</a> </a>
<?php } ?> <?php } ?>

View File

@ -73,11 +73,6 @@ $sql_years_select = mysqli_query($mysqli, "
<?php <?php
if ($user_config_dashboard_financial_enable == 1) { if ($user_config_dashboard_financial_enable == 1) {
// Ensure the user has the appropriate role to view the financial dashboard
if ($_SESSION['user_role'] != 3 && $_SESSION['user_role'] != 1) {
exit('<script type="text/javascript">window.location.href = \'dashboard_technical.php\';</script>');
}
// Fetch financial data for the dashboard // Fetch financial data for the dashboard
// Define variables to avoid errors in logs // Define variables to avoid errors in logs
$largest_income_month = 0; $largest_income_month = 0;
@ -129,11 +124,11 @@ if ($user_config_dashboard_financial_enable == 1) {
"); ");
// Get recurring invoice totals // Get recurring invoice totals
$sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_amount) AS recurring_yearly_total FROM recurring WHERE recurring_status = 1 AND recurring_frequency = 'year' AND YEAR(recurring_created_at) <= $year"); $sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_yearly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'year' AND YEAR(recurring_invoice_created_at) <= $year");
$row = mysqli_fetch_array($sql_recurring_yearly_total); $row = mysqli_fetch_array($sql_recurring_yearly_total);
$recurring_yearly_total = floatval($row['recurring_yearly_total']); $recurring_yearly_total = floatval($row['recurring_yearly_total']);
$sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_amount) AS recurring_monthly_total FROM recurring WHERE recurring_status = 1 AND recurring_frequency = 'month' AND YEAR(recurring_created_at) <= $year"); $sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_monthly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'month' AND YEAR(recurring_invoice_created_at) <= $year");
$row = mysqli_fetch_array($sql_recurring_monthly_total); $row = mysqli_fetch_array($sql_recurring_monthly_total);
$recurring_monthly_total = floatval($row['recurring_monthly_total']) + ($recurring_yearly_total / 12); $recurring_monthly_total = floatval($row['recurring_monthly_total']) + ($recurring_yearly_total / 12);

View File

@ -2423,10 +2423,974 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.7'"); mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.7'");
} }
// if (CURRENT_DATABASE_VERSION == '1.8.7') { if (CURRENT_DATABASE_VERSION == '1.8.7') {
// // Insert queries here required to update to DB version 1.8.8 mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_first_response_at` DATETIME NULL DEFAULT NULL AFTER `ticket_archived_at`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.8'");
}
if (CURRENT_DATABASE_VERSION == '1.8.8') {
mysqli_query($mysqli, "ALTER TABLE `invoices` ADD `invoice_recurring_invoice_id` INT(11) NOT NULL DEFAULT 0 AFTER `invoice_category_id`");
mysqli_query($mysqli, "ALTER TABLE `invoice_items` ADD `item_product_id` INT(11) NOT NULL DEFAULT 0 AFTER `item_tax_id`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.9'");
}
if (CURRENT_DATABASE_VERSION == '1.8.9') {
mysqli_query($mysqli, "ALTER TABLE `users` ADD `user_role_id` INT(11) DEFAULT 0 AFTER `user_archived_at`");
// Copy user role from user settings table to the users table
mysqli_query($mysqli,"
UPDATE `users`
JOIN `user_settings` ON users.user_id = user_settings.user_id
SET users.user_role_id = user_settings.user_role
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.9.0'");
}
if (CURRENT_DATABASE_VERSION == '1.9.0') {
mysqli_query($mysqli, "ALTER TABLE `user_settings` DROP `user_role`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.9.1'");
}
if (CURRENT_DATABASE_VERSION == '1.9.1') {
mysqli_query($mysqli,
"ALTER TABLE `user_roles`
CHANGE COLUMN `user_role_id` `role_id` INT(11) NOT NULL AUTO_INCREMENT,
CHANGE COLUMN `user_role_name` `role_name` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
CHANGE COLUMN `user_role_description` `role_description` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `user_role_type` `role_type` TINYINT(1) NOT NULL DEFAULT 1,
CHANGE COLUMN `user_role_is_admin` `role_is_admin` TINYINT(1) NOT NULL DEFAULT 0,
CHANGE COLUMN `user_role_created_at` `role_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(),
CHANGE COLUMN `user_role_updated_at` `role_updated_at` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(),
CHANGE COLUMN `user_role_archived_at` `role_archived_at` DATETIME NULL DEFAULT NULL
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.9.2'");
}
if (CURRENT_DATABASE_VERSION == '1.9.2') {
mysqli_query($mysqli, "RENAME TABLE `user_permissions` TO `user_client_permissions`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.9.3'");
}
if (CURRENT_DATABASE_VERSION == '1.9.3') {
// Now create the table with foreign keys
mysqli_query($mysqli, "
CREATE TABLE `ticket_assets` (
`ticket_id` INT(11) NOT NULL,
`asset_id` INT(11) NOT NULL,
PRIMARY KEY (`ticket_id`, `asset_id`),
FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE,
FOREIGN KEY (`ticket_id`) REFERENCES `tickets`(`ticket_id`) ON DELETE CASCADE
)
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.9.4'");
}
if (CURRENT_DATABASE_VERSION == '1.9.4') {
mysqli_query($mysqli, "RENAME TABLE `scheduled_tickets` TO `recurring_tickets`");
mysqli_query($mysqli,
"ALTER TABLE `recurring_tickets`
CHANGE COLUMN `scheduled_ticket_id` `recurring_ticket_id` INT(11) NOT NULL AUTO_INCREMENT,
CHANGE COLUMN `scheduled_ticket_category` `recurring_ticket_category` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `scheduled_ticket_subject` `recurring_ticket_subject` VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
CHANGE COLUMN `scheduled_ticket_details` `recurring_ticket_details` LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
CHANGE COLUMN `scheduled_ticket_priority` `recurring_ticket_priority` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `scheduled_ticket_frequency` `recurring_ticket_frequency` VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
CHANGE COLUMN `scheduled_ticket_billable` `recurring_ticket_billable` TINYINT(1) NOT NULL DEFAULT 0,
CHANGE COLUMN `scheduled_ticket_start_date` `recurring_ticket_start_date` DATE NOT NULL,
CHANGE COLUMN `scheduled_ticket_next_run` `recurring_ticket_next_run` DATE NOT NULL,
CHANGE COLUMN `scheduled_ticket_created_at` `recurring_ticket_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(),
CHANGE COLUMN `scheduled_ticket_updated_at` `recurring_ticket_updated_at` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(),
CHANGE COLUMN `scheduled_ticket_created_by` `recurring_ticket_created_by` INT(11) NOT NULL DEFAULT 0,
CHANGE COLUMN `scheduled_ticket_assigned_to` `recurring_ticket_assigned_to` INT(11) NOT NULL DEFAULT 0,
CHANGE COLUMN `scheduled_ticket_client_id` `recurring_ticket_client_id` INT(11) NOT NULL DEFAULT 0,
CHANGE COLUMN `scheduled_ticket_contact_id` `recurring_ticket_contact_id` INT(11) NOT NULL DEFAULT 0,
CHANGE COLUMN `scheduled_ticket_asset_id` `recurring_ticket_asset_id` INT(11) NOT NULL DEFAULT 0
"
);
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.9.5'");
}
if (CURRENT_DATABASE_VERSION == '1.9.5') {
// create the table with foreign keys
mysqli_query($mysqli, "
CREATE TABLE `recurring_ticket_assets` (
`recurring_ticket_id` INT(11) NOT NULL,
`asset_id` INT(11) NOT NULL,
PRIMARY KEY (`recurring_ticket_id`, `asset_id`),
FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE,
FOREIGN KEY (`recurring_ticket_id`) REFERENCES `recurring_tickets`(`recurring_ticket_id`) ON DELETE CASCADE
)
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.9.6'");
}
if (CURRENT_DATABASE_VERSION == '1.9.6') {
mysqli_query($mysqli, "RENAME TABLE `recurring` TO `recurring_invoices`");
mysqli_query($mysqli, "
ALTER TABLE `recurring_invoices`
CHANGE COLUMN `recurring_id` `recurring_invoice_id` INT(11) NOT NULL AUTO_INCREMENT,
CHANGE COLUMN `recurring_prefix` `recurring_invoice_prefix` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `recurring_number` `recurring_invoice_number` INT(11) NOT NULL,
CHANGE COLUMN `recurring_scope` `recurring_invoice_scope` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `recurring_frequency` `recurring_invoice_frequency` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
CHANGE COLUMN `recurring_last_sent` `recurring_invoice_last_sent` DATE NULL DEFAULT NULL,
CHANGE COLUMN `recurring_next_date` `recurring_invoice_next_date` DATE NOT NULL,
CHANGE COLUMN `recurring_status` `recurring_invoice_status` INT(1) NOT NULL,
CHANGE COLUMN `recurring_discount_amount` `recurring_invoice_discount_amount` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
CHANGE COLUMN `recurring_amount` `recurring_invoice_amount` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
CHANGE COLUMN `recurring_currency_code` `recurring_invoice_currency_code` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
CHANGE COLUMN `recurring_note` `recurring_invoice_note` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `recurring_created_at` `recurring_invoice_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(),
CHANGE COLUMN `recurring_updated_at` `recurring_invoice_updated_at` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(),
CHANGE COLUMN `recurring_archived_at` `recurring_invoice_archived_at` DATETIME NULL DEFAULT NULL,
CHANGE COLUMN `recurring_category_id` `recurring_invoice_category_id` INT(11) NOT NULL,
CHANGE COLUMN `recurring_client_id` `recurring_invoice_client_id` INT(11) NOT NULL
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.9.7'");
}
if (CURRENT_DATABASE_VERSION == '1.9.7') {
mysqli_query($mysqli, "
ALTER TABLE `settings`
CHANGE COLUMN `config_recurring_prefix` `config_recurring_invoice_prefix` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `config_recurring_next_number` `config_recurring_invoice_next_number` INT(11) NOT NULL DEFAULT 1
");
mysqli_query($mysqli, "
ALTER TABLE `history`
CHANGE COLUMN `history_recurring_id` `history_recurring_invoice_id` INT(11) NOT NULL DEFAULT 0
");
mysqli_query($mysqli, "
ALTER TABLE `invoice_items`
CHANGE COLUMN `item_recurring_id` `item_recurring_invoice_id` INT(11) NOT NULL DEFAULT 0
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.9.8'");
}
if (CURRENT_DATABASE_VERSION == '1.9.8') {
// Reference a Recurring Ticket that generated ticket
mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_recurring_ticket_id` INT(11) DEFAULT 0 AFTER `ticket_project_id`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.9.9'");
}
if (CURRENT_DATABASE_VERSION == '1.9.9') {
mysqli_query($mysqli, "RENAME TABLE `logins` TO `credentials`");
mysqli_query($mysqli, "
ALTER TABLE `credentials`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL AUTO_INCREMENT,
CHANGE COLUMN `login_name` `credential_name` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
CHANGE COLUMN `login_description` `credential_description` VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_category` `credential_category` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_uri` `credential_uri` VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_uri_2` `credential_uri_2` VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_username` `credential_username` VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_password` `credential_password` VARBINARY(200) NULL DEFAULT NULL,
CHANGE COLUMN `login_otp_secret` `credential_otp_secret` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_note` `credential_note` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_important` `credential_important` TINYINT(1) NOT NULL DEFAULT '0',
CHANGE COLUMN `login_created_at` `credential_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(),
CHANGE COLUMN `login_updated_at` `credential_updated_at` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(),
CHANGE COLUMN `login_archived_at` `credential_archived_at` DATETIME NULL DEFAULT NULL,
CHANGE COLUMN `login_accessed_at` `credential_accessed_at` DATETIME NULL DEFAULT NULL,
CHANGE COLUMN `login_password_changed_at` `credential_password_changed_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP(),
CHANGE COLUMN `login_folder_id` `credential_folder_id` INT(11) NOT NULL DEFAULT '0',
CHANGE COLUMN `login_contact_id` `credential_contact_id` INT(11) NOT NULL DEFAULT '0',
CHANGE COLUMN `login_asset_id` `credential_asset_id` INT(11) NOT NULL DEFAULT '0',
CHANGE COLUMN `login_client_id` `credential_client_id` INT(11) NOT NULL DEFAULT '0'
");
// Rename table contact_logins to contact_credentials
mysqli_query($mysqli, "RENAME TABLE `contact_logins` TO `contact_credentials`");
// Alter contact_credentials table and change login_id to credential_id
mysqli_query($mysqli, "
ALTER TABLE `contact_credentials`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL
");
// Clean up orphaned contact_id rows in contact_credentials
mysqli_query($mysqli, "
DELETE FROM `contact_credentials`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
// Clean up orphaned credential_id rows in contact_credentials
mysqli_query($mysqli, "
DELETE FROM `contact_credentials`
WHERE `credential_id` NOT IN (SELECT `credential_id` FROM `credentials`);
");
// Add foreign keys to contact_credentials
mysqli_query($mysqli, "
ALTER TABLE `contact_credentials`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE
");
// Rename table service_logins to service_credentials
mysqli_query($mysqli, "RENAME TABLE `service_logins` TO `service_credentials`");
// Alter service_credentials table and change login_id to credential_id
mysqli_query($mysqli, "
ALTER TABLE `service_credentials`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL
");
// Clean up orphaned service_id rows in service_credentials
mysqli_query($mysqli, "
DELETE FROM `service_credentials`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
// Clean up orphaned credential_id rows in service_credentials
mysqli_query($mysqli, "
DELETE FROM `service_credentials`
WHERE `credential_id` NOT IN (SELECT `credential_id` FROM `credentials`);
");
// Add foreign keys to service_credentials
mysqli_query($mysqli, "
ALTER TABLE `service_credentials`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE
");
// Rename table software_logins to software_credentials
mysqli_query($mysqli, "RENAME TABLE `software_logins` TO `software_credentials`");
// Alter software_credentials table and change login_id to credential_id
mysqli_query($mysqli, "
ALTER TABLE `software_credentials`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL
");
// Clean up orphaned software_id rows in software_credentials
mysqli_query($mysqli, "
DELETE FROM `software_credentials`
WHERE `software_id` NOT IN (SELECT `software_id` FROM `software`);
");
// Clean up orphaned credential_id rows in software_credentials
mysqli_query($mysqli, "
DELETE FROM `software_credentials`
WHERE `credential_id` NOT IN (SELECT `credential_id` FROM `credentials`);
");
// Add foreign keys to software_credentials
mysqli_query($mysqli, "
ALTER TABLE `software_credentials`
ADD FOREIGN KEY (`software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE
");
// Rename table vendor_logins to vendor_credentials
mysqli_query($mysqli, "RENAME TABLE `vendor_logins` TO `vendor_credentials`");
// Alter vendor_credentials table and change login_id to credential_id
mysqli_query($mysqli, "
ALTER TABLE `vendor_credentials`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL
");
// Clean up orphaned vendor_id rows in vendor_credentials
mysqli_query($mysqli, "
DELETE FROM `vendor_credentials`
WHERE `vendor_id` NOT IN (SELECT `vendor_id` FROM `vendors`);
");
// Clean up orphaned credential_id rows in vendor_credentials
mysqli_query($mysqli, "
DELETE FROM `vendor_credentials`
WHERE `credential_id` NOT IN (SELECT `credential_id` FROM `credentials`);
");
// Add foreign keys to vendor_credentials
mysqli_query($mysqli, "
ALTER TABLE `vendor_credentials`
ADD FOREIGN KEY (`vendor_id`) REFERENCES `vendors`(`vendor_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE
");
// Rename table login_tags to credential_tags
mysqli_query($mysqli, "RENAME TABLE `login_tags` TO `credential_tags`");
// Alter credential_tags table and change login_id to credential_id
mysqli_query($mysqli, "
ALTER TABLE `credential_tags`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL
");
// Clean up orphaned tag_id rows in credential_tags
mysqli_query($mysqli, "
DELETE FROM `credential_tags`
WHERE `tag_id` NOT IN (SELECT `tag_id` FROM `tags`);
");
// Clean up orphaned credential_id rows in credential_tags
mysqli_query($mysqli, "
DELETE FROM `credential_tags`
WHERE `credential_id` NOT IN (SELECT `credential_id` FROM `credentials`);
");
// Add foreign keys to credential_tags
mysqli_query($mysqli, "
ALTER TABLE `credential_tags`
ADD FOREIGN KEY (`tag_id`) REFERENCES `tags`(`tag_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE
");
// Create asset_credentials table with foreign keys
mysqli_query($mysqli, "
CREATE TABLE `asset_credentials` (
`credential_id` INT(11) NOT NULL,
`asset_id` INT(11) NOT NULL,
PRIMARY KEY (`credential_id`, `asset_id`),
FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE,
FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
)
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.0.0'");
}
if (CURRENT_DATABASE_VERSION == '2.0.0') {
//Dropping patch panel as a patch panel can be documented as an asset with interfaces.
mysqli_query($mysqli, "DROP TABLE `patch_panel_ports`");
mysqli_query($mysqli, "DROP TABLE `patch_panels`");
mysqli_query($mysqli, "RENAME TABLE `events` TO `calendar_events`");
mysqli_query($mysqli, "RENAME TABLE `event_attendees` TO `calendar_event_attendees`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.0.1'");
}
if (CURRENT_DATABASE_VERSION == '2.0.1') {
// Clean up orphaned data before adding foreign keys
// Clean up orphaned asset_custom_asset_id rows in asset_custom
mysqli_query($mysqli, "
DELETE FROM `asset_custom`
WHERE `asset_custom_asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign key to asset_custom
mysqli_query($mysqli, "
ALTER TABLE `asset_custom`
ADD FOREIGN KEY (`asset_custom_asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned asset_id rows in asset_documents
mysqli_query($mysqli, "
DELETE FROM `asset_documents`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Clean up orphaned document_id rows in asset_documents
mysqli_query($mysqli, "
DELETE FROM `asset_documents`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
// Add foreign keys to asset_documents
mysqli_query($mysqli, "
ALTER TABLE `asset_documents`
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE
");
// Clean up orphaned asset_id rows in asset_files
mysqli_query($mysqli, "
DELETE FROM `asset_files`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Clean up orphaned file_id rows in asset_files
mysqli_query($mysqli, "
DELETE FROM `asset_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign keys to asset_files
mysqli_query($mysqli, "
ALTER TABLE `asset_files`
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");
// Clean up orphaned asset_history_asset_id rows in asset_history
mysqli_query($mysqli, "
DELETE FROM `asset_history`
WHERE `asset_history_asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign key to asset_history
mysqli_query($mysqli, "
ALTER TABLE `asset_history`
ADD FOREIGN KEY (`asset_history_asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned interface_asset_id rows in asset_interfaces
mysqli_query($mysqli, "
DELETE FROM `asset_interfaces`
WHERE `interface_asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign key to asset_interfaces
mysqli_query($mysqli, "
ALTER TABLE `asset_interfaces`
ADD FOREIGN KEY (`interface_asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned asset_note_asset_id rows in asset_notes
mysqli_query($mysqli, "
DELETE FROM `asset_notes`
WHERE `asset_note_asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign key to asset_notes
mysqli_query($mysqli, "
ALTER TABLE `asset_notes`
ADD FOREIGN KEY (`asset_note_asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned contact_id rows in contact_assets
mysqli_query($mysqli, "
DELETE FROM `contact_assets`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
// Clean up orphaned asset_id rows in contact_assets
mysqli_query($mysqli, "
DELETE FROM `contact_assets`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign keys to contact_assets
mysqli_query($mysqli, "
ALTER TABLE `contact_assets`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned service_id rows in service_assets
mysqli_query($mysqli, "
DELETE FROM `service_assets`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
// Clean up orphaned asset_id rows in service_assets
mysqli_query($mysqli, "
DELETE FROM `service_assets`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign keys to service_assets
mysqli_query($mysqli, "
ALTER TABLE `service_assets`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned software_id rows in software_assets
mysqli_query($mysqli, "
DELETE FROM `software_assets`
WHERE `software_id` NOT IN (SELECT `software_id` FROM `software`);
");
// Clean up orphaned asset_id rows in software_assets
mysqli_query($mysqli, "
DELETE FROM `software_assets`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign keys to software_assets
mysqli_query($mysqli, "
ALTER TABLE `software_assets`
ADD FOREIGN KEY (`software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.0.2'");
}
if (CURRENT_DATABASE_VERSION == '2.0.2') {
// Clean up orphans
mysqli_query($mysqli, "
DELETE FROM `calendar_event_attendees`
WHERE `attendee_event_id` NOT IN (SELECT `event_id` FROM `calendar_events`);
");
mysqli_query($mysqli, "
DELETE FROM `calendar_events`
WHERE `event_calendar_id` NOT IN (SELECT `calendar_id` FROM `calendars`);
");
// Add foreign key to calendar_event_attendees
mysqli_query($mysqli, "
ALTER TABLE `calendar_event_attendees`
ADD FOREIGN KEY (`attendee_event_id`) REFERENCES `calendar_events`(`event_id`) ON DELETE CASCADE
");
// Add foreign key to calendar_events
mysqli_query($mysqli, "
ALTER TABLE `calendar_events`
ADD FOREIGN KEY (`event_calendar_id`) REFERENCES `calendars`(`calendar_id`) ON DELETE CASCADE
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.0.3'");
}
if (CURRENT_DATABASE_VERSION == '2.0.3') {
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `certificate_history`
WHERE `certificate_history_certificate_id` NOT IN (SELECT `certificate_id` FROM `certificates`);
");
// Add foreign key certificate history
mysqli_query($mysqli, "
ALTER TABLE `certificate_history`
ADD FOREIGN KEY (`certificate_history_certificate_id`) REFERENCES `certificates`(`certificate_id`) ON DELETE CASCADE
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.0.4'");
}
if (CURRENT_DATABASE_VERSION == '2.0.4') {
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `client_notes`
WHERE `client_note_client_id` NOT IN (SELECT `client_id` FROM `clients`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `client_notes`
ADD FOREIGN KEY (`client_note_client_id`) REFERENCES `clients`(`client_id`) ON DELETE CASCADE
");
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `client_tags`
WHERE `client_id` NOT IN (SELECT `client_id` FROM `clients`);
");
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `client_tags`
WHERE `tag_id` NOT IN (SELECT `tag_id` FROM `tags`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `client_tags`
ADD FOREIGN KEY (`client_id`) REFERENCES `clients`(`client_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`tag_id`) REFERENCES `tags`(`tag_id`) ON DELETE CASCADE
");
//Contact Assets
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `contact_assets`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
mysqli_query($mysqli, "
DELETE FROM `contact_assets`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `contact_assets`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Contact Documents
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `contact_documents`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
mysqli_query($mysqli, "
DELETE FROM `contact_documents`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `contact_documents`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE
");
// contact_files
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `contact_files`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
mysqli_query($mysqli, "
DELETE FROM `contact_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `contact_files`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");
// contact_notes
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `contact_notes`
WHERE `contact_note_contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `contact_notes`
ADD FOREIGN KEY (`contact_note_contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE
");
// contact_tags
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `contact_tags`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
mysqli_query($mysqli, "
DELETE FROM `contact_tags`
WHERE `tag_id` NOT IN (SELECT `tag_id` FROM `tags`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `contact_tags`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`tag_id`) REFERENCES `tags`(`tag_id`) ON DELETE CASCADE
");
// document_files
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `document_files`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
mysqli_query($mysqli, "
DELETE FROM `document_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `document_files`
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");
// domain_history
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `domain_history`
WHERE `domain_history_domain_id` NOT IN (SELECT `domain_id` FROM `domains`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `domain_history`
ADD FOREIGN KEY (`domain_history_domain_id`) REFERENCES `domains`(`domain_id`) ON DELETE CASCADE
");
// location_tags
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `location_tags`
WHERE `location_id` NOT IN (SELECT `location_id` FROM `locations`);
");
mysqli_query($mysqli, "
DELETE FROM `location_tags`
WHERE `tag_id` NOT IN (SELECT `tag_id` FROM `tags`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `location_tags`
ADD FOREIGN KEY (`location_id`) REFERENCES `locations`(`location_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`tag_id`) REFERENCES `tags`(`tag_id`) ON DELETE CASCADE
");
// quote_files
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `quote_files`
WHERE `quote_id` NOT IN (SELECT `quote_id` FROM `quotes`);
");
mysqli_query($mysqli, "
DELETE FROM `quote_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `quote_files`
ADD FOREIGN KEY (`quote_id`) REFERENCES `quotes`(`quote_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");
// service_certificates
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `service_certificates`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
mysqli_query($mysqli, "
DELETE FROM `service_certificates`
WHERE `certificate_id` NOT IN (SELECT `certificate_id` FROM `certificates`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `service_certificates`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`certificate_id`) REFERENCES `certificates`(`certificate_id`) ON DELETE CASCADE
");
// service_contacts
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `service_contacts`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
mysqli_query($mysqli, "
DELETE FROM `service_contacts`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `service_contacts`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE
");
// service_documents
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `service_documents`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
mysqli_query($mysqli, "
DELETE FROM `service_documents`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `service_documents`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE
");
// service_domains
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `service_domains`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
mysqli_query($mysqli, "
DELETE FROM `service_domains`
WHERE `domain_id` NOT IN (SELECT `domain_id` FROM `domains`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `service_domains`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`domain_id`) REFERENCES `domains`(`domain_id`) ON DELETE CASCADE
");
// service_vendors
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `service_vendors`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
mysqli_query($mysqli, "
DELETE FROM `service_vendors`
WHERE `vendor_id` NOT IN (SELECT `vendor_id` FROM `vendors`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `service_vendors`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`vendor_id`) REFERENCES `vendors`(`vendor_id`) ON DELETE CASCADE
");
// software_contacts
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `software_contacts`
WHERE `software_id` NOT IN (SELECT `software_id` FROM `software`);
");
mysqli_query($mysqli, "
DELETE FROM `software_contacts`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `software_contacts`
ADD FOREIGN KEY (`software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE
");
// software_documents
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `software_documents`
WHERE `software_id` NOT IN (SELECT `software_id` FROM `software`);
");
mysqli_query($mysqli, "
DELETE FROM `software_documents`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `software_documents`
ADD FOREIGN KEY (`software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE
");
// software_files
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `software_files`
WHERE `software_id` NOT IN (SELECT `software_id` FROM `software`);
");
mysqli_query($mysqli, "
DELETE FROM `software_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `software_files`
ADD FOREIGN KEY (`software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");
// vendor_documents
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `vendor_documents`
WHERE `vendor_id` NOT IN (SELECT `vendor_id` FROM `vendors`);
");
mysqli_query($mysqli, "
DELETE FROM `vendor_documents`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `vendor_documents`
ADD FOREIGN KEY (`vendor_id`) REFERENCES `vendors`(`vendor_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE
");
// vendor_files
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `vendor_files`
WHERE `vendor_id` NOT IN (SELECT `vendor_id` FROM `vendors`);
");
mysqli_query($mysqli, "
DELETE FROM `vendor_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `vendor_files`
ADD FOREIGN KEY (`vendor_id`) REFERENCES `vendors`(`vendor_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.0.5'");
}
if (CURRENT_DATABASE_VERSION == '2.0.5') {
// CONVERT All tables TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
$tables = [
'accounts', 'api_keys', 'app_logs', 'asset_credentials', 'asset_custom', 'asset_documents',
'asset_files', 'asset_history', 'asset_interface_links', 'asset_interfaces', 'asset_notes', 'assets',
'auth_logs', 'budget', 'calendar_event_attendees', 'calendar_events', 'calendars', 'categories',
'certificate_history', 'certificates', 'client_notes', 'client_stripe', 'client_tags', 'clients',
'companies', 'contact_assets', 'contact_credentials', 'contact_documents', 'contact_files', 'contact_notes',
'contact_tags', 'contacts', 'credential_tags', 'credentials', 'custom_fields', 'custom_links',
'custom_values', 'document_files', 'documents', 'domain_history', 'domains', 'email_queue', 'expenses',
'files', 'folders', 'history', 'invoice_items', 'invoices', 'location_tags', 'locations', 'logs',
'modules', 'networks', 'notifications', 'payments', 'products', 'project_template_ticket_templates',
'project_templates', 'projects', 'quote_files', 'quotes', 'rack_units', 'racks', 'records',
'recurring_expenses', 'recurring_invoices', 'recurring_payments', 'recurring_ticket_assets', 'recurring_tickets',
'remember_tokens', 'revenues', 'service_assets', 'service_certificates', 'service_contacts', 'service_credentials',
'service_documents', 'service_domains', 'service_vendors', 'services', 'settings', 'shared_items',
'software', 'software_assets', 'software_contacts', 'software_credentials', 'software_documents', 'software_files',
'tags', 'task_templates', 'tasks', 'taxes', 'ticket_assets', 'ticket_attachments', 'ticket_history', 'ticket_replies',
'ticket_statuses', 'ticket_templates', 'ticket_views', 'ticket_watchers', 'tickets', 'transfers', 'trips',
'user_client_permissions', 'user_role_permissions', 'user_roles', 'user_settings', 'users', 'vendor_credentials',
'vendor_documents', 'vendor_files', 'vendors'
];
foreach ($tables as $table) {
$sql = "ALTER TABLE `$table` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;";
mysqli_query($mysqli, $sql);
}
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.0.6'");
}
if (CURRENT_DATABASE_VERSION == '2.0.6') {
// Fix service_domains to yse InnoDB instead of MyISAM
mysqli_query($mysqli, "ALTER TABLE service_domains ENGINE = InnoDB;");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.0.7'");
}
if (CURRENT_DATABASE_VERSION == '2.0.7') {
mysqli_query($mysqli, "ALTER TABLE `files` DROP `file_hash`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.0.8'");
}
// if (CURRENT_DATABASE_VERSION == '2.0.8') {
// // Insert queries here required to update to DB version 2.0.9
// // Then, update the database to the next sequential version // // Then, update the database to the next sequential version
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.8'"); // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.0.9'");
// } // }
} else { } else {

1032
db.sql

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,7 @@ use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception; use PHPMailer\PHPMailer\Exception;
// Function to generate both crypto & URL safe random strings // Function to generate both crypto & URL safe random strings
function randomString($length = 16) function randomString($length = 16) {
{
// Generate some cryptographically safe random bytes // Generate some cryptographically safe random bytes
// Generate a little more than requested as we'll lose some later converting // Generate a little more than requested as we'll lose some later converting
$random_bytes = random_bytes($length + 5); $random_bytes = random_bytes($length + 5);
@ -31,8 +30,7 @@ function randomString($length = 16)
} }
// Older keygen function - only used for TOTP currently // Older keygen function - only used for TOTP currently
function key32gen() function key32gen() {
{
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$chars .= "234567"; $chars .= "234567";
while (1) { while (1) {
@ -46,25 +44,23 @@ function key32gen()
return $key; return $key;
} }
function nullable_htmlentities($unsanitizedInput) function nullable_htmlentities($unsanitizedInput) {
{
//return htmlentities($unsanitizedInput ?? ''); //return htmlentities($unsanitizedInput ?? '');
return htmlspecialchars($unsanitizedInput ?? '', ENT_QUOTES, 'UTF-8'); return htmlspecialchars($unsanitizedInput ?? '', ENT_QUOTES, 'UTF-8');
} }
function initials($str) function initials($string) {
{ if (!empty($string)) {
if (!empty($str)) { $return = '';
$ret = ''; foreach (explode(' ', $string) as $word) {
foreach (explode(' ', $str) as $word) $return .= mb_strtoupper($word[0], 'UTF-8'); // Use mb_strtoupper for UTF-8 support
$ret .= strtoupper($word[0]); }
$ret = substr($ret, 0, 2); $return = substr($return, 0, 2);
return $ret; return $return;
} }
} }
function removeDirectory($path) function removeDirectory($path) {
{
if (!file_exists($path)) { if (!file_exists($path)) {
return; return;
} }
@ -76,13 +72,11 @@ function removeDirectory($path)
rmdir($path); rmdir($path);
} }
function getUserAgent() function getUserAgent() {
{
return $_SERVER['HTTP_USER_AGENT']; return $_SERVER['HTTP_USER_AGENT'];
} }
function getIP() function getIP() {
{
if (defined("CONST_GET_IP_METHOD")) { if (defined("CONST_GET_IP_METHOD")) {
if (CONST_GET_IP_METHOD == "HTTP_X_FORWARDED_FOR") { if (CONST_GET_IP_METHOD == "HTTP_X_FORWARDED_FOR") {
$ip = getenv('HTTP_X_FORWARDED_FOR'); $ip = getenv('HTTP_X_FORWARDED_FOR');
@ -100,8 +94,7 @@ function getIP()
return $ip; return $ip;
} }
function getWebBrowser($user_browser) function getWebBrowser($user_browser) {
{
$browser = "-"; $browser = "-";
$browser_array = array( $browser_array = array(
'/msie/i' => "<i class='fab fa-fw fa-internet-explorer text-secondary'></i> Internet Explorer", '/msie/i' => "<i class='fab fa-fw fa-internet-explorer text-secondary'></i> Internet Explorer",
@ -120,8 +113,7 @@ function getWebBrowser($user_browser)
return $browser; return $browser;
} }
function getOS($user_os) function getOS($user_os) {
{
$os_platform = "-"; $os_platform = "-";
$os_array = array( $os_array = array(
'/windows/i' => "<i class='fab fa-fw fa-windows text-secondary'></i> Windows", '/windows/i' => "<i class='fab fa-fw fa-windows text-secondary'></i> Windows",
@ -141,8 +133,7 @@ function getOS($user_os)
return $os_platform; return $os_platform;
} }
function getDevice() function getDevice() {
{
$tablet_browser = 0; $tablet_browser = 0;
$mobile_browser = 0; $mobile_browser = 0;
if (preg_match('/(tablet|ipad|playbook)|(android(?!.*(mobi|opera mini)))/i', strtolower($_SERVER['HTTP_USER_AGENT']))) { if (preg_match('/(tablet|ipad|playbook)|(android(?!.*(mobi|opera mini)))/i', strtolower($_SERVER['HTTP_USER_AGENT']))) {
@ -189,8 +180,7 @@ function getDevice()
} }
} }
function truncate($text, $chars) function truncate($text, $chars) {
{
if (strlen($text) <= $chars) { if (strlen($text) <= $chars) {
return $text; return $text;
} }
@ -203,8 +193,7 @@ function truncate($text, $chars)
return $text . "..."; return $text . "...";
} }
function formatPhoneNumber($phoneNumber) function formatPhoneNumber($phoneNumber) {
{
global $mysqli; global $mysqli;
// Get Phone Mask Option // Get Phone Mask Option
@ -240,8 +229,7 @@ function formatPhoneNumber($phoneNumber)
return $phoneNumber; return $phoneNumber;
} }
function mkdirMissing($dir) function mkdirMissing($dir) {
{
if (!is_dir($dir)) { if (!is_dir($dir)) {
mkdir($dir); mkdir($dir);
} }
@ -249,8 +237,7 @@ function mkdirMissing($dir)
// Called during initial setup // Called during initial setup
// Encrypts the master key with the user's password // Encrypts the master key with the user's password
function setupFirstUserSpecificKey($user_password, $site_encryption_master_key) function setupFirstUserSpecificKey($user_password, $site_encryption_master_key) {
{
$iv = randomString(); $iv = randomString();
$salt = randomString(); $salt = randomString();
@ -268,8 +255,7 @@ function setupFirstUserSpecificKey($user_password, $site_encryption_master_key)
* New Users: Requires the admin setting up their account have a Specific/Session key configured * New Users: Requires the admin setting up their account have a Specific/Session key configured
* Password Changes: Will use the current info in the session. * Password Changes: Will use the current info in the session.
*/ */
function encryptUserSpecificKey($user_password) function encryptUserSpecificKey($user_password) {
{
$iv = randomString(); $iv = randomString();
$salt = randomString(); $salt = randomString();
@ -334,13 +320,13 @@ function generateUserSessionKey($site_encryption_master_key)
} }
} }
// Decrypts an encrypted password (website/asset login), returns it as a string // Decrypts an encrypted password (website/asset credentials), returns it as a string
function decryptLoginEntry($login_password_ciphertext) function decryptCredentialEntry($credential_password_ciphertext)
{ {
// Split the login into IV and Ciphertext // Split the credential into IV and Ciphertext
$login_iv = substr($login_password_ciphertext, 0, 16); $credential_iv = substr($credential_password_ciphertext, 0, 16);
$login_ciphertext = $salt = substr($login_password_ciphertext, 16); $credential_ciphertext = $salt = substr($credential_password_ciphertext, 16);
// Get the user session info. // Get the user session info.
$user_encryption_session_ciphertext = $_SESSION['user_encryption_session_ciphertext']; $user_encryption_session_ciphertext = $_SESSION['user_encryption_session_ciphertext'];
@ -350,12 +336,12 @@ function decryptLoginEntry($login_password_ciphertext)
// Decrypt the session key to get the master key // Decrypt the session key to get the master key
$site_encryption_master_key = openssl_decrypt($user_encryption_session_ciphertext, 'aes-128-cbc', $user_encryption_session_key, 0, $user_encryption_session_iv); $site_encryption_master_key = openssl_decrypt($user_encryption_session_ciphertext, 'aes-128-cbc', $user_encryption_session_key, 0, $user_encryption_session_iv);
// Decrypt the login password using the master key // Decrypt the credential password using the master key
return openssl_decrypt($login_ciphertext, 'aes-128-cbc', $site_encryption_master_key, 0, $login_iv); return openssl_decrypt($credential_ciphertext, 'aes-128-cbc', $site_encryption_master_key, 0, $credential_iv);
} }
// Encrypts a website/asset login password // Encrypts a website/asset credential password
function encryptLoginEntry($login_password_cleartext) function encryptCredentialEntry($credential_password_cleartext)
{ {
$iv = randomString(); $iv = randomString();
@ -367,26 +353,26 @@ function encryptLoginEntry($login_password_cleartext)
//Decrypt the session key to get the master key //Decrypt the session key to get the master key
$site_encryption_master_key = openssl_decrypt($user_encryption_session_ciphertext, 'aes-128-cbc', $user_encryption_session_key, 0, $user_encryption_session_iv); $site_encryption_master_key = openssl_decrypt($user_encryption_session_ciphertext, 'aes-128-cbc', $user_encryption_session_key, 0, $user_encryption_session_iv);
//Encrypt the website/asset login using the master key //Encrypt the website/asset credential using the master key
$ciphertext = openssl_encrypt($login_password_cleartext, 'aes-128-cbc', $site_encryption_master_key, 0, $iv); $ciphertext = openssl_encrypt($credential_password_cleartext, 'aes-128-cbc', $site_encryption_master_key, 0, $iv);
return $iv . $ciphertext; return $iv . $ciphertext;
} }
function apiDecryptLoginEntry($login_ciphertext, $api_key_decrypt_hash, #[\SensitiveParameter]$api_key_decrypt_password) function apiDecryptCredentialEntry($credential_ciphertext, $api_key_decrypt_hash, #[\SensitiveParameter]$api_key_decrypt_password)
{ {
// Split the login entry (username/password) into IV and Ciphertext // Split the Credential entry (username/password) into IV and Ciphertext
$login_iv = substr($login_ciphertext, 0, 16); $credential_iv = substr($credential_ciphertext, 0, 16);
$login_ciphertext = $salt = substr($login_ciphertext, 16); $credential_ciphertext = $salt = substr($credential_ciphertext, 16);
// Decrypt the api hash to get the master key // Decrypt the api hash to get the master key
$site_encryption_master_key = decryptUserSpecificKey($api_key_decrypt_hash, $api_key_decrypt_password); $site_encryption_master_key = decryptUserSpecificKey($api_key_decrypt_hash, $api_key_decrypt_password);
// Decrypt the login password using the master key // Decrypt the credential password using the master key
return openssl_decrypt($login_ciphertext, 'aes-128-cbc', $site_encryption_master_key, 0, $login_iv); return openssl_decrypt($credential_ciphertext, 'aes-128-cbc', $site_encryption_master_key, 0, $credential_iv);
} }
function apiEncryptLoginEntry(#[\SensitiveParameter]$credential_cleartext, $api_key_decrypt_hash, #[\SensitiveParameter]$api_key_decrypt_password) function apiEncryptCredentialEntry(#[\SensitiveParameter]$credential_cleartext, $api_key_decrypt_hash, #[\SensitiveParameter]$api_key_decrypt_password)
{ {
$iv = randomString(); $iv = randomString();
@ -539,9 +525,9 @@ function validateCSRFToken($token)
* Accountant - 1 * Accountant - 1
*/ */
function validateAdminRole() function validateAdminRole() {
{ global $session_user_role;
if (!isset($_SESSION['user_role']) || $_SESSION['user_role'] != 3) { if (!isset($session_user_role) || $session_user_role != 3) {
$_SESSION['alert_type'] = "danger"; $_SESSION['alert_type'] = "danger";
$_SESSION['alert_message'] = WORDING_ROLECHECK_FAILED; $_SESSION['alert_message'] = WORDING_ROLECHECK_FAILED;
header("Location: " . $_SERVER["HTTP_REFERER"]); header("Location: " . $_SERVER["HTTP_REFERER"]);
@ -551,9 +537,9 @@ function validateAdminRole()
// LEGACY // LEGACY
// Validates a user is a tech (or admin). Stops page load and attempts to direct away from the page if not (i.e. user is an accountant) // Validates a user is a tech (or admin). Stops page load and attempts to direct away from the page if not (i.e. user is an accountant)
function validateTechRole() function validateTechRole() {
{ global $session_user_role;
if (!isset($_SESSION['user_role']) || $_SESSION['user_role'] == 1) { if (!isset($session_user_role) || $session_user_role == 1) {
$_SESSION['alert_type'] = "danger"; $_SESSION['alert_type'] = "danger";
$_SESSION['alert_message'] = WORDING_ROLECHECK_FAILED; $_SESSION['alert_message'] = WORDING_ROLECHECK_FAILED;
header("Location: " . $_SERVER["HTTP_REFERER"]); header("Location: " . $_SERVER["HTTP_REFERER"]);
@ -563,9 +549,9 @@ function validateTechRole()
// LEGACY // LEGACY
// Validates a user is an accountant (or admin). Stops page load and attempts to direct away from the page if not (i.e. user is a tech) // Validates a user is an accountant (or admin). Stops page load and attempts to direct away from the page if not (i.e. user is a tech)
function validateAccountantRole() function validateAccountantRole() {
{ global $session_user_role;
if (!isset($_SESSION['user_role']) || $_SESSION['user_role'] == 2) { if (!isset($session_user_role) || $session_user_role == 2) {
$_SESSION['alert_type'] = "danger"; $_SESSION['alert_type'] = "danger";
$_SESSION['alert_message'] = WORDING_ROLECHECK_FAILED; $_SESSION['alert_message'] = WORDING_ROLECHECK_FAILED;
header("Location: " . $_SERVER["HTTP_REFERER"]); header("Location: " . $_SERVER["HTTP_REFERER"]);
@ -765,7 +751,7 @@ function checkFileUpload($file, $allowed_extensions)
$fileContent = file_get_contents($tmp); $fileContent = file_get_contents($tmp);
// Hash the file content using SHA-256 // Hash the file content using SHA-256
$hashedContent = hash('sha256', $fileContent); $hashedContent = hash('md5', $fileContent);
// Generate a secure filename using the hashed content // Generate a secure filename using the hashed content
$secureFilename = $hashedContent . randomString(2) . '.' . $extension; $secureFilename = $hashedContent . randomString(2) . '.' . $extension;
@ -1313,15 +1299,15 @@ function lookupUserPermission($module) {
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT "SELECT
urp.user_role_permission_level user_role_permissions.user_role_permission_level
FROM FROM
modules AS m modules
JOIN JOIN
user_role_permissions AS urp user_role_permissions
ON ON
m.module_id = urp.module_id modules.module_id = user_role_permissions.module_id
WHERE WHERE
m.module_name = '$module' AND urp.user_role_id = $session_user_role" module_name = '$module' AND user_role_permissions.user_role_id = $session_user_role"
); );
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);

View File

@ -91,21 +91,21 @@ if (isset($_GET['query'])) {
ORDER BY ticket_id DESC LIMIT 5" ORDER BY ticket_id DESC LIMIT 5"
); );
$sql_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM scheduled_tickets $sql_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM recurring_tickets
LEFT JOIN clients ON scheduled_ticket_client_id = client_id LEFT JOIN clients ON recurring_ticket_client_id = client_id
WHERE (scheduled_ticket_subject LIKE '%$query%' WHERE (recurring_ticket_subject LIKE '%$query%'
OR scheduled_ticket_details LIKE '%$query%') OR recurring_ticket_details LIKE '%$query%')
$access_permission_query $access_permission_query
ORDER BY scheduled_ticket_id DESC LIMIT 5" ORDER BY recurring_ticket_id DESC LIMIT 5"
); );
$sql_logins = mysqli_query($mysqli, "SELECT * FROM logins $sql_credentials = mysqli_query($mysqli, "SELECT * FROM credentials
LEFT JOIN contacts ON login_contact_id = contact_id LEFT JOIN contacts ON credential_contact_id = contact_id
LEFT JOIN clients ON login_client_id = client_id LEFT JOIN clients ON credential_client_id = client_id
WHERE login_archived_at IS NULL WHERE credential_archived_at IS NULL
AND (login_name LIKE '%$query%' OR login_description LIKE '%$query%') AND (credential_name LIKE '%$query%' OR credential_description LIKE '%$query%')
$access_permission_query $access_permission_query
ORDER BY login_id DESC LIMIT 5" ORDER BY credential_id DESC LIMIT 5"
); );
$sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices $sql_invoices = mysqli_query($mysqli, "SELECT * FROM invoices
@ -544,18 +544,18 @@ if (isset($_GET['query'])) {
<?php <?php
while ($row = mysqli_fetch_array($sql_recurring_tickets)) { while ($row = mysqli_fetch_array($sql_recurring_tickets)) {
$scheduled_ticket_id = intval($row['scheduled_ticket_id']); $recurring_ticket_id = intval($row['recurring_ticket_id']);
$scheduled_ticket_subject = nullable_htmlentities($row['scheduled_ticket_subject']); $recurring_ticket_subject = nullable_htmlentities($row['recurring_ticket_subject']);
$scheduled_ticket_frequency = nullable_htmlentities($row['scheduled_ticket_frequency']); $recurring_ticket_frequency = nullable_htmlentities($row['recurring_ticket_frequency']);
$scheduled_ticket_next_run = nullable_htmlentities($row['scheduled_ticket_next_run']); $recurring_ticket_next_run = nullable_htmlentities($row['recurring_ticket_next_run']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
?> ?>
<tr> <tr>
<td><a href="recurring_tickets.php"><?php echo $scheduled_ticket_subject; ?></a></td> <td><a href="recurring_tickets.php"><?php echo $recurring_ticket_subject; ?></a></td>
<td><?php echo $scheduled_ticket_frequency; ?></td> <td><?php echo $recurring_ticket_frequency; ?></td>
<td><?php echo $scheduled_ticket_next_run; ?></td> <td><?php echo $recurring_ticket_next_run; ?></td>
<td><a href="recurring_tickets.php?client_id=<?php echo $client_id ?>"><?php echo $client_name; ?></a></td> <td><a href="recurring_tickets.php?client_id=<?php echo $client_id ?>"><?php echo $client_name; ?></a></td>
</tr> </tr>
@ -571,9 +571,9 @@ if (isset($_GET['query'])) {
<?php } ?> <?php } ?>
<?php if (mysqli_num_rows($sql_logins) > 0) { ?> <?php if (mysqli_num_rows($sql_credentials) > 0) { ?>
<!-- Logins --> <!-- Credentials -->
<div class="col-sm-6"> <div class="col-sm-6">
<div class="card card-dark mb-3"> <div class="card card-dark mb-3">
<div class="card-header"> <div class="card-header">
@ -593,21 +593,21 @@ if (isset($_GET['query'])) {
<tbody> <tbody>
<?php <?php
while ($row = mysqli_fetch_array($sql_logins)) { while ($row = mysqli_fetch_array($sql_credentials)) {
$login_name = nullable_htmlentities($row['login_name']); $credential_name = nullable_htmlentities($row['credential_name']);
$login_description = nullable_htmlentities($row['login_description']); $credential_description = nullable_htmlentities($row['credential_description']);
$login_client_id = intval($row['login_client_id']); $credential_client_id = intval($row['credential_client_id']);
$login_username = nullable_htmlentities(decryptLoginEntry($row['login_username'])); $credential_username = nullable_htmlentities(decryptCredentialEntry($row['credential_username']));
$login_password = nullable_htmlentities(decryptLoginEntry($row['login_password'])); $credential_password = nullable_htmlentities(decryptCredentialEntry($row['credential_password']));
$client_id = intval($row['client_id']); $client_id = intval($row['client_id']);
$client_name = nullable_htmlentities($row['client_name']); $client_name = nullable_htmlentities($row['client_name']);
?> ?>
<tr> <tr>
<td><a href="credentials.php?client_id=<?php echo $login_client_id ?>&q=<?php echo $q ?>"><?php echo $login_name; ?></a></td> <td><a href="credentials.php?client_id=<?php echo $credential_client_id ?>&q=<?php echo $q ?>"><?php echo $credential_name; ?></a></td>
<td><?php echo $login_description; ?></td> <td><?php echo $credential_description; ?></td>
<td><?php echo $login_username; ?></td> <td><?php echo $credential_username; ?></td>
<td><a tabindex="0" class="btn btn-sm" data-toggle="popover" data-trigger="focus" data-placement="left" data-content="<?php echo $login_password; ?>"><i class="far fa-eye text-secondary"></i></a><button class="btn btn-sm clipboardjs" data-clipboard-text="<?php echo $login_password; ?>"><i class="far fa-copy text-secondary"></i></button> <td><a tabindex="0" class="btn btn-sm" data-toggle="popover" data-trigger="focus" data-placement="left" data-content="<?php echo $credential_password; ?>"><i class="far fa-eye text-secondary"></i></a><button class="btn btn-sm clipboardjs" data-clipboard-text="<?php echo $credential_password; ?>"><i class="far fa-copy text-secondary"></i></button>
</td> </td>
<td><a href="credentials.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td> <td><a href="credentials.php?client_id=<?php echo $client_id; ?>"><?php echo $client_name; ?></a></td>
</tr> </tr>

View File

@ -9,7 +9,7 @@
require_once "../config.php"; require_once "../config.php";
// Set Timezone // Set Timezone
require_once "../inc_set_timezone.php"; require_once "../includes/inc_set_timezone.php";
require_once "../functions.php"; require_once "../functions.php";
require_once "../plugins/totp/totp.php"; require_once "../plugins/totp/totp.php";

View File

@ -3,7 +3,7 @@
require_once "../config.php"; require_once "../config.php";
// Set Timezone // Set Timezone
require_once "../inc_set_timezone.php"; require_once "../includes/inc_set_timezone.php";
require_once "../functions.php"; require_once "../functions.php";

View File

@ -1,6 +1,6 @@
<?php <?php
require_once 'guest_header.php'; require_once 'includes/guest_header.php';
// Define wording // Define wording
DEFINE("WORDING_PAYMENT_FAILED", "<br><h2>There was an error verifying your payment. Please contact us for more information before attempting payment again.</h2>"); DEFINE("WORDING_PAYMENT_FAILED", "<br><h2>There was an error verifying your payment. Please contact us for more information before attempting payment again.</h2>");
@ -19,7 +19,7 @@ $config_stripe_flat_fee = floatval($stripe_vars['config_stripe_flat_fee']);
// Check Stripe is configured // Check Stripe is configured
if ($config_stripe_enable == 0 || $config_stripe_account == 0 || empty($config_stripe_publishable) || empty($config_stripe_secret)) { if ($config_stripe_enable == 0 || $config_stripe_account == 0 || empty($config_stripe_publishable) || empty($config_stripe_secret)) {
echo "<br><h2>Stripe payments not enabled/configured</h2>"; echo "<br><h2>Stripe payments not enabled/configured</h2>";
require_once 'guest_footer.php'; require_once 'includes/guest_footer.php';
error_log("Stripe payment error - disabled. Check payments are enabled, Expense account is set, Stripe publishable and secret keys are configured."); error_log("Stripe payment error - disabled. Check payments are enabled, Expense account is set, Stripe publishable and secret keys are configured.");
exit(); exit();
} }
@ -47,7 +47,7 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent
// Ensure we have a valid invoice // Ensure we have a valid invoice
if (!$sql || mysqli_num_rows($sql) !== 1) { if (!$sql || mysqli_num_rows($sql) !== 1) {
echo "<br><h2>Oops, something went wrong! Please ensure you have the correct URL and have not already paid this invoice.</h2>"; echo "<br><h2>Oops, something went wrong! Please ensure you have the correct URL and have not already paid this invoice.</h2>";
require_once 'guest_footer.php'; require_once 'includes/guest_footer.php';
error_log("Stripe payment error - Invoice with ID $invoice_id is unknown/not eligible to be paid."); error_log("Stripe payment error - Invoice with ID $invoice_id is unknown/not eligible to be paid.");
exit(); exit();
} }
@ -357,4 +357,4 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent
} }
require_once 'guest_footer.php'; require_once 'includes/guest_footer.php';

View File

@ -5,7 +5,7 @@ require_once "../functions.php";
session_start(); session_start();
require_once "../inc_set_timezone.php"; // Must be included after session_start to work require_once "../includes/inc_set_timezone.php"; // Must be included after session_start to work
if (isset($_GET['accept_quote'], $_GET['url_key'])) { if (isset($_GET['accept_quote'], $_GET['url_key'])) {
$quote_id = intval($_GET['accept_quote']); $quote_id = intval($_GET['accept_quote']);

View File

@ -1,10 +1,10 @@
<?php <?php
require_once "guest_header.php"; require_once "includes/guest_header.php";
if (!isset($_GET['invoice_id'], $_GET['url_key'])) { if (!isset($_GET['invoice_id'], $_GET['url_key'])) {
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>"; echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "guest_footer.php"; require_once "includes/guest_footer.php";
exit(); exit();
} }
@ -25,7 +25,7 @@ $sql = mysqli_query(
if (mysqli_num_rows($sql) !== 1) { if (mysqli_num_rows($sql) !== 1) {
// Invalid invoice/key // Invalid invoice/key
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>"; echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "guest_footer.php"; require_once "includes/guest_footer.php";
exit(); exit();
} }
@ -931,4 +931,4 @@ if ($outstanding_invoices_count > 0) { ?>
<?php } // End previous unpaid invoices <?php } // End previous unpaid invoices
require_once "guest_footer.php"; require_once "includes/guest_footer.php";

View File

@ -4,7 +4,7 @@ header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false); header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache'); header('Pragma: no-cache');
require_once "guest_header.php"; require_once "includes/guest_header.php";
//Initialize the HTML Purifier to prevent XSS //Initialize the HTML Purifier to prevent XSS
@ -38,7 +38,7 @@ $currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY);
<?php <?php
if (!isset($_GET['id']) || !isset($_GET['key'])) { if (!isset($_GET['id']) || !isset($_GET['key'])) {
echo "<div class='alert alert-danger'>Incorrect URL.</div>"; echo "<div class='alert alert-danger'>Incorrect URL.</div>";
include "guest_footer.php"; include "includes/guest_footer.php";
exit(); exit();
} }
@ -52,7 +52,7 @@ $row = mysqli_fetch_array($sql);
// Check we got a result // Check we got a result
if (mysqli_num_rows($sql) !== 1 || !$row) { if (mysqli_num_rows($sql) !== 1 || !$row) {
echo "<div class='alert alert-danger' >No item to view. Check with the person that sent you this link to ensure it is correct and has not expired.</div>"; echo "<div class='alert alert-danger' >No item to view. Check with the person that sent you this link to ensure it is correct and has not expired.</div>";
include "guest_footer.php"; include "includes/guest_footer.php";
exit(); exit();
} }
@ -60,7 +60,7 @@ if (mysqli_num_rows($sql) !== 1 || !$row) {
// Check item share is active & hasn't been viewed too many times but allow 0 views as that is consider infinite views // Check item share is active & hasn't been viewed too many times but allow 0 views as that is consider infinite views
if ($row['item_active'] !== "1" || ($row['item_view_limit'] > 0 && $row['item_views'] >= $row['item_view_limit'])) { if ($row['item_active'] !== "1" || ($row['item_view_limit'] > 0 && $row['item_views'] >= $row['item_view_limit'])) {
echo "<div class='alert alert-danger'>Item cannot be viewed at this time. Check with the person that sent you this link to ensure it is correct and has not expired.</div>"; echo "<div class='alert alert-danger'>Item cannot be viewed at this time. Check with the person that sent you this link to ensure it is correct and has not expired.</div>";
include "guest_footer.php"; include "includes/guest_footer.php";
exit(); exit();
} }
@ -122,7 +122,7 @@ if ($item_type == "Document") {
if (mysqli_num_rows($doc_sql) !== 1 || !$doc_row) { if (mysqli_num_rows($doc_sql) !== 1 || !$doc_row) {
echo "<div class='alert alert-danger'>Error retrieving document to view.</div>"; echo "<div class='alert alert-danger'>Error retrieving document to view.</div>";
require_once "guest_footer.php"; require_once "includes/guest_footer.php";
exit(); exit();
} }
@ -149,7 +149,7 @@ if ($item_type == "Document") {
if (mysqli_num_rows($file_sql) !== 1 || !$file_row) { if (mysqli_num_rows($file_sql) !== 1 || !$file_row) {
echo "<div class='alert alert-danger'>Error retrieving file.</div>"; echo "<div class='alert alert-danger'>Error retrieving file.</div>";
include "guest_footer.php"; include "includes/guest_footer.php";
exit(); exit();
} }
@ -163,61 +163,61 @@ if ($item_type == "Document") {
echo "<a href='guest_download_file.php?id=$item_id&key=$item_key'>Download $file_name</a>"; echo "<a href='guest_download_file.php?id=$item_id&key=$item_key'>Download $file_name</a>";
} elseif ($item_type == "Login") { } elseif ($item_type == "Credential") {
$encryption_key = $_GET['ek']; $encryption_key = $_GET['ek'];
$login_sql = mysqli_query($mysqli, "SELECT * FROM logins WHERE login_id = $item_related_id AND login_client_id = $client_id LIMIT 1"); $credential_sql = mysqli_query($mysqli, "SELECT * FROM credentials WHERE credential_id = $item_related_id AND credential_client_id = $client_id LIMIT 1");
$login_row = mysqli_fetch_array($login_sql); $credential_row = mysqli_fetch_array($credential_sql);
if (mysqli_num_rows($login_sql) !== 1 || !$login_row) { if (mysqli_num_rows($credential_sql) !== 1 || !$credential_row) {
echo "<div class='alert alert-danger'>Error retrieving login.</div>"; echo "<div class='alert alert-danger'>Error retrieving login.</div>";
include "guest_footer.php"; include "includes/guest_footer.php";
exit(); exit();
} }
$login_id = intval($login_row['login_id']); $credential_id = intval($credential_row['credential_id']);
$login_name = nullable_htmlentities($login_row['login_name']); $credential_name = nullable_htmlentities($credential_row['credential_name']);
$login_uri = nullable_htmlentities($login_row['login_uri']); $credential_uri = nullable_htmlentities($credential_row['credential_uri']);
$username_iv = substr($row['item_encrypted_username'], 0, 16); $username_iv = substr($row['item_encrypted_username'], 0, 16);
$username_ciphertext = substr($row['item_encrypted_username'], 16); $username_ciphertext = substr($row['item_encrypted_username'], 16);
$login_username = nullable_htmlentities(openssl_decrypt($username_ciphertext, 'aes-128-cbc', $encryption_key, 0, $username_iv)); $credential_username = nullable_htmlentities(openssl_decrypt($username_ciphertext, 'aes-128-cbc', $encryption_key, 0, $username_iv));
$password_iv = substr($row['item_encrypted_credential'], 0, 16); $password_iv = substr($row['item_encrypted_credential'], 0, 16);
$password_ciphertext = substr($row['item_encrypted_credential'], 16); $password_ciphertext = substr($row['item_encrypted_credential'], 16);
$login_password = nullable_htmlentities(openssl_decrypt($password_ciphertext, 'aes-128-cbc', $encryption_key, 0, $password_iv)); $credential_password = nullable_htmlentities(openssl_decrypt($password_ciphertext, 'aes-128-cbc', $encryption_key, 0, $password_iv));
$login_otp = nullable_htmlentities($login_row['login_otp_secret']); $credential_otp = nullable_htmlentities($credential_row['credential_otp_secret']);
$login_otp_secret = nullable_htmlentities($login_row['login_otp_secret']); $credential_otp_secret = nullable_htmlentities($credential_row['credential_otp_secret']);
$login_id_with_secret = '"' . $login_row['login_id'] . '","' . $login_row['login_otp_secret'] . '"'; $credential_id_with_secret = '"' . $credential_row['credential_id'] . '","' . $credential_row['credential_otp_secret'] . '"';
if (empty($login_otp_secret)) { if (empty($credential_otp_secret)) {
$otp_display = "-"; $otp_display = "-";
} else { } else {
$otp_display = "<span onmouseenter='showOTP($login_id_with_secret)'><i class='far fa-clock'></i> <span id='otp_$login_id'><i>Hover..</i></span></span>"; $otp_display = "<span onmouseenter='showOTP($credential_id_with_secret)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
} }
$login_notes = nullable_htmlentities($login_row['login_note']); $credential_notes = nullable_htmlentities($credential_row['credential_note']);
?> ?>
<h5><?php echo $login_name; ?></h5> <h5><?php echo $credential_name; ?></h5>
<table class="table col-md-3"> <table class="table col-md-3">
<tr> <tr>
<th>URL</th> <th>URL</th>
<td><?php echo $login_uri; ?></td> <td><?php echo $credential_uri; ?></td>
</tr> </tr>
<tr> <tr>
<th>Username</th> <th>Username</th>
<td><?php echo $login_username ?></td> <td><?php echo $credential_username ?></td>
</tr> </tr>
<tr> <tr>
<th>Password</th> <th>Password</th>
<td><?php echo $login_password ?></td> <td><?php echo $credential_password ?></td>
</tr> </tr>
<?php if(!empty($login_otp_secret)){ ?> <?php if(!empty($credential_otp_secret)){ ?>
<tr> <tr>
<th>2FA (TOTP)</th> <th>2FA (TOTP)</th>
<td><?php echo $otp_display ?></td> <td><?php echo $otp_display ?></td>
@ -250,12 +250,12 @@ if ($item_type == "Document") {
<?php <?php
// Update login view count // Update credential view count
$new_item_views = $item_views + 1; $new_item_views = $item_views + 1;
mysqli_query($mysqli, "UPDATE shared_items SET item_views = $new_item_views WHERE item_id = $item_id"); mysqli_query($mysqli, "UPDATE shared_items SET item_views = $new_item_views WHERE item_id = $item_id");
// Logging // Logging
$name = sanitizeInput($login_row['login_name']); $name = sanitizeInput($credential_row['credential_name']);
logAction("Share", "View", "Viewed shared $item_type $name via link", $client_id); logAction("Share", "View", "Viewed shared $item_type $name via link", $client_id);
} }
@ -273,6 +273,6 @@ if ($item_type == "Document") {
</div> </div>
<?php <?php
require_once "guest_footer.php"; require_once "includes/guest_footer.php";
?> ?>

View File

@ -1,11 +1,11 @@
<?php <?php
require_once "guest_header.php"; require_once "includes/guest_header.php";
if (!isset($_GET['quote_id'], $_GET['url_key'])) { if (!isset($_GET['quote_id'], $_GET['url_key'])) {
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>"; echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "guest_footer.php"; require_once "includes/guest_footer.php";
exit(); exit();
} }
@ -27,7 +27,7 @@ $sql = mysqli_query(
if (mysqli_num_rows($sql) !== 1) { if (mysqli_num_rows($sql) !== 1) {
// Invalid quote/key // Invalid quote/key
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>"; echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "guest_footer.php"; require_once "includes/guest_footer.php";
exit(); exit();
} }
@ -717,5 +717,5 @@ if ($quote_status == "Draft" || $quote_status == "Sent" || $quote_status == "Vie
<?php <?php
require_once "guest_quote_upload_file_modal.php"; require_once "guest_quote_upload_file_modal.php";
require_once "guest_footer.php"; require_once "includes/guest_footer.php";

View File

@ -1,6 +1,6 @@
<?php <?php
require_once "guest_header.php"; require_once "includes/guest_header.php";
//Initialize the HTML Purifier to prevent XSS //Initialize the HTML Purifier to prevent XSS
require "../plugins/htmlpurifier/HTMLPurifier.standalone.php"; require "../plugins/htmlpurifier/HTMLPurifier.standalone.php";
@ -12,7 +12,7 @@ $purifier = new HTMLPurifier($purifier_config);
if (!isset($_GET['ticket_id'], $_GET['url_key'])) { if (!isset($_GET['ticket_id'], $_GET['url_key'])) {
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>"; echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "guest_footer.php"; require_once "includes/guest_footer.php";
exit(); exit();
} }
@ -34,7 +34,7 @@ $ticket_sql = mysqli_query($mysqli,
if (mysqli_num_rows($ticket_sql) !== 1) { if (mysqli_num_rows($ticket_sql) !== 1) {
// Invalid invoice/key // Invalid invoice/key
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>"; echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
require_once "guest_footer.php"; require_once "includes/guest_footer.php";
exit(); exit();
} }
@ -208,4 +208,4 @@ if ($ticket_row) {
</div> </div>
<?php <?php
require_once "guest_footer.php"; require_once "includes/guest_footer.php";

View File

@ -6,7 +6,7 @@ require_once "../functions.php";
session_start(); session_start();
// Set Timezone // Set Timezone
require_once "../inc_set_timezone.php"; require_once "../includes/inc_set_timezone.php";
$ip = sanitizeInput(getIP()); $ip = sanitizeInput(getIP());
$user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']); $user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']);

View File

@ -2,7 +2,7 @@
require_once "../config.php"; require_once "../config.php";
require_once "../functions.php"; require_once "../functions.php";
require_once "../check_login.php"; require_once "check_login.php";
header('Content-Type: application/json'); header('Content-Type: application/json');

View File

@ -5,4 +5,4 @@
* Update this file each time we merge develop into master. Format is YY.MM (add a .v if there is more than one release a month. * Update this file each time we merge develop into master. Format is YY.MM (add a .v if there is more than one release a month.
*/ */
DEFINE("APP_VERSION", "25.02.3"); DEFINE("APP_VERSION", "25.02.4");

View File

@ -13,31 +13,25 @@ if (!isset($_SESSION)) {
// Check to see if setup is enabled // Check to see if setup is enabled
if (!isset($config_enable_setup) || $config_enable_setup == 1) { if (!isset($config_enable_setup) || $config_enable_setup == 1) {
header("Location: setup.php"); header("Location: ../setup.php");
exit; exit;
} }
// Check user is logged in with a valid session // Check user is logged in with a valid session
if (!isset($_SESSION['logged']) || !$_SESSION['logged']) { if (!isset($_SESSION['logged']) || !$_SESSION['logged']) {
if ($_SERVER["REQUEST_URI"] == "/") { if ($_SERVER["REQUEST_URI"] == "/") {
header("Location: login.php"); header("Location: ../login.php");
} else { } else {
header("Location: login.php?last_visited=" . base64_encode($_SERVER["REQUEST_URI"]) ); header("Location: ../login.php?last_visited=" . base64_encode($_SERVER["REQUEST_URI"]) );
} }
exit; exit;
} }
// Check user type
if ($_SESSION['user_type'] !== 1) {
header("Location: login.php");
exit();
}
// Set Timezone // Set Timezone
require_once "inc_set_timezone.php"; require_once "inc_set_timezone.php";
// User IP & UA // User Vars and User Settings
$session_ip = sanitizeInput(getIP()); $session_ip = sanitizeInput(getIP());
$session_user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']); $session_user_agent = sanitizeInput($_SERVER['HTTP_USER_AGENT']);
@ -47,7 +41,7 @@ $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT * FROM users "SELECT * FROM users
LEFT JOIN user_settings ON users.user_id = user_settings.user_id LEFT JOIN user_settings ON users.user_id = user_settings.user_id
LEFT JOIN user_roles ON user_settings.user_role = user_roles.user_role_id LEFT JOIN user_roles ON user_role_id = role_id
WHERE users.user_id = $session_user_id"); WHERE users.user_id = $session_user_id");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
@ -55,9 +49,10 @@ $session_name = sanitizeInput($row['user_name']);
$session_email = $row['user_email']; $session_email = $row['user_email'];
$session_avatar = $row['user_avatar']; $session_avatar = $row['user_avatar'];
$session_token = $row['user_token']; // MFA Token $session_token = $row['user_token']; // MFA Token
$session_user_role = intval($row['user_role']); $session_user_type = intval($row['user_type']);
$session_user_role_display = sanitizeInput($row['user_role_name']); $session_user_role = intval($row['user_role_id']);
if (isset($row['user_role_is_admin']) && $row['user_role_is_admin'] == 1) { $session_user_role_display = sanitizeInput($row['role_name']);
if (isset($row['role_is_admin']) && $row['role_is_admin'] == 1) {
$session_is_admin = true; $session_is_admin = true;
} else { } else {
$session_is_admin = false; $session_is_admin = false;
@ -65,6 +60,15 @@ if (isset($row['user_role_is_admin']) && $row['user_role_is_admin'] == 1) {
$session_user_config_force_mfa = intval($row['user_config_force_mfa']); $session_user_config_force_mfa = intval($row['user_config_force_mfa']);
$user_config_records_per_page = intval($row['user_config_records_per_page']); $user_config_records_per_page = intval($row['user_config_records_per_page']);
// Check user type
if ($session_user_type !== 1) {
session_unset();
session_destroy();
header("Location: login.php");
exit();
}
// Company Vars and Company Settings
$sql = mysqli_query($mysqli, "SELECT * FROM companies, settings WHERE settings.company_id = companies.company_id AND companies.company_id = 1"); $sql = mysqli_query($mysqli, "SELECT * FROM companies, settings WHERE settings.company_id = companies.company_id AND companies.company_id = 1");
$row = mysqli_fetch_array($sql); $row = mysqli_fetch_array($sql);
@ -78,7 +82,7 @@ $session_company_currency = $row['company_currency'];
$currency_format = numfmt_create($session_company_locale, NumberFormatter::CURRENCY); $currency_format = numfmt_create($session_company_locale, NumberFormatter::CURRENCY);
// Get User Client Access Permissions // Get User Client Access Permissions
$user_client_access_sql = "SELECT client_id FROM user_permissions WHERE user_id = $session_user_id"; $user_client_access_sql = "SELECT client_id FROM user_client_permissions WHERE user_id = $session_user_id";
$user_client_access_result = mysqli_query($mysqli, $user_client_access_sql); $user_client_access_result = mysqli_query($mysqli, $user_client_access_sql);
$client_access_array = []; $client_access_array = [];

View File

@ -74,8 +74,8 @@
<p> <p>
Recurring Tickets Recurring Tickets
<?php <?php
if ($num_scheduled_tickets) { ?> if ($num_recurring_tickets) { ?>
<span class="right badge"><?php echo $num_scheduled_tickets; ?></span> <span class="right badge"><?php echo $num_recurring_tickets; ?></span>
<?php } ?> <?php } ?>
</p> </p>
@ -103,8 +103,8 @@
<p> <p>
Calendar Calendar
<?php <?php
if ($num_events > 0) { ?> if ($num_calendar_events > 0) { ?>
<span class="right badge text-light"><?php echo $num_events; ?></span> <span class="right badge text-light"><?php echo $num_calendar_events; ?></span>
<?php } ?> <?php } ?>
</p> </p>
</a> </a>
@ -147,8 +147,8 @@
<p> <p>
Credentials Credentials
<?php <?php
if ($num_logins > 0) { ?> if ($num_credentials > 0) { ?>
<span class="right badge text-light"><?php echo $num_logins; ?></span> <span class="right badge text-light"><?php echo $num_credentials; ?></span>
<?php } ?> <?php } ?>
</p> </p>
</a> </a>
@ -277,8 +277,8 @@
<p> <p>
Recurring Invoices Recurring Invoices
<?php <?php
if ($num_recurring > 0) { ?> if ($num_recurring_invoices) { ?>
<span class="right badge"><?php echo $num_recurring; ?></span> <span class="right badge"><?php echo $num_recurring_invoices; ?></span>
<?php } ?> <?php } ?>
</p> </p>
</a> </a>

View File

@ -5,4 +5,4 @@
* It is used in conjunction with database_updates.php * It is used in conjunction with database_updates.php
*/ */
DEFINE("LATEST_DATABASE_VERSION", "1.8.7"); DEFINE("LATEST_DATABASE_VERSION", "2.0.8");

View File

@ -49,8 +49,8 @@ $config_invoice_late_fee_percent = floatval($row['config_invoice_late_fee_percen
$config_invoice_paid_notification_email = $row['config_invoice_paid_notification_email']; $config_invoice_paid_notification_email = $row['config_invoice_paid_notification_email'];
// Recurring Invoices // Recurring Invoices
$config_recurring_prefix = $row['config_recurring_prefix']; $config_recurring_invoice_prefix = $row['config_recurring_invoice_prefix'];
$config_recurring_next_number = intval($row['config_recurring_next_number']); $config_recurring_invoice_next_number = intval($row['config_recurring_invoice_next_number']);
// Quotes // Quotes
$config_quote_prefix = $row['config_quote_prefix']; $config_quote_prefix = $row['config_quote_prefix'];
@ -142,21 +142,22 @@ $config_whitelabel_key = $row['config_whitelabel_key'];
$theme_colors_array = array ( $theme_colors_array = array (
'lightblue', 'lightblue',
'blue', 'blue',
'green',
'cyan', 'cyan',
'yellow', 'green',
'red', 'olive',
'black',
'gray',
'indigo',
'navy',
'purple',
'fuchsia',
'pink',
'maroon',
'orange',
'teal', 'teal',
'olive' 'red',
'maroon',
'pink',
'purple',
'indigo',
'fuchsia',
'yellow',
'orange',
'yellow',
'black',
'navy',
'gray'
); );
$colors_array = array ( $colors_array = array (

View File

@ -10,7 +10,7 @@ $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('ticket_id') AS nu
$num_active_tickets = $row['num']; $num_active_tickets = $row['num'];
// Recurring Ticket Count // Recurring Ticket Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('scheduled_ticket_id') AS num FROM scheduled_tickets LEFT JOIN clients ON client_id = scheduled_ticket_client_id WHERE 1 = 1 $access_permission_query")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_ticket_id') AS num FROM recurring_tickets LEFT JOIN clients ON client_id = recurring_ticket_client_id WHERE 1 = 1 $access_permission_query"));
$num_recurring_tickets = $row['num']; $num_recurring_tickets = $row['num'];
// Active Project Count // Active Project Count
@ -22,7 +22,7 @@ $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('invoice_id') AS n
$num_open_invoices = $row['num']; $num_open_invoices = $row['num'];
// Recurring Invoice Count // Recurring Invoice Count
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_id') AS num FROM recurring WHERE recurring_archived_at IS NULL")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_invoice_id') AS num FROM recurring_invoices WHERE recurring_invoice_archived_at IS NULL"));
$num_recurring_invoices = $row['num']; $num_recurring_invoices = $row['num'];
// Open Quotes Count // Open Quotes Count

View File

@ -115,13 +115,13 @@ if (isset($_GET['client_id'])) {
$balance = $invoice_amounts - $amount_paid; $balance = $invoice_amounts - $amount_paid;
//Get Monthly Recurring Total //Get Monthly Recurring Total
$sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_amount) AS recurring_monthly_total FROM recurring WHERE recurring_status = 1 AND recurring_frequency = 'month' AND recurring_client_id = $client_id"); $sql_recurring_monthly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_monthly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'month' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_monthly_total); $row = mysqli_fetch_array($sql_recurring_monthly_total);
$recurring_monthly_total = floatval($row['recurring_monthly_total']); $recurring_monthly_total = floatval($row['recurring_monthly_total']);
//Get Yearly Recurring Total //Get Yearly Recurring Total
$sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_amount) AS recurring_yearly_total FROM recurring WHERE recurring_status = 1 AND recurring_frequency = 'year' AND recurring_client_id = $client_id"); $sql_recurring_yearly_total = mysqli_query($mysqli, "SELECT SUM(recurring_invoice_amount) AS recurring_yearly_total FROM recurring_invoices WHERE recurring_invoice_status = 1 AND recurring_invoice_frequency = 'year' AND recurring_invoice_client_id = $client_id");
$row = mysqli_fetch_array($sql_recurring_yearly_total); $row = mysqli_fetch_array($sql_recurring_yearly_total);
$recurring_yearly_total = floatval($row['recurring_yearly_total']) / 12; $recurring_yearly_total = floatval($row['recurring_yearly_total']) / 12;
@ -145,8 +145,8 @@ if (isset($_GET['client_id'])) {
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('ticket_id') AS num FROM tickets WHERE ticket_archived_at IS NULL AND ticket_closed_at IS NOT NULL AND ticket_client_id = $client_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('ticket_id') AS num FROM tickets WHERE ticket_archived_at IS NULL AND ticket_closed_at IS NOT NULL AND ticket_client_id = $client_id"));
$num_closed_tickets = $row['num']; $num_closed_tickets = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('scheduled_ticket_id') AS num FROM scheduled_tickets WHERE scheduled_ticket_client_id = $client_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_ticket_id') AS num FROM recurring_tickets WHERE recurring_ticket_client_id = $client_id"));
$num_scheduled_tickets = $row['num']; $num_recurring_tickets = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('service_id') AS num FROM services WHERE service_client_id = $client_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('service_id') AS num FROM services WHERE service_client_id = $client_id"));
$num_services = $row['num']; $num_services = $row['num'];
@ -154,8 +154,8 @@ if (isset($_GET['client_id'])) {
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('vendor_id') AS num FROM vendors WHERE vendor_archived_at IS NULL AND vendor_client_id = $client_id AND vendor_template = 0")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('vendor_id') AS num FROM vendors WHERE vendor_archived_at IS NULL AND vendor_client_id = $client_id AND vendor_template = 0"));
$num_vendors = $row['num']; $num_vendors = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('login_id') AS num FROM logins WHERE login_archived_at IS NULL AND login_client_id = $client_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('credential_id') AS num FROM credentials WHERE credential_archived_at IS NULL AND credential_client_id = $client_id"));
$num_logins = $row['num']; $num_credentials = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('network_id') AS num FROM networks WHERE network_archived_at IS NULL AND network_client_id = $client_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('network_id') AS num FROM networks WHERE network_archived_at IS NULL AND network_client_id = $client_id"));
$num_networks = $row['num']; $num_networks = $row['num'];
@ -196,8 +196,8 @@ if (isset($_GET['client_id'])) {
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('quote_id') AS num FROM quotes WHERE quote_archived_at IS NULL AND quote_client_id = $client_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('quote_id') AS num FROM quotes WHERE quote_archived_at IS NULL AND quote_client_id = $client_id"));
$num_quotes = $row['num']; $num_quotes = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_id') AS num FROM recurring WHERE recurring_archived_at IS NULL AND recurring_client_id = $client_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('recurring_invoice_id') AS num FROM recurring_invoices WHERE recurring_invoice_archived_at IS NULL AND recurring_invoice_client_id = $client_id"));
$num_recurring = $row['num']; $num_recurring_invoices = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('payment_id') AS num FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_client_id = $client_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('payment_id') AS num FROM payments, invoices WHERE payment_invoice_id = invoice_id AND invoice_client_id = $client_id"));
$num_payments = $row['num']; $num_payments = $row['num'];
@ -208,8 +208,8 @@ if (isset($_GET['client_id'])) {
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('document_id') AS num FROM documents WHERE document_archived_at IS NULL AND document_client_id = $client_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('document_id') AS num FROM documents WHERE document_archived_at IS NULL AND document_client_id = $client_id"));
$num_documents = $row['num']; $num_documents = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('event_id') AS num FROM events WHERE event_client_id = $client_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('event_id') AS num FROM calendar_events WHERE event_client_id = $client_id"));
$num_events = $row['num']; $num_calendar_events = $row['num'];
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('trip_id') AS num FROM trips WHERE trip_archived_at IS NULL AND trip_client_id = $client_id")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('trip_id') AS num FROM trips WHERE trip_archived_at IS NULL AND trip_client_id = $client_id"));
$num_trips = $row['num']; $num_trips = $row['num'];

View File

@ -27,7 +27,6 @@ $(document).on('click', '[data-toggle="ajax-modal"]', function (e) {
method: 'GET', method: 'GET',
data: { id: ajaxId }, data: { id: ajaxId },
dataType: 'json', dataType: 'json',
cache: false, // Prevent caching if necessary
success: function (response) { success: function (response) {
if (response.error) { if (response.error) {
alert(response.error); alert(response.error);
@ -42,7 +41,7 @@ $(document).on('click', '[data-toggle="ajax-modal"]', function (e) {
// Build the modal HTML using the returned title and content. // Build the modal HTML using the returned title and content.
var modalHtml = var modalHtml =
'<div class="modal fade text-sm" id="' + modalId + '" tabindex="-1">' + '<div class="modal fade" id="' + modalId + '" tabindex="-1">' +
' <div class="modal-dialog modal-'+ modalSize +'">' + ' <div class="modal-dialog modal-'+ modalSize +'">' +
' <div class="modal-content bg-dark">' ' <div class="modal-content bg-dark">'
+ response.content + + response.content +
@ -51,7 +50,7 @@ $(document).on('click', '[data-toggle="ajax-modal"]', function (e) {
'</div>'; '</div>';
// Append the modal to the body and show it. // Append the modal to the body and show it.
$('body').append(modalHtml); $('.content-wrapper').append(modalHtml);
var $modal = $('#' + modalId); var $modal = $('#' + modalId);
$modal.modal('show'); $modal.modal('show');

View File

@ -1,15 +1,15 @@
function showOTPViaLoginID(login_id) { function showOTPViaCredentialID(credential_id) {
// Send a GET request to ajax.php as ajax.php?get_totp_token_via_id=true&login_id=ID // Send a GET request to ajax.php as ajax.php?get_totp_token_via_id=true&credential_id=ID
jQuery.get( jQuery.get(
"ajax.php", { "ajax.php", {
get_totp_token_via_id: 'true', get_totp_token_via_id: 'true',
login_id: login_id credential_id: credential_id
}, },
function(data) { function(data) {
//If we get a response from post.php, parse it as JSON //If we get a response from post.php, parse it as JSON
const token = JSON.parse(data); const token = JSON.parse(data);
document.getElementById("otp_" + login_id).innerText = token document.getElementById("otp_" + credential_id).innerText = token
} }
); );

View File

@ -11,7 +11,7 @@ if (!file_exists('config.php')) {
require_once "config.php"; require_once "config.php";
// Set Timezone // Set Timezone
require_once "inc_set_timezone.php"; require_once "includes/inc_set_timezone.php";
// Check if the application is configured for HTTPS-only access // Check if the application is configured for HTTPS-only access
if ($config_https_only && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') && (!isset($_SERVER['HTTP_X_FORWARDED_PROTO']) || $_SERVER['HTTP_X_FORWARDED_PROTO'] !== 'https')) { if ($config_https_only && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') && (!isset($_SERVER['HTTP_X_FORWARDED_PROTO']) || $_SERVER['HTTP_X_FORWARDED_PROTO'] !== 'https')) {
@ -117,7 +117,7 @@ if (isset($_POST['login'])) {
$user_email = sanitizeInput($row['user_email']); $user_email = sanitizeInput($row['user_email']);
$token = sanitizeInput($row['user_token']); $token = sanitizeInput($row['user_token']);
$force_mfa = intval($row['user_config_force_mfa']); $force_mfa = intval($row['user_config_force_mfa']);
$user_role = intval($row['user_role']); $user_role_id = intval($row['user_role_id']);
$user_encryption_ciphertext = $row['user_specific_encryption_ciphertext']; $user_encryption_ciphertext = $row['user_specific_encryption_ciphertext'];
$user_extension_key = $row['user_extension_key']; $user_extension_key = $row['user_extension_key'];
@ -193,9 +193,6 @@ if (isset($_POST['login'])) {
// Session info // Session info
$_SESSION['user_id'] = $user_id; $_SESSION['user_id'] = $user_id;
$_SESSION['user_name'] = $user_name;
$_SESSION['user_type'] = 1;
$_SESSION['user_role'] = $user_role;
$_SESSION['csrf_token'] = randomString(156); $_SESSION['csrf_token'] = randomString(156);
$_SESSION['logged'] = true; $_SESSION['logged'] = true;

View File

@ -71,13 +71,13 @@
<select class="form-control select2" name="role" required> <select class="form-control select2" name="role" required>
<option value="">- Role -</option> <option value="">- Role -</option>
<?php <?php
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE user_role_archived_at IS NULL"); $sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL");
while ($row = mysqli_fetch_array($sql_user_roles)) { while ($row = mysqli_fetch_array($sql_user_roles)) {
$user_role_id = intval($row['user_role_id']); $role_id = intval($row['role_id']);
$user_role_name = nullable_htmlentities($row['user_role_name']); $role_name = nullable_htmlentities($row['role_name']);
?> ?>
<option value="<?php echo $user_role_id; ?>"><?php echo $user_role_name; ?></option> <option value="<?php echo $role_id; ?>"><?php echo $role_name; ?></option>
<?php } ?> <?php } ?>
</select> </select>
</div> </div>

View File

@ -82,9 +82,8 @@
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT users.user_id, user_name FROM users "SELECT user_id, user_name FROM users
LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role_id > 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
WHERE user_role > 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
); );
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$user_id = intval($row['user_id']); $user_id = intval($row['user_id']);

View File

@ -16,23 +16,23 @@
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
</div> </div>
<select class="form-control select2" name="login_id"> <select class="form-control select2" name="credential_id">
<option value="">- Select a Credential -</option> <option value="">- Select a Credential -</option>
<?php <?php
$sql_logins_select = mysqli_query($mysqli, "SELECT login_id, login_name FROM logins $sql_credentials_select = mysqli_query($mysqli, "SELECT credential_id, credential_name FROM credentials
WHERE login_client_id = $client_id WHERE credential_client_id = $client_id
AND login_asset_id != $contact_id AND credential_asset_id != $contact_id
AND login_asset_id = 0 AND credential_asset_id = 0
AND login_archived_at IS NULL AND credential_archived_at IS NULL
ORDER BY login_name ASC" ORDER BY credential_name ASC"
); );
while ($row = mysqli_fetch_array($sql_logins_select)) { while ($row = mysqli_fetch_array($sql_credentials_select)) {
$login_id = intval($row['login_id']); $credential_id = intval($row['credential_id']);
$login_name = nullable_htmlentities($row['login_name']); $credential_name = nullable_htmlentities($row['credential_name']);
?> ?>
<option value="<?php echo $login_id ?>"><?php echo $login_name; ?></option> <option value="<?php echo $credential_id ?>"><?php echo $credential_name; ?></option>
<?php <?php
} }
?> ?>

View File

@ -52,8 +52,8 @@
<li class="list-group-item"> <li class="list-group-item">
<div class="custom-control custom-checkbox"> <div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="logins" name="export_logins" value="1"> <input class="custom-control-input" type="checkbox" id="credentials" name="export_credentials" value="1">
<label for="logins" class="custom-control-label"> <label for="credentials" class="custom-control-label">
<i class='fas fa-fw fa-key mr-2'></i>Credentials <i class='fas fa-fw fa-key mr-2'></i>Credentials
</label> </label>
</div> </div>
@ -101,9 +101,9 @@
<li class="list-group-item"> <li class="list-group-item">
<div class="custom-control custom-checkbox"> <div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="scheduled_tickets" name="export_scheduled_tickets" value="1" checked> <input class="custom-control-input" type="checkbox" id="recurring_tickets" name="export_recurring_tickets" value="1" checked>
<label for="scheduled_tickets" class="custom-control-label"> <label for="recurring_tickets" class="custom-control-label">
<i class='fas fa-fw fa-clock mr-2'></i>Scheduled Tickets <i class='fas fa-fw fa-clock mr-2'></i>Recurring Tickets
</label> </label>
</div> </div>
</li> </li>
@ -128,8 +128,8 @@
<li class="list-group-item"> <li class="list-group-item">
<div class="custom-control custom-checkbox"> <div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="recurring" name="export_recurring" value="1" checked> <input class="custom-control-input" type="checkbox" id="recurring_invoices" name="export_recurring_invoices" value="1" checked>
<label for="recurring" class="custom-control-label"> <label for="recurring_invoices" class="custom-control-label">
<i class='fas fa-fw fa-sync mr-2'></i>Recurring Invoices <i class='fas fa-fw fa-sync mr-2'></i>Recurring Invoices
</label> </label>
</div> </div>

View File

@ -16,23 +16,23 @@
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span>
</div> </div>
<select class="form-control select2" name="login_id"> <select class="form-control select2" name="credential_id">
<option value="">- Select a Credential -</option> <option value="">- Select a Credential -</option>
<?php <?php
$sql_logins_select = mysqli_query($mysqli, "SELECT login_id, login_name FROM logins $sql_credentials_select = mysqli_query($mysqli, "SELECT credential_id, credential_name FROM credentials
WHERE login_client_id = $client_id WHERE credential_client_id = $client_id
AND login_contact_id != $contact_id AND credential_contact_id != $contact_id
AND login_contact_id = 0 AND credential_contact_id = 0
AND login_archived_at IS NULL AND credential_archived_at IS NULL
ORDER BY login_name ASC" ORDER BY credential_name ASC"
); );
while ($row = mysqli_fetch_array($sql_logins_select)) { while ($row = mysqli_fetch_array($sql_credentials_select)) {
$login_id = intval($row['login_id']); $credential_id = intval($row['credential_id']);
$login_name = nullable_htmlentities($row['login_name']); $credential_name = nullable_htmlentities($row['credential_name']);
?> ?>
<option value="<?php echo $login_id ?>"><?php echo $login_name; ?></option> <option value="<?php echo $credential_id ?>"><?php echo $credential_name; ?></option>
<?php <?php
} }
?> ?>

View File

@ -1,4 +1,4 @@
<div class="modal" id="addLoginModal" tabindex="-1"> <div class="modal" id="addCredentialModal" tabindex="-1">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content bg-dark"> <div class="modal-content bg-dark">
<div class="modal-header"> <div class="modal-header">
@ -245,7 +245,7 @@
</div> </div>
</div> </div>
<div class="modal-footer bg-white"> <div class="modal-footer bg-white">
<button type="submit" name="add_login" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button> <button type="submit" name="add_credential" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@ -49,7 +49,7 @@
</div> </div>
<div class="modal-footer bg-white"> <div class="modal-footer bg-white">
<button type="submit" name="bulk_assign_login_tags" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button> <button type="submit" name="bulk_assign_credential_tags" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Assign</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
</div> </div>
</div> </div>

View File

@ -1,4 +1,4 @@
<div class="modal" id="exportLoginModal" tabindex="-1"> <div class="modal" id="exportCredentialModal" tabindex="-1">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content bg-dark"> <div class="modal-content bg-dark">
<div class="modal-header"> <div class="modal-header">

View File

@ -1,8 +1,8 @@
<div class="modal" id="importLoginModal" tabindex="-1"> <div class="modal" id="importCredentialModal" tabindex="-1">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content bg-dark"> <div class="modal-content bg-dark">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title"><i class="fa fa-fw fa-key"></i> Import Credentials</h5> <h5 class="modal-title"><i class="fas fa-fw fa-key mr-2"></i>Import Credentials</h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span> <span>&times;</span>
</button> </button>

View File

@ -75,9 +75,8 @@
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT users.user_id, user_name FROM users "SELECT user_id, user_name FROM users
LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role_id > 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
WHERE user_role > 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
); );
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$user_id = intval($row['user_id']); $user_id = intval($row['user_id']);

View File

@ -1,4 +1,4 @@
<div class="modal" id="addRecurringModal" tabindex="-1"> <div class="modal" id="addRecurringInvoiceModal" tabindex="-1">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content bg-dark"> <div class="modal-content bg-dark">
<div class="modal-header"> <div class="modal-header">
@ -109,7 +109,7 @@
</div> </div>
<div class="modal-footer bg-white"> <div class="modal-footer bg-white">
<button type="submit" name="add_recurring" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button> <button type="submit" name="add_recurring_invoice" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Create</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@ -1,4 +1,4 @@
<div class="modal" id="recurringNoteModal" tabindex="-1"> <div class="modal" id="recurringInvoiceNoteModal" tabindex="-1">
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content bg-dark"> <div class="modal-content bg-dark">
<div class="modal-header"> <div class="modal-header">
@ -8,14 +8,14 @@
</button> </button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="recurring_id" value="<?php echo $recurring_id; ?>"> <input type="hidden" name="recurring_invoice_id" value="<?php echo $recurring_invoice_id; ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">
<div class="form-group"> <div class="form-group">
<textarea class="form-control" rows="8" name="note" placeholder="Enter some notes"><?php echo $recurring_note; ?></textarea> <textarea class="form-control" rows="8" name="note" placeholder="Enter some notes"><?php echo $recurring_note; ?></textarea>
</div> </div>
</div> </div>
<div class="modal-footer bg-white"> <div class="modal-footer bg-white">
<button type="submit" name="recurring_note" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button> <button type="submit" name="recurring_invoice_note" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button> <button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
</div> </div>
</form> </form>

View File

@ -1,15 +1,15 @@
<div class="modal" id="addRecurringPaymentModal<?php echo $recurring_id; ?>" tabindex="-1"> <div class="modal" id="addRecurringPaymentModal<?php echo $recurring_invoice_id; ?>" tabindex="-1">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content bg-dark"> <div class="modal-content bg-dark">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title"><i class="fa fa-fw fa-redo-alt mr-2"></i>Creating Recurring Payment: <strong><?php echo "$recurring_prefix$recurring_number"; ?></strong></h5> <h5 class="modal-title"><i class="fa fa-fw fa-redo-alt mr-2"></i>Creating Recurring Payment: <strong><?php echo "$recurring_invoice_prefix$recurring_invoice_number"; ?></strong></h5>
<button type="button" class="close text-white" data-dismiss="modal"> <button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span> <span>&times;</span>
</button> </button>
</div> </div>
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="recurring_id" value="<?php echo $recurring_id; ?>"> <input type="hidden" name="recurring_invoice_id" value="<?php echo $recurring_invoice_id; ?>">
<input type="hidden" name="currency_code" value="<?php echo $recurring_currency_code; ?>"> <input type="hidden" name="currency_code" value="<?php echo $recurring_invoice_currency_code; ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">
<div class="form-group"> <div class="form-group">

View File

@ -74,9 +74,8 @@
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT users.user_id, user_name FROM users "SELECT user_id, user_name FROM users
LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role_id > 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
WHERE user_role > 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
); );
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$user_id = intval($row['user_id']); $user_id = intval($row['user_id']);
@ -202,6 +201,31 @@
</div> </div>
</div> </div>
<div class="form-group">
<label>Additional Assets</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span>
</div>
<select class="form-control select2" name="additional_assets[]" data-tags="true" data-placeholder="- Select Additional Assets -" multiple>
<option value=""></option>
<?php
$sql_assets = mysqli_query($mysqli, "SELECT asset_id, asset_name, contact_name FROM assets LEFT JOIN contacts ON contact_id = asset_contact_id WHERE asset_client_id = $client_id AND asset_archived_at IS NULL ORDER BY asset_name ASC");
while ($row = mysqli_fetch_array($sql_assets)) {
$asset_id_select = intval($row['asset_id']);
$asset_name_select = nullable_htmlentities($row['asset_name']);
$asset_contact_name_select = nullable_htmlentities($row['contact_name']);
?>
<option value="<?php echo $asset_id_select; ?>"
><?php echo "$asset_name_select - $asset_contact_name_select"; ?>
</option>
<?php } ?>
</select>
</div>
</div>
<?php } ?> <?php } ?>
</div> </div>

View File

@ -190,14 +190,14 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="logins">Select related logins</label> <label for="logins">Select related Credentials</label>
<select class="form-control select2" id="logins" name="logins[]" multiple> <select class="form-control select2" id="credentials" name="credentials[]" multiple>
<?php <?php
$sql = mysqli_query($mysqli, "SELECT * FROM logins WHERE login_archived_at IS NULL AND login_client_id = $client_id"); $sql = mysqli_query($mysqli, "SELECT * FROM credentials WHERE credential_archived_at IS NULL AND credential_client_id = $client_id");
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$login_id = intval($row['login_id']); $credential_id = intval($row['credential_id']);
$login_name = nullable_htmlentities($row['login_name']); $credential_name = nullable_htmlentities($row['credential_name']);
echo "<option value=\"$login_id\">$login_name</option>"; echo "<option value=\"$credential_id\">$credential_name</option>";
} }
?> ?>
</select> </select>

View File

@ -178,9 +178,8 @@
$sql = mysqli_query( $sql = mysqli_query(
$mysqli, $mysqli,
"SELECT users.user_id, user_name FROM users "SELECT user_id, user_name FROM users
LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role_id > 1
WHERE user_role > 1
AND user_type = 1 AND user_type = 1
AND user_status = 1 AND user_status = 1
AND user_archived_at IS NULL AND user_archived_at IS NULL
@ -287,7 +286,7 @@
<div class="tab-pane fade" id="pills-assignment"> <div class="tab-pane fade" id="pills-assignment">
<div class="form-group"> <div class="form-group">
<label>Asset</label> <label>Primary Asset</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span> <span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span>
@ -312,6 +311,32 @@
</div> </div>
</div> </div>
<div class="form-group">
<label>Additional Assets</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-desktop"></i></span>
</div>
<select class="form-control select2" name="additional_assets[]" data-tags="true" data-placeholder="- Select Additional Assets -" multiple>
<option value=""></option>
<?php
$sql_assets = mysqli_query($mysqli, "SELECT asset_id, asset_name, contact_name FROM assets LEFT JOIN contacts ON contact_id = asset_contact_id WHERE asset_client_id = $client_id AND asset_archived_at IS NULL ORDER BY asset_name ASC");
while ($row = mysqli_fetch_array($sql_assets)) {
$asset_id_select = intval($row['asset_id']);
$asset_name_select = nullable_htmlentities($row['asset_name']);
$asset_contact_name_select = nullable_htmlentities($row['contact_name']);
?>
<option value="<?php echo $asset_id_select; ?>"
<?php if (isset($_GET['asset_id']) && $asset_id_select == $_GET['asset_id']) { echo "selected"; }
?>
><?php echo "$asset_name_select - $asset_contact_name_select"; ?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label>Location</label> <label>Location</label>
<div class="input-group"> <div class="input-group">

View File

@ -20,7 +20,6 @@
<?php <?php
$sql_users_select = mysqli_query($mysqli, "SELECT users.user_id, user_name FROM users $sql_users_select = mysqli_query($mysqli, "SELECT users.user_id, user_name FROM users
LEFT JOIN user_settings on users.user_id = user_settings.user_id LEFT JOIN user_settings on users.user_id = user_settings.user_id
WHERE user_role > 1
AND user_type = 1 AND user_type = 1
AND user_status = 1 AND user_status = 1
AND user_archived_at IS NULL AND user_archived_at IS NULL

View File

@ -89,9 +89,8 @@
<option value="">- Driver -</option> <option value="">- Driver -</option>
<?php <?php
$sql = mysqli_query($mysqli, "SELECT users.user_id, user_name FROM users $sql = mysqli_query($mysqli, "SELECT user_id, user_name FROM users
LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_role_id > 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
WHERE user_role > 1 AND user_archived_at IS NULL ORDER BY user_name ASC"
); );
while ($row = mysqli_fetch_array($sql)) { while ($row = mysqli_fetch_array($sql)) {
$user_id = intval($row['user_id']); $user_id = intval($row['user_id']);

View File

@ -4,13 +4,12 @@
* *
* To rebuild or modify this file with the latest versions of the included * To rebuild or modify this file with the latest versions of the included
* software please visit: * software please visit:
* https://datatables.net/download/#bs4/dt-2.2.1 * https://datatables.net/download/#bs4/dt-2.2.2
* *
* Included libraries: * Included libraries:
* DataTables 2.2.1 * DataTables 2.2.2
*/ */
@charset "UTF-8";
:root { :root {
--dt-row-selected: 2, 117, 216; --dt-row-selected: 2, 117, 216;
--dt-row-selected-text: 255, 255, 255; --dt-row-selected-text: 255, 255, 255;
@ -93,8 +92,8 @@ table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:before {
position: absolute; position: absolute;
display: block; display: block;
bottom: 50%; bottom: 50%;
content: ""; content: "\25B2";
content: ""/""; content: "\25B2"/"";
} }
table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after, table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after,
table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:after, table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:after,
@ -102,8 +101,8 @@ table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:after {
position: absolute; position: absolute;
display: block; display: block;
top: 50%; top: 50%;
content: ""; content: "\25BC";
content: ""/""; content: "\25BC"/"";
} }
table.dataTable thead > tr > th.dt-orderable-asc, table.dataTable thead > tr > th.dt-orderable-desc, table.dataTable thead > tr > th.dt-ordering-asc, table.dataTable thead > tr > th.dt-ordering-desc, table.dataTable thead > tr > th.dt-orderable-asc, table.dataTable thead > tr > th.dt-orderable-desc, table.dataTable thead > tr > th.dt-ordering-asc, table.dataTable thead > tr > th.dt-ordering-desc,
table.dataTable thead > tr > td.dt-orderable-asc, table.dataTable thead > tr > td.dt-orderable-asc,

View File

@ -4,13 +4,13 @@
* *
* To rebuild or modify this file with the latest versions of the included * To rebuild or modify this file with the latest versions of the included
* software please visit: * software please visit:
* https://datatables.net/download/#bs4/dt-2.2.1 * https://datatables.net/download/#bs4/dt-2.2.2
* *
* Included libraries: * Included libraries:
* DataTables 2.2.1 * DataTables 2.2.2
*/ */
/*! DataTables 2.2.1 /*! DataTables 2.2.2
* © SpryMedia Ltd - datatables.net/license * © SpryMedia Ltd - datatables.net/license
*/ */
@ -519,7 +519,7 @@
* *
* @type string * @type string
*/ */
builder: "bs4/dt-2.2.1", builder: "bs4/dt-2.2.2",
/** /**
@ -5556,6 +5556,15 @@
// This flag allows the above to be satisfied. // This flag allows the above to be satisfied.
var first = $(settings.nTableWrapper).is(':visible'); var first = $(settings.nTableWrapper).is(':visible');
// Use an empty div to attach the observer so it isn't impacted by height changes
var resizer = $('<div>')
.css({
width: '100%',
height: 0
})
.addClass('dt-autosize')
.appendTo(settings.nTableWrapper);
settings.resizeObserver = new ResizeObserver(function (e) { settings.resizeObserver = new ResizeObserver(function (e) {
if (first) { if (first) {
first = false; first = false;
@ -5565,7 +5574,7 @@
} }
}); });
settings.resizeObserver.observe(settings.nTableWrapper); settings.resizeObserver.observe(resizer[0]);
} }
else { else {
// For old browsers, the best we can do is listen for a window resize // For old browsers, the best we can do is listen for a window resize
@ -5897,10 +5906,14 @@
displayMaster = oSettings.aiDisplayMaster, displayMaster = oSettings.aiDisplayMaster,
aSort; aSort;
// Make sure the columns all have types defined
_fnColumnTypes(oSettings);
// Allow a specific column to be sorted, which will _not_ alter the display // Allow a specific column to be sorted, which will _not_ alter the display
// master // master
if (col !== undefined) { if (col !== undefined) {
var srcCol = oSettings.aoColumns[col]; var srcCol = oSettings.aoColumns[col];
aSort = [{ aSort = [{
src: col, src: col,
col: col, col: col,
@ -9844,12 +9857,14 @@
// Function to run either once the table becomes ready or // Function to run either once the table becomes ready or
// immediately if it is already ready. // immediately if it is already ready.
return this.tables().every(function () { return this.tables().every(function () {
var api = this;
if (this.context[0]._bInitComplete) { if (this.context[0]._bInitComplete) {
fn.call(this); fn.call(api);
} }
else { else {
this.on('init.dt.DT', function () { this.on('init.dt.DT', function () {
fn.call(this); fn.call(api);
}); });
} }
} ); } );
@ -9905,20 +9920,37 @@
jqTable.append( tfoot ); jqTable.append( tfoot );
} }
// Clean up the header
$(thead).find('span.dt-column-order').remove();
$(thead).find('span.dt-column-title').each(function () {
var title = $(this).html();
$(this).parent().append(title);
$(this).remove();
});
settings.colgroup.remove(); settings.colgroup.remove();
settings.aaSorting = []; settings.aaSorting = [];
settings.aaSortingFixed = []; settings.aaSortingFixed = [];
_fnSortingClasses( settings ); _fnSortingClasses( settings );
$(jqTable).find('th, td').removeClass(
$.map(DataTable.ext.type.className, function (v) {
return v;
}).join(' ')
);
$('th, td', thead) $('th, td', thead)
.removeClass( .removeClass(
orderClasses.none + ' ' +
orderClasses.canAsc + ' ' + orderClasses.canAsc + ' ' +
orderClasses.canDesc + ' ' + orderClasses.canDesc + ' ' +
orderClasses.isAsc + ' ' + orderClasses.isAsc + ' ' +
orderClasses.isDesc orderClasses.isDesc
) )
.css('width', ''); .css('width', '')
.removeAttr('data-dt-column')
.removeAttr('aria-sort');
// Add the TR elements back into the table in their original order // Add the TR elements back into the table in their original order
jqTbody.children().detach(); jqTbody.children().detach();
@ -10006,7 +10038,7 @@
* @type string * @type string
* @default Version number * @default Version number
*/ */
DataTable.version = "2.2.1"; DataTable.version = "2.2.2";
/** /**
* Private data store, containing all of the settings objects that are * Private data store, containing all of the settings objects that are
@ -13047,16 +13079,16 @@
cell.removeAttr('aria-sort'); cell.removeAttr('aria-sort');
} }
cell.attr('aria-label', orderable
? col.ariaTitle + ctx.api.i18n('oAria.orderable' + ariaType)
: col.ariaTitle
);
// Make the headers tab-able for keyboard navigation // Make the headers tab-able for keyboard navigation
if (orderable) { if (orderable) {
var orderSpan = cell.find('.dt-column-order'); var orderSpan = cell.find('.dt-column-order');
orderSpan.attr('role', 'button'); orderSpan
.attr('role', 'button')
.attr('aria-label', orderable
? col.ariaTitle + ctx.api.i18n('oAria.orderable' + ariaType)
: col.ariaTitle
);
if (tabIndex !== -1) { if (tabIndex !== -1) {
orderSpan.attr('tabindex', tabIndex); orderSpan.attr('tabindex', tabIndex);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
/** /**
* TinyMCE version 7.6.1 (2025-01-22) * TinyMCE version 7.7.1 (2025-03-05)
*/ */
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=(t,e,s)=>{const r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===s?null:{"list-style-type":s})},s=t=>e=>e.options.get(t),r=s("advlist_number_styles"),n=s("advlist_bullet_styles"),l=t=>null==t,i=t=>!l(t);class o{constructor(t,e){this.tag=t,this.value=e}static some(t){return new o(!0,t)}static none(){return o.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?o.some(t(this.value)):o.none()}bind(t){return this.tag?t(this.value):o.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:o.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return i(t)?o.some(t):o.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}o.singletonNone=new o(!1);const a=Array.prototype.indexOf,u=Object.keys;var d=tinymce.util.Tools.resolve("tinymce.util.Tools");const c=t=>e=>i(e)&&t.test(e.nodeName),h=c(/^(OL|UL|DL)$/),g=c(/^(TH|TD)$/),p=t=>l(t)||"default"===t?"":t,m=(t,e)=>s=>((t,e)=>{const s=t.selection.getNode();return e({parents:t.dom.getParents(s),element:s}),t.on("NodeChange",e),()=>t.off("NodeChange",e)})(t,(r=>((t,r)=>{const n=t.selection.getStart(!0);s.setActive(((t,e,s)=>((t,e,s)=>{for(let e=0,n=t.length;e<n;e++){const n=t[e];if(h(r=n)&&!/\btox\-/.test(r.className))return o.some(n);if(s(n,e))break}var r;return o.none()})(e,0,g).exists((e=>e.nodeName===s&&((t,e)=>t.dom.isChildOf(e,t.getBody()))(t,e))))(t,r,e)),s.setEnabled(!((t,e)=>{const s=t.dom.getParent(e,"ol,ul,dl");return((t,e)=>null!==e&&!t.dom.isEditable(e))(t,s)||!t.selection.isEditable()})(t,n))})(t,r.parents))),v=(t,s,r,n,l,i)=>{const c={"lower-latin":"lower-alpha","upper-latin":"upper-alpha","lower-alpha":"lower-latin","upper-alpha":"upper-latin"},h=(g=t=>{return e=i,s=t,a.call(e,s)>-1;var e,s},((t,e)=>{const s={};return((t,e)=>{const s=u(t);for(let r=0,n=s.length;r<n;r++){const n=s[r];e(t[n],n)}})(t,((t,r)=>{const n=e(t,r);s[n.k]=n.v})),s})(c,((t,e)=>({k:e,v:g(t)}))));var g;t.ui.registry.addSplitButton(s,{tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",presets:"listpreview",columns:3,fetch:t=>{t(d.map(i,(t=>{const e="OL"===l?"num":"bull",s="disc"===t||"decimal"===t?"default":t,r=p(t),n=(t=>t.replace(/\-/g," ").replace(/\b\w/g,(t=>t.toUpperCase())))(t);return{type:"choiceitem",value:r,icon:"list-"+e+"-"+s,text:n}})))},onAction:()=>t.execCommand(n),onItemAction:(s,r)=>{e(t,l,r)},select:e=>{const s=(t=>{const e=t.dom.getParent(t.selection.getNode(),"ol,ul"),s=t.dom.getStyle(e,"listStyleType");return o.from(s)})(t);return s.exists((t=>e===t||c[t]===e&&!h[e]))},onSetup:m(t,l)})},y=(t,s,r,n,l,i)=>{i.length>1?v(t,s,r,n,l,i):((t,s,r,n,l,i)=>{t.ui.registry.addToggleButton(s,{active:!1,tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",onSetup:m(t,l),onAction:()=>t.queryCommandState(n)||""===i?t.execCommand(n):e(t,l,i)})})(t,s,r,n,l,p(i[0]))};t.add("advlist",(t=>{t.hasPlugin("lists")?((t=>{const e=t.options.register;e("advlist_number_styles",{processor:"string[]",default:"default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman".split(",")}),e("advlist_bullet_styles",{processor:"string[]",default:"default,circle,square".split(",")})})(t),(t=>{y(t,"numlist","Numbered list","InsertOrderedList","OL",r(t)),y(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))})(t),(t=>{t.addCommand("ApplyUnorderedListStyle",((s,r)=>{e(t,"UL",r["list-style-type"])})),t.addCommand("ApplyOrderedListStyle",((s,r)=>{e(t,"OL",r["list-style-type"])}))})(t)):console.error("Please use the Lists plugin together with the List Styles plugin.")}))}(); !function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=(t,e,s)=>{const r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===s?null:{"list-style-type":s})},s=t=>e=>e.options.get(t),r=s("advlist_number_styles"),n=s("advlist_bullet_styles"),l=t=>null==t,i=t=>!l(t);class o{constructor(t,e){this.tag=t,this.value=e}static some(t){return new o(!0,t)}static none(){return o.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?o.some(t(this.value)):o.none()}bind(t){return this.tag?t(this.value):o.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:o.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return i(t)?o.some(t):o.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}o.singletonNone=new o(!1);const a=Array.prototype.indexOf,u=Object.keys;var d=tinymce.util.Tools.resolve("tinymce.util.Tools");const c=t=>e=>i(e)&&t.test(e.nodeName),h=c(/^(OL|UL|DL)$/),g=c(/^(TH|TD)$/),p=t=>l(t)||"default"===t?"":t,m=(t,e)=>s=>((t,e)=>{const s=t.selection.getNode();return e({parents:t.dom.getParents(s),element:s}),t.on("NodeChange",e),()=>t.off("NodeChange",e)})(t,(r=>((t,r)=>{const n=t.selection.getStart(!0);s.setActive(((t,e,s)=>((t,e,s)=>{for(let e=0,n=t.length;e<n;e++){const n=t[e];if(h(r=n)&&!/\btox\-/.test(r.className))return o.some(n);if(s(n,e))break}var r;return o.none()})(e,0,g).exists((e=>e.nodeName===s&&((t,e)=>t.dom.isChildOf(e,t.getBody()))(t,e))))(t,r,e)),s.setEnabled(!((t,e)=>{const s=t.dom.getParent(e,"ol,ul,dl");return((t,e)=>null!==e&&!t.dom.isEditable(e))(t,s)||!t.selection.isEditable()})(t,n))})(t,r.parents))),v=(t,s,r,n,l,i)=>{const c={"lower-latin":"lower-alpha","upper-latin":"upper-alpha","lower-alpha":"lower-latin","upper-alpha":"upper-latin"},h=(g=t=>{return e=i,s=t,a.call(e,s)>-1;var e,s},((t,e)=>{const s={};return((t,e)=>{const s=u(t);for(let r=0,n=s.length;r<n;r++){const n=s[r];e(t[n],n)}})(t,((t,r)=>{const n=e(t,r);s[n.k]=n.v})),s})(c,((t,e)=>({k:e,v:g(t)}))));var g;t.ui.registry.addSplitButton(s,{tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",presets:"listpreview",columns:3,fetch:t=>{t(d.map(i,(t=>{const e="OL"===l?"num":"bull",s="disc"===t||"decimal"===t?"default":t,r=p(t),n=(t=>t.replace(/\-/g," ").replace(/\b\w/g,(t=>t.toUpperCase())))(t);return{type:"choiceitem",value:r,icon:"list-"+e+"-"+s,text:n}})))},onAction:()=>t.execCommand(n),onItemAction:(s,r)=>{e(t,l,r)},select:e=>{const s=(t=>{const e=t.dom.getParent(t.selection.getNode(),"ol,ul"),s=t.dom.getStyle(e,"listStyleType");return o.from(s)})(t);return s.exists((t=>e===t||c[t]===e&&!h[e]))},onSetup:m(t,l)})},y=(t,s,r,n,l,i)=>{i.length>1?v(t,s,r,n,l,i):((t,s,r,n,l,i)=>{t.ui.registry.addToggleButton(s,{active:!1,tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",onSetup:m(t,l),onAction:()=>t.queryCommandState(n)||""===i?t.execCommand(n):e(t,l,i)})})(t,s,r,n,l,p(i[0]))};t.add("advlist",(t=>{t.hasPlugin("lists")?((t=>{const e=t.options.register;e("advlist_number_styles",{processor:"string[]",default:"default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman".split(",")}),e("advlist_bullet_styles",{processor:"string[]",default:"default,circle,square".split(",")})})(t),(t=>{y(t,"numlist","Numbered list","InsertOrderedList","OL",r(t)),y(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))})(t),(t=>{t.addCommand("ApplyUnorderedListStyle",((s,r)=>{e(t,"UL",r["list-style-type"])})),t.addCommand("ApplyOrderedListStyle",((s,r)=>{e(t,"OL",r["list-style-type"])}))})(t)):console.error("Please use the Lists plugin together with the List Styles plugin.")}))}();

View File

@ -1,4 +1,4 @@
/** /**
* TinyMCE version 7.6.1 (2025-01-22) * TinyMCE version 7.7.1 (2025-03-05)
*/ */
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=("allow_html_in_named_anchor",e=>e.options.get("allow_html_in_named_anchor"));const a="a:not([href])",r=e=>!e,i=e=>e.getAttribute("id")||e.getAttribute("name")||"",l=e=>(e=>"a"===e.nodeName.toLowerCase())(e)&&!e.getAttribute("href")&&""!==i(e),s=e=>e.dom.getParent(e.selection.getStart(),a),d=(e,a)=>{const r=s(e);r?((e,t,o)=>{o.removeAttribute("name"),o.id=t,e.addVisual(),e.undoManager.add()})(e,a,r):((e,a)=>{e.undoManager.transact((()=>{n(e)||e.selection.collapse(!0),e.selection.isCollapsed()?e.insertContent(e.dom.createHTML("a",{id:a})):((e=>{const n=e.dom;t(n).walk(e.selection.getRng(),(e=>{o.each(e,(e=>{var t;l(t=e)&&!t.firstChild&&n.remove(e,!1)}))}))})(e),e.formatter.remove("namedAnchor",void 0,void 0,!0),e.formatter.apply("namedAnchor",{value:a}),e.addVisual())}))})(e,a),e.focus()},c=e=>(e=>r(e.attr("href"))&&!r(e.attr("id")||e.attr("name")))(e)&&!e.firstChild,m=e=>t=>{for(let o=0;o<t.length;o++){const n=t[o];c(n)&&n.attr("contenteditable",e)}},u=e=>t=>{const o=()=>{t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",o),o(),()=>{e.off("NodeChange",o)}};e.add("anchor",(e=>{(e=>{(0,e.options.register)("allow_html_in_named_anchor",{processor:"boolean",default:!1})})(e),(e=>{e.on("PreInit",(()=>{e.parser.addNodeFilter("a",m("false")),e.serializer.addNodeFilter("a",m(null))}))})(e),(e=>{e.addCommand("mceAnchor",(()=>{(e=>{const t=(e=>{const t=s(e);return t?i(t):""})(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:t=>{((e,t)=>/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)?(d(e,t),!0):(e.windowManager.alert("ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!1))(e,t.getData().id)&&t.close()}})})(e)}))})(e),(e=>{const t=()=>e.execCommand("mceAnchor");e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:t,onSetup:t=>{const o=e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind,n=u(e)(t);return()=>{o(),n()}}}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:t,onSetup:u(e)})})(e),e.on("PreInit",(()=>{(e=>{e.formatter.register("namedAnchor",{inline:"a",selector:a,remove:"all",split:!0,deep:!0,attributes:{id:"%value"},onmatch:(e,t,o)=>l(e)})})(e)}))}))}(); !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=e=>e.options.get("allow_html_in_named_anchor");const a="a:not([href])",r=e=>!e,i=e=>e.getAttribute("id")||e.getAttribute("name")||"",l=e=>(e=>"a"===e.nodeName.toLowerCase())(e)&&!e.getAttribute("href")&&""!==i(e),s=e=>e.dom.getParent(e.selection.getStart(),a),d=(e,a)=>{const r=s(e);r?((e,t,o)=>{o.removeAttribute("name"),o.id=t,e.addVisual(),e.undoManager.add()})(e,a,r):((e,a)=>{e.undoManager.transact((()=>{n(e)||e.selection.collapse(!0),e.selection.isCollapsed()?e.insertContent(e.dom.createHTML("a",{id:a})):((e=>{const n=e.dom;t(n).walk(e.selection.getRng(),(e=>{o.each(e,(e=>{var t;l(t=e)&&!t.firstChild&&n.remove(e,!1)}))}))})(e),e.formatter.remove("namedAnchor",void 0,void 0,!0),e.formatter.apply("namedAnchor",{value:a}),e.addVisual())}))})(e,a),e.focus()},c=e=>(e=>r(e.attr("href"))&&!r(e.attr("id")||e.attr("name")))(e)&&!e.firstChild,m=e=>t=>{for(let o=0;o<t.length;o++){const n=t[o];c(n)&&n.attr("contenteditable",e)}},u=e=>t=>{const o=()=>{t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",o),o(),()=>{e.off("NodeChange",o)}};e.add("anchor",(e=>{(e=>{(0,e.options.register)("allow_html_in_named_anchor",{processor:"boolean",default:!1})})(e),(e=>{e.on("PreInit",(()=>{e.parser.addNodeFilter("a",m("false")),e.serializer.addNodeFilter("a",m(null))}))})(e),(e=>{e.addCommand("mceAnchor",(()=>{(e=>{const t=(e=>{const t=s(e);return t?i(t):""})(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:t=>{((e,t)=>/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)?(d(e,t),!0):(e.windowManager.alert("ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!1))(e,t.getData().id)&&t.close()}})})(e)}))})(e),(e=>{const t=()=>e.execCommand("mceAnchor");e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:t,onSetup:t=>{const o=e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind,n=u(e)(t);return()=>{o(),n()}}}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:t,onSetup:u(e)})})(e),e.on("PreInit",(()=>{(e=>{e.formatter.register("namedAnchor",{inline:"a",selector:a,remove:"all",split:!0,deep:!0,attributes:{id:"%value"},onmatch:(e,t,o)=>l(e)})})(e)}))}))}();

View File

@ -1,4 +1,4 @@
/** /**
* TinyMCE version 7.6.1 (2025-01-22) * TinyMCE version 7.7.1 (2025-03-05)
*/ */
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),n=t("autolink_pattern"),o=t("link_default_target"),r=t("link_default_protocol"),a=t("allow_unsafe_link_target"),s=("string",e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(a=o.constructor)||void 0===a?void 0:a.name)===r.name)?"string":t;var n,o,r,a})(e));const l=(void 0,e=>undefined===e);const i=e=>!(e=>null==e)(e),c=Object.hasOwnProperty,d=e=>"\ufeff"===e;var u=tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");const f=e=>/^[(\[{ \u00a0]$/.test(e),g=(e,t,n)=>{for(let o=t-1;o>=0;o--){const t=e.charAt(o);if(!d(t)&&n(t))return o}return-1},m=(e,t)=>{var o;const a=e.schema.getVoidElements(),s=n(e),{dom:i,selection:d}=e;if(null!==i.getParent(d.getNode(),"a[href]")||e.mode.isReadOnly())return null;const m=d.getRng(),k=u(i,(e=>{return i.isBlock(e)||(t=a,n=e.nodeName.toLowerCase(),c.call(t,n))||"false"===i.getContentEditable(e);var t,n})),{container:p,offset:y}=((e,t)=>{let n=e,o=t;for(;1===n.nodeType&&n.childNodes[o];)n=n.childNodes[o],o=3===n.nodeType?n.data.length:n.childNodes.length;return{container:n,offset:o}})(m.endContainer,m.endOffset),w=null!==(o=i.getParent(p,i.isBlock))&&void 0!==o?o:i.getRoot(),h=k.backwards(p,y+t,((e,t)=>{const n=e.data,o=g(n,t,(r=f,e=>!r(e)));var r,a;return-1===o||(a=n[o],/[?!,.;:]/.test(a))?o:o+1}),w);if(!h)return null;let v=h.container;const _=k.backwards(h.container,h.offset,((e,t)=>{v=e;const n=g(e.data,t,f);return-1===n?n:n+1}),w),A=i.createRng();_?A.setStart(_.container,_.offset):A.setStart(v,0),A.setEnd(h.container,h.offset);const C=A.toString().replace(/\uFEFF/g,"").match(s);if(C){let t=C[0];return $="www.",(b=t).length>=4&&b.substr(0,4)===$?t=r(e)+"://"+t:((e,t,n=0,o)=>{const r=e.indexOf(t,n);return-1!==r&&(!!l(o)||r+t.length<=o)})(t,"@")&&!(e=>/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t)&&(t="mailto:"+t),{rng:A,url:t}}var b,$;return null},k=(e,t)=>{const{dom:n,selection:r}=e,{rng:l,url:i}=t,c=r.getBookmark();r.setRng(l);const d="createlink",u={command:d,ui:!1,value:i};if(!e.dispatch("BeforeExecCommand",u).isDefaultPrevented()){e.getDoc().execCommand(d,!1,i),e.dispatch("ExecCommand",u);const t=o(e);if(s(t)){const o=r.getNode();n.setAttrib(o,"target",t),"_blank"!==t||a(e)||n.setAttrib(o,"rel","noopener")}}r.moveToBookmark(c),e.nodeChanged()},p=e=>{const t=m(e,-1);i(t)&&k(e,t)},y=p;e.add("autolink",(e=>{(e=>{const t=e.options.register;t("autolink_pattern",{processor:"regexp",default:new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i")}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"})})(e),(e=>{e.on("keydown",(t=>{13!==t.keyCode||t.isDefaultPrevented()||(e=>{const t=m(e,0);i(t)&&k(e,t)})(e)})),e.on("keyup",(t=>{32===t.keyCode?p(e):(48===t.keyCode&&t.shiftKey||221===t.keyCode)&&y(e)}))})(e)}))}(); !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),n=t("autolink_pattern"),o=t("link_default_target"),r=t("link_default_protocol"),a=t("allow_unsafe_link_target"),s=e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(a=o.constructor)||void 0===a?void 0:a.name)===r.name)?"string":t;var n,o,r,a})(e);const l=e=>undefined===e;const i=e=>!(e=>null==e)(e),c=Object.hasOwnProperty,d=e=>"\ufeff"===e;var u=tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");const f=e=>/^[(\[{ \u00a0]$/.test(e),g=(e,t,n)=>{for(let o=t-1;o>=0;o--){const t=e.charAt(o);if(!d(t)&&n(t))return o}return-1},m=(e,t)=>{var o;const a=e.schema.getVoidElements(),s=n(e),{dom:i,selection:d}=e;if(null!==i.getParent(d.getNode(),"a[href]")||e.mode.isReadOnly())return null;const m=d.getRng(),k=u(i,(e=>{return i.isBlock(e)||(t=a,n=e.nodeName.toLowerCase(),c.call(t,n))||"false"===i.getContentEditable(e);var t,n})),{container:p,offset:y}=((e,t)=>{let n=e,o=t;for(;1===n.nodeType&&n.childNodes[o];)n=n.childNodes[o],o=3===n.nodeType?n.data.length:n.childNodes.length;return{container:n,offset:o}})(m.endContainer,m.endOffset),w=null!==(o=i.getParent(p,i.isBlock))&&void 0!==o?o:i.getRoot(),h=k.backwards(p,y+t,((e,t)=>{const n=e.data,o=g(n,t,(r=f,e=>!r(e)));var r,a;return-1===o||(a=n[o],/[?!,.;:]/.test(a))?o:o+1}),w);if(!h)return null;let v=h.container;const _=k.backwards(h.container,h.offset,((e,t)=>{v=e;const n=g(e.data,t,f);return-1===n?n:n+1}),w),A=i.createRng();_?A.setStart(_.container,_.offset):A.setStart(v,0),A.setEnd(h.container,h.offset);const C=A.toString().replace(/\uFEFF/g,"").match(s);if(C){let t=C[0];return $="www.",(b=t).length>=4&&b.substr(0,4)===$?t=r(e)+"://"+t:((e,t,n=0,o)=>{const r=e.indexOf(t,n);return-1!==r&&(!!l(o)||r+t.length<=o)})(t,"@")&&!(e=>/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t)&&(t="mailto:"+t),{rng:A,url:t}}var b,$;return null},k=(e,t)=>{const{dom:n,selection:r}=e,{rng:l,url:i}=t,c=r.getBookmark();r.setRng(l);const d="createlink",u={command:d,ui:!1,value:i};if(!e.dispatch("BeforeExecCommand",u).isDefaultPrevented()){e.getDoc().execCommand(d,!1,i),e.dispatch("ExecCommand",u);const t=o(e);if(s(t)){const o=r.getNode();n.setAttrib(o,"target",t),"_blank"!==t||a(e)||n.setAttrib(o,"rel","noopener")}}r.moveToBookmark(c),e.nodeChanged()},p=e=>{const t=m(e,-1);i(t)&&k(e,t)},y=p;e.add("autolink",(e=>{(e=>{const t=e.options.register;t("autolink_pattern",{processor:"regexp",default:new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i")}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"})})(e),(e=>{e.on("keydown",(t=>{13!==t.keyCode||t.isDefaultPrevented()||(e=>{const t=m(e,0);i(t)&&k(e,t)})(e)})),e.on("keyup",(t=>{32===t.keyCode?p(e):(48===t.keyCode&&t.shiftKey||221===t.keyCode)&&y(e)}))})(e)}))}();

View File

@ -1,4 +1,4 @@
/** /**
* TinyMCE version 7.6.1 (2025-01-22) * TinyMCE version 7.7.1 (2025-03-05)
*/ */
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env");const o=e=>t=>t.options.get(e),n=o("min_height"),s=o("max_height"),i=o("autoresize_overflow_padding"),r=o("autoresize_bottom_margin"),g=(e,t)=>{const o=e.getBody();o&&(o.style.overflowY=t?"":"hidden",t||(o.scrollTop=0))},l=(e,t,o,n)=>{var s;const i=parseInt(null!==(s=e.getStyle(t,o,n))&&void 0!==s?s:"",10);return isNaN(i)?0:i},a=(e,o,r,c)=>{var d;const u=e.dom,h=e.getDoc();if(!h)return;if((e=>e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen())(e))return void g(e,!0);const m=h.documentElement,f=c?c():i(e),p=null!==(d=n(e))&&void 0!==d?d:e.getElement().offsetHeight;let y=p;const S=l(u,m,"margin-top",!0),v=l(u,m,"margin-bottom",!0);let C=m.offsetHeight+S+v+f;C<0&&(C=0);const H=e.getContainer().offsetHeight-e.getContentAreaContainer().offsetHeight;C+H>p&&(y=C+H);const b=s(e);b&&y>b?(y=b,g(e,!0)):g(e,!1);const w=o.get();if(w.set&&(e.dom.setStyles(e.getDoc().documentElement,{"min-height":0}),e.dom.setStyles(e.getBody(),{"min-height":"inherit"})),y!==w.totalHeight&&(C-f!==w.contentHeight||!w.set)){const n=y-w.totalHeight;if(u.setStyle(e.getContainer(),"height",y+"px"),o.set({totalHeight:y,contentHeight:C,set:!0}),(e=>{e.dispatch("ResizeEditor")})(e),t.browser.isSafari()&&(t.os.isMacOS()||t.os.isiOS())){const t=e.getWin();t.scrollTo(t.pageXOffset,t.pageYOffset)}e.hasFocus()&&(e=>{if("setcontent"===(null==e?void 0:e.type.toLowerCase())){const t=e;return!0===t.selection||!0===t.paste}return!1})(r)&&e.selection.scrollIntoView(),(t.browser.isSafari()||t.browser.isChromium())&&n<0&&a(e,o,r,c)}};e.add("autoresize",(e=>{if((e=>{const t=e.options.register;t("autoresize_overflow_padding",{processor:"number",default:1}),t("autoresize_bottom_margin",{processor:"number",default:50})})(e),e.options.isSet("resize")||e.options.set("resize",!1),!e.inline){const o=(e=>{let t={totalHeight:0,contentHeight:0,set:!1};return{get:()=>t,set:e=>{t=e}}})();((e,t)=>{e.addCommand("mceAutoResize",(()=>{a(e,t)}))})(e,o),((e,o)=>{const n=()=>r(e);e.on("init",(s=>{const r=i(e),g=e.dom;g.setStyles(e.getDoc().documentElement,{height:"auto"}),t.browser.isEdge()||t.browser.isIE()?g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r,"min-height":0}):g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r}),a(e,o,s,n)})),e.on("NodeChange SetContent keyup FullscreenStateChanged ResizeContent",(t=>{a(e,o,t,n)}))})(e,o)}}))}(); !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env");const o=e=>t=>t.options.get(e),n=o("min_height"),s=o("max_height"),i=o("autoresize_overflow_padding"),r=o("autoresize_bottom_margin"),g=(e,t)=>{const o=e.getBody();o&&(o.style.overflowY=t?"":"hidden",t||(o.scrollTop=0))},l=(e,t,o,n)=>{var s;const i=parseInt(null!==(s=e.getStyle(t,o,n))&&void 0!==s?s:"",10);return isNaN(i)?0:i},a=(e,o,r,c)=>{var d;const u=e.dom,h=e.getDoc();if(!h)return;if((e=>e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen())(e))return void g(e,!0);const m=h.documentElement,f=c?c():i(e),p=null!==(d=n(e))&&void 0!==d?d:e.getElement().offsetHeight;let y=p;const S=l(u,m,"margin-top",!0),v=l(u,m,"margin-bottom",!0);let C=m.offsetHeight+S+v+f;C<0&&(C=0);const H=e.getContainer().offsetHeight-e.getContentAreaContainer().offsetHeight;C+H>p&&(y=C+H);const b=s(e);b&&y>b?(y=b,g(e,!0)):g(e,!1);const w=o.get();if(w.set&&(e.dom.setStyles(e.getDoc().documentElement,{"min-height":0}),e.dom.setStyles(e.getBody(),{"min-height":"inherit"})),y!==w.totalHeight&&(C-f!==w.contentHeight||!w.set)){const n=y-w.totalHeight;if(u.setStyle(e.getContainer(),"height",y+"px"),o.set({totalHeight:y,contentHeight:C,set:!0}),(e=>{e.dispatch("ResizeEditor")})(e),t.browser.isSafari()&&(t.os.isMacOS()||t.os.isiOS())){const t=e.getWin();t.scrollTo(t.pageXOffset,t.pageYOffset)}e.hasFocus()&&(e=>{if("setcontent"===(null==e?void 0:e.type.toLowerCase())){const t=e;return!0===t.selection||!0===t.paste}return!1})(r)&&e.selection.scrollIntoView(),(t.browser.isSafari()||t.browser.isChromium())&&n<0&&a(e,o,r,c)}};e.add("autoresize",(e=>{if((e=>{const t=e.options.register;t("autoresize_overflow_padding",{processor:"number",default:1}),t("autoresize_bottom_margin",{processor:"number",default:50})})(e),e.options.isSet("resize")||e.options.set("resize",!1),!e.inline){const o=(()=>{let e={totalHeight:0,contentHeight:0,set:!1};return{get:()=>e,set:t=>{e=t}}})();((e,t)=>{e.addCommand("mceAutoResize",(()=>{a(e,t)}))})(e,o),((e,o)=>{const n=()=>r(e);e.on("init",(s=>{const r=i(e),g=e.dom;g.setStyles(e.getDoc().documentElement,{height:"auto"}),t.browser.isEdge()||t.browser.isIE()?g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r,"min-height":0}):g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r}),a(e,o,s,n)})),e.on("NodeChange SetContent keyup FullscreenStateChanged ResizeContent",(t=>{a(e,o,t,n)}))})(e,o)}}))}();

View File

@ -1,4 +1,4 @@
/** /**
* TinyMCE version 7.6.1 (2025-01-22) * TinyMCE version 7.7.1 (2025-03-05)
*/ */
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=("string",t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(a=String).prototype.isPrototypeOf(r)||(null===(s=o.constructor)||void 0===s?void 0:s.name)===a.name)?"string":e;var r,o,a,s})(t));const r=(void 0,t=>undefined===t);var o=tinymce.util.Tools.resolve("tinymce.util.Delay"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),s=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=t=>{const e=/^(\d+)([ms]?)$/.exec(t);return(e&&e[2]?{s:1e3,m:6e4}[e[2]]:1)*parseInt(t,10)},i=t=>e=>e.options.get(t),u=i("autosave_ask_before_unload"),l=i("autosave_restore_when_empty"),c=i("autosave_interval"),d=i("autosave_retention"),m=t=>{const e=document.location;return t.options.get("autosave_prefix").replace(/{path}/g,e.pathname).replace(/{query}/g,e.search).replace(/{hash}/g,e.hash).replace(/{id}/g,t.id)},v=(t,e)=>{if(r(e))return t.dom.isEmpty(t.getBody());{const r=s.trim(e);if(""===r)return!0;{const e=(new DOMParser).parseFromString(r,"text/html");return t.dom.isEmpty(e)}}},f=t=>{var e;const r=parseInt(null!==(e=a.getItem(m(t)+"time"))&&void 0!==e?e:"0",10)||0;return!((new Date).getTime()-r>d(t)&&(p(t,!1),1))},p=(t,e)=>{const r=m(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&(t=>{t.dispatch("RemoveDraft")})(t)},g=t=>{const e=m(t);!v(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),(t=>{t.dispatch("StoreDraft")})(t))},y=t=>{var e;const r=m(t);f(t)&&(t.setContent(null!==(e=a.getItem(r+"draft"))&&void 0!==e?e:"",{format:"raw"}),(t=>{t.dispatch("RestoreDraft")})(t))};var D=tinymce.util.Tools.resolve("tinymce.EditorManager");const h=t=>e=>{const r=()=>f(t)&&!t.mode.isReadOnly();e.setEnabled(r());const o=()=>e.setEnabled(r());return t.on("StoreDraft RestoreDraft RemoveDraft",o),()=>t.off("StoreDraft RestoreDraft RemoveDraft",o)};t.add("autosave",(t=>((t=>{const r=t.options.register,o=t=>{const r=e(t);return r?{value:n(t),valid:r}:{valid:!1,message:"Must be a string."}};r("autosave_ask_before_unload",{processor:"boolean",default:!0}),r("autosave_prefix",{processor:"string",default:"tinymce-autosave-{path}{query}{hash}-{id}-"}),r("autosave_restore_when_empty",{processor:"boolean",default:!1}),r("autosave_interval",{processor:o,default:"30s"}),r("autosave_retention",{processor:o,default:"20m"})})(t),(t=>{t.editorManager.on("BeforeUnload",(t=>{let e;s.each(D.get(),(t=>{t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))})),e&&(t.preventDefault(),t.returnValue=e)}))})(t),(t=>{(t=>{const e=c(t);o.setEditorInterval(t,(()=>{g(t)}),e)})(t);const e=()=>{(t=>{t.undoManager.transact((()=>{y(t),p(t)})),t.focus()})(t)};t.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)}),t.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)})})(t),t.on("init",(()=>{l(t)&&t.dom.isEmpty(t.getBody())&&y(t)})),(t=>({hasDraft:()=>f(t),storeDraft:()=>g(t),restoreDraft:()=>y(t),removeDraft:e=>p(t,e),isEmpty:e=>v(t,e)}))(t))))}(); !function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(a=String).prototype.isPrototypeOf(r)||(null===(s=o.constructor)||void 0===s?void 0:s.name)===a.name)?"string":e;var r,o,a,s})(t);const r=t=>undefined===t;var o=tinymce.util.Tools.resolve("tinymce.util.Delay"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),s=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=t=>{const e=/^(\d+)([ms]?)$/.exec(t);return(e&&e[2]?{s:1e3,m:6e4}[e[2]]:1)*parseInt(t,10)},i=t=>e=>e.options.get(t),u=i("autosave_ask_before_unload"),l=i("autosave_restore_when_empty"),c=i("autosave_interval"),d=i("autosave_retention"),m=t=>{const e=document.location;return t.options.get("autosave_prefix").replace(/{path}/g,e.pathname).replace(/{query}/g,e.search).replace(/{hash}/g,e.hash).replace(/{id}/g,t.id)},v=(t,e)=>{if(r(e))return t.dom.isEmpty(t.getBody());{const r=s.trim(e);if(""===r)return!0;{const e=(new DOMParser).parseFromString(r,"text/html");return t.dom.isEmpty(e)}}},f=t=>{var e;const r=parseInt(null!==(e=a.getItem(m(t)+"time"))&&void 0!==e?e:"0",10)||0;return!((new Date).getTime()-r>d(t)&&(p(t,!1),1))},p=(t,e)=>{const r=m(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&(t=>{t.dispatch("RemoveDraft")})(t)},y=t=>{const e=m(t);!v(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),(t=>{t.dispatch("StoreDraft")})(t))},g=t=>{var e;const r=m(t);f(t)&&(t.setContent(null!==(e=a.getItem(r+"draft"))&&void 0!==e?e:"",{format:"raw"}),(t=>{t.dispatch("RestoreDraft")})(t))};var D=tinymce.util.Tools.resolve("tinymce.EditorManager");const h=t=>e=>{const r=()=>f(t)&&!t.mode.isReadOnly();e.setEnabled(r());const o=()=>e.setEnabled(r());return t.on("StoreDraft RestoreDraft RemoveDraft",o),()=>t.off("StoreDraft RestoreDraft RemoveDraft",o)};t.add("autosave",(t=>((t=>{const r=t.options.register,o=t=>{const r=e(t);return r?{value:n(t),valid:r}:{valid:!1,message:"Must be a string."}};r("autosave_ask_before_unload",{processor:"boolean",default:!0}),r("autosave_prefix",{processor:"string",default:"tinymce-autosave-{path}{query}{hash}-{id}-"}),r("autosave_restore_when_empty",{processor:"boolean",default:!1}),r("autosave_interval",{processor:o,default:"30s"}),r("autosave_retention",{processor:o,default:"20m"})})(t),(t=>{t.editorManager.on("BeforeUnload",(t=>{let e;s.each(D.get(),(t=>{t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))})),e&&(t.preventDefault(),t.returnValue=e)}))})(t),(t=>{(t=>{const e=c(t);o.setEditorInterval(t,(()=>{y(t)}),e)})(t);const e=()=>{(t=>{t.undoManager.transact((()=>{g(t),p(t)})),t.focus()})(t)};t.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)}),t.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)})})(t),t.on("init",(()=>{l(t)&&t.dom.isEmpty(t.getBody())&&g(t)})),(t=>({hasDraft:()=>f(t),storeDraft:()=>y(t),restoreDraft:()=>g(t),removeDraft:e=>p(t,e),isEmpty:e=>v(t,e)}))(t))))}();

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
/** /**
* TinyMCE version 7.6.1 (2025-01-22) * TinyMCE version 7.7.1 (2025-03-05)
*/ */
!function(){"use strict";tinymce.util.Tools.resolve("tinymce.PluginManager").add("code",(e=>((e=>{e.addCommand("mceCodeEditor",(()=>{(e=>{const o=(e=>e.getContent({source_view:!0}))(e);e.windowManager.open({title:"Source Code",size:"large",body:{type:"panel",items:[{type:"textarea",name:"code"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{code:o},onSubmit:o=>{((e,o)=>{e.focus(),e.undoManager.transact((()=>{e.setContent(o)})),e.selection.setCursorLocation(),e.nodeChanged()})(e,o.getData().code),o.close()}})})(e)}))})(e),(e=>{const o=()=>e.execCommand("mceCodeEditor");e.ui.registry.addButton("code",{icon:"sourcecode",tooltip:"Source code",onAction:o}),e.ui.registry.addMenuItem("code",{icon:"sourcecode",text:"Source code",onAction:o})})(e),{})))}(); !function(){"use strict";tinymce.util.Tools.resolve("tinymce.PluginManager").add("code",(e=>((e=>{e.addCommand("mceCodeEditor",(()=>{(e=>{const o=(e=>e.getContent({source_view:!0}))(e);e.windowManager.open({title:"Source Code",size:"large",body:{type:"panel",items:[{type:"textarea",name:"code"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{code:o},onSubmit:o=>{((e,o)=>{e.focus(),e.undoManager.transact((()=>{e.setContent(o)})),e.selection.setCursorLocation(),e.nodeChanged()})(e,o.getData().code),o.close()}})})(e)}))})(e),(e=>{const o=()=>e.execCommand("mceCodeEditor");e.ui.registry.addButton("code",{icon:"sourcecode",tooltip:"Source code",onAction:o}),e.ui.registry.addMenuItem("code",{icon:"sourcecode",text:"Source code",onAction:o})})(e),{})))}();

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
/** /**
* TinyMCE version 7.6.1 (2025-01-22) * TinyMCE version 7.7.1 (2025-03-05)
*/ */
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>typeof e===t,o=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(o=r=t,(n=String).prototype.isPrototypeOf(o)||(null===(i=r.constructor)||void 0===i?void 0:i.name)===n.name)?"string":e;var o,r,n,i})(t),r=e("boolean"),n=t=>!(t=>null==t)(t),i=e("function"),s=e("number"),l=(!1,()=>false);class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return n(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const u=(t,e)=>{for(let o=0,r=t.length;o<r;o++)e(t[o],o)},c=t=>{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},d=c,h=(t,e)=>{const o=t.dom;if(1!==o.nodeType)return!1;{const t=o;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}};"undefined"!=typeof window?window:Function("return this;")();const m=t=>e=>(t=>t.dom.nodeType)(e)===t,g=m(1),f=m(3),v=m(11),y=(t,e)=>{t.dom.removeAttribute(e)},p=t=>d(t.dom.host),w=t=>{const e=f(t)?t.dom.parentNode:t.dom;if(null==e||null===e.ownerDocument)return!1;const o=e.ownerDocument;return(t=>{const e=(t=>d(t.dom.getRootNode()))(t);return v(o=e)&&n(o.dom.host)?a.some(e):a.none();var o})(d(e)).fold((()=>o.body.contains(e)),(r=w,i=p,t=>r(i(t))));var r,i},b=t=>"rtl"===((t,e)=>{const o=t.dom,r=window.getComputedStyle(o).getPropertyValue(e);return""!==r||w(t)?r:((t,e)=>(t=>void 0!==t.style&&i(t.style.getPropertyValue))(t)?t.style.getPropertyValue(e):"")(o,e)})(t,"direction")?"rtl":"ltr",S=(t,e)=>((t,o)=>((t,e)=>{const o=[];for(let r=0,n=t.length;r<n;r++){const n=t[r];e(n,r)&&o.push(n)}return o})(((t,e)=>{const o=t.length,r=new Array(o);for(let n=0;n<o;n++){const o=t[n];r[n]=e(o,n)}return r})(t.dom.childNodes,d),(t=>h(t,e))))(t),N=("li",t=>g(t)&&"li"===t.dom.nodeName.toLowerCase());const A=(t,e,n)=>{u(e,(e=>{const c=d(e),m=N(c),f=((t,e)=>{return(e?(o=t,r="ol,ul",((t,e,o)=>{let n=t.dom;const s=i(o)?o:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,r))return a.some(t);if(s(t))break}return a.none()})(o,0,n)):a.some(t)).getOr(t);var o,r,n})(c,m);var v;(v=f,(t=>a.from(t.dom.parentNode).map(d))(v).filter(g)).each((e=>{if(t.setStyle(f.dom,"direction",null),b(e)===n?y(f,"dir"):((t,e,n)=>{((t,e,n)=>{if(!(o(n)||r(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(f,"dir",n),b(f)!==n&&t.setStyle(f.dom,"direction",n),m){const e=S(f,"li[dir],li[style]");u(e,(e=>{y(e,"dir"),t.setStyle(e.dom,"direction",null)}))}}))}))},T=(t,e)=>{t.selection.isEditable()&&(A(t.dom,t.selection.getSelectedBlocks(),e),t.nodeChanged())},C=(t,e)=>o=>{const r=r=>{const n=d(r.element);o.setActive(b(n)===e),o.setEnabled(t.selection.isEditable())};return t.on("NodeChange",r),o.setEnabled(t.selection.isEditable()),()=>t.off("NodeChange",r)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{T(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{T(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:C(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:C(t,"rtl")})})(t)}))}(); !function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>typeof e===t,o=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(o=r=t,(n=String).prototype.isPrototypeOf(o)||(null===(i=r.constructor)||void 0===i?void 0:i.name)===n.name)?"string":e;var o,r,n,i})(t),r=e("boolean"),n=t=>!(t=>null==t)(t),i=e("function"),s=e("number"),l=()=>false;class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return n(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const u=(t,e)=>{for(let o=0,r=t.length;o<r;o++)e(t[o],o)},c=t=>{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},d=c,h=(t,e)=>{const o=t.dom;if(1!==o.nodeType)return!1;{const t=o;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}};"undefined"!=typeof window?window:Function("return this;")();const m=t=>e=>(t=>t.dom.nodeType)(e)===t,g=m(1),f=m(3),v=m(11),y=(t,e)=>{t.dom.removeAttribute(e)},p=t=>d(t.dom.host),w=t=>{const e=f(t)?t.dom.parentNode:t.dom;if(null==e||null===e.ownerDocument)return!1;const o=e.ownerDocument;return(t=>{const e=(t=>d(t.dom.getRootNode()))(t);return v(o=e)&&n(o.dom.host)?a.some(e):a.none();var o})(d(e)).fold((()=>o.body.contains(e)),(r=w,i=p,t=>r(i(t))));var r,i},b=t=>"rtl"===((t,e)=>{const o=t.dom,r=window.getComputedStyle(o).getPropertyValue(e);return""!==r||w(t)?r:((t,e)=>(t=>void 0!==t.style&&i(t.style.getPropertyValue))(t)?t.style.getPropertyValue(e):"")(o,e)})(t,"direction")?"rtl":"ltr",S=(t,e)=>(t=>((t,e)=>{const o=[];for(let r=0,n=t.length;r<n;r++){const n=t[r];e(n,r)&&o.push(n)}return o})(((t,e)=>{const o=t.length,r=new Array(o);for(let n=0;n<o;n++){const o=t[n];r[n]=e(o,n)}return r})(t.dom.childNodes,d),(t=>h(t,e))))(t),N=t=>g(t)&&"li"===t.dom.nodeName.toLowerCase();const A=(t,e,n)=>{u(e,(e=>{const c=d(e),m=N(c),f=((t,e)=>{return(e?(o=t,r="ol,ul",((t,e,o)=>{let n=t.dom;const s=i(o)?o:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,r))return a.some(t);if(s(t))break}return a.none()})(o,0,n)):a.some(t)).getOr(t);var o,r,n})(c,m);var v;(v=f,(t=>a.from(t.dom.parentNode).map(d))(v).filter(g)).each((e=>{if(t.setStyle(f.dom,"direction",null),b(e)===n?y(f,"dir"):((t,e,n)=>{((t,e,n)=>{if(!(o(n)||r(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(f,"dir",n),b(f)!==n&&t.setStyle(f.dom,"direction",n),m){const e=S(f,"li[dir],li[style]");u(e,(e=>{y(e,"dir"),t.setStyle(e.dom,"direction",null)}))}}))}))},T=(t,e)=>{t.selection.isEditable()&&(A(t.dom,t.selection.getSelectedBlocks(),e),t.nodeChanged())},C=(t,e)=>o=>{const r=r=>{const n=d(r.element);o.setActive(b(n)===e),o.setEnabled(t.selection.isEditable())};return t.on("NodeChange",r),o.setEnabled(t.selection.isEditable()),()=>t.off("NodeChange",r)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{T(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{T(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:C(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:C(t,"rtl")})})(t)}))}();

Some files were not shown because too many files have changed in this diff Show More