mirror of
https://github.com/itflow-org/itflow
synced 2026-03-12 00:34:52 +00:00
Compare commits
73 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d829e39b66 | ||
|
|
0e401df3c0 | ||
|
|
9072c37e95 | ||
|
|
2eff11efbf | ||
|
|
6a7a02d220 | ||
|
|
d6349bbc5c | ||
|
|
9a2f887db1 | ||
|
|
71d30ff95f | ||
|
|
3135247936 | ||
|
|
0d629221fe | ||
|
|
181ea4b487 | ||
|
|
fa769665df | ||
|
|
00f5198bed | ||
|
|
785a291614 | ||
|
|
92209c7125 | ||
|
|
690007be5c | ||
|
|
e6bcf0e12f | ||
|
|
ca6a903b8f | ||
|
|
50f790dd6c | ||
|
|
ed6aa843b7 | ||
|
|
52a27699f1 | ||
|
|
dba08714bf | ||
|
|
edabc5c33f | ||
|
|
6b6c70f1df | ||
|
|
93061eb695 | ||
|
|
1f9133c188 | ||
|
|
e7dcc6df3c | ||
|
|
fbd58b4723 | ||
|
|
e992138456 | ||
|
|
058f79d0a1 | ||
|
|
5c448c05a9 | ||
|
|
e966cd3068 | ||
|
|
6d3351b2f7 | ||
|
|
61a1d61901 | ||
|
|
4ff3231451 | ||
|
|
ce832d2805 | ||
|
|
b11730303e | ||
|
|
565f9ab314 | ||
|
|
9435434cf9 | ||
|
|
a58ca6f66d | ||
|
|
c769bbc405 | ||
|
|
0379143829 | ||
|
|
ee235cf231 | ||
|
|
04b29d43df | ||
|
|
dc0715da57 | ||
|
|
902323a75b | ||
|
|
3a5b18f3dd | ||
|
|
ce7d84aa2f | ||
|
|
981fb9585d | ||
|
|
23b2dcba70 | ||
|
|
e4a437f54c | ||
|
|
d4167f9595 | ||
|
|
88475a2b76 | ||
|
|
c26ce4b7dc | ||
|
|
5960e7cbd9 | ||
|
|
68872ab9fb | ||
|
|
64f12b42b8 | ||
|
|
8c0d542d7d | ||
|
|
c016b67c3a | ||
|
|
49d127e957 | ||
|
|
e7353c4757 | ||
|
|
3106685972 | ||
|
|
2b7017fae2 | ||
|
|
da0b01e23f | ||
|
|
d450ea4beb | ||
|
|
9210734911 | ||
|
|
ebae80bb7e | ||
|
|
dcade3a5c7 | ||
|
|
f51c3e9e3f | ||
|
|
b34298e45b | ||
|
|
9fa78897bc | ||
|
|
9642babb7e | ||
|
|
d2d1aed393 |
10
.gitignore
vendored
10
.gitignore
vendored
@@ -25,6 +25,14 @@ plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/CSS/*
|
||||
xcustom/*
|
||||
!xcustom/readme.php
|
||||
post/xcustom
|
||||
custom/*
|
||||
!post/xcustom/readme.php
|
||||
admin/custom/*
|
||||
!admin/custom/readme.php
|
||||
agent/custom/*
|
||||
!agent/custom/readme.php
|
||||
client/custom/*
|
||||
!client/custom/readme.php
|
||||
guest/custom/*
|
||||
!guest/custom/readme.php
|
||||
.zed
|
||||
|
||||
|
||||
76
CHANGELOG.md
76
CHANGELOG.md
@@ -2,6 +2,82 @@
|
||||
|
||||
This file documents all notable changes made to ITFlow.
|
||||
|
||||
## [25.10]
|
||||
|
||||
### Breaking Changes
|
||||
- Renamed `/user/` directory to `/agent/`.
|
||||
- Deprecation Notice: `/scripts/cron_mail_queue.php` and `/scripts/cron_ticket_email_parser.php` are being phased out. Please transition to `/cron/mail_queue.php` and `/cron/ticket_email_parser.php`. These older scripts will be removed in the November release—update accordingly. New Installs via the script will have this already configured.
|
||||
- Custom is working now. Custom code should be placed in /admin/custom/ , /agent/custom/ , /client/custom/ /guest/custom/
|
||||
We will provide example code with directory structure for each custom directory a week after this release.
|
||||
|
||||
### Fixes
|
||||
- Resolved issue with "Restore from Setup" not functioning correctly.
|
||||
- Corrected asset name display in logs and flash messages when editing an asset in a ticket.
|
||||
- Fixed Payment Provider Threshold not being applied.
|
||||
- Fixed issue where Threshold setting was not saving properly.
|
||||
- Various minor fixes for Payment Provider issues.
|
||||
- Removed leads from the client selection list in the "New Ticket" modal.
|
||||
- Fixed issues with the MFA modal.
|
||||
- Resolved MFA enforcement bugs.
|
||||
- Fixed KeepAlive functionality to maintain user sessions longer.
|
||||
- Fixed multiple broken links caused by the `/user/` to `/agent/` path migration.
|
||||
- Fixed Custom code directories.
|
||||
|
||||
### Added / Changed
|
||||
- Removed "ACH" as a payment method; added "Bank Transfer" instead.
|
||||
- Replaced relative paths with absolute paths for web assets.
|
||||
- Tickets can now be resolved via the API.
|
||||
- Added a filter for Archived Users and an option to restore them.
|
||||
- Introduced a modal when archiving users, allowing reassignment of open and recurring tickets to another agent.
|
||||
- Improved logic for determining the index/root page.
|
||||
- Added "Assigned Agent" column for recurring tickets.
|
||||
- Introduced "Additional Assets" option when editing assets in tickets; modal now uses the updated AJAX method.
|
||||
- Added Gibraltar to the list of supported countries.
|
||||
- Added Custom Link Option for the Admin Nav.
|
||||
- Added Custom Link Option for the Reports Nav.
|
||||
|
||||
### Other notes
|
||||
- Major releases will happen on the first week of every Month.
|
||||
|
||||
|
||||
## [25.09.2]
|
||||
|
||||
### Fixes
|
||||
- Fix Payment Method Select box in Revenue.
|
||||
- Remove Extra Feeback Wording When Invoice Sends.
|
||||
- Updated all CSV exports to use escape parameters.
|
||||
- Fix Missing First row on Asset interface export.
|
||||
- Fix Edit User not working due to incorrect modal footer path.
|
||||
- Fix Add Certificate breaking due spelling on function.
|
||||
- Update all CSV Exports to include company name or client name depending on when its being exported from.
|
||||
- Introduced new function sanitize_filename and implmented it in all exports.
|
||||
- Spruced up UI/UX Saved Paymented section in Client Portal.
|
||||
- Fix add Payment Link in client portal recurring invoice section.
|
||||
- Better Logic handling for default page redirect.
|
||||
|
||||
### Features
|
||||
- Introduced new Beta mail parser cron using webklex imap library instead of php-imap as this is deprecated --Not Enabled on existing installs, only new installs.
|
||||
- Introduced Beta support for OAUTH2 Authentication for Microsoft 365 and Google Workspaces for both incoming ticket parsing and outgoing email but must use new mail parser and mail queue for this to work, and requires changing the cron jobs: scripts/cron_mail_queue.php to cron/mail_queue.php and scripts/cron_ticket_email_parser.php to cron/ticket_email_parser.php.
|
||||
|
||||
---
|
||||
|
||||
## [25.09.1]
|
||||
|
||||
### Fixes
|
||||
- **Web Installer**: Resolved issue with broken installer caused by incorrect database schema file name.
|
||||
- Hide the "Add Credit" button as the feature is not fully implemented yet.
|
||||
- Corrected long invoice/quote notes that were overlapping with the footer in PDF exports.
|
||||
- Fixed AI settings not appearing in the Admin Menu when the Billing module was disabled.
|
||||
- Enabled wrapping of client tags when they are too long.
|
||||
- Fixed an issue where AI was not functioning correctly.
|
||||
- Removed extra spacing between the contact name and icon in the Ticket Details contact card.
|
||||
|
||||
### Features
|
||||
- Redesigned **AI Ticket Summary**, now divided into 3 sections: Main Issue, Actions Taken, and Resolution/Next Steps.
|
||||
- Updated the **AI Ticket Summary** prompt to include ticket status, reply author, source, category, and priority.
|
||||
|
||||
---
|
||||
|
||||
## [25.09]
|
||||
|
||||
***BACK UP*** before updating.
|
||||
|
||||
@@ -266,7 +266,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
if (empty($client_name)) {
|
||||
$client_name_display = "-";
|
||||
} else {
|
||||
$client_name_display = "<a href='../user/client_overview.php?client_id=$client_id'>$client_name</a>";
|
||||
$client_name_display = "<a href='../agent/client_overview.php?client_id=$client_id'>$client_name</a>";
|
||||
}
|
||||
$log_entity_id = intval($row['log_entity_id']);
|
||||
|
||||
|
||||
8
admin/custom/readme.php
Normal file
8
admin/custom/readme.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
- Custom Pages -
|
||||
If you wish to add custom pages to ITFlow, add them to this directory"
|
||||
Link to Documentation for File Directory Structure and examples
|
||||
*/
|
||||
@@ -96,6 +96,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
$custom_link_location_display = "Top Nav";
|
||||
} elseif ($custom_link_location == 3) {
|
||||
$custom_link_location_display = "Client Portal Nav";
|
||||
} elseif ($custom_link_location == 4) {
|
||||
$custom_link_location_display = "Admin Nav";
|
||||
} elseif ($custom_link_location == 5) {
|
||||
$custom_link_location_display = "Reports Nav";
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -3968,11 +3968,69 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
||||
|
||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.2'");
|
||||
}
|
||||
|
||||
if (CURRENT_DATABASE_VERSION == '2.3.2') {
|
||||
|
||||
mysqli_query($mysqli, "ALTER TABLE settings
|
||||
ADD `config_imap_provider` ENUM('standard_imap','google_oauth','microsoft_oauth') NULL DEFAULT NULL AFTER `config_mail_from_name`,
|
||||
ADD `config_mail_oauth_client_id` VARCHAR(255) NULL AFTER `config_imap_provider`,
|
||||
ADD `config_mail_oauth_client_secret` VARCHAR(255) NULL AFTER `config_mail_oauth_client_id`,
|
||||
ADD `config_mail_oauth_tenant_id` VARCHAR(255) NULL AFTER `config_mail_oauth_client_secret`,
|
||||
ADD `config_mail_oauth_refresh_token` TEXT NULL AFTER `config_mail_oauth_tenant_id`,
|
||||
ADD `config_mail_oauth_access_token` TEXT NULL AFTER `config_mail_oauth_refresh_token`,
|
||||
ADD `config_mail_oauth_access_token_expires_at` DATETIME NULL AFTER `config_mail_oauth_access_token`
|
||||
");
|
||||
|
||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.3'");
|
||||
}
|
||||
|
||||
if (CURRENT_DATABASE_VERSION == '2.3.3') {
|
||||
|
||||
mysqli_query($mysqli, "ALTER TABLE settings
|
||||
ADD `config_smtp_provider` ENUM('standard_smtp','google_oauth','microsoft_oauth') NULL DEFAULT NULL AFTER `config_start_page`
|
||||
");
|
||||
|
||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.4'");
|
||||
}
|
||||
|
||||
if (CURRENT_DATABASE_VERSION == '2.3.4') {
|
||||
|
||||
// Add Software Keys
|
||||
mysqli_query($mysqli, "CREATE TABLE `software_keys` (
|
||||
`software_key_id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`software_key` VARCHAR(400) NOT NULL,
|
||||
`software_key_software_id` INT(11) NOT NULL,
|
||||
PRIMARY KEY (`software_key_id`),
|
||||
FOREIGN KEY (`software_key_software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE
|
||||
)");
|
||||
|
||||
// Software Key Assignments to Contacts
|
||||
mysqli_query($mysqli, "CREATE TABLE `software_key_contact_assignments` (
|
||||
`software_key_id` INT(11) NOT NULL,
|
||||
`contact_id` INT(11) NOT NULL,
|
||||
`software_key_assigned_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`software_key_id`, `contact_id`),
|
||||
FOREIGN KEY (`software_key_id`) REFERENCES `software_keys`(`software_key_id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE
|
||||
)");
|
||||
|
||||
// Software Key Assignments to Assets
|
||||
mysqli_query($mysqli, "CREATE TABLE `software_key_asset_assignments` (
|
||||
`software_key_id` INT(11) NOT NULL,
|
||||
`asset_id` INT(11) NOT NULL,
|
||||
`software_key_assigned_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`software_key_id`, `asset_id`),
|
||||
FOREIGN KEY (`software_key_id`) REFERENCES `software_keys`(`software_key_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.3.5'");
|
||||
}
|
||||
|
||||
// if (CURRENT_DATABASE_VERSION == '2.3.2') {
|
||||
// // Insert queries here required to update to DB version 2.3.3
|
||||
// if (CURRENT_DATABASE_VERSION == '2.3.4') {
|
||||
// // Insert queries here required to update to DB version 2.3.4
|
||||
// // Then, update the database to the next sequential version
|
||||
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.3'");
|
||||
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.5'");
|
||||
// }
|
||||
|
||||
} else {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
require_once "../config.php";
|
||||
require_once "../functions.php";
|
||||
require_once "../includes/router.php";
|
||||
require_once "../includes/check_login.php";
|
||||
require_once "../includes/page_title.php";
|
||||
if (!isset($session_is_admin) || !$session_is_admin) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!-- Main Sidebar Container -->
|
||||
<aside class="main-sidebar sidebar-dark-<?php echo nullable_htmlentities($config_theme); ?> d-print-none">
|
||||
<a class="brand-link pb-1 mt-1" href="../user/dashboard.php">
|
||||
<a class="brand-link pb-1 mt-1" href="../agent/<?php echo $config_start_page ?>">
|
||||
<p class="h6">
|
||||
<i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i>
|
||||
<span class="brand-text">
|
||||
@@ -72,6 +72,7 @@
|
||||
<p>Saved Payments</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li class="nav-item">
|
||||
<a href="ai_provider.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'ai_provider.php' ? 'active' : ''); ?>">
|
||||
<i class="nav-icon fas fa-robot"></i>
|
||||
@@ -84,7 +85,7 @@
|
||||
<p>AI Models</p>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($config_module_enable_ticketing) { ?>
|
||||
<li class="nav-item">
|
||||
<a href="ticket_status.php" class="nav-link <?php echo (basename($_SERVER['PHP_SELF']) == 'ticket_status.php' ? 'active' : ''); ?>">
|
||||
@@ -276,6 +277,36 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<?php
|
||||
$sql_custom_links = mysqli_query($mysqli, "SELECT * FROM custom_links
|
||||
WHERE custom_link_location = 4 AND custom_link_archived_at IS NULL
|
||||
ORDER BY custom_link_order ASC, custom_link_name ASC"
|
||||
);
|
||||
|
||||
while ($row = mysqli_fetch_array($sql_custom_links)) {
|
||||
$custom_link_name = nullable_htmlentities($row['custom_link_name']);
|
||||
$custom_link_uri = sanitize_url($row['custom_link_uri']);
|
||||
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']);
|
||||
$custom_link_new_tab = intval($row['custom_link_new_tab']);
|
||||
if ($custom_link_new_tab == 1) {
|
||||
$target = "target='_blank' rel='noopener noreferrer'";
|
||||
} else {
|
||||
$target = "";
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="<?php echo $custom_link_uri; ?>" <?php echo $target; ?> class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == basename($custom_link_uri)) { echo "active"; } ?>">
|
||||
<i class="fas fa-<?php echo $custom_link_icon; ?> nav-icon"></i>
|
||||
<p><?php echo $custom_link_name; ?></p>
|
||||
<i class="fas fa-angle-right nav-icon float-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
<!-- /.sidebar-menu -->
|
||||
|
||||
@@ -66,6 +66,8 @@
|
||||
<option value="1">Main Side Nav</option>
|
||||
<option value="2">Top Nav (Icon Required)</option>
|
||||
<option value="3">Client Portal Nav</option>
|
||||
<option value="4">Admin Nav</option>
|
||||
<option value="5">Reports Nav</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -81,9 +81,11 @@ ob_start();
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-home"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="location" required>
|
||||
<option value="1" <?php if ($custom_link_location == 1) { echo "selected"; } ?> >Main Side Nav</option>
|
||||
<option value="2" <?php if ($custom_link_location == 2) { echo "selected"; } ?> >Top Nav (Icon Required)</option>
|
||||
<option value="3" <?php if ($custom_link_location == 3) { echo "selected"; } ?> >Client Portal Nav</option>
|
||||
<option value="1" <?php if ($custom_link_location === 1) { echo "selected"; } ?> >Main Side Nav</option>
|
||||
<option value="2" <?php if ($custom_link_location === 2) { echo "selected"; } ?> >Top Nav (Icon Required)</option>
|
||||
<option value="3" <?php if ($custom_link_location === 3) { echo "selected"; } ?> >Client Portal Nav</option>
|
||||
<option value="4" <?php if ($custom_link_location === 4) { echo "selected"; } ?> >Admin Nav</option>
|
||||
<option value="5" <?php if ($custom_link_location === 5) { echo "selected"; } ?> >Reports Nav</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
<input type="text" class="form-control" name="name" placeholder="Template name" maxlength="200">
|
||||
</div>
|
||||
|
||||
<?php if ($config_ai_enable == 1) { ?>
|
||||
<!-- Prompt for AI -->
|
||||
<div class="form-group">
|
||||
<label>Enter a prompt for the type of IT documentation you want to generate:</label>
|
||||
<div class="input-group mb-3">
|
||||
@@ -27,7 +25,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- TinyMCE Content -->
|
||||
<div class="form-group">
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="threshold" placeholder="1000.00">
|
||||
</div>
|
||||
<small class="form-text text-muted">Will not show as an option at Checkout if above this number</small>
|
||||
<small class="form-text text-muted">Will not show as an option at Checkout if invoice amount is above this number, 0 disables the threshold check.</small>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -58,7 +58,7 @@ ob_start();
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-shopping-cart"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="Threshold" placeholder="1000.00" value="<?php echo $threshold; ?>">
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*\.?[0-9]{0,2}" name="threshold" placeholder="1000.00" value="<?php echo $threshold; ?>">
|
||||
</div>
|
||||
<small class="form-text text-muted">Will not show as an option at Checkout if above this number</small>
|
||||
</div>
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once '../../includes/modal_header.php';
|
||||
|
||||
$user_id = intval($_GET['id']);
|
||||
|
||||
$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);
|
||||
$user_name = nullable_htmlentities($row['user_name']);
|
||||
$user_email = nullable_htmlentities($row['user_email']);
|
||||
$user_avatar = nullable_htmlentities($row['user_avatar']);
|
||||
$user_token = nullable_htmlentities($row['user_token']);
|
||||
$user_config_force_mfa = intval($row['user_config_force_mfa']);
|
||||
$user_role_id = intval($row['user_role_id']);
|
||||
$user_initials = nullable_htmlentities(initials($user_name));
|
||||
|
||||
// Get User Client Access Permissions
|
||||
$user_client_access_sql = mysqli_query($mysqli,"SELECT client_id FROM user_client_permissions WHERE user_id = $user_id");
|
||||
$client_access_array = [];
|
||||
while ($row = mysqli_fetch_assoc($user_client_access_sql)) {
|
||||
$client_access_array[] = intval($row['client_id']);
|
||||
}
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-edit mr-2"></i>Editing user:
|
||||
<strong><?php echo $user_name; ?></strong></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="user_id" value="<?php echo $user_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<ul class="nav nav-pills nav-justified mb-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="pill" href="#pills-user-details<?php echo $user_id; ?>">Details</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="pill" href="#pills-user-access<?php echo $user_id; ?>">Restrict Access</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade show active" id="pills-user-details<?php echo $user_id; ?>">
|
||||
|
||||
<center class="mb-3">
|
||||
<?php if (!empty($user_avatar)) { ?>
|
||||
<img class="img-fluid" src="<?php echo "uploads/users/$user_id/$user_avatar"; ?>">
|
||||
<?php } else { ?>
|
||||
<span class="fa-stack fa-4x">
|
||||
<i class="fa fa-circle fa-stack-2x text-secondary"></i>
|
||||
<span class="fa fa-stack-1x text-white"><?php echo $user_initials; ?></span>
|
||||
</span>
|
||||
<?php } ?>
|
||||
</center>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Name <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="name" placeholder="Full Name" maxlength="200"
|
||||
value="<?php echo $user_name; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Email <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-envelope"></i></span>
|
||||
</div>
|
||||
<input type="email" class="form-control" name="email" placeholder="Email Address" maxlength="200"
|
||||
value="<?php echo $user_email; ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>New Password</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
||||
</div>
|
||||
<input type="password" class="form-control" data-toggle="password" name="new_password"
|
||||
placeholder="Leave Blank For No Password Change" autocomplete="new-password">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Role <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="role" required>
|
||||
<?php
|
||||
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL");
|
||||
while ($row = mysqli_fetch_array($sql_user_roles)) {
|
||||
$role_id = intval($row['role_id']);
|
||||
$role_name = nullable_htmlentities($row['role_name']);
|
||||
|
||||
?>
|
||||
<option <?php if ($role_id == $user_role_id) {echo "selected";} ?> value="<?php echo $role_id; ?>"><?php echo $role_name; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Avatar</label>
|
||||
<input type="file" class="form-control-file" accept="image/*" name="file">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input class="custom-control-input" type="checkbox" id="forceMFACheckBox<?php echo $user_id; ?>" name="force_mfa" value="1" <?php if($user_config_force_mfa == 1){ echo "checked"; } ?>>
|
||||
<label for="forceMFACheckBox<?php echo $user_id; ?>" class="custom-control-label">
|
||||
Force MFA
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($user_token)) { ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label>2FA</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-id-card"></i></span>
|
||||
</div>
|
||||
<select class="form-control" name="2fa">
|
||||
<option value="">Keep enabled</option>
|
||||
<option value="disable">Disable</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-user-access<?php echo $user_id; ?>">
|
||||
|
||||
<div class="alert alert-info">
|
||||
Check boxes to authorize user client access. No boxes grant full client access. Admin users are unaffected.
|
||||
</div>
|
||||
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item bg-dark">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" onclick="this.closest('.tab-pane').querySelectorAll('.client-checkbox').forEach(checkbox => checkbox.checked = this.checked);">
|
||||
<label class="form-check-label ml-3"><strong>Restrict Access to Clients</strong></label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<?php
|
||||
|
||||
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||
while ($row = mysqli_fetch_array($sql_client_select)) {
|
||||
$client_id_select = intval($row['client_id']);
|
||||
$client_name_select = nullable_htmlentities($row['client_name']);
|
||||
|
||||
?>
|
||||
|
||||
<li class="list-group-item">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input client-checkbox" name="clients[]" value="<?php echo $client_id_select; ?>" <?php if (in_array($client_id_select, $client_access_array)) { echo "checked"; } ?>>
|
||||
<label class="form-check-label ml-2"><?php echo $client_name_select; ?></label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_user" 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>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once '../../includes/modal_footer.php';
|
||||
@@ -1,16 +1,83 @@
|
||||
<div class="modal" id="archiveUserModal<?php echo $user_id; ?>" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
<div class="mb-4" style="text-align: center;">
|
||||
<i class="far fa-10x fa-times-circle text-danger mb-3 mt-3"></i>
|
||||
<h2>Are you sure?</h2>
|
||||
<h6 class="mb-4 text-secondary">Do you really want to <b>archive <?php echo $user_name; ?></b>? This process cannot be undone.</h6>
|
||||
<h6 class="mb-4 text-secondary"><?php echo $user_name ?> will no longer be able to log in or use ITFlow, but all associated content will remain accessible.</h6>
|
||||
<button type="button" class="btn btn-outline-secondary btn-lg px-5 mr-4" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-danger btn-lg px-5" href="post.php?archive_user=<?php echo $user_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">Yes, archive!</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$user_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE users.user_id = $user_id LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$user_name = nullable_htmlentities($row['user_name']);
|
||||
$user_email = nullable_htmlentities($row['user_email']);
|
||||
$user_avatar = nullable_htmlentities($row['user_avatar']);
|
||||
$user_initials = nullable_htmlentities(initials($user_name));
|
||||
|
||||
$sql_related_tickets = mysqli_query($mysqli, "SELECT * FROM tickets
|
||||
WHERE ticket_assigned_to = $user_id AND ticket_resolved_at IS NULL AND ticket_closed_at IS NULL");
|
||||
|
||||
$ticket_count = mysqli_num_rows($sql_related_tickets);
|
||||
|
||||
// Related Recurring Tickets Query
|
||||
$sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT * FROM recurring_tickets WHERE recurring_ticket_assigned_to = $user_id");
|
||||
|
||||
$recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-slash mr-2"></i>Archiving user:
|
||||
<strong><?php echo $user_name; ?></strong></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="user_id" value="<?php echo $user_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
|
||||
<center class="mb-3">
|
||||
<?php if (!empty($user_avatar)) { ?>
|
||||
<img class="img-fluid" src="<?php echo "../uploads/users/$user_id/$user_avatar"; ?>">
|
||||
<?php } else { ?>
|
||||
<span class="fa-stack fa-4x">
|
||||
<i class="fa fa-circle fa-stack-2x text-secondary"></i>
|
||||
<span class="fa fa-stack-1x text-white"><?php echo $user_initials; ?></span>
|
||||
</span>
|
||||
<?php } ?>
|
||||
</center>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label>Reassign <?= $ticket_count ?> Open Tickets and <?= $recurring_ticket_count ?> Recurring Tickets To:</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="ticket_assign" required>
|
||||
<option value="0">No one</option>
|
||||
<?php
|
||||
$sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE user_type = 1 AND user_archived_at IS NULL");
|
||||
while ($row = mysqli_fetch_array($sql_users)) {
|
||||
$user_id_select = intval($row['user_id']);
|
||||
$user_name_select = nullable_htmlentities($row['user_name']);
|
||||
|
||||
?>
|
||||
<option value="<?= $user_id_select ?>"><?= $user_name_select ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="archive_user" class="btn btn-danger text-bold"><i class="fas fa-archive mr-2"></i>Archive</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once "../../../includes/modal_footer.php";
|
||||
|
||||
@@ -57,7 +57,7 @@ ob_start();
|
||||
|
||||
<center class="mb-3">
|
||||
<?php if (!empty($user_avatar)) { ?>
|
||||
<img class="img-fluid" src="<?php echo "uploads/users/$user_id/$user_avatar"; ?>">
|
||||
<img class="img-fluid" src="<?php echo "../uploads/users/$user_id/$user_avatar"; ?>">
|
||||
<?php } else { ?>
|
||||
<span class="fa-stack fa-4x">
|
||||
<i class="fa fa-circle fa-stack-2x text-secondary"></i>
|
||||
@@ -201,4 +201,4 @@ ob_start();
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once "../../../includes/modal_footer_new.php";
|
||||
require_once "../../../includes/modal_footer.php";
|
||||
|
||||
87
admin/modals/user/user_restore.php
Normal file
87
admin/modals/user/user_restore.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../includes/modal_header.php';
|
||||
|
||||
$user_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $user_id AND user_archived_at IS NOT NULL LIMIT 1");
|
||||
|
||||
$row = mysqli_fetch_array($sql);
|
||||
$user_name = str_replace(" (archived)", "", $row['user_name']); //Removed (archived) from user_name
|
||||
$user_name = nullable_htmlentities($user_name);
|
||||
$user_email = nullable_htmlentities($row['user_email']);
|
||||
$user_avatar = nullable_htmlentities($row['user_avatar']);
|
||||
$user_initials = initials($user_name);
|
||||
$user_role_id = intval($row['user_role_id']);
|
||||
|
||||
// Generate the HTML form content using output buffering.
|
||||
ob_start();
|
||||
?>
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-redo-alt mr-2"></i>Restoring user:
|
||||
<strong><?php echo $user_name; ?></strong></h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="user_id" value="<?php echo $user_id; ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
|
||||
<center class="mb-3">
|
||||
<?php if (!empty($user_avatar)) { ?>
|
||||
<img class="img-fluid" src="<?php echo "../uploads/users/$user_id/$user_avatar"; ?>">
|
||||
<?php } else { ?>
|
||||
<span class="fa-stack fa-4x">
|
||||
<i class="fa fa-circle fa-stack-2x text-secondary"></i>
|
||||
<span class="fa fa-stack-1x text-white"><?php echo $user_initials; ?></span>
|
||||
</span>
|
||||
<?php } ?>
|
||||
</center>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Set a New Password</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
||||
</div>
|
||||
<input type="password" class="form-control" data-toggle="password" name="new_password"
|
||||
placeholder="Enter a new password" autocomplete="new-password" required>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Role <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="role" required>
|
||||
<?php
|
||||
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE role_archived_at IS NULL");
|
||||
while ($row = mysqli_fetch_array($sql_user_roles)) {
|
||||
$role_id = intval($row['role_id']);
|
||||
$role_name = nullable_htmlentities($row['role_name']);
|
||||
|
||||
?>
|
||||
<option <?php if ($role_id == $user_role_id) {echo "selected";} ?> value="<?php echo $role_id; ?>"><?php echo $role_name; ?></option>
|
||||
<?php } ?>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="restore_user" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Restore</button>
|
||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once "../../../includes/modal_footer.php";
|
||||
@@ -55,7 +55,7 @@ $num_rows = mysqli_num_rows($sql);
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark">Fee</a>
|
||||
<a class="text-dark">Expensed Fee</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="text-dark">Saved Payment Methods</a>
|
||||
@@ -93,7 +93,7 @@ $num_rows = mysqli_num_rows($sql);
|
||||
<td><?php echo numfmt_format_currency($currency_format, $threshold, $session_company_currency); ?></td>
|
||||
<td><?php echo $vendor_name; ?></td>
|
||||
<td><?php echo $category; ?></td>
|
||||
<td><?php echo $percent_fee; ?> + <?php echo numfmt_format_currency($currency_format, $flat_fee, $session_company_currency); ?></td>
|
||||
<td><?php echo $percent_fee; ?>% + <?php echo numfmt_format_currency($currency_format, $flat_fee, $session_company_currency); ?></td>
|
||||
<td><?php echo $saved_payment_count; ?></td>
|
||||
<td>
|
||||
<div class="dropdown dropleft text-center">
|
||||
@@ -106,9 +106,12 @@ $num_rows = mysqli_num_rows($sql);
|
||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger confirm-link" href="post.php?disable_payment_provicer=<?php echo $provider_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
||||
<i class="fas fa-fw fa-thumbs-down mr-2"></i>Disable
|
||||
</a>
|
||||
<!-- <a class="dropdown-item text-danger confirm-link" href="post.php?disable_payment_provider=--><?php //echo $provider_id; ?><!--&csrf_token=--><?php //echo $_SESSION['csrf_token'] ?><!--">-->
|
||||
<!-- <i class="fas fa-fw fa-thumbs-down mr-2"></i>Disable-->
|
||||
<!-- </a>-->
|
||||
<!-- <a class="dropdown-item text-danger confirm-link" href="post.php?delete_payment_provider=--><?php //echo $provider_id; ?><!--&csrf_token=--><?php //echo $_SESSION['csrf_token'] ?><!--">-->
|
||||
<!-- <i class="fas fa-fw fa-trash mr-2"></i>Delete-->
|
||||
<!-- </a>-->
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -15,10 +15,10 @@ if (isset($_POST['add_payment_provider'])) {
|
||||
$private_key = sanitizeInput($_POST['private_key']);
|
||||
$threshold = floatval($_POST['threshold']);
|
||||
$enable_expense = intval($_POST['enable_expense'] ?? 0);
|
||||
$percentage_fee = floatval($_POST['percentage_fee']) / 100;
|
||||
$flat_fee = floatval($_POST['flat_fee']);
|
||||
$percentage_fee = floatval($_POST['percentage_fee']) / 100 ?? 0;
|
||||
$flat_fee = floatval($_POST['flat_fee']) ?? 0;
|
||||
|
||||
// Check to make sure Provider isnt added Twice
|
||||
// Check to ensure provider isn't added twice
|
||||
$sql = "SELECT 1 FROM payment_providers WHERE payment_provider_name = '$provider' LIMIT 1";
|
||||
$result = mysqli_query($mysqli, $sql);
|
||||
if (mysqli_num_rows($result) > 0) {
|
||||
@@ -26,7 +26,7 @@ if (isset($_POST['add_payment_provider'])) {
|
||||
redirect();
|
||||
}
|
||||
|
||||
// Check for Stripe Account if not create it
|
||||
// Check for Stripe Account, if not create it
|
||||
$sql_account = mysqli_query($mysqli,"SELECT account_id FROM accounts WHERE account_name = '$provider' AND account_archived_at IS NULL LIMIT 1");
|
||||
if (mysqli_num_rows($sql_account) == 0) {
|
||||
$account_id = mysqli_insert_id($mysqli);
|
||||
@@ -35,6 +35,10 @@ if (isset($_POST['add_payment_provider'])) {
|
||||
$account_id = intval($row['account_id']);
|
||||
}
|
||||
|
||||
// Expense defaults
|
||||
$category_id = 0;
|
||||
$vendor_id = 0;
|
||||
|
||||
if ($enable_expense) {
|
||||
// Category
|
||||
$sql_category = mysqli_query($mysqli,"SELECT category_id FROM categories WHERE category_name = 'Payment Processing' AND category_type = 'Expense' AND category_archived_at IS NULL LIMIT 1");
|
||||
@@ -45,10 +49,10 @@ if (isset($_POST['add_payment_provider'])) {
|
||||
$row = mysqli_fetch_array($sql_category);
|
||||
$category_id = intval($row['category_id']);
|
||||
}
|
||||
//Vendor
|
||||
// Vendor
|
||||
$sql_vendor = mysqli_query($mysqli,"SELECT vendor_id FROM vendors WHERE vendor_name = '$provider' AND vendor_client_id = 0 AND vendor_archived_at IS NULL LIMIT 1");
|
||||
if (mysqli_num_rows($sql_vendor) == 0) {
|
||||
mysqli_query($mysqli,"INSERT INTO vendors SET vendor_name = '$provider', vendor_descripion = 'Payment Processor Provider', vendor_client_id = 0");
|
||||
mysqli_query($mysqli,"INSERT INTO vendors SET vendor_name = '$provider', vendor_description = 'Payment Processor Provider', vendor_client_id = 0");
|
||||
$vendor_id = mysqli_insert_id($mysqli);
|
||||
} else {
|
||||
$row = mysqli_fetch_array($sql_vendor);
|
||||
@@ -56,7 +60,7 @@ if (isset($_POST['add_payment_provider'])) {
|
||||
}
|
||||
}
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO payment_providers SET payment_provider_name = '$provider', payment_provider_public_key = '$public_key', payment_provider_private_key = '$private_key', payment_provider_account = $account_id, payment_provider_expense_vendor = $vendor_id, payment_provider_expense_category = $category_id, payment_provider_expense_percentage_fee = $percentage_fee, payment_provider_expense_flat_fee = $flat_fee");
|
||||
mysqli_query($mysqli,"INSERT INTO payment_providers SET payment_provider_name = '$provider', payment_provider_public_key = '$public_key', payment_provider_private_key = '$private_key', payment_provider_threshold = $threshold, payment_provider_account = $account_id, payment_provider_expense_vendor = $vendor_id, payment_provider_expense_category = $category_id, payment_provider_expense_percentage_fee = $percentage_fee, payment_provider_expense_flat_fee = $flat_fee");
|
||||
|
||||
$provider_id = mysqli_insert_id($mysqli);
|
||||
|
||||
@@ -81,7 +85,7 @@ if (isset($_POST['edit_payment_provider'])) {
|
||||
$percentage_fee = floatval($_POST['percentage_fee']) / 100;
|
||||
$flat_fee = floatval($_POST['flat_fee']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE payment_providers SET payment_provider_public_key = '$public_key', payment_provider_private_key = '$private_key', payment_provider_expense_percentage_fee = $percentage_fee, payment_provider_expense_flat_fee = $flat_fee WHERE payment_provider_id = $provider_id");
|
||||
mysqli_query($mysqli,"UPDATE payment_providers SET payment_provider_public_key = '$public_key', payment_provider_private_key = '$private_key', payment_provider_threshold = $threshold, payment_provider_expense_percentage_fee = $percentage_fee, payment_provider_expense_flat_fee = $flat_fee WHERE payment_provider_id = $provider_id");
|
||||
|
||||
logAction("Payment Provider", "Edit", "$session_name edited Payment Provider $provider");
|
||||
|
||||
@@ -92,11 +96,14 @@ if (isset($_POST['edit_payment_provider'])) {
|
||||
}
|
||||
|
||||
if (isset($_GET['delete_payment_provider'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
$provider_id = intval($_GET['delete_payment_provider']);
|
||||
|
||||
$provider_name = sanitizeInput(getFieldById('provider_providers', $provider_id, 'provider_name'));
|
||||
$provider_name = sanitizeInput(getFieldById('payment_providers', $provider_id, 'provider_name'));
|
||||
|
||||
// Delete provider
|
||||
mysqli_query($mysqli,"DELETE FROM payment_providers WHERE payment_provider_id = $provider_id");
|
||||
|
||||
logAction("Payment Provider", "Delete", "$session_name deleted Payment Provider $provider_name");
|
||||
|
||||
@@ -37,7 +37,7 @@ if (isset($_GET['delete_saved_payment'])) {
|
||||
|
||||
$private_key = $row['payment_provider_private_key'];
|
||||
|
||||
// Seperate logic for each Payment Provider
|
||||
// Separate logic for each Payment Provider
|
||||
if ($payment_provider_name == 'Stripe') {
|
||||
|
||||
try {
|
||||
|
||||
@@ -3,41 +3,85 @@
|
||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||
|
||||
if (isset($_POST['edit_mail_smtp_settings'])) {
|
||||
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_smtp_host = sanitizeInput($_POST['config_smtp_host']);
|
||||
$config_smtp_port = intval($_POST['config_smtp_port']);
|
||||
$config_smtp_encryption = sanitizeInput($_POST['config_smtp_encryption']);
|
||||
$config_smtp_username = sanitizeInput($_POST['config_smtp_username']);
|
||||
$config_smtp_password = sanitizeInput($_POST['config_smtp_password']);
|
||||
$config_smtp_provider = sanitizeInput($_POST['config_smtp_provider'] ?? 'standard_smtp');
|
||||
$config_smtp_host = sanitizeInput($_POST['config_smtp_host']);
|
||||
$config_smtp_port = intval($_POST['config_smtp_port'] ?? 0);
|
||||
$config_smtp_encryption = sanitizeInput($_POST['config_smtp_encryption']);
|
||||
$config_smtp_username = sanitizeInput($_POST['config_smtp_username']);
|
||||
$config_smtp_password = sanitizeInput($_POST['config_smtp_password']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_smtp_host = '$config_smtp_host', config_smtp_port = $config_smtp_port, config_smtp_encryption = '$config_smtp_encryption', config_smtp_username = '$config_smtp_username', config_smtp_password = '$config_smtp_password' WHERE company_id = 1");
|
||||
// Shared OAuth fields
|
||||
$config_mail_oauth_client_id = sanitizeInput($_POST['config_mail_oauth_client_id']);
|
||||
$config_mail_oauth_client_secret = sanitizeInput($_POST['config_mail_oauth_client_secret']);
|
||||
$config_mail_oauth_tenant_id = sanitizeInput($_POST['config_mail_oauth_tenant_id']);
|
||||
$config_mail_oauth_refresh_token = sanitizeInput($_POST['config_mail_oauth_refresh_token']);
|
||||
$config_mail_oauth_access_token = sanitizeInput($_POST['config_mail_oauth_access_token']);
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited SMTP mail settings");
|
||||
mysqli_query($mysqli, "
|
||||
UPDATE settings SET
|
||||
config_smtp_provider = " . ($config_smtp_provider === 'none' ? "NULL" : "'$config_smtp_provider'") . ",
|
||||
config_smtp_host = '$config_smtp_host',
|
||||
config_smtp_port = $config_smtp_port,
|
||||
config_smtp_encryption = '$config_smtp_encryption',
|
||||
config_smtp_username = '$config_smtp_username',
|
||||
config_smtp_password = '$config_smtp_password',
|
||||
config_mail_oauth_client_id = '$config_mail_oauth_client_id',
|
||||
config_mail_oauth_client_secret = '$config_mail_oauth_client_secret',
|
||||
config_mail_oauth_tenant_id = '$config_mail_oauth_tenant_id',
|
||||
config_mail_oauth_refresh_token = '$config_mail_oauth_refresh_token',
|
||||
config_mail_oauth_access_token = '$config_mail_oauth_access_token'
|
||||
WHERE company_id = 1
|
||||
");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited SMTP settings");
|
||||
|
||||
flash_alert("SMTP Mail Settings updated");
|
||||
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['edit_mail_imap_settings'])) {
|
||||
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$config_imap_host = sanitizeInput($_POST['config_imap_host']);
|
||||
$config_imap_username = sanitizeInput($_POST['config_imap_username']);
|
||||
$config_imap_password = sanitizeInput($_POST['config_imap_password']);
|
||||
$config_imap_port = intval($_POST['config_imap_port']);
|
||||
$config_imap_encryption = sanitizeInput($_POST['config_imap_encryption']);
|
||||
$config_imap_provider = sanitizeInput($_POST['config_imap_provider'] ?? 'standard_imap');
|
||||
$config_imap_host = sanitizeInput($_POST['config_imap_host']);
|
||||
$config_imap_port = intval($_POST['config_imap_port'] ?? 0);
|
||||
$config_imap_encryption = sanitizeInput($_POST['config_imap_encryption']);
|
||||
$config_imap_username = sanitizeInput($_POST['config_imap_username']);
|
||||
$config_imap_password = sanitizeInput($_POST['config_imap_password']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_imap_host = '$config_imap_host', config_imap_port = $config_imap_port, config_imap_encryption = '$config_imap_encryption', config_imap_username = '$config_imap_username', config_imap_password = '$config_imap_password' WHERE company_id = 1");
|
||||
// Shared OAuth fields
|
||||
$config_mail_oauth_client_id = sanitizeInput($_POST['config_mail_oauth_client_id']);
|
||||
$config_mail_oauth_client_secret = sanitizeInput($_POST['config_mail_oauth_client_secret']);
|
||||
$config_mail_oauth_tenant_id = sanitizeInput($_POST['config_mail_oauth_tenant_id']);
|
||||
$config_mail_oauth_refresh_token = sanitizeInput($_POST['config_mail_oauth_refresh_token']);
|
||||
$config_mail_oauth_access_token = sanitizeInput($_POST['config_mail_oauth_access_token']);
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited IMAP mail settings");
|
||||
mysqli_query($mysqli, "
|
||||
UPDATE settings SET
|
||||
config_imap_provider = " . ($config_imap_provider === 'none' ? "NULL" : "'$config_imap_provider'") . ",
|
||||
config_imap_host = '$config_imap_host',
|
||||
config_imap_port = $config_imap_port,
|
||||
config_imap_encryption = '$config_imap_encryption',
|
||||
config_imap_username = '$config_imap_username',
|
||||
config_imap_password = '$config_imap_password',
|
||||
config_mail_oauth_client_id = '$config_mail_oauth_client_id',
|
||||
config_mail_oauth_client_secret = '$config_mail_oauth_client_secret',
|
||||
config_mail_oauth_tenant_id = '$config_mail_oauth_tenant_id',
|
||||
config_mail_oauth_refresh_token = '$config_mail_oauth_refresh_token',
|
||||
config_mail_oauth_access_token = '$config_mail_oauth_access_token'
|
||||
WHERE company_id = 1
|
||||
");
|
||||
|
||||
logAction("Settings", "Edit", "$session_name edited IMAP settings");
|
||||
|
||||
flash_alert("IMAP Mail Settings updated");
|
||||
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
@@ -236,16 +236,20 @@ if (isset($_GET['revoke_remember_me'])) {
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['archive_user'])) {
|
||||
if (isset($_POST['archive_user'])) {
|
||||
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
// Variables from GET
|
||||
$user_id = intval($_GET['archive_user']);
|
||||
$user_id = intval($_POST['user_id']);
|
||||
$ticket_assign = intval($_POST['ticket_assign']);
|
||||
$password = password_hash(randomString(), PASSWORD_DEFAULT);
|
||||
|
||||
$user_name = sanitizeInput(getFieldById('users', $user_id, 'user_name'));
|
||||
|
||||
// Un-assign / Re-assign tickets
|
||||
mysqli_query($mysqli, "UPDATE tickets SET ticket_assigned_to = $ticket_assign WHERE ticket_assigned_to = $user_id AND ticket_closed_at IS NULL AND ticket_resolved_at IS NULL");
|
||||
mysqli_query($mysqli, "UPDATE recurring_tickets SET recurring_ticket_assigned_to = $ticket_assign WHERE recurring_ticket_assigned_to = $user_id");
|
||||
|
||||
// Archive user query
|
||||
mysqli_query($mysqli, "UPDATE users SET user_name = '$user_name (archived)', user_password = '$password', user_status = 0, user_specific_encryption_ciphertext = '', user_archived_at = NOW() WHERE user_id = $user_id");
|
||||
|
||||
@@ -257,6 +261,36 @@ if (isset($_GET['archive_user'])) {
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['restore_user'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$user_id = intval($_POST['user_id']);
|
||||
$new_password = trim($_POST['new_password']);
|
||||
$role = intval($_POST['role']);
|
||||
|
||||
$user_name = getFieldById('users', $user_id, 'user_name');
|
||||
$user_name = sanitizeInput(str_replace(" (archived)", "", $user_name)); //Removed (archived) from user_name
|
||||
|
||||
// Restore user query
|
||||
mysqli_query($mysqli, "UPDATE users SET user_name = '$user_name', user_status = 1, user_role_id = $role, user_archived_at = NULL WHERE user_id = $user_id");
|
||||
|
||||
if (!empty($new_password)) {
|
||||
$new_password = password_hash($new_password, PASSWORD_DEFAULT);
|
||||
$user_specific_encryption_ciphertext = encryptUserSpecificKey(trim($_POST['new_password']));
|
||||
mysqli_query($mysqli, "UPDATE users SET user_password = '$new_password', user_specific_encryption_ciphertext = '$user_specific_encryption_ciphertext' WHERE user_id = $user_id");
|
||||
//Extended Logging
|
||||
$extended_log_description .= ", password changed";
|
||||
}
|
||||
|
||||
logAction("User", "Restored", "$session_name restored user $user_name", 0, $user_id);
|
||||
|
||||
flash_alert("User <strong>$user_name</strong> restored");
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['export_users_csv'])) {
|
||||
|
||||
//get records from database
|
||||
@@ -266,6 +300,8 @@ if (isset($_POST['export_users_csv'])) {
|
||||
|
||||
if ($count > 0) {
|
||||
$delimiter = ",";
|
||||
$enclosure = '"';
|
||||
$escape = '\\'; // backslash
|
||||
$filename = "Users-" . date('Y-m-d') . ".csv";
|
||||
|
||||
//create a file pointer
|
||||
@@ -273,7 +309,7 @@ if (isset($_POST['export_users_csv'])) {
|
||||
|
||||
//set column headers
|
||||
$fields = array('Name', 'Email', 'Role', 'Status', 'Creation Date');
|
||||
fputcsv($f, $fields, $delimiter);
|
||||
fputcsv($f, $fields, $delimiter, $enclosure, $escape);
|
||||
|
||||
//output each row of the data, format line as csv and write to file pointer
|
||||
while($row = $sql->fetch_assoc()) {
|
||||
@@ -288,7 +324,7 @@ if (isset($_POST['export_users_csv'])) {
|
||||
}
|
||||
|
||||
$lineData = array($row['user_name'], $row['user_email'], $row['role_name'], $user_status_display, $row['user_created_at']);
|
||||
fputcsv($f, $lineData, $delimiter);
|
||||
fputcsv($f, $lineData, $delimiter, $enclosure, $escape);
|
||||
}
|
||||
|
||||
//move back to beginning of file
|
||||
|
||||
@@ -10,61 +10,87 @@ require_once "includes/inc_all_admin.php";
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<!-- SMTP Provider -->
|
||||
<div class="form-group">
|
||||
<label>SMTP Host</label>
|
||||
<label>SMTP Provider</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-server"></i></span>
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-cloud"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="config_smtp_host" placeholder="Mail Server Address" value="<?php echo nullable_htmlentities($config_smtp_host); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>SMTP Port</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
|
||||
</div>
|
||||
<input type="number" min="0" class="form-control" name="config_smtp_port" placeholder="Mail Server Port Number" value="<?php echo intval($config_smtp_port); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Encryption</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
||||
</div>
|
||||
<select class="form-control" name="config_smtp_encryption">
|
||||
<option value=''>None</option>
|
||||
<option <?php if ($config_smtp_encryption == 'tls') { echo "selected"; } ?> value="tls">TLS</option>
|
||||
<option <?php if ($config_smtp_encryption == 'ssl') { echo "selected"; } ?> value="ssl">SSL</option>
|
||||
<select class="form-control" name="config_smtp_provider" id="config_smtp_provider">
|
||||
<option value="none" <?php if(($config_smtp_provider ?? '')==='none' || ($config_smtp_provider ?? '')==='') echo 'selected'; ?>>None (Disabled)</option>
|
||||
<option value="standard_smtp" <?php if(($config_smtp_provider ?? 'standard_smtp')==='standard_smtp') echo 'selected'; ?>>Standard SMTP (Username/Password)</option>
|
||||
<option value="google_oauth" <?php if(($config_smtp_provider ?? '')==='google_oauth') echo 'selected'; ?>>Google Workspace (OAuth)</option>
|
||||
<option value="microsoft_oauth" <?php if(($config_smtp_provider ?? '')==='microsoft_oauth') echo 'selected'; ?>>Microsoft 365 (OAuth)</option>
|
||||
</select>
|
||||
</div>
|
||||
<small class="text-secondary d-block mt-1" id="smtp_provider_hint">
|
||||
Choose your SMTP provider. OAuth options ignore the SMTP password here.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>SMTP Username</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="config_smtp_username" placeholder="Username (Leave blank if no auth is required)" value="<?php echo nullable_htmlentities($config_smtp_username); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>SMTP Password</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
||||
</div>
|
||||
<input type="password" class="form-control" data-toggle="password" name="config_smtp_password" placeholder="Password (Leave blank if no auth is required)" value="<?php echo nullable_htmlentities($config_smtp_password); ?>" autocomplete="new-password">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
|
||||
<!-- Standard SMTP fields (show only for standard_smtp) -->
|
||||
<div id="smtp_standard_fields">
|
||||
<div class="form-group">
|
||||
<label>SMTP Host</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-server"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="config_smtp_host" placeholder="Mail Server Address" value="<?php echo nullable_htmlentities($config_smtp_host); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>SMTP Port</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
|
||||
</div>
|
||||
<input type="number" min="0" class="form-control" name="config_smtp_port" placeholder="Mail Server Port Number" value="<?php echo intval($config_smtp_port); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Encryption</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
||||
</div>
|
||||
<select class="form-control" name="config_smtp_encryption">
|
||||
<option value=''>None</option>
|
||||
<option <?php if ($config_smtp_encryption == 'tls') { echo "selected"; } ?> value="tls">TLS</option>
|
||||
<option <?php if ($config_smtp_encryption == 'ssl') { echo "selected"; } ?> value="ssl">SSL</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>SMTP Username</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="config_smtp_username" placeholder="Username (Leave blank if no auth is required)" value="<?php echo nullable_htmlentities($config_smtp_username); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" id="smtp_password_group">
|
||||
<div class="form-group">
|
||||
<label>SMTP Password</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
||||
</div>
|
||||
<input type="password" class="form-control" data-toggle="password" name="config_smtp_password" placeholder="Password (Leave blank if no auth is required)" value="<?php echo nullable_htmlentities($config_smtp_password); ?>" autocomplete="new-password">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
@@ -84,37 +110,56 @@ require_once "includes/inc_all_admin.php";
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="form-group">
|
||||
<label>IMAP Host</label>
|
||||
<label>IMAP Provider</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-server"></i></span>
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-cloud"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="config_imap_host" placeholder="Incoming Mail Server Address (for email to ticket parsing)" value="<?php echo nullable_htmlentities($config_imap_host); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>IMAP Port</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
|
||||
</div>
|
||||
<input type="number" min="0" class="form-control" name="config_imap_port" placeholder="Incoming Mail Server Port Number (993)" value="<?php echo intval($config_imap_port); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>IMAP Encryption</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
||||
</div>
|
||||
<select class="form-control" name="config_imap_encryption">
|
||||
<option value=''>None</option>
|
||||
<option <?php if ($config_imap_encryption == 'tls') { echo "selected"; } ?> value="tls">TLS</option>
|
||||
<option <?php if ($config_imap_encryption == 'ssl') { echo "selected"; } ?> value="ssl">SSL</option>
|
||||
<select class="form-control" name="config_imap_provider" id="config_imap_provider">
|
||||
<option value="none" <?php if($config_imap_provider ==='') echo 'selected'; ?>>None (Disabled)</option>
|
||||
<option value="standard_imap" <?php if(($config_imap_provider ?? 'standard_imap')==='standard_imap') echo 'selected'; ?>>Standard IMAP (Username/Password)</option>
|
||||
<option value="google_oauth" <?php if(($config_imap_provider ?? '')==='google_oauth') echo 'selected'; ?>>Google Workspace (OAuth)</option>
|
||||
<option value="microsoft_oauth" <?php if(($config_imap_provider ?? '')==='microsoft_oauth') echo 'selected'; ?>>Microsoft 365 (OAuth)</option>
|
||||
</select>
|
||||
</div>
|
||||
<small class="text-secondary d-block mt-1" id="imap_provider_hint">
|
||||
Select your mailbox provider. OAuth options ignore the IMAP password here.
|
||||
</small>
|
||||
</div>
|
||||
<div id="standard_fields" style="display:none;">
|
||||
<div class="form-group">
|
||||
<label>IMAP Host</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-server"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="config_imap_host" placeholder="Incoming Mail Server Address (for email to ticket parsing)" value="<?php echo nullable_htmlentities($config_imap_host); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>IMAP Port</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-plug"></i></span>
|
||||
</div>
|
||||
<input type="number" min="0" class="form-control" name="config_imap_port" placeholder="Incoming Mail Server Port Number (993)" value="<?php echo intval($config_imap_port); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>IMAP Encryption</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
||||
</div>
|
||||
<select class="form-control" name="config_imap_encryption">
|
||||
<option value=''>None</option>
|
||||
<option <?php if ($config_imap_encryption == 'tls') { echo "selected"; } ?> value="tls">TLS</option>
|
||||
<option <?php if ($config_imap_encryption == 'ssl') { echo "selected"; } ?> value="ssl">SSL</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='form-group'>
|
||||
@@ -123,25 +168,81 @@ require_once "includes/inc_all_admin.php";
|
||||
<div class='input-group-prepend'>
|
||||
<span class='input-group-text'><i class='fa fa-fw fa-user'></i></span>
|
||||
</div>
|
||||
<input type='text' class='form-control' name='config_imap_username' placeholder='Username' value="<?php
|
||||
echo nullable_htmlentities($config_imap_username); ?>" required>
|
||||
<input type='text' class='form-control' name='config_imap_username' placeholder='Username (email address)' value="<?php echo nullable_htmlentities($config_imap_username); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='form-group'>
|
||||
<div class='form-group' id="imap_password_group">
|
||||
<label>IMAP Password</label>
|
||||
<div class='input-group'>
|
||||
<div class='input-group-prepend'>
|
||||
<span class='input-group-text'><i class='fa fa-fw fa-key'></i></span>
|
||||
</div>
|
||||
<input type='password' class='form-control' data-toggle='password' name='config_imap_password' placeholder='Password' value="<?php
|
||||
echo nullable_htmlentities($config_imap_password); ?>" autocomplete='new-password' required>
|
||||
<input type='password' class='form-control' data-toggle='password' name='config_imap_password' placeholder='Password (not used for OAuth)' value="<?php echo nullable_htmlentities($config_imap_password); ?>" autocomplete='new-password'>
|
||||
<div class='input-group-append'>
|
||||
<span class='input-group-text'><i class='fa fa-fw fa-eye'></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- OAuth shared fields (show for google_oauth / microsoft_oauth) -->
|
||||
<div id="smtp_oauth_fields" style="display:none;">
|
||||
<hr>
|
||||
<h5 class="mb-2">OAuth Settings (shared for IMAP & SMTP)</h5>
|
||||
<p class="text-secondary" id="oauth_hint">
|
||||
Configure OAuth credentials for the selected provider.
|
||||
</p>
|
||||
|
||||
<div class="form-group">
|
||||
<label>OAuth Client ID</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-id-badge"></i></span></div>
|
||||
<input type="text" class="form-control" name="config_mail_oauth_client_id"
|
||||
value="<?php echo nullable_htmlentities($config_mail_oauth_client_id ?? ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>OAuth Client Secret</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-key"></i></span></div>
|
||||
<input type="password" class="form-control" data-toggle="password" name="config_mail_oauth_client_secret"
|
||||
value="<?php echo nullable_htmlentities($config_mail_oauth_client_secret ?? ''); ?>" autocomplete="new-password">
|
||||
<div class="input-group-append"><span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" id="tenant_row" style="display:none;">
|
||||
<label>Tenant ID (Microsoft 365 only)</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-building"></i></span></div>
|
||||
<input type="text" class="form-control" name="config_mail_oauth_tenant_id"
|
||||
value="<?php echo nullable_htmlentities($config_mail_oauth_tenant_id ?? ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Refresh Token</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-sync-alt"></i></span></div>
|
||||
<textarea class="form-control" name="config_mail_oauth_refresh_token" rows="2"
|
||||
placeholder="Paste refresh token"><?php echo nullable_htmlentities($config_mail_oauth_refresh_token ?? ''); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Access Token (optional – will refresh if expired)</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend"><span class="input-group-text"><i class="fa fa-fw fa-shield-alt"></i></span></div>
|
||||
<textarea class="form-control" name="config_mail_oauth_access_token" rows="2"
|
||||
placeholder="Can be left blank; system refreshes using the refresh token"><?php echo nullable_htmlentities($config_mail_oauth_access_token ?? ''); ?></textarea>
|
||||
</div>
|
||||
<small class="text-secondary">
|
||||
Expires at: <?php echo !empty($config_mail_oauth_access_token_expires_at) ? htmlspecialchars($config_mail_oauth_access_token_expires_at) : 'n/a'; ?>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<button type="submit" name="edit_mail_imap_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||
@@ -327,5 +428,68 @@ require_once "includes/inc_all_admin.php";
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<?php require_once "../includes/footer.php";
|
||||
<script>
|
||||
(function(){
|
||||
function setDisabled(container, disabled){
|
||||
if(!container) return;
|
||||
container.querySelectorAll('input, select, textarea').forEach(el => el.disabled = !!disabled);
|
||||
}
|
||||
|
||||
function wireProvider(selectId, standardWrapId, passwordGroupId, oauthWrapId, tenantRowId, hintId, oauthHintId){
|
||||
const sel = document.getElementById(selectId);
|
||||
const std = document.getElementById(standardWrapId);
|
||||
const pwd = document.getElementById(passwordGroupId);
|
||||
const oauth = document.getElementById(oauthWrapId);
|
||||
const ten = document.getElementById(tenantRowId);
|
||||
const hint = document.getElementById(hintId);
|
||||
const ohint = document.getElementById(oauthHintId);
|
||||
|
||||
function toggle(){
|
||||
const v = (sel && sel.value) || '';
|
||||
const isNone = (v === 'none' || v === '');
|
||||
const isStd = v === 'standard_smtp' || v === 'standard_imap';
|
||||
const isG = v === 'google_oauth';
|
||||
const isM = v === 'microsoft_oauth';
|
||||
const isOAuth = isG || isM;
|
||||
|
||||
if (std) std.style.display = isStd ? '' : 'none';
|
||||
if (pwd) pwd.style.display = isStd ? '' : 'none';
|
||||
if (oauth) oauth.style.display = isOAuth ? '' : 'none';
|
||||
if (ten) ten.style.display = isM ? '' : 'none';
|
||||
|
||||
setDisabled(std, !isStd);
|
||||
setDisabled(pwd, !isStd);
|
||||
setDisabled(oauth, !isOAuth);
|
||||
|
||||
if (hint) {
|
||||
hint.textContent = isNone
|
||||
? 'Disabled.'
|
||||
: isStd
|
||||
? 'Standard: provide host, port, encryption, username & password.'
|
||||
: isG
|
||||
? 'Google OAuth: set Client ID/Secret; paste a refresh token; username should be the mailbox email.'
|
||||
: 'Microsoft 365 OAuth: set Client ID/Secret/Tenant; paste a refresh token; username should be the mailbox email.';
|
||||
}
|
||||
if (ohint) {
|
||||
ohint.textContent = isG
|
||||
? 'Google Workspace OAuth: Client ID/Secret from Google Cloud; Refresh token via consent.'
|
||||
: isM
|
||||
? 'Microsoft 365 OAuth: Client ID/Secret/Tenant from Entra ID; Refresh token via consent.'
|
||||
: 'Configure OAuth credentials for the selected provider.';
|
||||
}
|
||||
}
|
||||
|
||||
if (sel) { sel.addEventListener('change', toggle); toggle(); }
|
||||
}
|
||||
|
||||
// IMAP (you already have these IDs in your page)
|
||||
wireProvider('config_imap_provider', 'standard_fields', 'imap_password_group',
|
||||
'oauth_fields', 'tenant_row', 'imap_provider_hint', 'oauth_hint');
|
||||
|
||||
// SMTP (the IDs we just added)
|
||||
wireProvider('config_smtp_provider', 'smtp_standard_fields', 'smtp_password_group',
|
||||
'smtp_oauth_fields', 'smtp_tenant_row', 'smtp_provider_hint', 'smtp_oauth_hint');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<?php require_once "../includes/footer.php";
|
||||
|
||||
@@ -13,7 +13,7 @@ $sql = mysqli_query(
|
||||
LEFT JOIN user_settings ON users.user_id = user_settings.user_id
|
||||
WHERE (user_name LIKE '%$q%' OR user_email LIKE '%$q%')
|
||||
AND user_type = 1
|
||||
AND user_archived_at IS NULL
|
||||
AND user_$archive_query
|
||||
ORDER BY $sort $order LIMIT $record_from, $record_to"
|
||||
);
|
||||
|
||||
@@ -53,6 +53,12 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="btn-group float-right">
|
||||
<a href="?archived=<?php if($archived == 1){ echo 0; } else { echo 1; } ?>"
|
||||
class="btn btn-<?php if($archived == 1){ echo "primary"; } else { echo "default"; } ?>">
|
||||
<i class="fa fa-fw fa-archive mr-2"></i>Archived
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -113,8 +119,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
$user_config_force_mfa = intval($row['user_config_force_mfa']);
|
||||
$user_role = intval($row['user_role_id']);
|
||||
$user_role_display = nullable_htmlentities($row['role_name']);
|
||||
$user_archived_at = nullable_htmlentities($row['user_archived_at']);
|
||||
$user_initials = nullable_htmlentities(initials($user_name));
|
||||
|
||||
|
||||
$sql_last_login = mysqli_query(
|
||||
$mysqli,
|
||||
"SELECT * FROM logs
|
||||
@@ -196,10 +204,17 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<i class="fas fa-fw fa-user-slash mr-2"></i>Disable
|
||||
</a>
|
||||
<?php } ?>
|
||||
<?php if ($user_archived_at) { ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger" href="#" data-toggle="modal" data-target="#archiveUserModal<?php echo $user_id; ?>">
|
||||
<a class="dropdown-item text-info ajax-modal" href="#" data-modal-url="modals/user/user_restore.php?id=<?= $user_id ?>">
|
||||
<i class="fas fa-fw fa-redo-alt mr-2"></i>Restore
|
||||
</a>
|
||||
<?php } else { ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger ajax-modal" href="#" data-modal-url="modals/user/user_archive.php?id=<?= $user_id ?>">
|
||||
<i class="fas fa-fw fa-archive mr-2"></i>Archive
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
@@ -207,9 +222,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
require "modals/user/user_archive.php";
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -106,7 +106,7 @@ while ($row = mysqli_fetch_array($sql)) {
|
||||
<?php require_once "../includes/footer.php";
|
||||
?>
|
||||
|
||||
<script src='../plugins/fullcalendar/dist/index.global.js'></script>
|
||||
<script src='/plugins/fullcalendar/dist/index.global.js'></script>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
@@ -504,7 +504,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<?php } ?>
|
||||
<?php
|
||||
if (!empty($client_tags_display)) { ?>
|
||||
<div class="mt-1">
|
||||
<div class="mt-1 text-wrap">
|
||||
<?php echo $client_tags_display; ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
@@ -566,10 +566,12 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||
<span class="text-secondary">Paid</span>
|
||||
<span><?php echo numfmt_format_currency($currency_format, $amount_paid, $session_company_currency); ?></span>
|
||||
</div>
|
||||
<?php if ($credit_balance > 0) { ?>
|
||||
<div class="d-flex justify-content-between">
|
||||
<span class="text-secondary">Credit</span>
|
||||
<span class="text-success"><?php echo numfmt_format_currency($currency_format, $credit_balance, $session_company_currency); ?></span>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<div class="d-flex justify-content-between">
|
||||
<span class="text-secondary">Monthly</span>
|
||||
<span><?php echo numfmt_format_currency($currency_format, $recurring_monthly, $session_company_currency); ?></span>
|
||||
45
agent/custom/includes/custom_side_nav.php
Normal file
45
agent/custom/includes/custom_side_nav.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<!-- Main Sidebar Container -->
|
||||
<aside class="main-sidebar sidebar-dark-primary d-print-none">
|
||||
|
||||
<a class="pb-1 mt-1 brand-link" href="../<?php echo $config_start_page ?>">
|
||||
<p class="h5"><i class="nav-icon fas fa-arrow-left ml-3 mr-2"></i>
|
||||
<span class="brand-text ">Back | <strong>Custom</strong>
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
|
||||
<!-- Sidebar Menu -->
|
||||
<nav>
|
||||
|
||||
<ul class="nav nav-pills nav-sidebar flex-column mt-2" data-widget="treeview" data-accordion="false">
|
||||
|
||||
<li class="nav-header">CUSTOM HEADER</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="index.php" class="nav-link <?php if (basename($_SERVER["PHP_SELF"]) == "index.php") { echo "active"; } ?>">
|
||||
<i class="far fa-circle nav-icon"></i>
|
||||
<p>custom</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
<!-- /.sidebar-menu -->
|
||||
|
||||
<div class="sidebar-custom mb-3">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.sidebar -->
|
||||
</aside>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
13
agent/custom/includes/inc_all_custom.php
Normal file
13
agent/custom/includes/inc_all_custom.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
require_once "../../config.php";
|
||||
require_once "../../functions.php";
|
||||
require_once "../../includes/check_login.php";
|
||||
require_once "../../includes/page_title.php";
|
||||
require_once "../../includes/header.php";
|
||||
require_once "../../includes/top_nav.php";
|
||||
require_once "includes/custom_side_nav.php";
|
||||
require_once "../../includes/inc_wrapper.php";
|
||||
require_once "../../includes/inc_alert_feedback.php";
|
||||
require_once "../../includes/filter_header.php";
|
||||
|
||||
72
agent/custom/index.php
Normal file
72
agent/custom/index.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php require_once "includes/inc_all_custom.php"; ?>
|
||||
|
||||
<!-- Breadcrumbs-->
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="index.html">Dashboard</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">Blank Page</li>
|
||||
</ol>
|
||||
|
||||
<!-- Page Content -->
|
||||
<h1>Blank Page</h1>
|
||||
<hr>
|
||||
<p>This is a great starting point for new custom pages.</p>
|
||||
<h1><?php echo $session_user_role; ?></h1>
|
||||
<?php validateAdminRole(); ?>
|
||||
|
||||
<?php
|
||||
|
||||
$start_date = date('Y') . "-10-10";
|
||||
|
||||
echo "<H1>$start_date</H1>";
|
||||
|
||||
echo "<H2>User Agent</H2>";
|
||||
echo getUserAgent();
|
||||
|
||||
|
||||
?>
|
||||
<br>
|
||||
|
||||
<input type="tel" name="phone" id="phone">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Minimal</label>
|
||||
<select class="form-control select2 select2-hidden-accessible" style="width: 100%;" data-select2-id="1" tabindex="-1" aria-hidden="true">
|
||||
<option selected="selected" data-select2-id="3">Alabama</option>
|
||||
<option data-select2-id="35">Alaska</option>
|
||||
<option data-select2-id="36">California</option>
|
||||
<option data-select2-id="37">Delaware</option>
|
||||
<option data-select2-id="38">Tennessee</option>
|
||||
<option data-select2-id="39">Texas</option>
|
||||
<option data-select2-id="40">Washington</option>
|
||||
</select><span class="select2 select2-container select2-container--default select2-container--below" dir="ltr" data-select2-id="2" style="width: 100%;"><span class="selection"><span class="select2-selection select2-selection--single" role="combobox" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-disabled="false" aria-labelledby="select2-nbex-container"><span class="select2-selection__rendered" id="select2-nbex-container" role="textbox" aria-readonly="true" title="Alabama">Alabama</span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span></span></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>
|
||||
</div>
|
||||
|
||||
<dl>
|
||||
<dt>Requester</dt>
|
||||
<dd>Sam Adams</dd>
|
||||
|
||||
<dt>Created</dt>
|
||||
<dd><time datetime="2024-04-11T17:52:30+00:00" title="2024-04-11 13:52" data-datetime="calendar">Today at 13:52</time></dd>
|
||||
|
||||
<dt>Last activity</dt>
|
||||
<dd><time datetime="2024-04-11T18:08:55+00:00" title="2024-04-11 14:08" data-datetime="calendar">Today at 14:08</time></dd>
|
||||
</dl>
|
||||
|
||||
<?php echo randomString(100); ?>
|
||||
<br>
|
||||
<textarea class="tinymceTest"></textarea>
|
||||
|
||||
<textarea class="tinymce"></textarea>
|
||||
|
||||
<textarea class="tinymceTicket"></textarea>
|
||||
<?php
|
||||
// show the current Date and Time
|
||||
$date_time = date('Y-m-d H:i:s');
|
||||
echo "Current Date and Time: <strong>$date_time</strong>";
|
||||
?>
|
||||
|
||||
<script>toastr.success('Have Fun Wozz!!')</script>
|
||||
|
||||
<?php require_once "../../includes/footer.php";
|
||||
@@ -1,12 +1,12 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ITFlow - Custom GET/POST request handler
|
||||
* ITFlow - User GET/POST request handler
|
||||
*/
|
||||
|
||||
require_once "../config.php";
|
||||
require_once "../functions.php";
|
||||
require_once "../includes/check_login.php";
|
||||
require_once "../../config.php";
|
||||
require_once "../../functions.php";
|
||||
require_once "../../includes/check_login.php";
|
||||
|
||||
// Define a variable that we can use to only allow running post files via inclusion (prevents people/bots poking them)
|
||||
define('FROM_POST_HANDLER', true);
|
||||
@@ -24,17 +24,23 @@ $module = explode(".", basename($path))[0];
|
||||
$module = str_ireplace('_details', '', $module);
|
||||
|
||||
// Dynamically load admin-related module POST logic
|
||||
if (str_contains($module, 'custom')) {
|
||||
// Dynamically load any custom POST logic
|
||||
|
||||
include_once "post/$module.php";
|
||||
// Load all module POST logic
|
||||
// Loads everything in post/user/
|
||||
// Eventually, it would be nice to only specifically load what we need like we do for admins
|
||||
|
||||
foreach (glob("post/*.php") as $user_module) {
|
||||
if (!preg_match('/_model\.php$/', basename($user_module))) {
|
||||
require_once $user_module;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Logout is the same for user and admin
|
||||
require_once "../post/logout.php";
|
||||
require_once "../../post/logout.php";
|
||||
|
||||
// TODO: Find a home for these
|
||||
|
||||
require_once "../post/ai.php";
|
||||
require_once "../post/misc.php";
|
||||
require_once "../../post/ai.php";
|
||||
require_once "../../post/misc.php";
|
||||
|
||||
@@ -209,7 +209,7 @@ if ($user_config_dashboard_financial_enable == 1) {
|
||||
|
||||
<div class="col-lg-4 col-md-6 col-sm-12">
|
||||
<!-- small box -->
|
||||
<a class="small-box bg-success" href="report_profit_loss.php">
|
||||
<a class="small-box bg-success" href="reports/profit_loss.php">
|
||||
<div class="inner">
|
||||
<h3><?php echo numfmt_format_currency($currency_format, $profit, "$session_company_currency"); ?></h3>
|
||||
<p>Profit</p>
|
||||
@@ -223,7 +223,7 @@ if ($user_config_dashboard_financial_enable == 1) {
|
||||
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<!-- small box -->
|
||||
<a class="small-box bg-info" href="report_recurring_by_client.php">
|
||||
<a class="small-box bg-info" href="reports/recurring_by_client.php">
|
||||
<div class="inner">
|
||||
<h3><?php echo numfmt_format_currency($currency_format, $recurring_monthly_total, "$session_company_currency"); ?></h3>
|
||||
<p>Monthly Recurring Income</p>
|
||||
@@ -252,7 +252,7 @@ if ($user_config_dashboard_financial_enable == 1) {
|
||||
<?php if ($config_module_enable_ticketing && $config_module_enable_accounting) { ?>
|
||||
<div class="col-lg-2 col-md-6 col-sm-12">
|
||||
<!-- small box -->
|
||||
<a class="small-box bg-secondary" href="report_tickets_unbilled.php">
|
||||
<a class="small-box bg-secondary" href="reports/tickets_unbilled.php">
|
||||
<div class="inner">
|
||||
<h3><?php echo $unbilled_tickets; ?></h3>
|
||||
<p>Unbilled Ticket<?php if ($unbilled_tickets > 1 || $unbilled_tickets == 0) { echo "s"; } ?></p>
|
||||
@@ -338,7 +338,7 @@ if ($user_config_dashboard_financial_enable == 1) {
|
||||
<div class="card-header">
|
||||
<h3 class="card-title"><i class="fas fa-fw fa-chart-area mr-2"></i>Cash Flow</h3>
|
||||
<div class="card-tools">
|
||||
<a href="report_income_summary.php" class="btn btn-tool">
|
||||
<a href="reports/income_summary.php" class="btn btn-tool">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
<button type="button" class="btn btn-tool" data-card-widget="remove">
|
||||
@@ -2,7 +2,6 @@
|
||||
// Configuration & core
|
||||
require_once "../config.php";
|
||||
require_once "../functions.php";
|
||||
require_once "../includes/router.php";
|
||||
require_once "../includes/check_login.php";
|
||||
|
||||
// Page setup
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
require_once "../config.php";
|
||||
require_once "../functions.php";
|
||||
require_once "../includes/router.php";
|
||||
require_once "../includes/check_login.php";
|
||||
require_once "../includes/page_title.php";
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
require_once "../config.php";
|
||||
require_once "../functions.php";
|
||||
require_once "../includes/router.php";
|
||||
require_once "../includes/check_login.php";
|
||||
require_once "../includes/page_title.php";
|
||||
require_once "../includes/header.php";
|
||||
@@ -11,4 +10,3 @@ require_once "includes/client_overview_side_nav.php";
|
||||
require_once "../includes/inc_wrapper.php";
|
||||
require_once "../includes/inc_alert_feedback.php";
|
||||
require_once "../includes/filter_header.php";
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<?php $show_add_credit = 0; // Remove once credits is added hides the button ?>
|
||||
|
||||
<div class="card d-print-none">
|
||||
<div class="card-header pb-1 pt-2 px-3">
|
||||
<div class="card-title">
|
||||
@@ -16,10 +18,12 @@
|
||||
<i class="fas fa-fw fa-edit mr-2"></i>Edit Client
|
||||
</a>
|
||||
<?php if (lookupUserPermission("module_billing") >= 2) { ?>
|
||||
<?php if ($show_add_credit) { ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#addCreditModal">
|
||||
<i class="fas fa-fw fa-wallet mr-2"></i>Add Credit
|
||||
</a>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php if (lookupUserPermission("module_client") >= 3) { ?>
|
||||
<div class="dropdown-divider"></div>
|
||||
@@ -188,7 +188,7 @@
|
||||
|
||||
<?php if (lookupUserPermission("module_reporting") >= 1) { ?>
|
||||
<li class="nav-item mt-3">
|
||||
<a href="report_overview.php" class="nav-link">
|
||||
<a href="reports/" class="nav-link">
|
||||
<i class="fas fa-chart-line nav-icon"></i>
|
||||
<p>Reports</p>
|
||||
<i class="fas fa-angle-right nav-icon float-right"></i>
|
||||
@@ -15,10 +15,8 @@ require_once "includes/inc_all.php";
|
||||
<!-- Page Content -->
|
||||
<h1>Blank Page</h1>
|
||||
<hr>
|
||||
|
||||
<meta http-equiv="refresh" content="0;url=<?php echo $config_start_page; ?>">
|
||||
|
||||
<?php
|
||||
|
||||
if (isset($config_start_page)) { ?>
|
||||
<meta http-equiv="refresh" content="0;url=<?php echo $config_start_page; ?>">
|
||||
<?php }
|
||||
|
||||
require_once "../includes/footer.php";
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user