Commit Graph

350 Commits

Author SHA1 Message Date
Timon 3decc864b5 refactor(server)!: structured validation error responses (#28204)
* refactor(server)!: structured validation error responses

* refactor(server): clarify comment on removing duplicate HTTP response fields

* enhance validation error tests

* make path and message required

* fmt

* fix e2e test

* fmt

* feat: enhance error handling in getServerErrorMessage function
2026-05-04 00:00:03 -04:00
Timon c0898b96ca refactor(server)!: sanitize error messages to avoid leaking resource details (#28154)
* refactor(server)!: sanitize error messages to avoid leaking resource and permission details

* fix e2e tests

* fix(server): prevent login timing oracle by always running bcrypt

Always call compareBcrypt in the login path regardless of whether the
email is registered. When no user is found, a dummy hash is used so the
bcrypt KDF still runs and response latency is constant, making it
impossible to enumerate valid email addresses by measuring response time.

* fix(server): collapse OAuth callback messages to prevent email-existence oracle

Two distinct error messages in the OAuth callback endpoint revealed
whether an email address was already registered in the database.
An attacker controlling the OAuth provider's email claim could probe
the user table without authentication. Both cases now return the same
generic message.

* fix(server): replace email-in-use messages to prevent user-existence oracle

Error messages on registration and profile-update that named whether an
email address was already taken allowed callers to enumerate registered
accounts. All three sites now return the same generic message regardless
of whether the address is in use.

* fix(server): hide slug uniqueness constraint to prevent shared-link probe

Surfacing the Postgres unique-constraint name in the error response let
any authenticated user brute-force whether a custom slug was already in
use by another user's shared link, leaking the existence of other links.

* fix(server): unify profile image errors to prevent user-existence oracle via status code

GET /users/:id/profile-image returned HTTP 400 for an unknown user ID
but HTTP 404 when the user existed without a photo, letting callers
distinguish the two cases. Both now return 404 so the response is
identical regardless of whether the UUID maps to an account.

* fix(server): replace album user-not-found message to prevent UUID-existence oracle

Album owners could probe arbitrary UUIDs via the add-user endpoint and
determine whether they belonged to registered accounts by receiving
'User not found'. The message is now ambiguous about whether the ID was
unrecognised or the user is inactive.

* Revert "fix e2e tests"

This reverts commit c1bd7a116b3f0fccf3d2530c8e34b13c1d862989.

* Revert "refactor(server)!: sanitize error messages to avoid leaking resource and permission details"

This reverts commit b96421a08387340fbb77913ca89b0717bcd9945d.

* fix(server): use 403 instead of 400 for access-denied errors

requireAccess threw BadRequestException which is incorrect HTTP semantics.
Access denial is a client authorization problem (403 Forbidden), not a
malformed request (400 Bad Request). Keep the descriptive permission name
in the message since the full permission set is public API surface.

* Revert "fix(server): use 403 instead of 400 for access-denied errors"

This reverts commit bb069909571f4e514e7d050ddf588c017ee5a029.

* shorten comment

* add log messages

* format

* one more
2026-05-01 10:00:18 -04:00
Daniel Dietzler 5e9bda7fab chore: tailwind linting (#28165)
chore: tailwind cannonical classes
2026-05-01 00:18:03 -04:00
Mert b554664791 chore!: duration in milliseconds (#28003)
* server changes

* openapi

* web changes

* mobile changes

* assume 3.0 client

* deprecate

* review feedback

* update medium tests

* linting
2026-04-30 09:44:27 -04:00
Timon 92634f923b refactor(server)!: remove redundant error and statusCode fields from error responses (#28140)
* refactor(server)!: remove redundant error and statusCode fields from error responses

* use enum

* enhance response management

* chore: clean up header

* fix: chaining

* refactor: handle error

* fix e2e tests

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-04-28 17:54:54 -04:00
Timon 96b6165bd3 refactor(server)!: move correlationId to X-Correlation-ID response header (#28139) 2026-04-28 13:07:39 -04:00
Daniel Dietzler 4bfb8b36c2 chore!: migrate album owner to album_user (#27467)
Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-04-22 16:52:23 +02:00
Daniel Dietzler 837305da7e chore: un-skip tests (#28012) 2026-04-21 12:08:23 -04:00
renovate[bot] c2786978cd fix(deps): update typescript-projects (#28008)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2026-04-21 15:29:34 +02:00
Aki Hakune be1b9a5f67 feat(server): add MPO file type support (#27963)
* feat(server): add MPO file type support

* fix(server): document description error
2026-04-20 17:45:53 -04:00
sparsh985 55f2b3b6a0 feat(server): add configurable OAuth prompt parameter (#26755)
* feat(server): add configurable OAuth prompt parameter

Add a `prompt` field to the OAuth system config, allowing admins to
configure the OIDC `prompt` parameter (e.g. `select_account`, `login`,
`consent`). Defaults to empty string (no prompt sent), preserving
backward compatibility.

This is useful for providers like Google where users want to be prompted
to select an account when multiple accounts are signed in.

Discussed in #20762

* chore: regenerate OpenAPI spec and clients for OAuth prompt field

* Adding e2e test cases

* feat: web setting

* feat: docs

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-04-17 21:20:07 +00:00
santanoce dbf30b77bf feat(server): added backchannel logout api endpoint (#26235)
* feat(server): added backchannel logout api endpoint

* test(server): fixed e2e tests

* fix(server): fixed suggested changes by reviewer

* feat(server): created function invalidateOAuth

* fix(server): fixed session.repository.sql

* test(server): added unit tests for backchannelLogout function

* test(server): added e2e tests for oidc backchnnel logout

* docs(server): added documentation on backchannel logout url

* docs(server): fixed typo

* feat(server): minor improvements of the oidc backchannel logout

* test(server): fixed tests after merge with main

* fix(server): fixed e2e test file

* refactor(server): tiny refactor of validateLogoutToken

* chore: cleanup

* fix: tests

* fix: make jwks extractable

---------

Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2026-04-17 18:45:33 +00:00
Sergey Katsubo b7eff33f90 chore(web): refactor date section of asset viewer (#24514)
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2026-04-17 12:56:39 +00:00
Jason Rasmussen 2f8be45fe0 chore!: remove /api/server/theme endpoint (#27880)
chore: remove server/theme endpoint
2026-04-17 08:30:03 -04:00
Mees Frensel 7d181f0686 fix!: set duration to null when not present (#26982) 2026-04-17 11:57:10 +02:00
Timothy Dobras d046f16860 fix(oauth): normalize email claim to lowercase and trim before account lookup and registration (#26841)
* fix(oauth): normalize email claim to lowercase before account lookup and registration

* test(auth): add test for OAuth email case normalization

* chore: clean up

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-04-16 15:41:42 +00:00
renovate[bot] 88815a0345 chore(deps): update base-image to v202604141125 (major) (#27858)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 15:40:40 +00:00
bo0tzz 3356e81c85 fix!: do not allow insecure oauth requests by default (#27844)
* fix!: do not allow insecure oauth requests by default

* fix: format

* fix: make open-api

* fix: tests

* nit: casing

* chore: migration to allow insecure if current oauth uses http
2026-04-16 10:11:58 -04:00
Jason Rasmussen a69eecf3bc chore!: remove without assets (#27835)
* chore!: remove without assets

* fix: linting and e2e

---------

Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2026-04-15 18:34:22 -04:00
Daniel Dietzler 8ee5d3039a chore!: remove deviceId and deviceAssetId (#27818)
chore: remove deviceId and deviceAssetId
2026-04-15 15:00:33 -04:00
Brandon Wees 6da2d3d587 chore!: remove getRandom api endpoint (#27780)
* chore!: remove getRandom api endpoint

* chore: sync openapi

* fix: test

* chore: more cleanup
2026-04-14 21:32:12 -04:00
Jason Rasmussen 6ba17bb86f refactor!: remove my shared link dto (#27023)
refactor!: remove deprecated shared link apis
2026-04-14 20:58:02 -04:00
Jason Rasmussen e1a84d3ab6 refactor!: remove replace asset (#27022) 2026-04-14 20:21:05 -04:00
Timon 7d8f843be6 refactor!: migrate class-validator to zod (#26597) 2026-04-14 23:39:03 +02:00
renovate[bot] 921c8a8de3 chore(deps): update dependency typescript to v6 (#27577)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2026-04-07 17:15:55 +02:00
Ray 136bd1e2eb feat(server): Add support for .ts files (#27529) 2026-04-06 15:50:05 +02:00
Min Idzelis 9bcce59719 fix(e2e): fix search gallery delete tests (#27536) 2026-04-06 14:00:50 +02:00
John Maguire 4fcd9c2e0d feat: add preview button when selecting images (#27305)
* Add preview button when selecting images

* Fix test helper

* prettier

* styling

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2026-04-03 16:21:43 +00:00
Min Idzelis 18201a26d9 feat(web): OCR overlay interactivity during zoom (#27039)
Change-Id: Id62e1a0264df2de0f3177a59b24bc5176a6a6964
2026-03-30 19:19:53 -05:00
Phlogi 8c6adf7157 feat(server): resolve duplicates (#25316)
* feat(web): Synchronize information from deduplicated images

* Added new settings menu to the the deduplication tab.
* The toggable options in the settings are synchronization of: albums, favorites, ratings, description, visibility and location.
* When synchronizing the albums, the resolved images will be added to all albums of the duplicates.
* When synchronizing the favorite status, the resolved images will be marked as favorite, if at least one selectable image is marked as favorite.
* When synchronizing the ratings, the highest rating from the selectable images will be applied to the resolved image.
* When synchronizing the description, all descriptions from the selectable images will be merged into one description for the resolved image.
* When synchronizing the visibility, the most restrictive visibility setting from the selectable images will be applied to the resolved image.
* When synchronizing the location, if exactly one unique location exists among the selectable images, this location will be applied to the resolved image.
* There is no additional UI for these settings to keep the visual clutter minimal. The settings are applied automatically based on the user's preferences.

* Replace addAssetToAlbums with copyAsset

* fix linter

* feat(web): add duplicate sync fields and fix typo

* feat(web): add tag sync and enhance duplicate resolution

This update introduces tag synchronization for duplicate resolution,
ensuring all unique tag IDs from duplicates are applied to kept assets.
The visibility sync logic is updated to use a simplified ordering, as the hidden status items will never show up in a duplicate set.
Album synchronization now merges albums directly via addAssetsToAlbums; as the approach with copyAsset API endpoint was ineffiecient.
Description, rating, and location sync logic is improved for correctness.
and deduplication. i18n strings were added / updated.

* feat(server): move duplicate resolution to backend with sync and stacking

Moves duplicate metadata synchronization from frontend to backend, enabling robust
batch operations and proper validation. This is an improved refactor of PR #13851.

New endpoints:
- POST /duplicates/resolve - batch resolve with configurable metadata sync
- POST /duplicates/stack - create stacks from duplicate groups
- GET /duplicates - now includes suggestedKeepAssetIds based on file size and EXIF

Key changes:
- Move sync logic (albums, tags, favorites, ratings, descriptions, location, visibility) to server
- Add server-side metadata merge policies with proper conflict resolution
- Replace client-side resolution logic with new backend endpoints
- Add comprehensive E2E tests (70+ test cases) and unit tests
- Update OpenAPI specs and TypeScript SDK

No breaking changes - only additions to existing API.

* feat(preferences): enable all duplicate sync settings by default

* chore: clean up

* chore: clean up

* refactor: rename & clean up

* fix: preference upgrade

* chore: linting

* refactor(e2e): use updateAssets API for setAssetDuplicateId

* fix: visibility sync logic in duplicate resolution

* fix(duplicate): write description to exifUpdate

Previously the duplicate resolution populated assetUpdate.description even
though description belongs to exif info.

* fix(duplicate): remove redundant updateLockedColumns wrapper

updateAllExif already computes lockedProperties via distinctLocked
using Object.keys(options). The wrapper added a lockedProperties key
to the options object, causing the spurious string 'lockedProperties'
to be stored in the lockedProperties array.

* fix(duplicate): write merged tags to asset_exif to survive metadata re-extraction

During duplicate resolution, replaceAssetTags correctly wrote merged tag
IDs to the tag_asset table, but never updated asset_exif.tags or locked
the tags property. The subsequent SidecarWrite → AssetExtractMetadata
chain calls applyTagList, which destructively replaces tag_asset rows
with whatever is in asset_exif.tags — still the original per-asset tags,
not the merged set.

Write merged tag values to asset_exif.tags via updateAllExif (which also
locks the property via distinctLocked), and queue SidecarWrite when tags
change so they persist to the sidecar file.

* docs(duplicates): clarify location and tag sync behavior

* refactor(duplicate): remove sync settings, always sync all metadata on resolve

Remove DuplicateSyncSettingsDto and the per-field sync toggles
(albums, favorites, rating, description, visibility, location, tags).
Duplicate resolution now unconditionally syncs all metadata from
trashed assets to kept assets.

- Remove DuplicateSyncSettingsDto and settings field from DuplicateResolveDto
- Update DuplicateService to always run all sync logic without conditionals
- Delete DuplicateSettingsModal.svelte and settings gear button from UI
- Remove DuplicateSettings type and duplicateSettings persisted store
- Update unit and e2e tests to remove settings from resolve requests

* docs: update duplicates utility to reflect automatic metadata sync

* docs(web): replace duplicates info modal with link to documentation

* chore: clean up

* fix: add missing type cast to jsonAgg in duplicate repository getAll

* fix: skip persisting rating=0 in duplicate merge to avoid unnecessary sidecar write

---------

Co-authored-by: Toni <51962051+EinToni@users.noreply.github.com>
Co-authored-by: Jason Rasmussen <jason@rasm.me>
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2026-03-26 18:33:55 +00:00
Diogo Tavares Sendim Fernandes 958f270f0d fix(web): keep map view open after closing asset viewer (#26980) 2026-03-26 18:11:05 +00:00
Paul Makles 44ae0fa7ed fix(database restores): don't assume onboarding has completed (#27052) 2026-03-26 18:30:14 +01:00
Yaros 94b15b8678 fix(server): album permissions for editors (#27214)
* fix(server): album permissions for editors

* test: adjust e2e test

* test: fix test
2026-03-23 21:39:30 -05:00
Michel Heusschen 2dd785e3e2 fix(web): restore duplicate viewer arrow key navigation (#27176) 2026-03-23 10:01:15 -05:00
Min Idzelis 88002cf7fe fix(web): allow images to be downloaded again(long-press or right click) (#26992) 2026-03-18 12:40:36 +01:00
Belnadifia 55513cd59f feat(server): support IDPs that only send the userinfo in the ID token (#26717)
Co-authored-by: irouply <irouply@secom.fr>
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2026-03-13 22:14:45 +01:00
Michel Heusschen 3fd24e2083 fix(server): restrict individual shared link asset removal to owners (#26868)
* fix(server): restrict individual shared link asset removal to owners

* make open-api
2026-03-12 14:48:00 -04:00
Min Idzelis 8764a1894b feat: adaptive progressive image loading for photo viewer (#26636)
* feat(web): adaptive progressive image loading for photo viewer

Replace ImageManager with a new AdaptiveImageLoader that progressively
loads images through quality tiers (thumbnail → preview → original).

New components and utilities:
- AdaptiveImage: layered image renderer with thumbhash, thumbnail,
  preview, and original layers with visibility managed by load state
- AdaptiveImageLoader: state machine driving the quality progression
  with per-quality callbacks and error handling
- ImageLayer/Image: low-level image elements with load/error lifecycle
- PreloadManager: preloads adjacent assets for instant navigation
- AlphaBackground/DelayedLoadingSpinner: loading state UI

Zoom is handled via a derived CSS transform applied to the content
wrapper in AdaptiveImage, with the zoom library (zoomTarget: null)
only tracking state without manipulating the DOM directly.

Also adds scaleToCover to container-utils and getAssetUrls to utils.

* fix: don't partially render images in firefox

* add passive loading indicator to asset-viewer

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-11 09:48:46 -05:00
Min Idzelis 422111d26e test(e2e): fix flakiness: optimize resetDatabase with TRUNCATE and fix selectDay selector scoping (#26776)
fix(e2e): optimize resetDatabase with TRUNCATE and fix selectDay selector scoping
2026-03-08 01:38:15 -06:00
Min Idzelis 7f47cdd645 feat: enhance face-editor positioning (#26303)
feat: enhance face-editor positioning - less overlap

test: timeline with actual video
2026-03-02 09:44:59 -05:00
Min Idzelis 625b30c50a test: stack editor e2e tests (#26526)
* feat: add responsive layout to broken asset

* test: stack editor e2e tests
2026-03-02 09:43:56 -05:00
Min Idzelis 8619d14eca feat: add responsive layout to broken asset (#26384) 2026-03-02 09:27:40 -05:00
Min Idzelis 60dafecdc9 refactor: thumbnail components (#26379) 2026-02-23 11:56:20 -05:00
Min Idzelis aae64b5e2f test: thumbnail selector (#26383)
* test: face ordering issue/flakiness

* test: thumbnail selector
2026-02-20 15:04:17 +00:00
Min Idzelis b4e16efdf4 test: face ordering issue/flakiness (#26382) 2026-02-20 09:23:40 -05:00
Min Idzelis b2050583f5 chore: run maintenance test (e2e) in isolation too, share containers (#26246) 2026-02-18 09:39:13 -05:00
Jason Rasmussen 72cef8b94b feat: shared link login (#25678) 2026-02-12 12:08:38 -05:00
Min Idzelis 6af534fe4c feat: run maintenance tests in isolation, share containers between all … (#25856)
* feat: run maintance tests in isolation, share containers between all serial test suites

* refactor: organize files

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-02-10 11:05:06 -05:00
Daniel Dietzler 9c098109e0 fix: time zone upserts (#25889) 2026-02-05 12:43:03 -05:00
Min Idzelis 95e8e474b8 fix(web): enable asset viewer navigation across memory boundaries (#25741) 2026-02-02 10:12:08 -06:00