Commit Graph

27 Commits

Author SHA1 Message Date
Maurice
df695ee8d8 v2.5.1 — Security hardening, backup restore fix & restore warning modal 2026-03-21 15:13:10 +01:00
Maurice
d845057f84 Security hardening, backup restore fix & restore warning modal
- Fix backup restore: try/finally ensures DB always reopens after closeDb
- Fix EBUSY on uploads during restore (in-place overwrite instead of rmSync)
- Add DB proxy null guard for clearer errors during restore window
- Add red warning modal before backup restore (DE/EN, dark mode support)
- JWT secret: empty docker-compose default so auto-generation kicks in
- OIDC: pass token via URL fragment instead of query param (no server logs)
- Block SVG uploads on photos, files and covers (stored XSS prevention)
- Add helmet for security headers (HSTS, X-Frame, nosniff, etc.)
- Explicit express.json body size limit (100kb)
- Fix XSS in Leaflet map markers (escape image_url in HTML)
- Remove verbose WebSocket debug logging from client
2026-03-21 15:09:41 +01:00
Maurice
384d583628 v2.5.0 — Addon System, Vacay, Atlas, Dashboard Widgets & Mobile Overhaul
The biggest NOMAD update yet. Introduces a modular addon architecture and three major new features.

Addon System:
- Admin panel addon management with enable/disable toggles
- Trip addons (Packing List, Budget, Documents) dynamically show/hide in trip tabs
- Global addons appear in the main navigation for all users

Vacay — Vacation Day Planner (Global Addon):
- Monthly calendar view with international public holidays (100+ countries via Nager.Date API)
- Company holidays with auto-cleanup of conflicting entries
- User-based system: each NOMAD user is a person in the calendar
- Fusion system: invite other users to share a combined calendar with real-time WebSocket sync
- Vacation entitlement tracking with automatic carry-over to next year
- Full settings: block weekends, public holidays, company holidays, carry-over toggle
- Invite/accept/decline flow with forced confirmation modal
- Color management per user with collision detection on fusion
- Dissolve fusion with preserved entries

Atlas — Travel World Map (Global Addon):
- Fullscreen Leaflet world map with colored country polygons (GeoJSON)
- Glass-effect bottom panel with stats, continent breakdown, streak tracking
- Country tooltips with trip count, places visited, first/last visit dates
- Liquid glass hover effect on the stats panel
- Canvas renderer with tile preloading for maximum performance
- Responsive: mobile stats bars, no zoom controls on touch

Dashboard Widgets:
- Currency converter with 50 currencies, CustomSelect dropdowns, localStorage persistence
- Timezone widget with customizable city list, live updating clock
- Per-user toggle via settings button, bottom sheet on mobile

Admin Panel:
- Consistent dark mode across all tabs (CSS variable overrides)
- Online/offline status badges on user list via WebSocket
- Unified heading sizes and subtitles across all sections
- Responsive tab grid on mobile

Mobile Improvements:
- Vacay: slide-in sidebar drawer, floating toolbar, responsive calendar grid
- Atlas: top/bottom glass stat bars, no popups
- Trip Planner: fixed position content container prevents overscroll, portal-based sidebar buttons
- Dashboard: fixed viewport container, mobile widget bottom sheet
- Admin: responsive tab grid, compact buttons
- Global: overscroll-behavior fixes, modal scroll containment

Other:
- Trip tab labels: Planung→Karte, Packliste→Liste, Buchungen→Buchung (DE mobile)
- Reservation form responsive layout
- Backup panel responsive buttons
2026-03-20 23:14:06 +01:00
Maurice
3edf65957b Block demo user from deleting account and changing password (v2.4.1) 2026-03-20 00:02:53 +01:00
Maurice
c887acddee v2.4.0 — OIDC login, OpenStreetMap search, account management
Features:
- Single Sign-On (OIDC) — login with Google, Apple, Authentik, Keycloak
- OpenStreetMap place search as free fallback when no Google API key
- Change password in user settings
- Delete own account (with last-admin protection)
- Last login column in admin user management
- SSO badge and provider info in user settings
- Google API key "Recommended" badge in admin panel

Improvements:
- API keys load correctly after page reload
- Validate auto-saves keys before testing
- Time format respects 12h/24h setting everywhere
- Dark mode fixes for popups and backup buttons
- Admin stats: removed photos, 4-column layout
- Profile picture upload button on avatar overlay
- TravelStats duplicate key fix
- Backup panel dark mode support
2026-03-19 23:49:07 +01:00
Maurice
74be63555d Fix API keys not loading after reload, auto-save before validate (v2.3.5)
- Admin panel now loads API keys from /me/settings endpoint (not /me)
- Validate buttons auto-save keys first so validation uses current values
- Keys persist and display correctly after page reload
2026-03-19 21:27:34 +01:00
Maurice
fd6fc9e71f Fix mobile date picker + auto-update end date from start date (v2.3.4)
- Date picker dropdown stays within viewport on mobile (no more overflow)
- Opens above if not enough space below
- Centers on very small screens (<360px)
- End date auto-adjusts when start date changes:
  - If no end date or end < start → end = start
  - If both set → preserves trip duration (shifts end by same delta)
