Commit Graph

227 Commits

Author SHA1 Message Date
dependabot[bot]
f4778d09f6 chore(deps-dev): bump @types/node from 20.19.33 to 20.19.37 (#17)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.19.33 to 20.19.37.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 20.19.37
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-27 10:37:56 +01:00
dependabot[bot]
88dc8dcbeb chore(deps): bump actions/checkout from 4 to 6 (#13)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-27 10:37:13 +01:00
dependabot[bot]
457d92e657 chore(deps): bump the react group with 2 updates (#15)
Bumps the react group with 2 updates: [react](https://github.com/facebook/react/tree/HEAD/packages/react) and [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom).


Updates `react` from 19.2.3 to 19.2.4
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.4/packages/react)

Updates `react-dom` from 19.2.3 to 19.2.4
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.4/packages/react-dom)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react-dom
  dependency-version: 19.2.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-27 10:36:28 +01:00
Ralksta
43d5b4d15d 🛡️ Sentinel: Add rate limiting to /api/og endpoint (#47)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-03-27 10:36:25 +01:00
Ralksta
c8f75e4615 feat(a11y): enhance accessibility of password gate form (#46)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-03-27 10:36:22 +01:00
Ralksta
5ebc900851 feat(ux): Add proper ARIA attributes to Lightbox modal and EXIF toggle (#45)
Adds `role="dialog"`, `aria-modal="true"`, and `aria-label` to the `.overlay` container to improve screen reader accessibility. Also adds `aria-expanded` and `aria-controls` to the EXIF info toggle button, linking it to the newly ID'd `#exif-panel`.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-03-27 10:36:19 +01:00
ralksta
228771decc Merge PR 36 and resolve ci.yml conflict 2026-03-22 10:03:02 +01:00
Ralksta
6a45dc3657 Add aria-label to input fields for better accessibility (#39)
Added aria-labels to the password input in `components/PasswordGate.tsx` and the grid columns/gap inputs in `components/DevToolbar.tsx` to provide clear semantic meaning for screen readers.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-03-22 09:57:29 +01:00
Ralksta
e3e5972b32 ⚡ Bolt: Optimize base64 decoding for ThumbHash (#40)
* ⚡ Bolt: Optimize base64 decoding for ThumbHash

Co-authored-by: ralksta <16941050+ralksta@users.noreply.github.com>

* ⚡ Bolt: Fix CI by adding AUTH_SECRET env var to build step

Co-authored-by: ralksta <16941050+ralksta@users.noreply.github.com>

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-03-22 09:51:25 +01:00
dependabot[bot]
db19504c91 chore(deps-dev): bump eslint from 9.39.2 to 9.39.4 (#16)
Bumps [eslint](https://github.com/eslint/eslint) from 9.39.2 to 9.39.4.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.39.2...v9.39.4)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 9.39.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-22 09:51:19 +01:00
dependabot[bot]
1f83bad3a7 chore(deps): bump actions/setup-node from 4 to 6 (#14)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-22 09:51:11 +01:00
google-labs-jules[bot]
8cd96d4dac Fix CI failures due to AUTH_SECRET and missing Playwright types
Co-authored-by: ralksta <16941050+ralksta@users.noreply.github.com>
2026-03-20 11:38:33 +00:00
google-labs-jules[bot]
cdc26c00ac 🛡️ Sentinel: [HIGH] Cache health check endpoint to prevent upstream DoS
Co-authored-by: ralksta <16941050+ralksta@users.noreply.github.com>
2026-03-20 11:33:38 +00:00
ralksta
e9154cedb8 fix(security): resolve rate-limiting IP spoofing and eviction bypass 2026-03-15 07:41:49 +01:00
ralksta
922302ce5c chore: implement audit action items and translate hardcoded German text 2026-03-15 07:32:42 +01:00
ralksta
3fa47f7031 chore: add GitHub community files and CI pipeline
- .github/workflows/ci.yml: TypeScript check + Vitest + build on every PR
- .github/dependabot.yml: weekly npm + Actions updates (minor/patch grouped)
- .github/ISSUE_TEMPLATE/: bug_report, feature_request, config (→ Discussions)
- .github/PULL_REQUEST_TEMPLATE.md: checklist for contributors
- SECURITY.md: responsible disclosure policy via GitHub Advisories
- CONTRIBUTING.md: dev setup, code style, commit conventions
2026-03-13 13:00:19 +01:00
ralksta
a97b261c14 fix: raise map rate limit 30→120/min, allow 5min private browser cache
Prevents spurious 429s during normal browsing/refreshing.
Browser now caches personalised map data for 5 minutes (private,
so CDNs/proxies won't share it between users).
2026-03-13 12:55:07 +01:00
ralksta
6c20218369 security: fix XSS in map popups, refactor HeroTextContent, add evict test
- escapeHtml() in MapView.tsx sanitises city/country/url/name before HTML injection
- HeroTextContent extracted to top-level component with explicit props (was nested inside async Server Component)
- rate-limit.test.ts: add evictIfFull stress test (6/6 pass)
2026-03-13 12:52:09 +01:00
ralksta
c610ad2a7d fix(map): show HTTP status code in error message for easier debugging 2026-03-13 12:31:21 +01:00
ralksta
60b86b540f fix: move DevToolbar dynamic import to Client Component
ssr: false is not allowed with next/dynamic in Server Components.
Extracted the dynamic() call into DevToolbarLoader.tsx ('use client')
so layout.tsx stays a pure Server Component.
2026-03-13 12:28:59 +01:00
ralksta
33fd31e926 refactor: deslop — remove dead botanica preset, extract shared helpers
- Remove dead  theme preset (no CSS, not in DevToolbar)
- Extract  from closure → module-level export in lib/config/index.ts
- Extract  helper in app/[...path]/page.tsx to deduplicate password gate check
- Extract  inner component in app/page.tsx (was 4× inline in minimal/fullbleed/mosaic/split)
- Add 8 unit tests for buildSubpageGrid covering undefined, subset fields, layout fallback, and all fields
2026-03-13 11:56:40 +01:00
ralksta
d64a7239d1 refactor: audit improvements - rate limit ceiling, map route protection, lazy DevToolbar, lang=de
- lib/rate-limit.ts: add MAX_STORE_ENTRIES=10k ceiling + evictIfFull() to prevent DDoS memory exhaustion
- app/api/map/route.ts: add IP-based rate limiting (30 req/min) with proper Retry-After headers
- app/layout.tsx: lang='en' → 'de', DevToolbar loaded via dynamic import (reduces main bundle)
- app/layout.tsx: lazy DevToolbar keeps ~17KB out of production bundle via next/dynamic
2026-03-13 11:41:56 +01:00
ralksta
3b657b625c fix(hero): fix mosaic layout full-width + update screenshots
- Override inherited 2-column grid from .hero by adding display: block to .hero--mosaic
- Add explicit grid-column/grid-row for mosaic cells 3 & 4 to prevent auto-placement issues
- Slice heroData to 4 images to match 4 defined grid cells
- Regenerate hero-mosaic-home.png and theme-studio-home.png screenshots
2026-03-13 11:35:27 +01:00
ralksta
5f8693e19e docs: replace studio screenshots and heroes with correct versions from generator 2026-03-13 11:35:27 +01:00
ralksta
43c59f4bc9 chore: clean up repo root and improve .gitignore
- Remove debug scripts: check_albums.js, check_albums.ts
- Remove git-filter-repo binary from root
- Untrack server.log (was accidentally committed)
- Delete .DS_Store files
- Rewrite .gitignore with clear sections: deps, next.js,
  TypeScript, testing, logs, env, OS/editor, agent tools,
  one-off scripts, deployment, user content
- Add .Jules/ and *.log glob to .gitignore
2026-03-13 11:34:28 +01:00
Ralksta
f9315ad7d6 Merge pull request #9 from ralksta/fix/exif-rate-limit-3163002533333096016
🛡️ Sentinel: [HIGH] Fix missing rate limiting on /api/exif/[id]
2026-03-13 10:10:11 +01:00
google-labs-jules[bot]
63e6a2f784 🛡️ Sentinel: [HIGH] Fix missing rate limiting on /api/exif/[id]
Co-authored-by: ralksta <16941050+ralksta@users.noreply.github.com>
2026-03-12 11:30:45 +00:00
ralksta
a0364ac9f0 fix: remove request.ip which was removed in Next.js 15+
The request.ip property no longer exists on NextRequest in Next.js 15+.
Fall back to x-real-ip (set by trusted reverse proxies) then x-forwarded-for.
The security intent from PR #4 is preserved — x-real-ip is preferred over
the more easily spoofed x-forwarded-for header.

Fixes build error: Property 'ip' does not exist on type 'NextRequest'
2026-03-11 23:36:40 +01:00
ralksta
8926fc27b7 perf: add bounded in-memory LRU cache for thumbhash decoding
- Cache up to 1000 entries for thumbHashToBlurDataUrl and thumbHashToDominantHex
- Evicts oldest entry when limit is reached (FIFO on Map insertion order)
- ~100x speedup for repeated decoding of same thumbhash

Closes #7
2026-03-11 23:34:04 +01:00
ralksta
c0740f0db5 a11y: remove ScrollToTop from tab order and hide from screen readers when not visible
- Added tabIndex={-1} when button is hidden to remove from keyboard tab order
- Added aria-hidden when not visible to hide from screen readers
- Added title attribute for tooltip text

Closes #6
2026-03-11 23:33:51 +01:00
Ralksta
c845df4afb feat(lightbox): add keyboard shortcut 'i' for EXIF toggle and title tooltips on navigation buttons [#3]
Adds a keyboard shortcut (`i` or `I`) to toggle EXIF info in the Lightbox component. Also adds descriptive `title` tooltips with keyboard shortcut hints to all interactive buttons (Close, Previous, Next, Info) in the Lightbox overlay.

This improves accessibility and the overall user experience by providing more discoverable navigation options.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-03-11 23:33:00 +01:00
Ralksta
f3890fc6bc perf: memoize PhotoGrid assets map to prevent re-renders during lightbox navigation [#5]
Extracted the grid mapping logic out of the return block into a `useMemo`
hook depending on `[assets, layout, openLightbox]`. This prevents the
entire photo grid—including complex Next.js `<Image>` and `<FadeIn>`
components—from needlessly re-rendering every time the user navigates
via the lightbox arrows or presses next/prev buttons, which previously
caused `lightboxIndex` to update and trigger a re-render of the entire grid.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-03-11 23:32:40 +01:00
Ralksta
a94b55704e security: prioritize request.ip over x-forwarded-for to prevent IP spoofing [#4]
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-03-11 23:32:32 +01:00
Ralksta
96fe4db099 security: validate auth input types and limit length to prevent DoS [#1]
Added type checking and length validation to the `slug` and `password` variables in the `app/api/auth/route.ts` file to prevent potential DoS attacks via excessively long strings passed to expensive crypto functions.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-03-11 23:32:22 +01:00
ralksta
134eae94e4 feat(subpages): add optional sections with typographic TOC
- Add SubpageSectionConfig type to schema.ts
- Update config parser to handle sections with album overrides
- Refactor SubpageGridView to render TOC + section headers
- Add base CSS for subpage-toc and subpage-section in globals.css
- Add theme-specific overrides for all 5 themes (minimal, editorial,
  classic, noir, monograph)
- Update gallery.yaml.example and docs/gallery-config.md
2026-03-08 23:52:23 +01:00
ralksta
0eaadeda55 docs: clarify that album grid thumbnails adhere strictly to the cover selection performed in Immich UI 2026-03-08 23:21:25 +01:00
ralksta
25b9a92e12 feat: propagate subpage subtitle into deep AlbumDetailView headers 2026-03-08 23:16:01 +01:00
ralksta
7663bcbcd0 refactor: extract individual layout themes from globals.css into modular app/themes/*.css architecture 2026-03-08 22:57:38 +01:00
ralksta
5667ba01b8 style: align subpage header to correctly adopt layout rules from selected themes 2026-03-08 22:54:23 +01:00
ralksta
a0777e40e2 style: let theme alignment dictate subpage headers by removing hardcoded text centering 2026-03-08 22:52:44 +01:00
ralksta
3953db0ff8 style: add global typographic classes for the subpage header block 2026-03-08 22:50:36 +01:00
ralksta
425e61312d chore: update .gitignore with server.log and .agent directory 2026-03-08 22:49:14 +01:00
ralksta
6371a60d0a chore: add workflow rule for updating documentation whenever user-facing settings change 2026-03-08 22:48:06 +01:00
ralksta
a99406c382 docs: add title and subtitle documentation for subpages to gallery config 2026-03-08 22:47:38 +01:00
ralksta
32bb6cb2ca feat: allow subpages to override title and add subtitle in gallery.yaml 2026-03-08 22:46:27 +01:00
ralksta
88f03fe2ce fix: make impressum page dynamic so it reads volume settings at runtime instead of statically compiling to 404 2026-03-08 21:53:20 +01:00
ralksta
65a661ce84 chore: make .env.local optional in docker-compose 2026-03-08 21:45:10 +01:00
ralksta
05de957b66 feat: add .env instruction to setup screen 2026-03-08 21:43:26 +01:00
ralksta
b9993bd29e fix: gracefully handle Next.js static component fetch rendering when setup configs are completely empty 2026-03-08 21:38:44 +01:00
ralksta
89bb7c0038 chore: add build network context to docker-compose 2026-03-08 21:31:07 +01:00