* fix: browser back gesture closes modal instead of navigating
- Push history state when opening medication detail modal
- Handle popstate event to close modal on browser back
- Replace direct setSelectedMed(null) with closeMedDetail() helper
- Improves mobile UX: swiping back closes modal instead of leaving page
* feat: add back-swipe support for all modals
- Add history.pushState/popstate handling for all modal types
- Profile, ShareDialog, EditModal, RefillModal, ImageLightbox,
ScheduleLightbox, UserFilter now all support browser back button
- Mobile users can now swipe back to close any modal instead of
navigating away from the app
- ESC key also triggers proper history-based close for all modals
- Fix duplicate openShareDialog function
- Fix recursive call bug in openUserFilter
* fix: prevent past days count from wrapping to new line
- Add flex-wrap: nowrap to .past-days-toggle
- Add white-space: nowrap and flex-shrink: 0 to .past-days-count
- Ensures (7 Tage), (14 Tage) etc. stays on same line as label
* fix: improve schedule row layout for mobile screens
- Stack schedule label and value vertically on small screens (<400px)
- Add word-break for long text values
- Prevents 'Einnahmeprüfung' and '15 Min. vor geplanter Zeit' from overlapping
* feat: add back-swipe support for image lightbox on share page
- Add history.pushState/popstate handling for lightbox in SharedSchedule
- Mobile users can now swipe back to close image instead of navigating away
* feat: Add Medication Refill feature with UI improvements
- Add refill functionality to medications (add packs/loose pills)
- Add refill API endpoint with history tracking
- Add refill section in edit forms (desktop & mobile)
- Add refill modal in medication detail view
- Add refill history display with expand/collapse
- Add schedule lightbox for clicking medication images
- Improve button styling with primary/info/success classes
- Move '+ New entry' button to medication list header
- Lightbox size: 50% desktop, 90% mobile
- Update selectedMed sync after stock changes
- Migrate from schema-sql.ts to Drizzle Kit migrations
* fix: Improve mobile tooltips and refill modal layout
- Center tooltips on screen for mobile devices (fixed position)
- Close tooltips automatically when scrolling on touch devices
- Use click-based tooltip activation instead of hover on mobile
- Fix refill modal buttons to display in two rows on mobile
- Add dismissed column to dose_tracking table schema
- Add POST /doses/dismiss endpoint for batch dismissing
- Add DELETE /doses/dismiss endpoint to un-dismiss all
- Add frontend dismissedDoses state and missedPastDoseIds useMemo
- Add Clear missed button with confirmation dialog
- Add CSS styles for .past-days-header and .clear-missed-btn
- Add i18n translations for en/de
- Add 5 tests for dismiss endpoints
- Update test schemas with dismissed column
Allows users to acknowledge missed doses without deducting stock.
Closes#28
- Add Pushover to supported services list in UI
- Add Gotify to supported services list
- Add URL placeholder with examples (ntfy, pushover)
- Add link to shoutrrr.dev for all available services
- Change input type from 'url' to 'text' (shoutrrr URLs aren't HTTP URLs)
- Add comprehensive Push Notifications section to README
- Include URL examples for ntfy, Pushover, Gotify, Discord, Telegram
Closes feature request for Pushover support.
* fix(ui): improve Export/Import section layout and styling
- Redesign as two-column card layout with icons
- Remove CAPSLOCK from labels
- Add proper descriptions for export and import sections
- Improve checkbox and button styling
- Make responsive for mobile
* fix(ui): clean up Export/Import section design
- Remove ugly folder icons
- Replace hint text box with info tooltip on title
- Cleaner h3 styling with uppercase letters
- Better visual hierarchy
* feat: add data export/import functionality
- Add /export and /import API endpoints with schema-independent JSON format
- Export includes: medications, dose history, settings, share links
- Uses _exportId references for medications, remapped on import
- Images exported as base64 data URLs
- Optional sensitive data inclusion (shoutrrr URLs, etc.)
- Import replaces all existing data with confirmation warning
- Add comprehensive test coverage
- Add English and German translations
- Add frontend UI in Settings page with export/import controls
* fix: correct JSX structure and TypeScript types
- Fix modal placement outside ternary expression in Settings
- Add type assertion for request.body in import route test
* docs: translate copilot-instructions to English
- Add explicit rule that English is the primary language
- Translate all German sections to English
- User may communicate in German, but all project artifacts must be English
* ci: prevent duplicate test runs - tests only on PRs, inline tests for builds
* docs: add testing and CI/CD documentation
* security: fix CodeQL vulnerabilities (SSRF, XSS, rate limiting)
- Add URL validation to prevent SSRF attacks on notification endpoints
- Block private IPs (10.x, 172.16-31.x, 192.168.x, 169.254.x)
- Block localhost and internal hostnames
- Only allow HTTP/HTTPS protocols
- Add HTML escaping for medication names in email templates (XSS)
- Add stricter rate limiting for auth routes (5 req/15min for login/register)
- Add SSRF protection tests (405 tests total)
* security: add rate limiting to remaining auth routes
* chore: add CodeQL config to suppress rate-limit false positives
Rate limiting IS implemented via @fastify/rate-limit plugin:
- Global: 100 req/min (index.ts)
- Auth routes: 5-10 req/min via config.rateLimit option
CodeQL doesn't recognize Fastify's plugin-based rate limiting pattern.
* ci: switch to CodeQL Advanced Setup
- Add custom codeql.yml workflow
- Configure to use codeql-config.yml
- Exclude js/missing-rate-limiting rule (false positive)
Rate limiting is implemented via @fastify/rate-limit plugin
* ci: add explicit permissions to workflows
Fixes CodeQL 'Workflow does not contain permissions' warnings.
Sets minimal 'contents: read' at top level.
* ci: add manual trigger to CodeQL workflow
* ci: add explicit permissions to all workflow jobs
* build(deps): bump esbuild, @vitest/coverage-v8 and vitest in /backend
Bumps [esbuild](https://github.com/evanw/esbuild) to 0.27.2 and updates ancestor dependencies [esbuild](https://github.com/evanw/esbuild), [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest). These dependencies need to be updated together.
Updates `esbuild` from 0.21.5 to 0.27.2
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG-2024.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.21.5...v0.27.2)
Updates `@vitest/coverage-v8` from 2.1.9 to 4.0.16
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/coverage-v8)
Updates `vitest` from 2.1.9 to 4.0.16
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/vitest)
---
updated-dependencies:
- dependency-name: esbuild
dependency-version: 0.27.2
dependency-type: indirect
- dependency-name: "@vitest/coverage-v8"
dependency-version: 4.0.16
dependency-type: direct:development
- dependency-name: vitest
dependency-version: 4.0.16
dependency-type: direct:development
...
Signed-off-by: dependabot[bot] <support@github.com>
* docs: add GitHub issue templates
- Bug report template with deployment type, browser info, logs
- Feature request template with affected area, priority
- Config with link to discussions and README
- Optimize test.yml to skip tests for non-code changes
* Initial plan
* Remove database schema duplication by creating shared schema-sql.ts module
Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>
* Refactor frontend date formatting to eliminate duplication
Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>
* docs: Add branch protection warning and PR workflow to instructions
* ci: remove paths filter from test workflow to fix branch protection
* fix: add .js extension to schema-sql imports for ESM compatibility (#15)
* feat: add setting to skip reminders for taken doses
- Add skipRemindersForTakenDoses setting to database schema
- Extend settings API to save and load new setting
- Update intake reminder scheduler to filter taken doses
- Add frontend toggle in settings with i18n (EN/DE)
- Only check doses from today (timezone-aware)
- Update all test schemas with new field
- All 405 tests passing
* feat: add repeat reminders for missed doses
- Add repeatRemindersEnabled and reminderRepeatIntervalMinutes settings
- Refactor intake reminder state from array to object with sendCount tracking
- Update scheduler to send repeated reminders at configurable intervals
- Only remind for today's doses (timezone-aware filtering)
- Add frontend toggle and interval input (5-480 minutes) in settings
- Maintain backward compatibility for old state file format
- Update all test schemas and assertions
- All 406 tests passing
* feat: add nagging reminders with max limit and ENV defaults
- Add maxNaggingReminders setting to limit repeat reminders (1-20)
- Add ENV defaults for all user settings (DEFAULT_*)
- Add ALTER TABLE migrations for backward compatibility
- Add smtpConfigured/shoutrrrConfigured to health endpoint
- Fix Push toggle to allow enabling without existing URL
- Disable skip/repeat toggles when no notifications enabled
- Add Pocket ID button to registration page
- Add getTodaysIntakes() for repeat reminder logic
- Update translations (en/de) for new settings
- Add comprehensive tests for new features
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>
- Updated medication schema to replace stripsPerPack and tabsPerStrip with blistersPerPack and pillsPerBlister.
- Adjusted medication routes to handle new blister and pill structure, including calculations for total pills.
- Modified frontend components to reflect changes in medication data structure and ensure compatibility with new backend logic.
- Updated reminder scheduler and share routes to utilize the new medication model.
- Enhanced Docker configuration for better permissions handling during development.
- Enhanced the database migration process to ensure compatibility with existing production databases, including detailed steps for adding/modifying columns.
- Updated the client-side logic to support tracking doses taken by multiple users, including changes to the data structure and UI components.
- Added new styles for per-person dose tracking to improve user experience and visual clarity.
- Added `taken_by_json` column to `medications` table to store an array of names.
- Updated migration scripts to convert existing `taken_by` data into JSON format.
- Modified backend routes to handle the new `taken_by_json` structure, including parsing and filtering logic.
- Updated frontend to support multi-value input for "Taken By" using tags.
- Adjusted validation and state management for the new array format in forms.
- Enhanced UI for displaying multiple names and added autocomplete suggestions for input.
- Updated translations for input placeholders to reflect new functionality.
- Added CSS styles for tag input components.
- Added new translation keys for empty and low stock notifications in both English and German.
- Implemented user authentication for planner routes and improved user settings loading.
- Separated empty and low stock medications for clearer notifications.
- Enhanced email notifications with detailed alerts for empty and low stock medications.
- Updated user settings in the database when reminders are sent for both intake and stock notifications.
- Improved form validation in the frontend with character limits and error messages.
- Added CSS styles for form validation feedback and character count display.
feat(oidc): refactor setAuthCookies to use centralized cookie options for consistency
feat(nginx): update configuration to pass cookies through proxy for improved session handling
- Implemented avatar upload and deletion in the Auth context.
- Updated UserProfile component to handle avatar display and actions.
- Modified backend routes to return anonymous user ID when auth is disabled.
- Added avatar_url column to users table in the database.
- Enhanced UI for user menu and profile modal to support avatar display.
- Updated translations for new avatar-related strings.
- Improved stock status calculation for medications in the planner.