Commit Graph

128 Commits

Author SHA1 Message Date
Gérnyi Márk
015be3d53a fix: incorrect hook order 2026-03-31 23:36:15 +02:00
Gérnyi Márk
7d3b37a2a3 feat: add configurable permissions system with admin panel
Adds a full permissions management feature allowing admins to control
who can perform actions across the app (trip CRUD, files, places,
budget, packing, reservations, collab, members, share links).

- New server/src/services/permissions.ts: 16 configurable actions,
  in-memory cache, checkPermission() helper, backwards-compatible
  defaults matching upstream behaviour
- GET/PUT /admin/permissions endpoints; permissions loaded into
  app-config response so clients have them on startup
- checkPermission() applied to all mutating route handlers across
  10 server route files; getTripOwnerId() helper eliminates repeated
  inline DB queries; trips.ts and files.ts now reuse canAccessTrip()
  result to avoid redundant DB round-trips
- New client/src/store/permissionsStore.ts: Zustand store +
  useCanDo() hook; TripOwnerContext type accepts both Trip and
  DashboardTrip shapes without casting at call sites
- New client/src/components/Admin/PermissionsPanel.tsx: categorised
  UI with per-action dropdowns, customised badge, save/reset
- AdminPage, DashboardPage, FileManager, PlacesSidebar,
  TripMembersModal gated via useCanDo(); no prop drilling
