Commit Graph

788 Commits

Author SHA1 Message Date
Ulas c93be9049c feat(dashboard): add shopping list widget
Show shopping lists with open items directly on the dashboard.
Each list displays a progress bar, the first few unchecked items,
and a "+N more" overflow indicator. Widget only appears when there
are lists with open items.

Backend: new shoppingLists query in /api/v1/dashboard (up to 3 lists,
6 open items each). Frontend: renderShoppingLists() widget following
existing widget pattern. CSS: compact list/progress/item styles.
i18n: shoppingMore key added to de/en/it.

Requested in discussion #9
2026-04-04 14:30:31 +02:00
Ulas 47b34c4829 fix(modal): add fallback timer for mobile close animation
On mobile, closeModal() relies on the CSS animationend event to call
_doClose(). When the animation does not fire (prefers-reduced-motion,
tab switch, browser quirk), the modal stays stuck and the user cannot
dismiss it. A 300ms fallback timer now guarantees cleanup runs.

Reported in discussion #9
2026-04-04 14:16:00 +02:00
Ulas 597c2602aa fix(i18n): translate category names in tasks and budget displays
Category group headers in tasks and bar chart labels / transaction meta
in budget were showing raw German database keys instead of going through
CATEGORY_LABELS() i18n mapping.

Closes #11
2026-04-04 14:08:41 +02:00
ulsklyc 7b13275882 Update README.md 2026-04-04 12:54:18 +02:00
Ulas 6454c1fc9f chore: bump version to v0.7.5 and update changelog 2026-04-04 07:27:42 +02:00
Ulas 38c5852c78 fix(ux): improve microinteractions across the app
1. Nav-item tap: smooth scale transition instead of abrupt snap
2. Custom toggle switch: iOS-style toggle replaces native checkboxes
3. Focus-visible: outline on cards, buttons, FABs for keyboard users
4. Empty-state: gentle fade-in animation
5. Toast icons: SVG icons for success/danger/warning types
6. Swipe haptic: vibrate(15) fires at threshold during touchmove
2026-04-04 07:25:54 +02:00
Ulas db60279f87 docs: add interface design system documentation
Captures existing design decisions - palette, spacing, depth strategy,
typography, layout patterns, and module accent rationale.
2026-04-04 07:13:53 +02:00
Ulas dd10974997 fix(ux): defer old stylesheet removal until after page content is gone
Previous fix removed the old CSS when new CSS loaded, but that happened
BEFORE the out-animation completed - causing a flash of unstyled content.
Now the old stylesheet stays until replaceChildren removes the old DOM.
2026-04-04 07:04:52 +02:00
Ulas a9d2a802ab fix(ux): prevent flash of unstyled content during page transitions
- Keep old page stylesheet until new one is fully loaded
- Hide new page wrapper until render() completes before starting animation
2026-04-04 06:58:12 +02:00
Ulas 1c7b77401d chore: bump version to v0.7.4 and update changelog 2026-04-04 06:51:38 +02:00
Ulas d92f7ca446 fix(design): replace hardcoded values with design tokens
Audit found ~35 violations against the token system. Fixed:
- Hardcoded shadows in layout.css replaced with --shadow-sm/md
- 8 rgba colors extracted to new glass tokens (--color-glass-*)
- border-radius: 50% replaced with var(--radius-full)
- ~25 off-grid spacing values (5px, 6px, 7px, 14px, 15px, 22px,
  26px, 34px) aligned to 4px grid using space tokens
2026-04-04 06:50:19 +02:00
Ulas 364d029950 fix(ux): prevent iOS auto-zoom on inputs + lazy-load page CSS
Increase font-size to 16px on mobile for shopping quick-add inputs,
notes search, and contacts search. Desktop breakpoint restores compact
sizes. Move 9 page-specific stylesheets from index.html to on-demand
loading in router.js, reducing initial CSS payload.
2026-04-04 06:39:45 +02:00
Ulas 70c1291ae7 fix(a11y): skip-link target, priority labels, greeting tokens
- Rename #page-content to #main-content so skip-to-content link
  targets the semantic <main> landmark
