- Switch: 36x20 contained pill with 6px right padding so labels keep their distance even inside Stacks
- Radio: theme-level override, 20px ring with a fixed-size inner dot — checked state no longer animates a scale change that pushed labels around
- Slider: white thumb with primary-colour ring, 4px track, soft hover/active glow
- Drop the custom RadioInput icon overrides that bypassed the theme and caused the size jiggle
- Replace duplicated page/rowsPerPage state in Team, Notifications and Status Pages tables with a shared useClientPagination hook
- Drop unused placeholderColor prop from Select; placeholder always uses secondary text
- Restore LAYOUT.MD constant for the account menu item gap
- replace heavier per-cell header borders with one lighter row divider
- shrink header text to 11px with looser tracking for a more refined feel
- tighten failed-jobs labels: "Fail count" -> "Count", "Last failed at" -> "Last failed"
Across en + 15 locales:
- pages.<X>.fallback.title / .description for every page that has an
EmptyState (uptime, infrastructure, pageSpeed, notifications,
maintenance, statusPages, incidents, logs, logs.queueFallback,
checks, account.team).
- pages.<X>.header.title / .description for every page that uses the
new PageHeader (same list, plus settings).
- pages.logs.diagnostics.sections.runtimeStats / .memoryCpu titles
and descriptions for the diagnostics section explainers.
- components.pageHeader.links.support / docs / changelog tooltip
labels.
en.json also gains pages.logs.jobQueueExplainer and
.failedJobsExplainer (English only — non-English locales fall back
to English until a translator sweep).
- MuiOutlinedInput hover override: was inheriting MUI's default
white outline in dark mode (too bright). Now uses an alpha-23%
white in dark and text.primary in light.
- TextInput: -webkit-autofill now repaints the input bg with
background.paper (instead of Chrome's harsh blue/yellow autofill
highlight), text in text.primary, with the standard 5000s-transition
trick to suppress the brief flash. Works in both modes.
TableJobs:
- Cut from 11 to 7 columns, dropping active / runCount / failCount /
lastFinishedAt (covered by Failed jobs table or by lastRun + lastRunTook).
- All cells get whiteSpace:nowrap + textOverflow:ellipsis + maxWidth so
long timestamps and IDs no longer wrap and inflate row height; full
value visible via title tooltip.
- Running-row tint: was theme.palette.success.light (too saturated in
light, drowns white text in dark). Now #ECF7F2 in light, an 18%-alpha
green in dark — readable in both modes.
TabQueue:
- One-line explainer above the Job queue heading, with the words
"Highlighted rows" wrapped in the same green tint so the meaning
is immediately associated.
- One-line explainer above Failed jobs heading too.
- Stats and StatGauges use CSS grid (5 + 4 columns) so cards in each
row are equal width; widths overridden against the legacy 25%-flex
GradientBox so they fill their grid cell.
- DetailGauge gains a maxWidth prop (default 225) so consumers in
wide grids can opt out of the cap.
- Section explainers above each row: "Runtime stats" + description,
"Memory & CPU" + description (i18n driven, propagated to all 16
locales via pages.logs.diagnostics.sections).
- Both grids render immediately with placeholder "—" values, so the
initial paint shows the layout and values fill in as data loads
(eliminates the layout shake when switching to the tab).
- New PageHeader component (variant D — grouped icon-pill toolbar):
big title + muted description on the left, Support / Docs /
Changelog as a 3-icon segmented pill on the right with tooltips.
External links open in a new tab.
- BasePage / BasePageWithStates / MonitorBasePageWithStates accept
a headerKey prop; when set, render PageHeader pulling
pages.<headerKey>.header.title and .description from i18n.
When unset, falls back to the existing breadcrumb (no behavior
change for not-yet-migrated pages).
- All top-level pages (uptime, infrastructure, pageSpeed,
notifications, maintenance, statusPages, incidents, logs, checks,
account, settings) now pass their headerKey.
- Sidebar: removed the bottom menu (Support / Discussions / Docs /
Changelog) since those links now live in the page header.
- New EmptyState + EmptyStateIllustration components: stacked-cards SVG
with grid background, theme-aware light/dark palette.
- Variants: default (centered with title + description), compact
(horizontal, in-section), fullscreen (vertically centers in viewport).
- Wired into Checks, Incidents, Logs (Logs+Queue tabs), Notifications,
Maintenance, Status pages, and Team tab — each with i18n title +
description and a fullscreen layout when truly empty.
- Table.EmptyView now wraps the EmptyState in a divider-bordered card
so short messages no longer look orphaned.
- Incidents Option-A short-circuit: when summary.total === 0, replace
the whole page chrome with EmptyState; otherwise keep filters + cards.
- Fallback.tsx (BaseFallback / EmptyFallback / EmptyMonitorFallback /
ErrorFallback) refactored to delegate to EmptyState.
Replaces the cards-with-halo SkeletonCard fallback (which produced a
washed-out, hard-to-read placeholder) with a single canonical empty
state used everywhere in the app.
What's new:
- EmptyStateIllustration.tsx — custom inline SVG: two stacked monitor
cards (front blue, back gray, both with hairline strokes and a soft
fade toward the bottom), set against a faint grid of solid + dashed
background lines. Uses only lightened palette tokens (#7DA8E8 blue,
#B6C2CF gray, #CBD5E1 grid).
- EmptyState.tsx — the layout: illustration + title + description +
optional CTA + optional secondary link + optional inline alert slot.
Supports a compact horizontal variant for in-panel use.
Migrations:
- Fallback.tsx: BaseFallback / EmptyFallback / EmptyMonitorFallback /
ErrorFallback now delegate to EmptyState. Public APIs unchanged so
every existing consumer (BasePageWithStates, MonitorBasePageWithStates,
Pages/Uptime, Pages/Notifications, Pages/Infrastructure, etc.) keeps
working without edits.
- BasePage.tsx: PageSpeedKeyPriorityFallback rebuilt on top of EmptyState
with the warning slot. Fixes the previous reports of "white cloudy
area" + half-faded text — message and link now render in consistent
dark text with green Settings link.
No prop changes for any page-level consumer. The illustration is a
single SVG with no external assets.
The Open site action in monitor row menus called `window.open(monitor.url)`
unconditionally, which produced unresolvable navigation for monitors
targeting internal services:
- Hardware monitors always point at a Capture agent (e.g.
http://capture:59232/api/v1/metrics) that the user's browser can't
reach.
- Port, ping, docker, game, grpc, and websocket monitors store hostnames
or non-HTTP endpoints, which browsers can't load anyway.
This change hides the action where it can't possibly work:
- Removed entirely from the Infrastructure (hardware) monitors table.
- In the Uptime monitors table, only shown for http and pagespeed
monitor types whose URL starts with http:// or https://.
A more comprehensive fix that adds a separate user-facing siteUrl
field on the Monitor schema is left for a follow-up.
Closes#3434
The OpenAPI spec only listed `limit` for GET /monitors/team/with-checks,
but the route's Zod schema (getMonitorsWithChecksQueryValidation) also
accepts page, rowsPerPage, filter, field, order, type, and explain.
Users hitting the endpoint via Swagger UI would either get rejected
with "page is not allowed" (when guessing param names) or miss
pagination entirely.
Adds the missing parameters with constraints mirrored from the
validation schema. Also bumps `limit` max from 50 to 100 to match
the schema (was 100 in code, 50 in spec).
Closes#3354
The client version shown on the Settings page was hardcoded as a
literal in vite.config.ts, while client/package.json sat at the
placeholder "0.0.0". Bumping the displayed version required editing
two unrelated places, and stale Docker client images would keep
showing the old number after upgrades.
This change makes client/package.json the single source of truth
and reads it at build time. Bumps client/package.json from 0.0.0
to 3.6.1 to preserve current behaviour.
Closes#3271
Mongoose 8 logs a reserved-key warning at boot because the Check schema
defines an `errors` field, which collides with Mongoose's internal
document `errors` accessor. The field is intentional and safe to keep,
so opt out of the warning via `suppressReservedKeysWarning: true`.
Closes#1539
Vite >=4.3 rejects requests with a Host header not in the allowlist,
which broke status-page submissions and dev-server access for users
serving Checkmate behind a reverse proxy after upgrading.
Adds VITE_ALLOWED_HOSTS env var (comma-separated list). When unset,
falls back to allowing all hosts so existing self-hosted deployments
keep working without changes.
Closes#3397Closes#2951
## Changes
- Removed the "Register here" link from the login page — it misled users into thinking public registration was open.
- Added redirect from /login to /register when no super admin exists (initial setup).
- Added an info alert on the register page clarifying the page is only for initial setup; additional users are invited from team settings. Hidden for the invite-token flow.
- Extracted shared useSuperAdminRedirect hook to dedupe identical fetch/redirect logic across Login and Register.
## Benefits
- Clearer UX: login page no longer suggests self-registration is available post-setup.
- Correct routing on fresh installs: users land on the registration page instead of a login page they can't use.
All 15 non-English locale files had a structural mismatch with en.json:
- en.json used nested keys (common.buttons.cancel)
- Other locales used flat keys (cancel, DeleteAccountButton)
- Result: 0.3% effective translation coverage at runtime
## Changes
Migration script (client/scripts/migrate-locales.ts):
- Restructures all locale files to match en.json's nested key structure
- Recovers existing translations via safe key-matching strategies
- Backs up originals to locales/backup/
Translation of all 15 languages:
- ar (94.6%), cs (91.6%), de (89.4%), es (92.6%), fi (94.2%)
- fr (86.7%), ja (93.3%), pt-BR (91.0%), ru (93.0%), th (93.4%)
- tr (91.9%), uk (94.3%), vi (92.5%), zh-CN (94.0%), zh-TW (94.2%)
Keys intentionally left in English are technical terms (HTTP, CPU,
Docker, gRPC, etc.), placeholder examples, and brand names.
en.json was NOT modified.
Only changes user-facing text — no enum, type, or backend status changes.
## Changes
- locales/en.json: "breached" → "threshold exceeded"
- notificationMessageBuilder.ts: notification title/summary/details
- email.ts: email subject line
The word "breached" in infrastructure monitoring was confusing users
as it implied a security breach. Renamed to "exceeded" which better
describes threshold violations (e.g. "threshold exceeded").
## Changes
- Renamed monitor status value from "breached" to "exceeded" across
server types, status service, queue helper, notification builder,
email subject lines, and MongoDB aggregation queries
- Renamed client types, status box/label components, translation key,
and infrastructure page props to match
- Added DB migration (0005) to update existing monitors with the old
status value
CacheableLookup defaults to maxTtl=Infinity, meaning successful DNS
lookups are cached forever until process restart. This causes monitors
to fail permanently if DNS changes or if a resolver outage causes
ENOTFOUND errors to persist after recovery.
Set maxTtl=300s (5 min) for successful lookups and errorTtl=30s for
failed lookups so the cache recovers automatically.
- Merge duplicate react-router-dom imports into one
- Replace useIsAdmin + useIsSuperAdmin + useSelector with single useSelector
- Remove redundant !includes("superadmin") check from canDeleteUser
## Changes
- Add DELETE /api/v1/auth/users/:userId endpoint (admin + superadmin)
- Add deleteUserById service method with role hierarchy enforcement
- Superadmins can remove admins and regular users
- Admins can only remove regular users
- No one can remove superadmins, demo users, or themselves via this endpoint
- Add "Remove user" button with confirmation dialog on edit user page
- Allow admins to view user details and access the edit user page
- Add i18n strings for remove user button and confirmation dialog
## Access control
- superadmin -> can remove admin, user
- admin -> can remove user only
- admin cannot remove superadmin or other admins (enforced on both backend and frontend)
## Changes
- Replace MUI default blue-tinted dark background with neutral grays
(#151518 for default, #1c1c21 for paper/cards)
- Remove decorative blue/purple SVG blob overlay from dark mode background
## Benefits
- Dark mode now has a clean, neutral gray appearance instead of a blue tint
## Changes
- Fixed ping host sanitization regex that stripped everything after
the first colon, which destroyed IPv6 addresses like 2001:db8::1
- New regex properly handles bracketed IPv6 ([::1]:port), bare IPv6,
and IPv4/hostname:port formats separately
## Closes
Fixes#3053
## Changes
- Added migration 0004_fixInfrastructureThresholds that finds hardware
monitors with threshold values of 5 (the old incorrect default) and
updates them to 100 (effectively disabled)
- Runs automatically on server startup like other migrations
## Closes
Fixes#3327
## Changes
- Swagger UI now prepends the current server URL (protocol + host) to
the servers list, so it works correctly in remote/Docker environments
instead of always pointing to localhost.
## Closes
Fixes#3339
- Fix tooltip background using non-existent tertiary.background
property by switching to tertiary.main
- Fix Check component text color inheritance for noHighlightText
by adding color: inherit to inner Typography
- Add translation wrapper for validation error messages in PasswordPanel
- Add translation wrapper for validation error messages in ProfilePanel
## Changes
- Rename monitorUtils.js to monitorUtilsLegacy.js to avoid conflict with MonitorUtils.ts
- Update imports in IncidentActionsMenu, JobTable, FailedJobTable, and PageSpeed/Create
## Changes
- Add global theme overrides for MUI DatePicker components (MuiPickersPopper,
MuiDateCalendar, MuiPickersCalendarHeader, MuiDayCalendar, MuiPickersDay)
- Remove inline popper styling from CreateMaintenance component as it's now
handled globally
- Calendar popup now properly adapts to both light and dark themes using
theme palette tokens
## Changes
### Sidebar
- Remove hardcoded `backgroundColor: "#000000"`
- Use `theme.palette.background.main` for dynamic theming
- Update border color to use `theme.palette.border.light`
### Body Background
- Remove hardcoded `background-color: #000000` from index.css
- Add GlobalStyles in App.jsx to apply theme background to body element
## Benefits
- Sidebar now properly displays in light mode
- Body background adapts correctly to theme changes
- Consistent theming across light and dark modes
## Changes
### New Endpoints Added
- `/incidents/team` - Get incidents by team with filtering
- `/incidents/team/summary` - Get incident summary statistics
- `/incidents/{incidentId}` - Get incident by ID
- `/incidents/{incidentId}/resolve` - Manually resolve incident
- `/queue/jobs` (GET) - List queue jobs (admin only)
- `/queue/jobs` (POST) - Add job to queue (admin only)
- `/queue/metrics` - Get queue metrics (admin only)
- `/monitors/team/groups` - Get monitor groups by team
- `/monitors/pagespeed/details/{monitorId}` - Get PageSpeed details
- `/checks/{action}` - Acknowledge all checks for all monitors
- `/checks/{action}/{monitorId}` - Acknowledge checks for specific monitor
### Endpoints Fixed
- `/monitors/export` changed to `/monitors/export/json` (matches actual route)
- Removed non-existent `/monitors/stats/{monitorId}` endpoint
- Removed non-existent `/monitors/team/summary` endpoint
- Split optional path parameter into two valid endpoints for checks
### New Schemas Added
- `Incident` - Complete incident model
- `IncidentSummary` - Incident statistics summary
- `QueueJob` - Queue job information
- `QueueMetrics` - Queue metrics data
- `Check` - Complete check result model
- `CheckTimings` - HTTP timing information
- `CheckCpuInfo` - CPU metrics for infrastructure checks
- `CheckMemoryInfo` - Memory metrics for infrastructure checks
- `CheckDiskInfo` - Disk metrics for infrastructure checks
- `CheckHostInfo` - Host information for infrastructure checks
- `CheckErrorInfo` - Error information from checks
- `CheckCaptureInfo` - Capture agent information
- `CheckNetworkInfo` - Network interface metrics
- `CheckAudits` - PageSpeed audit results
- `LighthouseAudit` - Individual Lighthouse audit result
### Responses Added
- `BadRequest` - 400 error response
### Other Fixes
- Simplified server variables to fix OpenAPI 3.1.0 validation
- Added request body to `/checks/check/{checkId}` endpoint
- Added "incidents" tag to tags array
## Benefits
- OpenAPI specification now accurately reflects the actual API
- All endpoints have proper request/response schemas
- Validation passes with swagger-cli
- Better API documentation for consumers
Create shared useSidebar hook to centralize sidebar width and transition
logic, addressing code review feedback about duplicated logic between
Sidebar and HomeLayout components.
Changes:
- Add useSidebar hook with collapsed state, width, and transition values
- Update Sidebar to use the hook instead of inline selectors and values
- Update HomeLayout to use the hook for spacer element styling
This ensures sidebar width logic is defined in one place and stays in sync.
The sidebar was showing a visible gap at the bottom when scrolling on
pages with tall tables (e.g., /checks). This occurred because the
parent container's overflow-x: hidden was breaking sticky positioning.
Changes:
- Changed sidebar from position: sticky to position: fixed
- Added a spacer Box element to maintain layout spacing
- Moved border and background styles to the sidebar component
- Cleaned up unused CSS selectors
- Replace CheckIcon SVG import with Lucide Icon component in
LatestIncidentsPanel/index.jsx
- Format IncidentItem.jsx and StatisticsPanel.jsx with Prettier
Resolve conflicts in IncidentItem.jsx and StatisticsPanel.jsx by
keeping the UI improvements from this branch while adopting the
new Lucide Icon component from develop (replacing old SVG imports).
Add overflow-x: hidden and width: 100% to .home-layout to prevent
horizontal scrollbar. Add min-width: 0 to .home-content-wrapper to
allow flexbox child to shrink below content size at narrow widths.
The Joi validation marks dateRange as optional, but the controller was using
requireString() which throws a 400 error when dateRange is missing.
Changed to optionalString() with "recent" as the default value, matching
the behavior of other similar endpoints and the Joi validation schema.
- Use AlertCircle for error and AlertTriangle for warning icons
- Use Icon color prop instead of CSS fill for Lucide stroke-based icons
- Replace wildcard import with explicit named imports for tree-shaking
- Replace sx prop with style prop on Icon components
- Add Trash2 to Icon component imports
Replace custom SVG icons and @mui/icons-material with lucide-react for consistent,
lightweight icon management across the application.
## Changes
- Add lucide-react package and remove @mui/icons-material
- Create theme-aware Icon wrapper component with color resolution
- Create iconMap.js for legacy icon name mappings
- Migrate 64 components to use new Icon component
- Remove 74 unused SVG files from assets/icons/
## Benefits
- Consistent icon API across the application
- Smaller bundle size with tree-shakeable imports
- Theme-aware color support via MUI theme paths
- Simpler maintenance with single icon library
## Changes
- Remove < and > from password regex pattern in joi.js (these chars are
stripped by DOMPurify sanitization which caused confusing validation errors)
- Update locale strings to display the list of allowed special characters
in password tooltip, error messages, and PasswordPanel requirements
## Benefits
- Users now see exactly which special characters are allowed when setting passwords
- Eliminates confusing "password cannot be empty" errors when using < or >
- Regex now accurately reflects the characters that actually work
Fixes#3010
The delete handler was using monitor._id from state, which was undefined
because the fetched monitor object didn't have _id populated. Changed to
use monitorId directly from URL params, which is already available and
used by other handlers in the same component (e.g., handlePause).
Fixes "Failed to delete monitor" error when removing pagespeed monitors.
- Simplify incident rows to single line with grid layout
- Remove redundant "Monitor:" and "Status:" labels
- Align columns vertically (monitor name, status badge, duration)
- Center-align status badge column
- Match icon styling with General Statistics (18px, strokeWidth 1.5)
- Remove pointer cursor (click not implemented)
- Add dividers and minHeight to Statistics panel for alignment
## Changes
### Logs page
- Convert server logs from monospace text to DataTable with pagination
- Add table columns: Timestamp, Level, Service, Method, Message
- Add colored level badges (info=green, warn=yellow, error=red, debug=blue)
- Add pagination with configurable rows per page
- Align diagnostics gauge cards with 16px gap and responsive widths
### Incidents page
- Redesign summary cards with consistent styling
- Remove shadows and use 1px border matching other sections
- Reduce icon sizes to 18-24px (sidebar-style)
- Reduce font sizes (13px titles, 18-32px values)
- Add titles to all three summary cards
- Fix "Most Affected Monitor" showing "Unknown Monitor" when no incidents
- Show "N/A" for avg resolution time when no incidents
- Remove cluttered "Resolutions" progress bar section
- Remove horizontal dividers between statistics rows
- Standardize card padding and gap to 16px
### Uptime page
- Fix oversized monitor names in table (removed h6 variant)
## Changes
- Remove unused semantic color groups (successSecondary, map, chatbot)
- Remove unused properties from primary and tertiary groups
- Inline accent.darker usage in globalTheme.js
- Fix greeting component crash with persisted Redux state
- Fix MonitorGrid key prop warning
## Details
Theme simplification:
- Reduced constants.js from 355 to 291 lines
- Removed 3 unused semantic color groups
- Removed 6 unused properties (contrastBorder, contrastBorderDisabled, etc.)
- Inlined darken() call for accent hover states
Bug fixes:
- Added null-safe selectors in greeting.jsx for state.ui.greeting
- Added initialization check in setGreeting reducer for older persisted state
- Fixed key prop in MonitorGrid to handle both _id and id
- Removed unused console.log and Grid2 import
Removed the following unused CSS variables that were leftovers from when
the project switched to the MUI theme system:
- --env-var-radius-1
- --env-var-width-1
- --env-var-width-3
- --env-var-height-1
- --env-var-spacing-3
- --env-var-spacing-4
- --env-var-spacing-5
- --env-var-img-width-1
- --env-var-img-width-2
- --env-var-img-width-3
- --env-var-default-1
- --env-var-default-2
- --env-var-shadow-1
These variables are not referenced anywhere in the codebase. The project
now uses MUI theme configuration (theme.spacing(), theme.palette.*)
instead of CSS variables for styling.
Kept 19 CSS variables that are still actively used during the migration
to pure MUI theme.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add optional 'group' field to Monitor schema with trimming and validation
- Add group validation to Joi schemas for create and edit monitor endpoints
- Add GET /api/v1/monitors/team/groups endpoint to fetch unique groups
- Implement case-insensitive group filtering in database layer
- Support for organizing monitors into collapsible groups
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove redundant words 'active' and 'completely'
- Remove technical details about specific check types
- Keep the description concise while maintaining clarity
- Maintain all key information about maintenance behavior
- Update maintenance window description to clearly explain what happens during maintenance
- Clarify that ALL monitoring types are suspended (pings, HTTP, port checks, etc.)
- Explain that no notifications or alerts will be triggered
- Describe status page behavior (maintenance indicator shown)
- Note that monitoring resumes automatically when maintenance ends
- Clarify that maintenance periods don't affect uptime calculations
- Provide users with complete understanding of maintenance window impact
Address code review feedback to eliminate ambiguity issues and improve reliability:
**Backend Improvements:**
- Implement priority-based matching: exact ID → exact name → partial ID
- Add input normalization (strip leading slashes, case-insensitive)
- Add ambiguity detection with warning logs for debugging
- Maintain full backwards compatibility with existing monitors
**Frontend Improvements:**
- Update validation regex to support leading slashes (/container-name)
- Improve error message clarity for user guidance
**Resolves Ambiguity Issues:**
- Container name "abc" vs Container ID "abc123..." now deterministic
- Multiple containers with similar names handled predictably
- Case-insensitive matching for better user experience
**Priority Order:**
1. Exact full ID match (64-char) - highest priority
2. Exact container name match - case-insensitive
3. Partial ID match - backwards compatibility fallback
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update Docker monitoring to support both container names and IDs
- Maintain backward compatibility with existing container ID monitoring
- Add logic to find containers by name (with or without "/" prefix)
- Update frontend UI labels and placeholders to reflect name/ID support
- Update instructions to clarify both name and ID are supported
Resolves user request: "It would be great if we could monitor docker containers by name and not just ID - given that the ID changes when containers are taken down for any reason"
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix deleteStatusPage method call to use statusPageModule
- Change this.db.deleteStatusPage to this.db.statusPageModule.deleteStatusPage
- Ensures consistency with other controller methods
- Resolves "this.db.deleteStatusPage is not a function" error
Fixes bug where status page deletion failed due to incorrect database module reference.
- Move MuiSelect vertical alignment from FilterHeader component to globalTheme.js
- Ensures consistent vertical alignment for all Select components application-wide
- Removes component-specific styling in favor of theme-level consistency
- Addresses reviewer feedback to make this a theme-level change
Components already with custom Select styling will continue to work as local styles override theme styles.
Removed top margin (mt={theme.spacing(10)}) and adjusted sticky position
from the log level selector since it was creating unwanted space between
the tab bar and the 'Log level' dropdown after removing the description
text and divider.
Removed description strings and divider lines from:
- Server logs: 'System logs - last 1000 lines' and divider
- Queue metrics: queue description and divider
This cleans up the UI by removing redundant descriptive text
that users can infer from the tab names and content context.
Changed default tab from Diagnostics (index 2) to Server Logs (index 0)
when users navigate to the Logs section from the sidebar. This makes
Server Logs the active tab by default, which is more intuitive since
it's the first tab in the list.
Added flex alignment styles to MuiSelect-select class to ensure proper vertical
alignment between text labels and plus icons in Type, Status, and State filter
buttons on the Uptime page.
Adds the foundation for secure cookie-based authentication without changing
the authentication flow. This prepares the codebase for moving JWT tokens
from Redux state to httpOnly cookies in a follow-up PR.
Changes:
- Added cookie-parser dependency for HTTP cookie handling
- Added cookieParser() middleware to Express application
- Created cookieHelpers.js utilities for consistent cookie options
- Includes getAuthCookieOptions() for setting secure authentication cookies
- Includes getClearAuthCookieOptions() for clearing cookies on logout
Infrastructure only - no behavioral changes to authentication flow yet.
Files added/modified:
- package.json (cookie-parser dependency)
- src/app.js (cookieParser middleware)
- src/utils/cookieHelpers.js (cookie utilities)
Next steps:
- Follow-up PR will modify JWT verification to check cookies
- Enable secure cookie-based authentication
- Add logout functionality to clear httpOnly cookies
Risk level: LOW (infrastructure only, no authentication changes)
Adds foundational utilities for XSS prevention without applying them yet.
This prepares the codebase for comprehensive input sanitization in a follow-up PR.
Changes:
- Added isomorphic-dompurify and jsdom dependencies
- Created sanitization utilities in src/utils/sanitization.js
- Includes recursive object sanitization functions
- Provides Express middleware for body and query sanitization
Infrastructure only - no behavioral changes yet.
Files added:
- src/utils/sanitization.js (sanitization utilities)
- package.json (new dependencies)
Next steps:
- Apply sanitization middleware in follow-up PR
- Enable XSS protection across application