2026-03-19 18:01:41 +01:00
Maurice
22f5623adb Add screenshot gallery to README (v2.3.3) 2026-03-19 17:23:58 +01:00
Maurice
6117b80575 Add app screenshot to README (v2.3.2) 2026-03-19 17:19:00 +01:00
Maurice
d98eaaebee Add live demo link to README and repo description (v2.3.1) 2026-03-19 17:02:12 +01:00
Maurice
45d410c1b0 Demo baseline reset: full DB snapshot/restore (v2.3.0)
Hourly reset now restores entire DB from baseline snapshot instead of
just deleting demo trips. This reverts ALL demo user changes including
modifications to shared admin trips. Admin credentials (password, API
keys) are preserved across resets. Admin can save new baseline via
Admin Panel button. Removed demoWriteBlock middleware.
2026-03-19 16:31:27 +01:00
Maurice
cd36fba0c9 Add security policy (v2.2.8) 2026-03-19 16:16:47 +01:00
Maurice
f93efe9740 Add Nginx WebSocket config to README with reverse proxy docs (v2.2.7) 2026-03-19 16:01:05 +01:00
Maurice
53b1c8617e Add reset countdown timer to demo popup (v2.2.6) 2026-03-19 15:42:22 +01:00
Maurice
bf7412d016 Fix PDF export: show trip title instead of 'Meine Reise' (v2.2.5) 2026-03-19 15:31:20 +01:00
Maurice
9b0755debc Demo popup: show on every dashboard visit, add upload notice (v2.2.4)
- Popup now shows every time user visits dashboard (not session-cached)
- Only shows on dashboard, not other pages
- Added upload disabled notice with amber highlight
- Upload listed as first full-version feature
2026-03-19 15:17:31 +01:00
Maurice
c582a7b6c8 Block uploads for demo user, restore PDF preview modal (v2.2.3)
- Demo user gets 403 on all upload endpoints (files, photos, cover, avatar)
- Admin uploads still work normally
- PDF export back in modal popup using srcdoc iframe
- Zero behavior change when DEMO_MODE is not set
2026-03-19 15:09:20 +01:00
Maurice
1a5c8cd385 Fix PDF: export opens in new tab, file preview uses object tag (v2.2.2) 2026-03-19 15:01:27 +01:00
Maurice
98f90adb6d Bump version to 2.2.1 2026-03-19 14:57:42 +01:00
Maurice
c3535967ee Show app version (v2.2.0) in user menu 2026-03-19 14:49:36 +01:00
Maurice
4d9854062c Fix PDF export: allow same-origin iframes (X-Frame-Options) 2026-03-19 14:44:35 +01:00
Maurice
173d6cd953 Fix travel-stats: wrong JOIN on days table (d.trip_id not d.id) 2026-03-19 14:22:05 +01:00
Maurice
e8acbbd129 Add demo mode with hourly reset, example trips & demo banner
DEMO_MODE=true enables: auto-seeded admin + demo user, 3 example trips
(Tokyo, Barcelona, Wien), hourly reset of demo user data, one-click
demo login, visible banner with feature info. Zero behavior change
when DEMO_MODE is not set.
2026-03-19 13:25:37 +01:00
Maurice
74f19f3312 v2.1.0 — Real-time collaboration, performance & security overhaul
Real-Time Collaboration (WebSocket):
- WebSocket server with JWT auth and trip-based rooms
- Live sync for all CRUD operations (places, assignments, days, notes, budget, packing, reservations, files)
- Socket-based exclusion to prevent duplicate updates
- Auto-reconnect with exponential backoff
- Assignment move sync between days

Performance:
- 16 database indexes on all foreign key columns
- N+1 query fix in places, assignments and days endpoints
- Marker clustering (react-leaflet-cluster) with configurable radius
- List virtualization (react-window) for places sidebar
- useMemo for filtered places
- SQLite WAL mode + busy_timeout for concurrent writes
- Weather API: server-side cache (1h forecast, 15min current) + client sessionStorage
- Google Places photos: persisted to DB after first fetch
- Google Details: 3-tier cache (memory → sessionStorage → API)

Security:
- CORS auto-configuration (production: same-origin, dev: open)
- API keys removed from /auth/me response
- Admin-only endpoint for reading API keys
- Path traversal prevention in cover image deletion
- JWT secret persisted to file (survives restarts)
- Avatar upload file extension whitelist
- API key fallback: normal users use admin's key without exposure
- Case-insensitive email login

Dark Mode:
- Fixed hardcoded colors across PackingList, Budget, ReservationModal, ReservationsPanel
- Mobile map buttons and sidebar sheets respect dark mode
- Cluster markers always dark

UI/UX:
- Redesigned login page with animated planes, stars and feature cards
- Admin: create user functionality with CustomSelect
- Mobile: day-picker popup for assigning places to days
- Mobile: touch-friendly reorder buttons (32px targets)
- Mobile: responsive text (shorter labels on small screens)
- Packing list: index-based category colors
- i18n: translated date picker placeholder, fixed German labels
- Default map tile: CartoDB Light
2026-03-19 12:46:11 +01:00
Maurice
2cad77c8fb Auto-generate JWT_SECRET in all environments
No more crash on missing JWT_SECRET. A random secret is generated
automatically with a warning that sessions won't persist across restarts.
2026-03-19 00:29:38 +01:00
Maurice
8601370a47 Allow all origins by default, restrict only when ALLOWED_ORIGINS is set
Same-origin requests don't need CORS restrictions. Users can optionally
set ALLOWED_ORIGINS to lock it down.
2026-03-19 00:13:23 +01:00
Maurice
cb1e217bbe Initial commit — NOMAD (Navigation Organizer for Maps, Activities & Destinations)
Self-hosted travel planner with Express.js, SQLite, React & Tailwind CSS.
2026-03-18 23:58:08 +01:00