Commit Graph

44 Commits

Author SHA1 Message Date
Ralksta
81ce886b01 release: v0.19.1
Patch release for the Next.js advisory GHSA-vcvr-r3jv-pc5j (critical,
RCE in the Node.js `ImageResponse` from `next/og`).

- #743 — `next` and `eslint-config-next` 16.3.5 → 16.3.6
- #744 — prettier 3.9.8 → 3.9.9 (dev only)
- `chore(release): v0.19.1` — CHANGELOG, README "Latest" line, version

Folio uses `next/og` in `/api/og`. Title and subtitle are site-signed
since #767 and unsigned requests fall back to the site title, so
visitor-chosen text never reached the SVG. The upgrade is still the fix.

Checked on `dev` at 5dab342: `tsc --noEmit` clean, lint 0 errors,
`format:check` clean, 178 files / 2147 tests pass, `npm run build`
succeeds.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Ralf <rohlenbo79@gmail.com>
Co-authored-by: Paul Thies <110185070+ImScheinox@users.noreply.github.com>
Co-authored-by: lancetm714 <108419425+lancetm714@users.noreply.github.com>
Co-authored-by: Lance Martin <lancetaylor95@gmail.com>
2026-10-01 23:22:13 +02:00
Ralksta
ad8b09700b release: v0.19.0
Release v0.19.0. See the `## [0.19.0] — 2026-09-29` section of
[CHANGELOG.md](https://github.com/ralksta/immich-folio/blob/dev/CHANGELOG.md)
for the full list.

Highlights: client proofing links (#683), custom content pages (#738),
asset picker search (#740), concurrent-edit detection (#742), env-locked
settings (#739), an accessibility baseline (#741), three security fixes
with advisories (#737, #755, #759), and a pre-release quality pass
(#780–#797).

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Ralf <rohlenbo79@gmail.com>
Co-authored-by: Paul Thies <110185070+ImScheinox@users.noreply.github.com>
Co-authored-by: lancetm714 <108419425+lancetm714@users.noreply.github.com>
Co-authored-by: Lance Martin <lancetaylor95@gmail.com>
2026-09-29 22:50:30 +02:00
Ralksta
5f251923f0 release: v0.18.1 (#734)
## Thanks

- [@RichKidsDev](https://github.com/RichKidsDev) for reporting the admin
layout on iPhone (#732).

### Fixed

- **The admin fits a phone**
  ([#733](https://github.com/ralksta/immich-folio/pull/733), reported in
  [#732](https://github.com/ralksta/immich-folio/issues/732) by
[@RichKidsDev](https://github.com/RichKidsDev)). Below 860px the sidebar
  unfolded above the content — navigation, status and four actions — and
filled most of an iPhone screen. It is now a header row with the brand
and
a menu button; the menu opens as one column of full-width rows and
closes
again on navigation, and an unread message shows as a dot on the button.
  Desktop is unchanged.

- **The settings editor refuses prototype keys in a setting's path**
([#731](https://github.com/ralksta/immich-folio/pull/731)). All paths
are
written in the code, so this was not reachable; CodeQL flagged the
setter
  after the v0.18.0 release.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Ralf <rohlenbo79@gmail.com>
Co-authored-by: Paul Thies <110185070+ImScheinox@users.noreply.github.com>
Co-authored-by: lancetm714 <108419425+lancetm714@users.noreply.github.com>
Co-authored-by: Lance Martin <lancetaylor95@gmail.com>
2026-09-27 16:39:34 +02:00
Ralksta
3193c500e4 release: v0.18.0 (#725)
Release v0.18.0 — merges `dev` into `main`.

## Thanks

- [@lancetm714](https://github.com/lancetm714) for the accent-contrast
fix (#680 → #724).
- [@RichKidsDev](https://github.com/RichKidsDev) for reporting the
outdated Impressum (#697).

### Security

- **Journal drafts and password-protected entries no longer render
publicly
  as a subpage essay**
  ([#684](https://github.com/ralksta/immich-folio/pull/684),

[GHSA-987w-cpwm-c9g9](https://github.com/ralksta/immich-folio/security/advisories/GHSA-987w-cpwm-c9g9),
medium). A subpage's `essayFile` read the journal entry straight from
disk,
skipping the draft and password rules `/journal/<slug>` applies. It now
resolves through the same rules: a draft reads as missing for visitors,
and
  a protected entry shows its password gate, sharing the
  `lb_auth_journal_<slug>` cookie.

- **Immich descriptions are escaped in generated subpage essays**
  ([#684](https://github.com/ralksta/immich-folio/pull/684),

[GHSA-8ppx-39jv-q5xm](https://github.com/ralksta/immich-folio/security/advisories/GHSA-8ppx-39jv-q5xm),
  low). The essay built from a subpage's albums (`layout: essay` without
markdown) put each asset's Immich description into the page as raw HTML.
Captions are now HTML-escaped, and they go through `assetCaption()`, so
  `exif.caption: false` is respected there as well. Tracked in
  [#689](https://github.com/ralksta/immich-folio/issues/689).

- **Admin drafts no longer keep a typed password, and the contact form's
  email check runs in linear time**
([#727](https://github.com/ralksta/immich-folio/pull/727)). The admin's
  session drafts wrote a password as typed to `sessionStorage`; a draft
holding a plaintext password is now not kept (the unsaved-changes guard
still warns). The email pattern could backtrack polynomially on a
crafted
domain; its labels now exclude the dot and the length is checked first.
  Both found by CodeQL before release.

### Added

- **A built-in contact form with an inbox in the admin**
  ([#703](https://github.com/ralksta/immich-folio/pull/703), closes
[#702](https://github.com/ralksta/immich-folio/issues/702)). `/contact`
  needs neither SMTP nor a form service: each message is one file in
`content/messages/` (mode `0600`), read under the new _Messages_ tab,
where
_Reply by email_ opens the owner's mail client with the message quoted.
Messages older than `contact.retentionDays` (default 90) are deleted. An
optional ntfy push goes to `contact.notifyUrl` or `CONTACT_NOTIFY_URL`,
and
since [#709](https://github.com/ralksta/immich-folio/pull/709) it
carries a
  fixed "new message" line and nothing about the sender — no name, no
  address, no text. Spam is kept out without a captcha: an off-screen
honeypot, a minimum fill time, three submissions a minute per IP and a
cap
of 500 stored messages. With the Impressum on and no `legal.contactUrl`,
the Impressum links the form as its second contact channel. A new doctor
  check warns when the form is on but nobody is notified.

- **A privacy policy page, next to a list of what the site processes**
  ([#708](https://github.com/ralksta/immich-folio/pull/708)). `/privacy`
renders `content/privacy.md`, edited under Settings → Legal, and the
footer
links it once the file has text; `privacy.enabled: false` hides it.
Folio
writes no legal text. Beside the editor it lists what _this_
installation
  does, read off the configuration — the map, statistics, contact form,
password cookies, CDN — and marks every entry that involves a third
party.
_Insert headings_ adds the matching section headings and nothing else.
The
  doctor warns while the Impressum is on and there is no policy.

- **French, Spanish, Italian and Dutch interface translations**
([#681](https://github.com/ralksta/immich-folio/pull/681)), selected
with
  `settings.yaml: lang` as before. The admin panel stays English.

- **CDN mode for photos and videos**
([#681](https://github.com/ralksta/immich-folio/pull/681)). With
`CDN_URL`
set, image and video URLs point at a pull CDN whose origin is this
server,
  so repeat views reach neither the server nor Immich. A site password
switches the mode off, since a CDN would hand out cached photos without
  checking the unlock cookie. The CDN origin is added to the CSP, and a
  doctor check covers the password and `TRUSTED_PROXY_HOPS` cases. See
  `docs/deployment.md#cdn-mode`.

- **A reworked admin panel**
  ([#712](https://github.com/ralksta/immich-folio/pull/712),
  [#713](https://github.com/ralksta/immich-folio/pull/713),
  [#714](https://github.com/ralksta/immich-folio/pull/714),
  [#716](https://github.com/ralksta/immich-folio/pull/716),
  [#717](https://github.com/ralksta/immich-folio/pull/717),
  [#718](https://github.com/ralksta/immich-folio/pull/718),
  [#719](https://github.com/ralksta/immich-folio/pull/719),
  [#721](https://github.com/ralksta/immich-folio/pull/721)):
- **A sidebar instead of the header row**, grouped by task, with an
unread
    count on Messages and a dot on Diagnostics while Immich is down. It
    collapses to an icon rail, with names shown on hover and focus, and
    remembers that per browser.
  - **`/admin` is an overview**: what needs attention (unread messages,
    doctor warnings), published pages, journal entries and recent views.
  - **The site's own visual language** — the preset's fonts, hairline
borders, the square marker — and one page header on every screen. The
accent is kept for the current place and the primary action; switches
    are now pills reading ON or OFF, in green rather than the accent, so
    Studio Modern's red no longer makes an enabled setting look like an
    error.
- **The page builder is a structure list and a panel.** Hero, subpages
and
standalone albums sit in one list on the left, subpages drag-sorted in
    place; the selected entry is edited on the right instead of in an
    overlay.
- **Dialogs only where a change is permanent.** Deleting a message or a
journal entry, and resetting the favicon (which used to delete the file
without asking), go through one confirm dialog in the admin's own look.
Removals in the page builder, which only touch unsaved state, happen at
    once and offer _Undo_. No `window.confirm()` is left.
  - **Feature switches are grouped by meaning** as one-line rows under
Settings → General; page transitions and scroll-to-top moved to Theme →
    Look & motion. No setting keys changed.

### Changed

- **Fonts and the Leaflet stylesheet are served from the site itself**
([#700](https://github.com/ralksta/immich-folio/pull/700)). Every page
used
to link `fonts.googleapis.com`, which sends each visitor's IP address to
Google. The server now fetches a theme's Google fonts once, rewrites the
  stylesheet and caches the files in `content/.fonts/`; custom fonts in
`theme.fonts` keep working. If Google cannot be reached before a font is
  cached, the page falls back to the theme's system fonts. `leaflet.css`
  comes from the npm package instead of unpkg. The CSP drops
  `fonts.googleapis.com`, `fonts.gstatic.com` and `unpkg.com`.

- **Email addresses are kept out of the served HTML**
([#705](https://github.com/ralksta/immich-folio/pull/705)). The
Impressum
and footer render the address only after hydration, from an encoded
form,
  so harvesters reading raw HTML find nothing. Without JavaScript the
Impressum shows `name [at] example [dot] de`. This defeats bulk
harvesting,
  not a person with a browser.

- **The Impressum cites § 5 DDG and links its contacts**
  ([#698](https://github.com/ralksta/immich-folio/pull/698), reported in
  [#697](https://github.com/ralksta/immich-folio/issues/697) by
[@RichKidsDev](https://github.com/RichKidsDev)). The TMG was replaced by
the
DDG in May 2024; `legal.heading` replaces the line for other laws (e.g.
  § 5 ECG in Austria). `legal.contactUrl` and `legal.contactLabel` add a
  contact form as the second channel, so a phone number stays optional.
  Email, phone and contact URL are now links, and the "Created with the
Impressum generator by eRecht24" line, shown on every site whether true
or
not, is gone. Settings → Legal gains fields for heading, contact URL,
VAT
  ID and tax number, and a doctor check flags missing details.

- **Missing pages answer `404`**
([#704](https://github.com/ralksta/immich-folio/pull/704)). Every
missing
  page used to answer `200`, because streaming had started before
`notFound()` ran. `/contact`, `/impressum`, `/map` and `/privacy` while
switched off, and `/journal/<slug>` without an entry, now return a real
404 with the same not-found page. Album and subpage slugs still depend
on
  Immich and stay soft 404s.

- **Passwords set in the admin are stored as scrypt hashes**
  ([#706](https://github.com/ralksta/immich-folio/pull/706), closes
  [#690](https://github.com/ralksta/immich-folio/issues/690)). Subpage,
album, journal-entry and site passwords were written as typed. The save
routes now hash them; a stored hash reads _Protected_ with _Change_ and
_Remove_ and is never put into an input. Visitors who unlocked a page
stay
signed in across unrelated saves. Existing plaintext passwords are
hashed
  the next time their file is saved in the admin.

- **One notification surface in the admin**
([#707](https://github.com/ralksta/immich-folio/pull/707)) replaces
every
`alert()`: errors stay until dismissed, successes clear themselves, and
  screen readers announce both.

### Fixed

- **Map tiles load again**
([#701](https://github.com/ralksta/immich-folio/pull/701)). CARTO
started
answering every tile with an "API KEY REQUIRED" image, leaving `/map`
and
journal map blocks as a grey grid. Tiles now come from OpenStreetMap;
the
  dark look is a CSS filter, so the map now follows the colour mode.

- **The page builder no longer drops a subpage's `proofing:` flag on
save**
([#711](https://github.com/ralksta/immich-folio/pull/711)). A page
switched
  off for proofing by hand reverted after any unrelated edit.

- **Unsaved edits in Settings and About survive switching admin tabs,
and a
  backup restore is no longer overwritten by the next save**
([#687](https://github.com/ralksta/immich-folio/pull/687)). Editors that
were open during a restore now reload and offer unsaved edits back as a
  conflict. Also: "Restore my changes" after a conflict found nothing,
removing an album left its drawer showing the next album, and the
journal
  saved (rotating a backup) without changes.

- **Accent-backed buttons stay readable with a light or malformed
accent**
  ([#724](https://github.com/ralksta/immich-folio/pull/724), supersedes
[#680](https://github.com/ralksta/immich-folio/pull/680)) — contributed
by
  [@lancetm714](https://github.com/lancetm714). A white accent made the
  proofing dialog's _Download selected (.zip)_ button white on white.
`theme.accent` is now accepted as hex only and normalised to `#rrggbb`,
anything else falls back to the preset, and the proofing dialog and
filter
  pills use the mode-aware `--on-accent` text colour from #688.

- **Every preset's accent is visible in both colour modes**
([#688](https://github.com/ralksta/immich-folio/pull/688)). Presets had
one
accent for both modes; minimal's dark mode drew black buttons on black.
  Presets now carry a light and a dark accent, and text on accent-filled
  buttons picks black or white for contrast. A custom accent stays the
  owner's choice in both modes.

- **Visitor-side inconsistencies**
([#685](https://github.com/ralksta/immich-folio/pull/685)): after
visiting
`/impressum`, every subpage header turned centred and uppercase; back
links
  announced "Back to Back to …"; the hero EXIF chip ignored
`exif.location`/`camera`/`settings`; videos in journal entries opened as
  stills; the setup screen named a non-existent `.env.example`.

- **An essay's lightbox walks only the photos the story shows**
([#686](https://github.com/ralksta/immich-folio/pull/686)), not every
photo
of the subpage's albums, and the proofing bar in essays shows the
selection
  count instead of a filter button that did nothing.

- **The page panel scrolls with the mouse wheel**
  ([#720](https://github.com/ralksta/immich-folio/pull/720)).

- **The journal editor's top bar wraps on phones**
  ([#723](https://github.com/ralksta/immich-folio/pull/723), closes
[#675](https://github.com/ralksta/immich-folio/issues/675)), so the
title
  stays editable and Save stays on screen.

- **Every admin form field has a name for assistive technology**
([#715](https://github.com/ralksta/immich-folio/pull/715)). Only two
inputs
had a linked label; 47 are linked now, and clicking a label focuses its
  field.

### Internal

- **`SettingsEditor` and `PageBuilder` are split up**
  ([#710](https://github.com/ralksta/immich-folio/pull/710),
[#711](https://github.com/ralksta/immich-folio/pull/711)). The
2,200-line
settings editor is a shell with one file per section; the page builder's
YAML handling and edits are pure functions under test. Both were checked
  side by side against `dev` for identical output.
- **`useAdminFetch()`**
([#707](https://github.com/ralksta/immich-folio/pull/707))
gives Analytics, Messages, Backups and the journal list one loading and
  error pattern.
- README brought up to v0.17.0
  ([#678](https://github.com/ralksta/immich-folio/pull/678),
  [#679](https://github.com/ralksta/immich-folio/pull/679)).

### Upgrade notes

**`content/` gains two directories the app writes to:**
`content/.fonts/`
for the cached fonts and `content/messages/` for contact-form messages.
Both
are created on demand, so a writable `content/` is enough, as before.

**The server needs outbound HTTPS to Google once per font** to fill the
font
cache. Until then pages fall back to the theme's system fonts. Visitors'
browsers no longer contact Google.

**A custom CSP or reverse-proxy allowlist** must now allow
`tile.openstreetmap.org` for images instead of
`*.basemaps.cartocdn.com`,
and no longer needs `fonts.googleapis.com`, `fonts.gstatic.com` or
`unpkg.com`. The built-in CSP is updated.

**`theme.accent` must be hex** (`#rgb`, `#rrggbb` or `#rrggbbaa`).
Anything
else, including a value without `#`, falls back to the preset's accent.

**Plaintext passwords in `gallery.yaml`, `settings.yaml` or journal
entries**
are hashed the next time that file is saved in the admin; one save
clears the
doctor's warning.

**New, optional settings:** `contact.*` (the form is off by default),
`privacy.enabled`, `legal.heading`, `legal.contactUrl`,
`legal.contactLabel`,
and the `CDN_URL` and `CONTACT_NOTIFY_URL` environment variables. See
`content/settings.yaml.example` and `.env.local.example`. In the example
file,
`vatId` and `taxId` had swapped sample values; check yours if you copied
them.

No `IMAGE_CACHE_VERSION` bump is needed this time.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Ralf <rohlenbo79@gmail.com>
Co-authored-by: Paul Thies <110185070+ImScheinox@users.noreply.github.com>
Co-authored-by: lancetm714 <108419425+lancetm714@users.noreply.github.com>
Co-authored-by: Lance Martin <lancetaylor95@gmail.com>
2026-09-27 14:43:38 +02:00
Ralksta
89a8fac564 release: v0.17.0 (#677)
See CHANGELOG.md, section [0.17.0] — 2026-09-23.
2026-09-23 12:09:08 +02:00
Ralksta
a3a6319c29 release: v0.16.0
See CHANGELOG.md for the full v0.16.0 entry.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Ralf <rohlenbo79@gmail.com>
Co-authored-by: Paul Thies <110185070+ImScheinox@users.noreply.github.com>
Co-authored-by: lancetm714 <108419425+lancetm714@users.noreply.github.com>
2026-09-22 14:12:13 +02:00
Ralksta
c3f92ca4ec release: v0.15.0 (#585)
Eighteen changes since v0.14.0. See CHANGELOG.md for the full list and the upgrade notes (bump IMAGE_CACHE_VERSION).
2026-09-19 22:24:10 +02:00
Ralksta
e99d3f2f1b release: v0.14.0
Fourteen commits since v0.13.0. See CHANGELOG.md for the full list.

Two additions: `npm run doctor`, which runs the config doctor from a terminal — including inside the shipped image — and exits with the worst finding, so it can gate a deployment script; and a Playwright spec that loads all fourteen admin routes against a production build.

One change, invisible on screen: the admin panel got a form-field layer (#533).

Five fixes: grid.gap on both axes (#513), the dashboard status badge (#539), the journal editor's unsaved-changes guard (#538), essay paragraph markup (#537), and aria-pressed on the panel's switches and pickers.
2026-08-30 15:11:25 +02:00
Ralksta
a813433891 release: v0.13.0 (#535)
Twenty-nine commits since v0.12.0. See CHANGELOG.md for the full list
and the upgrade notes.

Ten additions — the SEO package (site URL, robots.txt, sitemap.xml,
JSON-LD), slideshow mode, opt-in original downloads, copy-link,
previous/next album navigation, alt text from the Immich description,
per-album location precision, the update notice, a Help tab, and a
subpage cover grid separate from its photo grid. Two fixes: CJK album
slugs, and the lightbox control bar.

Photo of the Day (#476) was built on `dev` and reverted as not planned;
it never appears in a release.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01DmsHVRL9yQvckUB1ZpVWre

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 10:08:12 +02:00
Ralksta
10ec68f493 release: v0.12.0 (#520)
Forty-one commits since v0.11.0. See CHANGELOG.md for the full list and the upgrade notes.
2026-08-23 23:18:14 +02:00
Ralksta
2f546f440d release: v0.11.0 (#459)
Ships `dev` as **v0.11.0**. `main` contains nothing that `dev` does not,
so this is a clean sync.

## Headline changes since v0.10.0

- **Journal & Journal Studio** — photo essays at `/journal`,
split-screen block editor with live preview, drafts, per-entry
passwords, cover images
- **First-run setup wizard at `/install`** — configure a fresh
deployment from the browser; credentials are verified against Immich
before anything is written, and the wizard is gated by a one-time token
- **About page editor and toggle** in the admin panel
- **Per-album photo order** independent of Immich, with a drag & drop
editor
- **Custom favicon upload**
- **Experimental portfolio features** — justified grid, `cover` hero,
unlisted subpages, per-album grid overrides, cover focal points,
external nav links
- **Security** — asset tokens length-capped before decoding (#423),
journal author markdown escaped rather than filtered, journal file paths
contained, admin session key derived with scrypt (#432), Next.js 16.3.0
for CVE-2025-13465
- **Fixed** — client proofing honours its own configuration again
(#454); journal photo rendering (#432)

Full detail in [CHANGELOG.md](CHANGELOG.md#0110--2026-08-15).

## Verified

`npx tsc --noEmit` clean · `npx vitest run` 435 tests pass · `npm run
build` succeeds · lint 0 errors · `prettier --check` clean · local
`docker build` of the release tree.

## After merge

Tag `v0.11.0` on `main` and publish the release — that triggers
`docker-publish.yml`, which pushes the image and moves `latest`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: lancetm714 <108419425+lancetm714@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 09:09:18 +02:00
Ralksta
f120f05157 docs(contributing): tell contributors to target dev (#412)
* fix(screenshots): sharp-Typen fuer 0.34 und 0.35 gleichzeitig (#410)

sharp 0.35 ist von `export =` auf ESM umgestellt: der Modul-Namespace
ist nicht mehr aufrufbar, die Factory sitzt unter .default. Der
Type-Check brach damit in scripts/screenshots.ts weg, sobald der
Next-Bump (#402) sharp von 0.34.5 auf 0.35.3 mitzieht -- sharp ist hier
keine deklarierte Dependency, sondern kommt ueber Next mit.

Die Form wird jetzt aus dem installierten Paket abgeleitet statt
festgeschrieben, zur Laufzeit wie im Typ. Geprueft mit beiden
Versionen: tsc laeuft mit 0.34.5 und mit 0.35.3 fehlerfrei durch.

Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore(deps): bump the nextjs group across 1 directory with 2 updates (#402)

Bumps the nextjs group with 2 updates in the / directory: [next](https://github.com/vercel/next.js) and [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next).


Updates `next` from 16.2.12 to 16.3.0
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](https://github.com/vercel/next.js/compare/v16.2.12...v16.3.0)

Updates `eslint-config-next` from 16.2.12 to 16.3.0
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](https://github.com/vercel/next.js/commits/v16.3.0/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 16.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: nextjs
- dependency-name: next
  dependency-version: 16.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nextjs
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump prettier from 3.8.3 to 3.9.6 (#405)

Bumps [prettier](https://github.com/prettier/prettier) from 3.8.3 to 3.9.6.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.8.3...3.9.6)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.9.6
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* docs(contributing): PRs gehen gegen dev

Nirgends stand, welcher Branch das Ziel ist -- die offene PR #398 zeigt
folgerichtig auf main. main bewegt sich aber nur ueber Releases: es wird
von dev fast-forwarded, getaggt, und der Tag stoesst den Image-Publish
an. Eine PR dagegen legt unveroeffentlichten Code in genau den Branch,
der dem publizierten Image entsprechen soll.

Steht jetzt als eigener Abschnitt in CONTRIBUTING.md, im Setup-Snippet
und in beiden Checklisten. Mit Hinweis, dass ein falsches Ziel ueber
"Edit" an der PR umgestellt werden kann, statt die Arbeit neu zu machen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-10 10:41:01 +02:00
dependabot[bot]
8cca5a1b55 chore(deps-dev): bump @types/leaflet from 1.9.21 to 1.9.22 (#403)
Bumps [@types/leaflet](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/leaflet) from 1.9.21 to 1.9.22.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/leaflet)

---
updated-dependencies:
- dependency-name: "@types/leaflet"
  dependency-version: 1.9.22
  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-08-10 10:24:17 +02:00
Ralksta
2318409e75 chore(release): v0.10.0 (#400)
Photo Essay mode, client proofing, studio-modern preset, admin panel overhaul, watermark, cookieless analytics, subpage toggle, SEO title templates. Analytics API now admin-only, Trivy scan on publish. Album order mirrors the Immich timeline; map theme, admin status panel, lightbox counter and Docker health check fixed.

See CHANGELOG.md for the full list and the health-check upgrade note.
2026-08-10 09:56:20 +02:00
Ralksta
304f5609cb chore(release): v0.9.2 (#396)
Bugfix release. Since v0.9.1:

- Immich outages surface as 503 with Retry-After instead of a cacheable
  404, so a transient failure can no longer pin a broken image in a
  visitor's browser cache (#394)
- `?w=` can narrow the image tier instead of being ignored, and the tier
  is part of the ETag so the three sizes cache separately (#394)
- IMAGE_CACHE_VERSION as an escape hatch for stale browser caches after
  Immich regenerates a thumbnail (#394)
- Every rate-limited response carries Retry-After; a warning fires when
  TRUSTED_PROXY_HOPS cannot identify a client (#394)
- Admin saves that would produce an unloadable gallery.yaml are rejected
  before the write rather than reported as successful (#394)
- middleware.ts migrated to the Next 16 proxy convention (#394)
- The admin password comparison no longer leaks the password length
  through timing (#395)
- next 16.2.12, react 19.2.8, js-yaml 4.3.1, @playwright/test 1.62.1,
  and three GitHub Actions majors

Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 12:28:28 +02:00
dependabot[bot]
0a67184335 chore(deps-dev): bump @playwright/test from 1.58.2 to 1.62.1 (#385)
Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.58.2 to 1.62.1.
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.58.2...v1.62.1)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-version: 1.62.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-05 12:13:21 +02:00
dependabot[bot]
88ecc2f489 chore(deps): bump js-yaml from 4.2.0 to 4.3.1 (#386)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.2.0 to 4.3.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/4.3.1/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.2.0...4.3.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-05 12:09:48 +02:00
dependabot[bot]
9e4dc270d6 chore(deps): bump the react group across 1 directory with 4 updates (#389)
Bumps the react group with 4 updates in the / directory: [react](https://github.com/react/react/tree/HEAD/packages/react), [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react), [react-dom](https://github.com/react/react/tree/HEAD/packages/react-dom) and [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom).


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

Updates `@types/react` from 19.2.17 to 19.2.18
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

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

Updates `@types/react-dom` from 19.2.3 to 19.2.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `@types/react` from 19.2.17 to 19.2.18
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@types/react-dom` from 19.2.3 to 19.2.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.2.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react
  dependency-version: 19.2.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react-dom
  dependency-version: 19.2.8
  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-08-05 12:09:40 +02:00
dependabot[bot]
55fca1ae01 chore(deps): bump the nextjs group across 1 directory with 2 updates (#383)
Bumps the nextjs group with 2 updates in the / directory: [next](https://github.com/vercel/next.js) and [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next).


Updates `next` from 16.2.10 to 16.2.12
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](https://github.com/vercel/next.js/compare/v16.2.10...v16.2.12)

Updates `eslint-config-next` from 16.2.10 to 16.2.12
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](https://github.com/vercel/next.js/commits/v16.2.12/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 16.2.12
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: nextjs
- dependency-name: next
  dependency-version: 16.2.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nextjs
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-05 12:04:40 +02:00
Ralksta
25d936f11f chore(release): v0.9.1 (#393)
Co-authored-by: ralksta <ralksta@users.noreply.github.com>
2026-08-05 00:28:52 +02:00
dependabot[bot]
00c7d33411 chore(deps): bump the nextjs group across 1 directory with 2 updates (#250)
Bumps the nextjs group with 2 updates in the / directory: [next](https://github.com/vercel/next.js) and [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next).


Updates `next` from 16.2.4 to 16.2.10
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](https://github.com/vercel/next.js/compare/v16.2.4...v16.2.10)

Updates `eslint-config-next` from 16.2.4 to 16.2.10
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](https://github.com/vercel/next.js/commits/v16.2.10/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 16.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: nextjs
- dependency-name: next
  dependency-version: 16.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nextjs
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-20 21:00:17 +02:00
dependabot[bot]
bac2562800 chore(deps): bump the react group across 1 directory with 3 updates (#251)
Bumps the react group with 3 updates in the / directory: [react](https://github.com/facebook/react/tree/HEAD/packages/react), [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) and [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom).


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

Updates `@types/react` from 19.2.15 to 19.2.17
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

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

Updates `@types/react` from 19.2.15 to 19.2.17
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.2.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react
  dependency-version: 19.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react-dom
  dependency-version: 19.2.7
  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-07-20 20:56:57 +02:00
dependabot[bot]
da6402c426 chore(deps): bump js-yaml from 4.1.1 to 4.2.0 (#252)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.1 to 4.2.0.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/commits)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-20 20:56:54 +02:00
dependabot[bot]
70313fa2a6 chore(deps-dev): bump eslint-plugin-prettier from 5.5.5 to 5.5.6 (#253)
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.5.5 to 5.5.6.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.5.5...v5.5.6)

---
updated-dependencies:
- dependency-name: eslint-plugin-prettier
  dependency-version: 5.5.6
  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-07-20 20:56:50 +02:00
Ralksta
37f7f62157 security: fix pre-auth bypasses and restore Immich 3.x compatibility (#378)
Seven security issues from an audit, plus album pages and the map coming
up empty against Immich 3.x. Verified against a real Immich 3.0.3
instance in a production build.

Security:
- Admin session forgery via a hardcoded 'dev-fallback-secret' signing key
  that bypassed the production AUTH_SECRET guard
- /api/map ignored album passwords and returned working asset tokens;
  rewriting ?size=thumbnail to ?size=original downloaded full-resolution
  originals from protected albums
- Admin login had no rate limit, and the client IP came from a spoofable
  header, so rotating it bypassed every limit in the app
- Raw Immich asset UUIDs were serialized into the RSC payload
- Album tokens never expired server-side; a captured token replayed forever
- Path traversal into the Immich API via an unvalidated album id
- /admin ran with no enforced CSP (only Report-Only reached it)

TRUSTED_PROXIES is replaced by TRUSTED_PROXY_HOPS. The old variable
matched proxy IPs against the socket peer address, which self-hosted
Next.js never exposes, so the check could never pass: unset, the limiter
read a spoofable header; set, every request shared one bucket and a single
client could rate-limit the whole site. Migrates automatically.

Immich 3.x: GET /albums/:id no longer embeds assets. Assets now come from
POST /search/metadata with withExif: true — without that flag EXIF is
omitted and grid aspect ratios, the lightbox panel and map markers stay
empty. Drops support for Immich below 3.0, which now logs a warning.

Upgrade: requires Immich 3.0+; set TRUSTED_PROXY_HOPS (nginx = 1);
visitors of protected areas and admin sessions must log in once more.

91 unit tests (25 new); the new admin-auth and rate-limit cases were
confirmed to fail against the pre-fix code.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 18:57:57 +02:00
dependabot[bot]
c5645a49fd chore(deps): bump the react group across 1 directory with 3 updates (#223)
Bumps the react group with 3 updates in the / directory: [react](https://github.com/facebook/react/tree/HEAD/packages/react), [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) and [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom).


Updates `react` from 19.2.5 to 19.2.6
- [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.6/packages/react)

Updates `@types/react` from 19.2.14 to 19.2.15
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 19.2.5 to 19.2.6
- [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.6/packages/react-dom)

Updates `@types/react` from 19.2.14 to 19.2.15
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.2.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react
  dependency-version: 19.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react-dom
  dependency-version: 19.2.6
  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-05-31 10:03:14 +02:00
ralksta
e8e65e7172 feat(admin): add asset picker with favorites, drag-and-drop reordering, preview links, and keyboard shortcuts
- Asset Picker: Visual browser for hero images with Favorites tab (shown first)
  and All Photos tab. Includes infinite scroll and UUID fallback input for
  assets not easily found in the grid.
- Drag & Drop: All lists (hero images, standalone albums, subpage albums,
  subpage tiles) are now reorderable via drag handles using @dnd-kit.
- Preview Links: 'Preview Site' button in save bar, '↗ Site' in header, and
  per-subpage preview links with URL slug preview shown inline.
- Keyboard Shortcuts: ⌘+S / Ctrl+S to save in both Pages and Settings tabs.
- Unsaved Changes Guard: beforeunload warning prevents accidental data loss.
- New API route /api/admin/assets for browsing Immich assets with pagination
  and favorites filter via search/metadata endpoint.
2026-05-29 17:59:25 +02:00
Ralksta
3c5715e0b0 Merge PR #141
chore(deps): bump the nextjs group with 2 updates
2026-05-06 12:00:01 +02:00
dependabot[bot]
a344228fb9 chore(deps-dev): bump prettier from 3.8.2 to 3.8.3
Bumps [prettier](https://github.com/prettier/prettier) from 3.8.2 to 3.8.3.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.8.2...3.8.3)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.8.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 07:48:48 +00:00
dependabot[bot]
64eff62db4 chore(deps): bump the nextjs group with 2 updates
Bumps the nextjs group with 2 updates: [next](https://github.com/vercel/next.js) and [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next).


Updates `next` from 16.2.1 to 16.2.4
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.2.1...v16.2.4)

Updates `eslint-config-next` from 16.2.1 to 16.2.4
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.2.4/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.2.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nextjs
- dependency-name: eslint-config-next
  dependency-version: 16.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: nextjs
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 07:48:20 +00:00
dependabot[bot]
b803daf8f9 chore(deps): bump the react group with 2 updates (#107)
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.4 to 19.2.5
- [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.5/packages/react)

Updates `react-dom` from 19.2.4 to 19.2.5
- [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.5/packages/react-dom)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react-dom
  dependency-version: 19.2.5
  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-04-21 22:51:29 +02:00
dependabot[bot]
972ace5833 chore(deps-dev): bump prettier from 3.8.1 to 3.8.2 (#108)
Bumps [prettier](https://github.com/prettier/prettier) from 3.8.1 to 3.8.2.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.8.1...3.8.2)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.8.2
  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-04-21 22:51:17 +02:00
dependabot[bot]
59153c9f48 chore(deps): bump the nextjs group with 2 updates (#43)
Bumps the nextjs group with 2 updates: [next](https://github.com/vercel/next.js) and [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next).


Updates `next` from 16.1.6 to 16.2.1
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.1.6...v16.2.1)

Updates `eslint-config-next` from 16.1.6 to 16.2.1
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.2.1/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nextjs
- dependency-name: eslint-config-next
  dependency-version: 16.2.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: nextjs
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ralksta <16941050+ralksta@users.noreply.github.com>
2026-03-27 10:51:26 +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
922302ce5c chore: implement audit action items and translate hardcoded German text 2026-03-15 07:32:42 +01:00
ralksta
7a1dfdc519 chore: remove unused 3P dependencies (zod, gray-matter, bcryptjs) and switch to native implementations 2026-03-08 21:12:52 +01:00
ralksta
74b5f45369 chore: make project open source under MIT license 2026-03-08 17:45:32 +01:00
ralksta
280c5430ca chore: full implementation of code review recommendations (security, quality, tests) 2026-03-07 09:27:47 +01:00
ralksta
a529614c19 refactor: completely remove framer-motion and page transitions 2026-03-07 09:11:40 +01:00
ralksta
1e079760d8 feat: add configurable page transitions with framer-motion 2026-03-07 08:30:12 +01:00
ralksta
62a7b178d6 feat: add smart map view with location-level clustering
- /map page with Leaflet (CartoDB dark tiles)
- Photos clustered by city/country (not per-photo)
- /api/map endpoint with encrypted cover asset IDs
- Configurable via gallery.yaml (map: true/false)
- Conditional nav link in header
- CSP updated for Leaflet CDN and tile servers
- Theme-aware popups with cover thumbnails and album links
2026-02-15 23:07:04 +01:00
ralksta
52fa16c1c8 feat: visual polish & UX — fade-in, theme toggle, scroll-to-top, footer, cursor, badge
- Add FadeIn component (IntersectionObserver scroll-reveal + load animation)
- Add dark/light theme toggle (useSyncExternalStore + localStorage)
- Add scroll-to-top button (appears after 300px scroll)
- Add configurable footer with social links (gallery.yaml)
- Add crosshair cursor on photo grid items
- Add 'X photos' count badge on subpage cover images
- Add light theme color palette in tokens.css
2026-02-14 11:47:26 +01:00
ralksta
b7217c4a76 feat: photography features & image optimizations
- Hero carousel: gallery.yaml hero accepts single UUID or array, crossfade component
- Full-bleed single albums: subpages with 1 album skip grid, render photos directly
- EXIF on hover: camera/lens/focal length overlay on grid items (toggle via exifOnHover)
- Customizable grid: columns/gap/aspectRatio/layout (masonry|uniform) via gallery.yaml
- Per-subpage grid overrides: each subpage can override global grid config
- True masonry: per-image aspect ratios from EXIF dimensions
- next/image migration: homepage hero, album covers, grid thumbnails, about portrait
- ThumbHash blur placeholders and dominant color backgrounds
- Custom next/image loader via image proxy with width/quality params
- Lightbox fade-in transition with dominant color background
- Password-protected subpages, health check, rate limiting, OG images
2026-02-14 10:30:27 +01:00
ralksta
688a28c7df Initial commit from Create Next App 2026-02-13 23:26:37 +01:00