How Photo Providers (Immich & Synology) Integrate with the Journey Addon in TREK
Photo providers extend the Journey addon by connecting external image libraries through server-side credential storage, proxy streaming, and a REST API that references assets without duplicating binary data.
The Journey addon in TREK transforms the platform into a photo-first travel journal, allowing users to document trips with geotagged entries. To prevent vendor lock-in and support existing self-hosted media libraries, TREK integrates with Immich and Synology Photos through a provider abstraction layer. This integration keeps sensitive credentials encrypted server-side while streaming images on-demand through TREK’s secure proxy.
Enabling Photo Providers in the Admin Panel
Before users can link external libraries, an administrator must activate the Journey addon and explicitly enable the desired photo providers.
- Navigate to Admin → Addons and toggle the Journey addon.
- Once enabled, two sub-toggles appear: Immich and Synology Photos.
- Activating either provider exposes a Photo Providers section in every user’s Settings → Integrations page.
According to the source configuration in wiki/Admin-Addons.md, the system stores these preferences as JSON:
{
"addons": {
"journey": true,
"photo_providers": {
"immich": true,
"synologyphotos": false
}
}
}
Configuring User Credentials and Scopes
Each user authenticates their personal photo libraries through the Integrations tab. Credentials are encrypted at rest and never exposed to the browser.
Required parameters for both providers:
- Server URL – The full API endpoint (e.g.,
https://immich.example.com/apiorhttps://nas:5001/photo). - API token / passphrase – Stored encrypted in the database.
- Scope selection – For Immich, the mandatory OAuth scope is
timeline.readfor browsing. Enableasset.uploadonly if you want TREK to mirror Journey uploads back to Immich.
If your provider runs on a private LAN, you must whitelist the URL in Admin → Internal Network Access so the TREK server can reach it, as documented in wiki/Internal-Network-Access.md.
API Integration and Photo Fetching
When a user attaches an external photo to a Journey entry, the frontend calls the protected endpoint:
POST /api/journeys/:entryId/provider-photos
The request payload follows the Zod schema defined in shared/src/journey/journey.schema.ts:
curl -X POST "https://trek.example.com/api/journeys/42/provider-photos" \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"provider": "immich",
"asset_id": "ae3f5d4c-1b2c-4d5e-9f6a-7b8c9d0e1f2a",
"caption": "Sunset at the beach",
"passphrase": "optional-secret"
}'
Backend processing flow:
JourneyController.providerPhotos(lines 148-155 inserver/src/nest/journey/journey.controller.ts) validates the JWT and checks for thejourney:writescope.- The controller delegates to
JourneyService.addProviderPhoto, which stores only the reference tuple (provider+asset_id) rather than the file itself. - The action is logged under
admin.places_photosin the audit log for compliance tracking.
Displaying Photos via Proxy Streaming
Journey entries display thumbnails by streaming images through TREK’s server-side proxy, ensuring provider tokens remain server-side only.
The UI references images via:
<img src="/api/public/journey/12" alt="Sunset at the beach"/>
When this route is hit, TREK reads the stored reference from the database, fetches the raw bytes from Immich or Synology, and streams the response to the client with proper Cache-Control headers. This architecture prevents credential leakage while allowing offline caching of frequently viewed images.
Mirroring Uploads to Immich
If the admin enables "Mirror journey photos to Immich on upload", TREK performs a dual-write operation:
- The uploaded file is stored locally under
uploads/photos/for fast retrieval and offline resilience. - Simultaneously, the image is pushed to the configured Immich instance using the
asset.uploadscope.
This synchronization happens inside JourneyService and is documented in the mirroring table within wiki/Photo-Providers.md. Local storage remains the primary source; the Immich copy serves as a backup in the user’s existing photo library.
Summary
- Enablement: Admins activate Immich and Synology Photos as sub-toggles under the Journey addon in
Admin-Addons.md. - Security: API tokens are encrypted in the database and never transmitted to the frontend; images are proxied through
/api/public/journey/:photoId. - Storage efficiency: Only asset references (
provider+asset_id) are stored in TREK’s database; binary data streams on-demand. - Permissions: Adding provider photos requires the
journey:writescope and is audited underadmin.places_photos. - Bidirectional sync: Optional mirroring pushes Journey uploads to Immich while keeping local copies for performance.
Frequently Asked Questions
Where are photo provider credentials stored in TREK?
Credentials are encrypted in the TREK database and decrypted only server-side when making requests to Immich or Synology APIs. They are never sent to the browser or exposed in network logs, following the security model defined in wiki/Photo-Providers.md.
Can I use Immich and Synology Photos simultaneously?
Yes. The Journey addon supports multiple active providers. Users can link both an Immich server and a Synology Photos account in their Settings → Integrations, then choose which provider to source from when adding photos to an entry via the provider field in the API payload.
Why does TREK proxy images instead of storing them directly?
TREK stores only lightweight references (asset_id) to avoid duplicating large binary files in its own storage. The proxy route (/api/public/journey/:photoId) fetches images on-demand from the external provider, ensuring credentials remain server-side while allowing TREK to apply caching headers and access control.
What permission is required to add a provider photo to a Journey entry?
Users must possess the journey:write OAuth scope. This scope is validated by JourneyController.providerPhotos before JourneyService.addProviderPhoto processes the request, and successful additions are logged to the audit trail under admin.places_photos.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →