mirror of
https://github.com/itflow-org/itflow
synced 2026-03-11 00:04:50 +00:00
Compare commits
258 Commits
ticket-tas
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d13104bb5a | ||
|
|
5d85810e58 | ||
|
|
b00014771d | ||
|
|
b133f63736 | ||
|
|
e45563ad66 | ||
|
|
cf639cbf98 | ||
|
|
b365b7c810 | ||
|
|
b394f484d3 | ||
|
|
ada336ceea | ||
|
|
26ebac450f | ||
|
|
6e33c071ef | ||
|
|
5bd21a2bd4 | ||
|
|
e2547122a6 | ||
|
|
edad83cc37 | ||
|
|
b0190f462c | ||
|
|
c936823912 | ||
|
|
7acaf55331 | ||
|
|
6122efc870 | ||
|
|
7f180eb6d9 | ||
|
|
72091670fd | ||
|
|
2b6ebca4c3 | ||
|
|
e44d571331 | ||
|
|
526fa1aff5 | ||
|
|
11ba077726 | ||
|
|
ffb97006ec | ||
|
|
8dbbef37bb | ||
|
|
92b98b95ee | ||
|
|
083262fedb | ||
|
|
fe9bc05937 | ||
|
|
726b1cd42b | ||
|
|
8de7b20ba1 | ||
|
|
6d2cb0aea3 | ||
|
|
c8273b2052 | ||
|
|
60b6c245ef | ||
|
|
fcf098f494 | ||
|
|
74ce8f4e98 | ||
|
|
6e3a36d8c4 | ||
|
|
6f0a2a5a73 | ||
|
|
111a30f13c | ||
|
|
202f55c2ff | ||
|
|
8ad8fd07b3 | ||
|
|
a1931f59f8 | ||
|
|
e7b70c7992 | ||
|
|
7563148182 | ||
|
|
a252ff717e | ||
|
|
7d41782013 | ||
|
|
91976cc415 | ||
|
|
8afa2dbf75 | ||
|
|
3983c45cac | ||
|
|
df5c350765 | ||
|
|
de8b9df4da | ||
|
|
3be815c749 | ||
|
|
71b19e125e | ||
|
|
8fc3dfed1f | ||
|
|
30357b9cf7 | ||
|
|
a81edc122d | ||
|
|
994526e2c8 | ||
|
|
203b161e82 | ||
|
|
47b8ec6f96 | ||
|
|
302914c789 | ||
|
|
f77bd4f0c6 | ||
|
|
af4327ff27 | ||
|
|
5cbed128e6 | ||
|
|
dd5fde4069 | ||
|
|
220e1d4e24 | ||
|
|
3481431eb5 | ||
|
|
b94604ae71 | ||
|
|
fe406487de | ||
|
|
99218d02ad | ||
|
|
8cd1668ff2 | ||
|
|
c0f26204c2 | ||
|
|
ef3a7d0490 | ||
|
|
f9558d4701 | ||
|
|
9d9ebe7b9e | ||
|
|
918b40afbe | ||
|
|
6da8821f2c | ||
|
|
90171064a8 | ||
|
|
6bbe887f8b | ||
|
|
b5fb14ec96 | ||
|
|
dd2ac00aa2 | ||
|
|
e7b5e7120a | ||
|
|
8bac4f9e53 | ||
|
|
023cb4ff11 | ||
|
|
1740599b61 | ||
|
|
24b244b612 | ||
|
|
c71d1f190e | ||
|
|
18e180eca5 | ||
|
|
d936339f07 | ||
|
|
ad16e92763 | ||
|
|
8a1335174d | ||
|
|
7b438e2889 | ||
|
|
550980719e | ||
|
|
3d80d1519e | ||
|
|
1d5fceeecd | ||
|
|
5b49908438 | ||
|
|
7e515afb79 | ||
|
|
dee5085f4a | ||
|
|
795144b288 | ||
|
|
5c3ff91f21 | ||
|
|
36ac006438 | ||
|
|
af1ebfea41 | ||
|
|
f653752026 | ||
|
|
4440581f14 | ||
|
|
2c47001b19 | ||
|
|
e1daa14087 | ||
|
|
308dc6e550 | ||
|
|
54638428e3 | ||
|
|
1508e6b055 | ||
|
|
9213249f7b | ||
|
|
63f6faf1e8 | ||
|
|
c2cbfc5558 | ||
|
|
ef1b65de09 | ||
|
|
ae81092112 | ||
|
|
f09be24188 | ||
|
|
10c37946b1 | ||
|
|
adb43703ed | ||
|
|
92fba49a91 | ||
|
|
ac4bb32081 | ||
|
|
7927312f4f | ||
|
|
04a74b5a34 | ||
|
|
87fd23f443 | ||
|
|
9cb1ff7330 | ||
|
|
1ba19cc249 | ||
|
|
702d9689d6 | ||
|
|
8efa354fdb | ||
|
|
129e95fd3a | ||
|
|
ef7794c411 | ||
|
|
12b3775041 | ||
|
|
52b509fdc5 | ||
|
|
f9d0a8bf43 | ||
|
|
2349ef33d1 | ||
|
|
ccaf15268c | ||
|
|
616635f951 | ||
|
|
ce7daaf1cf | ||
|
|
fb9f5d986d | ||
|
|
3148906cfe | ||
|
|
6c057f4fd0 | ||
|
|
3014bba66d | ||
|
|
97958d5e22 | ||
|
|
1a7452cc27 | ||
|
|
34ba5d0570 | ||
|
|
c0fe9813dc | ||
|
|
fd29eb7c15 | ||
|
|
1bee085b33 | ||
|
|
1d06e6d9c8 | ||
|
|
bdf8038148 | ||
|
|
62fb2c91a1 | ||
|
|
d1eeba67fc | ||
|
|
2ca8112daf | ||
|
|
546f10bc82 | ||
|
|
ec7f1d561d | ||
|
|
8d54bc3a2f | ||
|
|
1d8f77f799 | ||
|
|
1c6795dd55 | ||
|
|
4d895a56e4 | ||
|
|
bdd56c91f7 | ||
|
|
be172b5bd9 | ||
|
|
d224d71f59 | ||
|
|
065630b975 | ||
|
|
decea604ab | ||
|
|
004b3b2bdc | ||
|
|
dca0cc34e9 | ||
|
|
9afb165fc4 | ||
|
|
6a6eb4a714 | ||
|
|
629f4e0c81 | ||
|
|
7cbe9bf7fc | ||
|
|
fc33312e79 | ||
|
|
563c0ea9c4 | ||
|
|
10d1a902d9 | ||
|
|
4079257739 | ||
|
|
91aba13c0d | ||
|
|
2cca4f2f0e | ||
|
|
d2e8dc1439 | ||
|
|
f3f9d0dd71 | ||
|
|
f6845a046f | ||
|
|
a50a4f274f | ||
|
|
6b6d847756 | ||
|
|
65d1f59e9b | ||
|
|
f39e6ccbc9 | ||
|
|
747b62d78c | ||
|
|
af0f3ac25f | ||
|
|
6aefe99c2f | ||
|
|
61c5595a68 | ||
|
|
3d11611699 | ||
|
|
38b4ed4b96 | ||
|
|
34308a5f9a | ||
|
|
118cc10804 | ||
|
|
ae3386f2d5 | ||
|
|
bf1ccc62f5 | ||
|
|
1ce4dd932e | ||
|
|
ff0bb49926 | ||
|
|
018642cbb8 | ||
|
|
bf1d0655c4 | ||
|
|
874b07f4d7 | ||
|
|
19fa210743 | ||
|
|
c8a6513d1c | ||
|
|
01288c8452 | ||
|
|
a60d3bb3a0 | ||
|
|
0470159c55 | ||
|
|
e1a93035fd | ||
|
|
c0b7a26905 | ||
|
|
704d770ec2 | ||
|
|
d42d2d99b1 | ||
|
|
ebfcc15927 | ||
|
|
4693aa3c93 | ||
|
|
07df657848 | ||
|
|
ef9436a1fb | ||
|
|
9318f42ce0 | ||
|
|
85c37d78a8 | ||
|
|
ff02ab0cea | ||
|
|
bd8bf026f0 | ||
|
|
644dc95380 | ||
|
|
f4935efed3 | ||
|
|
1712d34846 | ||
|
|
f0f1134be6 | ||
|
|
e0f7460e08 | ||
|
|
ae1d71dcd7 | ||
|
|
3cfe38c948 | ||
|
|
c1f0b63101 | ||
|
|
0a658d7cab | ||
|
|
3ed2582a9b | ||
|
|
2ea68776f6 | ||
|
|
c1ff22298f | ||
|
|
e94d2f93ea | ||
|
|
e7f6f8a4c7 | ||
|
|
4ffe75683b | ||
|
|
687920743d | ||
|
|
1a93149643 | ||
|
|
11d6654763 | ||
|
|
512d65c17a | ||
|
|
5a274061f3 | ||
|
|
a398ac7a8d | ||
|
|
41df4c4b9f | ||
|
|
7e7909cec1 | ||
|
|
7322bd66df | ||
|
|
39affa5528 | ||
|
|
374111c88d | ||
|
|
72fc0015bf | ||
|
|
7ab406b3f5 | ||
|
|
df280cd574 | ||
|
|
0a30300bde | ||
|
|
cb8b99d6ae | ||
|
|
1d3f29d385 | ||
|
|
c154113474 | ||
|
|
e02a6fc5e6 | ||
|
|
78040573d1 | ||
|
|
981f9ace04 | ||
|
|
208f7ac8f0 | ||
|
|
661f8db10b | ||
|
|
b48168ffec | ||
|
|
908ebb46d9 | ||
|
|
1de023f9df | ||
|
|
5815ef2f75 | ||
|
|
e5dab8b1ca | ||
|
|
56c4b7fbe6 | ||
|
|
365b65e5b2 | ||
|
|
2193cd8d3e | ||
|
|
8b221bc055 |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -32,10 +32,6 @@ plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/URI/*
|
|||||||
plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/CSS/*
|
plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/CSS/*
|
||||||
!plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/CSS/.gitkeep
|
!plugins/htmlpurifier/standalone/HTMLPurifier/DefinitionCache/Serializer/CSS/.gitkeep
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
xcustom/*
|
|
||||||
!xcustom/readme.php
|
|
||||||
post/xcustom
|
|
||||||
!post/xcustom/readme.php
|
|
||||||
admin/custom/*
|
admin/custom/*
|
||||||
!admin/custom/readme.php
|
!admin/custom/readme.php
|
||||||
agent/custom/*
|
agent/custom/*
|
||||||
@@ -53,5 +49,3 @@ setup/custom/*
|
|||||||
api/v1/custom/*
|
api/v1/custom/*
|
||||||
!api/v1/custom/readme.php
|
!api/v1/custom/readme.php
|
||||||
.zed
|
.zed
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
107
CHANGELOG.md
107
CHANGELOG.md
@@ -2,6 +2,113 @@
|
|||||||
|
|
||||||
This file documents all notable changes made to ITFlow.
|
This file documents all notable changes made to ITFlow.
|
||||||
|
|
||||||
|
## [26.03] Stable Release
|
||||||
|
### Bug Fixes
|
||||||
|
- Ticket Templates: Fix Task Sorting.
|
||||||
|
- Ticket: Lower autoclose setting minimum value from 48 to 24 Hours.
|
||||||
|
- Ticket: Fix Task Approval.
|
||||||
|
- Recurring Ticket: add empty value placeholder for Ticket Frequency.
|
||||||
|
- Documents/Files: Fix redirect after File Upload to redirect to files instead of the non existent documents.
|
||||||
|
- Setup: Fix base url tacking on /setup when not installing via script.
|
||||||
|
|
||||||
|
|
||||||
|
### New Features & Updates
|
||||||
|
- Clients: Net Terms: Added common 45 and 15 Days, removed 14 Days not as common.
|
||||||
|
- Clients: Bulk Action Set Net Terms Added.
|
||||||
|
- Clients: Swapped location and contact column, add PopOver with Details such as created, abbreviation, DB ID instead of taking up space underneath client, rounded tag pills and increased padding, removed info badges and added one info badge that displays a popover with details.
|
||||||
|
- Clients: Added New Ticket to Client Top Header Menu.
|
||||||
|
- Clients: Client Overview: UI Sprucing.
|
||||||
|
- Invoice: Send reminder 1 day after due date.
|
||||||
|
- Invoices/Quotes/Recurring Invoices: Split Items tables into their own POST logic and Modal UIs and tables (quote_items, invoice_items, recurring_items).
|
||||||
|
- Tickets: New Ticket Parsing - Anyone CC'ed onto the original email that created the ticket is added as a ticket watcher.
|
||||||
|
- Ticket/Quotes: Quotes can now be associated with a ticket.
|
||||||
|
- Networks: Removed Subnet Mask Field, Use CIDR instead.
|
||||||
|
- Networks: Rearranged fields, Updated placeholders, Add/Edit/list for better flow.
|
||||||
|
- Networks: Renamed DHCP to IP Range to allow for you use of both DHCP and or Usable IPs.
|
||||||
|
- Assets: Rearranged fields, Updated placeholders, Add/Edit/list for better flow.
|
||||||
|
- Assets: Added IPv6 if available under IP, Make and Model are now one line with Serial Underneath. Added OS under Type. use pill for status.
|
||||||
|
- Calendar: Event thats are cut off can now be viewed as a tooltip on hover.
|
||||||
|
- Calendar: Renamed System Calendars to built-in calendars and added the names and color dot for reference.
|
||||||
|
- Calendar: You can now delete a custom calendar.
|
||||||
|
- Report: Client Ticket Time Detail Audit: Selectable Billing Time Increment, will later be avauilable globally.
|
||||||
|
- Roles/Permissions: Now complete and is out of beta all permission roles are strictly enforced, except for in Trips and Calendar, new enforce modules will be added for these at a later date.
|
||||||
|
- Project Templates: Ticket Template order can now be dragged and dropped.
|
||||||
|
- Global: Introduced new checkbox class to all Checkbox select columns to keep consistency and reduce space and enhance ui.
|
||||||
|
- Global: CSRF Checks everywhere instead of just deletion calls.
|
||||||
|
- Global: Renamed the rest of the unarchive post and label calls to restore.
|
||||||
|
- Files: Allow upload of .unifi extension.
|
||||||
|
- Bump Libraries:
|
||||||
|
- stripe-php from 19.0.0 to 19.4.1.
|
||||||
|
- fullcalendar from 6.1.19 to 6.1.20
|
||||||
|
- TCPDF from 6.10.1 to 6.11.2
|
||||||
|
|
||||||
|
## [26.02.1] Maint Release
|
||||||
|
### Bug Fixes
|
||||||
|
- Credentials: Fix Password Generator.
|
||||||
|
- Calendar: Restrict Events for client restricted agents.
|
||||||
|
- Ticket Merge: Fix.
|
||||||
|
- Asset Transfer: Fix.
|
||||||
|
- Ticket Listing: Restrict Tickets presented in ticket list view from client restricted agents.
|
||||||
|
- Ticket Details: Deny access to client restricted agents to view tickets without client_id in uri.
|
||||||
|
- Tickets: Allow agents with restricted client access to view and edit tickets without a client.
|
||||||
|
- Ticket Change client: Limit selection for agents with restricted client access.
|
||||||
|
- Ticket Details: Don't display updated at when null.
|
||||||
|
|
||||||
|
### New Features & Updates
|
||||||
|
- Report: Added Client Detail Auditing.
|
||||||
|
- API: Added Endpoint to retrieve time worked by agent.
|
||||||
|
- ajax-modal: Revert to previous JS implementation before 26.02 release.
|
||||||
|
- Ticket: Move Subject from Ticket main ticket header to ticket details card header.
|
||||||
|
|
||||||
|
## [26.02] Stable Release
|
||||||
|
### Bug Fixes
|
||||||
|
- Mail Parser - Do not automatically send new ticket notifications to noreply/donotreply addresses.
|
||||||
|
- Ticket: removed newline \n on Parsed emails.
|
||||||
|
- Show Trips for everyone if accounting module is enabled.
|
||||||
|
- Fix Invoice Exporting.
|
||||||
|
- Fix Billable Column not sorting correctly in tickets.
|
||||||
|
- Fix Login flow where user agent and client user exists and agent has MFA but will not let them continue.
|
||||||
|
- Fix passing missing user_id var in client portal.
|
||||||
|
- Fix Ticket Templates not auto filling when selected.
|
||||||
|
- Fix Invoices not being sent to all billings contacts when manaully sent.
|
||||||
|
- Fix Documents and Files not able to be bulk deleted.
|
||||||
|
- Fix Role Archiving, can be archived as long as no users are assigned to the role.
|
||||||
|
- Fix showing Powered By ITFlow visibility on the login screen when Whitelabel is enabled.
|
||||||
|
- Missing username in audit log on successful login due to missing passed user_id to logging.
|
||||||
|
- API: Fix updating all documents instead of the intended document.
|
||||||
|
- Documents: Fix Document created at not showing the correct creation date of the master document.
|
||||||
|
- Ticket: Fixed Using edit ticket modal agent was not able to be set.
|
||||||
|
- Always check if a user is archived and or disabled instead of just during login.
|
||||||
|
- Report: Fix Collected tax report not totalling all tax categories.
|
||||||
|
|
||||||
|
### New Features & Updates
|
||||||
|
- Task Approval System for ticket tasks: Once an approval is requested, the task cannot be marked as complete until approved. Internal Approvals Any other technician, or Specific technician, Client Approvals Anyone (usually the requestor) Tech contacts Billing contacts.
|
||||||
|
- Printable Invoice Packing Slips now available.
|
||||||
|
- Drastic Performance Bump: Up to 50% faster queries accross the board and reduced server memory usage by 40% by switching Database Query method from mysqli_fetch_array to mysqli_fetch_assoc.
|
||||||
|
- Added Connect to Microsoft 365 Button to mail settings.
|
||||||
|
- OAUTH2 support for Microsoft 365 and Google Workspaces is now considered stable and working.
|
||||||
|
- Favorites: Assets and Credentials now can be favorited singly or by Bulk action. Favorited items appear in the client overview now.
|
||||||
|
- Files/Documents: Collapsable folders feature, collapsed by default with a button to expand all.
|
||||||
|
- URL Keys and such are now set to a more manageable 32 Characters by default.
|
||||||
|
- Various UI/UX Updates throughout the app, with focus oin ticket details, contact details modal etc.
|
||||||
|
- Added Show Archived files and documents to the files section.
|
||||||
|
- Added Bulk Archive and restore options to files and documents.
|
||||||
|
- Rewrite of the Kanban Ticket view to match our procedural style of coding.
|
||||||
|
- All options are available in TinyMCE now in Mobile mode.
|
||||||
|
- Agent names appear now in Invoice History section.
|
||||||
|
- Mail Parser: Support flowed text.
|
||||||
|
- Assets: Keep Purchase reference when copying.
|
||||||
|
- Assets: Add basic tracking history: Archiving, restoring, name changes, transferimg to new clients.
|
||||||
|
- Mail Parser: NDR Parsing.
|
||||||
|
- Allow SVG files in mail attachments.
|
||||||
|
- Tickets: Use a more friendly time worked instead of 02:41:00 translates to 2h 41m.
|
||||||
|
- Update wording on ticket to invoice item details.
|
||||||
|
- Merge Tickets: Now wth a ticket merge dropdown list of tickets instead of a text field.
|
||||||
|
- Role Permissions can now be set during role creation, update Permission UI to use radio buttons instead of select boxes.
|
||||||
|
- Bump TinyMCE 8.2.2 to 8.3.2.
|
||||||
|
- Bump PHPMailer from 7.0.1 to 7.0.2.
|
||||||
|
- Bump Datatables from 2.3.4 to 2.3.7.
|
||||||
|
|
||||||
## [25.12.1] Maint Release
|
## [25.12.1] Maint Release
|
||||||
|
|
||||||
### Major Changes
|
### Major Changes
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ We track the implementation of confirmed features and bugs via [TaskFlow](https:
|
|||||||
For help using ITFlow, bugs, feature requests, and general ideas / discussions please use the community [forum](https://forum.itflow.org).
|
For help using ITFlow, bugs, feature requests, and general ideas / discussions please use the community [forum](https://forum.itflow.org).
|
||||||
|
|
||||||
### Contributing
|
### Contributing
|
||||||
If you want to improve ITFlow, feel free to fork the repo and create a pull reques. Make sure to discuss significant changes or new features with fellow contributors on the forum first. This helps ensure that your contributions are aligned with project goals, and saves time for everyone. All contributions should follow our [code standards](https://docs.itflow.org/code_standards). See the [contributing guide](https://docs.itflow.org/contribute).
|
We have temporarily paused PRs from the community.
|
||||||
|
|
||||||
#### Contributors
|
#### Contributors
|
||||||
<a href="https://github.com/itflow-org/itflow/graphs/contributors">
|
<a href="https://github.com/itflow-org/itflow/graphs/contributors">
|
||||||
@@ -93,6 +93,7 @@ If you want to improve ITFlow, feel free to fork the repo and create a pull requ
|
|||||||
We’re incredibly grateful to the organizations and individuals who support the project - a big thank you to:
|
We’re incredibly grateful to the organizations and individuals who support the project - a big thank you to:
|
||||||
- CompuMatter
|
- CompuMatter
|
||||||
- F1 for HELP
|
- F1 for HELP
|
||||||
|
- digiBandit
|
||||||
- JetBrains (PhpStorm)
|
- JetBrains (PhpStorm)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ $num_rows = mysqli_num_rows($sql);
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$provider_id = intval($row['ai_provider_id']);
|
$provider_id = intval($row['ai_provider_id']);
|
||||||
$provider_name = nullable_htmlentities($row['ai_provider_name']);
|
$provider_name = nullable_htmlentities($row['ai_provider_name']);
|
||||||
$model_id = intval($row['ai_model_id']);
|
$model_id = intval($row['ai_model_id']);
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ $num_rows = mysqli_num_rows($sql);
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$provider_id = intval($row['ai_provider_id']);
|
$provider_id = intval($row['ai_provider_id']);
|
||||||
$provider_name = nullable_htmlentities($row['ai_provider_name']);
|
$provider_name = nullable_htmlentities($row['ai_provider_name']);
|
||||||
$url = nullable_htmlentities($row['ai_provider_api_url']);
|
$url = nullable_htmlentities($row['ai_provider_api_url']);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<button class="dropdown-item text-danger text-bold"
|
<button class="dropdown-item text-danger text-bold"
|
||||||
type="submit" form="bulkActions" name="bulk_delete_api_keys">
|
type="submit" form="bulkActions" name="bulk_delete_api_keys">
|
||||||
<i class="fas fa-fw fa-trash mr-2"></i>Revoke
|
<i class="fas fa-fw fa-trash mr-2"></i>Delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -105,7 +105,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$api_key_id = intval($row['api_key_id']);
|
$api_key_id = intval($row['api_key_id']);
|
||||||
$api_key_name = nullable_htmlentities($row['api_key_name']);
|
$api_key_name = nullable_htmlentities($row['api_key_name']);
|
||||||
$api_key_secret = nullable_htmlentities("************" . substr($row['api_key_secret'], -4));
|
$api_key_secret = nullable_htmlentities("************" . substr($row['api_key_secret'], -4));
|
||||||
@@ -139,9 +139,16 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<i class="fas fa-ellipsis-h"></i>
|
<i class="fas fa-ellipsis-h"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_api_key=<?php echo $api_key_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
<?php if ($api_key_expire > date("Y-m-d H:i:s")) { ?>
|
||||||
|
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?revoke_api_key=<?php echo $api_key_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
||||||
<i class="fas fa-fw fa-times mr-2"></i>Revoke
|
<i class="fas fa-fw fa-times mr-2"></i>Revoke
|
||||||
</a>
|
</a>
|
||||||
|
<?php } ?>
|
||||||
|
<?php if ($api_key_expire < date("Y-m-d H:i:s")) { ?>
|
||||||
|
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_api_key=<?php echo $api_key_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">
|
||||||
|
<i class="fas fa-fw fa-times mr-2"></i>Delete
|
||||||
|
</a>
|
||||||
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@@ -164,4 +171,3 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
require_once "../includes/footer.php";
|
require_once "../includes/footer.php";
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql_types_filter = mysqli_query($mysqli, "SELECT DISTINCT app_log_type FROM app_logs ORDER BY app_log_type ASC");
|
$sql_types_filter = mysqli_query($mysqli, "SELECT DISTINCT app_log_type FROM app_logs ORDER BY app_log_type ASC");
|
||||||
while ($row = mysqli_fetch_array($sql_types_filter)) {
|
while ($row = mysqli_fetch_assoc($sql_types_filter)) {
|
||||||
$log_type = nullable_htmlentities($row['app_log_type']);
|
$log_type = nullable_htmlentities($row['app_log_type']);
|
||||||
?>
|
?>
|
||||||
<option <?php if ($type_filter == $log_type) { echo "selected"; } ?>><?php echo $log_type; ?></option>
|
<option <?php if ($type_filter == $log_type) { echo "selected"; } ?>><?php echo $log_type; ?></option>
|
||||||
@@ -85,7 +85,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql_categories_filter = mysqli_query($mysqli, "SELECT DISTINCT app_log_category FROM app_logs ORDER BY app_log_category ASC");
|
$sql_categories_filter = mysqli_query($mysqli, "SELECT DISTINCT app_log_category FROM app_logs ORDER BY app_log_category ASC");
|
||||||
while ($row = mysqli_fetch_array($sql_categories_filter)) {
|
while ($row = mysqli_fetch_assoc($sql_categories_filter)) {
|
||||||
$log_category = nullable_htmlentities($row['app_log_category']);
|
$log_category = nullable_htmlentities($row['app_log_category']);
|
||||||
?>
|
?>
|
||||||
<option <?php if ($category_filter == $log_category) { echo "selected"; } ?>><?php echo $log_category; ?></option>
|
<option <?php if ($category_filter == $log_category) { echo "selected"; } ?>><?php echo $log_category; ?></option>
|
||||||
@@ -141,7 +141,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$log_id = intval($row['app_log_id']);
|
$log_id = intval($row['app_log_id']);
|
||||||
$log_type = nullable_htmlentities($row['app_log_type']);
|
$log_type = nullable_htmlentities($row['app_log_type']);
|
||||||
$log_category = nullable_htmlentities($row['app_log_category']);
|
$log_category = nullable_htmlentities($row['app_log_category']);
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql_clients_filter = mysqli_query($mysqli, "SELECT * FROM clients ORDER BY client_name ASC");
|
$sql_clients_filter = mysqli_query($mysqli, "SELECT * FROM clients ORDER BY client_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql_clients_filter)) {
|
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
|
||||||
$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']);
|
||||||
?>
|
?>
|
||||||
@@ -108,7 +108,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql_users_filter = mysqli_query($mysqli, "SELECT * FROM users ORDER BY user_name ASC");
|
$sql_users_filter = mysqli_query($mysqli, "SELECT * FROM users ORDER BY user_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql_users_filter)) {
|
while ($row = mysqli_fetch_assoc($sql_users_filter)) {
|
||||||
$user_id = intval($row['user_id']);
|
$user_id = intval($row['user_id']);
|
||||||
$user_name = nullable_htmlentities($row['user_name']);
|
$user_name = nullable_htmlentities($row['user_name']);
|
||||||
?>
|
?>
|
||||||
@@ -128,7 +128,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql_types_filter = mysqli_query($mysqli, "SELECT DISTINCT log_type FROM logs ORDER BY log_type ASC");
|
$sql_types_filter = mysqli_query($mysqli, "SELECT DISTINCT log_type FROM logs ORDER BY log_type ASC");
|
||||||
while ($row = mysqli_fetch_array($sql_types_filter)) {
|
while ($row = mysqli_fetch_assoc($sql_types_filter)) {
|
||||||
$log_type = nullable_htmlentities($row['log_type']);
|
$log_type = nullable_htmlentities($row['log_type']);
|
||||||
?>
|
?>
|
||||||
<option <?php if ($type_filter == $log_type) { echo "selected"; } ?>><?php echo $log_type; ?></option>
|
<option <?php if ($type_filter == $log_type) { echo "selected"; } ?>><?php echo $log_type; ?></option>
|
||||||
@@ -147,7 +147,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql_actions_filter = mysqli_query($mysqli, "SELECT DISTINCT log_action FROM logs ORDER BY log_action ASC");
|
$sql_actions_filter = mysqli_query($mysqli, "SELECT DISTINCT log_action FROM logs ORDER BY log_action ASC");
|
||||||
while ($row = mysqli_fetch_array($sql_actions_filter)) {
|
while ($row = mysqli_fetch_assoc($sql_actions_filter)) {
|
||||||
$log_action = nullable_htmlentities($row['log_action']);
|
$log_action = nullable_htmlentities($row['log_action']);
|
||||||
?>
|
?>
|
||||||
<option <?php if ($action_filter == $log_action) { echo "selected"; } ?>><?php echo $log_action; ?></option>
|
<option <?php if ($action_filter == $log_action) { echo "selected"; } ?>><?php echo $log_action; ?></option>
|
||||||
@@ -225,7 +225,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$log_id = intval($row['log_id']);
|
$log_id = intval($row['log_id']);
|
||||||
$log_type = nullable_htmlentities($row['log_type']);
|
$log_type = nullable_htmlentities($row['log_type']);
|
||||||
$log_action = nullable_htmlentities($row['log_action']);
|
$log_action = nullable_htmlentities($row['log_action']);
|
||||||
@@ -280,4 +280,3 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
require_once "../includes/footer.php";
|
require_once "../includes/footer.php";
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$category_id = intval($row['category_id']);
|
$category_id = intval($row['category_id']);
|
||||||
$category_name = nullable_htmlentities($row['category_name']);
|
$category_name = nullable_htmlentities($row['category_name']);
|
||||||
$category_color = nullable_htmlentities($row['category_color']);
|
$category_color = nullable_htmlentities($row['category_color']);
|
||||||
@@ -135,11 +135,11 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
if ($archived) {
|
if ($archived) {
|
||||||
?>
|
?>
|
||||||
<a class="dropdown-item text-success confirm-link"
|
<a class="dropdown-item text-success confirm-link"
|
||||||
href="post.php?unarchive_category=<?php echo $category_id; ?>">
|
href="post.php?restore_category=<?php echo $category_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<i class="fas fa-fw fa-archive mr-2"></i>Unarchive
|
<i class="fas fa-fw fa-archive mr-2"></i>Restore
|
||||||
</a>
|
</a>
|
||||||
<a class="dropdown-item text-danger confirm-link"
|
<a class="dropdown-item text-danger confirm-link"
|
||||||
href="post.php?delete_category=<?php echo $category_id; ?>">
|
href="post.php?delete_category=<?php echo $category_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<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
|
||||||
@@ -150,7 +150,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<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 text-danger confirm-link"
|
<a class="dropdown-item text-danger confirm-link"
|
||||||
href="post.php?archive_category=<?php echo $category_id; ?>">
|
href="post.php?archive_category=<?php echo $category_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<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
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$id = intval($row['contract_template_id']);
|
$id = intval($row['contract_template_id']);
|
||||||
$name = nullable_htmlentities($row['contract_template_name']);
|
$name = nullable_htmlentities($row['contract_template_name']);
|
||||||
$type = nullable_htmlentities($row['contract_template_type']);
|
$type = nullable_htmlentities($row['contract_template_type']);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$custom_link_id = intval($row['custom_link_id']);
|
$custom_link_id = intval($row['custom_link_id']);
|
||||||
$custom_link_name = nullable_htmlentities($row['custom_link_name']);
|
$custom_link_name = nullable_htmlentities($row['custom_link_name']);
|
||||||
$custom_link_uri = nullable_htmlentities($row['custom_link_uri']);
|
$custom_link_uri = nullable_htmlentities($row['custom_link_uri']);
|
||||||
@@ -123,7 +123,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<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 text-danger text-bold confirm-link" href="post.php?delete_custom_link=<?php echo $custom_link_id; ?>">
|
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_custom_link=<?php echo $custom_link_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<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>
|
||||||
|
|||||||
@@ -791,7 +791,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
|||||||
|
|
||||||
// Copy primary_location and primary_contact to their new vars in their own respecting tables
|
// Copy primary_location and primary_contact to their new vars in their own respecting tables
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM clients");
|
$sql = mysqli_query($mysqli, "SELECT * FROM clients");
|
||||||
while($row = mysqli_fetch_array($sql)) {
|
while($row = mysqli_fetch_assoc($sql)) {
|
||||||
$primary_contact = $row['primary_contact'];
|
$primary_contact = $row['primary_contact'];
|
||||||
$primary_location = $row['primary_location'];
|
$primary_location = $row['primary_location'];
|
||||||
|
|
||||||
@@ -1666,7 +1666,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
|||||||
if (CURRENT_DATABASE_VERSION == '1.3.9') {
|
if (CURRENT_DATABASE_VERSION == '1.3.9') {
|
||||||
// Migrate all Network Info from Assets to Interface Table and make it primary interface
|
// Migrate all Network Info from Assets to Interface Table and make it primary interface
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM assets");
|
$sql = mysqli_query($mysqli, "SELECT * FROM assets");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$asset_id = intval($row['asset_id']);
|
$asset_id = intval($row['asset_id']);
|
||||||
$mac = sanitizeInput($row['asset_mac']);
|
$mac = sanitizeInput($row['asset_mac']);
|
||||||
$ip = sanitizeInput($row['asset_ip']);
|
$ip = sanitizeInput($row['asset_ip']);
|
||||||
@@ -1945,7 +1945,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
|||||||
if (CURRENT_DATABASE_VERSION == '1.5.7') {
|
if (CURRENT_DATABASE_VERSION == '1.5.7') {
|
||||||
// Create Users for contacts that have logins enabled and that are not archived
|
// Create Users for contacts that have logins enabled and that are not archived
|
||||||
$contacts_sql = mysqli_query($mysqli, "SELECT * FROM `contacts` WHERE contact_archived_at IS NULL AND (contact_auth_method = 'local' OR contact_auth_method = 'azure')");
|
$contacts_sql = mysqli_query($mysqli, "SELECT * FROM `contacts` WHERE contact_archived_at IS NULL AND (contact_auth_method = 'local' OR contact_auth_method = 'azure')");
|
||||||
while($row = mysqli_fetch_array($contacts_sql)) {
|
while($row = mysqli_fetch_assoc($contacts_sql)) {
|
||||||
$contact_id = intval($row['contact_id']);
|
$contact_id = intval($row['contact_id']);
|
||||||
$contact_name = mysqli_real_escape_string($mysqli, $row['contact_name']);
|
$contact_name = mysqli_real_escape_string($mysqli, $row['contact_name']);
|
||||||
$contact_email = mysqli_real_escape_string($mysqli, $row['contact_email']);
|
$contact_email = mysqli_real_escape_string($mysqli, $row['contact_email']);
|
||||||
@@ -3853,7 +3853,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
|||||||
|
|
||||||
// Get Current Stripe Settings
|
// Get Current Stripe Settings
|
||||||
$sql_stripe_settings = mysqli_query($mysqli, "SELECT * FROM settings WHERE company_id = 1");
|
$sql_stripe_settings = mysqli_query($mysqli, "SELECT * FROM settings WHERE company_id = 1");
|
||||||
$row = mysqli_fetch_array($sql_stripe_settings);
|
$row = mysqli_fetch_assoc($sql_stripe_settings);
|
||||||
$config_stripe_enable = intval($row['config_stripe_enable']);
|
$config_stripe_enable = intval($row['config_stripe_enable']);
|
||||||
if ($config_stripe_enable === 1) {
|
if ($config_stripe_enable === 1) {
|
||||||
$config_stripe_publishable = mysqli_real_escape_string($mysqli, $row['config_stripe_publishable']);
|
$config_stripe_publishable = mysqli_real_escape_string($mysqli, $row['config_stripe_publishable']);
|
||||||
@@ -3879,7 +3879,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
|||||||
|
|
||||||
// Migrate Clients and Payment Method over
|
// Migrate Clients and Payment Method over
|
||||||
$sql_stripe_clients = mysqli_query($mysqli, "SELECT * FROM client_stripe WHERE stripe_pm IS NOT NULL AND stripe_pm != ''");
|
$sql_stripe_clients = mysqli_query($mysqli, "SELECT * FROM client_stripe WHERE stripe_pm IS NOT NULL AND stripe_pm != ''");
|
||||||
while ($row = mysqli_fetch_array($sql_stripe_clients)) {
|
while ($row = mysqli_fetch_assoc($sql_stripe_clients)) {
|
||||||
$client_id = intval($row['client_id']);
|
$client_id = intval($row['client_id']);
|
||||||
$stripe_id = mysqli_real_escape_string($mysqli, $row['stripe_id']);
|
$stripe_id = mysqli_real_escape_string($mysqli, $row['stripe_id']);
|
||||||
$stripe_pm = mysqli_real_escape_string($mysqli, $row['stripe_pm']);
|
$stripe_pm = mysqli_real_escape_string($mysqli, $row['stripe_pm']);
|
||||||
@@ -3932,7 +3932,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
|||||||
// Migrate Payment Methods from Categories Table to new payment_methods table
|
// Migrate Payment Methods from Categories Table to new payment_methods table
|
||||||
$sql_categories = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' AND category_name != 'Stripe' AND category_archived_at IS NULL");
|
$sql_categories = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' AND category_name != 'Stripe' AND category_archived_at IS NULL");
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql_categories)) {
|
while ($row = mysqli_fetch_assoc($sql_categories)) {
|
||||||
$category_name = sanitizeInput($row['category_name']);
|
$category_name = sanitizeInput($row['category_name']);
|
||||||
|
|
||||||
mysqli_query($mysqli,"INSERT INTO payment_methods SET payment_method_name = '$category_name'");
|
mysqli_query($mysqli,"INSERT INTO payment_methods SET payment_method_name = '$category_name'");
|
||||||
@@ -4154,10 +4154,191 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
|
|||||||
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.9'");
|
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.3.9'");
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (CURRENT_DATABASE_VERSION == '2.3.9') {
|
if (CURRENT_DATABASE_VERSION == '2.3.9') {
|
||||||
// // Insert queries here required to update to DB version 2.4.0
|
mysqli_query($mysqli, "ALTER TABLE `clients` ADD `client_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `client_notes`");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `locations` ADD `location_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `location_notes`");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `vendors` ADD `vendor_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `vendor_notes`");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `software` ADD `software_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `software_notes`");
|
||||||
|
|
||||||
|
mysqli_query(
|
||||||
|
$mysqli,
|
||||||
|
"ALTER TABLE `credentials`
|
||||||
|
CHANGE `credential_important` `credential_favorite`
|
||||||
|
TINYINT(1) NOT NULL DEFAULT 0
|
||||||
|
AFTER `credential_note`"
|
||||||
|
);
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `assets` DROP `asset_important`");
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `assets` ADD `asset_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `asset_notes`");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `documents` DROP `document_important`");
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `documents` ADD `document_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `document_client_visible`");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `racks` ADD `rack_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `rack_notes`");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `files` DROP `file_important`");
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `files` ADD `file_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `file_mime_type`");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `networks` ADD `network_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `network_notes`");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `domains` ADD `domain_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `domain_notes`");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `certificates` ADD `certificate_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `certificate_notes`");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "ALTER TABLE `services` ADD `service_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `service_notes`");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.4.0'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CURRENT_DATABASE_VERSION == '2.4.0') {
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "
|
||||||
|
CREATE TABLE `quote_items` (
|
||||||
|
`item_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`item_name` varchar(200) NOT NULL,
|
||||||
|
`item_description` text DEFAULT NULL,
|
||||||
|
`item_quantity` decimal(15,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`item_price` decimal(15,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`item_subtotal` decimal(15,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`item_tax` decimal(15,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`item_total` decimal(15,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`item_order` int(11) NOT NULL DEFAULT 0,
|
||||||
|
`item_created_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`item_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
|
||||||
|
`item_archived_at` datetime DEFAULT NULL,
|
||||||
|
`item_tax_id` int(11) NOT NULL DEFAULT 0,
|
||||||
|
`item_product_id` int(11) NOT NULL DEFAULT 0,
|
||||||
|
`item_quote_id` int(11) NOT NULL,
|
||||||
|
PRIMARY KEY (`item_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "
|
||||||
|
CREATE TABLE `recurring_invoice_items` (
|
||||||
|
`item_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`item_name` varchar(200) NOT NULL,
|
||||||
|
`item_description` text DEFAULT NULL,
|
||||||
|
`item_quantity` decimal(15,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`item_price` decimal(15,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`item_subtotal` decimal(15,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`item_tax` decimal(15,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`item_total` decimal(15,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`item_order` int(11) NOT NULL DEFAULT 0,
|
||||||
|
`item_created_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`item_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
|
||||||
|
`item_archived_at` datetime DEFAULT NULL,
|
||||||
|
`item_tax_id` int(11) NOT NULL DEFAULT 0,
|
||||||
|
`item_product_id` int(11) NOT NULL DEFAULT 0,
|
||||||
|
`item_recurring_invoice_id` int(11) NOT NULL,
|
||||||
|
PRIMARY KEY (`item_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.4.1'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CURRENT_DATABASE_VERSION == '2.4.1') {
|
||||||
|
|
||||||
|
// Migrate Items
|
||||||
|
mysqli_query($mysqli, "
|
||||||
|
INSERT INTO `recurring_invoice_items` (
|
||||||
|
`item_name`,
|
||||||
|
`item_description`,
|
||||||
|
`item_quantity`,
|
||||||
|
`item_price`,
|
||||||
|
`item_subtotal`,
|
||||||
|
`item_tax`,
|
||||||
|
`item_total`,
|
||||||
|
`item_order`,
|
||||||
|
`item_created_at`,
|
||||||
|
`item_updated_at`,
|
||||||
|
`item_archived_at`,
|
||||||
|
`item_tax_id`,
|
||||||
|
`item_product_id`,
|
||||||
|
`item_recurring_invoice_id`
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
`item_name`,
|
||||||
|
`item_description`,
|
||||||
|
`item_quantity`,
|
||||||
|
`item_price`,
|
||||||
|
`item_subtotal`,
|
||||||
|
`item_tax`,
|
||||||
|
`item_total`,
|
||||||
|
`item_order`,
|
||||||
|
`item_created_at`,
|
||||||
|
`item_updated_at`,
|
||||||
|
`item_archived_at`,
|
||||||
|
`item_tax_id`,
|
||||||
|
`item_product_id`,
|
||||||
|
`item_recurring_invoice_id`
|
||||||
|
FROM `invoice_items`
|
||||||
|
WHERE `item_recurring_invoice_id` != 0
|
||||||
|
");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "
|
||||||
|
INSERT INTO `quote_items` (
|
||||||
|
`item_name`,
|
||||||
|
`item_description`,
|
||||||
|
`item_quantity`,
|
||||||
|
`item_price`,
|
||||||
|
`item_subtotal`,
|
||||||
|
`item_tax`,
|
||||||
|
`item_total`,
|
||||||
|
`item_order`,
|
||||||
|
`item_created_at`,
|
||||||
|
`item_updated_at`,
|
||||||
|
`item_archived_at`,
|
||||||
|
`item_tax_id`,
|
||||||
|
`item_product_id`,
|
||||||
|
`item_quote_id`
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
`item_name`,
|
||||||
|
`item_description`,
|
||||||
|
`item_quantity`,
|
||||||
|
`item_price`,
|
||||||
|
`item_subtotal`,
|
||||||
|
`item_tax`,
|
||||||
|
`item_total`,
|
||||||
|
`item_order`,
|
||||||
|
`item_created_at`,
|
||||||
|
`item_updated_at`,
|
||||||
|
`item_archived_at`,
|
||||||
|
`item_tax_id`,
|
||||||
|
`item_product_id`,
|
||||||
|
`item_quote_id`
|
||||||
|
FROM `invoice_items`
|
||||||
|
WHERE `item_quote_id` != 0
|
||||||
|
");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "
|
||||||
|
DELETE FROM `invoice_items`
|
||||||
|
WHERE `item_recurring_invoice_id` != 0
|
||||||
|
");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "
|
||||||
|
DELETE FROM `invoice_items`
|
||||||
|
WHERE `item_quote_id` != 0
|
||||||
|
");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "
|
||||||
|
ALTER TABLE `invoice_items`
|
||||||
|
DROP COLUMN `item_quote_id`,
|
||||||
|
DROP COLUMN `item_recurring_invoice_id`
|
||||||
|
");
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.4.2'");
|
||||||
|
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// // if (CURRENT_DATABASE_VERSION == '2.4.2') {
|
||||||
|
// // Insert queries here required to update to DB version 2.4.3
|
||||||
// // 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` = '2.4.0'");
|
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.4.3'");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<div class="card card-dark">
|
<div class="card card-dark">
|
||||||
<div class="card-header py-2">
|
<div class="card-header py-2">
|
||||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file mr-2"></i>Document Templates</h3>
|
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file-alt mr-2"></i>Document Templates</h3>
|
||||||
<div class="card-tools">
|
<div class="card-tools">
|
||||||
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/document_template/document_template_add.php" data-modal-size="xl">
|
<button type="button" class="btn btn-primary ajax-modal" data-modal-url="modals/document_template/document_template_add.php" data-modal-size="xl">
|
||||||
<i class="fas fa-plus mr-2"></i>New Template
|
<i class="fas fa-plus mr-2"></i>New Template
|
||||||
@@ -66,21 +66,30 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$document_template_id = intval($row['document_template_id']);
|
$document_template_id = intval($row['document_template_id']);
|
||||||
$document_template_name = nullable_htmlentities($row['document_template_name']);
|
$document_template_name = nullable_htmlentities($row['document_template_name']);
|
||||||
$document_template_description = nullable_htmlentities($row['document_template_description']);
|
$document_template_description = nullable_htmlentities($row['document_template_description']);
|
||||||
$document_template_content = nullable_htmlentities($row['document_template_content']);
|
$document_template_content = nullable_htmlentities($row['document_template_content']);
|
||||||
$document_template_created_by_name = nullable_htmlentities($row['user_name']);
|
$document_template_created_by_name = nullable_htmlentities($row['user_name']);
|
||||||
$document_template_created_at = nullable_htmlentities($row['document_template_created_at']);
|
$document_template_created_at = nullable_htmlentities($row['document_template_created_at']);
|
||||||
$document_template_updated_at = nullable_htmlentities($row['document_template_updated_at']);
|
$document_template_updated_at = nullable_htmlentities(getFallback($row['document_template_updated_at']));
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a class="text-bold" href="document_template_details.php?document_template_id=<?php echo $document_template_id; ?>"><i class="fas fa-fw fa-file-alt text-dark"></i> <?php echo $document_template_name; ?></a>
|
<a class="text-dark ajax-modal" href="#"
|
||||||
<div class="mt-1 text-secondary"><?php echo $document_template_description; ?></div>
|
data-modal-size="xl"
|
||||||
|
data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>">
|
||||||
|
<div class="media">
|
||||||
|
<i class="fas fa-fw fa-2x fa-file-alt mr-2"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<div><?= $document_template_name ?></div>
|
||||||
|
<div><small class="text-secondary"><?= $document_template_description ?></small></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<?php echo $document_template_created_at; ?>
|
<?php echo $document_template_created_at; ?>
|
||||||
@@ -93,13 +102,17 @@
|
|||||||
<i class="fas fa-ellipsis-h"></i>
|
<i class="fas fa-ellipsis-h"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
|
<a class="dropdown-item" href="document_template_details.php?document_template_id=<?= $document_template_id ?>">
|
||||||
|
<i class="fas fa-fw fa-eye mr-2"></i>View
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
<a class="dropdown-item ajax-modal" href="#"
|
<a class="dropdown-item ajax-modal" href="#"
|
||||||
data-modal-size="xl"
|
data-modal-size="xl"
|
||||||
data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>">
|
data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_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 text-danger text-bold" href="post.php?delete_document_template=<?php echo $document_template_id; ?>">
|
<a class="dropdown-item text-danger text-bold" href="post.php?delete_document_template=<?php echo $document_template_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<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>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ if (mysqli_num_rows($sql_document) == 0) {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql_document);
|
$row = mysqli_fetch_assoc($sql_document);
|
||||||
|
|
||||||
$document_template_name = nullable_htmlentities($row['document_template_name']);
|
$document_template_name = nullable_htmlentities($row['document_template_name']);
|
||||||
$document_template_description = nullable_htmlentities($row['document_template_description']);
|
$document_template_description = nullable_htmlentities($row['document_template_description']);
|
||||||
@@ -43,19 +43,19 @@ $document_template_updated_at = nullable_htmlentities($row['document_template_up
|
|||||||
<li class="breadcrumb-item">
|
<li class="breadcrumb-item">
|
||||||
<a href="document_template.php">Document Templates</a>
|
<a href="document_template.php">Document Templates</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="breadcrumb-item active"><i class="fas fa-file mr-2"></i><?php echo $document_template_name; ?></li>
|
<li class="breadcrumb-item active"><i class="fas fa-file-alt mr-2"></i><?php echo $document_template_name; ?></li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div class="card card-dark">
|
<div class="card card-dark">
|
||||||
<div class="card-header py-2">
|
<div class="card-header">
|
||||||
|
|
||||||
<h3 class="card-title mt-2"><i class="fa fa-fw fa-file mr-2"></i><?php echo $document_template_name; ?></h3>
|
<h3 class="card-title mt-1"><i class="fa fa-fw fa-file-alt mr-2"></i><?php echo $document_template_name; ?></h3>
|
||||||
|
|
||||||
<div class="card-tools">
|
<div class="card-tools">
|
||||||
<button type="button" class="btn btn-primary ajax-modal"
|
<button type="button" class="btn btn-tool ajax-modal"
|
||||||
data-modal-size="xl"
|
data-modal-size="xl"
|
||||||
data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>">
|
data-modal-url="modals/document_template/document_template_edit.php?id=<?= $document_template_id ?>">
|
||||||
<i class="fas fa-edit mr-2"></i>Edit
|
<i class="fas fa-edit mr-2"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -139,7 +139,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="/admin/document_template.php" class="nav-link <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['document_template.php', 'document_template_details.php']) ? 'active' : ''); ?>">
|
<a href="/admin/document_template.php" class="nav-link <?php echo (in_array(basename($_SERVER['PHP_SELF']), ['document_template.php', 'document_template_details.php']) ? 'active' : ''); ?>">
|
||||||
<i class="nav-icon fas fa-file"></i>
|
<i class="nav-icon fas fa-file-alt"></i>
|
||||||
<p>Document Templates</p>
|
<p>Document Templates</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -293,7 +293,7 @@
|
|||||||
ORDER BY custom_link_order ASC, custom_link_name ASC"
|
ORDER BY custom_link_order ASC, custom_link_name ASC"
|
||||||
);
|
);
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql_custom_links)) {
|
while ($row = mysqli_fetch_assoc($sql_custom_links)) {
|
||||||
$custom_link_name = nullable_htmlentities($row['custom_link_name']);
|
$custom_link_name = nullable_htmlentities($row['custom_link_name']);
|
||||||
$custom_link_uri = sanitize_url($row['custom_link_uri']);
|
$custom_link_uri = sanitize_url($row['custom_link_uri']);
|
||||||
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']);
|
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']);
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$email_id = intval($row['email_id']);
|
$email_id = intval($row['email_id']);
|
||||||
$email_from = nullable_htmlentities($row['email_from']);
|
$email_from = nullable_htmlentities($row['email_from']);
|
||||||
$email_from_name = nullable_htmlentities($row['email_from_name']);
|
$email_from_name = nullable_htmlentities($row['email_from_name']);
|
||||||
@@ -163,12 +163,12 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
|
|
||||||
<!-- Show force resend if all retries have failed -->
|
<!-- Show force resend if all retries have failed -->
|
||||||
<?php if ($email_status == 2 && $email_attempts > 3) { ?>
|
<?php if ($email_status == 2 && $email_attempts > 3) { ?>
|
||||||
<a class="btn btn-sm btn-success" href="post.php?send_failed_mail=<?php echo $email_id; ?>"><i class="fas fa-fw fa-paper-plane"></i></a>
|
<a class="btn btn-sm btn-success" href="post.php?send_failed_mail=<?php echo $email_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"><i class="fas fa-fw fa-paper-plane"></i></a>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
<!-- Allow cancelling a message if it hasn't yet been picked up (e.g. stuck/bugged) -->
|
<!-- Allow cancelling a message if it hasn't yet been picked up (e.g. stuck/bugged) -->
|
||||||
<?php if ($email_status !== 3) { ?>
|
<?php if ($email_status !== 3) { ?>
|
||||||
<a class="btn btn-sm btn-danger confirm-link" href="post.php?cancel_mail=<?php echo $email_id; ?>"><i class="fas fa-fw fa-trash"></i></a>
|
<a class="btn btn-sm btn-danger confirm-link" href="post.php?cancel_mail=<?php echo $email_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"><i class="fas fa-fw fa-trash"></i></a>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ ob_start();
|
|||||||
<option value="">- Select an AI Provider -</option>
|
<option value="">- Select an AI Provider -</option>
|
||||||
<?php
|
<?php
|
||||||
$sql_ai_providers = mysqli_query($mysqli, "SELECT * FROM ai_providers");
|
$sql_ai_providers = mysqli_query($mysqli, "SELECT * FROM ai_providers");
|
||||||
while ($row = mysqli_fetch_array($sql_ai_providers)) {
|
while ($row = mysqli_fetch_assoc($sql_ai_providers)) {
|
||||||
$ai_provider_id = intval($row['ai_provider_id']);
|
$ai_provider_id = intval($row['ai_provider_id']);
|
||||||
$ai_provider_name = nullable_htmlentities($row['ai_provider_name']);
|
$ai_provider_name = nullable_htmlentities($row['ai_provider_name']);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $model_id = intval($_GET['id']);
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models WHERE ai_model_id = $model_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models WHERE ai_model_id = $model_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$ai_model_ai_provider_id = intval($row['ai_model_ai_provider_id']);
|
$ai_model_ai_provider_id = intval($row['ai_model_ai_provider_id']);
|
||||||
$model_id = intval($row['ai_model_id']);
|
$model_id = intval($row['ai_model_id']);
|
||||||
$model_name = nullable_htmlentities($row['ai_model_name']);
|
$model_name = nullable_htmlentities($row['ai_model_name']);
|
||||||
@@ -39,7 +39,7 @@ ob_start();
|
|||||||
<option value="">- Select an AI Provider -</option>
|
<option value="">- Select an AI Provider -</option>
|
||||||
<?php
|
<?php
|
||||||
$sql_ai_providers = mysqli_query($mysqli, "SELECT * FROM ai_providers");
|
$sql_ai_providers = mysqli_query($mysqli, "SELECT * FROM ai_providers");
|
||||||
while ($row = mysqli_fetch_array($sql_ai_providers)) {
|
while ($row = mysqli_fetch_assoc($sql_ai_providers)) {
|
||||||
$ai_provider_id = intval($row['ai_provider_id']);
|
$ai_provider_id = intval($row['ai_provider_id']);
|
||||||
$ai_provider_name = nullable_htmlentities($row['ai_provider_name']);
|
$ai_provider_name = nullable_htmlentities($row['ai_provider_name']);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $provider_id = intval($_GET['id']);
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_providers WHERE ai_provider_id = $provider_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM ai_providers WHERE ai_provider_id = $provider_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$provider_name = nullable_htmlentities($row['ai_provider_name']);
|
$provider_name = nullable_htmlentities($row['ai_provider_name']);
|
||||||
$url = nullable_htmlentities($row['ai_provider_api_url']);
|
$url = nullable_htmlentities($row['ai_provider_api_url']);
|
||||||
$key = nullable_htmlentities($row['ai_provider_api_key']);
|
$key = nullable_htmlentities($row['ai_provider_api_key']);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ ob_start();
|
|||||||
<option value="0"> ALL CLIENTS </option>
|
<option value="0"> ALL CLIENTS </option>
|
||||||
<?php
|
<?php
|
||||||
$sql = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($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']); ?>
|
||||||
<option value="<?php echo $client_id; ?>"><?php echo "$client_name (Client ID: $client_id)"; ?></option>
|
<option value="<?php echo $client_id; ?>"><?php echo "$client_name (Client ID: $client_id)"; ?></option>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $category_id = intval($_GET['id']);
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_id = $category_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_id = $category_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$category_name = nullable_htmlentities($row['category_name']);
|
$category_name = nullable_htmlentities($row['category_name']);
|
||||||
$category_color = nullable_htmlentities($row['category_color']);
|
$category_color = nullable_htmlentities($row['category_color']);
|
||||||
$category_type = nullable_htmlentities($row['category_type']);
|
$category_type = nullable_htmlentities($row['category_type']);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ $update_frequency_array = ['Manual', 'Annually', '2 Year', '3 Year', '5 Year', '
|
|||||||
|
|
||||||
// Fetch existing template
|
// Fetch existing template
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM contract_templates WHERE contract_template_id = $contract_template_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM contract_templates WHERE contract_template_id = $contract_template_id LIMIT 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
|
|
||||||
// Assign locals
|
// Assign locals
|
||||||
$name = nullable_htmlentities($row['contract_template_name']);
|
$name = nullable_htmlentities($row['contract_template_name']);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
|
|||||||
$custom_link_id = intval($_GET['id']);
|
$custom_link_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM custom_links WHERE custom_link_id = $custom_link_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM custom_links WHERE custom_link_id = $custom_link_id LIMIT 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$custom_link_name = nullable_htmlentities($row['custom_link_name']);
|
$custom_link_name = nullable_htmlentities($row['custom_link_name']);
|
||||||
$custom_link_uri = nullable_htmlentities($row['custom_link_uri']);
|
$custom_link_uri = nullable_htmlentities($row['custom_link_uri']);
|
||||||
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']);
|
$custom_link_icon = nullable_htmlentities($row['custom_link_icon']);
|
||||||
@@ -24,7 +24,7 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="custom_link_id" value="<?php echo $custom_link_id; ?>">
|
<input type="hidden" name="custom_link_id" value="<?php echo $custom_link_id; ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -44,7 +46,7 @@ ob_start();
|
|||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
|
||||||
<button type="submit" name="add_document_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Create</button>
|
<button type="submit" name="add_document_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save template</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>
|
||||||
|
|||||||
@@ -5,12 +5,11 @@ require_once '../../../includes/modal_header.php';
|
|||||||
$document_template_id = intval($_GET['id']);
|
$document_template_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM document_templates WHERE document_template_id = $document_template_id LIMIT 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$document_template_name = nullable_htmlentities($row['document_template_name']);
|
$document_template_name = nullable_htmlentities($row['document_template_name']);
|
||||||
$document_template_description = nullable_htmlentities($row['document_template_description']);
|
$document_template_description = nullable_htmlentities($row['document_template_description']);
|
||||||
$document_template_content = nullable_htmlentities($row['document_template_content']);
|
$document_template_content = nullable_htmlentities($row['document_template_content']);
|
||||||
|
|
||||||
// Generate the HTML form content using output buffering.
|
|
||||||
ob_start();
|
ob_start();
|
||||||
?>
|
?>
|
||||||
|
|
||||||
@@ -21,7 +20,9 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="document_template_id" value="<?php echo $document_template_id; ?>">
|
<input type="hidden" name="document_template_id" value="<?php echo $document_template_id; ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -38,7 +39,7 @@ ob_start();
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="submit" name="edit_document_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save</button>
|
<button type="submit" name="edit_document_template" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Save template</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>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ $purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'htt
|
|||||||
$purifier = new HTMLPurifier($purifier_config);
|
$purifier = new HTMLPurifier($purifier_config);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM email_queue WHERE email_id = $email_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM email_queue WHERE email_id = $email_id LIMIT 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
|
|
||||||
$email_from = nullable_htmlentities($row['email_from']);
|
$email_from = nullable_htmlentities($row['email_from']);
|
||||||
$email_from_name = nullable_htmlentities($row['email_from_name']);
|
$email_from_name = nullable_htmlentities($row['email_from_name']);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $payment_method_id = intval($_GET['id']);
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM payment_methods WHERE payment_method_id = $payment_method_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM payment_methods WHERE payment_method_id = $payment_method_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$payment_method_id = intval($row['payment_method_id']);
|
$payment_method_id = intval($row['payment_method_id']);
|
||||||
$payment_method_name = nullable_htmlentities($row['payment_method_name']);
|
$payment_method_name = nullable_htmlentities($row['payment_method_name']);
|
||||||
$payment_method_description = nullable_htmlentities($row['payment_method_description']);
|
$payment_method_description = nullable_htmlentities($row['payment_method_description']);
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ ob_start();
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$account_id = intval($row['account_id']);
|
$account_id = intval($row['account_id']);
|
||||||
$account_name = nullable_htmlentities($row['account_name']);
|
$account_name = nullable_htmlentities($row['account_name']);
|
||||||
?>
|
?>
|
||||||
@@ -125,7 +125,7 @@ ob_start();
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$vendor_id = intval($row['vendor_id']);
|
$vendor_id = intval($row['vendor_id']);
|
||||||
$vendor_name = nullable_htmlentities($row['vendor_name']);
|
$vendor_name = nullable_htmlentities($row['vendor_name']);
|
||||||
?>
|
?>
|
||||||
@@ -149,7 +149,7 @@ ob_start();
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' AND category_archived_at IS NULL ORDER BY category_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' AND category_archived_at IS NULL ORDER BY category_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$category_id = intval($row['category_id']);
|
$category_id = intval($row['category_id']);
|
||||||
$category_name = nullable_htmlentities($row['category_name']);
|
$category_name = nullable_htmlentities($row['category_name']);
|
||||||
?>
|
?>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $provider_id = intval($_GET['id']);
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM payment_providers WHERE payment_provider_id = $provider_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM payment_providers WHERE payment_provider_id = $provider_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$provider_name = nullable_htmlentities($row['payment_provider_name']);
|
$provider_name = nullable_htmlentities($row['payment_provider_name']);
|
||||||
$public_key = nullable_htmlentities($row['payment_provider_public_key']);
|
$public_key = nullable_htmlentities($row['payment_provider_public_key']);
|
||||||
$private_key = nullable_htmlentities($row['payment_provider_private_key']);
|
$private_key = nullable_htmlentities($row['payment_provider_private_key']);
|
||||||
@@ -78,7 +78,7 @@ ob_start();
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT account_id, account_name FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$account_id_select = intval($row['account_id']);
|
$account_id_select = intval($row['account_id']);
|
||||||
$account_name = nullable_htmlentities($row['account_name']);
|
$account_name = nullable_htmlentities($row['account_name']);
|
||||||
?>
|
?>
|
||||||
@@ -117,7 +117,7 @@ ob_start();
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT vendor_id, vendor_name FROM vendors WHERE vendor_client_id = 0 AND vendor_archived_at IS NULL ORDER BY vendor_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$vendor_id_select = intval($row['vendor_id']);
|
$vendor_id_select = intval($row['vendor_id']);
|
||||||
$vendor_name = nullable_htmlentities($row['vendor_name']);
|
$vendor_name = nullable_htmlentities($row['vendor_name']);
|
||||||
?>
|
?>
|
||||||
@@ -143,7 +143,7 @@ ob_start();
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql_category = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' AND category_archived_at IS NULL ORDER BY category_name ASC");
|
$sql_category = mysqli_query($mysqli, "SELECT category_id, category_name FROM categories WHERE category_type = 'Expense' AND category_archived_at IS NULL ORDER BY category_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql_category)) {
|
while ($row = mysqli_fetch_assoc($sql_category)) {
|
||||||
$category_id_select = intval($row['category_id']);
|
$category_id_select = intval($row['category_id']);
|
||||||
$category_name = nullable_htmlentities($row['category_name']);
|
$category_name = nullable_htmlentities($row['category_name']);
|
||||||
?>
|
?>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
|
|||||||
$project_template_id = intval($_GET['project_template_id']);
|
$project_template_id = intval($_GET['project_template_id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_id = $project_template_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_id = $project_template_id LIMIT 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$project_template_name = nullable_htmlentities($row['project_template_name']);
|
$project_template_name = nullable_htmlentities($row['project_template_name']);
|
||||||
$project_template_description = nullable_htmlentities($row['project_template_description']);
|
$project_template_description = nullable_htmlentities($row['project_template_description']);
|
||||||
|
|
||||||
@@ -20,6 +20,7 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="project_template_id" value="<?php echo $project_template_id; ?>">
|
<input type="hidden" name="project_template_id" value="<?php echo $project_template_id; ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="project_template_id" value="<?php echo $project_template_id; ?>">
|
<input type="hidden" name="project_template_id" value="<?php echo $project_template_id; ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -36,7 +38,7 @@ ob_start();
|
|||||||
AND ticket_template_archived_at IS NULL
|
AND ticket_template_archived_at IS NULL
|
||||||
ORDER BY ticket_template_name ASC"
|
ORDER BY ticket_template_name ASC"
|
||||||
);
|
);
|
||||||
while ($row = mysqli_fetch_array($sql_ticket_templates_select)) {
|
while ($row = mysqli_fetch_assoc($sql_ticket_templates_select)) {
|
||||||
$ticket_template_id_select = intval($row['ticket_template_id']);
|
$ticket_template_id_select = intval($row['ticket_template_id']);
|
||||||
$ticket_template_name_select = nullable_htmlentities($row['ticket_template_name']);
|
$ticket_template_name_select = nullable_htmlentities($row['ticket_template_name']);
|
||||||
?>
|
?>
|
||||||
|
|||||||
@@ -11,11 +11,28 @@ ob_start();
|
|||||||
<span>×</span>
|
<span>×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
<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="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<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-role-details">Details</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" data-toggle="pill" href="#pills-role-permissions">Permissions</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
|
|
||||||
|
<!-- DETAILS TAB -->
|
||||||
|
<div class="tab-pane fade show active" id="pills-role-details">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Name <strong class="text-danger">*</strong></label>
|
<label>Name <strong class="text-danger">*</strong></label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
@@ -38,25 +55,159 @@ ob_start();
|
|||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Admin Access <strong class="text-danger">*</strong></label>
|
<label>Admin Access <strong class="text-danger">*</strong></label>
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
<div class="custom-control custom-radio mb-2">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-tools"></i></span>
|
<input type="radio" class="custom-control-input" id="admin_no" name="role_is_admin" value="0" checked required>
|
||||||
</div>
|
<label class="custom-control-label" for="admin_no">
|
||||||
<select class="form-control select2" name="role_is_admin" required>
|
No - use permissions on the next tab
|
||||||
<option value="0">No - edit after creation to set permissions</option>
|
</label>
|
||||||
<option value="1">Yes - this role should have full admin access</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="custom-control custom-radio">
|
||||||
|
<input type="radio" class="custom-control-input" id="admin_yes" name="role_is_admin" value="1" required>
|
||||||
|
<label class="custom-control-label" for="admin_yes">
|
||||||
|
Yes - this role should have full admin access
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- PERMISSIONS TAB -->
|
||||||
|
<div class="tab-pane fade" id="pills-role-permissions">
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Enumerate modules
|
||||||
|
$sql_modules = mysqli_query($mysqli, "SELECT * FROM modules");
|
||||||
|
while ($row_modules = mysqli_fetch_assoc($sql_modules)) {
|
||||||
|
|
||||||
|
$module_id = intval($row_modules['module_id']);
|
||||||
|
|
||||||
|
// raw for name, escaped for display
|
||||||
|
$module_name_raw = $row_modules['module_name'];
|
||||||
|
$module_name_display = ucfirst(str_replace("module_", "", $module_name_raw));
|
||||||
|
|
||||||
|
$module_name_display_safe = nullable_htmlentities($module_name_display);
|
||||||
|
$module_description = nullable_htmlentities($row_modules['module_description']);
|
||||||
|
|
||||||
|
// default for new role
|
||||||
|
$module_permission = 0;
|
||||||
|
|
||||||
|
$field_name = $module_id . "##" . $module_name_raw;
|
||||||
|
$group_id = "perm_group_$module_id";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label><?= $module_name_display_safe ?> <strong class="text-danger">*</strong></label>
|
||||||
|
|
||||||
|
<div class="btn-group btn-group-toggle btn-block" data-toggle="buttons" role="group"
|
||||||
|
aria-label="Permissions for <?= $module_name_display_safe ?>">
|
||||||
|
|
||||||
|
<label class="btn btn-outline-secondary btn-sm active" title="No Access">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="<?= $field_name ?>"
|
||||||
|
id="<?= $group_id ?>_0"
|
||||||
|
value="0"
|
||||||
|
autocomplete="off"
|
||||||
|
checked
|
||||||
|
required
|
||||||
|
>
|
||||||
|
None
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="btn btn-outline-primary btn-sm" title="Viewing Only">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="<?= $field_name ?>"
|
||||||
|
id="<?= $group_id ?>_1"
|
||||||
|
value="1"
|
||||||
|
autocomplete="off"
|
||||||
|
>
|
||||||
|
<i class="fas fa-fw fa-eye mr-1"></i>Read
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="btn btn-outline-warning btn-sm" title="Read, Edit, Archive">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="<?= $field_name ?>"
|
||||||
|
id="<?= $group_id ?>_2"
|
||||||
|
value="2"
|
||||||
|
autocomplete="off"
|
||||||
|
>
|
||||||
|
<i class="fas fa-fw fa-edit mr-1"></i>Modify
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="btn btn-outline-danger btn-sm" title="Read, Edit, Archive, Delete">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="<?= $field_name ?>"
|
||||||
|
id="<?= $group_id ?>_3"
|
||||||
|
value="3"
|
||||||
|
autocomplete="off"
|
||||||
|
>
|
||||||
|
<i class="fas fa-fw fa-trash mr-1"></i>Full
|
||||||
|
</label>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<small class="form-text text-muted mt-2"><?= $module_description ?></small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php } // end while ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="submit" name="add_role" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
<button type="submit" name="add_role" class="btn btn-primary text-bold">
|
||||||
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fas fa-times mr-2"></i>Cancel</button>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Optional: when Admin Yes is selected, disable permission radios + switch to Details tab
|
||||||
|
(function () {
|
||||||
|
function setPermissionsEnabled(enabled) {
|
||||||
|
const permsTab = document.getElementById('pills-role-permissions');
|
||||||
|
if (!permsTab) return;
|
||||||
|
|
||||||
|
permsTab.querySelectorAll('input[type="radio"]').forEach(function (el) {
|
||||||
|
el.disabled = !enabled;
|
||||||
|
});
|
||||||
|
|
||||||
|
// also visually dim the tab content
|
||||||
|
permsTab.style.opacity = enabled ? '1' : '0.5';
|
||||||
|
}
|
||||||
|
|
||||||
|
const adminYes = document.getElementById('admin_yes');
|
||||||
|
const adminNo = document.getElementById('admin_no');
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
const isAdmin = adminYes && adminYes.checked;
|
||||||
|
setPermissionsEnabled(!isAdmin);
|
||||||
|
|
||||||
|
if (isAdmin) {
|
||||||
|
// move user back to Details tab (avoids confusion)
|
||||||
|
const detailsTab = document.querySelector('a[href="#pills-role-details"]');
|
||||||
|
if (detailsTab) detailsTab.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adminYes && adminNo) {
|
||||||
|
adminYes.addEventListener('change', refresh);
|
||||||
|
adminNo.addEventListener('change', refresh);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
require_once '../../../includes/modal_footer.php';
|
require_once '../../../includes/modal_footer.php';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $role_id = intval($_GET['id']);
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE 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_assoc($sql);
|
||||||
$role_name = nullable_htmlentities($row['role_name']);
|
$role_name = nullable_htmlentities($row['role_name']);
|
||||||
$role_description = nullable_htmlentities($row['role_description']);
|
$role_description = nullable_htmlentities($row['role_description']);
|
||||||
$role_admin = intval($row['role_is_admin']);
|
$role_admin = intval($row['role_is_admin']);
|
||||||
@@ -31,36 +31,36 @@ if (empty($user_names_string)) {
|
|||||||
$user_names_string = "-";
|
$user_names_string = "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Generate the HTML form content using output buffering.
|
|
||||||
ob_start();
|
ob_start();
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<div class="modal-header bg-dark">
|
<div class="modal-header bg-dark">
|
||||||
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>Editing role:
|
<h5 class="modal-title"><i class="fas fa-fw fa-user-shield mr-2"></i>Editing role:
|
||||||
<strong><?php echo $role_name; ?></strong></h5>
|
<strong><?= $role_name ?></strong></h5>
|
||||||
<button type="button" class="close text-white" data-dismiss="modal">
|
<button type="button" class="close text-white" data-dismiss="modal">
|
||||||
<span>×</span>
|
<span>×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
|
<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="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="role_id" value="<?php echo $role_id; ?>">
|
<input type="hidden" name="role_id" value="<?= $role_id ?>">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<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-role-details<?php echo $role_id; ?>">Details</a>
|
<a class="nav-link active" data-toggle="pill" href="#pills-role-details">Details</a>
|
||||||
</li>
|
</li>
|
||||||
|
<?php if (!$role_admin) { ?>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" data-toggle="pill" href="#pills-role-access<?php echo $role_id; ?>">Access</a>
|
<a class="nav-link" data-toggle="pill" href="#pills-role-permissions">Permissions</a>
|
||||||
</li>
|
</li>
|
||||||
|
<?php } ?>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
|
|
||||||
<div class="tab-pane fade show active" id="pills-role-details<?php echo $role_id; ?>">
|
<div class="tab-pane fade show active" id="pills-role-details">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Name <strong class="text-danger">*</strong></label>
|
<label>Name <strong class="text-danger">*</strong></label>
|
||||||
@@ -68,7 +68,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-shield"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control" name="role_name" placeholder="Role Name" maxlength="200" value="<?php echo $role_name; ?>" required>
|
<input type="text" class="form-control" name="role_name" placeholder="Role Name" maxlength="200" value="<?= $role_name ?>" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -78,27 +78,33 @@ ob_start();
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-chevron-right"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-chevron-right"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control" name="role_description" placeholder="Role Description" maxlength="200" value="<?php echo $role_description; ?>" required>
|
<input type="text" class="form-control" name="role_description" placeholder="Role Description" maxlength="200" value="<?= $role_description ?>" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Admin Access <strong class="text-danger">*</strong></label>
|
<label>Admin Access <strong class="text-danger">*</strong></label>
|
||||||
<div class="input-group">
|
<div class="custom-control custom-radio mb-2">
|
||||||
<div class="input-group-prepend">
|
<input type="radio" class="custom-control-input" id="admin_yes" name="role_is_admin" value="1"
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-tools"></i></span>
|
<?php if ($role_admin) { echo 'checked'; } ?> required>
|
||||||
|
<label class="custom-control-label" for="admin_yes">
|
||||||
|
Yes - this role should have full admin access
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<select class="form-control select2" name="role_is_admin" required>
|
|
||||||
<option value="1" <?php if ($role_admin) { echo 'selected'; } ?> >Yes - this role should have full admin access</option>
|
<div class="custom-control custom-radio">
|
||||||
<option value="0" <?php if (!$role_admin) { echo 'selected'; } ?>>No - use permissions on the next tab</option>
|
<input type="radio" class="custom-control-input" id="admin_no" name="role_is_admin" value="0"
|
||||||
</select>
|
<?php if (!$role_admin) { echo 'checked'; } ?> required>
|
||||||
|
<label class="custom-control-label" for="admin_no">
|
||||||
|
No - use permissions on the next tab
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<?php if (!$role_admin) { ?>
|
||||||
<div class="tab-pane fade" id="pills-role-access<?php echo $role_id; ?>">
|
<div class="tab-pane fade" id="pills-role-permissions">
|
||||||
|
|
||||||
<?php if ($role_admin) { ?>
|
<?php if ($role_admin) { ?>
|
||||||
<div class="alert alert-warning"><strong>Module permissions do not apply to Admins.</strong></div>
|
<div class="alert alert-warning"><strong>Module permissions do not apply to Admins.</strong></div>
|
||||||
@@ -108,14 +114,14 @@ ob_start();
|
|||||||
|
|
||||||
// Enumerate modules
|
// Enumerate modules
|
||||||
$sql_modules = mysqli_query($mysqli, "SELECT * FROM modules");
|
$sql_modules = mysqli_query($mysqli, "SELECT * FROM modules");
|
||||||
while ($row_modules = mysqli_fetch_array($sql_modules)) {
|
while ($row_modules = mysqli_fetch_assoc($sql_modules)) {
|
||||||
$module_id = intval($row_modules['module_id']);
|
$module_id = intval($row_modules['module_id']);
|
||||||
$module_name = nullable_htmlentities($row_modules['module_name']);
|
$module_name = nullable_htmlentities($row_modules['module_name']);
|
||||||
$module_name_display = ucfirst(str_replace("module_","",$module_name));
|
$module_name_display = ucfirst(str_replace("module_","",$module_name));
|
||||||
$module_description = nullable_htmlentities($row_modules['module_description']);
|
$module_description = nullable_htmlentities($row_modules['module_description']);
|
||||||
|
|
||||||
// Get permission level for module
|
// Get permission level for module
|
||||||
$module_permission_row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT user_role_permission_level FROM user_role_permissions WHERE module_id = $module_id AND user_role_id = $role_id LIMIT 1"));
|
$module_permission_row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT user_role_permission_level FROM user_role_permissions WHERE module_id = $module_id AND user_role_id = $role_id LIMIT 1"));
|
||||||
$module_permission = 0;
|
$module_permission = 0;
|
||||||
if ($module_permission_row) {
|
if ($module_permission_row) {
|
||||||
$module_permission = $module_permission_row['user_role_permission_level'];
|
$module_permission = $module_permission_row['user_role_permission_level'];
|
||||||
@@ -123,22 +129,73 @@ ob_start();
|
|||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label> <?php echo $module_name_display ?> <strong class="text-danger">*</strong></label>
|
<label> <?= $module_name_display ?> <strong class="text-danger">*</strong></label>
|
||||||
<div class="input-group">
|
<?php
|
||||||
<select class="form-control select2" name="<?php echo "$module_id##$module_name" ?>" required>
|
$field_name = "$module_id##$module_name";
|
||||||
<option value="0" <?php if ($module_permission == 0) { echo 'selected'; } ?> >None</option>
|
$group_id = "perm_group_$module_id";
|
||||||
<option value="1" <?php if ($module_permission == 1) { echo 'selected'; } ?> >Read</option>
|
?>
|
||||||
<option value="2" <?php if ($module_permission == 2) { echo 'selected'; } ?>>Modify (Read, Edit, Archive)</option>
|
|
||||||
<option value="3" <?php if ($module_permission == 3) { echo 'selected'; } ?>>Full (Read, Edit, Archive, Delete)</option>
|
<div class="btn-group btn-group-toggle btn-block" data-toggle="buttons" role="group" aria-label="Permissions for <?= $module_name_display ?>">
|
||||||
</select>
|
|
||||||
|
<label class="btn btn-outline-secondary btn-sm <?php if ($module_permission == 0) { echo 'active'; } ?>" title="No Access">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="<?= $field_name ?>"
|
||||||
|
id="<?= $group_id ?>_0"
|
||||||
|
value="0"
|
||||||
|
autocomplete="off"
|
||||||
|
<?php if ($module_permission == 0) { echo 'checked'; } ?>
|
||||||
|
required
|
||||||
|
>
|
||||||
|
None
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="btn btn-outline-primary btn-sm <?php if ($module_permission == 1) { echo 'active'; } ?>" title="Viewing Only">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="<?= $field_name ?>"
|
||||||
|
id="<?= $group_id ?>_1"
|
||||||
|
value="1"
|
||||||
|
autocomplete="off"
|
||||||
|
<?php if ($module_permission == 1) { echo 'checked'; } ?>
|
||||||
|
>
|
||||||
|
<i class="fas fa-fw fa-eye mr-1"></i>Read
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="btn btn-outline-warning btn-sm <?php if ($module_permission == 2) { echo 'active'; } ?>" title="Read, Edit, Archive">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="<?= $field_name ?>"
|
||||||
|
id="<?= $group_id ?>_2"
|
||||||
|
value="2"
|
||||||
|
autocomplete="off"
|
||||||
|
<?php if ($module_permission == 2) { echo 'checked'; } ?>
|
||||||
|
>
|
||||||
|
<i class="fas fa-fw fa-edit mr-1"></i>Modify
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="btn btn-outline-danger btn-sm <?php if ($module_permission == 3) { echo 'active'; } ?>" title="Read, Edit, Archive, Delete">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="<?= $field_name ?>"
|
||||||
|
id="<?= $group_id ?>_3"
|
||||||
|
value="3"
|
||||||
|
autocomplete="off"
|
||||||
|
<?php if ($module_permission == 3) { echo 'checked'; } ?>
|
||||||
|
>
|
||||||
|
<i class="fas fa-fw fa-trash mr-1"></i>Full
|
||||||
|
</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<small class="form-text text-muted"><?php echo $module_description ?></small>
|
|
||||||
|
<small class="form-text text-muted mt-2"><?= $module_description ?></small>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php } // End while ?>
|
<?php } // End while ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
|
|||||||
$software_template_id = intval($_GET['id']);
|
$software_template_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM software_templates WHERE software_template_id = $software_template_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM software_templates WHERE software_template_id = $software_template_id LIMIT 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$software_name = nullable_htmlentities($row['software_template_name']);
|
$software_name = nullable_htmlentities($row['software_template_name']);
|
||||||
$software_version = nullable_htmlentities($row['software_template_version']);
|
$software_version = nullable_htmlentities($row['software_template_version']);
|
||||||
$software_description = nullable_htmlentities($row['software_template_description']);
|
$software_description = nullable_htmlentities($row['software_template_description']);
|
||||||
@@ -24,7 +24,9 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="software_template_id" value="<?php echo $software_template_id; ?>">
|
<input type="hidden" name="software_template_id" value="<?php echo $software_template_id; ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="type" value="<?php echo $type; ?>">
|
<input type="hidden" name="type" value="<?php echo $type; ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Name <strong class="text-danger">*</strong></label>
|
<label>Name <strong class="text-danger">*</strong></label>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $tag_id = intval($_GET['id']);
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_id = $tag_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM tags WHERE tag_id = $tag_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$tag_name = nullable_htmlentities($row['tag_name']);
|
$tag_name = nullable_htmlentities($row['tag_name']);
|
||||||
$tag_type = intval($row['tag_type']);
|
$tag_type = intval($row['tag_type']);
|
||||||
$tag_color = nullable_htmlentities($row['tag_color']);
|
$tag_color = nullable_htmlentities($row['tag_color']);
|
||||||
@@ -35,7 +35,9 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="tag_id" value="<?php echo $tag_id; ?>">
|
<input type="hidden" name="tag_id" value="<?php echo $tag_id; ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
|
|||||||
$tax_id = intval($_GET['id']);
|
$tax_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM taxes WHERE tax_id = $tax_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM taxes WHERE tax_id = $tax_id LIMIT 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$tax_name = nullable_htmlentities($row['tax_name']);
|
$tax_name = nullable_htmlentities($row['tax_name']);
|
||||||
$tax_percent = floatval($row['tax_percent']);
|
$tax_percent = floatval($row['tax_percent']);
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
|
|||||||
$ticket_status_id = intval($_GET['id']);
|
$ticket_status_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_id = $ticket_status_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM ticket_statuses WHERE ticket_status_id = $ticket_status_id LIMIT 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$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_status_order = intval($row['ticket_status_order']);
|
$ticket_status_order = intval($row['ticket_status_order']);
|
||||||
@@ -22,7 +22,9 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="ticket_status_id" value="<?php echo $ticket_status_id; ?>">
|
<input type="hidden" name="ticket_status_id" value="<?php echo $ticket_status_id; ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -59,7 +61,7 @@ ob_start();
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql_project_templates = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_archived_at IS NULL ORDER BY project_template_name ASC");
|
$sql_project_templates = mysqli_query($mysqli, "SELECT * FROM project_templates WHERE project_template_archived_at IS NULL ORDER BY project_template_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql_project_templates)) {
|
while ($row = mysqli_fetch_assoc($sql_project_templates)) {
|
||||||
$project_template_id_select = intval($row['project_template_id']);
|
$project_template_id_select = intval($row['project_template_id']);
|
||||||
$project_template_name_select = nullable_htmlentities($row['project_template_name']); ?>
|
$project_template_name_select = nullable_htmlentities($row['project_template_name']); ?>
|
||||||
<option value="<?php echo $project_template_id_select; ?>"><?php echo $project_template_name_select; ?></option>
|
<option value="<?php echo $project_template_id_select; ?>"><?php echo $project_template_name_select; ?></option>
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="ticket_template_id" value="<?php echo $ticket_template_id; ?>">
|
<input type="hidden" name="ticket_template_id" value="<?php echo $ticket_template_id; ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $task_template_id = intval($_GET['id']);
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE task_template_id = $task_template_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE task_template_id = $task_template_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$task_template_name = nullable_htmlentities($row['task_template_name']);
|
$task_template_name = nullable_htmlentities($row['task_template_name']);
|
||||||
$task_template_order = intval($row['task_template_order']);
|
$task_template_order = intval($row['task_template_order']);
|
||||||
$task_template_completion_estimate = intval($row['task_template_completion_estimate']);
|
$task_template_completion_estimate = intval($row['task_template_completion_estimate']);
|
||||||
@@ -24,6 +24,7 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="task_template_id" value="<?php echo $task_template_id; ?>">
|
<input type="hidden" name="task_template_id" value="<?php echo $task_template_id; ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ ob_start();
|
|||||||
<option value="">- Role -</option>
|
<option value="">- Role -</option>
|
||||||
<?php
|
<?php
|
||||||
$sql_user_roles = mysqli_query($mysqli, "SELECT * FROM user_roles WHERE 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_assoc($sql_user_roles)) {
|
||||||
$role_id = intval($row['role_id']);
|
$role_id = intval($row['role_id']);
|
||||||
$role_name = nullable_htmlentities($row['role_name']);
|
$role_name = nullable_htmlentities($row['role_name']);
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ ob_start();
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
$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)) {
|
while ($row = mysqli_fetch_assoc($sql_client_select)) {
|
||||||
$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']);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $user_id = intval($_GET['id']);
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE users.user_id = $user_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE users.user_id = $user_id LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$user_name = nullable_htmlentities($row['user_name']);
|
$user_name = nullable_htmlentities($row['user_name']);
|
||||||
$user_email = nullable_htmlentities($row['user_email']);
|
$user_email = nullable_htmlentities($row['user_email']);
|
||||||
$user_avatar = nullable_htmlentities($row['user_avatar']);
|
$user_avatar = nullable_htmlentities($row['user_avatar']);
|
||||||
@@ -60,7 +60,7 @@ ob_start();
|
|||||||
<option value="0">No one</option>
|
<option value="0">No one</option>
|
||||||
<?php
|
<?php
|
||||||
$sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE user_type = 1 AND user_archived_at IS NULL");
|
$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)) {
|
while ($row = mysqli_fetch_assoc($sql_users)) {
|
||||||
$user_id_select = intval($row['user_id']);
|
$user_id_select = intval($row['user_id']);
|
||||||
$user_name_select = nullable_htmlentities($row['user_name']);
|
$user_name_select = nullable_htmlentities($row['user_name']);
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ $sql = mysqli_query($mysqli, "SELECT * FROM users
|
|||||||
WHERE users.user_id = $user_id LIMIT 1"
|
WHERE users.user_id = $user_id LIMIT 1"
|
||||||
);
|
);
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$user_name = nullable_htmlentities($row['user_name']);
|
$user_name = nullable_htmlentities($row['user_name']);
|
||||||
$user_email = nullable_htmlentities($row['user_email']);
|
$user_email = nullable_htmlentities($row['user_email']);
|
||||||
$user_avatar = nullable_htmlentities($row['user_avatar']);
|
$user_avatar = nullable_htmlentities($row['user_avatar']);
|
||||||
@@ -114,7 +114,7 @@ ob_start();
|
|||||||
<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 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_assoc($sql_user_roles)) {
|
||||||
$role_id = intval($row['role_id']);
|
$role_id = intval($row['role_id']);
|
||||||
$role_name = nullable_htmlentities($row['role_name']);
|
$role_name = nullable_htmlentities($row['role_name']);
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ ob_start();
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql_client_select = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC");
|
$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)) {
|
while ($row = mysqli_fetch_assoc($sql_client_select)) {
|
||||||
$client_id_select = intval($row['client_id']);
|
$client_id_select = intval($row['client_id']);
|
||||||
$client_name_select = nullable_htmlentities($row['client_name']);
|
$client_name_select = nullable_htmlentities($row['client_name']);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $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");
|
$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);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$user_name = str_replace(" (archived)", "", $row['user_name']); //Removed (archived) from user_name
|
$user_name = str_replace(" (archived)", "", $row['user_name']); //Removed (archived) from user_name
|
||||||
$user_name = nullable_htmlentities($user_name);
|
$user_name = nullable_htmlentities($user_name);
|
||||||
$user_email = nullable_htmlentities($row['user_email']);
|
$user_email = nullable_htmlentities($row['user_email']);
|
||||||
@@ -64,7 +64,7 @@ ob_start();
|
|||||||
<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 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_assoc($sql_user_roles)) {
|
||||||
$role_id = intval($row['role_id']);
|
$role_id = intval($row['role_id']);
|
||||||
$role_name = nullable_htmlentities($row['role_name']);
|
$role_name = nullable_htmlentities($row['role_name']);
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ require_once '../../../includes/modal_header.php';
|
|||||||
$vendor_template_id = intval($_GET['id']);
|
$vendor_template_id = intval($_GET['id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM vendor_templates WHERE vendor_template_id = $vendor_template_id LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM vendor_templates WHERE vendor_template_id = $vendor_template_id LIMIT 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$vendor_name = nullable_htmlentities($row['vendor_template_name']);
|
$vendor_name = nullable_htmlentities($row['vendor_template_name']);
|
||||||
$vendor_description = nullable_htmlentities($row['vendor_template_description']);
|
$vendor_description = nullable_htmlentities($row['vendor_template_description']);
|
||||||
$vendor_account_number = nullable_htmlentities($row['vendor_template_account_number']);
|
$vendor_account_number = nullable_htmlentities($row['vendor_template_account_number']);
|
||||||
@@ -31,7 +31,9 @@ ob_start();
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="vendor_template_id" value="<?php echo $vendor_template_id; ?>">
|
<input type="hidden" name="vendor_template_id" value="<?php echo $vendor_template_id; ?>">
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<ul class="nav nav-pills nav-justified mb-3">
|
<ul class="nav nav-pills nav-justified mb-3">
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$module_id = intval($row['module_id']);
|
$module_id = intval($row['module_id']);
|
||||||
$module_name = nullable_htmlentities($row['module_name']);
|
$module_name = nullable_htmlentities($row['module_name']);
|
||||||
$module_description = nullable_htmlentities($row['module_description']);
|
$module_description = nullable_htmlentities($row['module_description']);
|
||||||
|
|||||||
103
admin/oauth_microsoft_mail_callback.php
Normal file
103
admin/oauth_microsoft_mail_callback.php
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "../config.php";
|
||||||
|
require_once "../functions.php";
|
||||||
|
require_once "../includes/check_login.php";
|
||||||
|
|
||||||
|
$settings_mail_path = '/admin/settings_mail.php';
|
||||||
|
|
||||||
|
if (!isset($session_is_admin) || !$session_is_admin) {
|
||||||
|
flash_alert("Admin access required.", 'error');
|
||||||
|
redirect($settings_mail_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$state = sanitizeInput($_GET['state'] ?? '');
|
||||||
|
$code = $_GET['code'] ?? '';
|
||||||
|
$error = sanitizeInput($_GET['error'] ?? '');
|
||||||
|
$error_description = sanitizeInput($_GET['error_description'] ?? '');
|
||||||
|
|
||||||
|
$session_state = $_SESSION['mail_oauth_state'] ?? '';
|
||||||
|
$session_state_expires = intval($_SESSION['mail_oauth_state_expires_at'] ?? 0);
|
||||||
|
|
||||||
|
unset($_SESSION['mail_oauth_state'], $_SESSION['mail_oauth_state_expires_at']);
|
||||||
|
|
||||||
|
if (!empty($error)) {
|
||||||
|
$msg = "Microsoft OAuth authorization failed: $error";
|
||||||
|
if (!empty($error_description)) {
|
||||||
|
$msg .= " ($error_description)";
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_alert($msg, 'error');
|
||||||
|
redirect($settings_mail_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($state) || empty($code) || empty($session_state) || !hash_equals($session_state, $state) || time() > $session_state_expires) {
|
||||||
|
flash_alert("Microsoft OAuth callback validation failed. Please try connecting again.", 'error');
|
||||||
|
redirect($settings_mail_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($config_mail_oauth_client_id) || empty($config_mail_oauth_client_secret) || empty($config_mail_oauth_tenant_id)) {
|
||||||
|
flash_alert("Microsoft OAuth settings are incomplete. Please fill Client ID, Client Secret, and Tenant ID.", 'error');
|
||||||
|
redirect($settings_mail_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined('BASE_URL') && !empty(BASE_URL)) {
|
||||||
|
$base_url = rtrim((string) BASE_URL, '/');
|
||||||
|
} else {
|
||||||
|
$base_url = 'https://' . rtrim((string) $config_base_url, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
$redirect_uri = $base_url . '/admin/oauth_microsoft_mail_callback.php';
|
||||||
|
$token_url = 'https://login.microsoftonline.com/' . rawurlencode($config_mail_oauth_tenant_id) . '/oauth2/v2.0/token';
|
||||||
|
$scope = 'offline_access openid profile https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send';
|
||||||
|
|
||||||
|
$ch = curl_init($token_url);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
|
||||||
|
'client_id' => $config_mail_oauth_client_id,
|
||||||
|
'client_secret' => $config_mail_oauth_client_secret,
|
||||||
|
'grant_type' => 'authorization_code',
|
||||||
|
'code' => $code,
|
||||||
|
'redirect_uri' => $redirect_uri,
|
||||||
|
'scope' => $scope,
|
||||||
|
], '', '&'));
|
||||||
|
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
|
||||||
|
|
||||||
|
$raw_body = curl_exec($ch);
|
||||||
|
$curl_err = curl_error($ch);
|
||||||
|
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
if ($raw_body === false || $http_code < 200 || $http_code >= 300) {
|
||||||
|
$reason = !empty($curl_err) ? $curl_err : "HTTP $http_code";
|
||||||
|
flash_alert("Microsoft OAuth token exchange failed: $reason", 'error');
|
||||||
|
redirect($settings_mail_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$json = json_decode($raw_body, true);
|
||||||
|
if (!is_array($json) || empty($json['refresh_token']) || empty($json['access_token'])) {
|
||||||
|
flash_alert("Microsoft OAuth token exchange failed: refresh token or access token missing.", 'error');
|
||||||
|
redirect($settings_mail_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$refresh_token = (string) $json['refresh_token'];
|
||||||
|
$access_token = (string) $json['access_token'];
|
||||||
|
$expires_at = date('Y-m-d H:i:s', time() + (int)($json['expires_in'] ?? 3600));
|
||||||
|
|
||||||
|
$refresh_token_esc = mysqli_real_escape_string($mysqli, $refresh_token);
|
||||||
|
$access_token_esc = mysqli_real_escape_string($mysqli, $access_token);
|
||||||
|
$expires_at_esc = mysqli_real_escape_string($mysqli, $expires_at);
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "UPDATE settings SET
|
||||||
|
config_imap_provider = 'microsoft_oauth',
|
||||||
|
config_smtp_provider = 'microsoft_oauth',
|
||||||
|
config_mail_oauth_refresh_token = '$refresh_token_esc',
|
||||||
|
config_mail_oauth_access_token = '$access_token_esc',
|
||||||
|
config_mail_oauth_access_token_expires_at = '$expires_at_esc'
|
||||||
|
WHERE company_id = 1
|
||||||
|
");
|
||||||
|
|
||||||
|
logAction("Settings", "Edit", "$session_name completed Microsoft OAuth connect flow for mail settings");
|
||||||
|
flash_alert("Microsoft OAuth connected successfully. Token expires at $expires_at.");
|
||||||
|
redirect($settings_mail_path);
|
||||||
@@ -45,7 +45,7 @@ $num_rows = mysqli_num_rows($sql);
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$payment_method_id = intval($row['payment_method_id']);
|
$payment_method_id = intval($row['payment_method_id']);
|
||||||
$payment_method_name = nullable_htmlentities($row['payment_method_name']);
|
$payment_method_name = nullable_htmlentities($row['payment_method_name']);
|
||||||
$payment_method_description = nullable_htmlentities($row['payment_method_description']);
|
$payment_method_description = nullable_htmlentities($row['payment_method_description']);
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ $num_rows = mysqli_num_rows($sql);
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$provider_id = intval($row['payment_provider_id']);
|
$provider_id = intval($row['payment_provider_id']);
|
||||||
$provider_name = nullable_htmlentities($row['payment_provider_name']);
|
$provider_name = nullable_htmlentities($row['payment_provider_name']);
|
||||||
$provider_description = nullable_htmlentities($row['payment_provider_description']);
|
$provider_description = nullable_htmlentities($row['payment_provider_description']);
|
||||||
|
|||||||
@@ -31,6 +31,27 @@ if (isset($_POST['add_api_key'])) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($_GET['revoke_api_key'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
|
$api_key_id = intval($_GET['revoke_api_key']);
|
||||||
|
|
||||||
|
// Get API Key Name
|
||||||
|
$row = mysqli_fetch_assoc(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id"));
|
||||||
|
$api_key_name = sanitizeInput($row['api_key_name']);
|
||||||
|
$client_id = intval($row['api_key_client_id']);
|
||||||
|
|
||||||
|
mysqli_query($mysqli,"UPDATE api_keys SET api_key_expire = NOW() WHERE api_key_id = $api_key_id");
|
||||||
|
|
||||||
|
logAction("API Key", "Revoke", "$session_name revoked API key $name", $client_id);
|
||||||
|
|
||||||
|
flash_alert("API Key <strong>$name</strong> revoked", 'error');
|
||||||
|
|
||||||
|
redirect();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($_GET['delete_api_key'])) {
|
if (isset($_GET['delete_api_key'])) {
|
||||||
|
|
||||||
validateCSRFToken($_GET['csrf_token']);
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
@@ -38,7 +59,7 @@ if (isset($_GET['delete_api_key'])) {
|
|||||||
$api_key_id = intval($_GET['delete_api_key']);
|
$api_key_id = intval($_GET['delete_api_key']);
|
||||||
|
|
||||||
// Get API Key Name
|
// Get API Key Name
|
||||||
$row = mysqli_fetch_array(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id"));
|
$row = mysqli_fetch_assoc(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id"));
|
||||||
$api_key_name = sanitizeInput($row['api_key_name']);
|
$api_key_name = sanitizeInput($row['api_key_name']);
|
||||||
$client_id = intval($row['api_key_client_id']);
|
$client_id = intval($row['api_key_client_id']);
|
||||||
|
|
||||||
@@ -66,7 +87,7 @@ if (isset($_POST['bulk_delete_api_keys'])) {
|
|||||||
$api_key_id = intval($api_key_id);
|
$api_key_id = intval($api_key_id);
|
||||||
|
|
||||||
// Get API Key Name
|
// Get API Key Name
|
||||||
$row = mysqli_fetch_array(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id"));
|
$row = mysqli_fetch_assoc(mysqli_query($mysqli,"SELECT api_key_name, api_key_client_id FROM api_keys WHERE api_key_id = $api_key_id"));
|
||||||
$api_key_name = sanitizeInput($row['api_key_name']);
|
$api_key_name = sanitizeInput($row['api_key_name']);
|
||||||
$client_id = intval($row['api_key_client_id']);
|
$client_id = intval($row['api_key_client_id']);
|
||||||
|
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ if (isset($_POST['backup_master_key'])) {
|
|||||||
$password = $_POST['password'];
|
$password = $_POST['password'];
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $session_user_id");
|
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $session_user_id");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
|
|
||||||
if (password_verify($password, $row['user_password'])) {
|
if (password_verify($password, $row['user_password'])) {
|
||||||
$site_encryption_master_key = decryptUserSpecificKey($row['user_specific_encryption_ciphertext'], $password);
|
$site_encryption_master_key = decryptUserSpecificKey($row['user_specific_encryption_ciphertext'], $password);
|
||||||
@@ -329,4 +329,3 @@ if (isset($_POST['backup_master_key'])) {
|
|||||||
redirect();
|
redirect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
|||||||
|
|
||||||
if (isset($_POST['add_category'])) {
|
if (isset($_POST['add_category'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
require_once 'category_model.php';
|
require_once 'category_model.php';
|
||||||
|
|
||||||
mysqli_query($mysqli,"INSERT INTO categories SET category_name = '$name', category_type = '$type', category_color = '$color'");
|
mysqli_query($mysqli,"INSERT INTO categories SET category_name = '$name', category_type = '$type', category_color = '$color'");
|
||||||
@@ -24,6 +26,8 @@ if (isset($_POST['add_category'])) {
|
|||||||
|
|
||||||
if (isset($_POST['edit_category'])) {
|
if (isset($_POST['edit_category'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
require_once 'category_model.php';
|
require_once 'category_model.php';
|
||||||
|
|
||||||
$category_id = intval($_POST['category_id']);
|
$category_id = intval($_POST['category_id']);
|
||||||
@@ -40,11 +44,13 @@ if (isset($_POST['edit_category'])) {
|
|||||||
|
|
||||||
if (isset($_GET['archive_category'])) {
|
if (isset($_GET['archive_category'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$category_id = intval($_GET['archive_category']);
|
$category_id = intval($_GET['archive_category']);
|
||||||
|
|
||||||
// Get Category Name and Type for logging
|
// Get Category Name and Type for logging
|
||||||
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
|
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$category_name = sanitizeInput($row['category_name']);
|
$category_name = sanitizeInput($row['category_name']);
|
||||||
$category_type = sanitizeInput($row['category_type']);
|
$category_type = sanitizeInput($row['category_type']);
|
||||||
|
|
||||||
@@ -58,21 +64,23 @@ if (isset($_GET['archive_category'])) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_GET['unarchive_category'])) {
|
if (isset($_GET['restore_category'])) {
|
||||||
|
|
||||||
$category_id = intval($_GET['unarchive_category']);
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
|
$category_id = intval($_GET['retore_category']);
|
||||||
|
|
||||||
// Get Category Name and Type for logging
|
// Get Category Name and Type for logging
|
||||||
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
|
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$category_name = sanitizeInput($row['category_name']);
|
$category_name = sanitizeInput($row['category_name']);
|
||||||
$category_type = sanitizeInput($row['category_type']);
|
$category_type = sanitizeInput($row['category_type']);
|
||||||
|
|
||||||
mysqli_query($mysqli,"UPDATE categories SET category_archived_at = NULL WHERE category_id = $category_id");
|
mysqli_query($mysqli,"UPDATE categories SET category_archived_at = NULL WHERE category_id = $category_id");
|
||||||
|
|
||||||
logAction("Category", "Unarchive", "$session_name unarchived category $category_type $category_name", 0, $category_id);
|
logAction("Category", "Restore", "$session_name retored category $category_type $category_name", 0, $category_id);
|
||||||
|
|
||||||
flash_alert("Category $category_type <strong>$category_name</strong> unarchived");
|
flash_alert("Category $category_type <strong>$category_name</strong> restored");
|
||||||
|
|
||||||
redirect();
|
redirect();
|
||||||
|
|
||||||
@@ -80,11 +88,13 @@ if (isset($_GET['unarchive_category'])) {
|
|||||||
|
|
||||||
if (isset($_GET['delete_category'])) {
|
if (isset($_GET['delete_category'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$category_id = intval($_GET['delete_category']);
|
$category_id = intval($_GET['delete_category']);
|
||||||
|
|
||||||
// Get Category Name and Type for logging
|
// Get Category Name and Type for logging
|
||||||
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
|
$sql = mysqli_query($mysqli,"SELECT category_name, category_type FROM categories WHERE category_id = $category_id");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$category_name = sanitizeInput($row['category_name']);
|
$category_name = sanitizeInput($row['category_name']);
|
||||||
$category_type = sanitizeInput($row['category_type']);
|
$category_type = sanitizeInput($row['category_type']);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
|||||||
|
|
||||||
if (isset($_POST['add_custom_link'])) {
|
if (isset($_POST['add_custom_link'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$uri = sanitizeInput($_POST['uri']);
|
$uri = sanitizeInput($_POST['uri']);
|
||||||
$new_tab = intval($_POST['new_tab'] ?? 0);
|
$new_tab = intval($_POST['new_tab'] ?? 0);
|
||||||
@@ -29,6 +31,8 @@ if (isset($_POST['add_custom_link'])) {
|
|||||||
|
|
||||||
if (isset($_POST['edit_custom_link'])) {
|
if (isset($_POST['edit_custom_link'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$custom_link_id = intval($_POST['custom_link_id']);
|
$custom_link_id = intval($_POST['custom_link_id']);
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$uri = sanitizeInput($_POST['uri']);
|
$uri = sanitizeInput($_POST['uri']);
|
||||||
@@ -49,11 +53,13 @@ if (isset($_POST['edit_custom_link'])) {
|
|||||||
|
|
||||||
if (isset($_GET['delete_custom_link'])) {
|
if (isset($_GET['delete_custom_link'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$custom_link_id = intval($_GET['delete_custom_link']);
|
$custom_link_id = intval($_GET['delete_custom_link']);
|
||||||
|
|
||||||
// Get Custom Link name and uri for logging
|
// Get Custom Link name and uri for logging
|
||||||
$sql = mysqli_query($mysqli,"SELECT custom_link_name, custom_link_uri FROM custom_links WHERE custom_link_id = $custom_link_id");
|
$sql = mysqli_query($mysqli,"SELECT custom_link_name, custom_link_uri FROM custom_links WHERE custom_link_id = $custom_link_id");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$custom_link_name = sanitizeInput($row['custom_link_name']);
|
$custom_link_name = sanitizeInput($row['custom_link_name']);
|
||||||
$custom_link_uri = sanitizeInput($row['custom_link_uri']);
|
$custom_link_uri = sanitizeInput($row['custom_link_uri']);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
|||||||
|
|
||||||
if (isset($_POST['add_document_template'])) {
|
if (isset($_POST['add_document_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$description = sanitizeInput($_POST['description']);
|
$description = sanitizeInput($_POST['description']);
|
||||||
|
|
||||||
@@ -36,6 +38,8 @@ if (isset($_POST['add_document_template'])) {
|
|||||||
|
|
||||||
if (isset($_POST['edit_document_template'])) {
|
if (isset($_POST['edit_document_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$document_template_id = intval($_POST['document_template_id']);
|
$document_template_id = intval($_POST['document_template_id']);
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$description = sanitizeInput($_POST['description']);
|
$description = sanitizeInput($_POST['description']);
|
||||||
@@ -69,6 +73,8 @@ if (isset($_POST['edit_document_template'])) {
|
|||||||
|
|
||||||
if (isset($_GET['delete_document_template'])) {
|
if (isset($_GET['delete_document_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$document_template_id = intval($_GET['delete_document_template']);
|
$document_template_id = intval($_GET['delete_document_template']);
|
||||||
|
|
||||||
$document_template_name = sanitizeInput(getFieldById('document_templates', $document_template_id, 'document_template_name'));
|
$document_template_name = sanitizeInput(getFieldById('document_templates', $document_template_id, 'document_template_name'));
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
|||||||
|
|
||||||
if (isset($_GET['send_failed_mail'])) {
|
if (isset($_GET['send_failed_mail'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$email_id = intval($_GET['send_failed_mail']);
|
$email_id = intval($_GET['send_failed_mail']);
|
||||||
|
|
||||||
mysqli_query($mysqli,"UPDATE email_queue SET email_status = 0, email_attempts = 3 WHERE email_id = $email_id");
|
mysqli_query($mysqli,"UPDATE email_queue SET email_status = 0, email_attempts = 3 WHERE email_id = $email_id");
|
||||||
@@ -18,6 +20,8 @@ if (isset($_GET['send_failed_mail'])) {
|
|||||||
|
|
||||||
if (isset($_GET['cancel_mail'])) {
|
if (isset($_GET['cancel_mail'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$email_id = intval($_GET['cancel_mail']);
|
$email_id = intval($_GET['cancel_mail']);
|
||||||
|
|
||||||
mysqli_query($mysqli,"UPDATE email_queue SET email_status = 2, email_attempts = 99, email_failed_at = NOW() WHERE email_id = $email_id");
|
mysqli_query($mysqli,"UPDATE email_queue SET email_status = 2, email_attempts = 99, email_failed_at = NOW() WHERE email_id = $email_id");
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ if (isset($_POST['edit_payment_method'])) {
|
|||||||
|
|
||||||
if (isset($_GET['delete_payment_method'])) {
|
if (isset($_GET['delete_payment_method'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$payment_method_id = intval($_GET['delete_payment_method']);
|
$payment_method_id = intval($_GET['delete_payment_method']);
|
||||||
|
|
||||||
$payment_method_name = sanitizeInput(getFieldById('payment_methods', $payment_method_is, 'payment_method_name'));
|
$payment_method_name = sanitizeInput(getFieldById('payment_methods', $payment_method_is, 'payment_method_name'));
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
|||||||
|
|
||||||
if (isset($_POST['add_project_template'])) {
|
if (isset($_POST['add_project_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$description = sanitizeInput($_POST['description']);
|
$description = sanitizeInput($_POST['description']);
|
||||||
|
|
||||||
@@ -21,6 +23,8 @@ if (isset($_POST['add_project_template'])) {
|
|||||||
|
|
||||||
if (isset($_POST['edit_project_template'])) {
|
if (isset($_POST['edit_project_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$project_template_id = intval($_POST['project_template_id']);
|
$project_template_id = intval($_POST['project_template_id']);
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$description = sanitizeInput($_POST['description']);
|
$description = sanitizeInput($_POST['description']);
|
||||||
@@ -37,6 +41,8 @@ if (isset($_POST['edit_project_template'])) {
|
|||||||
|
|
||||||
if (isset($_POST['edit_ticket_template_order'])) {
|
if (isset($_POST['edit_ticket_template_order'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$ticket_template_id = intval($_POST['ticket_template_id']);
|
$ticket_template_id = intval($_POST['ticket_template_id']);
|
||||||
$project_template_id = intval($_POST['project_template_id']);
|
$project_template_id = intval($_POST['project_template_id']);
|
||||||
$order = intval($_POST['order']);
|
$order = intval($_POST['order']);
|
||||||
@@ -49,6 +55,8 @@ if (isset($_POST['edit_ticket_template_order'])) {
|
|||||||
|
|
||||||
if (isset($_POST['add_ticket_template_to_project_template'])) {
|
if (isset($_POST['add_ticket_template_to_project_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$project_template_id = intval($_POST['project_template_id']);
|
$project_template_id = intval($_POST['project_template_id']);
|
||||||
$ticket_template_id = intval($_POST['ticket_template_id']);
|
$ticket_template_id = intval($_POST['ticket_template_id']);
|
||||||
$order = intval($_POST['order']);
|
$order = intval($_POST['order']);
|
||||||
@@ -65,7 +73,8 @@ if (isset($_POST['add_ticket_template_to_project_template'])) {
|
|||||||
|
|
||||||
if (isset($_POST['remove_ticket_template_from_project_template'])) {
|
if (isset($_POST['remove_ticket_template_from_project_template'])) {
|
||||||
|
|
||||||
validateTechRole();
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$ticket_template_id = intval($_POST['ticket_template_id']);
|
$ticket_template_id = intval($_POST['ticket_template_id']);
|
||||||
$project_template_id = intval($_POST['project_template_id']);
|
$project_template_id = intval($_POST['project_template_id']);
|
||||||
|
|
||||||
@@ -81,6 +90,8 @@ if (isset($_POST['remove_ticket_template_from_project_template'])) {
|
|||||||
|
|
||||||
if (isset($_GET['delete_project_template'])) {
|
if (isset($_GET['delete_project_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$project_template_id = intval($_GET['delete_project_template']);
|
$project_template_id = intval($_GET['delete_project_template']);
|
||||||
|
|
||||||
$project_template_name = sanitizeInput(getFieldById('project_templates', $project_template_id, 'project_template_name'));
|
$project_template_name = sanitizeInput(getFieldById('project_templates', $project_template_id, 'project_template_name'));
|
||||||
|
|||||||
@@ -18,9 +18,23 @@ if (isset($_POST['add_role'])) {
|
|||||||
|
|
||||||
$role_id = mysqli_insert_id($mysqli);
|
$role_id = mysqli_insert_id($mysqli);
|
||||||
|
|
||||||
|
// Insert role permissions (only if not admin)
|
||||||
|
if ($admin == 0) {
|
||||||
|
foreach ($_POST as $key => $value) {
|
||||||
|
if (str_contains($key, '##module_')) {
|
||||||
|
$module_id = intval(explode('##', $key)[0]);
|
||||||
|
$access_level = intval($value);
|
||||||
|
|
||||||
|
if ($access_level > 0) {
|
||||||
|
mysqli_query($mysqli, "INSERT INTO user_role_permissions SET user_role_id = $role_id, module_id = $module_id, user_role_permission_level = $access_level");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logAction("User Role", "Create", "$session_name created user role $name", 0, $role_id);
|
logAction("User Role", "Create", "$session_name created user role $name", 0, $role_id);
|
||||||
|
|
||||||
flash_alert("User Role <strong$name</strong> created");
|
flash_alert("User Role <strong>$name</strong> created");
|
||||||
|
|
||||||
redirect();
|
redirect();
|
||||||
|
|
||||||
@@ -76,7 +90,7 @@ if (isset($_GET['archive_role'])) {
|
|||||||
|
|
||||||
mysqli_query($mysqli, "UPDATE user_roles SET role_archived_at = NOW() WHERE role_id = $role_id");
|
mysqli_query($mysqli, "UPDATE user_roles SET role_archived_at = NOW() WHERE role_id = $role_id");
|
||||||
|
|
||||||
$role_name = sanitizeInput(getFieldById('roles', $role_id, 'role_name'));
|
$role_name = sanitizeInput(getFieldById('user_roles', $role_id, 'role_name'));
|
||||||
|
|
||||||
logAction("User Role", "Archive", "$session_name archived user role $role_name", 0, $role_id);
|
logAction("User Role", "Archive", "$session_name archived user role $role_name", 0, $role_id);
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ if (isset($_GET['delete_saved_payment'])) {
|
|||||||
WHERE client_saved_payment_methods.saved_payment_id = $saved_payment_id"
|
WHERE client_saved_payment_methods.saved_payment_id = $saved_payment_id"
|
||||||
);
|
);
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$client_id = intval($row['saved_payment_client_id']);
|
$client_id = intval($row['saved_payment_client_id']);
|
||||||
$provider_id = intval($row['saved_payment_provider_id']);
|
$provider_id = intval($row['saved_payment_provider_id']);
|
||||||
$payment_provider_name = nullable_htmlentities($row['payment_provider_name']);
|
$payment_provider_name = nullable_htmlentities($row['payment_provider_name']);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ if (isset($_POST['edit_company'])) {
|
|||||||
$tax_id = sanitizeInput($_POST['tax_id']);
|
$tax_id = sanitizeInput($_POST['tax_id']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT company_logo FROM companies WHERE company_id = 1");
|
$sql = mysqli_query($mysqli,"SELECT company_logo FROM companies WHERE company_id = 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$existing_file_name = sanitizeInput($row['company_logo']);
|
$existing_file_name = sanitizeInput($row['company_logo']);
|
||||||
|
|
||||||
// Company logo
|
// Company logo
|
||||||
@@ -54,8 +54,10 @@ if (isset($_POST['edit_company'])) {
|
|||||||
|
|
||||||
if (isset($_GET['remove_company_logo'])) {
|
if (isset($_GET['remove_company_logo'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT company_logo FROM companies");
|
$sql = mysqli_query($mysqli,"SELECT company_logo FROM companies");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$company_logo = $row['company_logo']; // FileSystem Operation Logo is already sanitized
|
$company_logo = $row['company_logo']; // FileSystem Operation Logo is already sanitized
|
||||||
|
|
||||||
unlink("../uploads/settings/$company_logo");
|
unlink("../uploads/settings/$company_logo");
|
||||||
|
|||||||
@@ -2,6 +2,79 @@
|
|||||||
|
|
||||||
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
||||||
|
|
||||||
|
if (!defined('MICROSOFT_OAUTH_BASE_URL')) {
|
||||||
|
define('MICROSOFT_OAUTH_BASE_URL', 'https://login.microsoftonline.com/');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_POST['oauth_connect_microsoft_mail'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
|
// Save current IMAP/OAuth form values first so auth flow always uses latest inputs.
|
||||||
|
$config_imap_provider = sanitizeInput($_POST['config_imap_provider'] ?? '');
|
||||||
|
$config_imap_username = sanitizeInput($_POST['config_imap_username'] ?? '');
|
||||||
|
$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'] ?? '');
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "UPDATE settings SET
|
||||||
|
config_imap_provider = '$config_imap_provider',
|
||||||
|
config_imap_username = '$config_imap_username',
|
||||||
|
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
|
||||||
|
");
|
||||||
|
|
||||||
|
if ($config_imap_provider !== 'microsoft_oauth') {
|
||||||
|
flash_alert("Please set IMAP Provider to Microsoft 365 (OAuth) before connecting.", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($config_mail_oauth_client_id) || empty($config_mail_oauth_client_secret) || empty($config_mail_oauth_tenant_id)) {
|
||||||
|
flash_alert("Missing Microsoft OAuth settings. Please provide Client ID, Client Secret, and Tenant ID first.", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined('BASE_URL') && !empty(BASE_URL)) {
|
||||||
|
$base_url = rtrim((string) BASE_URL, '/');
|
||||||
|
} else {
|
||||||
|
$base_url = 'https://' . rtrim((string) $config_base_url, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
$redirect_uri = $base_url . '/admin/oauth_microsoft_mail_callback.php';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$state = bin2hex(random_bytes(32));
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
$state = sha1(uniqid((string) mt_rand(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
$_SESSION['mail_oauth_state'] = $state;
|
||||||
|
$_SESSION['mail_oauth_state_expires_at'] = time() + 600;
|
||||||
|
|
||||||
|
$scope = 'offline_access openid profile https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send';
|
||||||
|
|
||||||
|
$authorize_url = MICROSOFT_OAUTH_BASE_URL . rawurlencode($config_mail_oauth_tenant_id) . '/oauth2/v2.0/authorize?'
|
||||||
|
. http_build_query([
|
||||||
|
'client_id' => $config_mail_oauth_client_id,
|
||||||
|
'response_type' => 'code',
|
||||||
|
'redirect_uri' => $redirect_uri,
|
||||||
|
'response_mode' => 'query',
|
||||||
|
'scope' => $scope,
|
||||||
|
'state' => $state,
|
||||||
|
'prompt' => 'consent',
|
||||||
|
], '', '&', PHP_QUERY_RFC3986);
|
||||||
|
|
||||||
|
logAction("Settings", "Edit", "$session_name started Microsoft OAuth connect flow for mail settings");
|
||||||
|
|
||||||
|
redirect($authorize_url);
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($_POST['edit_mail_smtp_settings'])) {
|
if (isset($_POST['edit_mail_smtp_settings'])) {
|
||||||
|
|
||||||
validateCSRFToken($_POST['csrf_token']);
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
@@ -163,12 +236,145 @@ if (isset($_POST['test_email_imap'])) {
|
|||||||
|
|
||||||
validateCSRFToken($_POST['csrf_token']);
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
|
$provider = sanitizeInput($config_imap_provider ?? '');
|
||||||
|
|
||||||
$host = $config_imap_host;
|
$host = $config_imap_host;
|
||||||
$port = (int) $config_imap_port;
|
$port = (int) $config_imap_port;
|
||||||
$encryption = strtolower(trim($config_imap_encryption)); // e.g. "ssl", "tls", "none"
|
$encryption = strtolower(trim($config_imap_encryption)); // e.g. "ssl", "tls", "none"
|
||||||
$username = $config_imap_username;
|
$username = $config_imap_username;
|
||||||
$password = $config_imap_password;
|
$password = $config_imap_password;
|
||||||
|
|
||||||
|
// Shared OAuth fields
|
||||||
|
$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 ?? '';
|
||||||
|
$config_mail_oauth_access_token_expires_at = $config_mail_oauth_access_token_expires_at ?? '';
|
||||||
|
|
||||||
|
$is_oauth = ($provider === 'google_oauth' || $provider === 'microsoft_oauth');
|
||||||
|
|
||||||
|
if ($provider === 'google_oauth') {
|
||||||
|
if (empty($host)) {
|
||||||
|
$host = 'imap.gmail.com';
|
||||||
|
}
|
||||||
|
if (empty($port)) {
|
||||||
|
$port = 993;
|
||||||
|
}
|
||||||
|
if (empty($encryption)) {
|
||||||
|
$encryption = 'ssl';
|
||||||
|
}
|
||||||
|
} elseif ($provider === 'microsoft_oauth') {
|
||||||
|
if (empty($host)) {
|
||||||
|
$host = 'outlook.office365.com';
|
||||||
|
}
|
||||||
|
if (empty($port)) {
|
||||||
|
$port = 993;
|
||||||
|
}
|
||||||
|
if (empty($encryption)) {
|
||||||
|
$encryption = 'ssl';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($host) || empty($port) || empty($username)) {
|
||||||
|
flash_alert("<strong>IMAP connection failed:</strong> Missing host, port, or username.", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$token_is_expired = function (?string $expires_at): bool {
|
||||||
|
if (empty($expires_at)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ts = strtotime($expires_at);
|
||||||
|
|
||||||
|
if ($ts === false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($ts - 60) <= time();
|
||||||
|
};
|
||||||
|
|
||||||
|
$http_form_post = function (string $url, array $fields): array {
|
||||||
|
$ch = curl_init($url);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields, '', '&'));
|
||||||
|
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
|
||||||
|
|
||||||
|
$raw = curl_exec($ch);
|
||||||
|
$err = curl_error($ch);
|
||||||
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'ok' => ($raw !== false && $code >= 200 && $code < 300),
|
||||||
|
'body' => $raw,
|
||||||
|
'code' => $code,
|
||||||
|
'err' => $err,
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($is_oauth) {
|
||||||
|
if (!empty($config_mail_oauth_access_token) && !$token_is_expired($config_mail_oauth_access_token_expires_at)) {
|
||||||
|
$password = $config_mail_oauth_access_token;
|
||||||
|
} else {
|
||||||
|
if (empty($config_mail_oauth_client_id) || empty($config_mail_oauth_client_secret) || empty($config_mail_oauth_refresh_token)) {
|
||||||
|
flash_alert("<strong>IMAP OAuth failed:</strong> Missing OAuth client credentials or refresh token.", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($provider === 'google_oauth') {
|
||||||
|
$response = $http_form_post('https://oauth2.googleapis.com/token', [
|
||||||
|
'client_id' => $config_mail_oauth_client_id,
|
||||||
|
'client_secret' => $config_mail_oauth_client_secret,
|
||||||
|
'refresh_token' => $config_mail_oauth_refresh_token,
|
||||||
|
'grant_type' => 'refresh_token',
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
if (empty($config_mail_oauth_tenant_id)) {
|
||||||
|
flash_alert("<strong>IMAP OAuth failed:</strong> Microsoft tenant ID is required.", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$token_url = MICROSOFT_OAUTH_BASE_URL . rawurlencode($config_mail_oauth_tenant_id) . "/oauth2/v2.0/token";
|
||||||
|
$response = $http_form_post($token_url, [
|
||||||
|
'client_id' => $config_mail_oauth_client_id,
|
||||||
|
'client_secret' => $config_mail_oauth_client_secret,
|
||||||
|
'refresh_token' => $config_mail_oauth_refresh_token,
|
||||||
|
'grant_type' => 'refresh_token',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$response['ok']) {
|
||||||
|
flash_alert("<strong>IMAP OAuth failed:</strong> Could not refresh access token.", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$json = json_decode($response['body'], true);
|
||||||
|
if (!is_array($json) || empty($json['access_token'])) {
|
||||||
|
flash_alert("<strong>IMAP OAuth failed:</strong> Token response did not include an access token.", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$password = $json['access_token'];
|
||||||
|
$expires_at = date('Y-m-d H:i:s', time() + (int)($json['expires_in'] ?? 3600));
|
||||||
|
$refresh_token_to_save = $json['refresh_token'] ?? null;
|
||||||
|
|
||||||
|
$token_esc = mysqli_real_escape_string($mysqli, $password);
|
||||||
|
$expires_at_esc = mysqli_real_escape_string($mysqli, $expires_at);
|
||||||
|
|
||||||
|
$refresh_sql = '';
|
||||||
|
if (!empty($refresh_token_to_save)) {
|
||||||
|
$refresh_token_esc = mysqli_real_escape_string($mysqli, $refresh_token_to_save);
|
||||||
|
$refresh_sql = ", config_mail_oauth_refresh_token = '{$refresh_token_esc}'";
|
||||||
|
}
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "UPDATE settings SET config_mail_oauth_access_token = '{$token_esc}', config_mail_oauth_access_token_expires_at = '{$expires_at_esc}'{$refresh_sql} WHERE company_id = 1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Build remote socket (implicit SSL vs plain TCP)
|
// Build remote socket (implicit SSL vs plain TCP)
|
||||||
$transport = 'tcp';
|
$transport = 'tcp';
|
||||||
if ($encryption === 'ssl') {
|
if ($encryption === 'ssl') {
|
||||||
@@ -178,16 +384,16 @@ if (isset($_POST['test_email_imap'])) {
|
|||||||
$remote_socket = $transport . '://' . $host . ':' . $port;
|
$remote_socket = $transport . '://' . $host . ':' . $port;
|
||||||
|
|
||||||
// Stream context (you can tighten these if you want strict validation)
|
// Stream context (you can tighten these if you want strict validation)
|
||||||
$contextOptions = [];
|
$context_options = [];
|
||||||
if (in_array($encryption, ['ssl', 'tls'], true)) {
|
if (in_array($encryption, ['ssl', 'tls'], true)) {
|
||||||
$contextOptions['ssl'] = [
|
$context_options['ssl'] = [
|
||||||
'verify_peer' => false,
|
'verify_peer' => false,
|
||||||
'verify_peer_name' => false,
|
'verify_peer_name' => false,
|
||||||
'allow_self_signed' => true,
|
'allow_self_signed' => true,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$context = stream_context_create($contextOptions);
|
$context = stream_context_create($context_options);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$errno = 0;
|
$errno = 0;
|
||||||
@@ -215,10 +421,8 @@ if (isset($_POST['test_email_imap'])) {
|
|||||||
fclose($fp);
|
fclose($fp);
|
||||||
throw new Exception("Invalid IMAP greeting: " . trim((string) $greeting));
|
throw new Exception("Invalid IMAP greeting: " . trim((string) $greeting));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If you really want STARTTLS for "tls" (port 143), you can do it here
|
// If you really want STARTTLS for "tls" (port 143), you can do it here
|
||||||
if ($encryption === 'tls' && stripos($greeting, 'STARTTLS') !== false) {
|
if ($encryption === 'tls' && stripos($greeting, 'STARTTLS') !== false) {
|
||||||
// Request STARTTLS
|
|
||||||
fwrite($fp, "A0001 STARTTLS\r\n");
|
fwrite($fp, "A0001 STARTTLS\r\n");
|
||||||
$line = fgets($fp, 1024);
|
$line = fgets($fp, 1024);
|
||||||
if ($line === false || stripos($line, 'A0001 OK') !== 0) {
|
if ($line === false || stripos($line, 'A0001 OK') !== 0) {
|
||||||
@@ -226,28 +430,31 @@ if (isset($_POST['test_email_imap'])) {
|
|||||||
throw new Exception("STARTTLS failed: " . trim((string) $line));
|
throw new Exception("STARTTLS failed: " . trim((string) $line));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable crypto on the stream
|
|
||||||
if (!stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
|
if (!stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
throw new Exception("Unable to enable TLS encryption on IMAP connection.");
|
throw new Exception("Unable to enable TLS encryption on IMAP connection.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Do LOGIN command ---
|
|
||||||
$tag = 'A0002';
|
$tag = 'A0002';
|
||||||
|
|
||||||
// Simple quoting; this may fail with some special chars in username/password.
|
if ($is_oauth) {
|
||||||
$loginCmd = sprintf(
|
$oauth_b64 = base64_encode("user={$username}\x01auth=Bearer {$password}\x01\x01");
|
||||||
|
$auth_cmd = sprintf("%s AUTHENTICATE XOAUTH2 %s\r\n", $tag, $oauth_b64);
|
||||||
|
fwrite($fp, $auth_cmd);
|
||||||
|
} else {
|
||||||
|
$login_cmd = sprintf(
|
||||||
"%s LOGIN \"%s\" \"%s\"\r\n",
|
"%s LOGIN \"%s\" \"%s\"\r\n",
|
||||||
$tag,
|
$tag,
|
||||||
addcslashes($username, "\\\""),
|
addcslashes($username, "\\\""),
|
||||||
addcslashes($password, "\\\"")
|
addcslashes($password, "\\\"")
|
||||||
);
|
);
|
||||||
|
|
||||||
fwrite($fp, $loginCmd);
|
fwrite($fp, $login_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
$success = false;
|
$success = false;
|
||||||
$errorLine = '';
|
$error_line = '';
|
||||||
|
|
||||||
while (!feof($fp)) {
|
while (!feof($fp)) {
|
||||||
$line = fgets($fp, 2048);
|
$line = fgets($fp, 2048);
|
||||||
@@ -255,12 +462,11 @@ if (isset($_POST['test_email_imap'])) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for tagged response for our LOGIN
|
|
||||||
if (strpos($line, $tag . ' ') === 0) {
|
if (strpos($line, $tag . ' ') === 0) {
|
||||||
if (stripos($line, $tag . ' OK') === 0) {
|
if (stripos($line, $tag . ' OK') === 0) {
|
||||||
$success = true;
|
$success = true;
|
||||||
} else {
|
} else {
|
||||||
$errorLine = trim($line);
|
$error_line = trim($line);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -271,12 +477,16 @@ if (isset($_POST['test_email_imap'])) {
|
|||||||
fclose($fp);
|
fclose($fp);
|
||||||
|
|
||||||
if ($success) {
|
if ($success) {
|
||||||
flash_alert("Connected successfully");
|
if ($is_oauth) {
|
||||||
|
flash_alert("Connected successfully using OAuth");
|
||||||
} else {
|
} else {
|
||||||
if (!$errorLine) {
|
flash_alert("Connected successfully");
|
||||||
$errorLine = 'Unknown IMAP authentication error';
|
|
||||||
}
|
}
|
||||||
throw new Exception($errorLine);
|
} else {
|
||||||
|
if (!$error_line) {
|
||||||
|
$error_line = 'Unknown IMAP authentication error';
|
||||||
|
}
|
||||||
|
throw new Exception($error_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@@ -285,3 +495,88 @@ if (isset($_POST['test_email_imap'])) {
|
|||||||
|
|
||||||
redirect();
|
redirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (isset($_POST['test_oauth_token_refresh'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
|
$provider = sanitizeInput($_POST['oauth_provider'] ?? '');
|
||||||
|
|
||||||
|
if ($provider !== 'google_oauth' && $provider !== 'microsoft_oauth') {
|
||||||
|
flash_alert("OAuth token test failed: unsupported provider.", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$oauth_client_id = sanitizeInput($config_mail_oauth_client_id ?? '');
|
||||||
|
$oauth_client_secret = sanitizeInput($config_mail_oauth_client_secret ?? '');
|
||||||
|
$oauth_tenant_id = sanitizeInput($config_mail_oauth_tenant_id ?? '');
|
||||||
|
$oauth_refresh_token = sanitizeInput($config_mail_oauth_refresh_token ?? '');
|
||||||
|
|
||||||
|
if (empty($oauth_client_id) || empty($oauth_client_secret) || empty($oauth_refresh_token)) {
|
||||||
|
flash_alert("OAuth token test failed: missing client ID, client secret, or refresh token.", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($provider === 'microsoft_oauth' && empty($oauth_tenant_id)) {
|
||||||
|
flash_alert("OAuth token test failed: Microsoft tenant ID is required.", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$token_url = 'https://oauth2.googleapis.com/token';
|
||||||
|
if ($provider === 'microsoft_oauth') {
|
||||||
|
$token_url = MICROSOFT_OAUTH_BASE_URL . rawurlencode($oauth_tenant_id) . "/oauth2/v2.0/token";
|
||||||
|
}
|
||||||
|
|
||||||
|
$post_fields = http_build_query([
|
||||||
|
'client_id' => $oauth_client_id,
|
||||||
|
'client_secret' => $oauth_client_secret,
|
||||||
|
'refresh_token' => $oauth_refresh_token,
|
||||||
|
'grant_type' => 'refresh_token',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$ch = curl_init($token_url);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
|
||||||
|
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
|
||||||
|
|
||||||
|
$raw_body = curl_exec($ch);
|
||||||
|
$curl_err = curl_error($ch);
|
||||||
|
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
if ($raw_body === false || $http_code < 200 || $http_code >= 300) {
|
||||||
|
$err_msg = !empty($curl_err) ? $curl_err : "HTTP $http_code";
|
||||||
|
flash_alert("OAuth token test failed: $err_msg", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$json = json_decode($raw_body, true);
|
||||||
|
|
||||||
|
if (!is_array($json) || empty($json['access_token'])) {
|
||||||
|
flash_alert("OAuth token test failed: access token missing in provider response.", 'error');
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_access_token = sanitizeInput($json['access_token']);
|
||||||
|
$new_expires_at = date('Y-m-d H:i:s', time() + (int)($json['expires_in'] ?? 3600));
|
||||||
|
$new_refresh_token = !empty($json['refresh_token']) ? sanitizeInput($json['refresh_token']) : '';
|
||||||
|
|
||||||
|
$new_access_token_esc = mysqli_real_escape_string($mysqli, $new_access_token);
|
||||||
|
$new_expires_at_esc = mysqli_real_escape_string($mysqli, $new_expires_at);
|
||||||
|
|
||||||
|
$refresh_sql = '';
|
||||||
|
if (!empty($new_refresh_token)) {
|
||||||
|
$new_refresh_token_esc = mysqli_real_escape_string($mysqli, $new_refresh_token);
|
||||||
|
$refresh_sql = ", config_mail_oauth_refresh_token = '$new_refresh_token_esc'";
|
||||||
|
}
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "UPDATE settings SET config_mail_oauth_access_token = '$new_access_token_esc', config_mail_oauth_access_token_expires_at = '$new_expires_at_esc'$refresh_sql WHERE company_id = 1");
|
||||||
|
|
||||||
|
$provider_label = $provider === 'microsoft_oauth' ? 'Microsoft 365' : 'Google Workspace';
|
||||||
|
logAction("Settings", "Edit", "$session_name tested OAuth token refresh for $provider_label mail settings");
|
||||||
|
|
||||||
|
flash_alert("OAuth token refresh successful for $provider_label. Access token expires at $new_expires_at.");
|
||||||
|
redirect();
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
|||||||
|
|
||||||
if (isset($_POST['edit_module_settings'])) {
|
if (isset($_POST['edit_module_settings'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$config_module_enable_itdoc = intval($_POST['config_module_enable_itdoc'] ?? 0);
|
$config_module_enable_itdoc = intval($_POST['config_module_enable_itdoc'] ?? 0);
|
||||||
$config_module_enable_ticketing = intval($_POST['config_module_enable_ticketing'] ?? 0);
|
$config_module_enable_ticketing = intval($_POST['config_module_enable_ticketing'] ?? 0);
|
||||||
$config_module_enable_accounting = intval($_POST['config_module_enable_accounting'] ?? 0);
|
$config_module_enable_accounting = intval($_POST['config_module_enable_accounting'] ?? 0);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ if (isset($_GET['stripe_remove_pm'])) {
|
|||||||
// Remove Auto Pay on recurring invoices that are stripe
|
// Remove Auto Pay on recurring invoices that are stripe
|
||||||
$sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id");
|
$sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id");
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql_recurring_invoices)) {
|
while ($row = mysqli_fetch_assoc($sql_recurring_invoices)) {
|
||||||
$recurring_invoice_id = intval($row['recurring_invoice_id']);
|
$recurring_invoice_id = intval($row['recurring_invoice_id']);
|
||||||
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id");
|
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id");
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ if (isset($_GET['stripe_reset_customer'])) {
|
|||||||
// Remove Auto Pay on recurring invoices that are stripe
|
// Remove Auto Pay on recurring invoices that are stripe
|
||||||
$sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id");
|
$sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id");
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql_recurring_invoices)) {
|
while ($row = mysqli_fetch_assoc($sql_recurring_invoices)) {
|
||||||
$recurring_invoice_id = intval($row['recurring_invoice_id']);
|
$recurring_invoice_id = intval($row['recurring_invoice_id']);
|
||||||
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id");
|
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ if (isset($_POST['edit_favicon_settings'])) {
|
|||||||
|
|
||||||
if (isset($_GET['reset_favicon'])) {
|
if (isset($_GET['reset_favicon'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
if (file_exists("../uploads/favicon.ico")) {
|
if (file_exists("../uploads/favicon.ico")) {
|
||||||
unlink("../uploads/favicon.ico");
|
unlink("../uploads/favicon.ico");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
|||||||
|
|
||||||
if (isset($_POST['edit_ticket_settings'])) {
|
if (isset($_POST['edit_ticket_settings'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$config_ticket_prefix = sanitizeInput($_POST['config_ticket_prefix']);
|
$config_ticket_prefix = sanitizeInput($_POST['config_ticket_prefix']);
|
||||||
$config_ticket_next_number = intval($_POST['config_ticket_next_number']);
|
$config_ticket_next_number = intval($_POST['config_ticket_next_number']);
|
||||||
$config_ticket_email_parse = intval($_POST['config_ticket_email_parse'] ?? 0);
|
$config_ticket_email_parse = intval($_POST['config_ticket_email_parse'] ?? 0);
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
|||||||
|
|
||||||
if (isset($_POST['add_software_template'])) {
|
if (isset($_POST['add_software_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$version = sanitizeInput($_POST['version']);
|
$version = sanitizeInput($_POST['version']);
|
||||||
$description = sanitizeInput($_POST['description']);
|
$description = sanitizeInput($_POST['description']);
|
||||||
@@ -27,6 +29,8 @@ if (isset($_POST['add_software_template'])) {
|
|||||||
|
|
||||||
if (isset($_POST['edit_software_template'])) {
|
if (isset($_POST['edit_software_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$software_template_id = intval($_POST['software_template_id']);
|
$software_template_id = intval($_POST['software_template_id']);
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$version = sanitizeInput($_POST['version']);
|
$version = sanitizeInput($_POST['version']);
|
||||||
@@ -47,11 +51,13 @@ if (isset($_POST['edit_software_template'])) {
|
|||||||
|
|
||||||
if (isset($_GET['delete_software_template'])) {
|
if (isset($_GET['delete_software_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$software_template_id = intval($_GET['delete_software_template']);
|
$software_template_id = intval($_GET['delete_software_template']);
|
||||||
|
|
||||||
// Get Software Template Name for logging and alert message
|
// Get Software Template Name for logging and alert message
|
||||||
$sql = mysqli_query($mysqli,"SELECT software_template_name FROM software_templates WHERE software_template_id = $software_template_id");
|
$sql = mysqli_query($mysqli,"SELECT software_template_name FROM software_templates WHERE software_template_id = $software_template_id");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$software_template_name = sanitizeInput($row['software_template_name']);
|
$software_template_name = sanitizeInput($row['software_template_name']);
|
||||||
|
|
||||||
mysqli_query($mysqli,"DELETE FROM software_templates WHERE software_template_id = $software_template_id");
|
mysqli_query($mysqli,"DELETE FROM software_templates WHERE software_template_id = $software_template_id");
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
|||||||
|
|
||||||
if (isset($_POST['add_tag'])) {
|
if (isset($_POST['add_tag'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
require_once 'tag_model.php';
|
require_once 'tag_model.php';
|
||||||
|
|
||||||
mysqli_query($mysqli,"INSERT INTO tags SET tag_name = '$name', tag_type = $type, tag_color = '$color', tag_icon = '$icon'");
|
mysqli_query($mysqli,"INSERT INTO tags SET tag_name = '$name', tag_type = $type, tag_color = '$color', tag_icon = '$icon'");
|
||||||
@@ -24,6 +26,8 @@ if (isset($_POST['add_tag'])) {
|
|||||||
|
|
||||||
if (isset($_POST['edit_tag'])) {
|
if (isset($_POST['edit_tag'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
require_once 'post/tag_model.php';
|
require_once 'post/tag_model.php';
|
||||||
|
|
||||||
$tag_id = intval($_POST['tag_id']);
|
$tag_id = intval($_POST['tag_id']);
|
||||||
@@ -40,6 +44,8 @@ if (isset($_POST['edit_tag'])) {
|
|||||||
|
|
||||||
if (isset($_GET['delete_tag'])) {
|
if (isset($_GET['delete_tag'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$tag_id = intval($_GET['delete_tag']);
|
$tag_id = intval($_GET['delete_tag']);
|
||||||
|
|
||||||
$tag_name = sanitizeInput(getFieldById('tags', $tag_id, 'tag_name'));
|
$tag_name = sanitizeInput(getFieldById('tags', $tag_id, 'tag_name'));
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
|||||||
if (isset($_POST['add_tax'])) {
|
if (isset($_POST['add_tax'])) {
|
||||||
|
|
||||||
validateCSRFToken($_POST['csrf_token']);
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$percent = floatval($_POST['percent']);
|
$percent = floatval($_POST['percent']);
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ if (isset($_POST['add_tax'])) {
|
|||||||
if (isset($_POST['edit_tax'])) {
|
if (isset($_POST['edit_tax'])) {
|
||||||
|
|
||||||
validateCSRFToken($_POST['csrf_token']);
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$tax_id = intval($_POST['tax_id']);
|
$tax_id = intval($_POST['tax_id']);
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$percent = floatval($_POST['percent']);
|
$percent = floatval($_POST['percent']);
|
||||||
@@ -44,6 +46,7 @@ if (isset($_POST['edit_tax'])) {
|
|||||||
if (isset($_GET['archive_tax'])) {
|
if (isset($_GET['archive_tax'])) {
|
||||||
|
|
||||||
validateCSRFToken($_GET['csrf_token']);
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$tax_id = intval($_GET['archive_tax']);
|
$tax_id = intval($_GET['archive_tax']);
|
||||||
|
|
||||||
$tax_name = sanitizeInput(getFieldById('taxes', $tax_id, 'tax_name'));
|
$tax_name = sanitizeInput(getFieldById('taxes', $tax_id, 'tax_name'));
|
||||||
@@ -60,6 +63,8 @@ if (isset($_GET['archive_tax'])) {
|
|||||||
|
|
||||||
if (isset($_GET['delete_tax'])) {
|
if (isset($_GET['delete_tax'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$tax_id = intval($_GET['delete_tax']);
|
$tax_id = intval($_GET['delete_tax']);
|
||||||
|
|
||||||
$tax_name = sanitizeInput(getFieldById('taxes', $tax_id, 'tax_name'));
|
$tax_name = sanitizeInput(getFieldById('taxes', $tax_id, 'tax_name'));
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
|
|||||||
|
|
||||||
if (isset($_POST['add_ticket_status'])) {
|
if (isset($_POST['add_ticket_status'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$color = sanitizeInput($_POST['color']);
|
$color = sanitizeInput($_POST['color']);
|
||||||
|
|
||||||
@@ -21,6 +23,8 @@ if (isset($_POST['add_ticket_status'])) {
|
|||||||
|
|
||||||
if (isset($_POST['edit_ticket_status'])) {
|
if (isset($_POST['edit_ticket_status'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$ticket_status_id = intval($_POST['ticket_status_id']);
|
$ticket_status_id = intval($_POST['ticket_status_id']);
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$color = sanitizeInput($_POST['color']);
|
$color = sanitizeInput($_POST['color']);
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ require_once '../agent/post/task.php';
|
|||||||
|
|
||||||
if (isset($_POST['add_ticket_template'])) {
|
if (isset($_POST['add_ticket_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$description = sanitizeInput($_POST['description']);
|
$description = sanitizeInput($_POST['description']);
|
||||||
$subject = sanitizeInput($_POST['subject']);
|
$subject = sanitizeInput($_POST['subject']);
|
||||||
@@ -34,6 +36,8 @@ if (isset($_POST['add_ticket_template'])) {
|
|||||||
|
|
||||||
if (isset($_POST['edit_ticket_template'])) {
|
if (isset($_POST['edit_ticket_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$ticket_template_id = intval($_POST['ticket_template_id']);
|
$ticket_template_id = intval($_POST['ticket_template_id']);
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$description = sanitizeInput($_POST['description']);
|
$description = sanitizeInput($_POST['description']);
|
||||||
@@ -52,6 +56,8 @@ if (isset($_POST['edit_ticket_template'])) {
|
|||||||
|
|
||||||
if (isset($_GET['delete_ticket_template'])) {
|
if (isset($_GET['delete_ticket_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$ticket_template_id = intval($_GET['delete_ticket_template']);
|
$ticket_template_id = intval($_GET['delete_ticket_template']);
|
||||||
|
|
||||||
$ticket_template_name = sanitizeInput(getFieldById('ticket_templates', $ticket_template_id, 'ticket_template_name'));
|
$ticket_template_name = sanitizeInput(getFieldById('ticket_templates', $ticket_template_id, 'ticket_template_name'));
|
||||||
@@ -72,6 +78,8 @@ if (isset($_GET['delete_ticket_template'])) {
|
|||||||
|
|
||||||
if (isset($_POST['add_ticket_template_task'])) {
|
if (isset($_POST['add_ticket_template_task'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$ticket_template_id = intval($_POST['ticket_template_id']);
|
$ticket_template_id = intval($_POST['ticket_template_id']);
|
||||||
$task_name = sanitizeInput($_POST['task_name']);
|
$task_name = sanitizeInput($_POST['task_name']);
|
||||||
|
|
||||||
@@ -89,6 +97,8 @@ if (isset($_POST['add_ticket_template_task'])) {
|
|||||||
|
|
||||||
if (isset($_GET['delete_task_template'])) {
|
if (isset($_GET['delete_task_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$task_template_id = intval($_GET['delete_task_template']);
|
$task_template_id = intval($_GET['delete_task_template']);
|
||||||
|
|
||||||
$task_template_name = sanitizeInput(getFieldById('tags', $task_template_id, 'task_template_name'));
|
$task_template_name = sanitizeInput(getFieldById('tags', $task_template_id, 'task_template_name'));
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ if (isset($_GET['update'])) {
|
|||||||
if ($config_telemetry > 0 OR $config_telemetry = 2) {
|
if ($config_telemetry > 0 OR $config_telemetry = 2) {
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
|
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
|
|
||||||
$company_name = sanitizeInput($row['company_name']);
|
$company_name = sanitizeInput($row['company_name']);
|
||||||
$website = sanitizeInput($row['company_website']);
|
$website = sanitizeInput($row['company_website']);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ if (isset($_POST['add_user'])) {
|
|||||||
mysqli_query($mysqli, "INSERT INTO user_settings SET user_id = $user_id, user_config_force_mfa = $force_mfa");
|
mysqli_query($mysqli, "INSERT INTO user_settings SET user_id = $user_id, user_config_force_mfa = $force_mfa");
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
|
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$company_name = sanitizeInput($row['company_name']);
|
$company_name = sanitizeInput($row['company_name']);
|
||||||
|
|
||||||
// Sanitize Config vars from load_global_settings.php
|
// Sanitize Config vars from load_global_settings.php
|
||||||
@@ -118,7 +118,7 @@ if (isset($_POST['edit_user'])) {
|
|||||||
|
|
||||||
// Get current Avatar
|
// Get current Avatar
|
||||||
$sql = mysqli_query($mysqli, "SELECT user_avatar FROM users WHERE user_id = $user_id");
|
$sql = mysqli_query($mysqli, "SELECT user_avatar FROM users WHERE user_id = $user_id");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$existing_file_name = sanitizeInput($row['user_avatar']);
|
$existing_file_name = sanitizeInput($row['user_avatar']);
|
||||||
|
|
||||||
$extended_log_description = '';
|
$extended_log_description = '';
|
||||||
@@ -353,7 +353,7 @@ if (isset($_POST['ir_reset_user_password'])) {
|
|||||||
// Confirm logged-in user password, for security
|
// Confirm logged-in user password, for security
|
||||||
$admin_password = $_POST['admin_password'];
|
$admin_password = $_POST['admin_password'];
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $session_user_id");
|
$sql = mysqli_query($mysqli, "SELECT * FROM users WHERE user_id = $session_user_id");
|
||||||
$userRow = mysqli_fetch_array($sql);
|
$userRow = mysqli_fetch_assoc($sql);
|
||||||
|
|
||||||
if (!password_verify($admin_password, $userRow['user_password'])) {
|
if (!password_verify($admin_password, $userRow['user_password'])) {
|
||||||
flash_alert("Incorrect password.", 'error');
|
flash_alert("Incorrect password.", 'error');
|
||||||
@@ -364,7 +364,7 @@ if (isset($_POST['ir_reset_user_password'])) {
|
|||||||
$sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE (user_archived_at IS NULL AND user_id != $session_user_id)");
|
$sql_users = mysqli_query($mysqli, "SELECT * FROM users WHERE (user_archived_at IS NULL AND user_id != $session_user_id)");
|
||||||
|
|
||||||
// Reset passwords
|
// Reset passwords
|
||||||
while ($row = mysqli_fetch_array($sql_users)) {
|
while ($row = mysqli_fetch_assoc($sql_users)) {
|
||||||
$user_id = intval($row['user_id']);
|
$user_id = intval($row['user_id']);
|
||||||
$user_email = sanitizeInput($row['user_email']);
|
$user_email = sanitizeInput($row['user_email']);
|
||||||
$new_password = randomString();
|
$new_password = randomString();
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ require_once '../agent/post/vendor.php';
|
|||||||
|
|
||||||
if (isset($_POST['add_vendor_template'])) {
|
if (isset($_POST['add_vendor_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$description = sanitizeInput($_POST['description']);
|
$description = sanitizeInput($_POST['description']);
|
||||||
$account_number = sanitizeInput($_POST['account_number']);
|
$account_number = sanitizeInput($_POST['account_number']);
|
||||||
@@ -37,6 +39,8 @@ if (isset($_POST['add_vendor_template'])) {
|
|||||||
|
|
||||||
if (isset($_POST['edit_vendor_template'])) {
|
if (isset($_POST['edit_vendor_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
$vendor_template_id = intval($_POST['vendor_template_id']);
|
$vendor_template_id = intval($_POST['vendor_template_id']);
|
||||||
$name = sanitizeInput($_POST['name']);
|
$name = sanitizeInput($_POST['name']);
|
||||||
$description = sanitizeInput($_POST['description']);
|
$description = sanitizeInput($_POST['description']);
|
||||||
@@ -141,6 +145,8 @@ if (isset($_POST['edit_vendor_template'])) {
|
|||||||
|
|
||||||
if (isset($_GET['delete_vendor_template'])) {
|
if (isset($_GET['delete_vendor_template'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
$vendor_template_id = intval($_GET['delete_vendor_template']);
|
$vendor_template_id = intval($_GET['delete_vendor_template']);
|
||||||
|
|
||||||
$vendor_template_name = sanitizeInput(getFieldById('vendor_templates', $vendor_template_id, 'vendor_template_name'));
|
$vendor_template_name = sanitizeInput(getFieldById('vendor_templates', $vendor_template_id, 'vendor_template_name'));
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while($row = mysqli_fetch_array($sql)){
|
while($row = mysqli_fetch_assoc($sql)){
|
||||||
$project_template_id = intval($row['project_template_id']);
|
$project_template_id = intval($row['project_template_id']);
|
||||||
$project_template_name = nullable_htmlentities($row['project_template_name']);
|
$project_template_name = nullable_htmlentities($row['project_template_name']);
|
||||||
$project_template_description = nullable_htmlentities($row['project_template_description']);
|
$project_template_description = nullable_htmlentities($row['project_template_description']);
|
||||||
@@ -87,16 +87,16 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a class="text-dark ajax-modal" href="#" data-modal-url="modals/project_template/project_template_edit.php?project_template_id=<?= $project_template_id ?>">
|
<a class="text-dark" href="project_template_details.php?project_template_id=<?= $project_template_id ?>">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<i class="fa fa-fw fa-2x fa-project-diagram mr-3"></i>
|
<i class="fa fa-fw fa-2x fa-project-diagram mr-3"></i>
|
||||||
<div class="media-body">
|
<div class="media-body">
|
||||||
<div>
|
<div>
|
||||||
<a href="project_template_details.php?project_template_id=<?php echo $project_template_id; ?>">
|
<?= $project_template_name ?>
|
||||||
<?php echo $project_template_name; ?>
|
</div>
|
||||||
</a>
|
<div>
|
||||||
|
<small class="text-secondary"><?= $project_template_description ?></small>
|
||||||
</div>
|
</div>
|
||||||
<div><small class="text-secondary"><?php echo $project_template_description; ?></small></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
@@ -114,7 +114,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
</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 confirm-link" href="post.php?delete_project_template=<?php echo $project_template_id; ?>">
|
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_project_template=<?php echo $project_template_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<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 } ?>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql_project_templates);
|
$row = mysqli_fetch_assoc($sql_project_templates);
|
||||||
|
|
||||||
$project_template_name = nullable_htmlentities($row['project_template_name']);
|
$project_template_name = nullable_htmlentities($row['project_template_name']);
|
||||||
$project_template_description = nullable_htmlentities($row['project_template_description']);
|
$project_template_description = nullable_htmlentities($row['project_template_description']);
|
||||||
@@ -104,13 +104,13 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
</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 confirm-link" href="post.php?archive_project_template=<?php echo $project_template_id; ?>">
|
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?archive_project_template=<?php echo $project_template_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<i class="fas fa-fw fa-archive mr-2"></i>Archive (not yet implemented)
|
<i class="fas fa-fw fa-archive mr-2"></i>Archive (not yet implemented)
|
||||||
</a>
|
</a>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<?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 confirm-link" href="post.php?delete_project_template=<?php echo $project_template_id; ?>">
|
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_project_template=<?php echo $project_template_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<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 } ?>
|
||||||
@@ -130,10 +130,9 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
|
|
||||||
<h5 class="text-secondary"><i class="fa fa-fw fa-life-ring mr-2"></i>Project Ticket Templates</h5>
|
<h5 class="text-secondary"><i class="fa fa-fw fa-life-ring mr-2"></i>Project Ticket Templates</h5>
|
||||||
<div class="table-responsive-sm">
|
<div class="table-responsive-sm">
|
||||||
<table class="table table-striped table-borderless table-hover">
|
<table class="table table-striped table-borderless table-hover" id="ticket_templates">
|
||||||
<thead class="text-dark">
|
<thead class="text-dark">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Order</th>
|
|
||||||
<th>Template Name</th>
|
<th>Template Name</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<th>Ticket Subject</th>
|
<th>Ticket Subject</th>
|
||||||
@@ -143,7 +142,7 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql_ticket_templates)) {
|
while ($row = mysqli_fetch_assoc($sql_ticket_templates)) {
|
||||||
$ticket_template_id = intval($row['ticket_template_id']);
|
$ticket_template_id = intval($row['ticket_template_id']);
|
||||||
$ticket_template_order = intval($row['ticket_template_order']);
|
$ticket_template_order = intval($row['ticket_template_order']);
|
||||||
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
|
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
|
||||||
@@ -154,16 +153,9 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<tr>
|
<tr data-task-id="<?php echo $ticket_template_id; ?>">
|
||||||
<td class="pr-0">
|
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
|
||||||
<input type="hidden" name="edit_ticket_template_order">
|
|
||||||
<input type="hidden" name="project_template_id" value="<?php echo $project_template_id; ?>">
|
|
||||||
<input type="hidden" name="ticket_template_id" value="<?php echo $ticket_template_id; ?>">
|
|
||||||
<input type="text" class="form-control pr-0" onchange="this.form.submit()" name="order" value="<?php echo $ticket_template_order; ?>">
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
|
<a href="#" class="drag-handle"><i class="fas fa-bars text-muted mr-2"></i></a>
|
||||||
<a href="ticket_template_details.php?ticket_template_id=<?php echo $ticket_template_id; ?>">
|
<a href="ticket_template_details.php?ticket_template_id=<?php echo $ticket_template_id; ?>">
|
||||||
<?php echo $ticket_template_name; ?>
|
<?php echo $ticket_template_name; ?>
|
||||||
</a>
|
</a>
|
||||||
@@ -172,6 +164,7 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
<td><?php echo $ticket_template_subject; ?></td>
|
<td><?php echo $ticket_template_subject; ?></td>
|
||||||
<td>
|
<td>
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="project_template_id" value="<?php echo $project_template_id; ?>">
|
<input type="hidden" name="project_template_id" value="<?php echo $project_template_id; ?>">
|
||||||
<input type="hidden" name="ticket_template_id" value="<?php echo $ticket_template_id; ?>">
|
<input type="hidden" name="ticket_template_id" value="<?php echo $ticket_template_id; ?>">
|
||||||
<button type="submit" class="btn btn-default btn-sm confirm-link"
|
<button type="submit" class="btn btn-default btn-sm confirm-link"
|
||||||
@@ -199,7 +192,7 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
<h5 class="text-secondary"><i class="fas fa-fw fa-tasks mr-2"></i>Project Task Templates</h5>
|
<h5 class="text-secondary"><i class="fas fa-fw fa-tasks mr-2"></i>Project Task Templates</h5>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<?php
|
<?php
|
||||||
while($row = mysqli_fetch_array($sql_task_templates)){
|
while($row = mysqli_fetch_assoc($sql_task_templates)){
|
||||||
$task_template_id = intval($row['task_template_id']);
|
$task_template_id = intval($row['task_template_id']);
|
||||||
$task_template_name = nullable_htmlentities($row['task_template_name']);
|
$task_template_name = nullable_htmlentities($row['task_template_name']);
|
||||||
?>
|
?>
|
||||||
@@ -219,6 +212,28 @@ if (isset($_GET['project_template_id'])) {
|
|||||||
|
|
||||||
</div> <!-- End row -->
|
</div> <!-- End row -->
|
||||||
|
|
||||||
|
<script src="../plugins/SortableJS/Sortable.min.js"></script>
|
||||||
|
<script>
|
||||||
|
new Sortable(document.querySelector('table#ticket_templates tbody'), {
|
||||||
|
handle: '.drag-handle',
|
||||||
|
animation: 150,
|
||||||
|
onEnd: function (evt) {
|
||||||
|
const rows = document.querySelectorAll('table#ticket_templates tbody tr');
|
||||||
|
const positions = Array.from(rows).map((row, index) => ({
|
||||||
|
id: row.dataset.taskId,
|
||||||
|
order: index
|
||||||
|
}));
|
||||||
|
|
||||||
|
$.post('/agent/ajax.php', {
|
||||||
|
update_project_template_ticket_order: true,
|
||||||
|
csrf_token: '<?= $_SESSION['csrf_token'] ?>',
|
||||||
|
project_template_id: <?php echo $project_template_id; ?>,
|
||||||
|
positions: positions
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ $sql = mysqli_query(
|
|||||||
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
$num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<div class="alert alert-info text-center"><strong>Roles are still in development. Permissions may not be fully enforced.</strong></div>
|
|
||||||
|
|
||||||
<div class="card card-dark">
|
<div class="card card-dark">
|
||||||
<div class="card-header py-2">
|
<div class="card-header py-2">
|
||||||
@@ -65,7 +64,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$role_id = intval($row['role_id']);
|
$role_id = intval($row['role_id']);
|
||||||
$role_name = nullable_htmlentities($row['role_name']);
|
$role_name = nullable_htmlentities($row['role_name']);
|
||||||
$role_description = nullable_htmlentities($row['role_description']);
|
$role_description = nullable_htmlentities($row['role_description']);
|
||||||
@@ -95,10 +94,15 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="#" <?php if ($role_id !== 3) { ?> class="ajax-modal" data-modal-url="modals/role/role_edit.php?id=<?= $role_id ?>" <?php } ?>>
|
<a class="<?php if ($role_id !== 3) { ?> ajax-modal" data-modal-url="modals/role/role_edit.php?id=<?= $role_id ?>" <?php } ?> href="#">
|
||||||
<strong class="text-dark"><?php echo $role_name; ?></strong>
|
<div class="media">
|
||||||
|
<i class="fas fa-fw fa-2x fa-user-shield text-dark mr-2"></i>
|
||||||
|
<div class="media-body">
|
||||||
|
<div><?= $role_name ?></div>
|
||||||
|
<div><small class="text-secondary"><?= $role_description ?></small></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<div class="text-secondary"><?php echo $role_description; ?></div>
|
|
||||||
</td>
|
</td>
|
||||||
<td><?php echo $user_names_string; ?></td>
|
<td><?php echo $user_names_string; ?></td>
|
||||||
<td><?php echo $role_admin ? 'Yes' : 'No' ; ?></td>
|
<td><?php echo $role_admin ? 'Yes' : 'No' ; ?></td>
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$saved_payment_id = intval($row['saved_payment_id']);
|
$saved_payment_id = intval($row['saved_payment_id']);
|
||||||
$client_id = intval($row['saved_payment_client_id']);
|
$client_id = intval($row['saved_payment_client_id']);
|
||||||
$client_name = nullable_htmlentities($row['client_name']);
|
$client_name = nullable_htmlentities($row['client_name']);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
|
$sql = mysqli_query($mysqli,"SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$company_id = intval($row['company_id']);
|
$company_id = intval($row['company_id']);
|
||||||
$company_name = nullable_htmlentities($row['company_name']);
|
$company_name = nullable_htmlentities($row['company_name']);
|
||||||
$company_country = nullable_htmlentities($row['company_country']);
|
$company_country = nullable_htmlentities($row['company_country']);
|
||||||
@@ -37,7 +37,7 @@ $company_initials = nullable_htmlentities(initials($company_name));
|
|||||||
<div class="col-md-3 text-center">
|
<div class="col-md-3 text-center">
|
||||||
<?php if ($company_logo) { ?>
|
<?php if ($company_logo) { ?>
|
||||||
<img class="img-thumbnail" src="<?php echo "../uploads/settings/$company_logo"; ?>">
|
<img class="img-thumbnail" src="<?php echo "../uploads/settings/$company_logo"; ?>">
|
||||||
<a href="post.php?remove_company_logo" class="btn btn-outline-danger btn-block">Remove Logo</a>
|
<a href="post.php?remove_company_logo&csrf_token=<?= $_SESSION['csrf_token'] ?>" class="btn btn-outline-danger btn-block">Remove Logo</a>
|
||||||
<hr>
|
<hr>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$custom_field_id = intval($row['custom_field_id']);
|
$custom_field_id = intval($row['custom_field_id']);
|
||||||
$custom_field_label = nullable_htmlentities($row['custom_field_label']);
|
$custom_field_label = nullable_htmlentities($row['custom_field_label']);
|
||||||
$custom_field_type = nullable_htmlentities($row['custom_field_type']);
|
$custom_field_type = nullable_htmlentities($row['custom_field_type']);
|
||||||
@@ -118,4 +118,3 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
require_once "custom_field_create_modal.php";
|
require_once "custom_field_create_modal.php";
|
||||||
|
|
||||||
require_once "../includes/footer.php";
|
require_once "../includes/footer.php";
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM calendars ORDER BY calendar_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM calendars ORDER BY calendar_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$calendar_id = intval($row['calendar_id']);
|
$calendar_id = intval($row['calendar_id']);
|
||||||
$calendar_name = nullable_htmlentities($row['calendar_name']); ?>
|
$calendar_name = nullable_htmlentities($row['calendar_name']); ?>
|
||||||
<option <?php if ($config_default_calendar == $calendar_id) {
|
<option <?php if ($config_default_calendar == $calendar_id) {
|
||||||
@@ -65,7 +65,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$account_id = intval($row['account_id']);
|
$account_id = intval($row['account_id']);
|
||||||
$account_name = nullable_htmlentities($row['account_name']); ?>
|
$account_name = nullable_htmlentities($row['account_name']); ?>
|
||||||
<option <?php if ($config_default_transfer_from_account == $account_id) {
|
<option <?php if ($config_default_transfer_from_account == $account_id) {
|
||||||
@@ -88,7 +88,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$account_id = intval($row['account_id']);
|
$account_id = intval($row['account_id']);
|
||||||
$account_name = nullable_htmlentities($row['account_name']); ?>
|
$account_name = nullable_htmlentities($row['account_name']); ?>
|
||||||
<option <?php if ($config_default_transfer_to_account == $account_id) {
|
<option <?php if ($config_default_transfer_to_account == $account_id) {
|
||||||
@@ -111,7 +111,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$account_id = intval($row['account_id']);
|
$account_id = intval($row['account_id']);
|
||||||
$account_name = nullable_htmlentities($row['account_name']); ?>
|
$account_name = nullable_htmlentities($row['account_name']); ?>
|
||||||
<option <?php if ($config_default_payment_account == $account_id) {
|
<option <?php if ($config_default_payment_account == $account_id) {
|
||||||
@@ -136,7 +136,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM accounts WHERE account_archived_at IS NULL ORDER BY account_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$account_id = intval($row['account_id']);
|
$account_id = intval($row['account_id']);
|
||||||
$account_name = nullable_htmlentities($row['account_name']); ?>
|
$account_name = nullable_htmlentities($row['account_name']); ?>
|
||||||
<option <?php if ($config_default_expense_account == $account_id) {
|
<option <?php if ($config_default_expense_account == $account_id) {
|
||||||
@@ -159,7 +159,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$payment_method = nullable_htmlentities($row['category_name']); ?>
|
$payment_method = nullable_htmlentities($row['category_name']); ?>
|
||||||
<option <?php if ($config_default_payment_method == $payment_method) {
|
<option <?php if ($config_default_payment_method == $payment_method) {
|
||||||
echo "selected";
|
echo "selected";
|
||||||
@@ -181,7 +181,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
|
$sql = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' ORDER BY category_name ASC");
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$payment_method = nullable_htmlentities($row['category_name']); ?>
|
$payment_method = nullable_htmlentities($row['category_name']); ?>
|
||||||
<option <?php if ($config_default_expense_payment_method == $payment_method) {
|
<option <?php if ($config_default_expense_payment_method == $payment_method) {
|
||||||
echo "selected";
|
echo "selected";
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
|
$sql = mysqli_query($mysqli,"SELECT * FROM companies, settings WHERE companies.company_id = settings.company_id AND companies.company_id = 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$company_locale = nullable_htmlentities($row['company_locale']);
|
$company_locale = nullable_htmlentities($row['company_locale']);
|
||||||
$company_currency = nullable_htmlentities($row['company_currency']);
|
$company_currency = nullable_htmlentities($row['company_currency']);
|
||||||
|
|
||||||
@@ -76,4 +76,3 @@ $timezones = DateTimeZone::listIdentifiers();
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
require_once "../includes/footer.php";
|
require_once "../includes/footer.php";
|
||||||
|
|
||||||
|
|||||||
@@ -243,6 +243,32 @@ require_once "includes/inc_all_admin.php";
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if (defined('BASE_URL') && !empty(BASE_URL)) {
|
||||||
|
$mail_oauth_callback_uri = rtrim((string) BASE_URL, '/') . '/admin/oauth_microsoft_mail_callback.php';
|
||||||
|
} else {
|
||||||
|
$mail_oauth_callback_uri = 'https://' . rtrim((string) $config_base_url, '/') . '/admin/oauth_microsoft_mail_callback.php';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Microsoft OAuth Connect (Web)</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text"><i class="fa fa-fw fa-link"></i></span>
|
||||||
|
</div>
|
||||||
|
<input type="text" class="form-control" readonly value="<?php echo htmlspecialchars($mail_oauth_callback_uri); ?>">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="submit" name="oauth_connect_microsoft_mail" class="btn btn-outline-primary">
|
||||||
|
<i class="fab fa-fw fa-microsoft mr-2"></i>Connect Microsoft 365
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<small class="text-secondary">
|
||||||
|
Add this callback URI in Entra App Registration, then click Connect to authorize and store refresh token automatically.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
<hr>
|
<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>
|
<button type="submit" name="edit_mail_imap_settings" class="btn btn-primary text-bold"><i class="fas fa-check mr-2"></i>Save</button>
|
||||||
@@ -359,7 +385,22 @@ require_once "includes/inc_all_admin.php";
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (!empty($config_smtp_host) && !empty($config_smtp_port) && !empty($config_mail_from_email) && !empty($config_mail_from_name)) { ?>
|
<?php
|
||||||
|
$smtp_standard_ready = !empty($config_smtp_host)
|
||||||
|
&& !empty($config_smtp_port)
|
||||||
|
&& !empty($config_mail_from_email)
|
||||||
|
&& !empty($config_mail_from_name);
|
||||||
|
|
||||||
|
$smtp_oauth_ready = ($config_smtp_provider === 'google_oauth' || $config_smtp_provider === 'microsoft_oauth')
|
||||||
|
&& !empty($config_mail_from_email)
|
||||||
|
&& !empty($config_mail_from_name)
|
||||||
|
&& !empty($config_mail_oauth_client_id)
|
||||||
|
&& !empty($config_mail_oauth_client_secret)
|
||||||
|
&& !empty($config_mail_oauth_refresh_token)
|
||||||
|
&& ($config_smtp_provider !== 'microsoft_oauth' || !empty($config_mail_oauth_tenant_id));
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if ($smtp_standard_ready || $smtp_oauth_ready) { ?>
|
||||||
|
|
||||||
<div class="card card-dark">
|
<div class="card card-dark">
|
||||||
<div class="card-header py-3">
|
<div class="card-header py-3">
|
||||||
@@ -409,7 +450,21 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
<?php if (!empty($config_imap_username) && !empty($config_imap_password) && !empty($config_imap_host) && !empty($config_imap_port)) { ?>
|
<?php
|
||||||
|
$imap_standard_ready = !empty($config_imap_username)
|
||||||
|
&& !empty($config_imap_password)
|
||||||
|
&& !empty($config_imap_host)
|
||||||
|
&& !empty($config_imap_port);
|
||||||
|
|
||||||
|
$imap_oauth_ready = ($config_imap_provider === 'google_oauth' || $config_imap_provider === 'microsoft_oauth')
|
||||||
|
&& !empty($config_imap_username)
|
||||||
|
&& !empty($config_mail_oauth_client_id)
|
||||||
|
&& !empty($config_mail_oauth_client_secret)
|
||||||
|
&& !empty($config_mail_oauth_refresh_token)
|
||||||
|
&& ($config_imap_provider !== 'microsoft_oauth' || !empty($config_mail_oauth_tenant_id));
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if ($imap_standard_ready || $imap_oauth_ready) { ?>
|
||||||
|
|
||||||
<div class="card card-dark">
|
<div class="card card-dark">
|
||||||
<div class="card-header py-3">
|
<div class="card-header py-3">
|
||||||
@@ -428,6 +483,46 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$oauth_provider_for_test = '';
|
||||||
|
if ($config_imap_provider === 'google_oauth' || $config_imap_provider === 'microsoft_oauth') {
|
||||||
|
$oauth_provider_for_test = $config_imap_provider;
|
||||||
|
} elseif ($config_smtp_provider === 'google_oauth' || $config_smtp_provider === 'microsoft_oauth') {
|
||||||
|
$oauth_provider_for_test = $config_smtp_provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
$oauth_has_required_fields = !empty($oauth_provider_for_test)
|
||||||
|
&& !empty($config_mail_oauth_client_id)
|
||||||
|
&& !empty($config_mail_oauth_client_secret)
|
||||||
|
&& !empty($config_mail_oauth_refresh_token)
|
||||||
|
&& ($oauth_provider_for_test !== 'microsoft_oauth' || !empty($config_mail_oauth_tenant_id));
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if ($oauth_has_required_fields) { ?>
|
||||||
|
|
||||||
|
<div class="card card-dark">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h3 class="card-title"><i class="fas fa-fw fa-key mr-2"></i>Test OAuth Token Refresh</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||||
|
<input type="hidden" name="oauth_provider" value="<?php echo htmlspecialchars($oauth_provider_for_test); ?>">
|
||||||
|
|
||||||
|
<p class="text-secondary mb-3">
|
||||||
|
This validates your refresh token and stores a new access token for
|
||||||
|
<?php echo $oauth_provider_for_test === 'microsoft_oauth' ? 'Microsoft 365' : 'Google Workspace'; ?>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button type="submit" name="test_oauth_token_refresh" class="btn btn-success">
|
||||||
|
<i class="fas fa-fw fa-sync-alt mr-2"></i>Test OAuth Token Refresh
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
(function(){
|
(function(){
|
||||||
function setDisabled(container, disabled){
|
function setDisabled(container, disabled){
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
|
|
||||||
<button type="submit" name="edit_favicon_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Upload Icon</button>
|
<button type="submit" name="edit_favicon_settings" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Upload Icon</button>
|
||||||
<?php if(file_exists("../uploads/favicon.ico")) { ?>
|
<?php if(file_exists("../uploads/favicon.ico")) { ?>
|
||||||
<a href="post.php?reset_favicon" class="btn btn-outline-danger"><i class="fas fa-redo-alt mr-2"></i>Reset Favicon</a>
|
<a href="post.php?reset_favicon&csrf_token=<?= $_SESSION['csrf_token'] ?>" class="btn btn-outline-danger"><i class="fas fa-redo-alt mr-2"></i>Reset Favicon</a>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -66,7 +66,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-clock"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-clock"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="number" min="72" class="form-control" name="config_ticket_autoclose_hours" placeholder="Delay in hours before a resolved ticket is fully closed" value="<?php echo intval($config_ticket_autoclose_hours); ?>">
|
<input type="number" min="24" class="form-control" name="config_ticket_autoclose_hours" placeholder="Delay in hours before a resolved ticket is fully closed" value="<?php echo intval($config_ticket_autoclose_hours); ?>">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ require_once "includes/inc_all_admin.php";
|
|||||||
<label>Kanban Settings</label>
|
<label>Kanban Settings</label>
|
||||||
<div class="custom-control custom-switch">
|
<div class="custom-control custom-switch">
|
||||||
<input type="checkbox" class="custom-control-input" name="config_ticket_ordering" <?php if ($config_ticket_ordering == 1) { echo "checked"; } ?> value="1" id="ticketOrderingSwitch">
|
<input type="checkbox" class="custom-control-input" name="config_ticket_ordering" <?php if ($config_ticket_ordering == 1) { echo "checked"; } ?> value="1" id="ticketOrderingSwitch">
|
||||||
<label class="custom-control-label" for="ticketOrderingSwitch">Allow ticket ordering within its column<small class="text-secondary">(uncheked will result in ordering it by priority and id)</small></label>
|
<label class="custom-control-label" for="ticketOrderingSwitch">Allow ticket ordering within its column<small class="text-secondary"> (unchecked = order by priority and id)</small></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-control custom-switch">
|
<div class="custom-control custom-switch">
|
||||||
<input type="checkbox" class="custom-control-input" name="config_ticket_moving_columns" <?php if ($config_ticket_moving_columns == 1) { echo "checked"; } ?> value="1" id="ticketMovingColumnsSwitch">
|
<input type="checkbox" class="custom-control-input" name="config_ticket_moving_columns" <?php if ($config_ticket_moving_columns == 1) { echo "checked"; } ?> value="1" id="ticketMovingColumnsSwitch">
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while($row = mysqli_fetch_array($sql)){
|
while($row = mysqli_fetch_assoc($sql)){
|
||||||
$software_template_id = intval($row['software_template_id']);
|
$software_template_id = intval($row['software_template_id']);
|
||||||
$software_template_name = nullable_htmlentities($row['software_template_name']);
|
$software_template_name = nullable_htmlentities($row['software_template_name']);
|
||||||
$software_template_version = nullable_htmlentities($row['software_template_version']);
|
$software_template_version = nullable_htmlentities($row['software_template_version']);
|
||||||
@@ -103,7 +103,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
</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 confirm-link" href="post.php?delete_software_template=<?php echo $software_template_id; ?>">
|
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_software_template=<?php echo $software_template_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<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 } ?>
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$tag_id = intval($row['tag_id']);
|
$tag_id = intval($row['tag_id']);
|
||||||
$tag_name = nullable_htmlentities($row['tag_name']);
|
$tag_name = nullable_htmlentities($row['tag_name']);
|
||||||
$tag_color = nullable_htmlentities($row['tag_color']);
|
$tag_color = nullable_htmlentities($row['tag_color']);
|
||||||
@@ -142,7 +142,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<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 text-danger text-bold confirm-link" href="post.php?delete_tag=<?php echo $tag_id; ?>">
|
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_tag=<?php echo $tag_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<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>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ $num_rows = mysqli_num_rows($sql);
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$tax_id = intval($row['tax_id']);
|
$tax_id = intval($row['tax_id']);
|
||||||
$tax_name = nullable_htmlentities($row['tax_name']);
|
$tax_name = nullable_htmlentities($row['tax_name']);
|
||||||
$tax_percent = floatval($row['tax_percent']);
|
$tax_percent = floatval($row['tax_percent']);
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$ticket_status_id = intval($row['ticket_status_id']);
|
$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']);
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while($row = mysqli_fetch_array($sql)){
|
while($row = mysqli_fetch_assoc($sql)){
|
||||||
$ticket_template_id = intval($row['ticket_template_id']);
|
$ticket_template_id = intval($row['ticket_template_id']);
|
||||||
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
|
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
|
||||||
$ticket_template_description = nullable_htmlentities($row['ticket_template_description']);
|
$ticket_template_description = nullable_htmlentities($row['ticket_template_description']);
|
||||||
@@ -101,7 +101,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<i class="fas fa-ellipsis-h"></i>
|
<i class="fas fa-ellipsis-h"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_ticket_template=<?= $ticket_template_id ?>">
|
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_ticket_template=<?= $ticket_template_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<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>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ if (mysqli_num_rows($sql_ticket_template) == 0) {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql_ticket_template);
|
$row = mysqli_fetch_assoc($sql_ticket_template);
|
||||||
|
|
||||||
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
|
$ticket_template_name = nullable_htmlentities($row['ticket_template_name']);
|
||||||
$ticket_template_description = nullable_htmlentities($row['ticket_template_description']);
|
$ticket_template_description = nullable_htmlentities($row['ticket_template_description']);
|
||||||
@@ -51,26 +51,17 @@ $sql_task_templates = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE
|
|||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-9">
|
<div class="col-md-9">
|
||||||
|
|
||||||
<div class="card card-dark">
|
<div class="card card-dark">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3 class="card-title mt-2">
|
<h3 class="card-title mt-1"><?php echo $ticket_template_name; ?></h3>
|
||||||
<div class="media">
|
|
||||||
<i class="fa fa-fw fa-2x fa-life-ring mr-3"></i>
|
|
||||||
<div class="media-body">
|
|
||||||
<h3 class="mb-0"><?php echo $ticket_template_name; ?></h3>
|
|
||||||
<div><small class="text-secondary"><?php //echo $ticket_template_description; ?></small></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</h3>
|
|
||||||
<div class="card-tools">
|
<div class="card-tools">
|
||||||
<button type="button" class="btn btn-default btn-sm" data-toggle="modal" data-target="#editTicketTemplateModal">
|
<button type="button" class="btn btn-tool btn-sm" data-toggle="modal" data-target="#editTicketTemplateModal">
|
||||||
<i class="fas fa-edit"></i>
|
<i class="fas fa-edit"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h5><?php echo $ticket_template_subject; ?></h5>
|
|
||||||
<div class="card-body prettyContent">
|
<div class="card-body prettyContent">
|
||||||
<?php echo $ticket_template_details; ?>
|
<?php echo $ticket_template_details; ?>
|
||||||
</div>
|
</div>
|
||||||
@@ -78,7 +69,7 @@ $sql_task_templates = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-3">
|
<div class="col-md-3">
|
||||||
|
|
||||||
<div class="card card-dark">
|
<div class="card card-dark">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
@@ -86,6 +77,7 @@ $sql_task_templates = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form action="post.php" method="post" autocomplete="off">
|
<form action="post.php" method="post" autocomplete="off">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||||
<input type="hidden" name="ticket_template_id" value="<?php echo $ticket_template_id; ?>">
|
<input type="hidden" name="ticket_template_id" value="<?php echo $ticket_template_id; ?>">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="input-group input-group-sm">
|
<div class="input-group input-group-sm">
|
||||||
@@ -98,7 +90,7 @@ $sql_task_templates = mysqli_query($mysqli, "SELECT * FROM task_templates WHERE
|
|||||||
</form>
|
</form>
|
||||||
<table class="table table-sm" id="tasks">
|
<table class="table table-sm" id="tasks">
|
||||||
<?php
|
<?php
|
||||||
while($row = mysqli_fetch_array($sql_task_templates)){
|
while($row = mysqli_fetch_assoc($sql_task_templates)){
|
||||||
$task_id = intval($row['task_template_id']);
|
$task_id = intval($row['task_template_id']);
|
||||||
$task_name = nullable_htmlentities($row['task_template_name']);
|
$task_name = nullable_htmlentities($row['task_template_name']);
|
||||||
$task_completion_estimate = intval($row['task_template_completion_estimate']);
|
$task_completion_estimate = intval($row['task_template_completion_estimate']);
|
||||||
@@ -154,8 +146,9 @@ new Sortable(document.querySelector('table#tasks tbody'), {
|
|||||||
order: index
|
order: index
|
||||||
}));
|
}));
|
||||||
|
|
||||||
$.post('ajax.php', {
|
$.post('/agent/ajax.php', {
|
||||||
update_task_templates_order: true,
|
update_task_templates_order: true,
|
||||||
|
csrf_token: '<?= $_SESSION['csrf_token'] ?>',
|
||||||
ticket_template_id: <?php echo $ticket_template_id; ?>,
|
ticket_template_id: <?php echo $ticket_template_id; ?>,
|
||||||
positions: positions
|
positions: positions
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$user_id = intval($row['user_id']);
|
$user_id = intval($row['user_id']);
|
||||||
$user_name = nullable_htmlentities($row['user_name']);
|
$user_name = nullable_htmlentities($row['user_name']);
|
||||||
$user_email = nullable_htmlentities($row['user_email']);
|
$user_email = nullable_htmlentities($row['user_email']);
|
||||||
@@ -139,7 +139,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
if (mysqli_num_rows($sql_last_login) == 0) {
|
if (mysqli_num_rows($sql_last_login) == 0) {
|
||||||
$last_login = "<span class='text-bold'>Never logged in</span>";
|
$last_login = "<span class='text-bold'>Never logged in</span>";
|
||||||
} else {
|
} else {
|
||||||
$row = mysqli_fetch_array($sql_last_login);
|
$row = mysqli_fetch_assoc($sql_last_login);
|
||||||
$log_created_at = nullable_htmlentities($row['log_created_at']);
|
$log_created_at = nullable_htmlentities($row['log_created_at']);
|
||||||
$log_ip = nullable_htmlentities($row['log_ip']);
|
$log_ip = nullable_htmlentities($row['log_ip']);
|
||||||
$log_user_agent = nullable_htmlentities($row['log_user_agent']);
|
$log_user_agent = nullable_htmlentities($row['log_user_agent']);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$vendor_template_id = intval($row['vendor_template_id']);
|
$vendor_template_id = intval($row['vendor_template_id']);
|
||||||
$vendor_template_name = nullable_htmlentities($row['vendor_template_name']);
|
$vendor_template_name = nullable_htmlentities($row['vendor_template_name']);
|
||||||
$vendor_template_description = nullable_htmlentities($row['vendor_template_description']);
|
$vendor_template_description = nullable_htmlentities($row['vendor_template_description']);
|
||||||
@@ -140,7 +140,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
</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 confirm-link" href="post.php?delete_vendor_template=<?= $vendor_template_id ?>">
|
<a class="dropdown-item text-danger text-bold confirm-link" href="post.php?delete_vendor_template=<?= $vendor_template_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
|
||||||
<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 } ?>
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($sql)) {
|
while ($row = mysqli_fetch_assoc($sql)) {
|
||||||
$account_id = intval($row['account_id']);
|
$account_id = intval($row['account_id']);
|
||||||
$account_name = nullable_htmlentities($row['account_name']);
|
$account_name = nullable_htmlentities($row['account_name']);
|
||||||
$opening_balance = floatval($row['opening_balance']);
|
$opening_balance = floatval($row['opening_balance']);
|
||||||
@@ -67,15 +67,15 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
|
|||||||
$account_notes = nullable_htmlentities($row['account_notes']);
|
$account_notes = nullable_htmlentities($row['account_notes']);
|
||||||
|
|
||||||
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments FROM payments WHERE payment_account_id = $account_id");
|
$sql_payments = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS total_payments FROM payments WHERE payment_account_id = $account_id");
|
||||||
$row = mysqli_fetch_array($sql_payments);
|
$row = mysqli_fetch_assoc($sql_payments);
|
||||||
$total_payments = floatval($row['total_payments']);
|
$total_payments = floatval($row['total_payments']);
|
||||||
|
|
||||||
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS total_revenues FROM revenues WHERE revenue_account_id = $account_id");
|
$sql_revenues = mysqli_query($mysqli, "SELECT SUM(revenue_amount) AS total_revenues FROM revenues WHERE revenue_account_id = $account_id");
|
||||||
$row = mysqli_fetch_array($sql_revenues);
|
$row = mysqli_fetch_assoc($sql_revenues);
|
||||||
$total_revenues = floatval($row['total_revenues']);
|
$total_revenues = floatval($row['total_revenues']);
|
||||||
|
|
||||||
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS total_expenses FROM expenses WHERE expense_account_id = $account_id");
|
$sql_expenses = mysqli_query($mysqli, "SELECT SUM(expense_amount) AS total_expenses FROM expenses WHERE expense_account_id = $account_id");
|
||||||
$row = mysqli_fetch_array($sql_expenses);
|
$row = mysqli_fetch_assoc($sql_expenses);
|
||||||
$total_expenses = floatval($row['total_expenses']);
|
$total_expenses = floatval($row['total_expenses']);
|
||||||
|
|
||||||
$balance = $opening_balance + $total_payments + $total_revenues - $total_expenses;
|
$balance = $opening_balance + $total_payments + $total_revenues - $total_expenses;
|
||||||
|
|||||||
119
agent/ajax.php
119
agent/ajax.php
@@ -40,32 +40,10 @@ if (isset($_GET['certificate_fetch_parse_json_details'])) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Looks up info on the ticket number provided, used to populate the ticket merge modal
|
|
||||||
*/
|
|
||||||
if (isset($_GET['merge_ticket_get_json_details'])) {
|
|
||||||
enforceUserPermission('module_support');
|
|
||||||
|
|
||||||
$merge_into_ticket_number = intval(preg_replace('/[^0-9]/', '', $_GET['merge_into_ticket_number']));
|
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT ticket_id, ticket_number, ticket_prefix, ticket_subject, ticket_priority, ticket_status, ticket_status_name, client_name, contact_name FROM tickets
|
|
||||||
LEFT JOIN clients ON ticket_client_id = client_id
|
|
||||||
LEFT JOIN contacts ON ticket_contact_id = contact_id
|
|
||||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
|
||||||
WHERE ticket_number = $merge_into_ticket_number");
|
|
||||||
|
|
||||||
if (mysqli_num_rows($sql) == 0) {
|
|
||||||
//Do nothing.
|
|
||||||
echo "No ticket found!";
|
|
||||||
} else {
|
|
||||||
//Return ticket, client and contact details for the given ticket number
|
|
||||||
$response = mysqli_fetch_array($sql);
|
|
||||||
|
|
||||||
echo json_encode($response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['client_set_notes'])) {
|
if (isset($_POST['client_set_notes'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
enforceUserPermission('module_client', 2);
|
enforceUserPermission('module_client', 2);
|
||||||
|
|
||||||
$client_id = intval($_POST['client_id']);
|
$client_id = intval($_POST['client_id']);
|
||||||
@@ -80,6 +58,9 @@ if (isset($_POST['client_set_notes'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['contact_set_notes'])) {
|
if (isset($_POST['contact_set_notes'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
enforceUserPermission('module_client', 2);
|
enforceUserPermission('module_client', 2);
|
||||||
|
|
||||||
$contact_id = intval($_POST['contact_id']);
|
$contact_id = intval($_POST['contact_id']);
|
||||||
@@ -89,7 +70,7 @@ if (isset($_POST['contact_set_notes'])) {
|
|||||||
$sql = mysqli_query($mysqli,"SELECT contact_name, contact_client_id
|
$sql = mysqli_query($mysqli,"SELECT contact_name, contact_client_id
|
||||||
FROM contacts WHERE contact_id = $contact_id"
|
FROM contacts WHERE contact_id = $contact_id"
|
||||||
);
|
);
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$contact_name = sanitizeInput($row['contact_name']);
|
$contact_name = sanitizeInput($row['contact_name']);
|
||||||
$client_id = intval($row['contact_client_id']);
|
$client_id = intval($row['contact_client_id']);
|
||||||
|
|
||||||
@@ -102,6 +83,9 @@ if (isset($_POST['contact_set_notes'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['asset_set_notes'])) {
|
if (isset($_POST['asset_set_notes'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
enforceUserPermission('module_support', 2);
|
enforceUserPermission('module_support', 2);
|
||||||
|
|
||||||
$asset_id = intval($_POST['asset_id']);
|
$asset_id = intval($_POST['asset_id']);
|
||||||
@@ -111,7 +95,7 @@ if (isset($_POST['asset_set_notes'])) {
|
|||||||
$sql = mysqli_query($mysqli,"SELECT asset_name, asset_client_id
|
$sql = mysqli_query($mysqli,"SELECT asset_name, asset_client_id
|
||||||
FROM assets WHERE asset_id = $asset_id"
|
FROM assets WHERE asset_id = $asset_id"
|
||||||
);
|
);
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$asset_name = sanitizeInput($row['asset_name']);
|
$asset_name = sanitizeInput($row['asset_name']);
|
||||||
$client_id = intval($row['asset_client_id']);
|
$client_id = intval($row['asset_client_id']);
|
||||||
|
|
||||||
@@ -143,7 +127,7 @@ if (isset($_GET['ticket_query_views'])) {
|
|||||||
$ticket_id = intval($_GET['ticket_id']);
|
$ticket_id = intval($_GET['ticket_id']);
|
||||||
|
|
||||||
$query = mysqli_query($mysqli, "SELECT user_name FROM ticket_views LEFT JOIN users ON view_user_id = user_id WHERE view_ticket_id = $ticket_id AND view_user_id != $session_user_id AND view_timestamp > DATE_SUB(NOW(), INTERVAL 2 MINUTE)");
|
$query = mysqli_query($mysqli, "SELECT user_name FROM ticket_views LEFT JOIN users ON view_user_id = user_id WHERE view_ticket_id = $ticket_id AND view_user_id != $session_user_id AND view_timestamp > DATE_SUB(NOW(), INTERVAL 2 MINUTE)");
|
||||||
while ($row = mysqli_fetch_array($query)) {
|
while ($row = mysqli_fetch_assoc($query)) {
|
||||||
$users[] = $row['user_name'];
|
$users[] = $row['user_name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +152,9 @@ if (isset($_GET['ticket_query_views'])) {
|
|||||||
* Generates public/guest links for sharing credentials/docs
|
* Generates public/guest links for sharing credentials/docs
|
||||||
*/
|
*/
|
||||||
if (isset($_GET['share_generate_link'])) {
|
if (isset($_GET['share_generate_link'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_GET['csrf_token']);
|
||||||
|
|
||||||
enforceUserPermission('module_support', 2);
|
enforceUserPermission('module_support', 2);
|
||||||
|
|
||||||
$item_encrypted_username = ''; // Default empty
|
$item_encrypted_username = ''; // Default empty
|
||||||
@@ -198,18 +185,18 @@ if (isset($_GET['share_generate_link'])) {
|
|||||||
$item_key = randomString(32);
|
$item_key = randomString(32);
|
||||||
|
|
||||||
if ($item_type == "Document") {
|
if ($item_type == "Document") {
|
||||||
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT document_name FROM documents WHERE document_id = $item_id AND document_client_id = $client_id LIMIT 1"));
|
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT document_name FROM documents WHERE document_id = $item_id AND document_client_id = $client_id LIMIT 1"));
|
||||||
$item_name = sanitizeInput($row['document_name']);
|
$item_name = sanitizeInput($row['document_name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($item_type == "File") {
|
if ($item_type == "File") {
|
||||||
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT file_name FROM files WHERE file_id = $item_id AND file_client_id = $client_id LIMIT 1"));
|
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT file_name FROM files WHERE file_id = $item_id AND file_client_id = $client_id LIMIT 1"));
|
||||||
$item_name = sanitizeInput($row['file_name']);
|
$item_name = sanitizeInput($row['file_name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($item_type == "Credential") {
|
if ($item_type == "Credential") {
|
||||||
$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");
|
$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($credential);
|
$row = mysqli_fetch_assoc($credential);
|
||||||
|
|
||||||
$item_name = sanitizeInput($row['credential_name']);
|
$item_name = sanitizeInput($row['credential_name']);
|
||||||
|
|
||||||
@@ -240,7 +227,7 @@ if (isset($_GET['share_generate_link'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
|
$sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$company_name = sanitizeInput($row['company_name']);
|
$company_name = sanitizeInput($row['company_name']);
|
||||||
$company_phone = sanitizeInput(formatPhoneNumber($row['company_phone'], $row['company_phone_country_code']));
|
$company_phone = sanitizeInput(formatPhoneNumber($row['company_phone'], $row['company_phone_country_code']));
|
||||||
|
|
||||||
@@ -298,7 +285,7 @@ if (isset($_GET['get_active_clients'])) {
|
|||||||
ORDER BY client_accessed_at DESC"
|
ORDER BY client_accessed_at DESC"
|
||||||
);
|
);
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($client_sql)) {
|
while ($row = mysqli_fetch_assoc($client_sql)) {
|
||||||
$response['clients'][] = $row;
|
$response['clients'][] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +309,7 @@ if (isset($_GET['get_client_contacts'])) {
|
|||||||
ORDER BY contact_primary DESC, contact_technical DESC, contact_important DESC, contact_name"
|
ORDER BY contact_primary DESC, contact_technical DESC, contact_important DESC, contact_name"
|
||||||
);
|
);
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($contact_sql)) {
|
while ($row = mysqli_fetch_assoc($contact_sql)) {
|
||||||
$response['contacts'][] = $row;
|
$response['contacts'][] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,10 +331,10 @@ if (isset($_GET['get_client_assets'])) {
|
|||||||
LEFT JOIN contacts ON contact_id = asset_contact_id
|
LEFT JOIN contacts ON contact_id = asset_contact_id
|
||||||
WHERE assets.asset_archived_at IS NULL AND asset_client_id = $client_id
|
WHERE assets.asset_archived_at IS NULL AND asset_client_id = $client_id
|
||||||
$access_permission_query
|
$access_permission_query
|
||||||
ORDER BY asset_important DESC, asset_name"
|
ORDER BY asset_favorite DESC, asset_name"
|
||||||
);
|
);
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($asset_sql)) {
|
while ($row = mysqli_fetch_assoc($asset_sql)) {
|
||||||
$response['assets'][] = $row;
|
$response['assets'][] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,7 +358,7 @@ if (isset($_GET['get_client_locations'])) {
|
|||||||
ORDER BY location_primary DESC, location_name ASC"
|
ORDER BY location_primary DESC, location_name ASC"
|
||||||
);
|
);
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($locations_sql)) {
|
while ($row = mysqli_fetch_assoc($locations_sql)) {
|
||||||
$response['locations'][] = $row;
|
$response['locations'][] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,7 +382,7 @@ if (isset($_GET['get_client_vendors'])) {
|
|||||||
ORDER BY vendor_name ASC"
|
ORDER BY vendor_name ASC"
|
||||||
);
|
);
|
||||||
|
|
||||||
while ($row = mysqli_fetch_array($vendors_sql)) {
|
while ($row = mysqli_fetch_assoc($vendors_sql)) {
|
||||||
$response['vendors'][] = $row;
|
$response['vendors'][] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,7 +489,7 @@ if (isset($_POST['update_kanban_ticket'])) {
|
|||||||
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
LEFT JOIN ticket_statuses ON ticket_status = ticket_status_id
|
||||||
WHERE ticket_id = $ticket_id
|
WHERE ticket_id = $ticket_id
|
||||||
");
|
");
|
||||||
$row = mysqli_fetch_array($ticket_sql);
|
$row = mysqli_fetch_assoc($ticket_sql);
|
||||||
|
|
||||||
$contact_name = sanitizeInput($row['contact_name']);
|
$contact_name = sanitizeInput($row['contact_name']);
|
||||||
$contact_email = sanitizeInput($row['contact_email']);
|
$contact_email = sanitizeInput($row['contact_email']);
|
||||||
@@ -521,7 +508,7 @@ if (isset($_POST['update_kanban_ticket'])) {
|
|||||||
|
|
||||||
// Get Company Info
|
// Get Company Info
|
||||||
$sql = mysqli_query($mysqli, "SELECT company_name, company_phone, company_phone_country_code FROM companies WHERE company_id = 1");
|
$sql = mysqli_query($mysqli, "SELECT company_name, company_phone, company_phone_country_code FROM companies WHERE company_id = 1");
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$company_name = sanitizeInput($row['company_name']);
|
$company_name = sanitizeInput($row['company_name']);
|
||||||
$company_phone = sanitizeInput(formatPhoneNumber($row['company_phone'], $row['company_phone_country_code']));
|
$company_phone = sanitizeInput(formatPhoneNumber($row['company_phone'], $row['company_phone_country_code']));
|
||||||
|
|
||||||
@@ -550,7 +537,7 @@ if (isset($_POST['update_kanban_ticket'])) {
|
|||||||
// Also Email all the watchers
|
// Also Email all the watchers
|
||||||
$sql_watchers = mysqli_query($mysqli, "SELECT watcher_email FROM ticket_watchers WHERE watcher_ticket_id = $ticket_id");
|
$sql_watchers = mysqli_query($mysqli, "SELECT watcher_email FROM ticket_watchers WHERE watcher_ticket_id = $ticket_id");
|
||||||
$body .= "<br><br>----------------------------------------<br>YOU ARE A COLLABORATOR ON THIS TICKET";
|
$body .= "<br><br>----------------------------------------<br>YOU ARE A COLLABORATOR ON THIS TICKET";
|
||||||
while ($row = mysqli_fetch_array($sql_watchers)) {
|
while ($row = mysqli_fetch_assoc($sql_watchers)) {
|
||||||
$watcher_email = sanitizeInput($row['watcher_email']);
|
$watcher_email = sanitizeInput($row['watcher_email']);
|
||||||
|
|
||||||
// Queue Mail
|
// Queue Mail
|
||||||
@@ -583,6 +570,9 @@ if (isset($_POST['update_kanban_ticket'])) {
|
|||||||
|
|
||||||
if (isset($_POST['update_ticket_tasks_order'])) {
|
if (isset($_POST['update_ticket_tasks_order'])) {
|
||||||
// Update multiple ticket tasks order
|
// Update multiple ticket tasks order
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
enforceUserPermission('module_support', 2);
|
enforceUserPermission('module_support', 2);
|
||||||
|
|
||||||
$positions = $_POST['positions'];
|
$positions = $_POST['positions'];
|
||||||
@@ -602,6 +592,9 @@ if (isset($_POST['update_ticket_tasks_order'])) {
|
|||||||
|
|
||||||
if (isset($_POST['update_task_templates_order'])) {
|
if (isset($_POST['update_task_templates_order'])) {
|
||||||
// Update multiple task templates order
|
// Update multiple task templates order
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
enforceUserPermission('module_support', 2);
|
enforceUserPermission('module_support', 2);
|
||||||
|
|
||||||
$positions = $_POST['positions'];
|
$positions = $_POST['positions'];
|
||||||
@@ -619,8 +612,32 @@ if (isset($_POST['update_task_templates_order'])) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($_POST['update_project_template_ticket_order'])) {
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
|
enforceUserPermission('module_support', 2);
|
||||||
|
|
||||||
|
$positions = $_POST['positions'];
|
||||||
|
$project_template_id = intval($_POST['project_template_id']);
|
||||||
|
|
||||||
|
foreach ($positions as $position) {
|
||||||
|
$id = intval($position['id']);
|
||||||
|
$order = intval($position['order']);
|
||||||
|
|
||||||
|
mysqli_query($mysqli, "UPDATE project_template_ticket_templates SET ticket_template_order = $order WHERE project_template_id = $project_template_id AND ticket_template_id = $id");
|
||||||
|
}
|
||||||
|
|
||||||
|
// return a response
|
||||||
|
echo json_encode(['status' => 'success']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($_POST['update_quote_items_order'])) {
|
if (isset($_POST['update_quote_items_order'])) {
|
||||||
// Update multiple quote items order
|
// Update multiple quote items order
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
enforceUserPermission('module_sales', 2);
|
enforceUserPermission('module_sales', 2);
|
||||||
|
|
||||||
$positions = $_POST['positions'];
|
$positions = $_POST['positions'];
|
||||||
@@ -630,7 +647,7 @@ if (isset($_POST['update_quote_items_order'])) {
|
|||||||
$id = intval($position['id']);
|
$id = intval($position['id']);
|
||||||
$order = intval($position['order']);
|
$order = intval($position['order']);
|
||||||
|
|
||||||
mysqli_query($mysqli, "UPDATE invoice_items SET item_order = $order WHERE item_quote_id = $quote_id AND item_id = $id");
|
mysqli_query($mysqli, "UPDATE quote_items SET item_order = $order WHERE item_quote_id = $quote_id AND item_id = $id");
|
||||||
}
|
}
|
||||||
|
|
||||||
// return a response
|
// return a response
|
||||||
@@ -640,6 +657,9 @@ if (isset($_POST['update_quote_items_order'])) {
|
|||||||
|
|
||||||
if (isset($_POST['update_invoice_items_order'])) {
|
if (isset($_POST['update_invoice_items_order'])) {
|
||||||
// Update multiple invoice items order
|
// Update multiple invoice items order
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
enforceUserPermission('module_sales', 2);
|
enforceUserPermission('module_sales', 2);
|
||||||
|
|
||||||
$positions = $_POST['positions'];
|
$positions = $_POST['positions'];
|
||||||
@@ -659,6 +679,9 @@ if (isset($_POST['update_invoice_items_order'])) {
|
|||||||
|
|
||||||
if (isset($_POST['update_recurring_invoice_items_order'])) {
|
if (isset($_POST['update_recurring_invoice_items_order'])) {
|
||||||
// Update multiple recurring invoice items order
|
// Update multiple recurring invoice items order
|
||||||
|
|
||||||
|
validateCSRFToken($_POST['csrf_token']);
|
||||||
|
|
||||||
enforceUserPermission('module_sales', 2);
|
enforceUserPermission('module_sales', 2);
|
||||||
|
|
||||||
$positions = $_POST['positions'];
|
$positions = $_POST['positions'];
|
||||||
@@ -668,7 +691,7 @@ if (isset($_POST['update_recurring_invoice_items_order'])) {
|
|||||||
$id = intval($position['id']);
|
$id = intval($position['id']);
|
||||||
$order = intval($position['order']);
|
$order = intval($position['order']);
|
||||||
|
|
||||||
mysqli_query($mysqli, "UPDATE invoice_items SET item_order = $order WHERE item_recurring_invoice_id = $recurring_invoice_id AND item_id = $id");
|
mysqli_query($mysqli, "UPDATE recurring_invoice_items SET item_order = $order WHERE item_recurring_invoice_id = $recurring_invoice_id AND item_id = $id");
|
||||||
}
|
}
|
||||||
|
|
||||||
// return a response
|
// return a response
|
||||||
@@ -691,7 +714,7 @@ if (isset($_GET['client_duplicate_check'])) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (mysqli_num_rows($sql_clients) > 0) {
|
if (mysqli_num_rows($sql_clients) > 0) {
|
||||||
while ($row = mysqli_fetch_array($sql_clients)) {
|
while ($row = mysqli_fetch_assoc($sql_clients)) {
|
||||||
$response['message'] = "<i class='fas fa-fw fa-copy mr-2'></i> Potential duplicate: <i>" . nullable_htmlentities($row['client_name']) . "</i> already exists.";
|
$response['message'] = "<i class='fas fa-fw fa-copy mr-2'></i> Potential duplicate: <i>" . nullable_htmlentities($row['client_name']) . "</i> already exists.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -713,7 +736,7 @@ if (isset($_GET['contact_email_check'])) {
|
|||||||
// 1. Duplicate check
|
// 1. Duplicate check
|
||||||
$sql_contacts = mysqli_query($mysqli, "SELECT contact_email FROM contacts WHERE contact_email = '$email' LIMIT 1");
|
$sql_contacts = mysqli_query($mysqli, "SELECT contact_email FROM contacts WHERE contact_email = '$email' LIMIT 1");
|
||||||
if (mysqli_num_rows($sql_contacts) > 0) {
|
if (mysqli_num_rows($sql_contacts) > 0) {
|
||||||
while ($row = mysqli_fetch_array($sql_contacts)) {
|
while ($row = mysqli_fetch_assoc($sql_contacts)) {
|
||||||
$response['message'] = "<i class='fas fa-fw fa-copy mr-2'></i> Potential duplicate: <i>" . nullable_htmlentities($row['contact_email']) . "</i> already exists.";
|
$response['message'] = "<i class='fas fa-fw fa-copy mr-2'></i> Potential duplicate: <i>" . nullable_htmlentities($row['contact_email']) . "</i> already exists.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -734,7 +757,7 @@ if (isset($_GET['ai_reword'])) {
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$model_name = $row['ai_model_name'];
|
$model_name = $row['ai_model_name'];
|
||||||
$promptText = $row['ai_model_prompt'];
|
$promptText = $row['ai_model_prompt'];
|
||||||
$url = $row['ai_provider_api_url'];
|
$url = $row['ai_provider_api_url'];
|
||||||
@@ -805,7 +828,7 @@ if (isset($_GET['ai_create_document_template'])) {
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$model_name = $row['ai_model_name'];
|
$model_name = $row['ai_model_name'];
|
||||||
$url = $row['ai_provider_api_url'];
|
$url = $row['ai_provider_api_url'];
|
||||||
$key = $row['ai_provider_api_key'];
|
$key = $row['ai_provider_api_key'];
|
||||||
@@ -861,7 +884,7 @@ if (isset($_GET['ai_ticket_summary'])) {
|
|||||||
|
|
||||||
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
$sql = mysqli_query($mysqli, "SELECT * FROM ai_models LEFT JOIN ai_providers ON ai_model_ai_provider_id = ai_provider_id WHERE ai_model_use_case = 'General' LIMIT 1");
|
||||||
|
|
||||||
$row = mysqli_fetch_array($sql);
|
$row = mysqli_fetch_assoc($sql);
|
||||||
$model_name = $row['ai_model_name'];
|
$model_name = $row['ai_model_name'];
|
||||||
$url = $row['ai_provider_api_url'];
|
$url = $row['ai_provider_api_url'];
|
||||||
$key = $row['ai_provider_api_key'];
|
$key = $row['ai_provider_api_key'];
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user