- Add sr-only priority labels to dashboard task items for screen
  readers (WCAG 1.4.1 color-not-only)
- Replace hardcoded hex in greeting gradient with accent tokens
  so dark mode themes the banner correctly
- Replace hardcoded gap: 2px with --space-0h token
- Bump version to 0.7.2
2026-04-04 06:31:21 +02:00
Ulas 6bc4c46f03 fix(security): eliminate XSS vectors and restore zoom accessibility
- Extract shared esc() utility (public/utils/html.js) replacing 8
  duplicate escHtml() functions across all page modules
- Apply HTML escaping to all user-controlled data in innerHTML
  templates: titles, names, locations, descriptions, colors, notes
  content, weather data, autocomplete suggestions
- Remove user-scalable=no and maximum-scale=1 from viewport meta
  tag, restoring pinch-to-zoom for WCAG 1.4.4 compliance
- Bump version to 0.7.1
2026-04-04 06:25:28 +02:00
Ulas 87186c03c0 docs: add BL-11 CardDAV contacts provider to backlog (issue #10) 2026-04-04 01:43:08 +02:00
Ulas 1146588212 docs: update public docs post-audit for v0.7.0
- SECURITY.md: add bcrypt v6 reference and mandatory SESSION_SECRET note
- CODE_OF_CONDUCT.md: add enforcement contact (GitHub Private Reporting)
- BACKLOG.md: add completed features table entries for v0.5.0 through v0.7.0
- docs/SPEC.md: add supported languages table with Italian (v0.5.8)
- Remove CLAUDE.md.proposed (tracked, deleted from disk)
2026-04-04 01:37:20 +02:00
Ulas 9b21a72d40 chore: release v0.7.0 - audit remediation
Bump version to 0.7.0 and add CHANGELOG entry covering all
audit findings: bcrypt upgrade, ESM migration, session secret
hardening, structured logging, documentation translations,
and repository cleanup.
2026-04-04 01:22:39 +02:00
Ulas 9a68fb7b0c fix(auth): remove SESSION_SECRET fallback - always throw if unset
App refuses to start without SESSION_SECRET regardless of NODE_ENV.
Removes risk of accidental insecure deployment when NODE_ENV is not
explicitly set to production.
2026-04-04 01:16:59 +02:00
Ulas c1176de661 fix(audit): address security audit findings
- Translate German error/warn messages in auth.js to English
- Add CODE_OF_CONDUCT.md (Contributor Covenant v2.1)
- Remove docs/claude-md-migration.md (internal migration artifact)
- Clarify README first-login instruction with credential hint
2026-04-04 01:13:50 +02:00
Ulas 7a2516153c fix(esm): fix stale comments and use node: prefix for crypto import 2026-04-03 23:19:16 +02:00
Ulas b139eea623 refactor(esm): migrate server and tests from CommonJS to ESM
Convert all server/, test, and setup files from require()/module.exports
to import/export syntax. Activate ESM globally via "type": "module" in
package.json and load dotenv via --import dotenv/config in npm scripts.
2026-04-03 23:11:20 +02:00
Ulas 2f6127911e fix(imports): convert require() to ESM import for randomBytes in auth.js 2026-04-03 23:00:38 +02:00
Ulas 3b90074723 refactor(logging): replace console.* with structured logger across server
Add server/logger.js - zero-dependency, level-based logger that outputs
JSON in production and human-readable format in development. Controlled
via LOG_LEVEL env var (debug/info/warn/error, default: info).

Replaces all 100 console.log/warn/error calls in 14 server files.
2026-04-03 22:05:22 +02:00
Ulas 5b1e6915ac fix(security): replace hardcoded session secret fallback with random generation
Instead of a static 'dev-only-secret-not-for-production' fallback,
generate a random one-time secret in development. Warns that sessions
won't survive restarts. Production guard unchanged.
2026-04-03 21:59:41 +02:00
Ulas ae8fbdd465 fix(deps): upgrade bcrypt 5.1.1->6.0.0 and patch path-to-regexp ReDoS
Resolves all 5 npm audit vulnerabilities (4 high in tar via
node-pre-gyp, 1 high path-to-regexp ReDoS). bcrypt 6 replaces
node-pre-gyp with prebuildify, removing 46 transitive packages.
2026-04-03 21:58:28 +02:00
Ulas 72eeee27c9 chore: translate .gitignore comments to English and add audit report patterns 2026-04-03 21:55:10 +02:00
Ulas 614a496256 docs: translate package.json description and .env.example to English
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 21:54:31 +02:00
Ulas ecff4a6e04 chore: remove orphaned audit docs
Internal dev artifacts (claude-md-audit, repo-audit) no longer needed -
findings have been actioned and tracked in git history.
2026-04-03 21:53:12 +02:00
Ulas 660a3ffa1c fix(budget): fix category update failing with SQLite binding error
The `date` import from validate.js shadowed the `date` field from
req.body, so SQLite received a function reference instead of a string
when updating a budget entry - causing a TypeError.

Fix by aliasing the import to `validateDate` and adding `date` to
the req.body destructuring.

Closes #8

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 18:28:31 +02:00
Ulas 3d2604bab9 fix(security): address critical and high findings from security audit
Fix stored XSS in tasks (titles/subtasks) and settings (member list)
by applying escHtml(). Harden trust proxy to loopback default, add
OAuth state parameter for Google Calendar CSRF protection, sanitize
CSV export against formula injection, invalidate sessions on user
deletion, restrict usernames to alphanumeric chars, and require admin
role for calendar sync triggers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 17:28:36 +02:00
Ulas 1122bd269b style: replace em dashes with hyphens throughout codebase
Replace all — with - in all source files (JS, CSS, HTML, JSON,
Markdown) for consistency and readability.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 17:04:39 +02:00
Ulas 6046cac7a8 docs: translate German documentation files to English
Translate BACKLOG.md and docs/SPEC.md from German to English for
international contributor accessibility. Fix outdated CONTRIBUTING.md
statement that claimed UI text is German-only — app now supports
multiple locales via i18n.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 17:01:19 +02:00
Ulas b1ee4439be feat(i18n): add Italian localization
Add complete Italian translation (497 keys) based on PR #7 by
@albanobattistella. Fixed filename from "it. json" to "it.json" and
registered Italian in SUPPORTED_LOCALES and the locale picker component.

Co-Authored-By: albanobattistella <34811668+albanobattistella@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 15:35:08 +02:00
Ulas 678c896862 fix(calendar): expand recurring multi-day events and support YEARLY frequency
Root causes:
1. parseRRule did not strip the "RRULE:" prefix stored by the ICS parser,
   causing all recurrence rules from CalDAV sync to silently fail parsing
2. YEARLY frequency (used by birthday events) was not supported
3. expandRecurringEvents filtered instances only by start date, missing
   multi-day events that start before the view window but span into it
4. All-day recurring instances got datetime end values instead of date-only

Fixes #5 (follow-up from @tschig)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 12:47:18 +02:00
Ulas 261dae5990 fix(calendar): correct all-day DTEND handling, add DURATION support, include birthdays
All-day events showed on the correct day plus the next day because ICS
DTEND for VALUE=DATE is exclusive (RFC 5545) but was treated as inclusive.
Multi-day events using DURATION instead of DTEND were missing entirely.
Birthday calendars were explicitly filtered out during Apple Calendar sync.

Closes #5

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 12:31:29 +02:00
Ulas 2e3c5a9afa docs: replace em dashes with hyphens in public-facing docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 12:25:47 +02:00
Ulas eafe2b964d fix(sync): resolve iCloud Calendar sync FOREIGN KEY crash and sync all calendars
The Apple Calendar sync hardcoded created_by=1 which fails when no user
with ID 1 exists, causing every single event import to fail silently.
Now dynamically resolves the first available user. Also syncs all
calendars instead of only the first one, adds the missing cfgDel helper,
and gracefully skips unreachable calendars.

Fixes #4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 12:10:58 +02:00
Ulas cd963540cf fix(db): quote SQLCipher PRAGMA hex key to fix fresh install crash
The hex-encoded encryption key (x'...') is not valid as a bare PRAGMA
value in better-sqlite3. Wrapping it in double quotes produces valid
SQLCipher PRAGMA syntax.

Fixes #3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 11:43:46 +02:00
ulsklyc 2e6fb3de65 Update README.md 2026-04-03 11:14:06 +02:00
ulsklyc fe3853594a Refine README formatting and punctuation
Updated formatting and punctuation in the README file for consistency and clarity.
2026-04-03 11:13:10 +02:00
Ulas 6e0eda8ba4 fix(security): address multiple security findings from audit
- Fix SQLCipher PRAGMA key interpolation (hex-encode key to prevent crash on single quotes)
- Enforce min password length (8 chars) on admin user creation
- Add length bounds on username/display_name and login inputs
- Invalidate other sessions on password change
- Multi-stage Docker build (exclude build tools from runtime)
- Exclude docs/ from Docker image
- Consolidate dotenv.config() to single entry point
- Document flat family authorization model in SECURITY.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 09:11:17 +02:00
Ulas 7a520a24de ci: add GitHub Actions workflow to publish Docker image to GHCR
Builds and pushes to ghcr.io/ulsklyc/oikos on every push to main
and on version tags. Tags: branch name, semver, short SHA.
Uses Docker layer caching via GitHub Actions cache.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 21:58:39 +02:00
Ulas 63a0febfa1 docs: add awesome-selfhosted submission files
Prepared oikos.yml and issue template for awesome-selfhosted-data.
Submission blocked until first release (v0.1.0, 2026-03-30) is 4 months old (earliest: 2026-07-30).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 17:13:22 +02:00
Ulas 1a7ad72d9a docs: use absolute URLs for OG meta images
Social media crawlers require absolute URLs to resolve images correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 15:48:58 +02:00
Ulas f425af390f docs: add project landing page for GitHub Pages
Static bilingual (EN/DE) landing page with dark/light theme support,
responsive design, scroll animations, theme-aware screenshot gallery,
and Open Graph images for social sharing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 15:34:02 +02:00
Ulas 7ef1389d44 fix(ci): remove Node.js 24.x from test matrix
Node 24 is not yet LTS and native dependencies (bcrypt, better-sqlite3,
sharp) fail to compile on it, causing CI failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 15:05:27 +02:00
Ulas 28cf388917 docs: add comprehensive installation guide and link from README
New docs/installation.md covers the full setup journey for Docker
beginners: prerequisites, step-by-step install, .env reference,
Nginx/HTTPS, updates, backup/restore, and troubleshooting.
README Quick Start updated to include clone + .env steps and
links to the detailed guide.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:54:20 +02:00
Ulas 789f07100e docs: refine README structure and Quick Start section
Separate docker compose and setup steps for clarity, remove redundant
horizontal rules, split License into its own section per style guide.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:45:02 +02:00
Ulas f7b9f8c876 docs: overhaul README with modern, concise project presentation
Replace verbose README with a streamlined structure inspired by
Immich/Mealie/LobeChat. Focus on scanability, mobile-first screenshots,
and clear communication of architectural decisions (zero-dependency
frontend, privacy-first, PWA).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:43:19 +02:00
Ulas 9a96a1a406 chore: remove CLAUDE.md.proposed after applying to local CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:30:23 +02:00