- 46 perm.* translation keys added to all 12 language files
2026-03-31 23:36:15 +02:00
Maurice
7eabe65bcf Merge pull request #240 from Summerfeeling/feat/more-currencies
feat: added all supported currencies from exchangerate-api (#229)
2026-03-31 23:12:32 +02:00
Maurice
3444e3f446 Merge branch 'perf-test' of https://github.com/jubnl/TREK into dev
# Conflicts:
#	client/src/components/Map/MapView.tsx
2026-03-31 23:10:02 +02:00
Maurice
c38e70e244 fix: toggle switches not reflecting state in admin settings 2026-03-31 22:49:31 +02:00
Maurice
ce7215341f fix: 12h time format input and display in bookings
- Allow typing AM/PM in time input when 12h format is active
- Format end time correctly in reservations panel (handle time-only strings)
2026-03-31 22:40:59 +02:00
Maurice
4733955531 fix: render Lucide category icons on map markers instead of text/emoji 2026-03-31 22:35:43 +02:00
Maurice
36267de117 fix: bag modal cut off on small screens 2026-03-31 22:27:26 +02:00
Maurice
fbe3b5b17e Merge pull request #225 from andreibrebene/improvements/various-improvements
Improvements/various improvements
2026-03-31 21:40:26 +02:00
Maurice
10107ecf31 fix: require auth for file downloads, localize atlas search, use flag images
- Block direct access to /uploads/files (401), serve via authenticated
  /api/trips/:tripId/files/:id/download with JWT verification
- Client passes auth token as query parameter for direct links
- Atlas country search now uses Intl.DisplayNames (user language) instead
  of English GeoJSON names
- Atlas search results use flagcdn.com flag images instead of emoji
2026-03-31 21:38:16 +02:00
Andrei Brebene
7522f396e7 feat: configurable trip reminders, admin full access, and enhanced audit logging
- Add configurable trip reminder days (1, 3, 9 or custom up to 30) settable by trip owner
- Grant administrators full access to edit, archive, delete, view and list all trips
- Show trip owner email in audit logs and docker logs when admin edits/deletes another user's trip
- Show target user email in audit logs when admin edits or deletes a user account
- Use email instead of username in all notifications (Discord/Slack/email) to avoid ambiguity
- Grey out notification event toggles when no SMTP/webhook is configured
- Grey out trip reminder selector when notifications are disabled
- Skip local admin account creation when OIDC_ONLY=true with OIDC configured
- Conditional scheduler logging: show disabled reason or active reminder count
- Log per-owner reminder creation/update in docker logs
- Demote 401/403 HTTP errors to DEBUG log level to reduce noise
- Hide edit/archive/delete buttons for non-owner invited users on trip cards
- Fix literal "0" rendering on trip cards from SQLite numeric is_owner field
- Add missing translation keys across all 14 language files

Made-with: Cursor
2026-03-31 22:23:38 +03:00
Andrei Brebene
9b2f083e4b feat: notifications, audit logging, and admin improvements
- Add centralized notification service with webhook (Discord/Slack) and
  email (SMTP) support, triggered for trip invites, booking changes,
  collab messages, and trip reminders
- Webhook sends one message per event (group channel); email sends
  individually per trip member, excluding the actor
- Discord invite notifications now include the invited user's name
- Add LOG_LEVEL env var (info/debug) controlling console and file output
- INFO logs show user email, action, and IP for audit events; errors
  for HTTP requests
- DEBUG logs show every request with full body/query (passwords redacted),
  audit details, notification params, and webhook payloads
- Add persistent trek.log file logging with 10MB rotation (5 files)
  in /app/data/logs/
- Color-coded log levels in Docker console output
- Timestamps without timezone name (user sets TZ via Docker)
- Add Test Webhook and Save buttons to admin notification settings
- Move notification event toggles to admin panel
- Add daily trip reminder scheduler (9 AM, timezone-aware)
- Wire up booking create/update/delete and collab message notifications
- Add i18n keys for notification UI across all 13 languages

Made-with: Cursor
2026-03-31 22:23:23 +03:00
jubnl
9a949d7391 Performance on trip planner (Maybe ?) 2026-03-31 21:13:29 +02:00
Summerfeeling | Timo
13904fb702 feat: added all supported currencies from exchangerate-api (#229) 2026-03-31 21:04:59 +02:00
Maurice
f7160e6dec Merge pull request #179 from shanelord01/audit/remediation-clean
Automated Security & Quality Audit via Claude Code
2026-03-31 20:53:48 +02:00
Maurice
6866644d0c Merge pull request #189 from M-Enderle/feat/gpx-full-route-import
feat(add-gpx-tracks): adds better gpx track views
2026-03-31 20:17:22 +02:00
Maurice
1d442c1d7a Merge pull request #182 from BKSalman/mobile-fixes
mobile UI fixes
2026-03-31 20:14:30 +02:00
Maurice
9a0294360c Merge pull request #181 from BKSalman/accom-fix
fix: update dayAccommodations state after create/edit/delete
2026-03-31 20:10:42 +02:00
Moritz Enderle
3aaa6e916b feat: adds better gpx track views 2026-03-31 10:29:49 +02:00
Salman Abuhaimed
299e26bebe make day plan side bar icons more readable 2026-03-31 06:29:31 +03:00
Salman Abuhaimed
96b6d7d81f fix: note modal hidden behind mobile sidebar due to z-index 2026-03-31 06:29:31 +03:00
Salman Abuhaimed
27d5c3400c fix: update dayAccommodations state after create/edit/delete 2026-03-31 06:27:45 +03:00
Claude
483190e7c1 fix: XSS in GitHubPanel markdown renderer and RouteCalculator profile bug
Escape HTML entities before dangerouslySetInnerHTML in release notes
renderer to prevent stored XSS via malicious GitHub release bodies.
Fix RouteCalculator ignoring the profile parameter (was hardcoded to
'driving').

https://claude.ai/code/session_01SoQKcF5Rz9Y8Nzo4PzkxY8
2026-03-31 00:34:09 +00:00
jubnl
fb643a1ade fix: stop drop event bubbling causing duplicate place assignment 2026-03-31 01:32:20 +02:00
Maurice
faebc62917 Merge branch 'pr-125'
# Conflicts:
#	client/src/api/client.ts
#	client/src/i18n/translations/ar.ts
#	client/src/i18n/translations/es.ts
#	client/src/i18n/translations/fr.ts
#	client/src/i18n/translations/nl.ts
#	client/src/i18n/translations/ru.ts
#	client/src/i18n/translations/zh.ts
#	client/src/pages/AdminPage.tsx
#	client/src/pages/SettingsPage.tsx
#	server/package.json
#	server/src/db/migrations.ts
#	server/src/index.ts
#	server/src/routes/admin.ts
2026-03-30 23:10:34 +02:00
Maurice
19c9e17884 Merge branch 'pr-120' into dev 2026-03-30 20:09:16 +02:00
Maurice
de859318fa feat: admin audit log — merged PR #118
Audit logging for admin actions, backups, auth events.
New AuditLogPanel in Admin tab with pagination.
Dockerfile security: run as non-root user.
i18n keys for all 9 languages.

Thanks @fgbona for the implementation!
2026-03-30 20:05:32 +02:00
Maurice
bcbb516448 refactor: replace hardcoded Vacay month/weekday arrays with Intl + i18n — based on PR #122
Remove 12 hardcoded arrays for weekdays/months across 6 languages.
Use Intl.DateTimeFormat for month names and i18n keys for weekdays.
Works for all locales automatically.

Thanks @slashwarm for the original PR!
2026-03-30 19:59:47 +02:00
Maurice
eb7984f40d fix: CustomSelect for backup schedule dropdowns, increase PWA cache limit
- Replace native <select> with CustomSelect for hour and day-of-month
  pickers in backup schedule settings (consistent UI)
- Increase PWA workbox cache size limit to 5MB
2026-03-30 19:39:54 +02:00
Maurice
70809d6c27 fix: TimezoneWidget respects 12h/24h setting, addon notification toggles, cover image path — closes #147 2026-03-30 18:08:22 +02:00
Maurice
a314ba2b80 feat: public read-only share links with permissions — closes #79
Share links:
- Generate a public link in the trip share modal
- Choose what to share: Map & Plan, Bookings, Packing, Budget, Chat
- Permissions enforced server-side
- Delete link to revoke access instantly

Shared trip page (/shared/:token):
- Read-only view with TREK logo, cover image, trip details
- Tabbed navigation with Lucide icons (responsive on mobile)
- Interactive map with auto-fit bounds per day
- Day plan, Bookings, Packing, Budget, Chat views
- Language picker, TREK branding footer

Technical:
- share_tokens DB table with per-field permissions
- Public GET /shared/:token endpoint (no auth)
- Two-column share modal (max-w-5xl)
2026-03-30 18:02:53 +02:00
Maurice
533d6f84d8 fix: use user locale instead of hardcoded de-DE for number/date formatting — closes #144
- CurrencyWidget: format numbers with user's locale
- ReservationModal: date formatting uses locale
- TripPDF: locale fallback to browser default instead of de-DE
- holidays.ts: formatDate accepts optional locale parameter
2026-03-30 17:28:14 +02:00
Maurice
095cb1b9d1 fix: transport bookings in PDF export with proper Lucide icons 2026-03-30 17:22:06 +02:00
Maurice
9aed5ff2ed fix: ICS export auth token key (auth_token not token) 2026-03-30 17:09:44 +02:00
Maurice
d189d6d776 feat: email notifications, webhook support, ICS export — closes #110
Email Notifications:
- SMTP configuration in Admin > Settings (host, port, user, pass, from)
- App URL setting for email CTA links
- Webhook URL support (Discord, Slack, custom)
- Test email button with SMTP validation
- Beautiful HTML email template with TREK logo, slogan, red heart footer
- All notification texts translated in 8 languages (en/de/fr/es/nl/ru/zh/ar)
- Emails sent in each user's language preference

Notification Events:
- Trip invitation (member added)
- Booking created (new reservation)
- Vacay fusion invite
- Photos shared (Immich)
- Collab chat message
- Packing list category assignment

User Notification Preferences:
- Per-user toggle for each event type in Settings
- Addon-aware: Vacay/Collab/Photos toggles hidden when addon disabled
- Webhook opt-in per user

ICS Calendar Export:
- Download button next to PDF in day plan header
- Exports trip dates + all reservations with details
- Compatible with Google Calendar, Apple Calendar, Outlook

Technical:
- Nodemailer for SMTP
- notification_preferences DB table with per-event columns
- GET/PUT /auth/app-settings for admin config persistence
- POST /notifications/test-smtp for validation
- Dynamic imports for non-blocking notification sends
2026-03-30 17:07:33 +02:00
Maurice
262905e357 feat: import places from Google Maps URLs — closes #141
Paste a Google Maps URL into the place search bar to automatically
import name, coordinates, and address. No API key required.

Supported URL formats:
- Short URLs: maps.app.goo.gl/..., goo.gl/maps/...
- Full URLs: google.com/maps/place/.../@lat,lng
- Data params: !3dlat!4dlng embedded coordinates

Server resolves short URL redirects and extracts coordinates.
Reverse geocoding via Nominatim provides name and address.
2026-03-30 15:18:22 +02:00
Maurice
a6a7edf0b2 feat: bucket list POIs with auto-search + optional dates — closes #105
- Bucket list now supports POIs (not just countries): add any place
  with auto-search via Google Places / Nominatim
- Optional target date (month/year) via CustomSelect dropdowns
- New target_date field on bucket_list table (DB migration)
- Server PUT route supports updating all fields
- Country bucket modal: date dropdowns default to empty
- CustomSelect: auto-opens upward when near bottom of viewport
- Search results open upward in the bucket add form
- i18n keys for DE and EN
2026-03-30 14:57:31 +02:00
Maurice
949d0967d2 feat: timezone support + granular backup schedule — closes #131
Based on PR #135 by @andreibrebene with adjustments:
- TZ environment variable for Docker timezone support
- Granular auto-backup schedule (hour, day of week, day of month)
- UTC timestamp fix for admin panel
- Server timezone exposed in app-config API
- Replaced native selects with CustomSelect for consistent UI
- Backup schedule UI with 12h/24h time format support

Thanks @andreibrebene for the implementation!
2026-03-30 14:02:27 +02:00
Maurice
cd634093af feat: multi-select category filter, performance fixes, check-in/out order
- Category filter is now a multi-select dropdown with checkboxes
- PlaceAvatar: replace 200ms polling intervals with event-based
  notification + React.memo for major performance improvement
- Map photo fetches: concurrency limited to 3 + lazy loading on images
- PlacesSidebar: content-visibility + useMemo for smooth scrolling
- Accommodation labels: check-out now appears before check-in on same day
- Timed places auto-sort chronologically when time is added
2026-03-30 13:52:35 +02:00
Maurice
1166a09835 feat: live GPS location on map + auto-sort timed places — closes #136
Live location:
- Crosshair button on the map toggles GPS tracking
- Blue dot shows live position with accuracy circle (<500m)
- Uses watchPosition for continuous updates
- Button turns blue when active, click again to stop

Auto-sort:
- Places with a time now auto-sort chronologically among other
  timed items (transports, other timed places)
- Adding a time to a place immediately moves it to the correct
  position in the timeline
- Untimed places keep their manual order_index
2026-03-30 13:30:41 +02:00
Andrei Brebene
6f2d7c8f5e Merge branch 'dev' into feat/auto-backup-schedule-and-timezone 2026-03-30 13:23:19 +03:00
Maurice
e6c4c22a1d feat: bulk import for packing lists + complete i18n sync — closes #133
Packing list bulk import:
- Import button in packing list header opens a modal
- Paste items or load CSV/TXT file
- Format: Category, Name, Weight (g), Bag, checked/unchecked
- Bags are auto-created if they don't exist
- Server endpoint POST /packing/import with transaction

i18n sync:
- Added all missing translation keys to fr, es, nl, ru, zh, ar
- All 8 language files now have matching key sets
- Includes memories, vacay weekdays, packing import, settlement,
  GPX import, blur booking codes, transport timeline keys
2026-03-30 12:16:00 +02:00
Maurice
9a044ada28 feat: blur booking codes setting + two-column settings page — closes #114
- New display setting "Blur Booking Codes" (off by default)
- When enabled, confirmation codes are blurred across all views
  (ReservationsPanel, DayDetailPanel, Transport detail modal)
- Hover or click reveals the code (click toggles on mobile)
- Settings page uses masonry two-column layout on desktop, single
  column on mobile (<900px)
- Fix hardcoded admin page title to use i18n key
2026-03-30 11:47:05 +02:00
Maurice
da5e77f78d feat: GPX file import for places — closes #98
Upload a GPX file to automatically create places from waypoints.
Supports <wpt>, <rtept>, and <trkpt> elements with CDATA handling.
Handles lat/lon in any attribute order. Track-only files import
start and end points with the track name.

- New server endpoint POST /places/import/gpx
- Import GPX button in PlacesSidebar below Add Place
- i18n keys for DE and EN
2026-03-30 11:35:28 +02:00
Andrei Brebene
cc8be328f9 feat: add granular auto-backup scheduling and timezone support
Add UI controls for configuring auto-backup schedule with hour, day of
week, and day of month pickers. The hour picker respects the user's
12h/24h time format preference from settings.

Add TZ environment variable support via docker-compose so the container
runs in the configured timezone. The timezone is passed to node-cron for
accurate scheduling and exposed via the API so the UI displays it.

Fix SQLite UTC timestamp handling by appending Z suffix to all timestamps
sent to the client, ensuring proper timezone conversion in the browser.

Made-with: Cursor
2026-03-30 12:27:52 +03:00
Maurice
f1c4155d81 feat: add Brazilian Portuguese (pt-BR) language support — thanks @fgbona 2026-03-30 12:27:21 +03:00
quentinClaudel
931c5bd990 feat: improve French translations — thanks @quentinClaudel 2026-03-30 12:27:21 +03:00
Maurice
ee54308819 feat: expand budget currencies from 14 to 46 — closes #96
Add BDT, INR, BRL, MXN, KRW, CNY, SGD, PHP, VND, ZAR, AED, SAR, ILS,
EGP, MAD, HUF, RON, BGN, HRK, ISK, RUB, UAH, LKR, CLP, COP, PEN, ARS,
NZD, IDR, MYR, HKD, TWD with correct currency symbols.
2026-03-30 11:16:23 +02:00
Gérnyi Márk
66b00c24e2 add leftWidth/rightWidth centering to PlaceInspector 2026-03-30 11:15:57 +02:00
Maurice
f6d08582ec feat: expense settlement — track who paid, show who owes whom — closes #41
- Click member avatars on budget items to mark who paid (green = paid)
- Multiple green chips = those people split the payment equally
- Settlement dropdown in the total budget card shows optimized payment
  flows (who owes whom how much) and net balances per person
- Info tooltip explains how the feature works
- New server endpoint GET /budget/settlement calculates net balances
  and minimized payment flows using a greedy algorithm
- Merged category legend: amount + percentage in one row
- i18n keys added for DE and EN
2026-03-30 11:12:22 +02:00