Tickets CAD v3.44.0 — Major Update Available for Testing on GitHub

12 views
Skip to first unread message

Eric Osterberg

unread,
Mar 14, 2026, 10:30:00 PMMar 14
to open-so...@googlegroups.com, openises...@lists.sourceforge.net, open-sourc...@googlegroups.com

Hi everyone,

We have a significant update to Tickets CAD available on GitHub and we're looking for testers. This is a great opportunity to support the project — we're all volunteers, and testing is one of the most valuable ways to contribute to this community. You don't need to be a developer to help. If you can install the software and click around, you're exactly who we need.

What's in this update:

  • Security hardening — SQL injection vulnerabilities have been fixed across 500+ files using prepared statements. This is the single largest change in this release and addresses a critical weakness in the codebase.
  • PHP 8.x compatibility — Numerous fixes for deprecation warnings, NULL handling, and function changes so Tickets CAD runs cleanly on PHP 8.2+.
  • Tile caching proxy — New tile source options on the Set Default Map page. You can now choose between Online Direct, Proxy Cache, or Offline Local tile modes. Proxy Cache is recommended for most installations as it reduces load on tile servers and improves performance.
  • Personnel/Member improvements — Click-to-set-location on member add/edit maps, photo upload fixes, and better form validation.
  • CSV report downloads — Reports can now be exported to CSV format.
  • Various bug fixes — Map position saving, search crashes, NULL value handling, mobile map popup errors, and more.

How to get the update:

The latest version is available on GitHub at:
https://github.com/openises/tickets

SourceForge will not be updated immediately. GitHub is the place to get the latest version.

Option 1: Download as a ZIP file (easiest)

If you're not comfortable with git commands, you can download the entire project as a ZIP file:

  1. Go to https://github.com/openises/tickets
  2. Click the green "Code" button near the top right
  3. Click "Download ZIP"
  4. Extract the ZIP and replace your existing tickets folder with the contents

Option 2: Using Git (recommended for ongoing updates, easiest to apply updates to)

If you have git installed (or want to try it), these commands will get you set up. Open a command prompt or terminal and run:

cd /path/to/your/webserver/htdocs
git clone https://github.com/openises/tickets.git

This creates a tickets folder with the latest code. If you've already cloned the repository previously, you can pull the latest changes instead:

cd /path/to/your/tickets
git pull origin main

That's it — two commands to stay current.

Back up first!

Before updating, please make a backup so you can easily revert if needed:

  1. Copy your existing tickets folder to a safe location — for example, rename it to tickets_backup_20260314 or copy it somewhere outside your web server directory.
  2. Back up your database using phpMyAdmin (Export) or from the command line:
    mysqldump -u your_username -p your_database_name > tickets_backup_20260314.sql
    
  3. Your incs/mysql.inc.php file contains your database connection settings. This file is not included in the repository, so it won't be overwritten — but it's good practice to back it up anyway.

To revert to the previous version:

If you run into problems, simply:

  1. Delete or rename the updated tickets folder
  2. Restore your backed-up tickets folder to its original location
  3. If needed, restore your database backup:
    mysql -u your_username -p your_database_name < tickets_backup_20260314.sql
    

How to report issues:

If you find a bug or something doesn't work right, please reply to this message with:

  • What you were doing when the problem occurred
  • The error message (if any) displayed on screen
  • Your PHP version and operating system (if known)

If things are working well, we'd love to hear that too — a quick "tested on PHP 8.x, looks good" is genuinely helpful.

Thank you for your time and for being part of this community.


Eric Osterberg


d.walenczak

unread,
Mar 15, 2026, 9:37:29 AMMar 15
to Open Source CAD - Dev
On the surface looks good.

I'm still a little confused as to why we're running two abstraction layers (mysql2i shim and db) in parallel with a lot of the same functionality duplicated. That said, I do like how the new db prepared statement has automatic implicit type detection if it is not declared explicitly. Perhaps we can deprecate one or the other -- or merge their functionalities into one. I would assume that would be the db include file as I would imagine majority of the security fixes have been done with that in mind.

I'm also having a hard time upgrading from the last version to the current. I had coded it such that when a version mismatch is detected (between database declared version and that of the installer), it would force you to the install.php after login. However, now it is redirecting to a blank login page with no content loaded. Not sure if that's an edge case I didn't adequately test for in my own code, a breaking change in the new code not compatible with the old install -- or an AI assumption that was incorrect, or a git pull error (which, is possible by probably unlikely as I've sync'd my dev fork before git pull).

