johnnyq
6ecc27e7ca
Version ITFlow's scripts and stylesheets so browsers fetch the new copies after an update instead of needing a cache clear: add staticFileUrl() in functions/app.php, which adds ?v= and the file's modification time to the address, and send every script and stylesheet tag through it, libs included, with page-relative addresses changed to start from the site root; add js/tinymce_defaults.js to set TinyMCE's cache_suffix so the plugins, theme and skins it loads itself are versioned too; load ticket collision detection only when a ticket is shown, so a ticket that isn't found no longer throws a script error; add changelog entries and a CONTRIBUTING rule that new tags must use staticFileUrl()
2026-11-09 01:22:35 -05:00
johnnyq
076f4295be
Bug fixes
2026-11-07 12:26:58 -05:00
johnnyq
53e6564f76
Stop row actions menus being cut off on short lists - a list's table scrolls sideways inside .table-responsive, which also clipped a row's menu at the bottom of the list when it had only a row or two, hiding its last options; new js/bootstrap_defaults.js, loaded right after Bootstrap on agent pages and the client portal, sets Bootstrap's dropdown default to Popper's fixed strategy so menus open over the page and still turn upward when there's no room below, covering every list, the board, modals and the portal, with navbar menus unaffected; changelog updated
2026-11-06 18:51:50 -05:00
johnnyq
2a36534583
Add demo mode for a public demo like demo.itflow.org - $config_demo_mode = true; in config.php puts one-click sign-in buttons for Admin, Technician, Accountant and a client portal contact on the sign-in page and a demo notice on every page, and the new Demo Reset cron job rebuilds the demo nightly at 2:00 AM from db.sql with all starter content, the demo clients and the demo accounts, empties uploads except the logo and signs everyone out, keeping the company details, timezone and cron schedules; visitors can try everything except users and roles, their own sign-in details, mail, payment, AI and texting settings, API keys, backups, updates, cron, log forwarding, company, module and portal settings, custom links, starter content and share links, Debug is closed, guest links open only for someone signed in, queued email is cancelled with the reason, no sign-in alert emails are sent, certificate checks reach only public addresses on port 443, and the domain and certificate refreshers are left out; new functions/demo.php and cron/demo_reset.php, no database change, changelog, CONTRIBUTING and README updated
2026-11-06 17:46:40 -05:00
johnnyq
b391e2ce6c
Add Skyetel text messaging with two-way ticket texting, text to ticket for contacts, Text reply on tickets, a Texts inbox for unmatched numbers, verification codes and spam (codes masked, limited to credential access, every reveal audited, wiped after a day), STOP/START/HELP handling, a text log with retry and cancel in Maintenance > Text Messages, the Text Messages cron job, and texts to clients about their tickets, visits, visit reminders and invoices with per-contact opt-in from the contact, by text or in the client portal, quiet hours, and new settings in Tickets and Notifications (database 3.6.0 and 3.6.1)
2026-11-06 00:08:10 -05:00
johnnyq
3b5c11c552
Add managed mode, so one ITFlow can manage others - Admin > Managed Instances adds an instance and gives a one-time connection code (a week) that the other ITFlow pastes into the new Admin > Managed By, after which it checks in every minute from the new Manager Check-in cron job with a health report (versions, update waiting and whether it has security fixes, cron, last backup, errors today, agents against the seat limit, clients, storage) and takes back what the manager sets; the manager lists each instance's version, health, seats and last check-in with a page per instance showing what needs a look, its requests and everything it reported, can update it by hand or automatically after a set number of days (security releases straight away, not retried for six hours after a failure), set its seat limit and white-label key (locked on the instance while set), make it read-only (look, export and download only, across agents, portal, guest links and the API) or suspended (a notice with the manager's message and contact, 503 for the API) with other cron jobs paused until it is active again, sign in to it as support through a signed one-time two-minute link into a two-hour session that takes no seat, can't open the vault and can't set passwords or make API keys, and remove it, while the new Managed Instances job notifies when one stops checking in and closes requests never answered; instances only call the manager, can disconnect unless config.php sets $config_manager_required, and the Update page and queue_update defer to the manager; database 3.5.8 adds managed_instances, managed_instance_commands, settings.config_manager_keys and settings.config_managed, the logic is in the new functions/managed.php with api/managed/enroll.php, api/managed/checkin.php, login_support.php and includes/managed_blocked.php, cronJobClaim() takes a paused reason that leaves a due job due, getAgentUserLimit() and getActiveAgentUserCount() honour the manager's limit and leave out the support user, the vault helpers read a missing session key as empty, the audit log knows the new types and actions, and the email parser no longer logs an App Logs error every minute while parsing is switched off; changelog updated
2026-11-05 15:22:41 -05:00
johnnyq
3143cdb115
Fix phone numbers keeping the 0 dialled at home after the country code (+49 0172 1234567) and click-to-call dialling it - formatPhoneNumber() now writes every country's numbers with Google libphonenumber's rules from the new functions/phone_formats.php, built by scripts/phone_formats_build.php from libphonenumber v9.0.43, taking off the national prefix and a typed-in country code where what is left is still a number of that country, with the international format after the code and the national format without it, German landlines split after their area code, Italy keeping its 0 and North America unchanged; the new phoneDialNumber() gives tel: links +code and the number without its prefix, used by contactPhoneLink(), vendorDialNumber() and every hand-built tel: link on the agent side, the client portal and the guest ticket page, and the ticket quick look now dials the extension after a pause instead of running it into the number; changelog updated
2026-11-05 13:16:06 -05:00
johnnyq
cf2c9c2d9b
Let clients pay the card fee - turn on Clients pay the card fee on Stripe in Admin > Payment Providers with Stripe's percent and fixed rate, and each card payment in the client portal, through an invoice's link, by autopay or from Charge Saved Card is grossed up so Stripe's fee comes out of it, with one fee per payment shared over its invoices; the fee is shown before paying (Pay invoices, checkout, the guest pay page, invoice pages, autopay and the Charge Saved Card window) and goes on each invoice as a Card Fee line with no tax when the payment is booked, carried in the PaymentIntent's itflow_fees metadata and checked against the amount received to the cent; a client can be let off it with No card fee on their Billing tab, refunding a card payment takes its Card Fee line back off, autopay and Charge Saved Card now compare cents instead of whole dollars, database 3.5.6 adds the provider and client columns, changelog updated
2026-11-05 12:47:06 -05:00
johnnyq
aff6812036
Security: hold an agent who must set up MFA to the set up page on every request, not just at sign in, and fix the client portal two-step gate, which a path added to the URL or a second action sent with the set up one got past - both now go through requestIsMfaSetup(), which checks the script actually running and every key in the request; View as contact is refused while an agent still owes MFA set up, and agents are emailed when MFA is turned on
2026-11-04 14:01:40 -05:00
johnnyq
9b92261e8c
Security: end a user's other sessions when their password changes - each session carries a stamp of the password it signed in with and the agent and client portal checks sign out any that no longer match, covering a self change, an admin setting it, the incident-response reset, portal reset links and invites, and View as contact; a portal self change keeps the browser that made it on a new session id
2026-11-04 13:50:17 -05:00
johnnyq
8e24607a0a
Contracts: refuse impossible dates (2026-02-30) when adding, editing, activating, renewing, cancelling or starting from a template instead of failing on save; keep each term to the day of the month it started on or the last day of a shorter month so month-end contracts no longer drift (PHP, nightly renewal, the Renew window, templates, Standard terms and contract_form.js); withdraw signing requests still waiting on the client or a countersignature when a contract is cancelled, when it ends nightly or when its client is archived (singly or in bulk), and refuse signing or countersigning on ended, cancelled or archived-client contracts through the link, the portal and Countersign; leave archived clients' contracts alone nightly (no renewing, ending or reminders), keep them out of the all-clients list, Due soon and the side menu count, and refuse sending them to sign; count a self-renewing contract as due soon and remind about it only when its notice date falls within its term, so Standard terms and monthly contracts with 30 days' notice no longer remind every term; keep drawing and adding prepaid hours on a cancelled contract until its last day; refuse deleting a contract once tickets drew on its prepaid hours or it was signed by both, showing why in place of Delete; changelog updated
2026-10-28 23:51:45 -04:00
johnnyq
9ba21cf352
Assets: add NAS, UPS, PDU, Modem/ONT and NVR/DVR types from a new registry in functions/asset_type.php that sets each type's icon, tone, group, fields and details; the asset form shows only the fields a type uses (fields that already hold a value stay shown) and adds a Details section per type (CPU/RAM/storage, VM host/vCPUs, switch ports/SFP/PoE/management, NAS drives/capacity/RAID, UPS capacity/output/runtime/outlets/battery dates, PDU kind/outlets/input, modem circuit ID/ISP account, printer, phone, mobile, display, camera and NVR details) stored in a new asset_specs table (database 3.4.9); new or changed port and SFP counts add the missing interfaces, continuing the asset's numbering, skipping Wi-Fi, VLAN and management ports and never deleting any; the asset page and quick look show the details, a server or NAS lists the VMs that run on it, and Assigned and Warranty show only on types that use them; the list gets Servers & NAS and Power tabs, an optional Details column, a UPS battery badge, an Assigned picker only on assigned types, and New buttons named for what they add; nightly UPS Battery Due notifications at 45, 7 and 1 days as a Support notification; copy leaves out per-unit details, Transfer to Client carries details and interface types, export adds per-detail columns, import reads detail columns after the standard twelve (VM hosts by name, resolved after every row is in) and reports values it could not keep, and the API reads and writes asset_specs; racks, client portal, client export, overview, document templates and AI lists group the new types; fix asset import carrying physical location and notes into the next row, saving 0000-00-00 for a missing purchase date and warning on an unknown contact or location, save API and import types in the list's spelling, and keep interface types on transfer; changelog updated
2026-10-27 15:59:03 -04:00
johnnyq
01fbcda75d
Security sweep 2: API archive, unarchive, resolve and close now check the client named in the call the same as create, update and delete do (every call except read.php and time.php counts as a write); API asset, contact, network and document create/update keep linked contacts, locations, vendors, networks and folders within the record's own client; linking a contact to an asset refuses another client's contact, and unlinking only clears the contact it was linked to; agents limited to certain clients no longer see other clients' names in the asset import template file name, export filter summaries, or the messages from file moves, unlinks, ticket asset removal, bulk project add and bulk interface network; guest quote Accept and Decline post instead of being plain links and check the key with hash_equals; exports that match nothing say so instead of showing a blank page; about 30 handlers now stop with 'no longer exists' when their record was just deleted, instead of showing warnings or an error page and writing history for a record that is gone; restore_contact_note reads its own id parameter; ticket prefix pattern escaped for the v flag; missing user agent and array key parameters handled; CHANGELOG updated
2026-10-26 19:54:36 -04:00
johnnyq
0e272910fb
Client portal: invite people by email from a client's Contacts (Invites tab with send again, cancel, search and sorting) or by the primary contact in the portal, several at once with optional names and roles, each joining from the emailed link with their own name, title, phone and password or Microsoft 365 and becoming a contact then, an existing contact with that address being given access instead; self sign-up from Create an account on the sign-in page for addresses at a client's Domains when it is on in Admin > Settings > Client portal and for that client, verified by an emailed link and joining as a plain contact with agents and the primary contact told; the same answer whatever address is entered, per address and per IP limits and a hidden field for bots; nightly clean-up of unused links; six new email previews; new functions/portal_invite.php, client/invite.php, client/join.php and client/signup.php, replacing the unused contact_invite modal; DB 3.4.6 adds portal_invites, client_portal_signup and config_client_portal_signup
2026-10-25 01:07:53 -04:00
johnnyq
0f9038b1ed
Contracts stage 3: prepaid hours - hours included each month, and blocks bought with a price, expiry, note and an optional draft invoice; a nightly draw of billable ticket time, oldest ticket first from the hours that run out first, with Draw now and Put back, and a ticket the hours run out on staying in Unbilled Time at the usual rate; Prepaid hours card, a low hours email to the owner, and hours left on the contracts list, client overview, ticket, Unbilled Time and the client portal; [Monthly Hours] placeholder; new functions/contract_hours.php; DB 3.4.4 adds monthly hours and the alert level to contracts and templates, plus contract_blocks and contract_block_uses
2026-10-25 01:06:27 -04:00
johnnyq
d0620067a1
Contracts stage 2: each contract is a document with placeholders ([Client], [Start Date], [Rate], an [SLA] table and more) to preview, print or download as PDF; Send to sign emails a contact or anyone a link to sign with a drawn or typed signature, from the link or the client portal (Billing > Contracts and the home page list of ones waiting); Countersign makes a draft active and emails the PDF signed by both with its signing trail and document fingerprint; Signing card with copy link, send again, withdraw and earlier requests; changing the document while it is out for signature withdraws the request; contract emails in Mail > Previews; new functions/contract_signature.php and functions/contract_pdf.php, guest/guest_view_contract.php, client/contracts.php and client/contract.php; DB 3.4.3 adds contract_signatures and keeps any stored signature as a recorded round
2026-10-25 01:05:42 -04:00
johnnyq
be374e9c2b
Rebuild Admin > Ticket Statuses: list on the standard pattern with In use and Switched off tabs, search, sortable headers, ticket counts linking to the tickets, SLA clock and client-reply columns and drag ordering for the pickers and board; one New/Edit window with badge preview, colour swatches and a description shown on hover across the app; per-status choice of whether a client reply by email or portal moves the ticket back to Open or leaves it; switch off and delete move a status's tickets to a chosen status with ticket history and SLA sync, and clear canned responses that set it; built-in statuses keep their names, stay on and have fixed SLA and reply behaviour enforced server-side; badges use readable text colour; the tickets filter keeps a switched-off status; database 3.4.0 adds ticket_status_description and ticket_status_client_reply; new functions/ticket_status.php
2026-10-24 15:14:10 -04:00
johnnyq
2b401cb405
Custom Links rebuilt: tabs for the agent menu, top bar, client portal, admin menu and reports menu with counts plus All and Archived, search by name, address or description, sortable columns, each link with its icon, description, address and new-tab marker, links whose address can't work flagged; drag into order on a menu's tab or move up and down, new links at the end of their menu in place of the Order number; one add and edit window with a live preview of the link in its menu, an icon picker with search, a description shown on hover and a new-tab switch that follows the address until changed; copy, open, archive, restore and confirmed delete; addresses limited to web addresses, ITFlow pages, mailto, tel and the remote tool schemes asset links allow, with javascript and data refused and old ones drawn as going nowhere; menus read one shared helper, the agent menu's links sit under Tools even without Reports, the admin menu's get a Links heading, new-tab links get a small arrow, links without an icon get the link arrow and every link shows its description on hover; fixes mailto and tel links showing as unsupported in the side menus, the portal menu taking any address, the delete message missing the name and the new-tab tick never showing; edits audit what changed from what to what; adds functions/custom_link.php and js/custom_link_form.js, no database change; changelog
2026-10-24 14:03:40 -04:00
johnnyq
dfc708145d
Vendor templates stage 1: Admin > Vendor Templates rebuilt on the standard list with Active and Archived tabs, support line, hours and SLA, how many clients have a vendor from each, last used and changed by, sortable and searchable including by support line; new template page with what a vendor starts with, the clients with it and their account numbers, the license templates that use it, made and changed by, and history; shared New/Edit window on the vendor window's tabs with per-field push to the vendors made from it, each logged on the vendor; copy, archive, restore and delete with vendors and license templates unlinked on delete; Make a template from a client's vendor, linking the vendor to it, and the vendor page linking its template for admins; Delete offered to every admin role, not only the built-in Administrator; the admin handler no longer includes the agent vendor handler; database 3.3.4 adds vendor_template_created_by and vendor_template_updated_by, backfilled from the audit log
2026-10-19 12:34:53 -04:00
johnnyq
a5a43e37ac
Audit logs stage 3: failed sign-ins say why and are logged against the account they were for - wrong password, no account with that email, disabled, archived or invited account, client archived, portal turned off, a wrong MFA or two-step code after the right password - with failed Microsoft 365 portal sign-ins logged too and marked Their account in the audit log; the IP lockout counts portal failures as well; the first sign-in from an IP address is badged New IP in the audit lists and quick look; new Admin > Sign-ins under Access with People and IP addresses views, search, date filter, sortable columns and paging; admins get a notification and an email on a run of failed sign-ins or turned-away API calls from one address or against one account, set in Settings > Security (10 to start, 5, 20, 50 or never), each in the audit log Security view and in Mail > Previews; API calls counted per key, day and endpoint, with a 30-day calls column and last IP on API Keys and a usage window, expired-key calls logged against the key, and usage deleted with the key and after the log retention; database 3.3.2 drops the unused auth_logs table and adds settings.config_login_alert_failures and api_key_usage; new functions/sign_in.php, admin/sign_ins.php and admin/modals/api/api_key_usage.php; the license template page no longer warns when view is missing
2026-10-19 00:56:52 -04:00
johnnyq
ea23a2bad5
Audit logs stage 1: Admin > Audit Logs rebuilt on the standard list with search, sortable columns and paging, filters for date, who (agent, portal contact or ITFlow itself), client, type and action, and counted views for Changes, Deletions, Sign-ins, Security and Data out; each entry shows who with their avatar, the client, the type and action as a coloured label, the description without the name in front, the IP and device in words, and links to its record while it exists or says No longer here; a quick look with the full entry, the raw user agent, everything from that IP, the record's other entries and what the same person did 15 minutes either side; CSV/PDF export with the page's filters, view and picked columns, itself audited; new functions/audit_log.php, admin/modals/audit_log/audit_log.php and audit_log_export.php, admin/post/audit_log.php and audit_logs export columns; agent/files.php takes ?open= for a file's quick look; database 3.3.1 adds log_client_id and log_entity_id keys on logs, gives each action one name (Unarchive/Restored to Restore, Deleted, Merged, Closed, Reopened, Resolved and Sent to Delete, Merge, Close, Reopen, Resolve and Send, Client Access to Denied, saved card and payment provider Updates to Create or Delete, contract template Update to Edit, type client to Client) and repoints entries at the right record (reply edits and redactions to the ticket, API document edits to the document, reimbursements to the recording expense, API client restores to the client), guarded so it can run again; logAudit call sites in agent, admin, api, client, cron and functions use the same names and record ids
2026-10-18 22:36:25 -04:00
johnnyq
0b6f002d49
Ticket templates stage 3: request forms in the client portal - a template can be offered there under its own title, description and icon, to everyone with portal access or primary and technical contacts only, at every client or the ones picked (migration 3.2.1 adds the ticket_template_portal columns, ticket_template_portal_clients, and fill_in_client, ticket_fill_in_client and recurring_ticket_fill_in_client); New ticket in the portal starts with a choice of Report a problem or one of the forms, home lists them under Ask for something, and a form asks the fill-ins set to ask the client plus anything else, files and the device when the template mentions [Asset], then raises the ticket set up as the template says with its category, priority, billing, agent (notified), due time, tags and the tasks for those answers, the client's notes first in the details and who asked in its history; fill-ins can be kept for agents to answer, marked on the agent's ticket and left off the client's Request details; the template window gets a Client portal tab, the template page a card showing how and where it is offered and its requests, and the list marks the ones in the portal; a copy starts off not offered; forms a contact may not use are refused by link or post, and View as contact raises nothing; [Agent] is no longer filled with a client's name for a portal ticket with no agent; changelog updated
2026-10-18 01:11:12 -04:00
johnnyq
9457442804
Emails stage 3: every email now goes through emailQueue and the shared layout - the client portal invite sends a link to set a password (or to sign in with Microsoft) instead of the password itself, offered on New Contact as well as Edit through portalMailInvite, with Forgot password, password changed and two-step sign-in emails through portalMailPasswordReset and portalMailAccountChange; shared link and code emails with the note quoted and the whole link printed under the button, replacing shareMailHtml and shareQueueMail; calendar invitations, updates and cancellations with when, repeats, where, the description and a join button; Email on the contacts and clients lists in the layout from one of the configured mailboxes with an optional greeting and send time, leaving out archived contacts and contacts without an address, each address once, nothing queued without mail set up, through emailBulkSend and emailBulkPost with a shared bulk_email_fields window; Admin > Mail > Previews shows all 52 emails built by their real senders on sample records inside a rolled-back transaction with emailQueue capturing and custom actions off, with computer and phone widths and Send me a copy; emailHtml gains content and button show_url, emailQueue gains queued_at and always so billing still queues as before, plus emailMailboxes and emailTestSend; ticketMailCreated, ticketMailReply, ticketMailWatchersAdded, ticketMailTaskApproval, ticketMailClosedReply, ticketSlaAlert and billingMailCardSaved moved into functions; fixes Email on the contacts list queuing mail to contacts with no address, the clients list including archived contacts, and both taking any From address posted; changelog updated
2026-10-17 23:26:25 -04:00
johnnyq
0a4aabbf9a
Emails stage 2: agent and staff emails in the shared email layout with an Open in ITFlow button - assigned to you (assignee pick, Bulk Action, New Ticket and Edit, several at once as one list, recurring tickets the same way, nothing when assigning yourself), new ticket to the new-ticket address (portal, email or scheduled, with what they wrote), client replied to the assigned agent (portal or email, with the reply), SLA at risk and missed to the SLA alert address and the assigned agent, scheduled work and its cancellation to the agent, contact and watchers with the calendar file, a new agent's sign in details, account changes, new device and failed MFA sign in alerts, a login sent back through a shared link, the Admin > Mail test email and the portal's saved card confirmation; nothing is queued when outgoing mail is not set up; fixes backslashes before apostrophes in the parser's new ticket and reply emails, emails skipped when no SMTP host was set for Microsoft 365 or Google mail, and the saved card email's wording; adds emailSettings(), emailReady() and cal_str to functions/email.php, the ticket agent email functions, userMailNewAccount() and userMailSignInAlert(), a new sendSlaAlert() signature, removes userQueueMail() and updates the changelog
2026-10-17 22:47:52 -04:00
johnnyq
e29369926f
Client portal stage 4: accounts - Your account rebuilt with details and an ask-us link, phone numbers, ticket email choices, password change needing the current password and 8 characters with an email notice, two-step sign-in with an authenticator app set up from a QR code, remembered browsers with Forget them, phone PIN and recent sign-ins with the device; activity rebuilt with signing-in and changes tabs and paging; sign-in asks portal users with two-step sign-in for a code, remembers the browser on request and locks an account after five wrong codes in ten minutes, matching portal users by contact_user_id; Admin > Client Portal can require two-step sign-in, sending anyone without it to set it up first, and agents can turn it off for a contact from the contact page; password links stored as SHA-256 and running out after an hour for Forgot password and a week for invites, the nightly run clearing only run-out links, Forgot password limited to one email per account every five minutes and ten requests per address in ten minutes, the reset page rebuilt with the password typed twice and a confirmation email, fixing the empty-token check that let anyone trigger the reset email; contacts choose every ticket email or replies and fixes only, and primary and technical contacts can hear about new tickets at their company or every update, honoured by agent, portal, email parser and recurring ticket emails; announcements for every client or one with tone and start and end dates on the portal home page, managed in Admin > Client Portal; View as contact opens the portal read only as a contact from the agent contact page, audited, with billing shown only when the agent's role reads sales and financial, nothing written or paid while viewing; agent contact page shows two-step status, last sign-in and ticket email choices; database 3.1.0 adds portal_announcements, contact ticket email columns and config_client_portal_require_mfa and hashes outstanding links; new functions/portal.php; changelog updated
2026-10-17 12:05:55 -04:00
johnnyq
5e77edb077
Client portal stage 3: Your IT - Devices with tabs by kind (Computers, Servers, Network, Phones and tablets, Other) with counts, an Everyone's or Mine filter, search and warranty badges when expired or expiring; a device page with make and model, serial, OS, user, location, purchase date and age, warranty, status, open tickets and licenses on it, Report a problem opening a new ticket with the device picked and plain contacts reaching their own devices from home; Licenses with All, Renewing soon and Expired tabs showing seats in use and renewal state without license keys; Domains and certificates on one page with registrar, DNS, website and email vendors, expiry and auto-renew, and a certificates tab with short-lived certificates shown as renewing themselves, the old certificates page redirecting there; Documents as a help library of client-visible documents with folder tabs and full-text search, a document page keeping its own tables and colours under a widened style policy, files to open or download with the first PDF or image shown inline, Print and Ask us about it, and new documents written in the editor or uploaded as a file with an agent notification; Contacts listing everyone primary first with roles and search, and the primary contact alone adding and editing contacts, giving portal access with an emailed set-password or Microsoft 365 invite, resending it, turning access off and marking someone as left, which turns off access and opens an offboarding ticket, all audited and notified; home renewals and devices linking to their pages; fixes a technical contact being able to change the primary contact's login email, revoked contacts staying signed in, portal documents recording the contact id as author, the upload stub going in unescaped and gated pages leaving a bare header; check_login ends sessions without a sign-in method, header.php buffers output so gates redirect properly, enforceContactCan sends contacts home with a message instead of logging them out, add_contact and edit_contact replaced by portal_contact_save, portal_contact_access and portal_contact_left, new Your IT helpers in client/functions.php and portal tile, roles, PDF and document styles; changelog updated
2026-10-17 02:40:59 -04:00
johnnyq
e84e3e7e49
Client portal stage 2: billing in the portal - invoices and quotes open in the portal with PDF download and print, Pay invoices pays several invoices as one Stripe card payment with a saved card or a new card on a checkout page (one payment per invoice under a shared reference, booked once under a lock, one receipt and one paid notification), quotes accepted or declined with the contact's name and a note plus signed copy or PO upload, payments list with printable receipts, statement with aging and the shared statement PDF, recurring invoice page with autopay, Cards and autopay on one page, quotes waiting and past-due invoices on home, Ask us links prefill a ticket subject; shared billingQuoteAnswer and billingQuoteAddFiles used by the guest links too, new functions/billing_pay.php, Stripe-aware CSP for card pages with js/portal_stripe.js, nightly Stripe fee reconciled once per payment reference, Stripe refund limited to the payment's own amount, old add_payment_by_provider removed
2026-10-17 02:12:05 -04:00
johnnyq
c6eadf3fa3
Client portal stage 1, look, home and tickets: a new light shell with the company logo or initials on the theme colour, sections shown by what each contact may open (Home, Tickets, Billing for billing contacts, Your IT for technical contacts, custom links), New ticket and an account menu with a dark mode switch kept in a cookie, a bottom tab bar and slide-in menu on phones, and the welcome banner removed; a rebuilt home showing what needs the contact (tickets waiting on their reply or to confirm, approvals, past-due invoices), open tickets, balance with Pay invoices, renewals in the next 45 days, their devices with warranty status and the company phone and email; tickets rebuilt with Open, Waiting on you, Resolved, Closed and All tabs with counts, search, paging and the whole company's tickets for primary and technical contacts with a Mine filter, the old all-tickets page redirecting there; a ticket page with progress steps, the conversation oldest first, approvals, details alongside, replies with drag and drop attachments, It's fixed, close or reopen and rating; New Ticket with priority, category, device and attachments; fixes downloading files from internal notes, files on closed tickets not downloading, new tickets linking to another client's device or a non-ticket category, empty replies and tickets being accepted, PHP warnings on Pay invoices and Recurring invoices with no payment provider, and Bootstrap icons and the editor setup blocked by the portal CSP, which now allows data: images; new js/portal.js and portal helpers in client/functions.php, ticketPortalStatusHtml removed; changelog updated
2026-10-17 01:28:27 -04:00
johnnyq
2fcdd6006b
Invoices, quotes and recurring invoices makeover stage 4: quote lines billed one time or each month, quarter or year with a Billed choice on the add-a-line row and in Edit Line, quotes grouped into One-time, Each month, Each quarter and Each year with a total for each on the page, PDF and client view, lines dragged within their own group, Start Billing on accepted quotes putting one-time lines on a draft invoice due on the client's terms and each recurring part on a new recurring invoice from a chosen date, emailed or left as drafts, or added to one of the client's recurring invoices of the same frequency, with an option to bill the first period on the invoice, an Invoiced as card on the quote linking every invoice and recurring invoice it became including ones it added lines to, From links back on invoices and recurring invoices, monthly amounts in the quotes list and its totals, search, client portal, quote email, Send and Copy windows, quotes export and client export, and Quotes Pipeline valuing quotes at up front plus a year of recurring lines. Fixes Make Invoice invoicing a quote twice or one never accepted, and its audit entry using the current quote prefix instead of the quote's own. Adds DB 2.9.3 with item_frequency, quote_monthly_amount, invoice_quote_id and recurring_invoice_quote_id, linking invoices to their quotes from history, quoteConvert() as the one invoicing path claiming the quote in a transaction, quoteLineGroups(), quoteAmountText() and quoteMadeFrom(), reportCsv() totals written as given, and updates the 26.11 changelog
2026-10-16 14:14:53 -04:00
johnnyq
422088fb60
Invoices, quotes and recurring invoices makeover stage 2: per user, per device and per license recurring lines that take their quantity from the client's contacts (all or tagged), devices (ticked types or tagged, lost/stolen/retired left out) or a license's seats (in use or bought), counted again for every invoice with an optional contract minimum, set from a Counted choice on the add row or the full Quantity from section in Edit Line with a live count, marked on each line and listed in a new Seats card with Update now when the client has changed, quarterly frequency alongside monthly and yearly counted as a third in MRR on the dashboard, client pages, client portal and reports, period words {month} {quarter} {year} {period} filled into scope, notes and lines, schedule card showing the period the next invoice covers, recurring_invoice_anchor_day so month-end schedules return to the 31st after a short month, nightly run and Invoice Now consolidated into recurringInvoiceGenerate() which claims the run so it is billed once, refreshes seat counts and takes taxes at current rates, nightly run now bills runs missed by up to 7 days, Invoice Now bills the next run early and moves the schedule on from that run instead of restarting from today, recurring email goes to non-archived primary and billing contacts once per address and stays a draft when outgoing mail is not set up. Fixes portal recurring card ignoring yearly-only clients and counting archived ones, edit recurring invoice resetting the billing day. Adds DB 2.9.1, recurring_invoice_sync and recurring_seat_count handlers, itflowBillingSeatForm(), and updates the 26.11 changelog
2026-10-16 13:09:59 -04:00
johnnyq
15844faa9b
Rebuild all reports on a shared framework (functions/reports.php, inc_report.php, inc_report_layout.php, js/reports.js) with period, client and agent filters, sortable tables, CSV export of any table and clean print layouts, add Client Review (QBR), Renewals & Expirations, Asset Lifecycle, Documentation Coverage, Customer Satisfaction, Open Ticket Aging, Client Profitability, Quotes Pipeline and Mileage reports, make Budget vs Actual editable with save and copy-last-year, rename reports to say what they show, enforce module and feature access on every report page, exclude transfers from income via dashboardRevenueSql, limit portal ticket ratings to Good or Bad, seed ratings and Windows 10 holdouts in demo data, link Client Review from the client menu, and update the 26.11 changelog
2026-10-16 00:04:40 -04:00
johnnyq
64d938db7f
Tickets modernization: list redesign with Open/Mine/Unassigned/Needs reply/Waiting/Overdue/Scheduled/Closed/All views, whose-move indicator, SLA and due badges, in-row status/priority/agent pickers, collapsible filters and phone layout; kanban board redesign with drag-to-resolve/reopen rules and dark mode; new ticket quick look modal; New Ticket modal with asset/contact prefill and already-open warning; Edit Ticket modal rework; recurring tickets list rework with pause/resume, raise now, plain-language schedules, next-run preview and bulk actions, cron skips paused and raises missed runs once; shared ticket tables on asset/contact/location/vendor/project pages; Also open card on ticket detail; portal waiting-on-your-reply status; merge limited to same client; closed tickets no longer editable from modals or API; consistent access checks across ticket modals, post handlers and ajax endpoints; new functions/ticket.php helpers; removed recurring_ticket_model.php; DB 2.8.5 adds recurring_ticket_paused_at and cleans orphaned recurring ticket rows
2026-10-15 15:29:10 -04:00
johnnyq
e4c8130ebe
Certificates: Check now connects to the host and saves what it serves - issuer, issued and expiry dates, names covered, SHA-256 fingerprint and the PEM - with the result (OK, name mismatch, untrusted, expired or unreachable) and when it ran, and a check that reaches nothing keeps the certificate on file; New/Edit form split into tabs (Certificate, Paste or by hand, Notes) with a Check button that shows what the host serves before saving, the host tidied from a pasted web address, the name defaulting to the host, the domain picked from the host and limited to the client's own, and a PEM paste or issuer and expiry by hand for hosts ITFlow can't reach; new certificate quick look with the check result and what to do about it, names covered, fingerprint copy, PEM copy and .crt download, domain, services, notes and history; certificates list rebuilt with All/Starred/Expiring soon/Expired/Problems/Not checked pills, host and names covered, domain link, issuer filter, last check column, whitelisted sort, ?open= and bulk check/star/archive/restore/delete; short-lived (ACME) certificates only count as expiring soon inside 20 days and skip the 45-day alert; domain and service quick looks link certificates to their quick look (with New certificate from a domain), global search finds certificates by name, host, names covered or fingerprint, client overview gets a Certificate problems box and renewals open the certificate, dashboard links to Expiring soon, client portal shows expiry badges, export adds last check, names covered, fingerprint and more, documentation PDF adds host and last check; certificate refresher now checks hosts daily in a time-boxed batch, writes history and notifies when an OK certificate turns bad; nightly alerts skip archived certificates and open the certificate; API create uses the same form rules and checks the host; demo data adds firewall, remote access and RADIUS certificates with real check results. Fixes the delete audit log using an undefined name, the archive flash type, certificates linking to another client's domain, services linking to another client's certificates, PEM parsing assuming an issuer organisation, and the API create using an undefined variable. DB 2.8.4
2026-10-15 01:07:32 -04:00
johnnyq
75df17698b
Domains makeover: rebuilt domains list with expiry pills (red expired, amber close, blue close but auto-renewing), registrar and hosts shown once per vendor with their roles, SPF/DMARC/DKIM email pills, filters for Starred, Expiring in 45 days, Expired, No auto-renew and Email gaps with counts, registrar-or-host and tag filters, search across notes, hosts and tag names, safe column sorting, open straight to a domain with ?open=ID; new domain quick look with expiry, auto-renew, registration date and status, who registers it and hosts DNS, website and email, A/NS/MX records to copy, plain-language email checks (SPF strictness and duplicates, DMARC policy, DKIM at common selectors), certificates, services, the registrar and host logins, notes, TXT records, raw WHOIS and history; tabbed add/edit form that tidies pasted addresses to the domain, checks the name as it is typed (saved as, subdomain, already on the client), auto-renew switch, star, tags, client and our own vendors as registrar and hosts, Registrar does it all; add several domains at once from a pasted list; bulk look up now, set registrar or host, tags, star and unstar; domain tags (tag type 7) with a starter pack; refresher looks up a batch of up to 50 a run, never-checked, stale and soon-to-expire first; expiry alerts skip archived domains and clients, mention auto-renew and open the domain; vendor Domains tab opens the quick look and adds a domain with that vendor as registrar, our vendors get a Client domains tab; service quick look, overview renewals and search open the domain; client portal shows days to expiry and auto-renew; more export columns and filters; demo data with auto-renew, varied DMARC and DKIM, WHOIS lines and campaign domains near expiry. Fixes lookups, edits, the refresher and API updates wiping expiry dates and records when a lookup came back empty, edits logged without a client and dropping a past expiry date, every edit running slow lookups, expiry alerts for archived domains, deleted domains left on services and certificates, bulk archive needing delete rights and list actions limited to admins, registrar and host pickers accepting another client's vendors and dropping our own on save, services linking other clients' domains, a new client's website domain not added when its expiry could not be found, the WHOIS summary cut at 254 characters, and API names, vendors and duplicates not checked. Adds functions/domain.php helpers, domain quick look and shared form, domain_check lookup; removes domain_model.php. DB 2.8.3
2026-10-15 00:09:09 -04:00
johnnyq
6ff9dbe9a4
Files and documents everywhere else: asset and contact quick looks list their documents and files with the same tiles and rows as the document page, files opening their quick look instead of a raw download; client overview share links show document and file tiles and open the document page or file quick look; service quick look shows linked documents as tiles and leaves out archived ones, service add and edit document pickers carry an icon and summary; global search shows file and document type tiles in the palette and on the results page, and a file result opens its folder narrowed to that file; quote attachments show their tile and size, open the file quick look and download through file.php instead of linking straight into the uploads folder; ticket attachments show their file type tile; client portal documents list shows the document tile, folder and summary with the last updated date; removed unused modals/asset/asset_documents.php
2026-10-14 20:47:30 -04:00
johnnyq
69484a8a2e
Replace Tom Select with ITFlow's own select picker: native select stays the source of truth, search, checklists for multi selects, add-your-own for tag fields, phone sheet, and client/agent/contact avatars, tag and category colours, priority dots and asset icons in the options
2026-10-13 12:41:29 -04:00
johnnyq
9bfd26d57b
Add titles to icon-only buttons
...
- title on 294 icon-only buttons, named for what each one does
- aria-label on the 7 show-password buttons (title becomes the popover
header) and the portal mobile nav toggle
- Fix dead add-category button on products filter, credential bulk tag
button now preselects Credential, drop duplicate inner-icon titles
2026-10-08 17:12:21 -04:00
johnnyq
49106e2a80
UI fixes: confirm irreversible actions, keep reply drafts guarded, re-enable CSP on portal recurring invoices
...
- Add confirm-link to 14 one-click delete/disable links (asset, contact,
files, templates, logo, MFA, calendar event, disable user, cancel schedule)
- confirm_modal.js treats btn-danger / btn-outline-danger as destructive
- Replace per-editor window.onbeforeunload with one guard over all editors
- New js/autosubmit.js replaces inline onchange in the portal; CSP back on
recurring_invoices.php
- Fix blank user name in disable_user audit log
2026-10-08 16:47:12 -04:00
johnnyq
5acb1802bb
Security: scope set_recurring_payment to the client's own invoice and payment method
2026-10-08 16:02:21 -04:00
Wrongecho
c4843095b2
Potential fix for Stripe charges being off by a cent
2026-09-22 16:01:46 +00:00
wrongecho
fa4beea116
Client Portal - Use flexbox to fix layout breaking
...
Updated header layout to use flexbox for better alignment and spacing thanks to @BoredManCodes
2026-09-06 20:24:05 +01:00
wrongecho
70cb378c12
Client Portal - Fix navbar
...
Thanks to @BoredManCodes
2026-09-06 20:15:29 +01:00
johnnyq
bcdfab996c
Fix approval Syntax
2026-08-31 17:52:44 -04:00
johnnyq
c89e3a90d4
Add Proper footers to Guest Area and client portal
2026-08-31 13:24:32 -04:00
Wrongecho
9bc0bf0b7b
Stripe ID creation/linking for guest flows (wip)
2026-08-30 12:42:12 +01:00
Marcus Hill
231651b603
Make saved payment wording clearer
2026-08-30 11:10:11 +01:00
johnnyq
bd7f67aa5b
Enhancement: Files: Document and Files are easily distinguashable now with the option to choose all docs or just files. Thumbnails view now shows all files, Previews now available for documents, pdfs, txts etc, List view and Thumbnail view now retain in search param when navigating folders
2026-08-28 17:33:04 -04:00
johnnyq
156c51224d
Fix client portal review findings: PIN wipe, log indexing, statement currency (db 2.7.8)
...
Setting a PIN containing < or > silently cleared it: the length check ran before escapeSql(), whose strip_tags() then emptied the value, and the UPDATE stored the blank while flashing success. Length is now checked after sanitising.
Password and PIN changes require the current password. SSO contacts are exempt - no local password to check, and the IdP already did it.
New index on logs(log_user_id, log_client_id) for the portal profile and activity pages, which were scanning the whole table twice per profile view. admin/audit_logs.php's date filter rewritten as a half-open range so KEY log_created_at is usable - DATE(log_created_at) BETWEEN made it non-sargable.
Portal statement page and PDF now render in the client's currency, matching the guest view and the emailed statement.
Quick Send asks for confirmation; confirm-link extended to submit buttons.
Portal audit entries logged an empty name - client/post.php used , which only exists agent-side.
2026-08-28 16:38:42 -04:00
johnnyq
be20810d18
Use Datatables for User Activity on the client portal
2026-08-28 16:19:27 -04:00
johnnyq
10fb40f36f
Feature: Major spruce up of the client portal profile page, added Department, Location, Title, Phone with Edit, editing Pin, Recent signins and recent activity along with a seperate activity page
2026-08-28 16:08:23 -04:00