# HPAdocHUB - Changelog All notable changes to this web app will be documented here. This project adheres to [Semantic Versioning](https://semver.org/) (MAJOR.MINOR.PATCH). --- ## πŸ”–πŸ”– v2.8.3 β€” 2025-09-14 - Improved session handling in the User Manager: - Force logout now also clears live presence so users appear offline immediately. - Suspending an account instantly removes any active presence records in addition to session invalidation. - Deleting a user now also purges any leftover presence data. - Shortened the β€œonline” detection window from 5 minutes to 2 minutes, making status changes reflect faster after a user logs out or deletes cookies. --- ## πŸ”–πŸ”– v2.8.2 β€” 2025-09-14 ### Fixed - Search results now include keyword-only matches even when full-text indexing is enabled. - Public items are always visible in search results regardless of role mappings. - Preserved exclusion of one-letter navigation headers from search results. - Unified scoring and sorting to keep relevance consistent across full-text and non-full-text matches. ### Notes - No data migrations required. - No configuration changes required. --- ## πŸ”–πŸ”– v2.8.1 β€” 2025-09-14 ### Fixed - Public footer: corrected a conditional so no raw template text appears when a visitor isn’t authenticated. ### Improved - Admin user list (mobile): prevented horizontal overflow on narrow viewports and tuned column layout so the table fits without side-scrolling. - Admin user list (mobile): names now render on two lines (first line: given name; second line: family name) for better readability on small screens. - Admin user list (mobile): header labels no longer wrap character-by-character. ### Notes - No data model changes. - No session or authentication behavior changes. --- ## πŸ”–πŸ”– v2.8.0 β€” 2025-09-13 ### Added - Online presence indicator on the user management screen. - Presence filter (All / Logged in / Logged out) on the user management screen. - Lightweight heartbeat on privileged screens to keep presence status current. - Administrative action to immediately invalidate a user’s active sessions. ### Changed - β€œLogged In” badge uses a darker green for better contrast and readability. - Standardized sign-out to also clear third-party/federated sessions. ### Fixed - Presence tracking now initializes reliably for elevated accounts on first load. - Sign-out flow more thoroughly removes residual cookies/session artifacts. ### Security - Stronger single sign-out across local and federated authentication providers. --- ## πŸ”–πŸ”– v2.7.0 β€” 2025-09-13 ### Added - **Bulk user import (CSV)** in the admin console with a two-step **Upload β†’ Preview β†’ Commit** flow. - CSV template now uses **comma-separated** role lists in the β€œdocument roles” field and auto-quotes the cell when needed. - Supports mapping by username or email, optional welcome/setup emails, and optional β€œrequire password change” for new or updated accounts. - **Account suspension handling** improvements: - Login is **hard-blocked** for suspended accounts in the legacy password flow (SSO already behaved this way). - When an account is changed from active to suspended, the system bumps a **session revocation counter** so existing sessions are invalidated promptly. ### Changed - Improved import preview with clear action labeling (**Create / Update / Skip**) and early validation of role names/slugs and site-level roles. ### Fixed - Resolved an edge case where the commit step could refresh without feedback during imports. - CSV template and parser now accept comma/semicolon/pipe for multi-value role fields and handle UTF-8 BOM more robustly. ### Security - **Privilege guard**: non-super operators cannot assign the top-tier site role or modify accounts that already hold it. - **Soft duplicate email protection** during import: - New users: skip create if another account already uses the same email. - Existing users: skip email changes that would conflict with another account. - Clearer error reporting during import to help operators correct data issues before committing. ### Notes - No breaking API or schema changes; any required columns/counters are created idempotently at runtime when missing. - UI strings and examples intentionally avoid referencing real paths, identifiers, or internal names. --- ## πŸ”–πŸ”– v2.6.0 β€” 2025-09-13 ### Added - Admins can mark user accounts as **Active** or **Suspended**. - Admin users can **filter** the accounts list by status (Active / Suspended / All). - **Immediate session revocation** control for a selected account; active sessions are invalidated on the next authenticated request. - Public results view now shows a prominent **Download** link above the embedded document. - Eligible, signed-in editors now see an **Edit** affordance next to the public download action (never shown to signed-out visitors). ### Changed - Sign-in flow blocks suspended accounts for both password and single-sign-on login paths. - Request-time auth guard enforces a per-user session version and a site-wide epoch for revoking sessions. - Session cookie handling normalized across the site for consistent scope and attributes. ### Fixed - Role editor now correctly populates the **identifier** field when editing an existing role. ### Security - Hardened authentication checks and error handling around identity verification and session validation. --- ## πŸ”–πŸ”– v2.5.3 β€” 2025-09-13 Added Public document view now shows an action row under the title with Download PDF version and a conditional Open in edit mode link. The edit option appears only for signed-in viewers who hold at least one β€œeditor”-type document role that also applies to the current item. The edit link is derived from the PDF URL by removing the PDF export suffix and appending an edit suffix. Changed Moved the β€œDownload PDF version” link to display directly under the title (above embedded content) on the public document view for consistency and visibility. Fixed Role editor screen now correctly displays the role slug when editing an existing entry. Security/Permissions Edit affordance remains gated by the intersection of the viewer’s β€œeditor”-type document roles with the item’s roles; visitors who aren’t signed in never see the edit option on public pages. --- ## πŸ”–πŸ”– v2.5.2 β€” 2025-09-12 Added Calendar link now adapts to authentication state; guests are sent to the public calendar (opens in a new tab), signed-in users are routed to the internal calendar. Document view shows a link row directly under the title: Download PDF version (when a PDF URL is present). Open in edit mode (only when the viewer holds at least one β€œeditor”-type document role that also applies to the current item; derived by converting the embed URL to an edit URL). Changed Repositioned the PDF action from below the embed to directly under the heading for better visibility. Improved role checks with safe fallbacks if optional data sources are unavailable. Security/Permissions Edit affordance is gated by intersection of the viewer’s β€œeditor”-type document roles with the item’s assigned roles. --- ## πŸ”–πŸ”– v2.5.1 β€” 2025-09-10 Changed Maintenance page: visual refresh to better match the site theme (SB-Admin style). Added version β€œpill” overlay beneath the left image on the maintenance page. Tuned background image behavior: Switched to layout that supports non-cropped logo (via contain/percent sizing). Allowed precise horizontal nudging with background-position (e.g., 115% center). Minor responsiveness & spacing tweaks for large and small screens. Fixed Prevented stray column gutters from creating an unintended vertical rule in certain layouts. Ensured the maintenance message renders safely with HTML-escaped content. Notes No database or schema changes. No changes to authentication logic. Backward compatible with the 2.5.0 release. --- ## πŸ”–πŸ”– v2.5.0 β€” 2025-09-10 ### Added - **Google SSO sign-in** using Google Identity Services (GIS) with domain restriction. - **Local account linking**: verified Google identity is matched to an existing local account by `google_sub` or email (case-insensitive). Optional auto-provision mode available via config. - **Session fixation protection**: rotate session ID on successful login. - **Unified logout** that clears app sessions from both legacy and SSO flows and deletes the auth cookie. - **Preserve `?next=`** across both legacy and SSO login flows. ### Changed - **Login UI**: legacy username/password screen now includes a β€œSign in with Google” button while preserving existing styling and behavior. - **Session bootstrap** standardized site-wide to ensure a single cookie name and attributes; SSO flow now uses the same bootstrap. - **Config**: session start is now guarded to avoid duplicate starts and header warnings. ### Security - Enforced Google ID token validation (audience, issuer, exp). - Enforced **hosted domain** allowlist for SSO. - Normalized cookie attributes (SameSite, HttpOnly, Secure). - Session ID regenerated post-authentication. ### Deprecated - None. ### Removed - None. ### Fixed - Eliminated β€œheaders already sent” issues during redirects by buffering output in the SSO verifier and normalizing session cookies. --- ## πŸ”–πŸ”– v2.4.3 β€” 2025-09-08 ### Changed - Adjusted layout for the role restriction section in the editor: - Introduced clearer visual separation with horizontal dividers. - Moved descriptive text directly below the section label for better readability. - Maintained the two-column grid for role checkboxes. --- ## πŸ”–πŸ”– v2.4.2 β€” 2025-09-08 - Fixed permission handling so that accounts with full administrative privileges can properly delete roles, while editor-level accounts remain restricted. - Improved redirect logic in the menu editor so that after saving, creating, or deleting an item, the previously selected filters (such as book selection or internal/public toggles) are preserved instead of resetting. --- ## πŸ”–πŸ”– v2.4.1 β€” 2025-09-07 ### Fixed - Internal navigation now respects the β€œopen as external link” setting, opening configured URLs in a new tab when enabled. - Behavior also applies to items surfaced via aliases within internal navigation. ### Notes - No schema changes. No permission changes. --- ## πŸ”–πŸ”– v2.4.0 β€” 2025-09-07 ### Added - Public/Internal filter in **Admin Menu Editor**. New internal query param supports proper flags. ### Fixed - Robust matching for proper internal flad using integer cast to prevent empty results. ### UI - Chip group for Internal/Public next to Status; fully responsive and mobile-friendly. ### Notes - No DB migrations. No changes to permissions or editor workflow. --- ## πŸ”–πŸ”– v2.3.9 β€” 2025-09-07 ### Improved - **Backups:** β€œRun backup” now shows a success banner and refreshes the β€œRecent backups” list immediately after the backup finishes (no manual refresh needed). Auto-download still works; when enabled, the page updates in the background after the file streams. ### Fixed - **User Manager :** Prevent browsers from auto-filling the β€œUsername” and bottom β€œPassword” fields on initial page load by setting `autocomplete="off"` and unique, non-login-ish names for the password fields. ### Notes - No schema changes. --- ## πŸ”–πŸ”– v2.3.8 β€” 2025-09-07 ### Fixed - **Dashboard sidebar** now includes `menu_alias` entries for *Internal* books. Aliases inherit the target menu item’s role visibility and status, so users with access now see those aliases in the left nav. ### Added - Debug toggle `see release notes` on `logged in users dashboard` to print alias/query diagnostics when troubleshooting. ### Notes - **No schema changes.** --- ## πŸ”–πŸ”– v2.3.7 β€” 2025-09-07 ### Fixed - **Books Manager :** β€œSave” on an existing book now works reliably. Root cause was a nested delete form interfering with the edit form submit. The delete form is now separate, and a PRG (Post/Redirect/Get) flow with flash messaging is used after Save/Delete. - **Menu Editor :** After Save (add or update), the page now returns to a fresh listing so recently edited titles/sections are immediately reflected without needing to press **Clear**. ### Notes - No schema changes. - Permissions/CSRF behavior unchanged; Editors still cannot delete. --- ## πŸ”–πŸ”– v2.3.6 β€” 2025-09-07 ### Changed - Admin UI: moved the quick **Save** action so it appears directly under the β€œEdit #…” heading on the editing screen. - Only displays while editing an existing item. - Matches the existing desktop styling and the compact sizing on small and tiny screens. - No behavior, data, or permission logic changes. ### Notes - Patch release; safe to deploy with no migrations or config changes. --- ## πŸ”–πŸ”– v2.3.5 β€” 2025-09-07 - Fix: Side navigation now shows the latest section labels after edits in the admin editor, even when only child items have role mappings. - Behavior is unchanged for access and visibility; only the displayed labels are updated. - Minor rendering improvement to avoid repeat lookups during navigation build. - No database or API changes. --- ## πŸ”–πŸ”– v2.3.4 β€” 2025-09-07 - Added a compact β€œβ† Support” button at the top of the bug tracking and bug reporting pages. - On small screens, the button auto-scales to a smaller size to preserve layout. - No changes to existing forms, filters, tables, or submission behavior. --- ## πŸ”–πŸ”– v2.3.3 β€” 2025-09-07 - Profile page now fully responsive on small and tiny screens: tightened card padding, scaled avatar, reduced button/input text size, and allowed the badges panel to shrink/stack to prevent horizontal overflow. - Scoped styles to the profile page to avoid side effects elsewhere. - Minor fix: corrected password error handling to use correct variable. --- ## πŸ”–πŸ”– v2.3.2 β€” 2025-09-07 - Improved readability of backup history names on small screens by inserting smart line breaks at separators and keeping file extensions intact. - Applied the same readable formatting on the download confirmation view. - Adjusted styling to prevent per-character wrapping while preserving intended breakpoints. --- ## πŸ”–πŸ”– v2.3.1 β€” 2025-09-07 -- Improved backup filename readability by adding discretionary line breaks at separators in history lists, enhancing mobile and narrow layouts. --- ## πŸ”–πŸ”– v2.3.0 β€” 2025-09-07 ### Highlights - Unified admin header across pages with a compact β€œActions” menu on mobile. - Admin landing refined; primary back action now routes to Internal Docs. - Safer password flows: email-based reset/setup links with expiring tokens. - Clear β€œView-Only Admin” experience with enforced write blocking. ### Added - Consistent topbar pattern on admin pages; accessible user pill and action tray. - Password reset setup via time-limited links; gentle welcome/reset email templates. - Audit logging for key admin mutations (create/update/delete). - Soft guardrails for destructive actions (confirmation prompts, dependency checks). ### Changed - Modernized layouts for user/accounts, role managers, and content managers: - Improved sorting, readability, and mobile responsiveness. - Clearer success/error toasts and inline validation. - Admin landing converted to a tile/grid catalog with concise descriptions. ### Fixed - Collisions in human-friendly identifiers (slugs) now auto-resolved. - Case/whitespace inconsistencies in list ordering. - Avatar preview/paths made more tolerant of different hosting setups. ### Security - CSRF verification on all write operations. - Stricter permission checks (e.g., built-in roles locked; editors restricted from deletes). - Deletes blocked when referenced by other records; clear reason messages. ### Migration Notes - No manual migration required. Supporting structures are created on demand when missing. ### Deprecations - None. ### Compatibility - Backward compatible. Some delete operations may be prevented until references are removed. --- --- ## πŸ”–πŸ”– v2.2.2 β€” 2025-09-07 --- Admin: Unified mobile topbar on `/admin/backups.php` to match `books.php`: - Added compact β€œActions ▾” dropdown on small screens --- Enabled topbar wrapping and reduced button sizing on phones --- No functional changes to backup logic. --- ## πŸ”–πŸ”– v2.2.1 β€” 2025-09-06 ### Security / Bug Fix - Gate `/dashboard/search.php` behind login and redirect anonymous users to `/search.php` while preserving the `k` query param. - Enforce maintenance guard on the dashboard search path. - Prevents internal sidebar from rendering to logged-out users. ### Compatibility - No schema changes. No config changes. Drop-in update. ### Files Touched - `/dashboard/search.php` (logic-only; layout unchanged) --- ## πŸ”–πŸ”– v2.2.0 β€” 2025-09-06 ### Added - Search now routes each result to the correct app surface: - Internal docs β†’ `/dashboard/results.php?id=…` - Public docs β†’ `/results.php?id=…` - Document-role gating in search results: - A result is shown only if it has **no** `menu_roles` mapping **or** the user holds at least one mapped role via `user_roles`. - Option-agnostic exclusion for β€œheader-only” items: results with a single-character `code` (e.g., `A`, `B`, `C`) are filtered out. ### Changed - Search context is respected regardless of entry point: - Logged-out users only see public results. - Logged-in users can search from either `/search.php` or `/dashboard/search.php` with correct visibility and routing. ### Fixed - Eliminated `Cannot redeclare h()` fatal by guarding helper definition in `db_sqlite.php` and `search.php`. - Minor consistency polish in top navbar to avoid context/routing mismatches after login. ### Notes - No schema migrations are required for this release. Role gating relies on existing `menu_roles` and `user_roles` tables when present. --- ## πŸ”–πŸ”– v2.1.0 β€” 2025-09-06 ### Added - **Maintenance Mode** (public guard + maintenance page) with optional **Strict** (admins-only login) and customizable message. - **Session epoch** flip to force non-admin re-auth on maintenance toggles. - **Admin guard** refinements: Updated correct View Only Admin read-only enforcement across /admin; Editor whitelist preserved; auto-seed correc admin view only role if missing. ### Changed - **Unified sessions/cookies** via `****_boot.php` (cookie path `/`, single name), eliminating cross-path double-login. - **Login flow**: stamps `$_S****['epoch']` and blocks non-admin login when Strict maintenance is ON. - **Sign-out**: robust cookie clearing across likely domain/path permutations; no-cache headers to avoid stale β€œlogged in” navbars. - **Backups/restore**: PHP-7-safe sort; restore paths toggle Maintenance ON (Strict) and bump epoch automatically. ### Fixed - Bounce to login when entering Admin from Dashboard. - Sign-out sometimes failing to fully log out. - Intermittent avatar and badge quirks due to mixed session scope. ### Security - Continued CSRF enforcement on admin forms. - Minimal, dependency-light maintenance page to avoid recursion/fatal risks. ### Migration notes - No manual DB migration required. `settings` is auto-created; correct admin view only role added if missing. - Ensure key public pages include `require_once _rootpath_/*****_guard.php';` before output. - (Optional) Display version by including `_version.php` in your head/footer. --- ## πŸ”–πŸ”– v2.0.0 β€” 2025-09-06 # Changelog All notable changes to this project are documented here. Dates are in **America/New_York**. ## [2.0.0] - 2025-09-06 β€” β€œGreen Beetle” ### Added - **Maintenance guard** enforced on public and dashboard entry points: - `/index.php`, `/dashboard/index.php`, `/search.php` now require `/common/maintenance_guard.php` early in the request. - Non-admins see a maintenance page when `maintenance_mode=1`. Admins may still sign in. - **Full-site backups** alongside DB-only backups: - New backup roots (outside webroot): - DB: `/home4/tracknas/hpa_backups/db/` - Full: `/home4/tracknas/hpa_backups/full/` - File naming: - DB: `datastore.sqlite_v{APP_VERSION}_YYYYMMDD_HHMM{AMPM}.zip` - Full: `HPAdocHUB_v{APP_VERSION}_YYYYMMDD_HHMM{AMPM}.zip` - View-Only Admins can list but **cannot** create or download backups. ### Changed - **Admin β†’ Maintenance** (`/admin/maintenance.php`) - Reliable save: writes `maintenance_mode`, `maintenance_strict`, `maintenance_message`. - **Bumps `session_epoch` only when mode/strict changes**, allowing force-logout of non-admins sitewide. - Kept existing UI/branding. - **Login** (`/users/sign_in/index.php`) - If `maintenance_mode=1` **and** `maintenance_strict=1`, only admins can sign in. - On successful admin/non-admin sign in, session stores current `session_epoch`. - **Logout** (`/users/sign_out/index.php`) - Hardened sign-out: clears cookies for multiple path/domain combos, no-cache headers, destroys session without immediately recreating. - **Backups** (`/admin/backups.php`) - Supports DB-only **and** full-site backups; safe outside-webroot storage; confirm-before-download flow. - Compatibility: removed PHP <7.4 arrow-function usage. - Requires `ZipArchive` for full-site backups. ### Fixed - Maintenance toggle sometimes appearing to revert: save handler now persists correctly and re-reads state. - Sign-out appearing to do β€œnothing” due to stale cookies or cached navbar: resolved with stricter cookie deletion + no-cache. ### Security - View-Only Admins are prevented from creating/downloading backups and making POST changes in admin sections. - Strict maintenance blocks non-admin sign-ins. ### Notes / Migration - Ensure backup folders exist and are private: - `mkdir -p /home4/tracknas/hpa_backups/{db,full}` then `chmod 700` both. - Drop a `.htaccess` inside each with `Deny from all` (or `Require all denied` on Apache 2.4+). - Public/dashboard entry pages must include `require_once $_SERVER['DOCUMENT_ROOT'].'/common/maintenance_guard.php';` **before** anything that renders content. --- --- ## πŸ”–πŸ”– v1.9.9 β€” 2025-09-06 ## 🐞 - New: Cursor-reactive Bug Badge Easter Egg - Herding: bugs steer away from the cursor with a brief panic speed boost so you can β€œcorral” them. - Pop on touch: when the cursor touches a bug, it zooms toward you and vanishes. - New: Spawn grace period (default **2.4s**) so bugs don’t explode instantly when triggered at the cursor. - Tweak: Shorter, lighter trails; tuned density so they don’t linger. - Config knobs (in `/js/hpa-bug-egg.js`): `SPAWN_GRACE_MS`, `AVOID_RADIUS`, `AVOID_STRENGTH`, `PANIC_BOOST`, `BUG_BASE_SPEED`. - No backend changes; front-end only. --- ## πŸ”–πŸ”– v1.9.8 β€” 2025-09-06 ## 🐞 v1.9.8 β€” 2025-09-06 - Tweak: Bug Badge Easter Egg now **crawls & meanders** instead of β€œrocketing”: - Slower base speed (~115 px/s) with slight variance. - Organic pathing with gentle turn bursts and occasional micro-pauses. - Subtle body wobble + step-bob β€œgait” for a bug-like feel. - Shorter trail that fades quickly; reduced dot density. - Perf: Frame loop runs **only while bugs exist**; DOM nodes GC promptly. - A11y: Continues to respect `prefers-reduced-motion`. - Lint cleanups: - `will-change` hyphenation fixed. - Replaced `inset: 0` with explicit edges for wider linter support. - Removed unnecessary `!important`. - Refactor to avoid β€œfunction inside loop” pattern. - Files touched: `/js/hpa-bug-egg.js`, `/css/hpa-bug-egg.css`. --- ## πŸ”–πŸ”– v1.9.7 β€” 2025-09-06 ## πŸ”° EASTER EGG - Feature: Bug Badge Easter Egg β€” clicking your bug badge spawns a fun green bug animation with a glowing trail. Respects reduced-motion, adds cooldown, and caps to prevent abuse. - Chore: Wired global CSS/JS includes (/css/hpa-bug-egg.css, /js/hpa-bug-egg.js). --- ## πŸ”–πŸ”– v1.9.6 β€” 2025-09-06 ### Changed - **Release Manager** now inserts a horizontal rule and an emoji + `v` prefix in release headings (e.g., `## πŸ”– v1.9.6 β€” 2025-09-06`) for much better scanability. - Only affects **new** entries going forward; existing history remains unchanged. - No runtime or database changes. # πŸ”–πŸ”– [1.9.5] - 2025-09-06 ### Fixed - Tech Support β€” Bug Queue: added a dedicated `.below-filters-gap` element right after the `.topbar` so the filter area keeps consistent spacing on phones **even when there are no results**. ### CSS - New rule shows the spacer only on small screens (≀700px); desktop unaffected. ### Notes - No DB or JS changes. πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”– πŸ”–πŸ”– [1.9.4] - 2025-09-06 - ****IDEA SUBMITTED BY HANNAH SANDERS (HPA Student)****πŸ”–πŸ”– πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”–πŸ”– ### Changed - Login badge in the navbar and profile is now **icon-only**; the hover tooltip shows the tier and the date earned in `MM-DD-YYYY` (e.g., β€œNewbie β€” Earned 09-06-2025”). ### Fixed - Consistent tooltip content across all tiers; minor CSS polish to keep badges aligned on one row. ### Notes - No DB changes. - Badge dates/timezone use **America/New_York**. # πŸ”–πŸ”– [1.9.3] - 2025-09-06 ### Fixed - **Login Badge** displays again in the top-right navbar and on the Profile page, with safe CSS include and graceful handling when PDO isn’t preloaded. - One-time **glow** correctly clears after first render (session flag), preventing persistent glow. ### Changed - **Mailer** now reliably sends from **noreply@hpaspart.org** when SMTP is enabled; mail() fallback sets an explicit From header to reduce β€œserver default” envelopes. ### Ops / Verification - No DB changes. - Verify after deploy: - Sign in β†’ see login badge under your name in the navbar. - Visit **/dashboard/profile.php** β†’ badge appears (before bug badge). - Trigger any system email β†’ From shows **noreply@hpaspart.org**. # πŸ”–πŸ”– [1.9.2] - 2025-09-06 ### Fixed - Badge emails now honor the canonical From correct domain. SMTP sets the envelope sender; fallback mail() uses `-f` to prevent host rewrites. Login badge code now routes all mail through the site mailer. # πŸ”–πŸ”– [1.9.1] - 2025-09-06 ### Fixed - Login Badges: replaced incompatible Database Query with manual/correct INSERT/UPDATE so it works on hosts without `INSERT ... ON CONFLICT ... DO UPDATE` support. - Corrected a stray parenthesis in `login badges` function guards. ### Notes - No schema changes. The `User Login Stats` table remains the same. # πŸ”–πŸ”– [1.9.0] - 2025-09-06 ### Added - **Login Badges** (unique daily login count, TZ **America/New_York**): - Ladder: Newbie (1), Regular (5), Explorer (15), Dedicated (30), Power User (60), Champion (120), Legend (240). - Displays in the top-right userbox **before** the Bug badge and on the Profile page. - Hover tooltip shows the earned date (MM-DD-YYYY). Only the **highest** badge is shown. - On level-up: one-time 30s glow highlight on next page view, plus a congrats email. ### Database - New table `user_login_stats` with `PRIMARY KEY (user_id)`; created automatically on first use. - Columns: `unique_login_days`, `last_login_day (YYYY-MM-DD)`, `badge_level`, `badge_earned_ts`, `badge_unseen`. - Index: `ix_uls_badge (badge_level)`. ### Config - `HPA_BADGE_TZ` (default `America/New_York`). - `HPA_BADGE_NOTIFY` (default `true`) to control level-up email. ### Notes - β€œUnique daily logins” = first successful login per calendar day in badge TZ. - Email uses the site mailer if available; otherwise falls back to `mail()` as a best-effort. # πŸ”–πŸ”– [1.8.4] - 2025-09-06 ### Changed - **Release Manager**: Page now allows **Admin (View Only)** users to access and **preview** releases. The **Apply** action is disabled in the UI and **blocked server-side**. ### Security/Permissions - Enforced a hard server-side check to prevent view-only users from writing to `/common/CHANGELOG.md`, `/admin/RELEASE_NOTES.md`, or `/common/version.php`. Full Admins unchanged. # πŸ”–πŸ”– [1.8.3] - 2025-09-06 ### Changed - All release backups now go into a sibling `/_backups` directory next to the source file: - `/common/CHANGELOG.md` β†’ `/common/_backups/CHANGELOG.md.YYYYMMDD_HHMMSS.bak` - `/admin/RELEASE_NOTES.md` β†’ `/admin/_backups/RELEASE_NOTES.md.YYYYMMDD_HHMMSS.bak` - `/common/version.php` β†’ `/common/_backups/version.php.YYYYMMDD_HHMMSS.bak` ### Security/Hardening - Writes a minimal `.htaccess` (`Require all denied`) to each `/_backups` folder to prevent direct web access on Apache. - Adds a `.gitignore` to keep backup files out of the repo. - Retains the **20 most recent** backups per file; older ones are pruned automatically. ### Ops Notes - No schema changes; only `/admin/release_manager.php` updated for backup handling. # πŸ”–πŸ”– [1.8.2] - 2025-09-06 ### Fixed - **Release Manager**: replaced regex replacement with a callback to avoid `$1`+digit back-reference ambiguity that corrupted `/common/version.php` (e.g., `.8.1');`). - Added post-write verification of `HPADOC_HUB_VERSION` and automatic restore from backup if verification fails. ### Changed - **Release Manager UI**: after a successful submit, the form fields and preview area reset; the success notice auto-dismisses after ~10s. ### Security/Hardening - Safer writes to `version.php` (exclusive file lock + backup + verification). ### Ops Notes - No database/schema changes. - Touched files: `/admin/release_manager.php` (function `bump_version_php()` and UI submit flow). # πŸ”–πŸ”– [1.8.1] - 2025-09-06 ### Changed - Release Manager now uses **Post β†’ Redirect β†’ Get (PRG)** after applying a release, which clears the form and preview to prevent accidental resubmits. ### UX - Success banner auto-hides after ~10 seconds. - Added a β€œReset Form” button for quick clearing without a page refresh. # πŸ”–πŸ”– [1.8.0] - 2025-09-06 ### Added - **Release Manager** (`/admin/release_manager.php`): Admin-only tool to bump app version and prepend entries to: - `/common/CHANGELOG.md` (inserts right under the fixed header), - `/admin/RELEASE_NOTES.md` (inserts right under the fixed header). - Live preview for both entries before applying. ### Changed - Admin dashboard: added link/tile to **Release Manager**. ### Security/Hardening - Enforced Admin-only access (View-Only Admins blocked). - CSRF protection on form posts. - File writes use `LOCK_EX` and create timestamped dot-backups next to the files (e.g., `.CHANGELOG.md.YYYYMMDD_HHMMSS.bak`) for easy rollback. - `/common/version.php` update is narrowly scoped to the `HPADOC_HUB_VERSION` define. ### Ops Notes - Ensure the web process can write to: - `/common/CHANGELOG.md` - `/admin/RELEASE_NOTES.md` - `/common/version.php` - To roll back, restore the most recent `.bak` files. ### QA Checklist - Open `/admin/release_manager.php` as an Admin (not View-Only). - Enter a new SemVer (e.g., `1.8.0`), today’s date, and body text for both files β†’ **Preview** shows the exact insertion blocks. - Click **Apply Release** β†’ version bumps in `/common/version.php`; both markdown files show the new entry directly beneath their headers (with one blank line of spacing). # πŸ”–πŸ”– [1.7.1] - 2025-09-06 ### Fixed - Reset page now tolerates both `password_resets` shapes: - Expiry as UTC `TEXT` (`Y-m-d H:i:s`) with `used_at` timestamp, **or** - Expiry as `INTEGER` epoch seconds with `used` (0/1). - Token regex widened to accept 32–128 hex chars so both admin (64-hex) and forgot (32-hex) links work. - `/admin/users.php`: corrected `$pass2 = (string)param('password2');` parse error. ### Changed - Unified password reset TTL to **60 minutes** for both admin-initiated and self-service flows. - When an admin sets a temp password, `must_change_password=1` (if column exists) is enforced and a reset link is emailed (no plaintext passwords). ### Security/Hardening - Self-service forgot flow: enumeration-safe responses, prior tokens cleared before issuing a new one, rate limiting via `common/rate_limit_forgot.php`, and a honeypot field. ### Email - Reset email uses the correct HPA logo and forces white button text for β€œReset your password” across clients. ### Ops Notes - No DB migration required. Optional indexes for performance/uniqueness: - `CREATE UNIQUE INDEX IF NOT EXISTS ux_pwreset_token ON password_resets(token);` - `CREATE INDEX IF NOT EXISTS ix_pwreset_user ON password_resets(user_id);` # πŸ”–πŸ”– [1.7.0] - 2025-09-06 ### Added - **Forgot-password abuse protections**: - Per-IP and per-email throttling with a minimum interval between requests. - Honeypot field and attempt logging (privacy-respecting). - Responses remain enumeration-safe. - **Transactional email footer**: - All outbound emails now include a small branded footer with the current app version. - **Bug Queue (Tech Support)** mobile UX: - β€œReported Bug” modal refined to stay fully on-screen. - Clearer spacing between the Status filter and the results table on phones. ### Changed - **Bug Queue (Tech Support)** display: - **Desktop**: Summary now starts with **β€œReported Bug:”** and, when present, shows **Accepted/Declined/Resolved** lines with names + dates. - **Dates**: Desktop uses `MM-DD-YYYY HH:MM:SS`; mobile modal uses `MM-DD-YYYY` (with β€œon” phrasing). - Footer included at the bottom of the Bug Queue page for consistency. ### Fixed - Prevented header/filter overlap on small screens. - Prevented Accept/Decline/Resolve controls and textareas from overflowing horizontally on phones. - Modal close behavior (close button, backdrop, Escape) is reliable. ### Security - Browse-only enforcement for View-Only Admins remains in effect; state-changing routes still protected by CSRF. - Forgot-password requests are rate limited and bot-hardened. ### Upgrade Steps 1. Deploy and bump the app version to **1.7.0**. 2. No database changes required for this release (beyond prior migrations). 3. Clear caches/CDN as needed. --- # πŸ”–πŸ”– [1.6.0] - 2025-09-06 ### Added - **Unified admin authorization layer** - Supports Admin, View-Only Admin (browse-only), and Editor roles. - Users with the **Tech Support** role can access the Bug Queue (respecting view-only limitations). - **Admin dashboard** - Bug Queue tile is visible to Admins and View-Only Admins so support users can reach it easily. - **Bug Queue (Tech Support)** - **Mobile modal**: tapping **β€œReported Bug”** opens a pop-up summarizing: - **Reported by** _Name_ **on** `MM-DD-YYYY` - If accepted: **Accepted by** _Name_ **on** `MM-DD-YYYY` - If declined: **Declined by** _Name_ **on** `MM-DD-YYYY` + **Decline reason** - If resolved: **Resolved by** _Name_ **on** `MM-DD-YYYY` + **Resolution** - Optional **Page** link and full **Reported Bug** text. - Standard admin footer now included for consistency. ### Changed - **Permissions** - View-Only Admins can browse all admin areas; server-side blocks prevent modify actions. - **Bug Queue display** - **Desktop**: Summary now prefixes the text with **β€œReported Bug:”** and shows **Accepted/Declined/Resolved** lines (with names + dates) when applicable. - **Dates**: Desktop uses `MM-DD-YYYY HH:MM:SS`; mobile modal uses `MM-DD-YYYY` (with β€œon” phrasing). - **Mobile layout**: Hides non-essential columns and stacks actions full-width under each row; adds spacing so the Status filter doesn’t crowd the table header. ### Fixed - **Backups**: View-Only Admins cannot download backup files. - **Bug Queue mobile UX** - Prevented header/filter overlap. - Prevented action buttons and textareas from overflowing horizontally. - Modal close behavior fixed (close button, backdrop, and Escape). - CSRF checks enforced on all modifying actions. ### Security - Server-side enforcement of browse-only behavior for View-Only Admins. - CSRF protection on all state-changing requests. ### Database / Migration Notes - Adds a **view-only** capability to the role model; seeds a default View-Only Admin role when missing. ### Upgrade Steps 1. Deploy and bump the app version to **1.6.0**. 2. Run role/capability migrations (or load an admin page once if migrations are applied automatically). 3. Clear caches. --- ## [1.5.3] - 2025-09-05 ### Added - **Tech Support** role access to the admin dashboard and Bug Queue. - **Token-based password reset**: - β€œForgot Password” issues a single-use email token. - β€œReset Password” consumes the token, sets a new password, and clears forced-reset flags. - Automatic storage + indexing for reset tokens. - **Profile upgrades** - β€œYour Site Roles” section with badges for Editor/Admin/Super Admin. - β€œBadges Earned” panel with hover tooltips. - **Bug tracker modal** improvements: - Shows **Reported Bug** details and **Resolution** details when available. - **Bug badge module** - Displayed in top nav and profile. - Config option to pick icon renderer. ### Changed - Top-nav userbox: improved role badges and avatar handling. - Dashboard copy/layout polish; responsive tweaks for bug tracker filters and tables. ### Fixed - Resolved a PHP syntax issue in the bug badge component. - More reliable session bootstrap across hosts. - Avatar URL and file resolution edge cases. ### Security - Password reset uses **single-use**, **time-limited** tokens; previous tokens invalidated on issuance. - Enumeration-safe responses for password reset requests. - CSRF tokens on relevant forms. - Forced-reset flag cleared only after a successful reset. ### Database / Migration Notes - Ensures unique/reset indexes for the password-reset storage. - Ensures a β€œmust change password” flag exists for accounts (auto-added if missing). ### Upgrade Steps 1. Deploy and bump the app version to **1.5.3**. 2. Initialize password-reset storage (first run will auto-create if needed). 3. Clear caches.