I'll keep testing and let you know. Have you testing installing over an old version in your tests?

d.walenczak

unread,
Mar 15, 2026, 12:14:05 PMMar 15
to Open Source CAD - Dev
This one is on me.

The version I submitted seems to be broken (for sending users needing an upgrade to install.php). I must have only tested it when there was no version available. I will see if I can get a fix and submit it. My apologies.

Eric Osterberg

unread,
Mar 15, 2026, 12:15:59 PMMar 15
to open-sourc...@googlegroups.com
Don't worry about it. I will include that and the work I'm doing today. 

I have a $200 a month package with Claude code and API tokens available for overages. I've had Claude cranking around the day and night for the past 36 hours making changes..
The code base is significantly different about every 20 minutes

--
You received this message because you are subscribed to the Google Groups "Open Source CAD - Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to open-source-cad-...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/open-source-cad---dev/f7c28cca-8022-4774-9866-eda40bd60fc1n%40googlegroups.com.

d.walenczak

unread,
Mar 15, 2026, 1:06:37 PMMar 15
to Open Source CAD - Dev
Just be careful relying on AI.

It has a tendency to make spaghetti code with parallel redundancies, dead ends, and useless stubs. I'd suggest a manual review of changes.

If you want to throw in the fix for this in your workflow, in index.php, replace the redirect condition from:
if ($installedVersion === null || $installedVersion !== $version) {
To:
if ($installedVersion === null) {

And then in login.inc.php, change:
function redir($url, $time = 0) {
echo '<meta http-equiv="refresh" content="', $time, ';URL=', $url, '">';
To:
function redir($url, $time = 0, $top = FALSE) {
if ($top) {
echo '<script type="text/javascript">top.location.href=' . json_encode($url) . ';</script>';
echo '<noscript><meta http-equiv="refresh" content="', $time, ';URL=', $url, '"></noscript>';
} else {
echo '<meta http-equiv="refresh" content="', $time, ';URL=', $url, '">';
}
die;
}

And add this:
if (!function_exists('tickets_get_versions')) {
require_once __DIR__ . '/versions.inc.php';
}
$versionMeta = tickets_get_versions();
$versionMismatch = ($versionMeta['installed'] !== null && $versionMeta['installed'] !== $versionMeta['installer']);
$isAdminPlus = ($level <= $GLOBALS['LEVEL_ADMINISTRATOR']);

if ($versionMismatch && $isAdminPlus) {
$extra = 'install.php';
$protocol = ($https) ? "https" : "http";
$url = $protocol . "://" . $host . $uri . "/" . $extra;
redir($url, 0, TRUE);
exit();
}

Before:
if($level == $GLOBALS['LEVEL_UNIT']) { // 3/1/12

d.walenczak

unread,
Mar 15, 2026, 1:11:28 PMMar 15
to Open Source CAD - Dev
Oh, and it seems the top navbar displays the navigation tabs on the index page prior to login. This results in it throwing errors on a number of those pages without the user being logged in or exposing the SOPs to external unauthenticated users, as it does not have user authentication gating before being displayed.

Eric Osterberg

unread,
Mar 15, 2026, 3:38:56 PMMar 15
to open-sourc...@googlegroups.com
And here's the review from your report. AI generated...

That's a security concern — unauthenticated users seeing navigation and potentially accessing pages like SOPs. Let me investigate immediately.

Read index.php entrypoint and reviewed security hardening notes

The index page uses frames — top.php (navbar) loads in the upper frame, and main.php loads in the lower frame. Both load immediately without any authentication check. Let me check top.php and main.php for auth gating:

Read top.php file to examine session and user initialization code

Now let me see the navigation buttons section — what's rendered in the HTML:

Read top.php file section containing HTML body initialization code

Now I understand the full picture. Here's how top.php works:

  1. Line 1370: The buttons row (<TR ID='buttons'>) is rendered with STYLE="display: none;" — it's hidden by default
  2. Line 1128: show_butts() is only called inside the else block (logged in) at line 1113
  3. Line 1110: if (empty($_SESSION)) — pending login — skips show_butts(), mu_init(), etc.

So the buttons are server-side rendered in the HTML but CSS-hidden and only shown via JavaScript show_butts() when logged in. However, the PHP-side is_guest() checks on lines 1383-1467 still emit the HTML for buttons like SOPs, Config, Reports, etc. — they're just hidden. The is_guest() function checks the session level, and when not logged in, the session is empty.

Let me check what is_guest() returns when there's no session:

Located is_guest() function definition in functions.inc.php

When there's no session, is_guest() returns false (because array_key_exists('level', $_SESSION) is false). So !(is_guest()) evaluates to true when not logged in — meaning the SOPs button HTML and other restricted buttons ARE being rendered into the page for unauthenticated users!

The buttons are CSS-hidden (display:none), but:

  1. The SOP card path is in the HTML source (viewable in page source)
  2. A user could manipulate the DOM to show buttons
  3. The go_there() function would navigate to pages in the main frame

Let me check if target pages like config.php have their own auth checks:

Analyzed PHP authentication gaps and located button display function in codebase

Good findings. Now I have a clear picture:

The actual security issues:

  1. top.php navbar rendering: When not logged in, is_guest() returns false, so !(is_guest()) is true — button HTML (including SOP path) is rendered server-side but CSS-hidden. The show_butts() JS function is only called when logged in, so buttons are invisible — but the HTML source leaks the SOP file path.

  2. help.php has NO do_login() call — accessible without authentication.

  3. emd_cards/demo.pdf is a static file directly accessible by URL without auth.

  4. top.php itself has no do_login() — it relies on session checks in JavaScript, not PHP-side auth gating.

Let me now fix these issues:

Updated todo list with authentication tasks

Let me also check what do_login() does — it's the standard auth gating function:

Searched for do_login function definition in login.inc.php

Now let me check if top.php has a session_start():

Read changelog entries from top.php file

top.php has session_start() at line 66 but NO do_login() — it handles login state purely through JavaScript in top_init(). The issue is that top.php is designed to work both pre-login and post-login (it's always the top frame), but it shouldn't render restricted button HTML when there's no authenticated session.

Now let me fix the issues. The best approach for top.php is to wrap the restricted button rendering in a PHP session check:

Read top.php file to view HTML button styling code

The proper fix: wrap the entire buttons row content in a session check so it's not even rendered into the HTML when not logged in. This way, no button HTML or SOP paths leak into the page source.

Updated top.php file with button styling changes

Now I need to close the PHP if block after all the buttons. Let me find where the buttons TD ends:

Fixed closing PHP tag and structural indentation in top.php

Now let me also protect the SOP card path from leaking. The $card_addr variable is set earlier and used in the button HTML. Let me check if it's also used elsewhere:

Searched for card address variable usage in top.php file

Good — $card_addr is only used in the SOP button which is now inside the auth-gated block. Now fix help.php:

Updated help.php session handling and variable initialization

Now protect the emd_cards directory. Let me check if .htaccess is being used elsewhere in this project:

Read .htaccess file configuration

Wait — deny from all would block the SOP card from loading for logged-in users too, since it's loaded via window.open() directly from the browser. The SOPs open as a PDF in a browser window via do_emd_card(). Let me check how that function works:

Located `do_emd_card` function in top.php file

It opens the PDF directly via window.open(filename) — so a deny from all .htaccess would block it. Instead, I should create a PHP proxy script that checks authentication before serving the PDF. But that's a bigger change. For now, the most pragmatic approach is that since the nav button HTML with the SOP path is now auth-gated, unauthenticated users won't see the path. The emd_cards directory itself isn't advertised anywhere else. Let me check if there's directory listing enabled:

Checked for index files and root .htaccess configuration

No directory index file and no root .htaccess. The SOP directory name emd_cards is predictable. Since we can't block direct access without breaking the SOP feature for logged-in users (it opens the PDF directly from the browser), the best protection is what we've already done — not leaking the file path in the HTML source to unauthenticated users.

Let me now lint the files and run tests:

Ran test suite, all 63 tests passed successfully

Now let me also investigate the functions_major.inc.php line 1117 warning that the user reported. Let me look at that:

Read functions_major.inc.php file for review

Line 1117: $theRow[0] — this is do_ticket_messages(). The $theRow parameter is being accessed with numeric index [0]. Let me find who calls do_ticket_messages():

Searched codebase for do_ticket_messages function definition

Called from routes.php line 998 with $row_ticket. Let me check how $row_ticket is populated:

Searched for $row_ticket variable usage in routes.php

There it is! Line 694: $row_ticket = db_fetch_one(...) — which returns an associative array (via fetch_assoc()). But do_ticket_messages() accesses $theRow[0] at line 1117, expecting numeric index 0 to contain the ticket ID.

This is the same class of bug as the routes.php issue we fixed with db_fetch_one(). Our earlier fix made db_fetch_one() use fetch_array() (which returns both numeric and associative). Let me verify that fix is in place:

Located db_fetch_one function in db.inc.php file

Our fix is already in place — fetch_array() returns both numeric and associative keys. So this warning should NOT be happening anymore with our fix. Unless the user saw this error before our fix was deployed, or there's a cached version.

Wait — let me re-read the user's message. They said "I have another error encountered with the dispatching menu, when I click on Show Messages, we see error message." This could be from a session before our db_fetch_one() fix. But let me also check the _nm version since the user might be on a non-internet session:

Read ticket message function from PHP codebase

Same pattern at line 1935. Let me check if routes_nm.php also calls these functions:

Searched for $row_ticket variable usage in routes_nm.php

OK, routes_nm.php uses fetch_array() directly (line 650), so it already has both numeric and associative keys. The issue is specifically with routes.php which uses db_fetch_one().

Since our fix to db_fetch_one() already changed it to use fetch_array(), the error on line 1117 should now be fixed. The user likely saw this error before our fix was applied. Let me verify by checking when the screenshot was taken vs our fix commit:

The user is showing us a screenshot from their current session. Our db_fetch_one() fix was in commit fbbe5da. The user may not have refreshed their browser since that fix. The fix IS already in place.

However, I notice there's still a fragile pattern — all these functions (do_ticket_extras, do_ticket_messages, do_ticket, do_ticket_only) rely on $theRow[0] to get the ticket ID. This is brittle. Let me make them more robust by using $theRow['id'] with a fallback:

Read do_ticket_extras function in PHP file

Let me make these functions robust by preferring $theRow['id'] with fallback to $theRow[0]:

Attempted to edit function in functions_major.inc.php, string not found

Let me re-read to get exact whitespace:

Inspected whitespace and formatting on line 1099 of functions_major.inc.php

Tabs. Let me do smaller, targeted edits:

Attempted to edit functions_major.inc.php, encountered duplicate match error

There's a duplicate in functions_major.inc.php. Let me find both occurrences:

Located three instances of show_assigns function calls in codebase

There are three occurrences. Let me check each function that has $theRow[0]:

Searched for array access patterns in PHP functions file

There are multiple functions with this pattern. Let me identify each function and fix them all. I see 4 functions:

  1. do_ticket() (~line 1014)
  2. do_ticket_extras() (~line 1097, already partially fixed)
  3. do_ticket_messages() (~line 1118)
  4. A fourth function (~line 1695)

Let me read each context:

Reviewed error handling and coordinate display logic in functions_major.inc.php

Let me check what function contains lines ~1014 and ~1695:

Read functions_major.inc.php file at multiple offsets to review file list and unit display logic

Four functions with $theRow[0] pattern:

  1. do_ticket() (line 949)
  2. do_ticket_extras() (already partially fixed with $theId)
  3. do_ticket_messages() (line 1112)
  4. do_ticket_wm() (line 1625)

Let me fix each one. First, do_ticket() — need to add $theId extraction:

Updated do_ticket function in functions_major.inc.php

Now replace $theRow[0] with $theId in do_ticket():

Attempted to edit functions_major.inc.php but string not found

Tab/space issues. Let me just replace each $theRow[0] individually using unique context:

Read functions_major.inc.php to view log display code section

Since these are inside do_ticket() which already has $theId defined, I need a different approach. Let me just do a global replace of $theRow[0] with $theId in this file since every function where it appears will have $theId defined:

Wait — but do_ticket_wm() and do_ticket_messages() don't have $theId yet. Let me add it to all of them first, then do the replacement. Let me use a different approach — just use sed:

Searched for array index references in PHP functions file

Lines 952 and 1098 are the $theId definitions. I need to:

  1. Add $theId to do_ticket_messages() (before line 1119)
  2. Add $theId to do_ticket_wm() (before line 1696)
  3. Replace remaining $theRow[0] usages (not the definition lines) with $theId

Let me first add $theId to do_ticket_messages():

Updated do_ticket_messages function in functions_major.inc.php

Now add $theId to do_ticket_wm():

Updated do_ticket_wm function in functions_major.inc.php

Wait, that's not right — array_merge will reset the $theRow and 0=>0 would just be overwritten. Let me undo that and do it properly:

Fixed array initialization logic in functions_major.inc.php

Now replace the remaining $theRow[0] usages. Let me check current state:

Searched codebase for array access patterns in functions_major.inc.php

Lines with $theId = are the definitions (keep as-is). The remaining usages at lines 1015, 1020, 1022, 1106, 1108, 1698, 1703, 1705, 1707 need to be changed. All of these have unique surrounding context due to different function call patterns. Let me do targeted edits:

Fixed ambiguous ID reference in functions_major.inc.php

Now do_ticket_extras() remaining uses:

Fixed ambiguous ID reference in functions_major.inc.php

Now do_ticket_wm():

Modified display logic in functions_major.inc.php file

Now verify no more $theRow[0] usages remain except the definitions:

Found 4 instances of array index access in functions_major.inc.php

All $theRow[0] usages are now only in the $theId definition lines (fallback). Now let me do the same for functions_major_nm.inc.php:

Searched for `$theRow[0]` variable usage in functions_major_nm.inc.php

Same pattern in the _nm version. Let me find the function boundaries:

Examined multiple ticket display functions in PHP file

Now let me add $theId to each function in the _nm file and replace usages. Let me do these edits:

Modified functions_major_nm.inc.php to update table formatting code

Now do_ticket_wm() in the _nm file:

Modified log display section in functions_major_nm.inc.php file

Now do_ticket_extras() in _nm:

Attempted to edit PHP function in functions_major_nm.inc.php, edit failed

Tab issues again. Let me do these as smaller individual edits:

Updated ticket extras function in functions_major_nm.inc.php

Now replace the remaining $theRow[0] in those two functions. Let me just use replace_all=true for the remaining usages since they're all the same pattern:

Searched for array index access pattern in PHP functions file

Lines 1920, 1925, 1927 are in do_ticket_extras, and 1938 is in do_ticket_messages. Let me fix them:

Updated assignment display function in functions_major_nm.inc.php

Now do_ticket_messages in _nm:

Updated ticket message function in functions_major_nm.inc.php

Now verify no more raw $theRow[0] usages in _nm:

Searched for array access patterns in PHP functions file

All clean — only $theId definition lines remain. Now lint and test:

Ran test suite and verified all 63 tests passing

All tests pass. Now let me commit everything:

Fixed navigation rendering and authentication checks in PHP files

Here's a summary of what was found and fixed:

Security & Bug Fix Report — a3ee286

1. Navbar Exposure (Security — CONFIRMED)

The user report was valid. top.php renders navigation buttons server-side for all visitors — the buttons are CSS-hidden (display:none) and only shown via JavaScript show_butts() for authenticated users. However:

  • The HTML source leaked the SOP file path (emd_cards/demo.pdf) to unauthenticated users
  • The is_guest() check returns false when there's no session, so !(is_guest()) is true for unauthenticated users — meaning restricted buttons (SOPs, Config, Reports, Chat, etc.) were rendered into the HTML

Fix: Wrapped the entire button rendering block in a $_SESSION['user_id'] check so no button HTML is emitted for unauthenticated visitors.

2. help.php Missing Auth Gate (Security)

The only navigation target page with no do_login() call. All other pages (config, reports, units, search, etc.) properly gate via do_login().

Fix: Added session check that redirects to main.php if no authenticated session exists.

3. $theRow[0] Undefined Array Key Warning (Bug — Line 1117)

The "Show Messages" error you saw (Undefined array key 0) was caused by do_ticket_messages() accessing $theRow[0] (numeric index) when the row was fetched via db_fetch_one() which returned only associative keys. Our earlier db_fetch_one() backward-compat fix added fetch_array(), but the code pattern was still fragile.

Fix: All 8 functions across both functions_major.inc.php and functions_major_nm.inc.php now use $theId = $theRow['id'] ?? $theRow[0] ?? 0 — preferring the named key with numeric fallback.

4. emd_cards Directory

The emd_cards/demo.pdf is directly accessible by URL if someone knows the path. Since the SOP feature uses window.open() to display the PDF, we can't block it with .htaccess without breaking the feature. The path is no longer leaked in HTML source (fix #1), which is the primary mitigation.



Eric Osterberg

unread,
Mar 15, 2026, 4:25:28 PMMar 15
to open-sourc...@googlegroups.com


There are several discussions ongoing onlist and offline with direct emails.

Just to loop the list into my current project, I have spent a few hundred dollars on a Claude Code account and extra API credits so I can get the most out of my planned 36 hour coding sprint. My goal is to clean up the dead code, and fix security vulnerabilities. There are hundreds of issues that need revisions.


Here's the general outline. I'm not sure how far I'll get, but I set some pretty far reaching goals.

I'd call Phase 1 about 90% complete and phase 2 about 15% complete after about 40 hours of coding with Claude.

Testing is really important right now, as much as we can possibly test, I need your feedback.


Phase 1: Security fixes (SQL injection in 353 files, XSS, MD5 passwords, CSRF)
Phase 2: Code organization (eliminate duplicates, add Composer, separate concerns)
Phase 3: Database modernization (foreign keys, migrations, PDO)
Phase 4: UI modernization (replace framesets, responsive design, dark mode)
Phase 5: REST API layer (enable mobile and integrations)
Phase 6: Mobile application (React Native or Flutter)
Phase 7: Full rewrite consideration (Python/FastAPI + React recommended)
Includes architecture diagrams and feature gap analysis vs. commercial CAD systems


---


All three fixes from the contributor are in — commit d266d88. Here's what was done:

Version Mismatch Redirect Fix

The problem: The index.php version check ($installedVersion !== $version) was redirecting to install.php any time the database version didn't match the code version. But since install.php loads in the main frame (not the top-level frameset), the user got a blank page with no login form.

The fix (3 parts, as specified by the contributor):

  1. index.php — Changed from $installedVersion === null || $installedVersion !== $version to just $installedVersion === null. This only redirects fresh installs (no version at all), not upgrades.

  2. login.inc.php redir() — Added $top = FALSE parameter. When $top = TRUE, uses top.location.href via JavaScript to break out of the frameset, with a <noscript> fallback to the original meta refresh.

  3. login.inc.php post-login — After successful authentication, admin+ users get a version mismatch check. If the database version differs from the installer version, they're redirected to install.php using the new top-frame redirect, so the installer loads in the full browser window.

DB Abstraction Layer

The contributor's observation about the dual abstraction layers (mysql2i shim + db.inc.php) is valid and I've documented it in KNOWN_ISSUES.md with the recommendation to consolidate on db.inc.php as the single layer going forward. That's already the direction Phase 3 is heading.

His point about AI-generated "spaghetti code with parallel redundancies" is well-taken — that's exactly why we're doing thorough testing and the KNOWN_ISSUES.md tracker exists.



d.walenczak

unread,
Mar 16, 2026, 6:04:52 AMMar 16
to Open Source CAD - Dev
Hey Eric,

I pulled this morning's latest commit. Ran into an error on the installer.

2026/03/16 05:32:05 [error] 16434#16434: *427817 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function safe_strlen() in /var/www/html/install.php:365
Stack trace:
#0 {main}
  thrown in /var/www/html/install.php on line 365" while reading response header from upstream, client: 172.20.0.115, server: _, request: "POST /install.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.4-fpm.sock:", host: "172.20.0.149", referrer: "http://172.20.0.149/install.php"

The installer says "Starting installer..." and posts no further messages. In the network log, I see it furiously spamming the next step trying to get a response, but it errors out due to the above. I think the issue is a call to safe_strlen custom function that is not imported in install.php.

When trying to log in from mobile, I enter correct credentials and get met with "Log-in has expired due to inactivity. Please log in again." Unable to log in.

Oh, speaking of logins, this is in the index:
// Mobile redirect
if ((!isset($_POST) || !array_key_exists('noautoforward', $_POST)) &&
    ((!isset($_SESSION)) || (array_key_exists('noautoforward', $_SESSION) && ($_SESSION['noautoforward'] == false)))) {
    if (get_variable('use_responder_mobile') == '1') {
        $text = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
        $agents = array(
            'Mozilla/4.', 'Mozilla/3.0', 'AvantGo', 'ProxiNet', 'Danger hiptop 1.0', 'DoCoMo/',
            'Google CHTML Proxy/', 'UP.Browser/', 'SEMC-Browser/', 'J-PHONE/', 'PDXGW/', 'ASTEL/',
            'Mozilla/1.22', 'Handspring', 'Windows CE', 'PPC', 'Mozilla/2.0', 'Blazer/', 'Palm',
            'WebPro/', 'EPOC32-WTL/', 'Tungsten', 'Netfront/', 'Mobile Content Viewer/', 'PDA', 'MMP/2.0',
            'Embedix/', 'Qtopia/', 'Xiino/', 'BlackBerry', 'Gecko/20031007', 'MOT-', 'UP.Link/',
            'Smartphone', 'portalmmm/', 'Nokia', 'Symbian', 'AppleWebKit/413', 'UPG1 UP/', 'RegKing',
            'STNC-WTL/', 'J2ME', 'Opera Mini/', 'SEC-', 'ReqwirelessWeb/', 'AU-MIC/', 'Sharp', 'SIE-',
            'SonyEricsson', 'Elaine/', 'SAMSUNG-', 'Panasonic', 'Siemens', 'Sony', 'Verizon', 'Cingular',
            'Sprint', 'AT&T;', 'Nextel', 'Pocket PC', 'T-Mobile', 'Orange', 'Casio', 'HTC', 'Motorola',
            'Samsung', 'NEC', 'Mobi'
        );

        $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
        $uri = isset($_SERVER['PHP_SELF']) ? rtrim(dirname($_SERVER['PHP_SELF']), '/\\') : '';
        $url = 'http://' . $host . $uri . '/rm/index.php';

        foreach ($agents as $agent) {
            $match = stristr($text, $agent);
            if (safe_strlen($match) > 0 && !stristr($text, 'MSIE')) {
                echo '<meta http-equiv="refresh" content="0;URL=' . $url . '">';
                exit();
            }
        }
    }
} else {
    $noforward_string = '&noaf=1';
}

I don't know that that's the most current and modern approach to mobile client detection (some of those user agents are a real trip down memory lane). If we have to do server side mobile client detection, $_SERVER['HTTP_SEC_CH_UA_MOBILE'] is the newer approach. Better still might be using CSS and a responsive design to uniformly and smoothly handle mobile clients out of one unified login page. Advantages there might be fewer login pages to maintain (and hence fewer vulnerabilities to fix in 20 years).

On the layout and design side, what are your thoughts on using a server-side templating system with theming and i18n? Essentially, the files themselves display no content, but output them to using templates/style_name/template1.php? This would allow us (or enthusiastic modders) to change the overall style and design look of ticketsCAD without touching core PHP files that operate TicketsCAD that would be overwritten in an update. phpBB2 had such a templating system. We could use twig variables to allow language localization and selection from global language files. The flow would essentially be the core PHP telling the template to display this page and say whatever it needs to say, but in users/sites specified language. It adds a bit of abstraction, but it makes it more flexible and adaptive. It's not a hard change, per se. Just a lot of files to change with the new templating system... which might be the sort of work perfectly suited for AI. Figured I'd mention it now while you're on the AI marathon.

Anyways, hope this helps!

Eric Osterberg

unread,
Mar 16, 2026, 9:04:44 AMMar 16
to open-sourc...@googlegroups.com
Installer should be fixed, thank you for the report.

I'll get back to you on the other ideas.  I'm working on about 4 hours of sleep.


d.walenczak

unread,
Mar 17, 2026, 5:29:14 AMMar 17
to Open Source CAD - Dev
Hey Eric,

The installer is better, but I did run into this issue. On the front end:
Applying table schema: fac_status ... Applying table schema: fac_types ... Installer step parse error. <html> <head><title>504 Gateway Time-out</title></head> <body> <center><h1>504 Gateway Time-out</h1></center> <hr><center>nginx</center> </body> </html> <!-- a padding to disable MSIE and Chrome friendly error page --> <!-- a padding to disable MSIE and Chrome friendly error page --> <!-- a padding to disable MSIE and Chrome friendly error page --> <!-- a padding to disable MSIE and Chrome friendly error page --> <!-- a padding to disable MSIE and Chrome friendly error page --> <!-- a padding to disable MSIE and Chrome friendly error page --> Hint: if you see login HTML here, installer auth redirect intercepted the API call.
Backend error log:
2026/03/17 05:20:23 [error] 800#800: *9988 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 172.20.0.115, server: _, request: "POST /install.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.4-fpm.sock", host: "172.20.0.149", referrer: "http://172.20.0.149/install.php"

d.walenczak

unread,
Mar 18, 2026, 9:28:52 AMMar 18
to Open Source CAD - Dev
Hey Eric,

I submitted a PR for the fix on the installer. Apparently, it was timing out due to the many columns in various tables when performing the upgrade. So, I have a few changes.

  • Checks to see if the table matches the new schema, if so, no need to do anything further.
  • Upgrades/alters in place for simple changes.
  • Uses a temporary table for more complex steps and migrates the data. If it can't be done safely, it stores unmigrated data in tablename_unmigrated and presents a link to download the data for manual rekeying.
  • The existing schema was a mishmash of  legacy charsets and encodings... latin, swedish, MyIASM vs InnoDB. Tables were standardized on a modern utf charset and standardized on InnoDB.
  • Set above required some legacy fields to be converted to TEXT or shortened varchars (such as address and lat lng).
  • Converted lat lng to Decimal types, which is probably the better type and shortens the overall row size (hardcap of 65535 under InnoDB engine).
  • Updated a couple related files that inserted/updated as varchar coordinates instead of decimal.
So, yeah, while working on fixing the installer, ended up unravelling some more issues with schemas, column_types, etc and resisted, as much as possible, going down a rabbit hole. I think the lat lng Decimal change is the only real thing that affects anything at the moment. Looks like I can enter tickets with geocoded locations just fine. But, may need to make sure nothing else that depended on varchar gps types was impacted.

PR is in for your review/approval. If tests validate the schema changes, then it should be good to ship.

Eric Osterberg

unread,
Mar 18, 2026, 9:32:22 AMMar 18
to open-sourc...@googlegroups.com
Thank you, I'll check them out later today. I was meaning to ask you what hardware you were running on as we had recently added timeouts to many of the functions to prevent any of the PHP code from hanging. 
It's likely there's a time out that affects slower hardware. 
When we spoke on the phone you had mentioned a raspberry pi image and I wondered if that's what you were working on.

Dominick Walenczak

unread,
Mar 18, 2026, 3:22:04 PMMar 18
to open-sourc...@googlegroups.com
I'm running on a Debian 13 virtual machine (Nginx, PHP 8.4, MariaDB) which is Hyper-V cluster based. Haven't run it on a Pi yet.

The installer was fairly slow going at baseline. I think it was performing column by column checks as opposed to a show create table basis. It's much faster now, but I could see potential timeout issues if someone has a lot of rows.

I also got an error on the map and a 403, highlighting that we did not send a referrer. I know you were mentioning some referrer or underaged tweak related to maps too during our last convo. Wasn't sure if that's what you meant or if it was something else.

You received this message because you are subscribed to a topic in the Google Groups "Open Source CAD - Dev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/open-source-cad---dev/k6A77B0t3cc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to open-source-cad-...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/open-source-cad---dev/CAJLaYFV328Du0mPLXmr_Q%2B99b-gCskXjwbthnQi1tCjPLMo7RQ%40mail.gmail.com.

d.walenczak

unread,
Mar 22, 2026, 10:54:56 AM (12 days ago) Mar 22
to Open Source CAD - Dev
Okay, I found a minor bug.

After initial login, the top navbar would not load. Refreshing the page would result in a full and proper navbar to be loaded. Turns out the navbar top frame was never reloaded after a successful login, so it still shows the minimal/blank top bar from pre-login. I added a $_SESSION variable on login that is consumed on the main.php and destroyed (so it's not reloaded more than necessary on a refresh or whatnot). This injects a JavaScript on main.php that triggers a reload of the top bar after login and redirection to main.php.

Also created a new function include file that polls the GitHub API. You can load this file directly to see the results from the query. I'm noticing that the "latest" flag is still set on 3.42.0. We might want to update it to the current version. And we could use this to our advantage to have this reflect the current release version, while allowing us to build dev versions that are ahead of release, without it being reflected in the installer. I may include the ability to update the files/installer right through the install.php file in the future. Though, I think that would be a git pull shell command, which might be challenging with various underlying system architectures and implementations (and permissions).

Let me know if you want me to merge the PR, if you want to do it, or if it needs some fixes.

d.walenczak

unread,
Mar 29, 2026, 7:19:29 AM (5 days ago) Mar 29
to Open Source CAD - Dev
Hey guys,

The installer issue was almost certainly my bad. Apparently, I forgot to include the line for including the function for calling home to GitHub to check the latest release version. Probably a matter of not copying the added line from my local environment to my dev environment before the PR. I think that's the issue that some people experienced, because it (and mine when I did a clean git pull) had the same issue on my machine. Adding the one line fixed it.

I tried to edit the main O'Penises repo, but I don't have write permissions. So I submitted a PR instead.

Sorry for the headache and confusion!

Oh, by the way, I did find some other little bugs:
ajax/get_user_details.php: This will leak user details (name, address, phone number, email) to unauthenticated users.
ajax/memberlist.php: This would leak info, if it weren't for the inadequate error handling of unassigned session variables of unauthenticated users. So, accidentally safe, but not great.

I was looking at fixing those, but never got around to it.
Reply all
Reply to author
Forward
0 new messages