Initial skills documentation — 25 categories, all SKILL.md + references + scripts
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
# Ops Portal Full Code Audit — July 12, 2026
|
||||
|
||||
Auditor: Hermes | Pages: 11 | Total bugs: 42
|
||||
|
||||
## The Four Root Causes
|
||||
|
||||
Everything else flows from these four:
|
||||
|
||||
### RC-1: `window.initNav` is undefined (affects ALL pages)
|
||||
`app.js` exports `initNav` only under `window.Ops.initNav`, not `window.initNav`.
|
||||
Every page's guard `typeof window.initNav === 'function'` evaluates FALSE.
|
||||
Nav hamburger, active-link, and logout wiring are dead on every page.
|
||||
|
||||
**Fix (one line in app.js, inside IIFE before `window.Ops = {...}`):**
|
||||
```javascript
|
||||
window.initNav = initNav;
|
||||
```
|
||||
|
||||
### RC-2: `utils.js` does not exist
|
||||
All pages reference `/js/utils.js?v=2` but the file is `/js/app.js`.
|
||||
The 404 is silent because `app.js` loads next and provides `window.Ops`.
|
||||
But if the server returns a hard error, all pages break.
|
||||
|
||||
**Fix:** Rename `app.js` → `utils.js` OR update all `<script src="/js/utils.js">` to `app.js`.
|
||||
|
||||
### RC-3: `logoutBtn` DOM lookup before nav fetch completes
|
||||
`services.html`, `servers.html`, `backups.html` all call
|
||||
`document.getElementById('logoutBtn').classList.add('show')` synchronously.
|
||||
`logoutBtn` lives in `nav.html` which is fetched asynchronously.
|
||||
Result: TypeError on every authenticated page load on those 3 pages.
|
||||
|
||||
**Fix:** Move the `getElementById('logoutBtn')` call inside the fetch callback:
|
||||
```javascript
|
||||
fetch('/nav.html').then(r => r.text()).then(h => {
|
||||
document.getElementById('nav').innerHTML = h;
|
||||
document.getElementById('logoutBtn').classList.add('show'); // ← here
|
||||
if (typeof window.initNav === 'function') window.initNav();
|
||||
});
|
||||
```
|
||||
|
||||
### RC-4: 6 of 11 pages have NO auth guard
|
||||
network.html, cron.html, config.html, logs.html, cost.html, fleettracker360.html
|
||||
load and show data without any `Ops.isAuthenticated()` check.
|
||||
|
||||
---
|
||||
|
||||
## Full Bug Inventory by Page
|
||||
|
||||
### index.html
|
||||
- B1 [HIGH] utils.js 404 (silent)
|
||||
- B2 [HIGH] window.initNav() call fails — window.initNav undefined
|
||||
- B3 [MED] navUser shown via inline style, inconsistent with .show pattern
|
||||
- B4 [MED] logoutBtn shown but never wired to logout (depends on initNav fix)
|
||||
|
||||
### services.html
|
||||
- S1 [CRIT] utils.js 404
|
||||
- S2 [HIGH] login-overlay hardcoded class="show" — flash of login for auth'd users
|
||||
- S3 [HIGH] loginError "Invalid credentials" visible without display:none
|
||||
- S4 [CRIT] logoutBtn/navUser lookup before nav.html fetch completes → TypeError
|
||||
- S5 [MED] window.initNav undefined (nav never initialized)
|
||||
- S6 [MED] No guard for session expiry mid-session
|
||||
|
||||
### servers.html
|
||||
- V1 [CRIT] utils.js 404
|
||||
- V2 [CRIT] logoutBtn.style.display = 'block' before nav loads → TypeError
|
||||
- V3 [HIGH] Login form inputs have no CSS classes, no form-group wrapper — unstyled
|
||||
- V4 [MED] loginError always shows hardcoded "Invalid credentials" text
|
||||
- V5 [MED] window.initNav undefined
|
||||
- V6 [LOW] No <label> tags on login inputs (accessibility + autofill)
|
||||
- V7 [LOW] login-logo uses emoji 🖥 instead of SVG (inconsistent)
|
||||
|
||||
### backups.html
|
||||
- K1 [CRIT] utils.js 404
|
||||
- K2 [CRIT] logoutBtn.classList.add('show') before nav loads → TypeError
|
||||
- K3 [HIGH] login-overlay hardcoded class="show"
|
||||
- K4 [MED] loginError no display:none
|
||||
- K5 [MED] window.initNav undefined
|
||||
- K6 [HIGH] .summary-bar, .summary-item, .summary-label, .summary-val not in ops.css
|
||||
|
||||
### network.html
|
||||
- N1 [CRIT] utils.js 404
|
||||
- N2 [HIGH] Scripts in <head> without defer (execute before DOM)
|
||||
- N3 [CRIT] NO auth guard — page shows all network data without login
|
||||
- N4 [MED] window.initNav undefined
|
||||
- N5 [MED] Grafana link uses Tailscale IP 100.71.155.7 — unreachable without Tailscale
|
||||
- N6 [LOW] Inline <style> redefines .card, .badge, .status-dot (may conflict with ops.css)
|
||||
|
||||
### cron.html
|
||||
- C1 [CRIT] utils.js 404
|
||||
- C2 [HIGH] Scripts in <head> without defer
|
||||
- C3 [CRIT] NO auth guard
|
||||
- C4 [HIGH] <main id="main-content"> placed AFTER the three <section> elements (inverted)
|
||||
- C5 [MED] window.initNav undefined
|
||||
- C6 [LOW] app.js loaded but Ops.* never used — all utilities re-implemented locally
|
||||
|
||||
### config.html
|
||||
- G1 [CRIT] utils.js 404
|
||||
- G2 [CRIT] window.escapeHtml() called throughout — not exported by app.js → TypeError
|
||||
- G3 [HIGH] window.formatTime() used — not exported → falls back to Date.toLocaleString()
|
||||
- G4 [HIGH] fetchStatus() called — not defined anywhere → typeof guard prevents crash but live data never loads
|
||||
- G5 [CRIT] NO auth guard
|
||||
- G6 [MED] window.initNav undefined
|
||||
- G7 [HIGH] Local initNav() defined inside IIFE shadows concept, calls window.initNav (self-referencing risk)
|
||||
- G8 [MED] .content-area and .page-footer not in ops.css
|
||||
- G9 [MED] Uses <header class="header"> but ops.css defines .page-header not .header
|
||||
|
||||
### logs.html
|
||||
- L1 [CRIT] utils.js 404
|
||||
- L2 [HIGH] Scripts in <head> without defer
|
||||
- L3 [CRIT] NO auth guard
|
||||
- L4 [MED] window.initNav undefined
|
||||
- L5 [MED] <main> doesn't cleanly wrap content (navPlaceholder outside main, script inside </main>)
|
||||
|
||||
### audit.html
|
||||
- A1 [CRIT] utils.js 404
|
||||
- A2 [CRIT] Uses sessionStorage for token — all other pages use localStorage — token not found on nav
|
||||
- A3 [MED] app.js loaded but Ops.* never used — own escapeHtml/fmtTime re-implemented
|
||||
- A4 [MED] logoutBtn in nav never wired (initNav not called)
|
||||
- A5 [MED] window.initNav undefined
|
||||
- A6 [LOW] Login form pre-filled with value="germaine" — leaks valid username
|
||||
|
||||
### cost.html
|
||||
- T1 [CRIT] utils.js 404
|
||||
- T2 [CRIT] window.fetchStatus(...) called — not defined anywhere → TypeError on load → no data renders
|
||||
- T3 [CRIT] NO auth guard
|
||||
- T4 [MED] app.js loaded but unused
|
||||
- T5 [MED] window.initNav undefined
|
||||
- T6 [LOW] Refresh button uses Unicode ↻ not SVG icon, .spinning animation doesn't apply
|
||||
|
||||
### fleettracker360.html
|
||||
- F1 [HIGH] No app.js or utils.js loaded — no auth system
|
||||
- F2 [HIGH] NO auth guard
|
||||
- F3 [MED] Missing viewport-fit=cover (all other pages have it)
|
||||
- F4 [LOW] Hardcoded date "2026-07-12" in timestamp string
|
||||
- F5 [LOW] COT hour calculation: `(utcHours + (-5) + 24).slice(-2)` fails at midnight (produces "24")
|
||||
- F6 [LOW] Not linked from nav.html — orphaned page
|
||||
|
||||
---
|
||||
|
||||
## Cross-Cutting Issues
|
||||
|
||||
| ID | Bug | Pages | Severity |
|
||||
|----|-----|-------|----------|
|
||||
| X1 | /js/utils.js 404 | All 10 auth pages | CRIT |
|
||||
| X2 | window.initNav undefined | All pages with fetch-nav | HIGH |
|
||||
| X3 | logoutBtn null before nav loads | services, servers, backups | CRIT |
|
||||
| X4 | No auth guard | network, cron, config, logs, cost, fleettracker | CRIT |
|
||||
| X5 | login-overlay hardcoded show class | services, servers, backups | HIGH |
|
||||
| X6 | Grafana link unreachable on mobile | nav.html + index.html | MED |
|
||||
| X7 | ops.css vs ops.css?v=2 version inconsistency | Mixed across pages | LOW |
|
||||
|
||||
---
|
||||
|
||||
## Priority Fix Order
|
||||
|
||||
1. Add `window.initNav = initNav;` to app.js (fixes X2, B2, S5, V5, K5, N4, C5, G6, L4, A5, T5)
|
||||
2. Rename utils.js reference or file (fixes X1)
|
||||
3. Move logoutBtn lookups inside nav fetch callback (fixes X3)
|
||||
4. Replace `window.fetchStatus(...)` in cost.html with direct fetch (fixes T2)
|
||||
5. Add `window.escapeHtml = Ops.escapeHtml` to app.js or fix config.html (fixes G2)
|
||||
6. Change audit.html to use localStorage not sessionStorage (fixes A2)
|
||||
7. Add auth guard + login overlay to network, cron, config, logs, cost (fixes X4)
|
||||
8. Remove hardcoded `show` class from login-overlay in services/servers/backups HTML (fixes X5)
|
||||
9. Fix <main> placement in cron.html (fixes C4)
|
||||
10. Add .summary-bar CSS to ops.css (fixes K6)
|
||||
Reference in New Issue
Block a user