mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-05 04:04:07 +00:00
Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ec486214f1 | |||
| d09a09ad52 | |||
| 8b41561db9 | |||
| 73744203fb | |||
| bc385f27dd | |||
| 866b9e94af | |||
| ed7c79bcb7 | |||
| 1e4b618878 | |||
| 982861264e | |||
| 6434fe7a3c | |||
| 70e07f1965 | |||
| 87041c8842 | |||
| edb113f97f | |||
| fcd5f5dbb6 | |||
| 6849742d67 | |||
| 022e088da4 | |||
| 2471fc5aa7 | |||
| fad301ef5e | |||
| 1c83bf78fa | |||
| a6cd4ffdff | |||
| 988d27c39d | |||
| 62b954cffc | |||
| a2fed6afb8 | |||
| 97510e007e | |||
| 36f81934aa | |||
| 303bce431d | |||
| 73811e0bb7 | |||
| 0ca9f7241a | |||
| bab4c7edcd | |||
| 166b0d8ab3 | |||
| a5dbf6934c | |||
| d2bd6e7556 | |||
| 676d086ff2 | |||
| d8793f3d0b | |||
| fcf4c6e736 | |||
| fa40dfba2c | |||
| 2a17227337 | |||
| a5757dd59f | |||
| 2e10263155 | |||
| 7a7c66e801 | |||
| a55728fe46 | |||
| 8bd5e428b4 | |||
| 504b58ecf6 | |||
| 0f05b0342c | |||
| 7eea0e7669 | |||
| 0f88a74976 | |||
| 9ffd5e5ffb | |||
| 00a326029b | |||
| a47b35b965 | |||
| fcfcf2ff17 | |||
| 016567dd9a | |||
| b64dd700a8 | |||
| b0b6f5872f |
@@ -0,0 +1,120 @@
|
||||
# AI Assistant
|
||||
|
||||
The assistant is a chat inside TREK that knows your trip. Ask it what is still open, let it plan a day, find somewhere to eat near the hotel or turn a booking confirmation into a booking. It reads your plan the way you see it and answers in words, cards and places on the map. **Nothing in your trip changes until you confirm it**: every change the assistant wants to make arrives as a card with **Apply** and **Discard**, and an applied change can be undone.
|
||||
|
||||
The assistant runs on an AI model from a provider you or your administrator connect, such as Anthropic, OpenAI, Gemini, OpenRouter, a ChatGPT plan, or a model server of your own. Setting that up is explained in [AI-Connections](AI-Connections).
|
||||
|
||||
> **Admin:** The assistant is the **AI Assistant** addon. It is off by default. In **Admin → Addons** it sits on the **AI** tile together with AI Parsing and MCP; switch it on there and set up the connection with **Set up AI**. See [AI-Connections](AI-Connections#for-administrators) and [Admin-Addons](Admin-Addons).
|
||||
|
||||
## Where the assistant runs
|
||||
|
||||
| Where | What it is about | What it may change |
|
||||
|---|---|---|
|
||||
| In a trip | That trip: its days, places, bookings, transports, costs, lists, tours, road trip and collab | Everything you may change in the trip yourself, after you confirm |
|
||||
| Outside a trip (the home chat) | All your trips at once, plus your Atlas, Vacay and journals | Nothing. It reads, compares and answers, and hands you over to a trip's own chat |
|
||||
| In [TREK Studio](TREK-Studio#the-book-assistant) | One journey and its photo book | The book's pages, layouts and theme, after you confirm |
|
||||
|
||||
The assistant appears only once a connection you can use is set up. Until then there is no button for it, so nobody is shown a feature they cannot use.
|
||||
|
||||
## Opening it
|
||||
|
||||
- **On the desktop**, the **Assistant** button in the navigation bar opens and closes it, and in the trip planner a round button floats at the bottom of the screen. **Ctrl+K** (**⌘K** on a Mac) does the same anywhere, except while a dialog is open.
|
||||
- **On a phone**, a trip's **More** sheet starts with **Ask TREK** (*Plan with the assistant*), and outside a trip **Assistant** leads the **More** list of the bottom bar. The dashboard has an assistant button at the top as well. See [Mobile-App](Mobile-App).
|
||||
- **From the planner**, a right click on a place offers **Find an alternative** and **Restaurant nearby**, and one on a day offers **Plan this day** and **Plan for rain**. The place details have an **Ask** button. Each of these opens the chat with that place or day as its subject and sends the question straight away.
|
||||
|
||||
On the desktop the assistant is a window floating over the app. Drag it by its head, resize it from any edge or corner, and let go near a corner to make it settle there. A double click on the head switches between a compact and a large window, and **Alt+arrow keys** move it (**Alt+Shift+arrow keys** resize it). The window remembers where it was. Closing it only hides it: an answer still being written carries on, and the round button breathes until it is done. **Escape** first stops an answer, then closes the window.
|
||||
|
||||
## Asking
|
||||
|
||||
Type into **Ask anything about** *your trip* and press **Send**. While an answer is being written, **Stop** ends it.
|
||||
|
||||
- **Suggestions.** An empty chat offers questions that fit the moment, such as *Plan the first days for me* before the trip, *What's on today?* during it, or *Sum up our trip* after it.
|
||||
- **Mentions.** Type **@** to pick a day, a place or a booking of the trip, and the assistant knows exactly which one you mean. You can also drag a place from the sidebar or the map into the chat.
|
||||
- **Steps.** While it works, the chat shows what the assistant is doing (*Reading your plan*, *Searching for places*, *Checking the weather*) and folds the steps away once the answer is there.
|
||||
- **Ask next.** Under an answer come a few follow ups that fit it, for example *Only cheaper ones* or *Plan the next day the same way*. One click sends it.
|
||||
- **Web search.** When the administrator allows it and the provider supports it (ChatGPT, Anthropic and OpenRouter), the assistant can look things up on the web, such as reviews, opening times or events. The answer then lists its **Sources**.
|
||||
|
||||
**Recent chats** in the window's head lists your earlier conversations, and **New chat** starts another. Your chats are your own: other trip members never see them. A chat you no longer want goes with **Delete chat** in the **More options** menu.
|
||||
|
||||
### Trip notes
|
||||
|
||||
The assistant can remember things about a trip for every later conversation: *we eat vegetarian*, *we travel with children*, *no early mornings*. When it keeps something, the chat shows **Noted for this trip:** and the note. **Edit trip notes** in the **More options** menu opens the full list, with a row of **Common wishes** to tick and a field for your own words. Trip notes are yours, per trip, and are not shown to other members.
|
||||
|
||||
### Hints
|
||||
|
||||
The assistant looks over the plan on its own and lists what is **Worth a look**: two things that overlap, a place that is closed on the day you planned it or opens too late, a long gap in a day, a leg that is far or tight, nights with nowhere to stay yet, and bookings that are not on any day. Each hint is one click away from a question about it, and **Hide this hint** puts one away. The launcher shows how many hints are waiting; **Stop showing hints** in the **More options** menu switches them off.
|
||||
|
||||
## Suggested changes
|
||||
|
||||
When the assistant wants to change something, it does not do it. It shows a **Suggested changes** card:
|
||||
|
||||
1. Each row names what would happen (**Add place**, **Move to another day**, **Add expense**, **Add booking**, and so on) and the values it would set. Untick **Include this change** on a row to leave it out.
|
||||
2. **Compare on the map** switches between **Before** and **After**, and **Show on map** opens the planner on the change. Planned days come with a day preview (*Moves here*, *Comes off*), a check whether the day still **Fits the time**, and for longer plans an overview of **The days of this plan**.
|
||||
3. **Apply** (or **Apply** *count*) makes the changes, with your own permissions, exactly as if you had made them by hand. **Discard** drops them.
|
||||
|
||||
While a card is waiting, the chat asks you to **Apply or discard the changes above first** before it goes on. A suggestion nobody decides on expires after 24 hours and then reads **No longer available**.
|
||||
|
||||
**Undo** on an applied card takes the change back again, and **Undo all** takes back the whole card. Undo is offered for 15 minutes. When someone changed the same thing in the meantime, TREK does not overwrite their work: the row reads *Changed in the meantime. Please adjust it by hand.*
|
||||
|
||||
On a trip you can only view, the assistant still answers questions, but it says so and suggests no changes.
|
||||
|
||||
## What the answers show
|
||||
|
||||
Besides text, an answer can carry cards that work like the rest of TREK:
|
||||
|
||||
- **Places found**: the places the assistant found, with **Add to trip**, **On map**, opening hours (**Open now** or **Closed**) and the distance from the previous stop. A place already planned reads **Already in your trip**. On a tour, **Add to tour** puts one in as a stop.
|
||||
- **Weather** for the days the question is about, with the chance of rain.
|
||||
- Cards for days, bookings, costs, packing items, to-dos, tours, journal entries and photo book pages, each with a way to open the item in TREK.
|
||||
- With **Map follows the assistant** on, the trip map moves to where the assistant searches and suggests places.
|
||||
- With **Estimate costs** on, a suggested restaurant or ticket comes with an estimated expense for the budget, as a card you confirm.
|
||||
|
||||
Both switches are in **Settings → Integrations** under the AI connection, see [AI-Connections](AI-Connections#your-settings).
|
||||
|
||||
## Files and bookings
|
||||
|
||||
**Attach a booking** under the chat field, or a file dropped on the chat, hands the assistant a booking confirmation, an email, a PDF, an image or a wallet pass of up to 10 MB.
|
||||
|
||||
- TREK's own booking reader looks at it first, the same one [AI-Booking-Import](AI-Booking-Import) uses. The bookings it finds come back as cards to add.
|
||||
- When it finds none, the chat says why and offers what to do next: **Keep it in Files**, **Create a booking from it**, **Attach it to a booking or an expense** or **What is in the file?**
|
||||
- The file's contents go to the AI provider only after you confirm a card, **Let the assistant read the file**, which names where it is sent. Keeping the file in the trip's Files is a card too.
|
||||
- Route files (GPX and similar) can become a tour, see [Tours](Tours).
|
||||
|
||||
A file attached in the chat is kept for seven days so the conversation can come back to it, then it is deleted. A file you kept in Files stays there like any upload.
|
||||
|
||||
## Sharing an answer
|
||||
|
||||
**Share in the trip chat** posts an answer to the trip's [Collab chat](Collab-Chat), marked as coming from the assistant. The preview shows what everyone on the trip will see, and **Add the changes you applied** lists what you applied. This needs the trip chat to be switched on.
|
||||
|
||||
## The home chat
|
||||
|
||||
Outside a trip the assistant is about **Your travels**: *Which trip is next, and what is still open?*, *Compare my upcoming trips*, *How many countries have I visited?* or *How many vacation days do I have left this year?* It reads your trips but changes none of them. When a question belongs to one trip, it offers **Continue in a trip chat**, and **Chat about one trip** in the head opens a trip's own chat directly. **Back to all trips** returns.
|
||||
|
||||
## What it can and cannot do
|
||||
|
||||
The assistant works with your rights and no more. It can do what you could do through [MCP](MCP-Overview) yourself, with a few exceptions it never gets: it cannot delete a trip, create share or invite links, read the contents of your files without your consent, or use plugin tools.
|
||||
|
||||
- One answer may take up to 30 model steps. A very large request stops there and asks *That was a lot at once. Shall I continue?*, and **Continue** goes on.
|
||||
- The administrator can limit how many messages each person sends per day while the instance pays for the model. Your settings then show how many of today's messages you have used, and at the limit the chat says *That's it for today. See you tomorrow.*
|
||||
- The assistant needs a connection. Offline it says so and waits.
|
||||
|
||||
## Privacy
|
||||
|
||||
The first time you chat, a banner names the provider your messages go to. **What gets shared?** spells it out: your messages and the trip details the assistant reads, like places, days and bookings. Not your password, your files or your other trips. The provider handles this under its own privacy terms.
|
||||
|
||||
Chats are deleted after the number of days the administrator chose (90 by default); the chat list says how long they are kept. Deleting a chat removes it at once.
|
||||
|
||||
## The assistant and other AI features
|
||||
|
||||
| Feature | What it is |
|
||||
|---|---|
|
||||
| AI Assistant (this page) | A chat inside TREK that suggests changes you confirm |
|
||||
| [AI-Booking-Import](AI-Booking-Import) | Reads booking files that TREK's own reader cannot. It can share the assistant's connection |
|
||||
| [MCP](MCP-Overview) | Lets an AI app outside TREK, such as Claude or Cursor, work with your trips |
|
||||
|
||||
## See also
|
||||
|
||||
- [AI-Connections](AI-Connections)
|
||||
- [TREK-Studio](TREK-Studio#the-book-assistant)
|
||||
- [Mobile-App](Mobile-App)
|
||||
- [Admin-Addons](Admin-Addons)
|
||||
- [MCP-Overview](MCP-Overview)
|
||||
+71
-22
@@ -2,9 +2,9 @@
|
||||
|
||||
The **AI Parsing** addon gives TREK's booking import a second reader. When [KDE Itinerary](Reservations-and-Bookings#import-from-booking-confirmation) cannot make sense of a confirmation (a plain-text email, an unusual PDF layout, a vendor whose format it does not know) TREK hands the document to an AI model and turns the answer into a booking you check before it is saved. With a model that reads images, it also reads photos of tickets.
|
||||
|
||||
The addon is **off by default**. It works with a model running on your own hardware, so booking data never has to leave your server.
|
||||
The addon is **off by default**. It reads with the same AI connection the [AI assistant](#the-ai-assistant-and-this-addon) uses, and it also works with a model running on your own hardware, so booking data never has to leave your server.
|
||||
|
||||
> **Admin:** turn on **AI Parsing** in [Admin-Addons](Admin-Addons), in the *Integration* group. Import then works even without the `kitinerary-extractor` binary: with no extractor, the model reads every uploaded file instead of only the ones Itinerary cannot. Installing the extractor is still the better setup, since structured tickets stay fast and predictable and the model stays a fallback. Set up a provider and a model before anyone uses it, though. The import button appears as soon as the addon is on, and with neither an extractor nor a model the import fails.
|
||||
> **Admin:** turn on **AI Parsing** in [Admin-Addons](Admin-Addons). AI Parsing, AI Assistant and MCP share one tile named **AI** in the *Integration* group, with a switch for each of the three. Once AI Parsing or the AI Assistant is on, the tile shows a **Set up AI** button that opens the dialog described in [Admin: setting up AI](#admin-setting-up-ai). Import works even without the `kitinerary-extractor` binary: with no extractor, the model reads every uploaded file instead of only the ones Itinerary cannot. Installing the extractor is still the better setup, since structured tickets stay fast and predictable and the model stays a fallback. Set up a connection and a model before anyone uses it, though. The import button appears as soon as the addon is on, and with neither an extractor nor a model the import fails.
|
||||
|
||||
## How it fits with normal import
|
||||
|
||||
@@ -18,9 +18,37 @@ Structured tickets keep being read the fast, predictable way, and the model only
|
||||
|
||||
AI results are marked for review internally, but the mark never reaches the card: saving in the editor stores each booking as checked.
|
||||
|
||||
## Which connection reads your files
|
||||
|
||||
AI parsing looks for a connection in this order and uses the first one it finds:
|
||||
|
||||
1. **The addon's own connection.** An admin can give AI parsing a connection of its own in the **Set up AI** dialog (**Own connection**). It is used for everyone and wins over everything below. Installs that set a model on the addon before the shared connection existed keep it.
|
||||
2. **The shared AI connection.** The one the AI assistant runs on: a connection an admin set up once for everyone, or the one each person connected for themselves, depending on the admin's **Who pays** choice. This is the default, and the reason most installs never need a separate setup for parsing.
|
||||
3. **A personal parsing model.** Only for people who saved one under **Settings → Integrations → AI parsing** before parsing could read with the shared connection. See [Your own connection](#your-own-connection).
|
||||
|
||||
If none of them exists, the import fails with an error shown in the widget.
|
||||
|
||||
Two details of the shared connection:
|
||||
|
||||
- A **ChatGPT** sign-in is not used for parsing. It only reaches ChatGPT's chat models, not the endpoint that parsing calls. Connect an API key (or another provider) for parsing instead.
|
||||
- **Model reads images** is a setting of AI parsing itself and stays there, whichever connection reads. See [Photos](#photos).
|
||||
|
||||
## Choosing a provider
|
||||
|
||||
The addon supports three providers:
|
||||
The shared connection of the AI assistant supports these providers:
|
||||
|
||||
| Provider | Runs where | Notes |
|
||||
|----------|-----------|-------|
|
||||
| **OpenAI** | OpenAI's API | Needs an API key. |
|
||||
| **Anthropic** | Anthropic's API | Needs an API key. **Reads PDFs natively, scans included.** |
|
||||
| **Gemini** | Google's OpenAI-compatible endpoint | Needs an API key. |
|
||||
| **OpenRouter** | OpenRouter's API | **Connect OpenRouter** signs you in, so there is no key to copy. |
|
||||
| **Sign in with ChatGPT** | ChatGPT | Uses a ChatGPT plan, no key. Chat only, not used for parsing. |
|
||||
| **Own server** | Your own hardware | Any OpenAI-compatible server, for example Ollama, at a **Server address** you enter. The API key is optional. |
|
||||
|
||||
To connect, pick **Sign in with ChatGPT**, **Paste an API key** or **Own server**. When you paste a key, TREK shows *Detected: {provider}*; if it cannot tell, it asks *Which provider is this key from?*. **Connect OpenRouter** is offered as its own button.
|
||||
|
||||
The addon's **Own connection** offers three providers of its own:
|
||||
|
||||
| Provider | Runs where | Notes |
|
||||
|----------|-----------|-------|
|
||||
@@ -36,40 +64,51 @@ The addon supports three providers:
|
||||
>
|
||||
> **Photos:** a photo (JPG, PNG, WEBP) goes to the model as an image, with every provider, as long as the model reads images. See [Photos](#photos).
|
||||
|
||||
## Admin: instance-wide configuration
|
||||
## Admin: setting up AI
|
||||
|
||||
Once the addon is on, a configuration panel appears right under it in [Admin-Addons](Admin-Addons):
|
||||
**Set up AI** on the AI tile opens one dialog for the connection that the assistant and AI parsing share. A tab shows only while its addon is on: **Connection**, **AI Assistant** and **AI Parsing**. Every change saves at once.
|
||||
|
||||
> *Set instance-wide config (applies to all users). Leave blank to let each user configure their own provider.*
|
||||
### Connection
|
||||
|
||||
- **Provider**: Local · OpenAI-compatible, OpenAI, or Anthropic.
|
||||
- **Who pays** decides whose connection is used: **I pay for everyone** (everyone uses the connection below and cannot add their own), **I pay, own allowed** (everyone uses the connection below unless they connect their own) or **Everyone uses their own account** (everyone connects their own provider and nothing is charged to you).
|
||||
- **Connection for everyone** appears while you pay. Connect a provider from the list under [Choosing a provider](#choosing-a-provider), pick the **Model** (only models that can use tools are listed), and use **Change** or **Remove connection** later. API keys are stored encrypted.
|
||||
- The **AI Assistant** tab holds the assistant's own limits: **Messages per person per day** (it only counts while you pay), **Keep chats** and **Web search**.
|
||||
|
||||
### AI Parsing
|
||||
|
||||
The **AI Parsing** tab starts with **Reads bookings with**, which shows the connection that reads right now, tagged **Shared** or **Own connection**:
|
||||
|
||||
- On the shared connection, **Use a different one** lets you give parsing a connection of its own. If there is no shared connection yet, the tab says so and offers a **Connection** button that takes you back to the first tab. With **Everyone uses their own account**, it says that each person reads with the connection set up in their settings.
|
||||
- With an **Own connection**, **Use the shared connection** goes back. The own connection is *used instead of the shared connection*.
|
||||
|
||||
The form for an **Own connection** has these fields:
|
||||
|
||||
- **Provider**: **Local (Ollama)**, **OpenAI** or **Anthropic**.
|
||||
- **Base URL**: empty means the provider's own address: `http://localhost:11434/v1` for a local Ollama server, `https://api.openai.com/v1` for OpenAI and `https://api.anthropic.com` for Anthropic. Any OpenAI-compatible endpoint goes here. For Anthropic it can name a gateway that speaks the Anthropic Messages API; give it without `/v1`, since TREK adds `/v1/messages`, and the gateway has to accept PDF document blocks and forced tool calls. Picking another provider empties the field, so an address meant for one never receives another provider's key.
|
||||
- **API key**: optional for a local server (the field says *(often not required)*), required for the cloud providers. It is stored **encrypted** and shown masked (`••••••••`) once saved; leaving it unchanged keeps the stored key.
|
||||
- **API key**: optional for a local server (the field says *Often not needed*), required for the cloud providers. It is stored **encrypted** and shown masked (`••••••••`) once saved; leaving it unchanged keeps the stored key.
|
||||
- **Model**: the model id, for example `qwen3.5:4b`, `gpt-4o` or `claude-opus-4-8`.
|
||||
- **Model reads images**: **Automatic**, **Yes** or **No**. With the Local provider, **Automatic** asks the Ollama server what the model can do (`/api/show`) and follows its answer. With OpenAI or Anthropic, **Automatic** means no. **Yes** and **No** apply as set, whatever the server or the model id says. Photos are only accepted when this comes out as yes.
|
||||
|
||||
A provider and model set here apply to **all users** and override their personal settings. Leave the panel blank to let every user bring their own model (see below).
|
||||
**Model reads images** sits below, with **Automatic**, **Yes** and **No**. With a local server, **Automatic** asks the Ollama server what the model can do (`/api/show`) and follows its answer. With a cloud model, **Automatic** means no, so choose **Yes** if your model reads images. **Yes** and **No** apply as set, whatever the server or the model id says. Photos are only accepted when this comes out as yes. The switch is shared by the booking import and by [Scan receipt](Budget-Tracking#scanning-a-receipt) in Costs.
|
||||
|
||||
### Pulling a local model
|
||||
|
||||
With the **Local** provider selected, the panel manages your Ollama server directly:
|
||||
With **Local (Ollama)** selected in an own connection, the form manages your Ollama server directly:
|
||||
|
||||
- **Installed on the server** lists the models Ollama already has, with a **Refresh** button. Click a model to select it.
|
||||
- **Pull a recommended model** downloads a model with a live progress bar. The recommended one is **Qwen3.5 4B** (`qwen3.5:4b`, 3.4 GB, 256K context): small and quick on a CPU-only host, with "thinking" switched off automatically, under the Apache-2.0 licence. It reads images, so with **Model reads images** on Automatic it accepts photos. A PDF with a text layer reaches it as extracted text, a scanned one as its first two pages drawn as images. When the download finishes, the model is selected.
|
||||
- **Installed on the server** lists the models Ollama already has, with a **Refresh** button. Click a model to select it. Until one is installed, the list says *No models installed yet. Pull one below.*
|
||||
- **Pull a recommended model** downloads a model with a live progress bar. The recommended one is **Qwen3.5 4B** (`qwen3.5:4b`, 3.4 GB, 256K context): small and quick on a CPU-only host, with "thinking" switched off automatically, under the Apache-2.0 licence. It reads images, so with **Model reads images** on Automatic it accepts photos. A PDF with a text layer reaches it as extracted text, a scanned one as its first two pages drawn as images. When the download finishes, the model is selected. **Pull** becomes **Use** once a model is on the server, and **Selected** for the one in use.
|
||||
|
||||
Any other model already on the server can be selected too, or typed in by hand.
|
||||
Any other model already on the server can be selected too, or typed in by hand. If the server cannot be reached, the form says *Could not reach the local server*.
|
||||
|
||||
## Per-user configuration
|
||||
## Your own connection
|
||||
|
||||
When an admin leaves the instance configuration blank, each user can set up their own model under **Settings → Integrations → AI parsing**. The section only appears while the addon is on:
|
||||
What a person sees in **Settings → Integrations** depends on the addons that are on and on the admin's **Who pays** choice:
|
||||
|
||||
> *Choose the AI model used to extract bookings from uploaded files. This applies only when your administrator has not configured a model for the whole instance.*
|
||||
- With the AI Assistant or AI Parsing on, an **AI connection** section lets you connect your own provider when the admin allows it, shows who answers and which model, and lets you sign out or disconnect. Its title reads *AI assistant* while the assistant is on, and *AI parsing* when only AI Parsing is. When the admin pays, the section shows *Provided by your admin*.
|
||||
- A separate **AI parsing** section appears only for people who already saved a personal model there before parsing could read with the shared connection. It offers **OpenAI** or **Anthropic**, a **Model** id and an **API key**, which is stored encrypted; leave the key blank to keep the current one. There is no personal Base URL. The address the server calls is instance configuration, so a local Ollama server can only be set up by an admin. The server refuses a personal base URL or a personal `local` provider from anyone, admins included.
|
||||
|
||||
There you pick a **Provider** (only **OpenAI** or **Anthropic**), a **Model** id and an **API key**, which is stored encrypted; leave the key blank to keep the current one. There is no personal Base URL. The address the server calls is instance configuration, so a local Ollama model can only be set up by an admin on the addon. The server refuses a personal base URL or a personal `local` provider from anyone, admins included.
|
||||
A personal parsing model has its own **Model reads images** switch, on or off. It decides whether photos are offered and sent to your model, both for the booking import and for [Scan receipt](Budget-Tracking#scanning-a-receipt) in Costs. PDFs are not affected: only Anthropic gets the raw PDF, every other provider the extracted text.
|
||||
|
||||
The **Model reads images** switch decides whether photos are offered and sent to your model, both for the booking import and for [Scan receipt](Budget-Tracking#scanning-a-receipt) in Costs. PDFs are not affected: only Anthropic gets the raw PDF, every other provider the extracted text.
|
||||
|
||||
> **Precedence:** a model set by the admin for the whole instance always wins. Personal settings only count when there is none.
|
||||
> **Precedence:** the addon's own connection always wins when an admin has set one. Otherwise the shared connection is used, and a personal parsing model only counts when there is neither.
|
||||
|
||||
## Importing a booking with AI
|
||||
|
||||
@@ -99,6 +138,14 @@ The model is asked for the complete booking, **every leg of a multi-segment flig
|
||||
- **Linked cost**: when the [Costs addon](Budget-Tracking) is on and the booking has a price, a linked expense is created in the currency the price was quoted in. Without the addon, the price stays on the booking.
|
||||
- **Source document**: the uploaded file is attached to the booking.
|
||||
|
||||
## The AI assistant and this addon
|
||||
|
||||
The in-app [AI assistant](Addons-Overview) can read a booking confirmation too. Attach the file to the chat (**Attach a booking**) and the assistant proposes an **Add booking from file** card that you confirm before it is saved. The file can be kept in the trip's Files, alone or together with the booking (**Keep the file with this booking**).
|
||||
|
||||
Use the import button on the Bookings or Transports tab when you have several files or want the normal editor review for each. Use the assistant when you are already talking to it about the trip. Both read with the same AI connection. The assistant also needs the AI Assistant addon; the import widget needs only AI Parsing.
|
||||
|
||||
Receipt scans in Costs use the shared connection as well, with the vision setting kept in AI Parsing. See [Budget-Tracking](Budget-Tracking#scanning-a-receipt).
|
||||
|
||||
## Photos
|
||||
|
||||
When the model reads images (see **Model reads images** above), the import takes photos as well: a phone picture of a paper train ticket, a boarding pass, a hotel confirmation. The upload dialog then says *Photos (JPG, PNG, WEBP) are read by the AI model.*, and a photo goes through the same background job, review and linked cost as any other file.
|
||||
@@ -118,7 +165,7 @@ Photographing a receipt for the Costs tab is covered in [Budget-Tracking](Budget
|
||||
- **Local models can be slow.** On a CPU-only host one booking can take from tens of seconds to a couple of minutes. TREK gives a model 15 minutes per document by default; `LLM_TIMEOUT_MS` raises or lowers that. Uploads are parsed **one at a time** per user, so several files wait in line rather than run in parallel.
|
||||
- **A long booking list can outgrow the answer.** A model may write at most 4096 tokens per document (8192 on Anthropic). When a document holds more than that, the import says the answer was cut off; `LLM_MAX_OUTPUT_TOKENS` raises the cap, as far as your model's context allows.
|
||||
- **Parse jobs are kept for about 10 minutes** after they finish. Start the review within that time.
|
||||
- **Privacy**: with the Local provider nothing leaves your network. With OpenAI or Anthropic, the document's text (for Anthropic the PDF itself, and for either a photo) is sent to that provider.
|
||||
- **Privacy**: with the Local provider or an own server nothing leaves your network. With OpenAI or Anthropic, the document's text (for Anthropic the PDF itself, and for either a photo) is sent to that provider.
|
||||
- **API keys are never sent back in plain text.** They are encrypted at rest and only ever shown masked.
|
||||
|
||||
## See also
|
||||
@@ -127,3 +174,5 @@ Photographing a receipt for the Costs tab is covered in [Budget-Tracking](Budget
|
||||
- [Transport-Flights-Trains-Cars](Transport-Flights-Trains-Cars)
|
||||
- [Admin-Addons](Admin-Addons)
|
||||
- [Budget-Tracking](Budget-Tracking), for linked costs and receipt scans
|
||||
- [AI-Connections](AI-Connections), the connection AI Parsing can share with the assistant
|
||||
- [AI-Assistant](AI-Assistant)
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
# AI Connections
|
||||
|
||||
TREK's AI features run on a language model from a provider you choose. The **AI connection** is that link: which provider answers, with which account or key, and which model. The [AI Assistant](AI-Assistant) runs on it, and [AI Parsing](AI-Booking-Import) can read your imported bookings with the same connection, so one setup serves both.
|
||||
|
||||
[MCP](MCP-Overview) works the other way round and needs no AI connection in TREK: there an AI app outside TREK brings its own model and talks to TREK.
|
||||
|
||||
## Providers
|
||||
|
||||
| Provider | How you connect | Notes |
|
||||
|---|---|---|
|
||||
| **Anthropic** | API key | *Claude Max and Team include API credits.* |
|
||||
| **OpenAI** | API key | Create a key in your OpenAI dashboard. |
|
||||
| **Gemini** | API key | AI Studio has a free tier with limits per minute and per day, on which Google may use what you send to improve its products. With billing turned on the limits are higher and that does not apply. |
|
||||
| **OpenRouter** | API key, or **Connect OpenRouter** | Signing in with OpenRouter hands TREK a key, no copying needed. Offered only when TREK runs on an `https://` address, because OpenRouter only sends the browser back to one. |
|
||||
| **ChatGPT** | **Sign in with ChatGPT** | Uses your ChatGPT plan, no key needed. Marked **Beta**: an API key is the official way. |
|
||||
| **Own server** | Server address, optional API key, model | Any OpenAI compatible server, for example Ollama. Only an administrator can set one up, for everyone. |
|
||||
|
||||
**Paste an API key** recognises the provider from the key itself and says **Detected:** with its name. When a key does not give its provider away, TREK asks **Which provider is this key from?** The key is tested as soon as you connect. **Get a key** opens the provider's page for making one.
|
||||
|
||||
**Sign in with ChatGPT** works in two steps, because ChatGPT does not send you back to TREK by itself:
|
||||
|
||||
1. **Open ChatGPT sign-in** opens ChatGPT in a new tab. Sign in there.
|
||||
2. Your browser then shows an error page. That is expected. Copy the address at the top, which starts with `127.0.0.1`, come back and use **Paste address**.
|
||||
|
||||
If it takes too long, TREK asks you to sign in again. A ChatGPT account other than the one already connected is refused until you remove the connection first.
|
||||
|
||||
### Choosing a model
|
||||
|
||||
Once connected, **Model** lists what the provider offers. *Only models that can use tools are listed*, because the assistant works through TREK's tools. **Recommended** marks a good default and **Free** a model without charge. A new connection starts on a model TREK picks; change it whenever you like.
|
||||
|
||||
## Your settings
|
||||
|
||||
Your connection lives in **Settings → Integrations**, in the **AI assistant** section (named **AI parsing** when only AI Parsing is switched on). What the section offers depends on how the administrator set things up:
|
||||
|
||||
| The administrator chose | What you see |
|
||||
|---|---|
|
||||
| **I pay for everyone** | **Provided by your admin**, and nothing to set up. *Your admin sets this up.* |
|
||||
| **I pay, own allowed** | **Provided by your admin**, plus **Connect your own provider** if you prefer your own account. Your own connection then takes over for you. |
|
||||
| **Everyone uses their own account** | *What would you like to chat with?* with **Sign in with ChatGPT** and **Paste an API key**. |
|
||||
|
||||
A connected section shows **Connected to** *the provider*, its status and the model:
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| **Connected** | Working. |
|
||||
| **Sign-in expired** | A ChatGPT sign-in ran out. **Sign in again** renews it. |
|
||||
| **Signed out** | You signed out; the connection counts as none. |
|
||||
| **Not reachable** | The provider did not answer or refused the key. **Replace key** fixes a key that stopped working. |
|
||||
|
||||
When your own connection breaks, TREK does not quietly switch you to the administrator's: you see why yours does not work instead.
|
||||
|
||||
**Disconnect** (or **Sign out** for ChatGPT) removes your connection. Your chats stay. **Open assistant** opens the chat straight from here.
|
||||
|
||||
Two switches for the assistant sit in the same section:
|
||||
|
||||
- **Map follows the assistant**: the trip map moves to where the assistant searches and suggests places.
|
||||
- **Estimate costs**: with a restaurant or a ticket, the assistant suggests an estimated expense for the budget, as a card you confirm.
|
||||
|
||||
While the administrator pays, the section also shows how many of today's messages you have used.
|
||||
|
||||
If you saved your own AI parsing model before the shared connection existed, that older section still shows below; see [AI-Booking-Import](AI-Booking-Import).
|
||||
|
||||
## For administrators
|
||||
|
||||
> **Admin:** In **Admin → Addons**, the **AI Assistant**, **AI Parsing** and **MCP** addons share one **AI** tile: *One connection for the assistant and booking import. MCP lets other AI apps use TREK.* Switch the addons on there, then press **Set up AI**. See [Admin-Addons](Admin-Addons).
|
||||
|
||||
**Set up AI** opens one dialog with a tab per part. A tab shows only while its addon is on, and every change is saved at once.
|
||||
|
||||
### Connection
|
||||
|
||||
**Who pays** decides whose connection the assistant runs on:
|
||||
|
||||
| Choice | Effect |
|
||||
|---|---|
|
||||
| **I pay for everyone** | Everyone uses the connection below and cannot add their own. |
|
||||
| **I pay, own allowed** (the default) | Everyone uses the connection below unless they connect their own. |
|
||||
| **Everyone uses their own account** | Everyone connects their own provider. Nothing is charged to you. |
|
||||
|
||||
While you pay, **Connection for everyone** holds the instance's connection: an API key, a ChatGPT sign-in, or an **Own server**. An own server takes a **Server address**, an optional API key and a model; when AI Parsing already talks to a local model, the form is prefilled from it (*Taken over from AI Parsing.*). **Change** replaces the connection and **Remove connection** deletes it.
|
||||
|
||||
> Signing in with your own ChatGPT plan for everyone shares that plan with everyone on the server: their chats count against your plan. Check that your plan and OpenAI's terms allow this.
|
||||
|
||||
TREK reaches an own server through the guard meant for services on your own network, so a model server on the same machine or your LAN works without `ALLOW_INTERNAL_NETWORK`. The cloud providers go through the strict guard. See [Internal-Network-Access](Internal-Network-Access).
|
||||
|
||||
### AI Assistant
|
||||
|
||||
- **Messages per person per day**: the daily limit, 50 by default. *Only counts while you pay*, so it never limits someone on their own connection. The day ends at midnight UTC.
|
||||
- **Keep chats**: how long conversations are kept, 30 days, 90 days (the default), 365 days or **Forever**. Older chats are deleted every night.
|
||||
- **Web search**: on by default. The assistant may look things up on the web through the search of the provider it talks to. Works with ChatGPT, Anthropic and OpenRouter; the searches go only to that provider.
|
||||
|
||||
### AI Parsing
|
||||
|
||||
**Reads bookings with** chooses the model that reads imported booking files: the shared connection (marked **Shared**), or an **Own connection** used instead of it, such as a local Ollama. Under **Everyone uses their own account**, each person reads with their own connection, set up in their settings. For a local model the tab lists what is **Installed on the server**, with **Refresh**, and **Pull a recommended model**. Details are on [AI-Booking-Import](AI-Booking-Import).
|
||||
|
||||
### Where secrets are kept
|
||||
|
||||
API keys and ChatGPT sign-in tokens are stored encrypted with the server's encryption key and are never shown again. Rotating that key re-encrypts them; see [Encryption-Key-Rotation](Encryption-Key-Rotation). Saving and removing connections and changing the AI settings is recorded in the [Audit-Log](Audit-Log).
|
||||
|
||||
The demo account cannot connect a provider of its own.
|
||||
|
||||
## See also
|
||||
|
||||
- [AI-Assistant](AI-Assistant)
|
||||
- [AI-Booking-Import](AI-Booking-Import)
|
||||
- [MCP-Overview](MCP-Overview)
|
||||
- [Admin-Addons](Admin-Addons)
|
||||
- [User-Settings](User-Settings)
|
||||
@@ -10,6 +10,7 @@ There are three ways to create a stay:
|
||||
|
||||
- **From a day:** choose **Add accommodation** in a day's **+** menu, or click **Add accommodation** in the [day details panel](#in-the-day-detail-panel). Both open the stay editor, described below.
|
||||
- **From the Bookings tab:** click **Manual Booking** and pick **Accommodation** in the type pill of the dialog's head band. The date and time fields make way for the stay's own fields, see [Accommodation fields in the booking editor](#accommodation-fields-in-the-booking-editor). Saving creates the booking and the stay at the same time.
|
||||
- **From the AI assistant:** the in-app assistant proposes a stay as a stay card in the chat. Nothing is saved until you confirm it, and the stay then appears in the day plan like any other.
|
||||
- **From the road trip search:** **Add as an overnight stay** books the night and adds the stop in one go. See [Road-Trip](Road-Trip#booked-nights-on-the-drive).
|
||||
|
||||
### The stay editor
|
||||
@@ -51,6 +52,8 @@ On every day from the check-in day to the check-out day, the **Accommodation** s
|
||||
- **Reservation**: the linked booking with its title, its status (**Confirmed** or **Pending**) and code. Click it to open the booking's detail.
|
||||
- For members who can edit days: the pencil (**Edit accommodation**) opens the stay editor, and the **X** (**Remove**) deletes the stay straight away, together with its booking and the expenses linked to that booking.
|
||||
|
||||
A stay booked in another place (the booking form, the assistant or the road trip search) shows up in the day plan and the day details at once, without a reload.
|
||||
|
||||
**Add accommodation** at the foot of the section adds another stay, for example a second hotel on a transfer day.
|
||||
|
||||
## In the day plan sidebar
|
||||
@@ -104,4 +107,9 @@ A stay that only runs across a deleted day, with its check-in before and its che
|
||||
|
||||
---
|
||||
|
||||
**See also:** [Reservations-and-Bookings](Reservations-and-Bookings) · [Day-Plans-and-Notes](Day-Plans-and-Notes) · [Transport-Flights-Trains-Cars](Transport-Flights-Trains-Cars) · [Road-Trip](Road-Trip)
|
||||
**See also**
|
||||
|
||||
- [Reservations-and-Bookings](Reservations-and-Bookings)
|
||||
- [Day-Plans-and-Notes](Day-Plans-and-Notes)
|
||||
- [Transport-Flights-Trains-Cars](Transport-Flights-Trains-Cars)
|
||||
- [Road-Trip](Road-Trip)
|
||||
|
||||
@@ -10,11 +10,11 @@ Each addon extends TREK with functionality beyond the core trip-planning feature
|
||||
|
||||
## Addon list
|
||||
|
||||
The following addons are registered in the system (defined in `server/src/db/seeders/AddonSeeder.ts`; the TypeScript constant `ADDON_IDS` in `server/src/addons.ts` covers all addons except `naver_list_import`):
|
||||
The following addons are registered in the system (defined in `server/src/db/seeders/AddonSeeder.ts`; the TypeScript constant `ADDON_IDS` in `server/src/addons.ts` covers all addons except `naver_list_import`). The admin panel groups `mcp`, `llm_parsing` and `ai_assistant` in one **AI** tile, see [Admin-Addons](Admin-Addons#the-ai-tile):
|
||||
|
||||
| Addon ID | Type | Description |
|
||||
|---|---|---|
|
||||
| `mcp` | integration | Exposes TREK data and actions through the Model Context Protocol for AI assistant integrations. |
|
||||
| `mcp` | integration | Exposes TREK data and actions through the Model Context Protocol for AI assistant integrations. Off by default. See [MCP-Overview](MCP-Overview). |
|
||||
| `packing` | trip | **Lists**: packing lists and to-do tasks for your trips. See [Packing-Lists](Packing-Lists). |
|
||||
| `budget` | trip | **Costs**: track and split trip expenses. See [Budget-Tracking](Budget-Tracking). |
|
||||
| `documents` | trip | Document and file attachments for trips: itineraries, visa copies and other files. Can be kept in step with a self-hosted document store (Paperless-ngx, Papra, Nextcloud, OpenCloud, Synology). See [Documents-and-Files](Documents-and-Files) and [Document-Sync](Document-Sync). |
|
||||
@@ -27,7 +27,8 @@ The following addons are registered in the system (defined in `server/src/db/see
|
||||
| `collections` | global | A personal, server-wide library of saved places in named lists, with idea/want/visited status, categories, and fusion sharing with per-member roles. See [Collections](Collections). |
|
||||
| `airtrail` | integration | Sync flights from your self-hosted AirTrail instance into trips. |
|
||||
| `dawarich` | integration | Read the stays and recorded routes of each user's own Dawarich instance, offered as suggestions to confirm. Read-only, nothing is written back. See [Dawarich](Dawarich). |
|
||||
| `llm_parsing` | integration | **AI Parsing**: an LLM fallback that extracts bookings from confirmation files KDE Itinerary can't read. With a model that reads images it also takes photos and scanned PDFs, and Costs gets **Scan receipt**. See [AI-Booking-Import](AI-Booking-Import) and [Budget-Tracking](Budget-Tracking#scanning-a-receipt). |
|
||||
| `llm_parsing` | integration | **AI Parsing**: an LLM fallback that extracts bookings from confirmation files KDE Itinerary can't read. With a model that reads images it also takes photos and scanned PDFs, and Costs gets **Scan receipt**. Off by default. See [AI-Booking-Import](AI-Booking-Import) and [Budget-Tracking](Budget-Tracking#scanning-a-receipt). |
|
||||
| `ai_assistant` | integration | **AI Assistant**: a chat in the trip that reads the plan and proposes changes you confirm. It runs on the same AI connection as AI Parsing. Off by default. |
|
||||
| `naver_list_import` | integration | Import places from shared Naver Maps lists directly into a trip. |
|
||||
|
||||
|
||||
@@ -39,4 +40,6 @@ The following addons are registered in the system (defined in `server/src/db/see
|
||||
|
||||
Some addons expose sub-features that an admin can independently toggle. The [Real-Time-Collaboration](Real-Time-Collaboration) addon, for example, lets an admin decide which of its five sub-features (chat, notes, links, polls, and what's next) are active across the instance. These are configured from the [Admin-Addons](Admin-Addons) panel alongside the addon's main toggle.
|
||||
|
||||
**Lists** has a **Bag Tracking** switch. **Journey** carries one switch per photo provider (Immich, Synology Photos). **Tours** carries switches for wanderer, the Hiking map (OpenHikingMap), the Cycling map (CyclOSM) and the Piste router.
|
||||
|
||||
The **Documents** addon carries one switch per document store: Paperless-ngx, Papra, Nextcloud, OpenCloud and Synology Drive. They are off by default and only show while Documents is on, and switching Documents off switches all of them off. The stores themselves are connected per trip, in the trip's file manager. See [Document-Sync](Document-Sync).
|
||||
|
||||
+46
-7
@@ -10,13 +10,15 @@ Each addon toggle controls a feature set. When you disable an addon, users lose
|
||||
|
||||
## Addon categories
|
||||
|
||||
Addons are grouped into three columns side by side: **Trip**, **Global** and **Integration**. Each column's head names the type with a short hint and counts how many of its addons are on, and the head of the **Addons** card shows the total as a pill (for example `9/14`; hover it for **{enabled} of {total} enabled**). Each addon is a tile with its icon, name, description and switch; its sub-toggles or settings open underneath the tile while it is on.
|
||||
The tab opens with a head card, **Addons**, that shows how many addons are on as a pill (for example `8/16`; hover it for **{enabled} of {total} enabled**). Under it sit three tiles, one per type (**Trip**, **Global** and **Integration**), each with its own count, then a **Search addons** field that finds an addon by name or description and an **All**, **On** and **Off** switch that filters the list.
|
||||
|
||||
Below the head card the addons are grouped in one card per type. From extra-wide screens the **Trip** card sits on the left and the **Global** and **Integration** cards are stacked on the right; on narrower screens all three are stacked. A card's head names the type with a short hint and counts how many of its addons are on. Each addon is a tile with its icon, name, description and switch; its sub-toggles open underneath the tile while it is on, and a long list is folded behind an options bar.
|
||||
|
||||
### Trip addons
|
||||
|
||||
Trip addons add per-trip feature panels. They appear in every trip where the addon is enabled.
|
||||
|
||||
The trip addons are: **Lists**, **Costs**, **Documents** and **Collab** (all enabled by default), and **Road trip** and **Tours** (disabled by default). The exact list is determined by what is registered in your TREK database.
|
||||
The trip addons are: **Lists**, **Costs**, **Documents**, **Collab** and **Tours** (all enabled by default), and **Road trip** (disabled by default). The exact list is determined by what is registered in your TREK database.
|
||||
|
||||
**Sub-toggles on trip addons:**
|
||||
|
||||
@@ -33,7 +35,14 @@ Each sub-toggle can be disabled independently while the parent addon remains ena
|
||||
|
||||
**Road trip** plans a trip as one continuous drive: search along the route, driving limits, daily travel times, via points and avoidance of toll roads, motorways and ferries. **Disabled by default.** It needs no key: routing runs on the public OSRM and Valhalla servers until you set your own under **User Defaults** (**Own routing engine**, **Own Valhalla instance**, restart required). See [Road-Trip](Road-Trip).
|
||||
|
||||
**Tours** plans hikes and paddle tours (kayak, canoe, SUP) as tours of their own and adds them to the days of a trip. **Disabled by default.** Underneath its tile, the **wanderer** sub-toggle lets users connect their own wanderer instance and import its trails. Each user can also switch on a background check of the trails they imported (Settings, Integrations, wanderer): TREK then reads the small record of each such trail at most once a day, never its GPX, and leaves a notification when the trail may have changed. It never changes a tour; taking a change in stays the user's own check and confirmed reimport. Switching wanderer off here stops those checks too.
|
||||
**Tours** plans hikes, bike rides, ski tours, paddle tours (kayak, canoe, SUP) and other tours as tours of their own and adds them to the days of a trip. **Enabled by default.** Underneath its tile are four switches that decide which outside services Tours may use:
|
||||
|
||||
- **wanderer**: lets users connect their own wanderer instance and import its trails. Each user can also switch on a background check of the trails they imported (Settings, Integrations, wanderer): TREK then reads the small record of each such trail at most once a day, never its GPX, and leaves a notification when the trail may have changed. It never changes a tour; taking a change in stays the user's own check and confirmed reimport. Switching wanderer off here stops those checks too.
|
||||
- **Hiking map (OpenHikingMap)**: offers OpenHikingMap as a base map in the tour planner. It is free for non-commercial installs up to 500,000 tiles a month; a commercial or larger install needs an agreement with openmaps.fr first.
|
||||
- **Cycling map (CyclOSM)**: offers CyclOSM as a base map for bike tours. OpenStreetMap France serves it for moderate use; a heavy or commercial install switches it off or reaches an agreement with the operator first.
|
||||
- **Piste router**: plans ski tours along runs, lifts and trails on the piste data of the Places server. Switched off, the legs of a ski tour are drawn straight.
|
||||
|
||||
Each of these changes is recorded in the [Audit-Log](Audit-Log).
|
||||
|
||||
#### Paddle water data
|
||||
|
||||
@@ -43,6 +52,14 @@ While **Tours** is on, a **Paddle water data** card appears under the addons. It
|
||||
2. Click **Add**. TREK downloads the extract in the background, reads the paddle objects out of it, builds the region's water network from the same read and deletes the file. The card shows the download, the reading and the building with their progress, without reloading the page. A large region takes a few minutes; regions are read one after another.
|
||||
3. Once the region is **Ready**, the card shows how many objects it holds, the date its data is current to and how many kilometres of water its network holds (lakes, mapped and assumed portages, locks and bridged gaps in its tooltip). A region read with an older TREK shows **No water network** until it is read again.
|
||||
|
||||
**Load regions automatically.** The card also decides what happens when someone plans a paddle tour where no water data exists yet:
|
||||
|
||||
- **Automatic** (the default): TREK loads the smallest matching region right away, up to **Largest region loaded automatically** (500 MB unless you change it) and at most five regions a day. Anything larger, or anything past the daily limit, waits in a **Requested** list. Only the region's name goes to Geofabrik, never the place.
|
||||
- **On request**: every new region waits in the **Requested** list until an admin lets it through. When an admin plans the tour, the region loads right away.
|
||||
- **Off**: TREK loads nothing by itself and asks for nothing; add regions by hand.
|
||||
|
||||
Each entry in **Requested** shows who asked and why it waits (**On request**, **Too large** or **Daily limit**). **Load** reads the region, **Decline** removes the request. Admins get a **Paddle region requested** notification when a request arrives, see [Admin-Notifications](Admin-Notifications). Regions TREK loaded by itself are tagged **Automatic**.
|
||||
|
||||
Paddle tours inside a region show its obstacles on the planner map, each with a card that says how it stands to the route, what paddling rule its tags give and how current the data is. Outside every region a paddle tour says that no obstacle data is known there; TREK never shows the water as free of obstacles.
|
||||
|
||||
**Routing on the water.** Inside a region the planner plans a paddle tour along rivers and canals and across lakes, the way it routes a hike on paths: set the put-in and the take-out, and the route follows the water. Where a weir, dam or waterfall bars the way it carries round it, on a mapped portage way where there is one and on a short straight carry where there is none, and it goes through open locks. A click on the route sets a shaping point that steers it, for example to one side of an island. Lakes are crossed straight over or near the shore, as each tour chooses; on a windy day the wind card suggests the shore. A leg TREK cannot plan, because a point lies off the water or between two regions, stays a straight red line until it is moved or drawn by hand on purpose. The router runs in a thread of the server itself; no other service is asked. Each region's network is a file in the data folder (a large region takes a few megabytes) and is built again with every read.
|
||||
@@ -58,7 +75,7 @@ Global addons add features that are not tied to a single trip. The default globa
|
||||
- **Vacay**: personal vacation day planner with calendar view. Enabled by default.
|
||||
- **Atlas**: world map of visited countries with travel stats. Enabled by default.
|
||||
- **Collections**: personal place library that saves places across trips into named lists, copies them into any trip, and shares them. **Disabled by default.** See [Collections](Collections).
|
||||
- **Journey**: trip tracking and travel journal (check-ins, photos, daily stories). **Disabled by default.**
|
||||
- **Journey**: trip tracking and travel journal (check-ins, photos, daily stories). **Disabled by default.** See [Journey-Journal](Journey-Journal).
|
||||
|
||||
**Sub-items on global addons:**
|
||||
|
||||
@@ -68,11 +85,26 @@ Global addons add features that are not tied to a single trip. The default globa
|
||||
|
||||
Integration addons connect TREK to external services. Most of them need additional configuration (API keys, URLs) once enabled, but not in the admin **Settings** tab: each one has its own place.
|
||||
|
||||
- The **MCP** addon requires `APP_URL` to be set in your environment. When enabled, the **MCP Access** tab appears in the Admin Panel. **Disabled by default.** See [MCP-Overview](MCP-Overview) for full details.
|
||||
- The **Naver List Import** addon imports the places of a shared Naver Maps list into a trip. **Enabled by default.** It needs no key.
|
||||
- The **AirTrail** addon syncs flights from a self-hosted AirTrail instance. **Disabled by default.** The toggle here is the instance-wide switch only; each user connects their own instance (URL + API key) in **Settings → Integrations**.
|
||||
- The **Dawarich** addon reads the stays and recorded routes of a self-hosted Dawarich instance and offers them as suggestions. **Disabled by default.** The toggle here is the instance-wide switch only; each user connects their own instance (address + API key) in **Settings → Integrations**. A Dawarich on your local network also needs `ALLOW_INTERNAL_NETWORK=true`. See [Dawarich](Dawarich).
|
||||
- The **AI Parsing** addon is the LLM fallback for booking imports KItinerary cannot read. **Disabled by default.** When enabled, its provider, base URL, API key, and model fields appear inline underneath the addon row, with **Model reads images** (**Automatic**, **Yes** or **No**). Automatic asks a local Ollama server whether the model reads images and means no for a cloud provider. When it resolves to yes, the booking import takes photos (JPG, PNG, WEBP) and scanned PDFs are read page by page, and Costs offers **Scan receipt**. Filling the fields in sets the instance-wide config for all users; leaving them blank lets each user configure their own provider in **Settings → Integrations**. See [AI-Booking-Import](AI-Booking-Import) and [Budget-Tracking](Budget-Tracking#scanning-a-receipt).
|
||||
- The three AI addons share one tile, described next.
|
||||
|
||||
#### The AI tile
|
||||
|
||||
**MCP**, **AI Parsing** and the **AI Assistant** do not have a tile each. They are one tile named **AI** at the head of the **Integration** card ("One connection for the assistant and booking import. MCP lets other AI apps use TREK."), with a pill that counts how many of the three are on and one switch row for each. All three are **disabled by default**.
|
||||
|
||||
- **AI Assistant**: a chat in the trip that reads the plan and proposes changes you confirm.
|
||||
- **AI Parsing**: the LLM fallback for booking imports KItinerary cannot read. See [AI-Booking-Import](AI-Booking-Import) and [Budget-Tracking](Budget-Tracking#scanning-a-receipt).
|
||||
- **MCP**: lets other AI apps use TREK through the Model Context Protocol. It requires `APP_URL` to be set in your environment. While it is on, the **MCP Access** tab appears in the Admin Panel. See [MCP-Overview](MCP-Overview) for full details.
|
||||
|
||||
Below the switches, **Set up AI** opens a dialog for the connection and limits. The button appears while the AI Assistant or AI Parsing is on; every change in the dialog saves at once. It has up to three tabs, and a tab only shows while its addon is on:
|
||||
|
||||
- **Connection**: **Who pays** is a choice of three. **I pay for everyone** gives everyone the connection below and they cannot add their own. **I pay, own allowed** does the same unless someone connects their own account. **Everyone uses their own account** charges nothing to you; each person connects a provider in **Settings → Integrations**. Unless everyone uses their own, **Connection for everyone** holds the shared connection: sign in with ChatGPT or OpenRouter, paste an API key (Anthropic, OpenAI, Gemini and others), or use **Own server**, any OpenAI-compatible server such as Ollama with its **Server address** and an optional API key. Pick the **Model**, and **Remove connection** takes it away again. If you share your own ChatGPT plan, a notice reminds you that everyone's chats count against it. A server on your own network goes through the relaxed guard, see [Internal-Network-Access](Internal-Network-Access).
|
||||
- **AI Assistant**: **Messages per person per day** (it only counts while you pay), **Keep chats** for 30 days, 90 days, 365 days or forever, and a **Web search** switch that lets the assistant look things up through the search of the AI provider it talks to (it works with ChatGPT, Anthropic and OpenRouter, and the searches go only to that provider).
|
||||
- **AI Parsing**: **Reads bookings with** shows whether parsing uses the shared connection or an **Own connection**. For an own connection pick a provider (**Local (Ollama)**, **OpenAI** or **Anthropic**), the base URL, API key and model, and set **Model reads images** (**Automatic**, **Yes** or **No**). Automatic asks a local Ollama server whether the model reads images and means no for a cloud provider. When it resolves to yes, the booking import takes photos (JPG, PNG, WEBP) and scanned PDFs are read page by page, and Costs offers **Scan receipt**. For a local Ollama the tab also lists the models **Installed on the server** and lets you **Pull a recommended model**. Leaving parsing without a connection of its own lets each user configure their own in **Settings → Integrations**.
|
||||
|
||||
The Settings screen of each user shows the matching **AI assistant** card, see [User-Settings](User-Settings#integrations-tab).
|
||||
|
||||
## Enabling or disabling an addon
|
||||
|
||||
@@ -87,8 +119,13 @@ Some addons require credentials or environment variables before they are functio
|
||||
- **Documents**: the document stores need nothing instance-wide beyond their switch. The trip owner enters a store's address and credentials in the trip's file manager. A store on your local network also needs `ALLOW_INTERNAL_NETWORK=true`. See [Document-Sync](Document-Sync) and [Internal-Network-Access](Internal-Network-Access).
|
||||
- **Journey**: works without any external integration. To embed photos from Immich or Synology Photos, enable the corresponding photo-provider toggle listed under Journey, then configure credentials per-user in **Settings → Integrations**. See [Photo-Providers](Photo-Providers).
|
||||
- **MCP**: requires `APP_URL` to be set so OAuth redirect URIs resolve correctly.
|
||||
- **AI Assistant** and **AI Parsing**: need a connection, either one shared for everyone under **Set up AI** or one per person in **Settings → Integrations**.
|
||||
- **Road trip**: works out of the box on the public routing servers. To use your own OSRM or Valhalla, set **Own routing engine** or **Own Valhalla instance** under **Admin → User Defaults**, then restart the server and reload the page. See [Road-Trip](Road-Trip#routing-engines).
|
||||
- **Tours**: hikes need nothing more. For the obstacles on paddle tours, add the regions you paddle in under **Paddle water data** (see above).
|
||||
- **Tours**: hikes need nothing more. For the obstacles on paddle tours, add the regions you paddle in under **Paddle water data** (see above), or let TREK load them.
|
||||
|
||||
## On a phone
|
||||
|
||||
The phone admin has the same addon list in its **Addons** section, with the same switches, the AI tile and the **Paddle water data** regions.
|
||||
|
||||
## Related pages
|
||||
|
||||
@@ -97,3 +134,5 @@ Some addons require credentials or environment variables before they are functio
|
||||
- [MCP-Overview](MCP-Overview)
|
||||
- [Addons-Overview](Addons-Overview)
|
||||
- [Document-Sync](Document-Sync)
|
||||
- [AI-Connections](AI-Connections)
|
||||
- [Wanderer](Wanderer)
|
||||
|
||||
@@ -21,7 +21,7 @@ Click **New Category** (top right of the card). A dialog opens:
|
||||
2. **Icon**: a grid of 47 curated Lucide icons (Pin, Hotel, Restaurant, Transport, Nature and so on). Click an icon to select it. The default icon is `MapPin`.
|
||||
3. **Color**: 12 preset swatches plus **Choose custom color** (pipette button). The default color is `#6366f1` (indigo). The 12 presets are:
|
||||
|
||||
`#6366f1` · `#8b5cf6` · `#ec4899` · `#ef4444` · `#f97316` · `#f59e0b` · `#10b981` · `#06b6d4` · `#3b82f6` · `#84cc16` · `#6b7280` · `#1f2937`
|
||||
`#6366f1`, `#8b5cf6`, `#ec4899`, `#ef4444`, `#f97316`, `#f59e0b`, `#10b981`, `#06b6d4`, `#3b82f6`, `#84cc16`, `#6b7280`, `#1f2937`
|
||||
|
||||
4. **Preview**: a chip shows how the category will look to users as you make selections.
|
||||
|
||||
@@ -43,6 +43,10 @@ When a user adds a place from the search or from a map POI, TREK picks the match
|
||||
|
||||
Categories are always displayed in alphabetical order by name. There is no manual reordering.
|
||||
|
||||
## On a phone
|
||||
|
||||
The phone admin has the same card in its **Personalization** section, with the same create, edit and delete steps.
|
||||
|
||||
## Related pages
|
||||
|
||||
- [Places-and-Search](Places-and-Search)
|
||||
|
||||
@@ -19,7 +19,7 @@ The **About** card at the top of the tab holds six tiles that link to external r
|
||||
|
||||
## Release timeline
|
||||
|
||||
Below it, the **Release History** card holds a chronological timeline lists GitHub releases for the `liketrek/TREK` repository. Each entry shows:
|
||||
Below it, the **Release History** card ("Latest updates from liketrek/TREK", with a GitHub button in its head) holds a chronological timeline of GitHub releases for the `liketrek/TREK` repository. Each entry shows:
|
||||
|
||||
- **Version tag** (e.g., `v2.9.14`)
|
||||
- A **Latest** badge on the first (most recent) entry in the displayed list, and a **Pre-release** badge on pre-releases
|
||||
@@ -28,7 +28,7 @@ Below it, the **Release History** card holds a chronological timeline lists GitH
|
||||
|
||||
Pre-release entries are hidden unless the server has both found a newer version and is itself running a pre-release. In every other case, including a pre-release install that is already on the newest pre-release, the timeline shows stable releases only.
|
||||
|
||||
Releases load 10 at a time. Click **Load more** at the bottom of the timeline to fetch additional pages.
|
||||
Releases load 10 at a time. Click **Load more** at the bottom of the timeline to fetch additional pages. While pre-releases are hidden, one load may read up to five pages so that it does not come back empty when the newest releases are all pre-releases.
|
||||
|
||||
If the admin API request fails, the card shows **Failed to load releases**. If the server cannot reach the GitHub API, the timeline displays no releases (the server returns an empty list rather than an error).
|
||||
|
||||
@@ -40,7 +40,7 @@ Results are cached for 5 minutes to avoid repeated API calls.
|
||||
|
||||
## Release notes notice
|
||||
|
||||
After an update, every user is shown a **release notes** notice once: a modal on the desktop with what the release brought (three headline cards), a note from the maintainer, the support links and a **Release notes** link to the release on GitHub. Closing it keeps it closed for the version that is running; the next version brings it back once, a patch release included. It replaces the 4.0.0 notice. There is no switch for it in the admin panel.
|
||||
After an update, every user is shown a **release notes** notice once: a modal on the desktop with what the release brought (a few headline cards), a note from the maintainer, the support links and a **Release notes** link to the release on GitHub. Closing it keeps it closed for the version that is running; the next version brings it back once, a patch release included. There is no switch for it in the admin panel. The phone has its own onboarding instead.
|
||||
|
||||
## When to check
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
The **MCP Access** tab (in the **Integrations** group of the admin side navigation) shows all active MCP OAuth sessions and API tokens across every user on the instance. As an admin you can revoke sessions and delete tokens.
|
||||
|
||||
This panel is only visible when the **MCP addon** is enabled in the [Admin-Addons](Admin-Addons) panel.
|
||||
This panel is only visible when the **MCP** addon is enabled. MCP is one of the three switches in the **AI** tile on the **Integration** card of the [Admin-Addons](Admin-Addons#the-ai-tile) tab. The phone admin has the same lists in its **MCP Access** section.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -44,11 +44,13 @@ In-app notifications are always active and cannot be switched off for the whole
|
||||
|
||||
### Trip Reminders
|
||||
|
||||
Sends a reminder notification before a trip starts, to trips that have reminder days set. **On by default.** The check runs once a day and picks trips that start exactly that many days later. When it is off, the reminder section of a trip is greyed out with a note that reminders are disabled. See [Creating-a-Trip](Creating-a-Trip).
|
||||
Sends a reminder notification before a trip starts, to trips that have reminder days set. **On by default.** The check runs once a day at 09:00 server time. It reminds a trip once the reminder day has come and the trip has not started; a day the server was down is caught up on the next run, and a trip moved to a new start date is reminded again. When it is off, the reminder section of a trip is greyed out with a note that reminders are disabled. See [Creating-a-Trip](Creating-a-Trip).
|
||||
|
||||
The same run at 09:00 also sends the **to-do due** reminders for unchecked to-dos that fall due within the next three days. They have no switch of their own here; each user decides in their notification settings whether to receive them.
|
||||
|
||||
## Admin alerts
|
||||
|
||||
Admin-only notifications, such as a new TREK version or a failed write to a storage replica, go to the admin's own targets. These are separate from the users' webhooks and topics.
|
||||
Admin-only notifications, such as a new TREK version, a failed write to a storage replica or a request for paddle water data, go to the admin's own targets. These are separate from the users' webhooks and topics.
|
||||
|
||||
### Admin Webhook
|
||||
|
||||
@@ -66,7 +68,7 @@ An ntfy topic used only for admin notifications. It always fires when a topic is
|
||||
|
||||
### Notifications
|
||||
|
||||
The matrix under the admin targets sets which channels deliver each admin-only event: **New version available** and **Storage replica failure**. Columns appear only for channels that can reach the admin: **In-App** always, **Email** once SMTP is configured, **Webhook** once an admin webhook URL is saved, **Ntfy** once an admin topic is saved. Every cell is a switch, on by default, and saves at once. A dash means that event cannot go out on that channel. Admin alerts are never sent as Web Push.
|
||||
The matrix under the admin targets sets which channels deliver each admin-only event: **New version available**, **Storage replica failure** and **Paddle region requested** (sent when a paddle region waits for your decision, see [Admin-Addons](Admin-Addons#paddle-water-data)). Columns appear only for channels that can reach the admin: **In-App** always, **Email** once SMTP is configured, **Webhook** once an admin webhook URL is saved, **Ntfy** once an admin topic is saved. Every cell is a switch, on by default, and saves at once. A dash means that event cannot go out on that channel. Admin alerts are never sent as Web Push.
|
||||
|
||||
## Defaults for users
|
||||
|
||||
@@ -82,10 +84,14 @@ Each cell is a pill that cycles through three states when clicked, and saves at
|
||||
|
||||
A default applies to every user who has not changed that cell themselves, including users who joined before you set it, so a later change reaches them too. A cell a user switched keeps the user's choice, unless you block it. The events themselves are listed in [Notifications](Notifications#notification-events).
|
||||
|
||||
## On a phone
|
||||
|
||||
The phone admin has the same settings in its **Notifications** section: the channels, the admin targets and alerts, and the **Defaults for users** matrix.
|
||||
|
||||
## See also
|
||||
|
||||
- [Notifications](Notifications) - the per-user side: channels, events, webhook and ntfy setup, Web Push
|
||||
- [Admin-Panel-Overview](Admin-Panel-Overview) - all admin tabs
|
||||
- [Environment-Variables](Environment-Variables) - SMTP and Web Push variables
|
||||
- [Creating-a-Trip](Creating-a-Trip) - setting a trip's reminder
|
||||
- [Admin-Storage](Admin-Storage) - storage replicas and their failure alerts
|
||||
- [Notifications](Notifications): the per-user side: channels, events, webhook and ntfy setup, Web Push
|
||||
- [Admin-Panel-Overview](Admin-Panel-Overview): all admin tabs
|
||||
- [Environment-Variables](Environment-Variables): SMTP and Web Push variables
|
||||
- [Creating-a-Trip](Creating-a-Trip): setting a trip's reminder
|
||||
- [Admin-Storage](Admin-Storage): storage replicas and their failure alerts
|
||||
|
||||
@@ -23,10 +23,10 @@ Templates are instance-wide. Besides the ones you build here, the list also show
|
||||
The template list shows each template as a collapsible row displaying:
|
||||
|
||||
- Template name
|
||||
- Category count and item count (e.g., `3 categories · 12 items`)
|
||||
- Category count and item count (for example 3 categories and 12 items)
|
||||
- Rename and delete buttons
|
||||
|
||||
Inside an expanded template, an item shows its quantity, weight and bag next to its name when it has them (for example `2× · 300 g · Backpack`). These values come from the trip list the template was saved from; items you add here start with none of them.
|
||||
Inside an expanded template, an item shows its quantity, weight and bag next to its name when it has them (for example 2×, 300 g, Backpack). These values come from the trip list the template was saved from; items you add here start with none of them.
|
||||
|
||||
## Creating a template
|
||||
|
||||
@@ -52,9 +52,11 @@ All editing is inline:
|
||||
|
||||
## Deleting
|
||||
|
||||
- **Delete a template**: click the trash icon on the template row. The template is removed at once, without a confirmation. This does not affect trips that already had items from this template applied.
|
||||
- **Delete a category**: click the trash icon in the category header. All items in that category are also deleted from the template.
|
||||
- **Delete an item**: hover the item row to reveal the trash icon.
|
||||
- **Delete a template**: click the trash icon on the template row and confirm (**Delete the template "{name}" with all its categories and items?**). This does not affect trips that already had items from this template applied.
|
||||
- **Delete a category**: click the trash icon in the category header. A category that still has items asks first (**Delete the category "{name}" and all its items?**) and removes the items with it; an empty category goes at once.
|
||||
- **Delete an item**: hover the item row to reveal the trash icon. It goes at once.
|
||||
|
||||
The phone admin has the same card in its **Personalization** section.
|
||||
|
||||
## Applying templates to a trip
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@ Open the user menu in the top navigation bar (your avatar), then select **Admin*
|
||||
|
||||
## Layout
|
||||
|
||||
On desktop the page opens with a header (**Administration**, *User management and system settings*) whose right side shows four counters: **Users**, **Trips**, **Places** and **Files**. When a newer TREK release exists, an update banner sits below it. Under that, a side navigation on the left lists the tabs in four groups, and the selected tab fills the right side. Every tab is built from cards with toggle rows, and anything that needs confirming (deleting a user, restoring a backup, revoking a token) asks in TREK's own dialog rather than the browser's.
|
||||
On desktop the page opens with a header (**Administration**, *User management and system settings*) whose right side shows four counters: **Users**, **Trips**, **Places** and **Files**. When a newer TREK release exists, an update banner sits below it, with a **How to Update** button that opens a dialog with the update commands for your kind of install and a link to the update guide. On a demo instance a **Demo Baseline** card with a **Save Baseline** button sits there too, see [Demo-Mode](Demo-Mode). Under that, a side navigation on the left lists the tabs in four groups, and the selected tab fills the right side. Every tab is built from cards with toggle rows, and anything that needs confirming (deleting a user, restoring a backup, revoking a token) asks in TREK's own dialog rather than the browser's.
|
||||
|
||||
On a phone the admin is a separate screen: the same four counters sit at the top and a section picker switches between the same sections (users, user defaults, personalization, settings, addons, plugins, storage, notifications, MCP, GitHub, backup, audit). Each section offers what its desktop tab offers, including the permissions panel within the users section.
|
||||
|
||||
## Tabs
|
||||
|
||||
@@ -22,7 +24,7 @@ Most tabs are always visible; a few appear only under specific conditions.
|
||||
| Users | **User Defaults** | Default settings applied to users who have not picked their own: colour mode, units, time format, currency, week start, blurred booking codes, map engine and the routing services. See [Admin-User-Defaults](Admin-User-Defaults) | No |
|
||||
| Configuration | **Personalization** | Packing templates, place categories and the manually maintained school holiday catalog (see [Vacay](Vacay#manually-maintained-school-holidays)) | No |
|
||||
| Configuration | **Settings** | Authentication methods (password and SSO login and registration), passkeys, required MFA, OIDC/SSO configuration, allowed file types, API keys and place providers (Google, Unsplash, Amap, public transit backend, place search provider, the **Daily limit for Google calls**), and **Rotate JWT Secret**. See [Admin-Settings](Admin-Settings) | No |
|
||||
| Configuration | **Addons** | Enable or disable optional features instance-wide. See [Admin-Addons](Admin-Addons) | No |
|
||||
| Configuration | **Addons** | Enable or disable optional features instance-wide, and manage the **Paddle water data** regions below the addon cards. See [Admin-Addons](Admin-Addons) | No |
|
||||
| Configuration | **Plugins** | Install, update, and manage plugins; rescan the plugins folder; view each plugin's error log. See [Admin-Plugins](Admin-Plugins) | No |
|
||||
| Configuration | **Storage** | Storage backends, category assignment, replication, health. See [Admin-Storage](Admin-Storage) | No |
|
||||
| Integrations | **Notifications** | Email (SMTP), webhook, ntfy and Web Push channels; trip reminders; the admin's own webhook and ntfy; **Defaults for users** (see below). See [Admin-Notifications](Admin-Notifications) | No |
|
||||
|
||||
@@ -61,12 +61,15 @@ Actions are grouped into five sections. Each row shows the action's name, a hint
|
||||
| `packing_edit` | **Manage packing lists** | Manage packing items and bags | Trip members | Trip owner, Trip members |
|
||||
| `collab_edit` | **Collaboration (notes, polls, chat)** | Create notes, polls, and send messages | Trip members | Trip owner, Trip members |
|
||||
| `share_manage` | **Manage share links** | Read, create or delete public share links and calendar feed links | Trip owner | Trip owner, Trip members |
|
||||
| `journal_link` | **Link a journal** | Link a journal from Journey to the trip and open it to its members | Trip owner | Trip owner, Trip members |
|
||||
|
||||
## Changing permissions
|
||||
|
||||
Each action row has a dropdown. Select the minimum role level required. A **customized** badge appears next to any action that differs from its default.
|
||||
|
||||
Click **Save** (top right of the card) to persist your changes; it stays disabled until something has changed. **Reset to defaults** (circular arrow icon) puts every action back to its shipped default in the form without saving: click **Save** afterwards if you want to keep the reset.
|
||||
Click **Save** (in the head of the card) to persist your changes; it stays disabled until something has changed. **Reset to defaults**, next to it, puts every action back to its shipped default in the form without saving: click **Save** afterwards if you want to keep the reset.
|
||||
|
||||
The phone admin shows the same panel below the user list in its **Users** section.
|
||||
|
||||
## Related pages
|
||||
|
||||
|
||||
+35
-31
@@ -8,7 +8,7 @@ Install, review, enable, update, and remove third-party plugins on your instance
|
||||
|
||||
Open the **Admin Panel** and select the **Plugins** tab (in the **Configuration** group of the side navigation). *Install and manage third-party plugins on your instance.*
|
||||
|
||||
> **Admin:** This whole panel is admin-only. It also needs the plugin runtime turned on — otherwise you get *Plugins are disabled*: **The plugin runtime is turned off (`TREK_PLUGINS_ENABLED`). No plugin can run until an admin enables it in the server configuration.** When the runtime is on, a green **Runtime on** pill appears in the header.
|
||||
> **Admin:** This whole panel is admin-only. It also needs the plugin runtime turned on, otherwise you get *Plugins are disabled*: **The plugin runtime is turned off (`TREK_PLUGINS_ENABLED`). No plugin can run until an admin enables it in the server configuration.** When the runtime is on, a green **Runtime on** pill appears in the header.
|
||||
|
||||
For what plugins are and how users interact with them, see [Plugins](Plugins).
|
||||
|
||||
@@ -16,10 +16,10 @@ For what plugins are and how users interact with them, see [Plugins](Plugins).
|
||||
|
||||
A segmented switch at the top toggles between:
|
||||
|
||||
- **Installed** — what is on this instance, with a count.
|
||||
- **Discover** — the community registry, browsable as cards.
|
||||
- **Installed**: what is on this instance, with a count.
|
||||
- **Discover**: the community registry, browsable as cards.
|
||||
|
||||
Both views share a toolbar: a **Search plugins…** box, a **Type** filter (Widget / Page / Integration / Trip page), a **Sort** menu, an **Upload plugin** button, and a **Rescan** button. The **Installed** view adds a **Status** filter (Active / Off / Update available / Error).
|
||||
Both views share a toolbar: a **Search plugins…** box, a **Type** filter (Widget / Page / Integration / Trip page) and a **Sort** menu (**Name**, **Recently updated**, **Updates first** or **Most downloads**). The **Installed** view adds a **Status** filter (Active / Off / Update available / Error). In the head of the card, two icon buttons named by their tooltips, **Upload plugin** and **Rescan**, sit beside the **Runtime on** pill.
|
||||
|
||||
**Rescan** does two things: it rediscovers locally-installed plugins *and* force-pulls the registry, bypassing the 30-minute server cache and GitHub's CDN, so a just-published plugin shows up immediately instead of up to ~35 minutes later.
|
||||
|
||||
@@ -29,7 +29,7 @@ Both views share a toolbar: a **Search plugins…** box, a **Type** filter (Widg
|
||||
2. Click a card to open the **pre-install review dialog** (see below).
|
||||
3. Click **Install**.
|
||||
|
||||
If the newest release does not support the TREK you are running — either it needs a newer one, or your TREK has outgrown the upper bound it declares (`>=3.2.0 <4.0.0` on TREK 4, say) — the button changes: when an older release still fits you get **Install {version}** for that one; when nothing fits, the button reads **Incompatible** and is disabled. Either way the dialog explains why in an amber note — it does not hide the reason behind a tooltip.
|
||||
If the newest release does not support the TREK you are running, the button changes. This happens when it needs a newer TREK, or when your TREK has outgrown the upper bound it declares (`>=3.2.0 <4.0.0` on TREK 4, say). Then: when an older release still fits you get **Install {version}** for that one; when nothing fits, the button reads **Incompatible** and is disabled. Either way the dialog explains why in an amber note; it does not hide the reason behind a tooltip.
|
||||
|
||||
A newly installed plugin is **off**. Nothing runs until you enable it.
|
||||
|
||||
@@ -37,38 +37,38 @@ A newly installed plugin is **off**. Nothing runs until you enable it.
|
||||
|
||||
Before installing, read these sections:
|
||||
|
||||
- **What it can access** — a plain-language summary of what the plugin's permissions let it do ("Reads your trips", "Edits places", "Provides photos"), plus a line for its own isolated database. It is a summary, not the raw permission list: permissions TREK has no summary line for — `notify:send`, `ai:invoke`, `jobs:run`, `db:write:members` and others — do not appear here at all, and a plugin that asks only for those still reads *Needs no special access.* For the complete list, read the manifest in the plugin's source repository. Only the consent dialog for an update renders permissions code by code, unknown codes verbatim.
|
||||
- **What it can access**: a plain-language summary of what the plugin's permissions let it do ("Reads your trips", "Edits places", "Provides photos"), plus a line for its own isolated database. It is a summary, not the raw permission list: permissions TREK has no summary line for (`notify:send`, `ai:invoke`, `jobs:run`, `db:write:members` and others) do not appear here at all, and a plugin that asks only for those still reads *Needs no special access.* For the complete list, read the manifest in the plugin's source repository. Only the consent dialog for an update renders permissions code by code, unknown codes verbatim.
|
||||
- **Map categories it adds**: for a plugin that asks for `hook:poi-category-provider`, each button it would add to the category row on the trip map (see [Places and Search](Places-and-Search#categories-from-plugins)), with its icon on its colour and its name in your language. The access list above reads *Adds map categories* for the same permission, and so does a chip on the plugin's row once it is installed. A plugin that declares categories without asking for the permission shows no list, because its buttons would never appear. The consent dialog of an update that adds the permission spells out what it shares: *Add its own place categories to Explore places on the map; picking one sends the plugin the map area you are viewing.*
|
||||
- A plugin that asks for `hook:search-provider` reads **Answers searches** in the access list: its own index answers place searches beside TREK's results, and a plugin built for it also answers while the search is still being typed, with its places marked with the plugin's name (see [Places and Search](Places-and-Search#suggestions-while-you-type)).
|
||||
- **Connects to** — every host the manifest declares it may reach, as monospace chips.
|
||||
- **Setup** — settings the plugin will ask you (or each user) to fill in, tagged **Instance-wide** or **Per user**, and **Required** where applicable.
|
||||
- **Details** — version, size, the TREK version range it requires, when it was reviewed, and total downloads.
|
||||
- **Connects to**: every host the manifest declares it may reach, as monospace chips.
|
||||
- **Setup**: settings the plugin will ask you (or each user) to fill in, tagged **Instance-wide** or **Per user**, and **Required** where applicable.
|
||||
- **Details**: version, size, the TREK version range it requires, when it was reviewed, and total downloads.
|
||||
|
||||
A footer links to the **Source repository**, **Report an issue**, and the plugin's **Homepage**.
|
||||
|
||||
### Operator egress hosts
|
||||
|
||||
Some plugins talk to a service only *you* can name — a self-hosted Gotify, ntfy, or similar. Their manifest cannot list a host, so the review dialog adds a **+ hosts you add** chip and this note:
|
||||
Some plugins talk to a service only *you* can name; a self-hosted Gotify, ntfy, or similar. Their manifest cannot list a host, so the review dialog adds a **+ hosts you add** chip and this note:
|
||||
|
||||
> *This plugin talks to a service only you can name. After installing, add the hosts it may reach under ⋯ → Allowed hosts. It can reach no others.*
|
||||
|
||||
After install, open the row's **⋯ → Allowed hosts** dialog and add hostnames one at a time. Until you add at least one, the plugin's row shows an amber **Add allowed host** chip, because it can reach nothing and would otherwise look silently broken. Once hosts exist the chip turns blue and counts them.
|
||||
|
||||
Saving restarts the plugin so it picks up the new list — a running plugin's allow-list can never be widened in place.
|
||||
Saving restarts the plugin so it picks up the new list; a running plugin's allow-list can never be widened in place.
|
||||
|
||||
## Enabling, restarting, and disabling
|
||||
|
||||
Each installed row has a toggle (**Enable plugin**) and shows **Active** or **Off**. A coloured dot on the icon tile reflects runtime health: green when the plugin is active, a pulsing blue while it starts, red when it has errored, grey when it is not running. Incompatibility is not a dot colour — a plugin this TREK cannot run gets an amber chip on the row instead.
|
||||
Each installed row has a toggle (**Enable plugin**) and shows **Active** or **Off**. A coloured dot on the icon tile reflects runtime health: green when the plugin is active, a pulsing blue while it starts, red when it has errored, grey when it is not running. Incompatibility is not a dot colour; a plugin this TREK cannot run gets an amber chip on the row instead.
|
||||
|
||||
Enabling can be refused for good reasons. The first three are version gates that run before everything else — a plugin that cannot run on this TREK is never offered a permission dialog, because consenting would not make it start:
|
||||
Enabling can be refused for good reasons. The first three are version gates that run before everything else; a plugin that cannot run on this TREK is never offered a permission dialog, because consenting would not make it start:
|
||||
|
||||
- **This TREK is outside the range the plugin declares** — the row carries an amber *Needs TREK {range} — this server runs {host}* chip and the toggle is refused. Expect this after a major upgrade: a plugin that declared `>=3.2.0 <4.0.0` stops activating on TREK 4 even though it ran fine the day before. There is no dialog to click through, it takes a release from the author that admits this TREK — and once the registry has one, the row's **Update** button offers it.
|
||||
- **The plugin does not say which TREK versions it supports** — the chip reads *Does not say which TREK versions it supports*. That is a plugin folder which predates the range field or was dropped into the plugins directory by hand: **Rescan** registers it rather than letting it vanish silently, and the gate then refuses it instead of guessing. It needs a manifest with a `trek` range.
|
||||
- **Version checks off** — the operator set `TREK_PLUGINS_IGNORE_TREK_RANGE` (see [Environment Variables](Environment-Variables)), and the header shows an amber *Version checks off* pill. The two cases above then stop being blockers: the row carries an amber *Outside its TREK range ({range}) — version checks off* (or *Declares no TREK range — version checks off*) chip for as long as the plugin runs here, but the toggle works. In Discover, an entry the registry marks incompatible gets an **Install anyway** button instead of a dead one; pressing it opens a warning first — the author has not updated the plugin's range for this TREK, nothing guarantees it works, and in rare cases a mismatched plugin can corrupt TREK data — and only **Install anyway** in that dialog sends the request. A sideload, dev-link, update or dependency download that lands outside its range cannot ask first, so the same warning appears right after it succeeds. The bypass never lifts the plugin-API version gate.
|
||||
- **The plugin needs a newer plugin API** — its manifest's `apiVersion` is higher than the plugin API this TREK implements (currently v1). Install, upload, and dev-link reject that up front, so this only shows for a plugin picked up from the plugins directory on disk — registered at the next restart, or when you press **Rescan**.
|
||||
- **A required addon is disabled** — a toast names the addon; turn it on in [Admin-Addons](Admin-Addons).
|
||||
- **A plugin dependency is missing or outdated** — a dialog lists each dependency with a one-click **Download** / **Update** that installs the newest compatible version and then retries.
|
||||
- **The update widened its permissions** — the consent dialog (below).
|
||||
- **This TREK is outside the range the plugin declares**: the row carries an amber *Needs TREK {range}* chip that also names the version this server runs, and the toggle is refused. Expect this after a major upgrade: a plugin that declared `>=3.2.0 <4.0.0` stops activating on TREK 4 even though it ran fine the day before. There is no dialog to click through: it takes a release from the author that admits this TREK, and once the registry has one, the row's **Update** button offers it.
|
||||
- **The plugin does not say which TREK versions it supports**: the chip reads *Does not say which TREK versions it supports*. That is a plugin folder which predates the range field or was dropped into the plugins directory by hand: **Rescan** registers it rather than letting it vanish silently, and the gate then refuses it instead of guessing. It needs a manifest with a `trek` range.
|
||||
- **Version checks off**: the operator set `TREK_PLUGINS_IGNORE_TREK_RANGE` (see [Environment Variables](Environment-Variables)), and the header shows an amber *Version checks off* pill. The two cases above then stop being blockers: the row carries an amber chip for as long as the plugin runs here, saying the plugin is *Outside its TREK range ({range})* (or *Declares no TREK range*) and that version checks are off, but the toggle works. In Discover, an entry the registry marks incompatible gets an **Install anyway** button instead of a dead one; pressing it opens a warning first (the author has not updated the plugin's range for this TREK, nothing guarantees it works, and in rare cases a mismatched plugin can corrupt TREK data) and only **Install anyway** in that dialog sends the request. A sideload, dev-link, update or dependency download that lands outside its range cannot ask first, so the same warning appears right after it succeeds. The bypass never lifts the plugin-API version gate.
|
||||
- **The plugin needs a newer plugin API**: its manifest's `apiVersion` is higher than the plugin API this TREK implements (currently v1). Install, upload, and dev-link reject that up front, so this only shows for a plugin picked up from the plugins directory on disk, registered at the next restart, or when you press **Rescan**.
|
||||
- **A required addon is disabled**: a toast names the addon; turn it on in [Admin-Addons](Admin-Addons).
|
||||
- **A plugin dependency is missing or outdated**: a dialog lists each dependency with a one-click **Download** / **Update** that installs the newest compatible version and then retries.
|
||||
- **The update widened its permissions**: the consent dialog (below).
|
||||
|
||||
Installed-but-disabled dependencies are enabled automatically as a cascade, and a toast tells you which.
|
||||
|
||||
@@ -84,34 +84,38 @@ If the new version requests rights you have not granted, TREK installs it but le
|
||||
|
||||
The dialog lists **Newly requested permissions** and **New outbound connections**. Choose **Approve & turn on** or **Keep off for now**. Updating several plugins at once queues these prompts, so none is skipped. If the version being approved is unsigned, the dialog adds a line saying nothing ties it to its author.
|
||||
|
||||
### Changing the version
|
||||
|
||||
**⋯ → Change version…** (registry plugins only) lists the versions the registry has published, each with a **Switch to {version}** button and a note when it needs a different TREK. Picking an older one asks first (**Roll back this plugin?**: data written by the newer version stays in place, and the older version may not understand it) and installs it after you press **Roll back**. A deliberate pick other than the newest version holds that plugin there: its row reads **Updates paused at v{version}** with a **Resume updates** link, and it is left out of the update banner and **Update all** until you resume or move to the newest version.
|
||||
|
||||
### Blocked updates
|
||||
|
||||
If an author's signing key no longer matches the one pinned at install, the update is refused and the row shows **Update blocked — {reason}** with a **Review** link. The dialog then shows the pinned key fingerprint next to the offered one:
|
||||
If an author's signing key no longer matches the one pinned at install, the update is refused and the row shows **Update blocked** and the reason, with a **Review** link. The dialog then shows the pinned key fingerprint next to the offered one:
|
||||
|
||||
> *TREK cannot tell a legitimate key rotation apart from a takeover — both look identical from here. Confirm the new key with the author through a channel you already trust before you accept it.*
|
||||
> *TREK cannot tell a legitimate key rotation apart from a takeover; both look identical from here. Confirm the new key with the author through a channel you already trust before you accept it.*
|
||||
|
||||
Only a **changed key** can be overridden (**Trust the new key & update**). A signature that is invalid, missing, or half-declared gets an explanation and **no override button at all** — the server refuses those too.
|
||||
Only a **changed key** can be overridden (**Trust the new key & update**). A signature that is invalid, missing, or half-declared gets an explanation and **no override button at all**; the server refuses those too.
|
||||
|
||||
## Uninstalling
|
||||
|
||||
**⋯ → Delete** asks **Uninstall plugin?** — *This stops the plugin, removes its code, and deletes all of its data. This cannot be undone.*
|
||||
**⋯ → Delete** asks **Uninstall plugin?** (*This stops the plugin, removes its code, and deletes all of its data. This cannot be undone.*)
|
||||
|
||||
## Badges: what they do and do not guarantee
|
||||
|
||||
- **Reviewed** — *"Reviewed" means a TREK maintainer scanned this plugin for malware on each version — not for quality or whether it works. It is not a guarantee that a plugin is harmless.*
|
||||
- **Signed** — the files were verified against the author's signing key at install, and that key is pinned. A checksum already proves the files are what the *registry* vouches for; a signature proves they came from the *author*.
|
||||
- **Unsigned** — *The files match what the registry vouches for, but nothing ties them to the author. One guarantee fewer — not unsafe.* Most registry plugins are unsigned today, which is why this is an amber note rather than an alarm.
|
||||
- **Reviewed**: a TREK maintainer scanned this plugin for malware on each version, not for quality or whether it works. It is not a guarantee that a plugin is harmless.
|
||||
- **Signed**: the files were verified against the author's signing key at install, and that key is pinned. A checksum already proves the files are what the *registry* vouches for; a signature proves they came from the *author*.
|
||||
- **Unsigned**: *The files match what the registry vouches for, but nothing ties them to the author. One guarantee fewer, not unsafe.* Most registry plugins are unsigned today, which is why this is an amber note rather than an alarm.
|
||||
|
||||
Neither badge says anything about what the code *does*. A collapsible **How plugins are contained — and the limits** panel at the bottom of the tab spells out the isolation model, what permissions really constrain, what TREK cannot promise, and the worst case. Read it once.
|
||||
Neither badge says anything about what the code *does*. A collapsible panel at the bottom of the tab, titled **How plugins are contained**, spells out the isolation model, what permissions really constrain, what TREK cannot promise, and the worst case. Read it once.
|
||||
|
||||
## Sideloading and dev-linking
|
||||
|
||||
Two paths install a plugin that never went through the registry:
|
||||
|
||||
- **Upload plugin** (toolbar button, or drag a `.zip` onto the panel) — installs the archive **inactive**; you still consent on activation. The row is marked **Sideloaded**: *Uploaded manually — not from the registry, unsigned and unreviewed.*
|
||||
- **Link a local plugin** — a path field that registers a plugin from a local build directory and hot-reloads it against real data. Dev only, and only shown when the server sets `TREK_PLUGINS_DEV_LINK=1`. The row is marked **Dev-Link**.
|
||||
- **Upload plugin** (toolbar button, or drag a `.zip` onto the panel): installs the archive **inactive**; you still consent on activation. The row is marked **Sideloaded**: *Uploaded manually, not from the registry, unsigned and unreviewed.*
|
||||
- **Link a local plugin**: a path field that registers a plugin from a local build directory and hot-reloads it against real data. Dev only, and only shown when the server sets `TREK_PLUGINS_DEV_LINK=1`. The row is marked **Dev-Link**.
|
||||
|
||||
Be honest with yourself about what these badges mean: both are only a *label on the card*. They record where the code came from — they do not check, sandbox differently, or restrict it. A sideloaded or dev-linked plugin runs with exactly the permissions it declares, same as a registry one, and it received no malware scan and carries no signature. The badge is there so you can tell at a glance that no one but you vouched for that code. (The source badge also replaces the Signed/Unsigned badge on those rows, since it already says something stronger.)
|
||||
Be honest with yourself about what these badges mean: both are only a *label on the card*. They record where the code came from; they do not check, sandbox differently, or restrict it. A sideloaded or dev-linked plugin runs with exactly the permissions it declares, same as a registry one, and it received no malware scan and carries no signature. The badge is there so you can tell at a glance that no one but you vouched for that code. (The source badge also replaces the Signed/Unsigned badge on those rows, since it already says something stronger.)
|
||||
|
||||
## Permissions
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
The **Settings** tab (in the **Configuration** group of the admin side navigation, `/admin?tab=settings`) holds the instance-wide switches for signing in, uploads and place data. On a wide screen the cards sit in two columns: access and identity on the left (**Authentication Methods**, **Passkey login**, **Require two-factor authentication (2FA)**, **Single Sign-On (OIDC)**), files and place data on the right (**Allowed File Types**, **API Keys**). The **Danger Zone** runs across the full width at the bottom. On a narrow screen the same cards stack in that order.
|
||||
|
||||
Switches save as soon as you flip them. Text fields save with the card's own **Save** button.
|
||||
Switches save as soon as you flip them. Text fields save with the card's own **Save** button. The phone admin has the same cards in its **Settings** section.
|
||||
|
||||
## Authentication Methods
|
||||
|
||||
@@ -143,11 +143,11 @@ Rotating the JWT secret does not touch the encryption key that protects stored A
|
||||
|
||||
## See also
|
||||
|
||||
- [Admin-Panel-Overview](Admin-Panel-Overview) - all admin tabs
|
||||
- [OIDC-SSO](OIDC-SSO) - single sign-on setup
|
||||
- [Passkeys](Passkeys) - passkeys from the user's side
|
||||
- [Two-Factor-Authentication](Two-Factor-Authentication) - 2FA and the enforced setup
|
||||
- [TREK-Places-API](TREK-Places-API) - TREK's own place index
|
||||
- [Places-and-Search](Places-and-Search) - how place search uses these providers
|
||||
- [Environment-Variables](Environment-Variables) - variables that override these fields
|
||||
- [Encryption-Key-Rotation](Encryption-Key-Rotation) - rotating the encryption key
|
||||
- [Admin-Panel-Overview](Admin-Panel-Overview): all admin tabs
|
||||
- [OIDC-SSO](OIDC-SSO): single sign-on setup
|
||||
- [Passkeys](Passkeys): passkeys from the user's side
|
||||
- [Two-Factor-Authentication](Two-Factor-Authentication): 2FA and the enforced setup
|
||||
- [TREK-Places-API](TREK-Places-API): TREK's own place index
|
||||
- [Places-and-Search](Places-and-Search): how place search uses these providers
|
||||
- [Environment-Variables](Environment-Variables): variables that override these fields
|
||||
- [Encryption-Key-Rotation](Encryption-Key-Rotation): rotating the encryption key
|
||||
|
||||
+29
-27
@@ -16,15 +16,15 @@ A backend is a named place bytes can live. Two exist out of the box:
|
||||
You can **edit** a built-in to relocate its root directory, and **add**
|
||||
backends of type:
|
||||
|
||||
- **Local** — a directory on a disk or mount reachable by the server.
|
||||
- **S3** — any S3-compatible service (AWS S3, Cloudflare R2, Backblaze B2,
|
||||
- **Local**: a directory on a disk or mount reachable by the server.
|
||||
- **S3**: any S3-compatible service (AWS S3, Cloudflare R2, Backblaze B2,
|
||||
Garage, MinIO/AIStor). Endpoint URL, bucket, credentials, and optionally
|
||||
region, key prefix, retries, and timeout. For self-hosted endpoints, use an
|
||||
IP address or `localhost` in the URL unless your server is configured for
|
||||
virtual-hosted bucket addressing.
|
||||
|
||||
If `TREK_PLACE_PHOTO_DIR` is set, a read-only `place-photos-local` backend
|
||||
appears too — it is defined by that environment variable, not by this panel.
|
||||
appears too; it is defined by that environment variable, not by this panel.
|
||||
|
||||
### Replication (Mirror targets)
|
||||
|
||||
@@ -33,36 +33,36 @@ backend is then also copied to each selected target. Removing all targets
|
||||
turns replication off again.
|
||||
|
||||
- A backend can serve as a **mirror target or as a category target, not
|
||||
both** — only backends no category is stored on are offered in the list, and
|
||||
both**: only backends no category is stored on are offered in the list, and
|
||||
saving a configuration that mixes the two is refused. A sync makes a target
|
||||
match its backend (see below), so anything else stored there would be
|
||||
deleted.
|
||||
- Writes go to the backend itself first (it stays the source of truth), then
|
||||
to each target in order. A slow or unreachable target slows every upload of
|
||||
every category on that backend — ideal for backups, worth weighing before
|
||||
every category on that backend, ideal for backups, worth weighing before
|
||||
replicating hot categories like trip documents.
|
||||
- Replica failures **never fail the original request**. They are recorded and
|
||||
shown in the **Health** strip at the top of the tab, with the backend, the
|
||||
object, the operation, and how long ago it happened. An empty strip means
|
||||
every replicated write landed. Replica failures also notify admins — in-app
|
||||
every replicated write landed. Replica failures also notify admins, in-app
|
||||
and over the configured webhook/ntfy/email channels (first failure
|
||||
immediately, then at most one summary per backend per hour). Preferences
|
||||
live in the admin Notifications tab.
|
||||
- Replication starts with the next write. To copy objects that existed before
|
||||
you added a target, press **Sync now** on the backend's row — one sync runs
|
||||
you added a target, press **Sync now** on the backend's row; one sync runs
|
||||
at a time, with progress and a cancel button; objects already present with
|
||||
matching sizes are skipped, and per-object failures land in the Health
|
||||
strip without stopping the run. A sync makes the target **match** the
|
||||
backend, not just catch up: it also deletes target objects that no longer
|
||||
exist on the backend — it's not a trash can, so run it only when you want
|
||||
exist on the backend; it's not a trash can, so run it only when you want
|
||||
the target pruned to match, and stray deletions land in the Health strip
|
||||
like any other replica failure.
|
||||
|
||||
### Test
|
||||
|
||||
Every backend row has a **Test** button: the server writes, checks, and
|
||||
deletes a small probe object (`trek-probe/…`) on the backend — for a
|
||||
replicated backend, on the backend itself and each target individually — and
|
||||
deletes a small probe object (`trek-probe/…`) on the backend (for a
|
||||
replicated backend, on the backend itself and each target individually) and
|
||||
reports per-target results. "Connection OK" means credentials, bucket, and
|
||||
reachability all check out. Targets must be **saved** before Test can probe
|
||||
them; a just-added, unsaved backend used as a target reports an error until
|
||||
@@ -75,22 +75,22 @@ assigned to exactly one backend:
|
||||
|
||||
| Category | Id | What it stores |
|
||||
|----------|----|----------------|
|
||||
| Trip documents | `files` | File attachments uploaded to trips — tickets, PDFs, booking confirmations, and files shared in trip chat |
|
||||
| Trip documents | `files` | File attachments uploaded to trips, tickets, PDFs, booking confirmations, and files shared in trip chat |
|
||||
| Journey photos | `journey` | Photos and thumbnails attached to journey entries |
|
||||
| Cover images | `covers` | Trip and collection cover images, including covers fetched from Unsplash |
|
||||
| Profile pictures | `avatars` | User account profile pictures |
|
||||
| Place images | `places` | Images attached to places and collection places — uploaded or imported |
|
||||
| Google photo cache | `photos-google` | Cached copies of Google Places photos — re-fetchable, safe to lose |
|
||||
| TREK photo cache | `photos-trek` | Cached photos from the TREK photo service used by Memories — re-fetchable, safe to lose |
|
||||
| Place images | `places` | Images attached to places and collection places, uploaded or imported |
|
||||
| Google photo cache | `photos-google` | Cached copies of Google Places photos, re-fetchable, safe to lose |
|
||||
| TREK photo cache | `photos-trek` | Cached photos from the TREK photo service used by Memories, re-fetchable, safe to lose |
|
||||
| Backups | `backups` | Server backup archives created by the Backup panel or schedule |
|
||||
|
||||
Reassigning a category changes where **new** objects go. If the category
|
||||
already holds objects, the panel asks first: **Move existing objects** copies
|
||||
everything to the new backend, switches the category, then sweeps any writes
|
||||
that raced the copy; **Just route new writes** keeps the previous behavior —
|
||||
that raced the copy; **Just route new writes** keeps the previous behavior:
|
||||
new objects go to the new backend, existing ones stay put and keep being
|
||||
served from wherever they already are. Replicating the Google photo cache or
|
||||
Place images is flagged as not recommended — both hold content that is
|
||||
Place images is flagged as not recommended; both hold content that is
|
||||
re-fetchable or provider-derived.
|
||||
|
||||
The legacy `/uploads/photos` directory written by older TREK versions is not
|
||||
@@ -100,18 +100,18 @@ writes there anymore and it cannot be reassigned.
|
||||
### Moving a category's objects
|
||||
|
||||
A category migration shares its one-at-a-time slot with mirror syncs (see
|
||||
*Replication* above) — starting a move while a sync (or another move) is
|
||||
*Replication* above); starting a move while a sync (or another move) is
|
||||
running is refused, and vice versa. Progress (done/total, copied/skipped/
|
||||
failed) shows inline with a cancel button.
|
||||
|
||||
Cancelling before the category switches is completely safe: nothing has
|
||||
changed yet, the copy just stops. A failed copy behaves the same way — the
|
||||
changed yet, the copy just stops. A failed copy behaves the same way; the
|
||||
category is never switched if any object failed to copy. Once the switch has
|
||||
happened, the delta sweep (catching writes that landed on the old backend
|
||||
while the copy was running) always runs to completion, even if you cancel.
|
||||
|
||||
The old objects are **not** deleted when a move finishes — that's what the
|
||||
reclaimable line means (`N objects (size) remain on <backend> — reclaim
|
||||
The old objects are **not** deleted when a move finishes; that's what the
|
||||
reclaimable line means (`N objects (size) remain on <backend>, reclaim
|
||||
manually`). It's left behind on purpose so you can confirm the new backend
|
||||
looks right before removing it yourself.
|
||||
|
||||
@@ -119,18 +119,18 @@ looks right before removing it yourself.
|
||||
|
||||
The Backends section shows per-backend and per-category object counts and
|
||||
sizes, scanned nightly (04:15 server time) and on demand via **Refresh**. The
|
||||
stamp shows when the numbers were computed — reassigning categories does not
|
||||
stamp shows when the numbers were computed; reassigning categories does not
|
||||
retroactively move them until the next scan. The uploads backend's total
|
||||
includes the legacy photo library.
|
||||
|
||||
## Secrets and encryption
|
||||
|
||||
Backend credentials (the S3 secret access key) are stored encrypted. Setting
|
||||
the `ENCRYPTION_KEY` environment variable explicitly is recommended — without
|
||||
the `ENCRYPTION_KEY` environment variable explicitly is recommended; without
|
||||
it the implicit key persisted in the data directory is used, which works but
|
||||
rides inside backup archives (someone holding a backup can decrypt the
|
||||
secrets it contains). If you later move from the implicit key to an explicit
|
||||
one, follow [[Encryption Key Rotation|Encryption-Key-Rotation]] — setting a
|
||||
one, follow [[Encryption Key Rotation|Encryption-Key-Rotation]]; setting a
|
||||
new key directly would orphan already-stored secrets. Saved secrets display
|
||||
as a masked placeholder; leaving the mask untouched when editing keeps the
|
||||
stored value.
|
||||
@@ -139,12 +139,12 @@ stored value.
|
||||
|
||||
For scripted deployments, place a `storage-config.json` in the data directory
|
||||
(in Docker: mount it at `/app/data/storage-config.json`). It is imported
|
||||
exactly once — on the first boot that has no stored storage configuration —
|
||||
exactly once, on the first boot that has no stored storage configuration,
|
||||
then ignored (a log line says so). An invalid file aborts boot with the exact
|
||||
validation error.
|
||||
|
||||
```jsonc
|
||||
// storage-config.json - secrets may be plaintext (encrypted on import)
|
||||
// storage-config.json: secrets may be plaintext (encrypted on import)
|
||||
// or already-encrypted enc:v1: values.
|
||||
{
|
||||
"backends": [
|
||||
@@ -167,7 +167,7 @@ The panel presents this exact setup as **Mirror targets** on `backups-local`.
|
||||
|
||||
To reset storage configuration (or re-import a seed file): stop the server,
|
||||
`sqlite3 data/travel.db "DELETE FROM app_settings WHERE key LIKE 'storage.%';"`,
|
||||
start it again — it boots on the built-in defaults, or re-imports the seed
|
||||
start it again; it boots on the built-in defaults, or re-imports the seed
|
||||
file if present.
|
||||
|
||||
**Restore chicken-and-egg:** backups include the storage configuration. If
|
||||
@@ -175,9 +175,11 @@ your only backup lives on S3 and the credentials are inside it: start a fresh
|
||||
instance, enter the S3 credentials here (or mount a seed file), then restore
|
||||
from the Backup panel.
|
||||
|
||||
The phone admin has the same functions in its **Storage** section.
|
||||
|
||||
## Related pages
|
||||
|
||||
- [[Backups|Backups]] — what a backup contains, restore procedure
|
||||
- [[Backups|Backups]]: what a backup contains, restore procedure
|
||||
- [[Environment Variables|Environment-Variables]]
|
||||
- [[Encryption Key Rotation|Encryption-Key-Rotation]]
|
||||
- [[Admin Panel Overview|Admin-Panel-Overview]]
|
||||
|
||||
@@ -4,7 +4,7 @@ The **User Defaults** tab (in the **Users** group of the admin side navigation,
|
||||
|
||||

|
||||
|
||||
On a wide screen the tab has two cards side by side: **Default User Settings** on the left, **Map** on the right. On a narrow screen the map card follows below.
|
||||
On a wide screen the tab has two cards side by side: **Default User Settings** on the left, **Map** on the right. On a narrow screen the map card follows below. The phone admin has the same tab as a section of its own.
|
||||
|
||||
## Saving and resetting
|
||||
|
||||
@@ -77,9 +77,9 @@ See [Map-Settings](Map-Settings) for the styles and what the two Mapbox switches
|
||||
|
||||
## See also
|
||||
|
||||
- [Admin-Panel-Overview](Admin-Panel-Overview) - all admin tabs
|
||||
- [Display-Settings](Display-Settings) - the same settings from the user's side
|
||||
- [Appearance-Settings](Appearance-Settings) - colour mode and the rest of the look
|
||||
- [Map-Settings](Map-Settings) - map engines, tile sources, styles and keys
|
||||
- [Road-Trip](Road-Trip#routing-engines) - routing engines in detail
|
||||
- [Currencies](Currencies) - display and trip currencies
|
||||
- [Admin-Panel-Overview](Admin-Panel-Overview): all admin tabs
|
||||
- [Display-Settings](Display-Settings): the same settings from the user's side
|
||||
- [Appearance-Settings](Appearance-Settings): colour mode and the rest of the look
|
||||
- [Map-Settings](Map-Settings): map engines, tile sources, styles and keys
|
||||
- [Road-Trip](Road-Trip#routing-engines): routing engines in detail
|
||||
- [Currencies](Currencies): display and trip currencies
|
||||
|
||||
@@ -40,6 +40,8 @@ If an install from before 5.0 already holds two accounts whose addresses differ
|
||||
|
||||
Below the fields sits **Reset passkeys**, which removes every passkey that user has registered: the recovery path when someone loses their authenticator. It asks for confirmation in a dialog, reports how many passkeys it removed, and takes effect immediately rather than on **Save**. The user can still sign in with their password. See [Passkeys](Passkeys).
|
||||
|
||||
For every other account the dialog also has **Reset 2FA**, for example after a lost phone. After you confirm (**Turn off two-factor authentication for {name}?**) it switches 2FA off for that user and signs them out everywhere; they can set it up again after logging in with their password. It is not offered for your own account, and it is recorded in the [Audit-Log](Audit-Log). See [Two-Factor-Authentication](Two-Factor-Authentication).
|
||||
|
||||
### Delete a user
|
||||
|
||||
Click the trash icon and confirm in the **Delete user** dialog (**Delete user "name"? All trips will be permanently deleted.**). Deletion is permanent. The user's account is removed from the database along with their data, including the trips they own (cascade behavior is enforced at the database level).
|
||||
@@ -81,7 +83,7 @@ Existing invites are listed below the creation button. Each row shows:
|
||||
- **adds to** the bound trip, if the invite is trip-bound
|
||||
- **by** the admin who generated the link
|
||||
- A **Copy link** button (only on active invites)
|
||||
- A delete (revoke) button
|
||||
- A delete (revoke) button, which asks you to confirm in the **Delete invite link** dialog ("Anyone who has not used it yet can no longer register with it.")
|
||||
|
||||
Revoking an invite immediately invalidates it; anyone following the link after revocation will receive an error.
|
||||
|
||||
@@ -89,6 +91,10 @@ Revoking an invite immediately invalidates it; anyone following the link after r
|
||||
|
||||
The **Users** tab also hosts the Permissions panel at the bottom, which controls what roles can perform which actions. See [Admin-Permissions](Admin-Permissions) for details.
|
||||
|
||||
## On a phone
|
||||
|
||||
The phone admin has the same functions in its **Users** section (user list, edit and create dialogs, invite links) with the permissions panel below it.
|
||||
|
||||
## Related pages
|
||||
|
||||
- [Login-and-Registration](Login-and-Registration)
|
||||
|
||||
+25
-24
@@ -1,6 +1,6 @@
|
||||
# Appearance Settings
|
||||
|
||||
Tune how TREK looks — colour mode, accent scheme, readability, and which dashboard widgets you see.
|
||||
Tune how TREK looks: colour mode, accent scheme, readability, and which dashboard widgets you see.
|
||||
|
||||

|
||||
|
||||
@@ -10,7 +10,7 @@ Open **Settings** and select the **Appearance** tab.
|
||||
|
||||
Changes preview instantly and are saved to your account a moment later, so they follow you to every browser you sign in with. A **Reset to defaults** button at the bottom of the tab restores the colour scheme, the readability settings, the dashboard widgets and the mobile layout in one click. Your **Color mode** (Light / Dark / Auto) is a separate setting and is left as it is.
|
||||
|
||||
> These are personal settings — no permission and no admin toggle gate them.
|
||||
> These are personal settings; no permission and no admin toggle gate them.
|
||||
|
||||
## Theme
|
||||
|
||||
@@ -22,10 +22,10 @@ Three segmented buttons: **Light**, **Dark**, and **Auto**. **Auto** follows you
|
||||
|
||||
A grid of accent schemes, each with a colour dot that previews in your current mode:
|
||||
|
||||
- **Default** — TREK's monochrome look.
|
||||
- **High contrast** — raises text and border contrast.
|
||||
- **Indigo**, **Teal**, **Rose**, **Amber**, **Violet** — coloured accents.
|
||||
- **Custom** — pick your own accent (below).
|
||||
- **Default**: TREK's monochrome look.
|
||||
- **High contrast**: raises text and border contrast.
|
||||
- **Indigo**, **Teal**, **Rose**, **Amber**, **Violet**: coloured accents.
|
||||
- **Custom**: pick your own accent (below).
|
||||
|
||||
### Custom accent
|
||||
|
||||
@@ -36,8 +36,8 @@ Choosing **Custom** reveals a **Custom accent** picker:
|
||||
|
||||
Next to the pickers, a live contrast badge evaluates the accent you are currently seeing against white and shows the ratio:
|
||||
|
||||
- **Good contrast (n.n:1)** — the ratio meets WCAG AA for normal text (4.5:1 or better).
|
||||
- **Low contrast (n.n:1)** — below 4.5:1; white text on that accent will be hard to read.
|
||||
- **Good contrast (n.n:1)**: the ratio meets WCAG AA for normal text (4.5:1 or better).
|
||||
- **Low contrast (n.n:1)**: below 4.5:1; white text on that accent will be hard to read.
|
||||
|
||||
The badge is advisory. TREK will still let you apply a low-contrast accent.
|
||||
|
||||
@@ -45,44 +45,44 @@ The badge is advisory. TREK will still let you apply a low-contrast accent.
|
||||
|
||||
This whole section carries an **Experimental** badge.
|
||||
|
||||
- **Transparency** — *Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.*
|
||||
- **Reduce motion** — *Minimize animations and transitions.*
|
||||
- **Density** — **Comfortable** or **Compact**. *Compact tightens spacing and padding for a denser layout that fits more on screen.*
|
||||
- **Transparency**: *Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.*
|
||||
- **Reduce motion**: *Minimize animations and transitions.*
|
||||
- **Density**: **Comfortable** or **Compact**. *Compact tightens spacing and padding for a denser layout that fits more on screen.*
|
||||
|
||||
### Text size
|
||||
|
||||
Text scaling works on four axes plus one master control. Every slider runs from **80%** to **160%** in 5% steps, and shows its current percentage on the right.
|
||||
|
||||
- **Everything** — a global scale applied on top of the per-tier values.
|
||||
- **Large** — *Headings, big numbers*
|
||||
- **Medium** — *Sub-headings*
|
||||
- **Normal** — *Place names, descriptions*
|
||||
- **Small** — *Addresses, labels*
|
||||
- **Everything**: a global scale applied on top of the per-tier values.
|
||||
- **Large**: *Headings, big numbers*
|
||||
- **Medium**: *Sub-headings*
|
||||
- **Normal**: *Place names, descriptions*
|
||||
- **Small**: *Addresses, labels*
|
||||
|
||||
Each of the four rows renders a live sample in that tier ("Large heading", "Medium subtitle", "Normal body text", "Small caption / address"), so you can see the effect while dragging.
|
||||
|
||||
## Dashboard widgets
|
||||
|
||||
*Show or hide dashboard widgets independently on desktop and mobile.* This does not detect your current device — it sets two independent layouts, and the dashboard picks the one matching the viewport it is rendered at. Both layouts are stored on your account, so a change made on your laptop also changes what your phone shows.
|
||||
*Show or hide dashboard widgets independently on desktop and mobile.* This does not detect your current device; it sets two independent layouts, and the dashboard picks the one matching the viewport it is rendered at. Both layouts are stored on your account, so a change made on your laptop also changes what your phone shows.
|
||||
|
||||
### Desktop
|
||||
|
||||
- **Below the hero** — **Atlas / countries**, **Trips total**, **Days traveled**, **Distance flown**.
|
||||
- **Right sidebar** — a master toggle (*The whole right column. Turn off and the dashboard centers.*) with four widgets nested under it: **Currency**, **Collections**, **Timezones**, **Upcoming reservations**. Turning the master off greys the nested toggles out; their individual states are remembered for when you turn it back on.
|
||||
- **Below the hero**: **Atlas / countries**, **Trips total**, **Days traveled**, **Distance flown**.
|
||||
- **Right sidebar**: a master toggle (*The whole right column. Turn off and the dashboard centers.*) with four widgets nested under it: **Currency**, **Collections**, **Timezones**, **Upcoming reservations**. Turning the master off greys the nested toggles out; their individual states are remembered for when you turn it back on.
|
||||
|
||||
### Mobile
|
||||
|
||||
- **Below the hero** — **Trips total**, **Days traveled**.
|
||||
- **Bottom of page** — **Currency**, **Collections**, **Timezones**, **Upcoming reservations**.
|
||||
- **Below the hero**: **Trips total**, **Days traveled**.
|
||||
- **Bottom of page**: **Currency**, **Collections**, **Timezones**, **Upcoming reservations**.
|
||||
|
||||
Hiding a widget here only affects your own dashboard. Widgets that depend on an addon (for example **Collections**) also need that addon enabled by an admin — see [Dashboard-Widgets](Dashboard-Widgets) and [Admin-Addons](Admin-Addons).
|
||||
Hiding a widget here only affects your own dashboard. Widgets that depend on an addon (for example **Collections**) also need that addon enabled by an admin, see [Dashboard-Widgets](Dashboard-Widgets) and [Admin-Addons](Admin-Addons).
|
||||
|
||||
## On a phone
|
||||
|
||||
Opened on a phone, the Appearance screen carries an extra **Mobile** card that the desktop tab does not have:
|
||||
|
||||
- **Bottom navbar** — which items sit in the bottom bar, in which order, and which are demoted under **More**. **Dashboard** is pinned first and cannot be moved; two more items fit next to it, and a counter above the list shows how full the bar is. Leaving both lists untouched keeps TREK's automatic split.
|
||||
- **Dashboard order** — reorder how the trip list and the inline widgets stack on the phone dashboard. The featured trip always stays on top. A block whose widget is switched off under **Dashboard widgets** keeps its place in the list and is marked **Hidden**.
|
||||
- **Bottom navbar**: which items sit in the bottom bar, in which order, and which are demoted under **More**. **Dashboard** is pinned first and cannot be moved; two more items fit next to it, and a counter above the list shows how full the bar is. Leaving both lists untouched keeps TREK's automatic split.
|
||||
- **Dashboard order**: reorder how the trip list and the inline widgets stack on the phone dashboard. The featured trip always stays on top. A block whose widget is switched off under **Dashboard widgets** keeps its place in the list and is marked **Hidden**.
|
||||
|
||||
Both are stored on your account alongside the rest of the appearance settings, and both are cleared by **Reset to defaults**.
|
||||
|
||||
@@ -97,3 +97,4 @@ None. Every setting on this tab applies only to your own account.
|
||||
- [Dashboard-Widgets](Dashboard-Widgets)
|
||||
- [My-Trips-Dashboard](My-Trips-Dashboard)
|
||||
- [Map-Settings](Map-Settings)
|
||||
- [Mobile-App](Mobile-App)
|
||||
|
||||
+24
-7
@@ -26,7 +26,7 @@ Actions are grouped by area below. The **Action key** is the raw value stored in
|
||||
| `user.password_reset_success` | Password reset completed |
|
||||
| `user.password_reset_fail` | Password reset attempt rejected (`reason` in details) |
|
||||
|
||||
A request for an account that can actually be reset writes **two** rows: one with `delivered: "pending"` when the mail is handed off, one with the delivery result. Every other outcome writes a single row carrying a `reason` instead — `no_user`, `oidc_only`, `throttled_per_email` or `password_login_disabled`. Passkey logins are not a separate key: they land as `user.login` with `method: passkey` in the details, and SSO logins the same way with `method: oidc`. An account created by a first SSO login also writes `user.register` with `method: oidc`, carrying the same fields as a password signup.
|
||||
A request for an account that can actually be reset writes **two** rows: one with `delivered: "pending"` when the mail is handed off, one with the delivery result. Every other outcome writes a single row carrying a `reason` instead: `no_user`, `oidc_only`, `throttled_per_email` or `password_login_disabled`. Passkey logins are not a separate key: they land as `user.login` with `method: passkey` in the details, and SSO logins the same way with `method: oidc`. An account created by a first SSO login also writes `user.register` with `method: oidc`, carrying the same fields as a password signup.
|
||||
|
||||
### MFA
|
||||
|
||||
@@ -50,7 +50,7 @@ Logging out writes no row, and neither do the sessions a password change, a rese
|
||||
|---|---|
|
||||
| `user.passkey_register` | Passkey enrolled |
|
||||
| `user.passkey_delete` | Passkey removed (resource = the passkey's numeric ID) |
|
||||
| `user.passkey_clone_suspected` | A passkey presented a signature counter that did not advance — a possible cloned authenticator. That assertion is rejected, the credential stays enabled |
|
||||
| `user.passkey_clone_suspected` | A passkey presented a signature counter that did not advance; a possible cloned authenticator. That assertion is rejected, the credential stays enabled |
|
||||
|
||||
### SSO
|
||||
|
||||
@@ -69,7 +69,7 @@ Logging out writes no row, and neither do the sessions a password change, a rese
|
||||
| `trip.transfer_ownership` | Trip ownership transferred (includes the trip title and both owner emails) |
|
||||
| `trip.invite_link_create` | Trip invite link created or rotated (a trip has one link, so creating it again replaces the previous token) |
|
||||
| `trip.invite_link_delete` | Trip invite link revoked |
|
||||
| `trip.invite_link_join` | An invite link was accepted (`joined` in details). The row is written even when nobody was added — the trip owner or an existing member opening the link logs `joined: false` |
|
||||
| `trip.invite_link_join` | An invite link was accepted (`joined` in details). The row is written even when nobody was added; the trip owner or an existing member opening the link logs `joined: false` |
|
||||
|
||||
### Admin actions
|
||||
|
||||
@@ -110,6 +110,15 @@ Logging out writes no row, and neither do the sessions a password change, a rese
|
||||
| `admin.storage_stats_refresh` | Storage usage stats recomputed |
|
||||
| `admin.default_user_settings_update` | Default user settings updated |
|
||||
| `admin.demo_baseline_save` | Demo baseline snapshot saved |
|
||||
| `admin.tours_wanderer` | The wanderer switch under Tours toggled |
|
||||
| `admin.tours_hiking_map` | The Hiking map (OpenHikingMap) switch under Tours toggled |
|
||||
| `admin.tours_cycle_map` | The Cycling map (CyclOSM) switch under Tours toggled |
|
||||
| `admin.tours_ski_routing` | The Piste router switch under Tours toggled |
|
||||
| `admin.paddle_region_add` | A paddle water region added |
|
||||
| `admin.paddle_region_remove` | A paddle water region removed |
|
||||
| `admin.paddle_region_refresh` | A paddle water region read again |
|
||||
| `admin.paddle_region_decline` | A requested paddle water region declined |
|
||||
| `admin.paddle_region_settings` | The automatic loading of paddle water regions changed (mode and size limit in details) |
|
||||
|
||||
### Settings
|
||||
|
||||
@@ -157,13 +166,21 @@ Logging out writes no row, and neither do the sessions a password change, a rese
|
||||
| `airtrail.private_ip_configured` | AirTrail URL saved that resolves to a private IP |
|
||||
| `dawarich.private_ip_configured` | Dawarich URL saved that resolves to a private IP |
|
||||
| `dawarich.disconnected` | A user disconnected their Dawarich instance |
|
||||
| `wanderer.connected` | A user connected a wanderer instance (the address is recorded, never the token) |
|
||||
| `wanderer.updated` | A user changed their wanderer connection |
|
||||
| `wanderer.disconnected` | A user disconnected their wanderer instance |
|
||||
| `wanderer.watch_enabled` | A user switched on the background check of their imported wanderer trails |
|
||||
| `wanderer.watch_disabled` | A user switched it off again |
|
||||
| `ai.connection.saved` | An AI connection was saved, by a user or as the shared connection (`scope` and the provider `kind` in details) |
|
||||
| `ai.connection.removed` | An AI connection was removed |
|
||||
| `ai.settings.saved` | An admin saved the AI setup (who pays, daily limit, retention, web search) |
|
||||
|
||||
## Log columns
|
||||
|
||||
| Column | Description |
|
||||
|---|---|
|
||||
| Time | Timestamp of the action |
|
||||
| User | Username of the acting user, falling back to their email, then `#<user id>`. Unauthenticated events show `—` (the plain-text log file writes `anonymous` for those instead) |
|
||||
| User | Username of the acting user, falling back to their email, then `#<user id>`. Unauthenticated events show an empty placeholder (the plain-text log file writes `anonymous` for those instead) |
|
||||
| Action | Action key (see tables above) |
|
||||
| Resource | Affected resource (filename, trip ID, tool name, etc.) where applicable |
|
||||
| IP | Client IP address |
|
||||
@@ -171,13 +188,13 @@ Logging out writes no row, and neither do the sessions a password change, a rese
|
||||
|
||||
## Pagination
|
||||
|
||||
The panel loads 100 entries at a time. Click **Load more** at the bottom to fetch the next page, or **Refresh** to reload from the newest entry. The count is shown above the table as `{loaded} loaded · {total} total`.
|
||||
The panel loads 100 entries at a time. Click **Load more** at the bottom to fetch the next page, or **Refresh** (in the head of the card) to reload from the newest entry. A pill in the head of the card shows the count as `{loaded} loaded, {total} total`. The phone admin shows the same log in its **Audit** section.
|
||||
|
||||
## IP addresses
|
||||
|
||||
The client IP is the one Express resolves after applying `TRUST_PROXY`, not whatever the `X-Forwarded-For` header happens to say. That distinction matters: the header is written by the caller, and an audit row an attacker can address to someone else's IP is worse than no row at all.
|
||||
|
||||
`TRUST_PROXY` is **the number of proxy hops in front of TREK**, and it has to be accurate. With `TRUST_PROXY=1` (the default) TREK trusts exactly one hop, so a request that passed through two proxies is recorded as coming from the *outer* one — the Cloudflare edge in the example below, not nginx and not the real client. If your setup is Cloudflare in front of nginx in front of TREK, set `TRUST_PROXY=2`. Set it to `0` to trust nothing and always record the socket address.
|
||||
`TRUST_PROXY` is **the number of proxy hops in front of TREK**, and it has to be accurate. With `TRUST_PROXY=1` (the default) TREK trusts exactly one hop, so a request that passed through two proxies is recorded as coming from the *outer* one; the Cloudflare edge in the example below, not nginx and not the real client. If your setup is Cloudflare in front of nginx in front of TREK, set `TRUST_PROXY=2`. Set it to `0` to trust nothing and always record the socket address.
|
||||
|
||||
See [Environment-Variables](Environment-Variables).
|
||||
|
||||
@@ -195,7 +212,7 @@ Audit entries in the database are never automatically deleted. They accumulate a
|
||||
|
||||
## Plugin capability audit
|
||||
|
||||
Separate from the instance audit log above, TREK keeps a dedicated **hash-chained capability audit** for installed plugins. Every host-mediated action a plugin takes — core-data reads, WebSocket broadcasts, notifications, AI calls, cross-plugin calls — is recorded at the point the plugin cannot reach, together with the acting user (bound by the host, never supplied by the plugin), the resource touched, and the outcome.
|
||||
Separate from the instance audit log above, TREK keeps a dedicated **hash-chained capability audit** for installed plugins. Every host-mediated action a plugin takes (core-data reads, WebSocket broadcasts, notifications, AI calls, cross-plugin calls) is recorded at the point the plugin cannot reach, together with the acting user (bound by the host, never supplied by the plugin), the resource touched, and the outcome.
|
||||
|
||||
Each plugin's entries form a per-plugin hash chain (`hash = sha256(previous_hash + row)`), so the log is tamper-evident: any altered or removed entry breaks the chain. Older rows are pruned per plugin once the row cap is reached (default 20,000 rows/plugin, tunable via `TREK_PLUGIN_AUDIT_MAX_ROWS`; `0` disables pruning). Pruning keeps the retained window verifiable.
|
||||
|
||||
|
||||
+12
-10
@@ -1,6 +1,6 @@
|
||||
# Backups
|
||||
|
||||
TREK stores all data in a single SQLite database (`travel.db`) plus an `uploads/` directory of attachments, cover photos, and avatars — by default; storage backends and replication are configured in [[Admin: Storage|Admin-Storage]]. The Backup panel lets you create, download, restore, and schedule backups of both.
|
||||
TREK stores all data in a single SQLite database (`travel.db`) plus an `uploads/` directory of attachments, cover photos, and avatars, by default; storage backends and replication are configured in [[Admin: Storage|Admin-Storage]]. The Backup panel lets you create, download, restore, and schedule backups of both.
|
||||
|
||||
## Where to find it
|
||||
|
||||
@@ -15,11 +15,11 @@ A backup is a ZIP archive with these entries:
|
||||
| Entry | Contents |
|
||||
|---|---|
|
||||
| `travel.db` | The full SQLite database, as a consistent snapshot taken while TREK keeps running (writes during the backup cannot tear it) |
|
||||
| `uploads/` | All uploaded attachments, covers, and avatars (default location — see [Admin: Storage](Admin-Storage)) |
|
||||
| `uploads/` | All uploaded attachments, covers, and avatars (default location, see [Admin: Storage](Admin-Storage)) |
|
||||
| `plugins-data/` | Each installed plugin's own database + files (present only if plugins are installed) |
|
||||
| `plugins-code/` | The installed plugin code, so a restore is self-contained (dev-linked plugins are skipped) |
|
||||
|
||||
**Also included:** the at-rest encryption key, unless you supply it through the `ENCRYPTION_KEY` environment variable — in that case the file is not the source of truth and is left out. Bundling it is what makes a backup restorable onto a different install, and it makes the ZIP as sensitive as the key itself: store and transfer it accordingly. See [Encryption-Key-Rotation](Encryption-Key-Rotation).
|
||||
**Also included:** the at-rest encryption key, unless you supply it through the `ENCRYPTION_KEY` environment variable; in that case the file is not the source of truth and is left out. Bundling it is what makes a backup restorable onto a different install, and it makes the ZIP as sensitive as the key itself: store and transfer it accordingly. See [Encryption-Key-Rotation](Encryption-Key-Rotation).
|
||||
|
||||
## Manual backup
|
||||
|
||||
@@ -36,12 +36,12 @@ You can restore from:
|
||||
- **A stored backup**: click **Restore** next to any backup in the list.
|
||||
- **An uploaded ZIP**: click **Upload Backup** and select a backup file from your computer (maximum upload size: 500 MB by default, configurable with the `BACKUP_UPLOAD_LIMIT_MB` environment variable; see [Environment-Variables](Environment-Variables)).
|
||||
|
||||
A second limit caps the **decompressed** size of a restore archive at 5 GB by default (`BACKUP_MAX_DECOMPRESSED_MB`). It applies to both routes — a stored backup as well as an uploaded ZIP — and a restore that exceeds it is refused with `Backup exceeds the maximum decompressed size.` Raise it if your own backups legitimately grow past the default, otherwise they become unrestorable.
|
||||
A second limit caps the **decompressed** size of a restore archive at 5 GB by default (`BACKUP_MAX_DECOMPRESSED_MB`). It applies to both routes (a stored backup as well as an uploaded ZIP) and a restore that exceeds it is refused with `Backup exceeds the maximum decompressed size.` Raise it if your own backups legitimately grow past the default, otherwise they become unrestorable.
|
||||
|
||||
Before restoring, TREK runs integrity checks on the uploaded database:
|
||||
|
||||
1. **SQLite `PRAGMA integrity_check`** — verifies the database file is not corrupt.
|
||||
2. **Required tables present** — confirms the file contains `users`, `trips`, `trip_members`, `places`, and `days`. Files missing any of these are rejected as not being a valid TREK backup.
|
||||
1. **SQLite `PRAGMA integrity_check`**: verifies the database file is not corrupt.
|
||||
2. **Required tables present**: confirms the file contains `users`, `trips`, `trip_members`, `places`, and `days`. Files missing any of these are rejected as not being a valid TREK backup.
|
||||
3. **Not from a newer TREK**: a backup whose database a newer release migrated is refused with `This backup was made by a newer TREK version. Update TREK before restoring it.` Restoring it would leave this version unable to start.
|
||||
|
||||
The database being replaced is kept as `pre-restore-<time>.db` next to it (in `data/` on a standard install), so a restore of the wrong archive can be undone by hand. Delete these copies once you no longer need them.
|
||||
@@ -52,7 +52,7 @@ Either way, TREK asks first in a **Restore Backup?** dialog that names the file,
|
||||
|
||||
> **Warning:** Restoring replaces all current data. Back up your current state first if you want to keep it.
|
||||
|
||||
> **Plugins & restart:** `travel.db` and `uploads/` are swapped in immediately. Plugin data and code are **staged** beside the live trees and applied right away: the running plugins hold their databases open, so the restore asks the plugin runtime to shut them down and swaps the trees in the moment the handles are closed. If the runtime isn't up (plugins switched off, or a restore that happens during startup), the staged trees are applied at the next boot instead. Restart the server after restoring an instance that uses plugins — the plugins are stopped for the swap and stay down until the process restarts, and the bundled encryption key is only read at startup.
|
||||
> **Plugins & restart:** `travel.db` and `uploads/` are swapped in immediately. Plugin data and code are **staged** beside the live trees and applied right away: the running plugins hold their databases open, so the restore asks the plugin runtime to shut them down and swaps the trees in the moment the handles are closed. If the runtime isn't up (plugins switched off, or a restore that happens during startup), the staged trees are applied at the next boot instead. Restart the server after restoring an instance that uses plugins; the plugins are stopped for the swap and stay down until the process restarts, and the bundled encryption key is only read at startup.
|
||||
|
||||
### Restoring on a new install, before setup
|
||||
|
||||
@@ -84,13 +84,15 @@ Turn on **Enable auto-backup** in the **Auto-Backup** card of the Backup tab, pi
|
||||
|
||||
**Schedule** options (depend on interval):
|
||||
|
||||
- **Run at hour**: time of day for daily, weekly, and monthly backups (0 to 23, server local time).
|
||||
- **Run at hour**: time of day for daily, weekly, and monthly backups (0 to 23, server local time). The hint under the field names the server's timezone and whether the list uses the 12h or the 24h format.
|
||||
- **Day of week**: Sunday through Saturday (for weekly backups).
|
||||
- **Day of month**: 1 to 28 (for monthly backups). Days 29 to 31 are excluded to avoid months with fewer days.
|
||||
|
||||
Auto-backup files are named `auto-backup-<timestamp>.zip` (manual backups use `backup-<timestamp>.zip`).
|
||||
|
||||
After each auto-backup run, **auto-backup files** older than `keep_days` are pruned. Manual backups are never pruned — delete those yourself when you no longer need them. Set `keep_days` to `0` to disable pruning entirely.
|
||||
After each auto-backup run, **auto-backup files** older than `keep_days` are pruned. Manual backups are never pruned; delete those yourself when you no longer need them. Set `keep_days` to `0` to disable pruning entirely.
|
||||
|
||||
The phone admin has the same lists and settings in its **Backup** section.
|
||||
|
||||
## Before updating TREK
|
||||
|
||||
@@ -112,7 +114,7 @@ The following actions are recorded in the [Audit-Log](Audit-Log):
|
||||
|
||||
## See also
|
||||
|
||||
- [Admin: Storage](Admin-Storage) — replicate backups to S3-compatible storage
|
||||
- [Admin: Storage](Admin-Storage): replicate backups to S3-compatible storage
|
||||
- [Encryption-Key-Rotation](Encryption-Key-Rotation)
|
||||
- [Admin-Panel-Overview](Admin-Panel-Overview)
|
||||
- [Security-Hardening](Security-Hardening)
|
||||
|
||||
+26
-6
@@ -19,7 +19,9 @@ The tab opens with the same bar as Transports, Bookings, Lists and Files. From l
|
||||
- The **Filter** button (funnel). Its popover holds the **All / Paid by me / I'm owed** switch, a **Category** list and a **Day** list with the days that have expenses. The button shows how many filters are on, and **Reset filters** at the foot of the popover switches them all off.
|
||||
- **Export CSV** (download icon), see [Exporting](#exporting).
|
||||
- **List** and **Table** (two icons), which switch the tab between the expense ledger and the [Table view](#table-view). The list is where Costs opens; the choice is remembered in this browser.
|
||||
- For members who may edit costs: **Settle up**, **Scan receipt** (only with the AI Parsing addon, see [Scanning a receipt](#scanning-a-receipt)) and **Add expense**.
|
||||
- For members who may edit costs: **Settle up**, **Scan receipt** (only with the AI Parsing addon and a model that reads images, see [Scanning a receipt](#scanning-a-receipt)) and **Add expense**.
|
||||
|
||||
On a phone, the Costs tab shows the summary on top, the ledger below it, and a scan icon in the header when receipt scanning is available. Adding an expense opens a sheet, and the ticket split works there too.
|
||||
|
||||
In a window narrower than 1024 px the tab stacks into one column: the total on a dark card with **Add expense** under it, then the summary cards, the settle-up list and the ledger with its own search and filters.
|
||||
|
||||
@@ -27,7 +29,7 @@ In a window narrower than 1024 px the tab stacks into one column: the total on a
|
||||
|
||||
Costs is **multi-currency** (#551). Three settings are involved, and they do different jobs:
|
||||
|
||||
- The **trip currency** (Trip → Edit trip) is the trip's accounting base. Every balance and settle-up is calculated in it.
|
||||
- The **trip currency** (set in the trip's dialog on My Trips: the pencil on the trip card, **Edit Trip**) is the trip's accounting base. Every balance and settle-up is calculated in it.
|
||||
- Each **expense** carries **its own currency**. Pick it in the expense dialog and enter what the receipt says (a $100 dinner on a rouble trip is `100 USD`). It is converted into the trip currency at a rate **frozen when you save it**, so a settled debt does not reopen when the market moves.
|
||||
- Your **display currency** (Settings → General → Language & region → **Display currency**) converts what you *read* (totals, balances, the ledger) into one currency. It changes nothing that is stored. Left on **Trip currency** (the default), each trip is shown in its own currency.
|
||||
|
||||
@@ -57,7 +59,7 @@ An expense row shows:
|
||||
- the **note** as a pill; click it to read the whole note, click again to fold it,
|
||||
- the **total**, and under it a green **you lent** or red **you borrowed** chip when the split leaves you up or down on it.
|
||||
|
||||
Beside the row, members who may edit costs find a pencil that opens the expense and a bin that deletes it straight away, without asking. A payment row has a pencil and **Undo** instead.
|
||||
Beside the row, members who may edit costs find a pencil that opens the expense and a bin that deletes it. TREK asks first (*Delete expense?*, with *"{name}" will be permanently deleted.*), on the desktop and on the phone. When the expense has receipts, the question adds *Its receipt files stay in Files.* A payment row has a pencil and **Undo** instead.
|
||||
|
||||
The filters work together: pick a day and a banner above the list names the day in full, with the number of expenses and their total. Payments carry no name or category, so a search or a category filter hides them; **I'm owed** hides them too, and **Paid by me** keeps only the transfers you are part of.
|
||||
|
||||
@@ -100,7 +102,9 @@ On the phone the booking, transport and place sheets carry the same block. Tap a
|
||||
|
||||
### Receipts and invoices
|
||||
|
||||
An expense can carry the receipt or invoice behind it. **Attach** in the **Receipts & Invoices** block of the expense dialog opens the file picker for images and PDFs, and several files can go on one expense. They are uploaded when the expense is saved, land in the trip's Files with a link to the expense, and are listed in the block from then on; click a name to view it. If the save fails after the upload, the uploaded files are taken back out again; any that could not be removed are reported, so you can delete them in the Files tab.
|
||||
An expense can carry the receipt or invoice behind it. **Attach** in the **Receipts & Invoices** block of the expense dialog opens the file picker for images and PDFs, and several files can go on one expense. They are uploaded when the expense is saved, land in the trip's Files with a link to the expense, and are listed in the block from then on; click a name to view it. If the save fails after the upload, the uploaded files are taken back out again. Any that could not be removed are reported (*Save failed, and 1 uploaded receipt is still there. Remove it in the Files tab.*), so you can delete them there.
|
||||
|
||||
Receipts need a connection. If you are offline, the dialog says *Receipts need a connection to upload. Remove the new ones to save the expense offline, or save once you are back online.* An expense without new receipts can be saved offline.
|
||||
|
||||
A row with receipts shows a **Receipts** chip beside the name, with the count when there is more than one. Click it to open the viewer: it shows one receipt at a time, pages through them with the **arrow keys**, and offers a download for a PDF.
|
||||
|
||||
@@ -108,7 +112,7 @@ The bin beside a receipt (**Remove receipt**) only unlinks the file from the exp
|
||||
|
||||
### Scanning a receipt
|
||||
|
||||
With the [AI Parsing](AI-Booking-Import) addon on and a model that reads images (see *Model reads images* there), **Scan receipt** sits beside **Add expense**, and on a phone the Costs header carries a scan icon. It is offered to whoever may add expenses.
|
||||
With the [AI Parsing](AI-Booking-Import) addon on and a model that reads images (see *Model reads images* there), **Scan receipt** sits beside **Add expense**, and on a phone the Costs header carries a scan icon. It is offered to whoever may add expenses. The model that reads the receipt can be the AI connection shared with the AI assistant; whether it reads images is the AI Parsing addon's own *Model reads images* setting. See [AI-Booking-Import](AI-Booking-Import#which-connection-reads-your-files).
|
||||
|
||||
1. Click **Scan receipt**. The **Scan a receipt** dialog takes one photo of the receipt (JPG, PNG or WEBP, up to 10 MB; a photo over 40 megapixels or a WEBP over 3.5 MB is refused): drop it on the box, or click the box to pick one or, on a phone, take one. Then click **Scan**.
|
||||
2. The dialog closes and the model reads the photo in the background: the **background tasks** widget shows *Reading the receipt…*, and you can keep using TREK meanwhile. On a local model running on CPU this takes from a few seconds to a couple of minutes.
|
||||
@@ -147,7 +151,7 @@ Costs works out the smallest number of transfers that settles every debt (a gree
|
||||
|
||||
The final budget comes to each member's share of the paid expenses (exact in the trip's own currency; in another display currency, rounding can leave a single figure a cent off while the column still adds up), so recording a payment moves an amount from *pending* to *net reimbursements* without changing it. An expense nobody has paid yet stays out of it, as it stays out of the balances.
|
||||
|
||||
**Settle up** in the bar at the top of the tab records every open transfer at once, without asking. **Add payment** in the head of the Settle up card records a single transfer by hand, for a repayment that did not follow a suggested one. Recorded payments then appear in the ledger as their own rows, with the pencil and **Undo** beside them.
|
||||
**Settle up** in the bar at the top of the tab records every open transfer at once, without asking. **Add payment** in the head of the Settle up card records a single transfer by hand, for a repayment that did not follow a suggested one. Recorded payments then appear in the ledger as their own rows, with the pencil and **Undo** beside them. Offline, a payment is saved in the queue (*You are offline. The payment is saved and shows up once TREK is back online.*) and sent when TREK is back online.
|
||||
|
||||

|
||||
|
||||
@@ -155,6 +159,22 @@ The **Add payment** dialog has **From** and **To** (the head band reads *You →
|
||||
|
||||
Balances are always netted in the **trip currency** and converted to your display currency once, at the end, so they stay stable even when the trip mixes currencies. An expense or payment in a foreign currency for which no exchange rate is known yet is left out of the balances and totals rather than counted 1:1; see [Currencies](Currencies#expense-currency).
|
||||
|
||||
## Members who left and deleted guests
|
||||
|
||||
Someone who has left the trip is still named in the lists and keeps their balance, so the settlement stays correct. Deleting a guest keeps the costs adding up: their payments are not dropped from the totals.
|
||||
|
||||
## Currency decimals
|
||||
|
||||
Amounts follow each currency's own decimals and format. Currencies without decimals, such as the Korean won and the Japanese yen, are shown and settled in whole units, so the suggested transfers in **Settle up** add up and settling them clears the balances. A payment counts on the day it happened in your local time. See [Currencies](Currencies).
|
||||
|
||||
## Offline
|
||||
|
||||
Expenses and payments you save while offline wait in a queue and sync when TREK is back online. Receipts are the exception, see [Receipts and invoices](#receipts-and-invoices).
|
||||
|
||||
## AI assistant
|
||||
|
||||
The in-app AI assistant can propose expenses, payments and settle-ups as cards in the chat, and give cost estimates for a trip. Nothing is saved until you confirm a card.
|
||||
|
||||
## Costs summary
|
||||
|
||||
Four cards sit above the ledger:
|
||||
|
||||
@@ -10,6 +10,9 @@ There are two feeds, each with its own way in:
|
||||
|
||||
- **Per-trip feed**: in the trip planner, click **Export** at the top of the days column. Under **Calendar**, pick **Subscribe to calendar** (*Auto-updates in your calendar app*). The row above it, **Download .ics**, is the one-off file. The subscribe row only appears if you may manage the trip's share links, see [Permissions](#permissions).
|
||||
- **All-trips feed**: on the **My Trips** dashboard, click the calendar-plus button in the toolbar, **Subscribe to all trips**.
|
||||
- **On a phone**: the trip's export sheet has **Subscribe to calendar**, and the phone dashboard has a button for the all-trips feed.
|
||||
|
||||
The feed is managed under **Export**, not in **Trip settings** (People, Sharing and Journal).
|
||||
|
||||

|
||||
|
||||
@@ -60,13 +63,13 @@ Use **Regenerate** when a link has leaked, and **Turn off** when you no longer w
|
||||
The feed carries the same events as the `.ics` download:
|
||||
|
||||
- **The trip itself**: an all-day event from the trip's start to its end date, with the trip description.
|
||||
- **Timed stops**: one event per place in the day plan that has a time, titled with the place name, with its address as the location and its notes as the description. Times follow the place's own time zone.
|
||||
- **Timed stops**: one event per place in the day plan that has a time, titled with the place name, with its address as the location and its notes as the description. Times follow the place's own time zone. A stop with a start time but no end time lasts as long as the place's duration, when one is set; without a duration your calendar app picks its own default length. An end time you set always wins.
|
||||
- **A summary per day**: an all-day event for every day with untimed places or notes, titled with the day's title (or *Day N*), listing those places and notes.
|
||||
- **Bookings** of every type, transport included. Flights and other rides take their start and end from the departure and arrival points, each in its own time zone. A booking with no date that can be placed is left out.
|
||||
- **Connections**: a flight, train or cruise with several legs becomes one event per leg, titled *{title}: FRA → BER*, with each leg's own departure, arrival and segment reference, each in the time zone of its own stops, so the layover (or the stay in a port of call) shows as the gap between them. This needs a departure date and time on every leg; otherwise the booking stays one event.
|
||||
- **Accommodations**: an all-day event covering every night of the stay, from the arrival day to the departure day, so the hotel sits above those days rather than showing up once on the day you check in. The dates come from the trip days the stay is attached to, so reordering days moves the event with them.
|
||||
- **Check-in and check-out**: separate timed events on the arrival and departure days whenever the stay has those times. If you entered a check-in window, its end becomes the event's end time.
|
||||
- **Car pickup and drop-off**: a booking of type *Car* also gets two timed events of its own, *Pickup: {title}* and *Drop-off: {title}*, next to the rental's own event, both with the booking's location. Each side prefers its own endpoint (the pickup point for the pickup, the return point for the drop-off) and takes that endpoint's local time and time zone. Otherwise it falls back to the booking's own times and to the time zone of the linked place. A side with no usable date and time from either source is left out, so a rental imported with only one located endpoint can end up with a single event.
|
||||
- **Check-in and check-out**: separate timed events on the arrival and departure days whenever the stay has those times. If you entered a check-in window, its end becomes the event's end time. Without one, the event lasts 60 minutes, because calendar apps collapse events of no length.
|
||||
- **Car pickup and drop-off**: when pickup and return fall on the same day, a booking of type *Car* gets two timed events of its own, *Pickup: {title}* and *Drop-off: {title}*, next to the rental's own event, both with the booking's location. When the two ends fall on different days, the rental's own block is replaced by the two hand-over events; they carry the booking's description and last 60 minutes each. *Parking* works the same way with the wording the other way round: *Drop-off* comes first and *Pickup* after. Each side prefers its own endpoint (the pickup point for the pickup, the return point for the drop-off) and takes that endpoint's local time and time zone. Otherwise it falls back to the booking's own times and to the time zone of the linked place. A side with no usable date and time from either source is left out, so a rental imported with only one located endpoint can end up with a single event.
|
||||
|
||||
Feeds are sent with headers that tell clients not to cache them, plus a hint to refresh every hour (`REFRESH-INTERVAL` and `X-PUBLISHED-TTL`). Most calendar apps treat that as a suggestion. Google in particular refreshes on its own schedule, often far less often, so an edit can take a while to show up there.
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ Emoji are drawn with Twemoji, so they look the same on every platform.
|
||||
|
||||
Hover a message to bring up its buttons. **Reply** (the arrow) quotes that message: a preview with a bar in the accent colour appears above the field, with an **×** to cancel. Once sent, the quoted text sits inside your bubble above your answer.
|
||||
|
||||
## Answers from the assistant
|
||||
|
||||
With the AI assistant on, a member can share one of its answers into the trip chat with **Share in the trip chat**. Everyone on the trip then sees the message marked **from the assistant**; hovering the badge reads *(name) shared this answer from the assistant*. The badge is set by the server, so nobody can fake it by typing into a normal message.
|
||||
|
||||
## URL link previews
|
||||
|
||||
When a message contains a web address, TREK fetches an Open Graph preview (site, title, description and image) and shows it under the text. Only the first address in a message gets a preview.
|
||||
|
||||
@@ -27,7 +27,7 @@ Open the trip planner, select the **Collab** tab and look for the card headed **
|
||||
|
||||
## The poll card
|
||||
|
||||
Each poll is a card. Its head band holds the question and, under it, small chips: **Closed** when voting has ended, the time left while a deadline runs (for example `2d 5h`), **Multiple choice** for such a poll, and the number of votes. Members with `collab_edit` find two round buttons on the right: the lock (**Close**) while the poll is open, and the bin (**Delete**).
|
||||
Each poll is a card. Its head band holds the question and, under it, small chips: **Closed** when voting has ended, the time left while a deadline runs (for example `2d 5h left`), **Multiple choice** for such a poll, and the number of votes. Members with `collab_edit` find two round buttons on the right: the lock (**Close**) while the poll is open, and the bin (**Delete**).
|
||||
|
||||
Below the head band every option is a bar you can click.
|
||||
|
||||
|
||||
+3
-1
@@ -12,7 +12,9 @@ A place you save to a trip only exists inside that trip. Collections is the oppo
|
||||
|
||||
## Accessing Collections
|
||||
|
||||
When the admin has enabled the addon, a **Collections** entry appears in the main navigation (and a bottom-tab on mobile). Opening it shows your lists on the left, the active list's places in the middle, and a map on the right. **Expand map** above the map gives it the whole width, and **Show list** brings the places back.
|
||||
When the admin has enabled the addon, a **Collections** entry appears in the main navigation (and a bottom-tab on mobile). Opening it shows your lists on the left, the active list's places in the middle, and a map on the right. **Expand map** above the map gives it the whole width, and **Show list** brings the places back. In a window too narrow for the three columns, a **List** / **Map** switch in the toolbar changes between the places and the map (it appears once at least one saved place has coordinates).
|
||||
|
||||
With the AI assistant on, it can also read and manage your lists for you, for example saving a place to a list or accepting and declining list invites.
|
||||
|
||||
The dashboard also gains a **Collections widget** that surfaces your lists as compact badges. Each user can hide that widget from their own dashboard under **Dashboard widgets** on the Appearance tab (see [Appearance-Settings](Appearance-Settings)) without affecting anyone else.
|
||||
|
||||
|
||||
+12
-3
@@ -8,6 +8,8 @@ Thanks for your interest in contributing to TREK! Here are the guidelines for su
|
||||
- **Check existing issues** — Look for open issues or discussions before starting work
|
||||
- **Target the `dev` branch** — All PRs must be opened against `dev`, not `main`. Exception: PRs that only modify files under `wiki/` may target any branch
|
||||
- **One thing per PR** — Keep PRs focused on a single change. Don't bundle unrelated fixes
|
||||
- **Tests are required**: Your change must come with tests. The project holds 80% or more coverage, and a PR that drops it is closed
|
||||
- **Stay up to date**: Your branch must be [up to date with `dev`](Development-environment#3-keep-your-fork-up-to-date) before you submit
|
||||
|
||||
## Pull Request Guidelines
|
||||
|
||||
@@ -36,13 +38,18 @@ feat(component): short description of new feature
|
||||
|
||||
### PR Description
|
||||
|
||||
Follow the template provided by default (.github/PULL_REQUEST_TEMPLATE.md).
|
||||
Follow the template provided by default (.github/PULL_REQUEST_TEMPLATE.md). A PR description contains:
|
||||
|
||||
- **Summary:** what changes and why, in one to three bullet points
|
||||
- **Test plan:** how you verified it works
|
||||
- **Linked issue:** for example `Fixes #123`
|
||||
|
||||
### What Will Get Your PR Closed
|
||||
|
||||
- PRs that weren't discussed and approved in `#github-pr` on Discord first
|
||||
- PRs that add unnecessary complexity (e.g. a redo button when undo already exists)
|
||||
- PRs with breaking changes
|
||||
- PRs that reformat or refactor unrelated code
|
||||
- PRs that change code style or formatting across unrelated files
|
||||
- PRs that add dependencies without justification
|
||||
|
||||
@@ -59,9 +66,11 @@ See the [[Development Environment|Development-environment]] page for the full se
|
||||
| Real-time | WebSocket (ws) |
|
||||
| Database | SQLite with WAL mode |
|
||||
| Auth | JWT (HS256), bcrypt, TOTP MFA, passkeys (WebAuthn), OIDC |
|
||||
| Maps | Leaflet + react-leaflet (default, OpenFreeMap vector basemap via maplibre-gl-leaflet), MapLibre GL, Mapbox GL, OSRM, Nominatim |
|
||||
| Maps | Leaflet + react-leaflet (default, OpenFreeMap vector basemap via maplibre-gl-leaflet), MapLibre GL 5, Mapbox GL 3, OSRM, Nominatim |
|
||||
| i18n | 27 languages, EN canonical (locale directories live in shared/src/i18n/) |
|
||||
|
||||
Documentation changes go to `wiki/`. The same pages ship inside the app: the in-app help reads them (served under `/api/help`) and links into them, and the MCP help tools search them, so a wiki edit reaches users with the next release as well as the GitHub wiki.
|
||||
|
||||
Every translation key must exist in all 27 locales — the `Shared: i18n Parity` CI job fails on drift, so run `npm run i18n:parity:strict --workspace=shared` before pushing. Two directory names differ from the language they hold: Brazilian Portuguese is `br`, Greek is `gr`.
|
||||
Beyond the tests, CI enforces a set of quality gates: type checks, lint ratchets that may only shrink, and a SonarCloud gate on new code (80% coverage, at most 3% duplicated lines). The [[Development Environment|Development-environment]] page lists the commands, and the `CLAUDE.md` file of each package explains its rules. Desktop and phone views of a feature share one hook, so a feature that touches both keeps its logic in that hook.
|
||||
|
||||
Every translation key must exist in all 27 locales, the `Shared: i18n Parity` CI job fails on drift, so run `npm run i18n:parity:strict --workspace=shared` before pushing. Add a real translation to every locale; an English placeholder in a non-English file is not accepted. Two directory names differ from the language they hold: Brazilian Portuguese is `br`, Greek is `gr`.
|
||||
|
||||
+12
-1
@@ -43,7 +43,7 @@ The cover image is displayed on the trip card and as the background of the Spotl
|
||||
- **Drag and drop** an image file onto the dashed upload area.
|
||||
- **Paste from clipboard**: if you have an image in your clipboard, paste it anywhere in the dialog.
|
||||
- **File picker**: click the upload area to browse for a file.
|
||||
- **Search Unsplash**: type a query to pick a stock photo. If this returns *"Unsplash search unavailable"* (common on VPS/datacenter IPs), configure a free Unsplash Access Key; see [Environment-Variables → Image Search (Unsplash)](Environment-Variables#image-search-unsplash).
|
||||
- **Search Unsplash**: type a query into the **Search destination photos** field and click **Search Unsplash** to pick a stock photo. With the field empty, the button searches for the trip title. If this returns *"Unsplash search unavailable"* (common on VPS/datacenter IPs), configure a free Unsplash Access Key; see [Environment-Variables → Image Search (Unsplash)](Environment-Variables#image-search-unsplash).
|
||||
|
||||
When **creating** a new trip the cover image field is always visible. When **editing** an existing trip it is only shown if you have the `trip_cover_upload` permission. For a new trip, the image is uploaded immediately after the trip is created.
|
||||
|
||||
@@ -69,6 +69,16 @@ A new trip starts on **3 days**. If reminders are switched off on your instance,
|
||||
|
||||
Add initial trip members under **Travel buddies**. On a **new** trip, selected members are queued locally and added to the trip immediately after it is saved. The selector shows all registered users on your instance except yourself.
|
||||
|
||||
Once the trip exists, people are managed from the planner instead: the **Trip settings** pill in the top bar opens **People** (members and guests without an account) and **Sharing** (the read-only link and the invite link). See [Trip-Members-and-Sharing](Trip-Members-and-Sharing).
|
||||
|
||||
## Changing the start date
|
||||
|
||||
When you move the start date of an existing trip, a step called **New start date** asks how your plans follow: **Keep bookings on their dates** moves the day plans with the new dates while reservations and accommodations stay on their original dates as long as those are still part of the trip, and **Shift everything** moves the entire itinerary, bookings included. If the new dates hold fewer days than the plan, a **Remove days?** step lists what goes first; see [Shortening a trip](Day-Plans-and-Notes#shortening-a-trip).
|
||||
|
||||
## Editing offline
|
||||
|
||||
Editing a trip uses this same dialog. While you are offline, the name, description and reminder can be changed, and they are sent when the connection is back. New dates, a different number of days, another currency or a new cover need a connection.
|
||||
|
||||
## Saving
|
||||
|
||||
Click **Create New Trip** (when editing, the button reads **Update**). The trip is saved, the dialog closes and a *"Trip created successfully!"* toast confirms it, and you stay on the dashboard. The new trip is sorted into the trip list by its dates; click its card (or the Spotlight card, if it is the trip that earns that spot) to open the [Trip-Planner-Overview](Trip-Planner-Overview).
|
||||
@@ -78,3 +88,4 @@ Click **Create New Trip** (when editing, the button reads **Update**). The trip
|
||||
- [Trip-Members-and-Sharing](Trip-Members-and-Sharing)
|
||||
- [Trip-Planner-Overview](Trip-Planner-Overview)
|
||||
- [My-Trips-Dashboard](My-Trips-Dashboard)
|
||||
- [Trip-Settings](Trip-Settings)
|
||||
|
||||
+13
-7
@@ -4,7 +4,7 @@ TREK has **three** currency settings, and they answer three different questions.
|
||||
|
||||
| Setting | Where | Question it answers | Affects |
|
||||
|---|---|---|---|
|
||||
| **Trip currency** | Trip → Edit trip | *What is this trip's money?* | Stored data: the base every balance is calculated in |
|
||||
| **Trip currency** | My Trips → pencil on the trip card (**Edit Trip**) | *What is this trip's money?* | Stored data: the base every balance is calculated in |
|
||||
| **Expense currency** | Costs → expense modal | *What currency did I actually pay in?* | Stored data: that one expense |
|
||||
| **Display currency** | Settings → General → Language & region | *What currency do I want to read?* | Presentation only, never the stored data |
|
||||
|
||||
@@ -12,7 +12,7 @@ The short version: **the trip currency is the accounting base, the expense curre
|
||||
|
||||
## Trip currency
|
||||
|
||||
Every trip has exactly one currency. It is set when you create the trip and can be changed later in the trip edit dialog (requires the `trip_edit` permission). The new-trip dialog pre-fills it with **your display currency**, falling back to **EUR** when you have left that on *Trip currency*. A trip created through MCP or by a plugin without a currency gets the same value. This is the one moment the display currency touches stored data: it seeds the field, and from then on the trip's currency is its own.
|
||||
Every trip has exactly one currency. It is set when you create the trip and can be changed later in the same dialog: on **My Trips**, click the pencil on the trip card (**Edit Trip**). This needs the `trip_edit` permission. The **Trip settings** pill beside the trip name in the planner does not hold the currency; it only holds People, Sharing and Journal. The new-trip dialog pre-fills it with **your display currency**, falling back to **EUR** when you have left that on *Trip currency*. A trip created through MCP or by a plugin without a currency gets the same value. This is the one moment the display currency touches stored data: it seeds the field, and from then on the trip's currency is its own.
|
||||
|
||||
This is the trip's **accounting base**. It is not a cosmetic label:
|
||||
|
||||
@@ -46,7 +46,11 @@ Rates come from [Frankfurter](https://frankfurter.dev) (European Central Bank da
|
||||
|
||||
### Settle-up payments
|
||||
|
||||
A payment recorded in **Settle Up** also carries its own currency, for the same reason: settling a rouble debt with a euro transfer is perfectly normal. Its rate is frozen at the moment you record it, exactly like an expense's, so the payment keeps cancelling the debt it was meant to cancel.
|
||||
A payment recorded in **Settle Up** also carries its own currency, for the same reason: settling a rouble debt with a euro transfer is perfectly normal. Its rate is frozen at the moment you record it, exactly like an expense's, so the payment keeps cancelling the debt it was meant to cancel. A payment counts on the local day you give it, not on the day of the server.
|
||||
|
||||
## Decimals and formats
|
||||
|
||||
Every currency is shown with its own number of decimals. Most use two. The Japanese yen, Korean won, Vietnamese dong, Chilean peso, Icelandic krona and Hungarian forint have none, and the Bahraini, Iraqi, Jordanian, Kuwaiti, Libyan, Omani and Tunisian currencies have three. Amounts you type follow the same rule, and the suggested transfers in **Settle up** for won and yen are whole units, so the balances add up and settling clears them.
|
||||
|
||||
## Display currency
|
||||
|
||||
@@ -65,6 +69,8 @@ Leave it on **Trip currency** unless you specifically want everything in your ho
|
||||
|
||||
An administrator can set an instance-wide default (Admin → User Defaults), and it interacts with **Trip currency**: picking **Trip currency** stores an *empty* value, and an empty value on a defaultable setting counts as "not set", so the admin's currency is applied again (#1634). While an instance-wide default currency is configured, there is no way back to per-trip currencies from the Settings page; the admin has to clear it.
|
||||
|
||||
> The **Currency** converter widget on the dashboard is a separate tool. It converts an amount between two currencies and has no effect on trips or stored costs. See [Dashboard-Widgets](Dashboard-Widgets).
|
||||
|
||||
> Display conversion uses **live** rates, not the frozen ones: it is a view, and a view should reflect today. This is why a converted total can shift slightly day to day while the underlying balances stay rock steady.
|
||||
|
||||
An expense you enter in your display currency reads back exactly as you typed it on the day you enter it, on its row, in the totals and in the final budget, and paying the amount settle-up offers for it leaves both balances at zero. When the rate has moved since, the row shows the value the totals count, with what was entered and the trip-currency amount it was booked at underneath (`$801.76 → 685,26 €`).
|
||||
@@ -92,7 +98,7 @@ A public share page has no logged-in viewer, so it cannot use "your" display cur
|
||||
|
||||
## Relationship with the Costs addon
|
||||
|
||||
The **trip currency lives on the trip itself**, not in the Costs addon. It is set in the trip dialog and remains set even if Costs is disabled. Expense currencies, frozen rates and settle-up all belong to **Costs** (addon id `budget`), which an admin can toggle in [Admin-Addons](Admin-Addons). Turning Costs off hides the money features; it does not clear the trip's currency.
|
||||
The **trip currency lives on the trip itself**, not in the Costs addon. It is set in the trip's create and edit dialog and remains set even if Costs is disabled. Expense currencies, frozen rates and settle-up all belong to **Costs** (addon id `budget`), which an admin can toggle in [Admin-Addons](Admin-Addons). Turning Costs off hides the money features; it does not clear the trip's currency.
|
||||
|
||||
Changing the trip currency requires `trip_edit`. Adding or editing expenses (and their currencies) requires `budget_edit`. See [Admin-Permissions](Admin-Permissions).
|
||||
|
||||
@@ -112,8 +118,8 @@ Its rate was frozen when it was entered, and the market has moved since. That is
|
||||
|
||||
## See also
|
||||
|
||||
- [Budget-Tracking](Budget-Tracking) — the Costs tab
|
||||
- [Creating-a-Trip](Creating-a-Trip) — where the trip currency is set
|
||||
- [Display-Settings](Display-Settings) — where the display currency is set
|
||||
- [Budget-Tracking](Budget-Tracking), the Costs tab
|
||||
- [Creating-a-Trip](Creating-a-Trip), where the trip currency is set
|
||||
- [Display-Settings](Display-Settings), where the display currency is set
|
||||
- [Public-Share-Links](Public-Share-Links)
|
||||
- [Admin-Addons](Admin-Addons)
|
||||
|
||||
@@ -249,8 +249,10 @@ Each request to Dawarich gives up after 15 seconds, and TREK reads at most 8 MB
|
||||
|
||||
## See also
|
||||
|
||||
- [Help Center](Help-Center): guides for the screens Dawarich appears on, with a picture of each step
|
||||
- [Public API](Public-API): how Dawarich reads your trips
|
||||
- [Atlas](Atlas): the bucket list and the visited countries map
|
||||
- [Journey Journal](Journey-Journal): where accepted stays become entries
|
||||
- [Internal Network Access](Internal-Network-Access): reaching an instance on your LAN
|
||||
- [Addons Overview](Addons-Overview): the full addon table
|
||||
- [wanderer](Wanderer): trails from your own wanderer instance, imported as tours
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Day Plans and Notes
|
||||
|
||||
The days column on the left of the Plan tab holds the itinerary: one card per day, with the places, bookings, transports and notes of that day in order.
|
||||
The days column on the left of the Plan tab holds the itinerary: one card per day, with the places, bookings, transports, tours and notes of that day in order.
|
||||
|
||||

|
||||
|
||||
@@ -41,7 +41,7 @@ An empty day shows a dashed **Add place to this day** button instead of an empty
|
||||
|
||||
## Day timeline
|
||||
|
||||
An expanded day lists its places, bookings, transports and notes in one merged order: by time where they have one, and by their position otherwise.
|
||||
An expanded day lists its places, bookings, transports, tours and notes in one merged order: by time where they have one, and by their position otherwise.
|
||||
|
||||
### Places
|
||||
|
||||
@@ -71,6 +71,16 @@ Clicking the row opens the booking's detail, see [Bookings on the plan](Trip-Pla
|
||||
|
||||
A note row shows its icon in the note's colour, the title and, under it, the text, rendered as Markdown. Click a note to edit it. See [Day notes](#day-notes).
|
||||
|
||||
### Tours
|
||||
|
||||
While the Tours addon is on, a tour put on a day is a row of its own, like any stop. It has no entry in the **+** menu: a tour comes onto a day from the Tours list in the places column, by dragging or with its **Add to day** button; see [Putting a tour on a day](Tours#putting-a-tour-on-a-day).
|
||||
|
||||
- The row can carry a **Start** and an **End**, worked out from the tour's time when you only give a start. See [Tour times in the day plan](Tours#tour-times-in-the-day-plan).
|
||||
- A day that holds one stage of a multi-day tour shows it as **Stage N**, with its own distance and time. See [Multi-day tours on the trip days](Tours#multi-day-tours-on-the-trip-days).
|
||||
- A city walk shows how many of its stops you have checked off, for example **3/7**. See [Checking off a city walk](Tours#checking-off-a-city-walk).
|
||||
- When two city walks are on the same day, the leg between them can be planned by public transit. See [Public transit between city walks](Tours#public-transit-between-city-walks).
|
||||
- The row's **…** menu (*More options*) offers **Edit** for the times, **Remove from day**, **Leave out of route**, **Open Website** and **Save to Collection**. There is no **Delete** for a tour here.
|
||||
|
||||
### The row menu
|
||||
|
||||
Every place and note row has a **…** button (*More options*) at its right end, which offers the same actions as a right-click on the row:
|
||||
@@ -204,4 +214,4 @@ The save button then reads **Remove days and save**. When the start moved, the s
|
||||
|
||||
On a trip without dates, a lower **Day count** only takes away days with no places, notes or stay on them, starting from the end. A day with plans on it stays.
|
||||
|
||||
**See also:** [Trip Planner Overview](Trip-Planner-Overview) · [Places-and-Search](Places-and-Search) · [Map-Features](Map-Features) · [Route-Optimization](Route-Optimization) · [Weather-Forecasts](Weather-Forecasts) · [Accommodations](Accommodations) · [Reservations-and-Bookings](Reservations-and-Bookings)
|
||||
**See also:** [Trip Planner Overview](Trip-Planner-Overview), [Places-and-Search](Places-and-Search), [Map-Features](Map-Features), [Route-Optimization](Route-Optimization), [Weather-Forecasts](Weather-Forecasts), [Accommodations](Accommodations), [Reservations-and-Bookings](Reservations-and-Bookings), [Tours](Tours)
|
||||
|
||||
+26
-12
@@ -1,6 +1,6 @@
|
||||
# Demo Mode
|
||||
|
||||
Demo mode lets you run a public "try before you install" instance of TREK. A shared demo account is available for visitors, write operations are blocked for that account, and the database resets automatically every hour so the instance stays in a known state.
|
||||
Demo mode lets you run a public "try before you install" instance of TREK. A shared demo account is available for visitors, who can view, edit and create trips. Account-level and upload operations are blocked for that account, and the database resets automatically every hour so the instance stays in a known state.
|
||||
|
||||
<!-- TODO: screenshot: demo mode banner or try-demo button on login page -->
|
||||
|
||||
@@ -8,7 +8,7 @@ Demo mode lets you run a public "try before you install" instance of TREK. A sha
|
||||
|
||||
Set `DEMO_MODE=true` in your environment and restart TREK. See [Environment-Variables](Environment-Variables) for how to set environment variables.
|
||||
|
||||
When demo mode is active, the login page shows a one-click **"Try the demo"** button. Clicking it logs the visitor in as the demo user immediately — no credentials need to be entered and no registration is required.
|
||||
When demo mode is active, the login page shows a one-click **Try the demo** button ("no registration needed"). Clicking it logs the visitor in as the demo user immediately. No credentials need to be entered and no registration is required.
|
||||
|
||||
**Demo account (auto-created on first start):**
|
||||
|
||||
@@ -19,17 +19,31 @@ When demo mode is active, the login page shows a one-click **"Try the demo"** bu
|
||||
|
||||
**Admin account:** an admin account is also seeded on first start. By default it uses username `admin`, email `admin@trek.app`, and password `admin12345`. You can override these at seed time with the `DEMO_ADMIN_USER`, `DEMO_ADMIN_EMAIL`, and `DEMO_ADMIN_PASS` environment variables (they only take effect when `DEMO_MODE=true`, on the first start before the database is seeded). See [Environment-Variables](Environment-Variables).
|
||||
|
||||
## The welcome popup
|
||||
|
||||
Every time the dashboard opens for a demo visitor, a **Welcome to the TREK Demo** popup appears over it. It is shown in the visitor's language when TREK has a translation for it. It holds:
|
||||
|
||||
- A short description: visitors can view, edit and create trips, and all changes are reset every hour.
|
||||
- A live countdown, **Next reset in N minutes**, counted to the top of the next hour.
|
||||
- A note that file uploads (photos, documents, covers) are disabled in demo mode.
|
||||
- **What is TREK?**, a one line description of the product.
|
||||
- **Modular Addons**, six tiles for Vacay, Atlas, Packing, Budget, Documents and Widgets with a line each. These are the addons a self-hosted admin can switch off.
|
||||
- **Additionally in the full version**: file uploads, API key management, user and permission management, automatic backups, addon management and OIDC / SSO.
|
||||
- An open source note with a **self-host it** link.
|
||||
|
||||
**Got it** closes the popup. It appears again the next time the dashboard loads.
|
||||
|
||||
## What the demo user can and cannot do
|
||||
|
||||
The demo user account has read access to the shared trip data but the following operations are permanently blocked:
|
||||
The demo user can work with the shared example trips like any member, but the following operations are permanently blocked:
|
||||
|
||||
- **Password change** — returns 403.
|
||||
- **Account deletion** — returns 403.
|
||||
- **MFA enrollment or removal** — returns 403.
|
||||
- **File uploads** — avatar uploads, trip cover uploads, and document/photo file attachments are blocked and return 403.
|
||||
- **All MCP write tools** — create, update, and delete operations via the MCP API are blocked for the demo user.
|
||||
- **Password change**: returns 403.
|
||||
- **Account deletion**: returns 403.
|
||||
- **MFA enrollment or removal**: returns 403. The 2FA card in Settings says it is not available in demo mode, and the Passkeys card is hidden.
|
||||
- **File uploads**: avatar uploads, trip cover uploads, and document/photo file attachments are blocked and return 403.
|
||||
- **All MCP write tools**: create, update, and delete operations via the MCP API are blocked for the demo user.
|
||||
|
||||
Registration is also disabled while demo mode is active — visitors cannot create new accounts.
|
||||
Registration is also disabled while demo mode is active; visitors cannot create new accounts.
|
||||
|
||||
The admin account is unaffected and retains full access.
|
||||
|
||||
@@ -38,11 +52,11 @@ The admin account is unaffected and retains full access.
|
||||
TREK schedules an automatic hourly reset of the demo database. At each reset:
|
||||
|
||||
1. The current `travel.db` is replaced with the saved baseline (`travel-baseline.db`).
|
||||
2. The admin account's credentials (`password_hash`, API keys, avatar) are re-applied on top of the restored baseline, so admin API keys and password changes survive the reset — but only when `DEMO_ADMIN_EMAIL` is set explicitly.
|
||||
2. The admin account's credentials (`password_hash`, API keys, avatar) are re-applied on top of the restored baseline, so admin API keys and password changes survive the reset, but only when `DEMO_ADMIN_EMAIL` is set explicitly.
|
||||
|
||||
If no baseline has been saved yet, the reset is skipped and a message is logged.
|
||||
|
||||
The seeder defaults the admin address to `admin@trek.app` while the reset defaults it to `admin@nomad.app`, a legacy quirk that is pinned deliberately. With `DEMO_ADMIN_EMAIL` unset the reset looks up an address that does not exist, finds no admin row, and skips the carry-over entirely — a password change, API key or avatar set after the baseline was saved is lost on every hourly reset. Set `DEMO_ADMIN_EMAIL` (to `admin@trek.app`, for instance) if you want them to survive. Unlike the seed-time variables above, the reset reads it on every run, so setting it on an already-seeded instance and restarting is enough.
|
||||
The seeder defaults the admin address to `admin@trek.app` while the reset defaults it to `admin@nomad.app`, a legacy quirk that is pinned deliberately. With `DEMO_ADMIN_EMAIL` unset the reset looks up an address that does not exist, finds no admin row, and skips the carry-over entirely; a password change, API key or avatar set after the baseline was saved is lost on every hourly reset. Set `DEMO_ADMIN_EMAIL` (to `admin@trek.app`, for instance) if you want them to survive. Unlike the seed-time variables above, the reset reads it on every run, so setting it on an already-seeded instance and restarting is enough.
|
||||
|
||||
The instance-wide Maps and Unsplash keys stored in `app_settings` are carried across either way, so map and photo search keep working after a reset.
|
||||
|
||||
@@ -61,7 +75,7 @@ On first start with demo mode active, TREK seeds three example trips (Tokyo & Ky
|
||||
## Limitations
|
||||
|
||||
- Demo mode is not for production use with real user data. The hourly reset deletes all visitor-created content.
|
||||
- All demo visitors share a single account — there is no isolation between sessions.
|
||||
- All demo visitors share a single account; there is no isolation between sessions.
|
||||
- Because the demo account is shared, its session list (`GET /api/auth/sessions`) shows each visitor only their own session, and ending sessions (`DELETE /api/auth/sessions/{id}`, `POST /api/auth/sessions/revoke-others`) answers 403 `Sessions cannot be ended in demo mode.`, so one visitor cannot see or sign out the others. Logging out still ends the visitor's own session.
|
||||
- File uploads (photos, documents, trip covers, avatars) are disabled for the demo user.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js 24, the version in `.nvmrc` and the one the Docker image and CI run (`nvm use` or `fnm use` picks it up). 22.22.2 or later still installs, but nothing tests it.
|
||||
- Node.js 24, the version in `.nvmrc` and the one the Docker image and CI run (`nvm use` or `fnm use` picks it up). The `engines` field accepts 24.15 or later, 22.22.2 or later on the 22 line, or 26 and above; the 22 line installs, but nothing tests it.
|
||||
- npm
|
||||
- Git
|
||||
- Python 3 and a C++ toolchain (`build-essential` on Debian/Ubuntu, the Xcode Command Line Tools on macOS, the Visual Studio Build Tools on Windows). better-sqlite3 ships prebuilt binaries, but a lockfile-driven `npm install` still runs node-gyp against them and stops without these (npm/cli#9837).
|
||||
@@ -132,6 +132,9 @@ These commands run across all workspaces at once and are the recommended way to
|
||||
| `npm run lint:fix` | Apply ESLint's fixes in shared and server |
|
||||
| `npm run format` | Format shared, server, and client |
|
||||
| `npm run format:check` | Check formatting across all workspaces |
|
||||
| `npm run lint:knip` | Unused files, exports, types and dependencies may only shrink against a baseline (CI gate) |
|
||||
| `npm run test:ci-scripts` | Tests of the scripts under `scripts/ci/` |
|
||||
| `npm run test:lib-scripts` | Tests of the scripts under `scripts/lib/` |
|
||||
|
||||
### Shared (`/shared`)
|
||||
|
||||
@@ -154,6 +157,8 @@ The `@trek/shared` package is the single source of truth for code shared between
|
||||
| `npm run format` | Format source |
|
||||
| `npm run format:check` | Check formatting |
|
||||
| `npm run contracts:open` | Open shapes in the request contracts may only shrink (CI gate) |
|
||||
| `npm run i18n:untranslated` | Report strings that are still identical to English in a locale; the count may only shrink |
|
||||
| `npm run i18n:untranslated:update` | Lower the baseline of that report after you translated strings |
|
||||
|
||||
### Server (`/server`)
|
||||
|
||||
@@ -189,6 +194,18 @@ The `@trek/shared` package is the single source of truth for code shared between
|
||||
| `npm run probe:pg` | Run the dialect helpers and repository statements against Postgres (CI job, needs `TREK_PG_PROBE_URL`) |
|
||||
| `npm run lint:format` | Every file outside the shrinking baseline is Prettier-formatted (CI gate) |
|
||||
| `npm run lint:strict` | Strict type errors per file may not grow past their baseline; a new file has none (CI gate) |
|
||||
| `npm run lint:test-mocks` | `vi.mock` of config, realtime and database modules in `tests/` may not grow past their baseline (CI gate) |
|
||||
| `npm run lint:test-new-service` | Hand-built services and repositories in `tests/` may not grow past their baseline (CI gate) |
|
||||
| `npm run lint:mcp-zod` | Inline Zod in the MCP tool files may not grow past its baseline; fields derive from `@trek/shared` (CI gate) |
|
||||
| `npm run lint:service-http` | `{ error, status }` results in services may not grow past their baseline; services throw `DomainError` (CI gate) |
|
||||
| `npm run lint:response-contracts` | Route handlers without `@ResponseContract` may not grow past their baseline (CI gate) |
|
||||
| `npm run contracts:dto-open` | Open shapes in the server DTOs may only shrink (CI gate) |
|
||||
| `npm run gen:entities` | Regenerate the MikroORM entities from the migrated schema |
|
||||
| `npm run check:entities` | Verify the entities match the migrated schema (CI gate) |
|
||||
| `npm run typecheck:scripts` | Type-check the scripts under `scripts/` (CI gate) |
|
||||
| `npm run db:call-graph` | Lists server methods that touch the database synchronously or leave a promise unawaited; the list may not grow (CI gate) |
|
||||
| `npm run start:prod` | Run the compiled server from `dist/` |
|
||||
| `npm run reset-admin` | Reset or create an admin account when you are locked out |
|
||||
| `npm run format` | Format source |
|
||||
|
||||
### Client (`/client`)
|
||||
@@ -210,6 +227,7 @@ The `@trek/shared` package is the single source of truth for code shared between
|
||||
| `npm run lint:pages` | Enforce the Page pattern (CI gate) |
|
||||
| `npm run lint:rtl` | Physical left/right styling may not grow past its baseline, so the layout follows the reading direction (CI gate) |
|
||||
| `npm run lint:size` | No file grows past its line limit or its baseline entry (CI gate) |
|
||||
| `npm run lint:strict` | Strict type errors per file may only shrink; a new file has none (CI gate) |
|
||||
| `npm run lint:format` | Every file outside the shrinking baseline is Prettier-formatted (CI gate) |
|
||||
| `npm run lint:layers` | Imports only go downwards through the layers (CI gate) |
|
||||
| `npm run lint:offline` | Views reach `src/api/` only through the offline core; the baseline only shrinks (CI gate) |
|
||||
@@ -223,6 +241,7 @@ The `@trek/shared` package is the single source of truth for code shared between
|
||||
| `npm run e2e` | Playwright end-to-end tests; CI runs the public and app projects in Chromium and WebKit, the screenshot and help-media projects are local only |
|
||||
| `npm run shots` | Capture the wiki screenshots with Playwright |
|
||||
| `npm run shots:promote` | Downscale the captured screenshots and move them into `wiki/assets/` |
|
||||
| `npm run e2e:report` | Open the HTML report of the last Playwright run |
|
||||
| `npm run help:media` | Record the help-center pictures against the real app on its own ports, so `npm run dev` can keep running |
|
||||
| `npm run help:media:promote` | Convert the recorded help pictures to WebP and move them into `public/help-media/` |
|
||||
| `npm run format` | Format source |
|
||||
@@ -249,9 +268,9 @@ Then open a Pull Request from your fork to `liketrek/TREK` targeting the `dev` b
|
||||
## Tips
|
||||
|
||||
- Always branch off from an up-to-date `dev` — run `git fetch upstream && git rebase upstream/dev` before starting new work.
|
||||
- Run tests before pushing: `npm test` at the repo root runs all workspaces. That alone is not the full CI gate. With `shared` built, these are the checks CI runs beside the tests (`.github/workflows/test.yml` is the source of truth):
|
||||
- in `shared/`: `npm run typecheck && npm run contracts:open`
|
||||
- in `server/`: `npm run build && npm run typecheck && npm run typecheck:tests && npm run typecheck:scripts && npm run check:entities && npm run check:db-types && npm run lint:check && npm run db:call-graph -- --sync --tx && npm run lint:size && npm run lint:boundaries && npm run lint:tx && npm run lint:test-sql && npm run lint:query-api && npm run lint:dialect && npm run check:plugin-facts`
|
||||
- in `client/`: `npm run typecheck && npm run lint:warnings && npm run lint:pages && npm run lint:rtl && npm run lint:size && npm run lint:format && npm run lint:layers && npm run lint:offline && npm run lint:dup && npm run lint:pairs && npm run lint:skips && npm run lint:i18n-keys`
|
||||
- at the root, if you touched translations: `npm run i18n:parity:strict --workspace=shared`
|
||||
- Run tests before pushing: `npm test` at the repo root runs all workspaces. That alone is not the full CI gate: CI also runs type checks, the lint ratchets of every package (the `lint:*` and `theme:lint` commands in the tables above), the i18n parity check and a SonarCloud scan that wants 80% coverage on new code and at most 3% duplicated lines. `.github/workflows/test.yml` is the source of truth for the exact list, and each package has a `CLAUDE.md` that explains its rules.
|
||||
- If you touched translations, run `npm run i18n:parity:strict --workspace=shared` before you push. Every locale needs a real translation, not an English placeholder.
|
||||
- Desktop and phone views of a feature share one hook, so a change to both belongs in that hook and not in two copies of the markup (`lint:pairs` and `lint:dup` check this).
|
||||
- Testing the S3 storage driver against a real MinIO needs the licence-gated `docker-compose.minio-test.yml` at the repo root; the comments in that file explain the setup.
|
||||
- Working on a plugin or on the SDK: install and run from `plugin-sdk/` (see step 5).
|
||||
- Follow the commit message conventions described in the [[Contributing]] guidelines.
|
||||
|
||||
@@ -6,15 +6,15 @@ The General tab (Settings → General) controls your locale preferences and a fe
|
||||
|
||||
## Where to find it
|
||||
|
||||
Open the user menu in the top navigation bar, select **Settings**, and stay on the **General** tab — it is the tab the page opens on.
|
||||
Open the user menu in the top navigation bar, select **Settings**, and stay on the **General** tab; it is the tab the page opens on.
|
||||
|
||||
The tab is split into three sections: **Startup** (where opening TREK lands), **Language & region** (currency, language, place names, temperature, distance, time format, week start) and **Travel & map** (open places in, date first in day headings, booking route labels, always show booking routes, compact markers for unplanned places, explore places on the map, blur booking codes, optimize route from accommodation).
|
||||
|
||||
> Color mode (Light / Dark / Auto) is **not** here — it lives on the **Appearance** tab. See [Appearance-Settings](Appearance-Settings).
|
||||
> Color mode (Light / Dark / Auto) is **not** here; it lives on the **Appearance** tab. See [Appearance-Settings](Appearance-Settings).
|
||||
|
||||
## Start page
|
||||
|
||||
Where TREK goes when you open it — the app root (`/`), which is also what the installed PWA and any home-screen shortcut launch.
|
||||
Where TREK goes when you open it: the app root (`/`), which is also what the installed PWA and any home-screen shortcut launch.
|
||||
|
||||
| Option | Behaviour |
|
||||
|--------|-----------|
|
||||
@@ -23,7 +23,7 @@ Where TREK goes when you open it — the app root (`/`), which is also what the
|
||||
|
||||
Your **active trip** is the one running today; if none is, the next one starting; if you have only past trips, the most recent one. That is the same trip the dashboard features in its hero, so the two never disagree. Archived trips are never picked, and if you have no trip at all, TREK opens the dashboard as usual.
|
||||
|
||||
The dashboard stays reachable at `/dashboard` — only the root redirects.
|
||||
The dashboard stays reachable at `/dashboard`; only the root redirects.
|
||||
|
||||
## Start tab
|
||||
|
||||
@@ -57,16 +57,16 @@ The parameter is consumed on arrival and disappears from the address bar; switch
|
||||
|
||||
## Currency
|
||||
|
||||
Your **display currency** — the currency you want to *read* amounts in on the Costs tab (totals, the category chart, balances, settle-up). It is presentation only: it never changes what is stored, and two members of the same trip can read it in different currencies and both see correct balances.
|
||||
Your **display currency**: the currency you want to *read* amounts in on the Costs tab (totals, the category chart, balances, settle-up). It is presentation only: it never changes what is stored, and two members of the same trip can read it in different currencies and both see correct balances.
|
||||
|
||||
| Option | Behaviour |
|
||||
|--------|-----------|
|
||||
| **Trip currency** (default) | Each trip is shown in **its own** currency — a Tokyo trip in yen, a Moscow trip in roubles. |
|
||||
| **Trip currency** (default) | Each trip is shown in **its own** currency; a Tokyo trip in yen, a Moscow trip in roubles. |
|
||||
| A specific currency (e.g. `USD`) | **Every** trip is converted into that currency for you, whatever its own currency is. |
|
||||
|
||||
165 currencies are available. Conversion uses live rates, so a converted total can shift slightly from day to day while the trip's actual balances stay fixed.
|
||||
|
||||
> This is **not** the trip's currency, which is set on the trip itself and is the base its balances are calculated in. The distinction matters — see [Currencies](Currencies).
|
||||
> This is **not** the trip's currency, which is set on the trip itself and is the base its balances are calculated in. The distinction matters, see [Currencies](Currencies).
|
||||
|
||||
An administrator can set an instance-wide default in **Admin → User Defaults**. It is not only a starting value for new accounts: it is merged in every time your settings are loaded, so it applies to anyone whose own display currency is empty. Picking a specific currency of your own overrides it. **Trip currency** does not, because it stores an empty value that counts as "not set", so the admin default takes effect again on your next reload.
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ Open the trip's **Files** tab. When a store is available, a **Document sync** bu
|
||||
|
||||
1. Open **Document sync**. Under **Connect a provider**, pick the store.
|
||||
2. Fill in the form. The fields per store are listed below; optional ones are marked as such.
|
||||
3. Press **Test connection**. On success the footer reads *Reached it, signed in as* followed by the account name. On failure it names the reason; see [Troubleshooting](#troubleshooting).
|
||||
3. Press **Test connection**. On success the footer reads *Reached it, signed in as* followed by the account name. On failure it names the reason; see [Troubleshooting](#troubleshooting). A long answer wraps to two lines next to the buttons, and pointing at it shows the store's own reason in full. On the phone the sheet prints the answer below the buttons.
|
||||
4. Press **Connect**.
|
||||
5. TREK asks *Where should this trip live in* followed by the store's name. Either create a new tag, folder or space under **Make a new one** (the name is prefilled from the trip's title plus its id, for example `japan-2026-42`) and press **Create**, or pick an existing one under **Or use one you already have**.
|
||||
|
||||
@@ -140,6 +140,7 @@ Every connection form ends with **Accept a self-signed certificate**, off by def
|
||||
- **Sub-folders** inside the bound folder are included.
|
||||
- **Renames** in File Station come through even though DSM has no file ids: TREK recognises the renamed or moved file by its size and modification time.
|
||||
- **Two-factor accounts:** the code is used once. DSM then hands TREK a trusted-device token, which TREK keeps encrypted with the trip's Synology connection, so it survives a restart of TREK and no new code is needed afterwards. TREK appears as **TREK** among the account's trusted devices in DSM.
|
||||
- **Login:** TREK sends the account and password to DSM as plain values. Older builds sent them in quotes, and DSM then refused every account with *credentials refused*; update if you saw that.
|
||||
- **Failed logins:** DSM blocks an address after a few failed logins. TREK does not retry a refused password for a minute, and waits fifteen minutes when DSM has already blocked it.
|
||||
- **Recycle bin:** File Station's API only deletes permanently, so a document TREK removes is moved into a `.trek-trash` folder inside the bound folder instead, where anyone can take it back out in File Station. A file of the same name already in there is renamed with a timestamp rather than overwritten. TREK never lists the `.trek-trash` folder.
|
||||
- **Instant updates:** none. File Station has no change feed, so the binding runs on the timer.
|
||||
@@ -150,7 +151,7 @@ Once bound, the dialog lists the trip's stores under **This trip** and shows the
|
||||
|
||||
- **The store's name** with a state dot, and **Paused** while **Sync automatically** is off.
|
||||
- **Where and when:** the bound tag, folder or space, and the last run.
|
||||
- **A notice line** when the binding needs attention, for example *Failed · The provider could not be reached.*
|
||||
- **A notice line** when the binding needs attention, for example *Failed*, with the reason *The provider could not be reached.*
|
||||
- **The flow bar:** TREK on one side, the store on the other, each with the number of documents it holds, and two lanes between them, **Out to the store** and **In from the store**. The trip owner switches a direction off by clicking its lane; the last lane cannot be switched off. Other members see the same bar without the switch.
|
||||
- **Sync now**, for every member, and **Disconnect** for the trip owner.
|
||||
|
||||
@@ -213,7 +214,7 @@ With **Ask me**, the document waits under **Needs a look** as a *Conflict*. **Re
|
||||
|
||||
An unmounted share, a revoked share or an expired token all answer the same way: a listing far shorter than the last one. Read literally, that would flag a whole trip as deleted.
|
||||
|
||||
So once a binding knows **five or more** documents in the store, a run that finds **more than 40 percent** of them gone at once is thrown away without acting on any of it, not even the parts that look fine. The binding shows *Partly synced · Most documents vanished at once, so nothing was changed. Check that the folder is still mounted.* and waits until the documents are back, or until the trip is bound again. Fewer missing documents are flagged one by one as *Missing at the provider*. Deleting documents in TREK never trips the guard.
|
||||
So once a binding knows **five or more** documents in the store, a run that finds **more than 40 percent** of them gone at once is thrown away without acting on any of it, not even the parts that look fine. The binding shows *Partly synced*, with the reason *Most documents vanished at once, so nothing was changed. Check that the folder is still mounted.* and waits until the documents are back, or until the trip is bound again. Fewer missing documents are flagged one by one as *Missing at the provider*. Deleting documents in TREK never trips the guard.
|
||||
|
||||
## Needs a look
|
||||
|
||||
@@ -221,12 +222,16 @@ The dialog lists what a person has to decide about under **Needs a look**, with
|
||||
|
||||
| Shown as | What it says | What to do |
|
||||
|---|---|---|
|
||||
| **Conflict** | *Changed in both places. Pick which one to keep.* | Press **Resolve** and pick a side. |
|
||||
| **Conflict** | *Changed in both places. Pick which one to keep.* | Press **Resolve** and pick a side. Where the button covers several conflicts it carries their number, for example *Resolve 2*. |
|
||||
| **Missing at the provider** | *Gone from the store. The TREK copy is still here.* | Put the document back in the store, for example from its recycle bin, if it went by mistake. The flag clears on the first run that finds it again. |
|
||||
| **Type not allowed** | *This file type is not allowed here.* | TREK refused an incoming file, or the store refused an outgoing one. See [File types and sizes](#file-types-and-sizes). |
|
||||
| **Too large** | *Bigger than the limit.* | The file is over TREK's limit or over the store's. |
|
||||
| **Error** | *The transfer did not go through.* | TREK tries again after 30 seconds, 2 minutes, 10 minutes and an hour. After six failed attempts in a row the document waits; **Sync now** gives it another go. |
|
||||
|
||||
## Offline
|
||||
|
||||
Syncing is a job of the TREK server, so it does not depend on your device. What does depend on it is the Files tab: an upload needs a connection, so a file you add while offline reaches the store only after you upload it again once TREK is back online. See [Documents-and-Files](Documents-and-Files#offline).
|
||||
|
||||
## File types and sizes
|
||||
|
||||
**Into TREK**, a document from the store goes through the same checks as an upload in the file manager:
|
||||
|
||||
@@ -6,7 +6,7 @@ Keep tickets, confirmations, vouchers and photos with the trip, and tie each one
|
||||
|
||||
## Where to find it
|
||||
|
||||
Open the **Files** tab inside the trip planner, or go straight to `/trips/:id/files`.
|
||||
Open the **Files** tab inside the trip planner. The same files also open on a stand-alone page at `/trips/:id/files`, titled **Files & Documents**, with a **Back to Planning** link. It shows the same files with an older layout; the tab is the one described on this page.
|
||||
|
||||
> **Admin:** The Files tab belongs to the **Documents** addon. Enable it in [Admin-Addons](Admin-Addons).
|
||||
|
||||
@@ -14,13 +14,13 @@ The tab opens with the same bar as Transports, Bookings, Lists and Costs: **File
|
||||
|
||||
## Uploading
|
||||
|
||||

|
||||

|
||||
|
||||
Drop files onto the dashed upload area under the bar, click it to open the file picker, or paste an image straight into the tab (Ctrl+V). Several files can go up at once.
|
||||
|
||||
When the upload is done and the trip has places or bookings, the **Assign File** dialog opens for the last file you uploaded, so you can tie it to a place or a booking right away (see [Linking files](#linking-files-to-places-reservations-or-assignments)). Close it if the file belongs nowhere in particular.
|
||||
|
||||
- **Maximum file size:** 50 MB per file by default. Videos (mp4, m4v, webm, mov) have their own cap of 500 MB.
|
||||
- **Maximum file size:** 50 MB per file by default; the upload area shows it as *Max {count} MB*. Videos (mp4, m4v, webm, mov) have their own cap of 500 MB.
|
||||
- **Blocked file types:** renderable documents (`.svg`, `.svgz`, `.html`, `.htm`, `.shtml`, `.shtm`, `.xml`, `.xhtml`, `.xht`), scripts (`.js`, `.jsx`, `.ts`, `.tsx`, `.mjs`, `.cjs`, `.php`, `.py`, `.rb`, `.pl`) and executables (`.exe`, `.bat`, `.sh`, `.cmd`, `.msi`, `.dll`, `.com`, `.vbs`, `.ps1`, `.app`). These are always refused, as is any file whose MIME type contains `svg`.
|
||||
- **Allowed types by default:** jpg, jpeg, png, gif, webp, heic, pdf, doc, docx, xls, xlsx, txt, csv, pkpass, pkpasses, md, markdown. The upload area lists the types your instance allows. An admin can change the list under **Admin → Settings → Allowed File Types**: comma-separated extensions, or `*` to allow everything except the blocked types above.
|
||||
|
||||
@@ -30,7 +30,11 @@ When the upload is done and the trip has places or bookings, the **Assign File**
|
||||
|
||||
Uploading needs the `file_upload` permission; without it the upload area is not shown.
|
||||
|
||||
Files also reach this tab from elsewhere: **Attach file** in a booking or transport editor, **Upload** in the Files section of the place inspector, **Attach** in the place dialog, receipts on an expense (see [Budget-Tracking](Budget-Tracking#receipts-and-invoices)) and attachments on a collab note. They all land here.
|
||||
Files for a tour are uploaded in the **Files** section of the tour's card; they are the trip's files as well and show up here. A place can carry files too: in the place dialog, files need a connection to upload (*Files need a connection to upload. Remove the new ones to save the place offline, or save once you are back online.*).
|
||||
|
||||
Files also reach this tab from elsewhere: **Attach file** in a booking or transport editor, **Upload** in the Files section of the place inspector, **Attach** in the place dialog, receipts on an expense (see [Budget-Tracking](Budget-Tracking#receipts-and-invoices)) and attachments on a collab note. They all land here. Deleting an expense does not delete its receipt files; they stay in Files.
|
||||
|
||||
The in-app AI assistant can keep a file you attach to the chat in Files (**Keep it in Files**), alone or together with a booking (**Keep the file with this booking**) or an expense.
|
||||
|
||||
An AI assistant connected through MCP can add files too: the `upload_trip_file` tool uploads a document to a trip (and can attach it to a booking or a place in the same call) under the same type rules and the `file_upload` permission as the upload area, up to 10 MB per file (or the upload limit, if that is lower). See [MCP-Tools-and-Resources](MCP-Tools-and-Resources).
|
||||
|
||||
@@ -107,6 +111,10 @@ See [Document-Sync](Document-Sync) for setup per store, the delete and conflict
|
||||
|
||||
> **Admin:** Each store is switched on separately under the **Documents** addon in [Admin-Addons](Admin-Addons). They ship switched off.
|
||||
|
||||
## Offline
|
||||
|
||||
Notes on files, links, stars and the trash wait in a queue while you are offline and are sent when TREK is back online. Uploading a file needs a connection (*Uploading needs a connection. Try again once TREK is back online.*), and so does removing a link from a file (*Removing this link needs a connection. Try again once TREK is back online.*).
|
||||
|
||||
## Permissions
|
||||
|
||||
| Permission | Controls |
|
||||
|
||||
@@ -16,6 +16,8 @@ TREK encrypts sensitive settings at rest using AES-256-GCM. The following values
|
||||
- Synology Photos password, session ID, and device ID (per user)
|
||||
- Per-user webhook URL, ntfy notification token, and LLM provider API key (in `settings` table)
|
||||
- Instance-wide API key of the AI Parsing addon (in `addons.config`)
|
||||
- Credentials of the AI Assistant's connections: an API key, or the tokens of a ChatGPT sign-in, kept as one encrypted blob per connection (in `ai_connections`)
|
||||
- Wanderer access token (per user, in `wanderer_connections`)
|
||||
- Document sync credentials of a trip's stores, one encrypted blob per store and trip (in `document_connections`), and the webhook secret of each binding (in `trip_document_links`); see [Document-Sync](Document-Sync)
|
||||
- OIDC client secret (global, in `app_settings`)
|
||||
- SMTP password (global, in `app_settings`)
|
||||
@@ -40,7 +42,7 @@ On startup, TREK resolves the encryption key in this order:
|
||||
|
||||
## What happens if the key is lost
|
||||
|
||||
All encrypted settings (API keys, SMTP password, OIDC secret, MFA secrets, notification tokens, etc.) become unreadable — TREK cannot decrypt them. They must be re-entered manually after the key is restored or replaced. Unencrypted data (trips, places, users, etc.) is unaffected.
|
||||
All encrypted settings (API keys, SMTP password, OIDC secret, MFA secrets, notification tokens, the AI Assistant's provider key and ChatGPT sign-ins, Wanderer tokens, etc.) become unreadable, TREK cannot decrypt them. They must be re-entered manually after the key is restored or replaced. Unencrypted data (trips, places, users, etc.) is unaffected.
|
||||
|
||||
The Web Push key pair cannot be re-entered, and TREK never replaces it on its own: unless the `VAPID_*` variables supply a pair, push stays off, with an error in the log, until TREK runs with the original key again, and then every device receives as before. To give it up instead, delete both `web_push_vapid_public_key` and `web_push_vapid_private_key` from `app_settings`. TREK then generates a new pair, and every device has to subscribe again (see [Environment-Variables](Environment-Variables#web-push)).
|
||||
|
||||
@@ -86,6 +88,7 @@ The script:
|
||||
- `document_connections`: `secrets` (the one encrypted blob per store and trip, including tokens the store handed out itself, such as Synology's device token)
|
||||
- `trip_document_links`: `webhook_secret`
|
||||
- `addons.config`: the instance-wide API key of the AI Parsing addon
|
||||
- `ai_connections`: `secrets` (the AI Assistant's API key or ChatGPT sign-in tokens; left out, the admin would have to enter the key again and every ChatGPT user would have to sign in anew)
|
||||
5. Reports counts of migrated, already-migrated, skipped (empty), and errored values.
|
||||
6. Writes the new key to `.encryption_key` next to the database, when that file exists, so the file and the secrets agree again.
|
||||
|
||||
@@ -94,6 +97,8 @@ After a successful migration:
|
||||
1. If you supply the key through `ENCRYPTION_KEY`, update it to the new value. (TREK refuses to start while the variable and the key file disagree.)
|
||||
2. Restart TREK.
|
||||
|
||||
The rotation script does not cover the Wanderer access token. After a rotation, each user who connected Wanderer enters the token again in their settings; the rest of the connection is unaffected.
|
||||
|
||||
If any secrets could not be migrated, the script exits with a non-zero status and the original database backup is retained.
|
||||
|
||||
## Upgrading from very old versions
|
||||
|
||||
@@ -7,8 +7,8 @@ Complete reference for all environment variables TREK reads.
|
||||
- **Docker Compose** — use the `environment:` block or a `.env` file alongside `docker-compose.yml`
|
||||
- **Docker run** — pass each variable with `-e VARIABLE=value`
|
||||
- **Helm** — use `env:` for plain values and `secretEnv:` for sensitive values in `values.yaml`. The chart only
|
||||
passes through the keys it declares (37 in `templates/configmap.yaml`, the credentials in `templates/secret.yaml`), so a variable
|
||||
that is not one of them (`DEFAULT_LANGUAGE`, `FILE_UPLOAD_LIMIT_MB`, `RESTORE_FROM_BACKUP` and `MCP_MAX_SESSION_PER_USER` among them) is dropped silently. Patch it onto the Deployment or add it to the chart
|
||||
passes through the keys it declares in `templates/configmap.yaml` (plus the credentials in `templates/secret.yaml`), so a variable
|
||||
that is not one of them (`FILE_UPLOAD_LIMIT_MB` and `RESTORE_FROM_BACKUP` among them) is dropped silently. Put it in `extraEnv` instead.
|
||||
- **Unraid** — set in the container template editor
|
||||
- **Proxmox Community Script** — set in `/opt/trek/server/.env`
|
||||
|
||||
@@ -49,7 +49,7 @@ warning in the log; the web UI is only served with `NODE_ENV=production` in lowe
|
||||
|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------|
|
||||
| `PORT` | Server port | Sources: `3001`, Docker: `3000` |
|
||||
| `HOST` | Bind address for the HTTP server (e.g. `127.0.0.1`, `10.0.0.72`). **Source / Proxmox installs only** — do not set this in Docker or any containerized deployment. See note below. | all interfaces |
|
||||
| `NODE_ENV` | Environment (`production` / `development`) | `production` |
|
||||
| `NODE_ENV` | Environment (`production` / `development`). The Docker image sets `production`; a start from source defaults to `development` | `production` |
|
||||
| `ENCRYPTION_KEY` | At-rest encryption key — see resolution order below | auto |
|
||||
| `TZ` | Timezone for logs, reminders, and cron jobs (e.g. `Europe/Berlin`) | `UTC` |
|
||||
| `LOG_LEVEL` | `info` = concise user actions; `debug` = verbose details | `info` |
|
||||
@@ -296,6 +296,12 @@ randomly generated password that is printed to the server log. Once any user exi
|
||||
|
||||
---
|
||||
|
||||
## AI Assistant
|
||||
|
||||
The AI Assistant addon has no environment variables for its provider. The AI connection (provider, API key or sign-in) is set up inside TREK, and its secrets are encrypted with `ENCRYPTION_KEY`. `LLM_TIMEOUT_MS` and `LLM_MAX_OUTPUT_TOKENS` under [Booking Import](#booking-import-kde-itinerary) bound the AI calls.
|
||||
|
||||
---
|
||||
|
||||
## MCP
|
||||
|
||||
For setup instructions, see [MCP-Overview](MCP-Overview).
|
||||
@@ -397,6 +403,7 @@ A Google Maps API key gives place search Google as the keyed provider beside the
|
||||
| Variable | Description | Default |
|
||||
|------------------|-------------|---------|
|
||||
| `PLACES_API_KEY` | Google Maps API key with the **Places API (New)** enabled. When set, it takes priority over the key configured in **Admin → Settings → API Keys** and is used for every member of the instance. | unset |
|
||||
| `PLACES_API_BASE` | Base URL for the Google Places calls, for routing them through an egress proxy, a cache or a gateway that speaks the same API instead of Google directly. Must be a valid URL. | unset |
|
||||
|
||||
**Two ways to configure it**, pick one; the env var wins if both are present:
|
||||
|
||||
@@ -461,6 +468,7 @@ through environment variables. `TREK_PLACE_PHOTO_DIR` below is unaffected.
|
||||
| `BACKUP_UPLOAD_LIMIT_MB` | Maximum **compressed** size (in MB) of a restore-backup archive that may be uploaded. Raise it if your backups (which include the `uploads/` directory) exceed the default. Non-positive or invalid values abort startup. | `500` |
|
||||
| `RESTORE_FROM_BACKUP` | Path to a backup ZIP to restore on the **first** start, before any setup. Only acts while no database exists; afterwards it is ignored with a warning. A backup that fails the restore checks stops the start. See [Backups](Backups#restoring-on-a-new-install-before-setup). | none |
|
||||
| `BACKUP_MAX_DECOMPRESSED_MB` | Maximum **decompressed** size (in MB) of a restore-backup archive — the zip-bomb guard. Independent of `BACKUP_UPLOAD_LIMIT_MB` and enforced on both restore paths, so a restore that fits the upload cap can still be refused with `Backup exceeds the maximum decompressed size.` Raise both when restoring a very large instance. | `5120` (5 GB) |
|
||||
| `TREK_DB_FILE` | Explicit path of the database file. Unset, TREK uses `travel.db` in the data directory. | unset |
|
||||
| `TREK_DB_JOURNAL_MODE` | SQLite [journal mode](https://sqlite.org/pragma.html#pragma_journal_mode): `DELETE`, `TRUNCATE`, `PERSIST`, `MEMORY`, `WAL` or `OFF`. Set `DELETE` when the data directory lives on network storage — see below. Values SQLite doesn't know log a warning and fall back. | `WAL` |
|
||||
| `TREK_DB_PRE_MIGRATE_SNAPSHOT` | Copy the database to `pre-migrate-<schema>-<time>.db` next to it before a startup applies pending migrations, so the previous image can be started on that copy again. If the copy cannot be written the startup refuses rather than migrate without one. Set `false` only to get past that when you cannot free space and have a backup of your own. See [Updating](Updating#database-migrations). | `true` |
|
||||
| `TREK_DB_PRE_MIGRATE_SNAPSHOT_KEEP` | How many of those copies stay in the data directory, newest first (1 to 100). | `3` |
|
||||
|
||||
+34
-1
@@ -8,7 +8,7 @@ To keep the Google bill in check, the same card has **Daily limit for Google cal
|
||||
|
||||
## Can I use TREK offline?
|
||||
|
||||
Yes. TREK is a Progressive Web App. After your first visit, the service worker (powered by Workbox) caches map tiles (Carto, OpenStreetMap, Mapbox GL and OpenFreeMap), uploaded covers and avatars, and every page of the app. Subsequent visits work without a network connection for already-cached content. Trip data does not come from that cache: it is stored per user in IndexedDB and read back through TREK's own offline layer, with writes queued and replayed once you reconnect. See [Offline Mode and PWA](Offline-Mode-and-PWA) for installation instructions.
|
||||
Yes. TREK is a Progressive Web App. After your first visit, the service worker (powered by Workbox) caches map tiles (Carto, OpenStreetMap, Mapbox GL and OpenFreeMap), uploaded covers and avatars, and every page of the app. Subsequent visits work without a network connection for already-cached content. Trip data does not come from that cache: it is stored per user in IndexedDB and read back through TREK's own offline layer, with writes queued and replayed once you reconnect. **Settings → Offline** adds **Force offline mode**, which routes the whole app to the local copy, and **Download for offline use**, which fetches your trips, documents and map tiles up front. See [Offline Mode and PWA](Offline-Mode-and-PWA) for installation instructions.
|
||||
|
||||
> **Note:** API responses are **never** stored in the service-worker cache. Workbox keys its entries by URL and cannot vary them on the session cookie, so caching them would mean one account's data could be served to the next on a shared device.
|
||||
|
||||
@@ -48,3 +48,36 @@ Yes, via OpenID Connect (OIDC). Compatible providers include Google, Authentik,
|
||||
Yes. In Settings → General → **Startup**, set the start page to **Active trip** and pick the tab it should open on — Costs, for instance, if you mostly add expenses while travelling. Opening TREK (including the installed PWA or a home-screen shortcut) then goes there in one step instead of three.
|
||||
|
||||
If you would rather build the shortcut yourself, or point a wrapper app at it, any trip URL takes a tab directly: `/trips/42?tab=finanzplan`. See [Display-Settings](Display-Settings) for the full list of tab ids.
|
||||
|
||||
|
||||
## Is the AI assistant required, and what does it send out?
|
||||
|
||||
No. The **AI Assistant** addon is off by default, and an admin has to switch it on before anyone sees it. It is a chat inside the trip that reads the plan and proposes changes, and nothing changes until you confirm a proposal. Each person connects their own AI account: an API key from Anthropic, OpenAI or Gemini, a sign-in with OpenRouter or ChatGPT, or an own server that speaks the same protocol. The conversation and the parts of your trip the assistant reads to answer go to the provider you connected, and nowhere else. In TREK Studio the assistant sees a page only after you allow it with **Show it pages**. See [Journey-Journal](Journey-Journal#trek-studio).
|
||||
|
||||
## What is the difference between the AI assistant and AI parsing?
|
||||
|
||||
They are two separate addons with their own switches. **AI Parsing** reads booking confirmations that the built-in parser cannot, see [AI-Booking-Import](AI-Booking-Import). The **AI Assistant** is the chat. You can run one without the other.
|
||||
|
||||
## What are Tours and Road trip?
|
||||
|
||||
**Tours** are hikes, city walks, bike, ski, paddle and horse tours with a route that you draw in TREK or import from GPX, KML or KMZ, see [Tours](Tours). **Road trip** plans a trip as one continuous drive, with search along the route and daily driving times, see [Road-Trip](Road-Trip). Both are addons that an admin switches on.
|
||||
|
||||
## Can I turn a trip into a photo book?
|
||||
|
||||
Yes. Link a journal to the trip, then open the journey and click **Studio**. TREK Studio lays the journey out as a printable photo book and exports it as a PDF. It needs a window at least 1024 px wide, so it is not offered on a phone. See [Journey-Journal](Journey-Journal#trek-studio).
|
||||
|
||||
## Can I get notifications on my phone?
|
||||
|
||||
Yes, in three ways. The bell and the **Notifications** page inside TREK, email, webhook and ntfy if your admin set them up, and **Web Push**, which reaches a device even while TREK is closed. Push needs HTTPS, and on an iPhone or iPad it only works in the Home Screen app. You turn it on per device under **Settings → Notifications**. See [Notifications](Notifications).
|
||||
|
||||
## Can TREK show where I actually travelled?
|
||||
|
||||
If you run a [Dawarich](Dawarich) server, you can connect it, and TREK offers the stays and routes it recorded as suggestions that you confirm. Nothing is written back to Dawarich.
|
||||
|
||||
## Where do I find help inside the app?
|
||||
|
||||
Click the **?** in the top bar for the help center, which explains the screen you are on, with guides and pictures. It is hidden on phones. The full wiki is also available inside TREK at `/help`. See [Help-Center](Help-Center) and [In-App-Help](In-App-Help).
|
||||
|
||||
## How do I check that TREK is running?
|
||||
|
||||
Open `/api/health` on your instance. The compose file's healthcheck polls it. During a shutdown, `/api/health/ready` answers 503 while TREK finishes what it is doing, which is what an orchestrator should wait on. See [Install-Docker](Install-Docker).
|
||||
|
||||
+6
-6
@@ -17,7 +17,7 @@ The panel opens over the app, already on the screen you were looking at. **Escap
|
||||
the focus goes back to the `?`. If you opened a dialog while following a guide, Escape closes that
|
||||
first.
|
||||
|
||||
The `?` is a desktop control. On a phone the app does not show it.
|
||||
The `?` is hidden on phones. It shows from a window width of 640 px up, so tablets and narrow desktop windows have it too.
|
||||
|
||||
## What is in it
|
||||
|
||||
@@ -35,8 +35,8 @@ The overview of a screen opens first. It carries:
|
||||
- **In the docs**, the wiki pages that go deeper. A guide's link to them reads **Open in Help & Docs**.
|
||||
|
||||
A screen that has sub-screens lists them under **Sub-screens**, folded: the trip folds its plan
|
||||
columns, its panels and its tabs; Settings and the Admin panel fold their tabs; Journey folds the
|
||||
journal and the studio.
|
||||
columns, its panels and its tabs (including Place details, Day details and Road trip); Settings and the Admin panel fold their tabs; Journey folds the
|
||||
journal and the studio. Dashboard, Vacay, Atlas, Collections and the Notifications inbox have help of their own.
|
||||
|
||||
### Guides
|
||||
|
||||
@@ -46,7 +46,7 @@ A guide is one task, start to finish. It opens with the goal and a chip that say
|
||||
1. **Steps**, numbered. Each step is one sentence naming the app's own buttons and fields, with a
|
||||
picture beside it. The picture is framed on the thing the sentence tells you to use, ringed in
|
||||
your accent colour and numbered to match. A step that asks you to drag something shows both ends
|
||||
and an arrow between them. Click a picture to open it full size.
|
||||
and an arrow between them. Some steps show a short looping clip instead of a still, so you see the movement; with your system set to reduce motion, the still is shown instead. Click a picture to open it full size.
|
||||
2. **What you get**, which says what changed, often with a picture of the result.
|
||||
3. **Good to know**, the caveats: what needs an addon, what cannot be undone, what a permission
|
||||
hides.
|
||||
@@ -78,12 +78,12 @@ every screen.
|
||||
|
||||
## The pictures
|
||||
|
||||
Every picture is generated by driving the real app: same viewport, same theme, same language, same
|
||||
Every picture and clip is generated by driving the real app: same viewport, same theme, same language, same
|
||||
demo trip, on every screen. Nothing is drawn, cropped or retouched by hand, and a picture only
|
||||
exists if the steps it shows still work. When a button moves or a label changes, the run that makes
|
||||
the pictures fails, which is how the guides stay honest.
|
||||
|
||||
The pictures ship with your install as WebP and are loaded only when you open the panel, so they
|
||||
The pictures and clips ship with your install as WebP and are loaded only when you open the panel, so they
|
||||
cost nothing to a visitor who never asks for help.
|
||||
|
||||
## Languages
|
||||
|
||||
+13
-3
@@ -13,6 +13,7 @@ TREK is a self-hosted, real-time collaborative travel planner licensed under AGP
|
||||
- **Day Notes**: notes between a day's stops, each with a title, Markdown text, an icon and a colour
|
||||
- **Route Optimization**: auto-optimize place order, draw the day for driving, walking or cycling, leave single stops out of the route, and hand the day to Google Maps or CoMaps (see [Route Optimization](Route-Optimization))
|
||||
- **Weather Forecasts**: 16-day forecasts via Open-Meteo (no API key required), historical climate averages as fallback
|
||||
- **Trip Settings**: the **Trip settings** pill in the planner's top bar holds People, Sharing and a Journal section where you link a journal from Journey (see [Trip Members and Sharing](Trip-Members-and-Sharing))
|
||||
|
||||
### Travel Management
|
||||
- **Reservations & Bookings**: hotels, restaurants, tickets and every other booking with its confirmation code, travelers, costs and files, shown as cards, as a list or on a timeline; flights, trains and cars have their own Transports tab
|
||||
@@ -30,22 +31,24 @@ TREK is a self-hosted, real-time collaborative travel planner licensed under AGP
|
||||
- **Two-Factor Authentication**: TOTP-based 2FA with QR code setup
|
||||
- **Passkeys** _(admin-enabled)_: passwordless WebAuthn sign-in with Touch ID, Windows Hello, Android screen lock, or a hardware key; owning one also satisfies the require-2FA policy (see [Passkeys](Passkeys))
|
||||
- **Public Share Links**: share a read-only view of any trip, in full, as **Travel & stays only** or **Without photos** (see [Public Share Links](Public-Share-Links))
|
||||
- **Notifications**: in-app, email, webhook and ntfy, and Web Push to a phone or computer even while TREK is closed (see [Notifications](Notifications))
|
||||
- **Notifications**: an inbox with a tile per kind and a list cut into days, plus email, webhook and ntfy, and Web Push to a phone or computer even while TREK is closed (see [Notifications](Notifications))
|
||||
|
||||
### Addons _(admin-toggleable)_
|
||||
- **Lists**: packing lists and to-dos with templates, member assignments, optional bag tracking
|
||||
- **Costs**: expense tracker with category breakdown, splits, multi-currency
|
||||
- **Documents**: file manager for trips, places, and reservations
|
||||
- **Collab**: group chat, shared notes, polls, day-by-day attendance
|
||||
- **Tours**: hikes, city walks, bike, ski, paddle and horse tours with a route, drawn in TREK or imported from GPX, KML or KMZ, as single-day tours or with stages over several days; a **Tours** tab in the planner on the desktop (see [Tours](Tours))
|
||||
- **Road trip**: plan a trip as one continuous drive, with search along the route, driving limits, daily travel times and avoidance of toll roads, motorways and ferries (see [Road Trip](Road-Trip))
|
||||
- **Vacay**: personal vacation day planner with calendar view, public holidays, company holidays (also as half days), and carry-over tracking
|
||||
- **Atlas**: interactive world map with visited countries and regions, bucket list (countries or regions), travel stats, continent breakdown
|
||||
- **Collections**: a personal place library that saves places across trips into named lists, copies them into any trip, and shares them with per-member roles (see [Collections](Collections))
|
||||
- **Journey**: magazine-style travel journal with entries, drafts, photos (via Immich/Synology Photos) shown on the journey's map when geotagged, and moods
|
||||
- **Journey**: magazine-style travel journal with entries, drafts, photos (via Immich/Synology Photos) shown on the journey's map when geotagged, and moods; a journey can be linked to a trip and laid out as a printable photo book in TREK Studio (see [Journey Journal](Journey-Journal))
|
||||
- **Naver List Import**: import places from shared Naver Maps lists
|
||||
- **MCP**: expose TREK to AI assistants via the Model Context Protocol (OAuth 2.1)
|
||||
- **AirTrail**: sync flights from your self-hosted AirTrail instance into trips
|
||||
- **Dawarich**: read the stays and routes your self-hosted Dawarich instance recorded, offered as suggestions you confirm; nothing is written back (see [Dawarich](Dawarich))
|
||||
- **AI Assistant**: a chat inside the trip that reads the plan and proposes changes you confirm, using your own AI connection (off by default)
|
||||
- **AI Parsing**: LLM fallback that extracts bookings from confirmation files KDE Itinerary cannot read, and, with a model that reads images, from photos and scanned PDFs and receipts (see [AI-Booking-Import](AI-Booking-Import))
|
||||
|
||||
> Dashboard widgets (currency converter and timezone clock) are per-user preferences, not an admin-toggleable addon; see [Dashboard-Widgets](Dashboard-Widgets).
|
||||
@@ -58,7 +61,7 @@ TREK is a self-hosted, real-time collaborative travel planner licensed under AGP
|
||||
|
||||
### AI / MCP Integration
|
||||
- **MCP Server**: built-in Model Context Protocol server with OAuth 2.1 authentication
|
||||
- **300+ Tools**: create trips, plan itineraries, manage budgets, upload files, search places near a point, send messages, and more
|
||||
- **400+ Tools**: create trips, plan itineraries, manage budgets, upload files, search places near a point, send messages, and more
|
||||
- **30 Resources**: read-only `trek://` URIs for trips, days, places, budget, packing, journeys, and more
|
||||
- **35 OAuth Scopes**: granular permissions across 17 permission groups
|
||||
- **Pre-built Prompts**: `trip-summary`, `packing-list`, and `budget-overview` context loaders
|
||||
@@ -81,6 +84,13 @@ TREK is a self-hosted, real-time collaborative travel planner licensed under AGP
|
||||
|---|---|
|
||||
| [Quick Start](Quick-Start) | Install in minutes with a single Docker command |
|
||||
| [My Trips Dashboard](My-Trips-Dashboard) | Start planning your first trip |
|
||||
| [Trip Settings](Trip-Settings) | People, sharing links and the linked journal of a trip |
|
||||
| [Notifications Inbox](Notifications-Inbox) | The bell and the inbox page |
|
||||
| [TREK on a Phone](Mobile-App) | The phone layout, its bottom bar and what stays on the desktop |
|
||||
| [AI Assistant](AI-Assistant) | A chat in the trip that suggests changes you confirm |
|
||||
| [AI Connections](AI-Connections) | Connect the AI provider the assistant and AI Parsing run on |
|
||||
| [TREK Studio](TREK-Studio) | Lay a journey out as a printable photo book |
|
||||
| [wanderer](Wanderer) | Import trails from your own wanderer instance as tours |
|
||||
| [Help Center](Help-Center) | The `?` in the navbar: guides for the screen you are on |
|
||||
| [Admin Panel](Admin-Panel-Overview) | Configure your instance |
|
||||
| [MCP / AI Integration](MCP-Overview) | Connect Claude, Cursor, or any MCP client |
|
||||
|
||||
@@ -46,6 +46,14 @@ volumes:
|
||||
|
||||
Docker creates the volumes automatically on first `docker compose up`. Use `docker volume ls` and `docker volume inspect` to manage them.
|
||||
|
||||
### Optional storage seed
|
||||
|
||||
A commented line mounts a storage-config.json file from the compose folder read-only into the data directory. Uncomment it to provision file storage once on the first start. See [Admin-Storage](Admin-Storage).
|
||||
|
||||
## Healthcheck and Logs
|
||||
|
||||
The compose file includes a healthcheck that polls `/api/health` every 30 seconds and follows a changed `PORT`, so `docker ps` shows `healthy` once TREK is up. It also limits the container log to three files of 10 MB each, because Docker keeps every line forever by default.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
The compose file has no `env_file:` key, so a `.env` placed alongside `docker-compose.yml` is used only for `${VAR}` interpolation — a value reaches the container only if a line in the `environment:` block references it. Four entries are wired that way:
|
||||
@@ -64,25 +72,30 @@ Every other variable — `APP_URL`, the OIDC block, `FORCE_HTTPS`, `TRUST_PROXY`
|
||||
|
||||
A few variables are not in the compose file at all, among them `FILE_UPLOAD_LIMIT_MB` (the upload limit for files, 50 MB by default) and `RESTORE_FROM_BACKUP` (a backup ZIP to restore on the very first start, see [Backups](Backups#restoring-on-a-new-install-before-setup)). Add a line for them to the `environment:` block yourself.
|
||||
|
||||
Some optional variables ship as commented lines, ready to uncomment: `LLM_TIMEOUT_MS` and `LLM_MAX_OUTPUT_TOKENS` for AI parsing, the `VAPID_*` keys for Web Push, `TREK_PLACES_*` and `PLACES_API_KEY` for place search, `AMAP_*`, `UNSPLASH_ACCESS_KEY`, `GOOGLE_LIST_DATA_BASE` and `TREK_WIKI_DIR`. Rootless Podman users will also find `HSTS_INCLUDE_SUBDOMAINS`, `COOKIE_SECURE` and `ALLOW_LINK_LOCAL_IPS` there.
|
||||
|
||||
`APP_URL` is usually not needed. TREK resolves its public base URL as `APP_URL` → first `ALLOWED_ORIGINS` entry → `http://localhost:<PORT>`, so the `ALLOWED_ORIGINS` value above already gives OIDC redirect URIs, passkey origin checks and the links in email notifications the correct origin. Uncomment `APP_URL` only when the public base URL has to differ from the first allowed origin.
|
||||
|
||||
For a full description of every variable, see [Environment-Variables](Environment-Variables).
|
||||
|
||||
## Image Tags
|
||||
|
||||
Three tag strategies are available:
|
||||
Five tags are available:
|
||||
|
||||
| Tag | Example | Behavior |
|
||||
|---|--------------------------|---|
|
||||
| `latest` | `mauriceboe/trek:latest` | Always the newest release across all major versions |
|
||||
| Major version | `mauriceboe/trek:4` | Latest release pinned to that major version |
|
||||
| Full version | `mauriceboe/trek:4.0.0` | Exact release; never changes |
|
||||
| Major version | `mauriceboe/trek:5` | Latest release pinned to that major version |
|
||||
| Minor version | `mauriceboe/trek:5.0` | Latest patch of that minor version; never moves to the next minor. Published from 5.0.0 on |
|
||||
| Full version | `mauriceboe/trek:5.0.0` | Exact release; never changes |
|
||||
| `latest-pre` | `mauriceboe/trek:latest-pre` | Test build of the next version; not for production |
|
||||
|
||||
The compose file above uses `latest`. To pin, change the `image:` line:
|
||||
|
||||
```yaml
|
||||
image: mauriceboe/trek:4 # track major version 4
|
||||
image: mauriceboe/trek:4.0.0 # pin to exact release
|
||||
image: mauriceboe/trek:5 # track major version 5
|
||||
image: mauriceboe/trek:5.0 # stay on 5.0.x patches
|
||||
image: mauriceboe/trek:5.0.0 # pin to exact release
|
||||
```
|
||||
|
||||
## Start TREK
|
||||
|
||||
+16
-5
@@ -39,14 +39,23 @@ See [Environment-Variables](Environment-Variables) for the full list.
|
||||
| Tag | Example | Behavior |
|
||||
|---|--------------------------|---|
|
||||
| `latest` | `mauriceboe/trek:latest` | Always the newest release across all major versions |
|
||||
| Major version | `mauriceboe/trek:4` | Latest release pinned to that major version |
|
||||
| Major version | `mauriceboe/trek:5` | Latest release pinned to that major version |
|
||||
| Minor version | `mauriceboe/trek:5.0` | Latest patch of that minor version; never moves to the next minor. Published from 5.0.0 on: 4.x releases have no minor tag, so pin those by major or full version |
|
||||
| Full version | `mauriceboe/trek:4.0.0` | Exact release; never changes |
|
||||
| Full version | `mauriceboe/trek:5.0.0` | Exact release; never changes |
|
||||
| `latest-pre` | `mauriceboe/trek:latest-pre` | Test build of the next version; not for production |
|
||||
|
||||
Replace `mauriceboe/trek:latest` in the run command with your chosen tag to pin to a major version, a minor version or an exact release. Test builds of the next version are tagged `latest-pre`; see [Updating](Updating#image-tags).
|
||||
Replace `mauriceboe/trek:latest` in the run command with your chosen tag to pin to a major version, a minor version or an exact release. See [Updating](Updating#image-tags) for how the tags behave.
|
||||
|
||||
Every image carries the standard `org.opencontainers.image.*` labels (title, version, source, documentation, licence), so an update tool such as Renovate links an image update to its release notes. `docker inspect mauriceboe/trek:latest --format '{{json .Config.Labels}}'` shows them.
|
||||
|
||||
## First Start
|
||||
|
||||
On the very first start with an empty database TREK creates an admin account. Without `ADMIN_EMAIL` and `ADMIN_PASSWORD` (both are needed, and they only apply on that first start) it uses `admin@trek.local` with a random password that is printed to the container log, so run `docker logs trek` and sign in with it. See [Quick-Start](Quick-Start).
|
||||
|
||||
When you start a newer image, TREK first copies the database to `data/pre-migrate-<schema>-<time>.db` before it applies any migration, so you can go back to the previous image if needed. See [Updating](Updating).
|
||||
|
||||
The in-app Help pages come from the image itself (`/app/wiki`), so they always match the version you run. You do not need to set `TREK_WIKI_DIR`.
|
||||
|
||||
## Volume Reference
|
||||
|
||||
| Volume | Container path | What lives there |
|
||||
@@ -54,7 +63,9 @@ Every image carries the standard `org.opencontainers.image.*` labels (title, ver
|
||||
| `./data` | `/app/data` | `travel.db` (SQLite database), `logs/trek.log`, `.jwt_secret`, `.encryption_key` |
|
||||
| `./uploads` | `/app/uploads` | Uploaded files (photos, documents, covers, avatars) |
|
||||
|
||||
Both volumes must survive container replacement — they are your persistent state. Never remove them before pulling a new image.
|
||||
Both volumes must survive container replacement, they are your persistent state. Never remove them before pulling a new image. Installed plugins also live under `data` by default (`TREK_PLUGINS_DIR` moves them), so they are covered as long as `data` persists.
|
||||
|
||||
You can optionally mount a `storage-config.json` read-only at `/app/data/storage-config.json` to set up file storage once on the first start. See [Admin-Storage](Admin-Storage).
|
||||
|
||||
### Named Volumes
|
||||
|
||||
@@ -96,7 +107,7 @@ docker logs trek
|
||||
|
||||
## Limitations of `docker run`
|
||||
|
||||
A bare `docker run` command has no built-in secret management and is harder to reproduce after a system reboot. For production, see [Install-Docker-Compose](Install-Docker-Compose), which adds security hardening (`read_only`, `cap_drop`, `cap_add`, `no-new-privileges`, `tmpfs`) and makes it easy to manage environment variables through a `.env` file.
|
||||
A bare `docker run` command has no built-in secret management and is harder to reproduce after a system reboot. It also lacks the hardening of the compose file (`read_only`, `cap_drop`, `cap_add`, `no-new-privileges`, `tmpfs`) and does not rotate container logs, which the compose file limits to three files of 10 MB. For production, see [Install-Docker-Compose](Install-Docker-Compose), which also makes it easy to manage environment variables through a `.env` file.
|
||||
|
||||
## Next Steps
|
||||
|
||||
|
||||
+12
-2
@@ -112,6 +112,9 @@ env:
|
||||
# TZ: "Europe/Berlin" # timezone for logs, reminders, cron jobs
|
||||
# LOG_LEVEL: "info" # "info" = concise, "debug" = verbose
|
||||
# TREK_WIKI_DIR: "/app/wiki" # where /help reads its docs from; leave unset (the image ships them)
|
||||
# DEFAULT_LANGUAGE: "en" # fallback language on the login page
|
||||
# MCP_MAX_SESSION_PER_USER: "20" # max concurrent MCP sessions per user
|
||||
# GOOGLE_LIST_DATA_BASE: "" # base URL of a list-data service for pasted list URLs
|
||||
# ALLOWED_ORIGINS: "https://trek.example.com"
|
||||
# APP_URL: "https://trek.example.com"
|
||||
# FORCE_HTTPS: "false" # enable HTTPS redirect + HSTS; set TRUST_PROXY for correct client IPs
|
||||
@@ -146,7 +149,7 @@ env:
|
||||
# VAPID_SUBJECT: "mailto:admin@example.com" # Web Push contact; defaults to APP_URL when it is https
|
||||
```
|
||||
|
||||
> **Note:** The chart only passes on the keys its ConfigMap declares. `DEFAULT_LANGUAGE`, `MCP_MAX_SESSION_PER_USER` (although `values.yaml` lists it in a comment), `FILE_UPLOAD_LIMIT_MB` and `RESTORE_FROM_BACKUP` are not among them, so a value under `env:` is dropped and the default stays. Patch such a variable onto the Deployment if you need it. See [Environment-Variables](Environment-Variables#default_language--supported-codes) for the language codes.
|
||||
> **Note:** The chart only passes on the keys its ConfigMap declares. `FILE_UPLOAD_LIMIT_MB` and `RESTORE_FROM_BACKUP` are not among them, so a value under `env:` is dropped and the default stays. Put such a variable in `extraEnv` (see below) instead. See [Environment-Variables](Environment-Variables#default_language--supported-codes) for the language codes.
|
||||
|
||||
### Sensitive Variables (`secretEnv`)
|
||||
|
||||
@@ -163,9 +166,10 @@ secretEnv:
|
||||
AMAP_API_KEY: "" # optional; Amap Web 服务 key for place search in mainland China
|
||||
AMAP_API_SECRET: "" # optional; the signing secret of that key, only when signing is on
|
||||
VAPID_PRIVATE_KEY: "" # optional; Web Push private half, only together with env.VAPID_PUBLIC_KEY
|
||||
SMTP_PASS: "" # optional; password of your SMTP account
|
||||
```
|
||||
|
||||
Alternatively, use `generateEncryptionKey: true` to let the chart generate and manage the encryption key, or point `existingSecret` / `existingSecretKey` at an existing Kubernetes Secret.
|
||||
Alternatively, use `generateEncryptionKey: true` to let the chart generate and manage the encryption key, or point `existingSecret` / `existingSecretKey` at an existing Kubernetes Secret. A Secret you bring yourself can carry any of the keys above by the same names, `SMTP_PASS` included.
|
||||
|
||||
Every value the chart writes into its Secret is quoted, so a password such as `12345` or a value like `true` reaches the container as the text you typed.
|
||||
|
||||
@@ -175,6 +179,8 @@ Every value the chart writes into its Secret is quoted, so a password such as `1
|
||||
|
||||
### Persistent Storage
|
||||
|
||||
The data PVC holds the database, the plugins you install and the automatic `pre-migrate-<schema>-<time>.db` copy TREK writes before an upgrade migrates the database, so the previous image can run on that copy again. See [Updating](Updating).
|
||||
|
||||
```yaml
|
||||
persistence:
|
||||
enabled: true
|
||||
@@ -252,6 +258,10 @@ ingress:
|
||||
|
||||
## Upgrade
|
||||
|
||||
The Deployment uses the `Recreate` update strategy (`updateStrategy: Recreate`): the old pod stops before the new one starts. TREK is a single-writer SQLite application, and during a rolling update the new pod would migrate the database while the old one still writes to it. A ReadWriteMany volume does not make that safe, so leave the strategy as it is and keep one replica.
|
||||
|
||||
The in-app Help pages come from the image (`/app/wiki`), so they match the version you upgrade to.
|
||||
|
||||
```bash
|
||||
helm repo update
|
||||
helm upgrade trek trek/trek
|
||||
|
||||
+28
-16
@@ -4,7 +4,7 @@ Install TREK on Portainer using a Stack (Docker Compose).
|
||||
|
||||
## Prerequisite
|
||||
|
||||
Portainer must be installed and connected to your Docker environment. Use **Stacks** — it supports Docker Compose and gives you the full compose syntax including environment variables, volumes, and restart policies.
|
||||
Portainer must be installed and connected to your Docker environment. Use **Stacks**. They support Docker Compose and give you the full compose syntax, including environment variables, volumes, the healthcheck and restart policies.
|
||||
|
||||
## Create a Stack
|
||||
|
||||
@@ -12,11 +12,11 @@ Portainer must be installed and connected to your Docker environment. Use **Stac
|
||||
|
||||
1. In Portainer, go to **Stacks → Add stack**.
|
||||
2. Give the stack a name (e.g. `trek`).
|
||||
3. Select **Web editor** and paste the compose file from [docker-compose.yml](https://github.com/liketrek/TREK/blob/main/docker-compose.yml).
|
||||
3. Select **Web editor** and paste the compose file from [docker-compose.yml](https://github.com/liketrek/TREK/blob/main/docker-compose.yml). Keep it complete, including the `read_only` and `cap_drop` hardening, the `healthcheck` block and the `logging` block, so Portainer can show the container's health and Docker does not let the log grow without limit.
|
||||
|
||||

|
||||
|
||||
4. Fill in the environment variables at the bottom of the page.
|
||||
4. Fill in the environment variables at the bottom of the page. Use **Advanced mode** to paste several `KEY=value` lines at once.
|
||||
|
||||

|
||||
|
||||
@@ -24,15 +24,21 @@ Portainer must be installed and connected to your Docker environment. Use **Stac
|
||||
|
||||

|
||||
|
||||
## Check That It Runs
|
||||
|
||||
Open **Containers** in Portainer. After the first 15 seconds or so the `trek` container shows a green **healthy** status, because the compose file defines a healthcheck that polls `/api/health` and follows a changed `PORT`. While it still says `starting`, TREK is booting or migrating its database.
|
||||
|
||||
Then open `http://<host>:3000`. On the very first start TREK creates an admin account. Without `ADMIN_EMAIL` and `ADMIN_PASSWORD` (both are needed, and they only apply on that first start) it uses `admin@trek.local` with a random password. Find the password in the container's log: **Containers → trek → Logs**. See [Quick-Start](Quick-Start).
|
||||
|
||||
## Compose Content
|
||||
|
||||
See https://github.com/liketrek/TREK/blob/main/docker-compose.yml
|
||||
|
||||
Set at minimum `ENCRYPTION_KEY`, `TZ`, and `ALLOWED_ORIGINS` in the **Environment variables** section of the stack editor. Portainer's stack variables are only substituted into `${...}` placeholders in the compose file, they are not injected into the container, and the shipped compose file interpolates exactly four: `ENCRYPTION_KEY`, `TZ`, `LOG_LEVEL`, and `ALLOWED_ORIGINS`.
|
||||
|
||||
Every other variable ships commented out, so setting it here does nothing. To use one — `APP_URL`, for example, which OIDC needs and which email notification links are built from — uncomment its line in the **Web editor** and put the value there directly, or change it to `- APP_URL=${APP_URL:-}` so the stack variable is picked up.
|
||||
Every other variable ships commented out, so setting it here does nothing. To use one, for example `APP_URL`, which OIDC needs and which email notification links are built from, uncomment its line in the **Web editor** and put the value there directly, or change it to `- APP_URL=${APP_URL:-}` so the stack variable is picked up.
|
||||
|
||||
> Change a variable later by editing the **stack** and redeploying it — never by editing the container in place. Portainer's container editor rewrites the container's start-up command as well, which leaves it unable to boot; see [Troubleshooting](Troubleshooting#container-wont-start-syntax-error-end-of-file-unexpected-expecting-fi).
|
||||
> Change a variable later by editing the **stack** and redeploying it, never by editing the container in place. Portainer's container editor rewrites the container's start-up command as well, which leaves it unable to boot; see [Troubleshooting](Troubleshooting#container-wont-start-syntax-error-end-of-file-unexpected-expecting-fi).
|
||||
|
||||
Generate an encryption key with:
|
||||
|
||||
@@ -42,44 +48,50 @@ openssl rand -hex 32
|
||||
|
||||
## Image Tags
|
||||
|
||||
Three tag strategies are available:
|
||||
Five tags are available:
|
||||
|
||||
| Tag | Example | Behavior |
|
||||
|---|---|---|
|
||||
| `latest` | `mauriceboe/trek:latest` | Always the newest release across all major versions |
|
||||
| Major version | `mauriceboe/trek:4` | Latest release pinned to that major version |
|
||||
| Full version | `mauriceboe/trek:4.0.0` | Exact release; never changes |
|
||||
| Major version | `mauriceboe/trek:5` | Latest release pinned to that major version |
|
||||
| Minor version | `mauriceboe/trek:5.0` | Latest patch of that minor version; never moves to the next minor. Published from 5.0.0 on |
|
||||
| Full version | `mauriceboe/trek:5.0.0` | Exact release; never changes |
|
||||
| `latest-pre` | `mauriceboe/trek:latest-pre` | Test build of the next version; not for production |
|
||||
|
||||
Use `latest` or a major-version tag (e.g. `4`) if you want automatic updates on redeploy. Use a full version tag (e.g. `4.0.0`) if you want explicit control over which release runs.
|
||||
Use `latest` or a major-version tag (e.g. `5`) if you want automatic updates on redeploy. Use the minor tag (e.g. `5.0`) to receive patch releases only, or a full version tag (e.g. `5.0.0`) if you want explicit control over which release runs.
|
||||
|
||||
## Updating
|
||||
|
||||
How you update depends on the tag you chose:
|
||||
|
||||
**`latest` or major-version tag** — In Portainer, open the stack, click **Redeploy**, enable the **Re-pull image and redeploy** switch, then confirm. Portainer will pull the newest matching image and recreate the container.
|
||||
**`latest`, major-version or minor-version tag.** In Portainer, open the stack and go to the **Editor**. Switch on **Re-pull image and redeploy**, then click **Update the stack**. Portainer pulls the newest matching image and recreates the container.
|
||||
|
||||

|
||||
|
||||
**Pinned full-version tag** — Edit the stack, change the tag in the `image:` line (e.g. `4.0.0` → `4.0.1`), then click **Update the stack**. No need to toggle the re-pull switch — a tag change forces a fresh pull.
|
||||
**Pinned full-version tag.** Edit the stack, change the tag in the `image:` line (e.g. `5.0.0` → `5.0.1`), then click **Update the stack**. No need to toggle the re-pull switch, because a changed tag forces a fresh pull.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
When the new container starts, TREK first copies the database to `data/pre-migrate-<schema>-<time>.db`, so you can go back to the previous image if an update does not suit you. See [Updating](Updating).
|
||||
|
||||
> Back up your data before any update. Go to **Admin Panel → Backup** or copy your `./data` and `./uploads` directories. See [Backups](Backups).
|
||||
|
||||
## Volumes
|
||||
|
||||
| Stack-relative path | Container path | Contents |
|
||||
|---|---|---|
|
||||
| `./data` | `/app/data` | SQLite database, logs, encryption key |
|
||||
| `./data` | `/app/data` | SQLite database, logs, encryption key, installed plugins |
|
||||
| `./uploads` | `/app/uploads` | Uploaded files (photos, documents, covers, avatars) |
|
||||
|
||||
Portainer resolves `./` relative to the stack's working directory. Confirm the paths under **Stack details** after deploying.
|
||||
|
||||
Installed plugins live under `data` by default, so they persist with it. If you move them with `TREK_PLUGINS_DIR`, give that directory a volume of its own as well, or they are gone after the container is recreated.
|
||||
|
||||
### Named Volumes
|
||||
|
||||
You can use Docker named volumes instead of bind mounts. Named volumes are fully managed by Docker and not tied to a host path — a good fit for Portainer where the working directory can vary. See the [Docker Compose volumes reference](https://docs.docker.com/reference/compose-file/volumes/) for all options.
|
||||
You can use Docker named volumes instead of bind mounts. Named volumes are fully managed by Docker and not tied to a host path, a good fit for Portainer where the working directory can vary. See the [Docker Compose volumes reference](https://docs.docker.com/reference/compose-file/volumes/) for all options.
|
||||
|
||||
Replace the `volumes:` block in the service and add a top-level declaration:
|
||||
|
||||
@@ -100,6 +112,6 @@ Portainer lists named volumes under **Volumes** in the sidebar, where you can in
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Environment-Variables](Environment-Variables) — full variable reference
|
||||
- [Reverse-Proxy](Reverse-Proxy) — HTTPS configuration
|
||||
- [Updating](Updating) — update strategies across all install methods
|
||||
- [Environment-Variables](Environment-Variables): full variable reference
|
||||
- [Reverse-Proxy](Reverse-Proxy): HTTPS configuration
|
||||
- [Updating](Updating): update strategies across all install methods
|
||||
|
||||
@@ -23,6 +23,8 @@ The script will prompt you to choose between **Default** and **Advanced** settin
|
||||
|
||||
### Default container specs
|
||||
|
||||
These are the defaults at the time of writing. The script decides them, so check the script page for the current values.
|
||||
|
||||
| Resource | Value |
|
||||
|---|---|
|
||||
| OS | Debian 13 |
|
||||
@@ -47,6 +49,8 @@ On first boot, TREK automatically creates an admin account. The credentials are
|
||||
journalctl -u trek -n 50
|
||||
```
|
||||
|
||||
If you put `ADMIN_EMAIL` and `ADMIN_PASSWORD` into `/opt/trek/server/.env` before the first start, TREK uses them instead, but only on that first start and only when both are set. Once a user exists they have no effect.
|
||||
|
||||
The `ENCRYPTION_KEY` is auto-generated during setup and saved to `/opt/trek/server/.env`. Record that file in your backups.
|
||||
|
||||
## Viewing Logs
|
||||
@@ -92,6 +96,8 @@ HOST=10.0.0.72 # bind only on this LAN interface
|
||||
|
||||
If the container reaches the internet only through a proxy, set `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` in the same file, and `NODE_USE_ENV_PROXY=1` next to them: unlike the Docker image, a Proxmox install does not set that switch for you, and without it Node ignores the proxy for everything except TREK's guarded integration requests. See [Environment-Variables](Environment-Variables#outbound-https-proxy).
|
||||
|
||||
The same file takes every other variable from [Environment-Variables](Environment-Variables), for example the Web Push, OIDC or place search settings. The in-app Help pages are read from the `wiki` folder that comes with the installed version, so they match what you run. Installed plugins are stored under the `data` folder by default (`TREK_PLUGINS_DIR` moves them), so keep that folder in your backups.
|
||||
|
||||
See [Environment-Variables](Environment-Variables) for the full variable reference.
|
||||
|
||||
## Updating
|
||||
@@ -104,7 +110,7 @@ bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/Proxmo
|
||||
|
||||
> **Tip:** Always check the [community-scripts TREK page](https://community-scripts.org/scripts/trek) to confirm the latest command before running.
|
||||
|
||||
The script stops the service, backs up your data and uploads, applies the new release, restores the backup, and restarts. No manual steps required.
|
||||
The script stops the service, backs up your data and uploads, applies the new release, restores the backup, and restarts. No manual steps required. When the new version starts, TREK also copies the database to `data/pre-migrate-<schema>-<time>.db` before migrating it, so you can go back if needed (see [Updating](Updating#database-migrations)).
|
||||
|
||||
## Next Steps
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
Install TREK on Unraid via Community Applications or a direct template import.
|
||||
|
||||
<!-- TODO: screenshot: Unraid container template settings -->
|
||||
|
||||
## Prerequisite
|
||||
|
||||
Docker must be enabled in Unraid (**Settings → Docker → Enable Docker: Yes**).
|
||||
@@ -47,7 +45,7 @@ The Unraid template exposes the following fields in the container UI:
|
||||
|
||||
Additional variables (`PORT`, `NODE_ENV`, `LOG_LEVEL`, `TREK_WIKI_DIR`, `DEFAULT_LANGUAGE`, `FORCE_HTTPS`, `HSTS_INCLUDE_SUBDOMAINS`, `TRUST_PROXY`, `COOKIE_SECURE`, `ALLOW_INTERNAL_NETWORK`, `SESSION_DURATION`, `SESSION_DURATION_REMEMBER`, the OIDC variables apart from `OIDC_USERNAME_CLAIM`, `MCP_RATE_LIMIT`, `MCP_MAX_SESSION_PER_USER`, `DEMO_MODE`, `UNSPLASH_ACCESS_KEY`, `VAPID_PUBLIC_KEY`, `VAPID_PRIVATE_KEY`, `VAPID_SUBJECT`) are available under **Advanced View** in the template editor.
|
||||
|
||||
Any other variable from [Environment-Variables](Environment-Variables), such as `OIDC_USERNAME_CLAIM`, `FILE_UPLOAD_LIMIT_MB`, `PLACES_API_KEY` or `HTTP_PROXY`, is added as a new variable in the template editor, with its name as the key.
|
||||
Any other variable from [Environment-Variables](Environment-Variables), such as `OIDC_USERNAME_CLAIM`, `ALLOW_LINK_LOCAL_IPS`, `FILE_UPLOAD_LIMIT_MB`, `PLACES_API_KEY`, the `SMTP_*` settings, the `AMAP_*` keys or `HTTP_PROXY`, is added as a new variable in the template editor, with its name as the key.
|
||||
|
||||
## Setting the Encryption Key
|
||||
|
||||
@@ -69,6 +67,10 @@ http://<unraid-ip>:<port>
|
||||
|
||||
On first boot, TREK automatically creates an admin account. The credentials are printed to the container log — check **Docker → trek → Log** in the Unraid UI. If you set both `ADMIN_EMAIL` and `ADMIN_PASSWORD`, those values are used; otherwise the email is `admin@trek.local` and a random password is generated.
|
||||
|
||||
## Updating
|
||||
|
||||
Click the TREK container in the **Docker** tab and select **Update**. Before the new version migrates the database, TREK copies it to `pre-migrate-<schema>-<time>.db` in the `data` folder (`/mnt/user/appdata/trek/data` by default), so you can go back to the previous image if needed. See [Updating](Updating#database-migrations).
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Environment-Variables](Environment-Variables) — complete variable reference
|
||||
|
||||
@@ -6,11 +6,11 @@ TREK makes outbound HTTP requests when you configure integrations such as Immich
|
||||
|
||||
TREK has two SSRF guards, both in `ssrfGuard.ts`. Which one applies depends on the call site, not on who configured the URL.
|
||||
|
||||
**The strict guard** (`safeFetch` / `safeFetchFollow`, built on `checkSsrf`) covers most outbound traffic: Immich, Synology Photos, AirTrail, Dawarich, the document stores behind [Document-Sync](Document-Sync) (Paperless-ngx, Papra, Nextcloud, OpenCloud and Synology), notification webhooks, ntfy, Unsplash, and place lookups. It resolves the hostname to an IP address before allowing the connection and blocks loopback, link-local and private ranges. Only the private ranges open up, and only with `ALLOW_INTERNAL_NETWORK=true`. The two tables below describe this guard.
|
||||
**The strict guard** (`safeFetch` / `safeFetchFollow`, built on `checkSsrf`) covers most outbound traffic: Immich, Synology Photos, AirTrail, Dawarich, the wanderer connection, the document stores behind [Document-Sync](Document-Sync) (Paperless-ngx, Papra, Nextcloud, OpenCloud and Synology), notification webhooks, ntfy, Unsplash, place lookups, and the cloud hosts the AI assistant connections talk to (the ChatGPT sign-in and the hosted providers). It resolves the hostname to an IP address before allowing the connection and blocks loopback, link-local and private ranges. Only the private ranges open up, and only with `ALLOW_INTERNAL_NETWORK=true`. The two tables below describe this guard.
|
||||
|
||||
[Web Push](Notifications#web-push) deliveries go through the strict guard as well, with two narrower rules: they only ever go to the known push services (Google, Mozilla, Apple and Microsoft), and private ranges stay closed for them even with `ALLOW_INTERNAL_NETWORK=true`, because a push service is never on your LAN.
|
||||
|
||||
**The relaxed guard** (`safeFetchAdminConfigured`, also exported as `safeFetchLlm`) covers endpoints that are expected to live on your own network: OIDC (discovery, token, userinfo, JWKS), the LLM providers behind the AI Parsing addon (a local Ollama or any OpenAI-compatible endpoint), and plugin OAuth token exchanges. The self-hosted routing engines an admin sets for the [Road-Trip](Road-Trip) addon (**Own routing engine**, **Own Valhalla instance**) go through it too when the server asks them itself, which it does for the MCP road trip tools. The planner asks them from the browser, so they must also be reachable from your users' devices. It deliberately permits loopback and LAN targets, so a model server on `localhost` or an identity provider on your LAN works **without** `ALLOW_INTERNAL_NETWORK`. It still resolves every hostname, re-checks every redirect hop, and always blocks link-local and cloud-metadata addresses (`169.254.0.0/16`, the full `fe80::/10`, and the AWS and Alibaba metadata addresses). The only way past is a single address listed in `ALLOW_LINK_LOCAL_IPS`, see [below](#a-link-local-address-you-need).
|
||||
**The relaxed guard** (`safeFetchAdminConfigured`, also exported as `safeFetchLlm`) covers endpoints that are expected to live on your own network: OIDC (discovery, token, userinfo, JWKS), the LLM providers behind the AI Parsing addon (a local Ollama or any OpenAI-compatible endpoint), the AI server an admin sets up for the AI assistant, and plugin OAuth token exchanges. The self-hosted routing engines an admin sets for the [Road-Trip](Road-Trip) addon (**Own routing engine**, **Own Valhalla instance**) go through it too when the server asks them itself, which it does for the MCP road trip tools. The planner asks them from the browser, so they must also be reachable from your users' devices. It deliberately permits loopback and LAN targets, so a model server on `localhost` or an identity provider on your LAN works **without** `ALLOW_INTERNAL_NETWORK`. It still resolves every hostname, re-checks every redirect hop, and always blocks link-local and cloud-metadata addresses (`169.254.0.0/16`, the full `fe80::/10`, and the AWS and Alibaba metadata addresses). The only way past is a single address listed in `ALLOW_LINK_LOCAL_IPS`, see [below](#a-link-local-address-you-need).
|
||||
|
||||
**No guard** applies to the addresses an admin sets in the environment for place search: `TREK_PLACES_URL`, `NOMINATIM_URL` and `OVERPASS_URL`. They are configuration rather than user input, so a self-run copy of the [TREK Places API](TREK-Places-API), a Nominatim or an Overpass instance on your LAN or in the same Docker network is reached without `ALLOW_INTERNAL_NETWORK`.
|
||||
|
||||
@@ -48,13 +48,13 @@ The hostname `localhost` is matched at the hostname stage too, but it normally r
|
||||
|
||||
## When to enable
|
||||
|
||||
Set `ALLOW_INTERNAL_NETWORK=true` when a service reached through the strict guard (Immich, Synology Photos, AirTrail, Dawarich, a document store bound through [Document-Sync](Document-Sync), or a notification webhook) is hosted on your local network and you need TREK to reach it. You do **not** need it for a local or LAN Ollama, an OpenAI-compatible endpoint, an OIDC provider on your LAN, your own OSRM or Valhalla, or plugin OAuth; those go through the relaxed guard and already work. Nor do you need it for your own TREK Places API, Nominatim or Overpass, which are not guarded at all. Leave the flag off if only those need internal access, since turning it on widens the surface for every strict-guard integration at once.
|
||||
Set `ALLOW_INTERNAL_NETWORK=true` when a service reached through the strict guard (Immich, Synology Photos, AirTrail, Dawarich, wanderer, a document store bound through [Document-Sync](Document-Sync), or a notification webhook) is hosted on your local network and you need TREK to reach it. You do **not** need it for a local or LAN Ollama, an OpenAI-compatible endpoint, an OIDC provider on your LAN, your own OSRM or Valhalla, or plugin OAuth; those go through the relaxed guard and already work. Nor do you need it for your own TREK Places API, Nominatim or Overpass, which are not guarded at all. Leave the flag off if only those need internal access, since turning it on widens the surface for every strict-guard integration at once.
|
||||
|
||||
A service in another container on the same Docker network counts as internal too, because its container name resolves to a private address; so do a Tailscale address (`100.64.0.0/10`) and a `.local` name. A service on loopback (`localhost`, `127.0.0.1`) is never reached through the strict guard, whatever the flag says: use the host's LAN address or the container name instead.
|
||||
|
||||
See [Environment-Variables](Environment-Variables) for how to set environment variables.
|
||||
|
||||
> **Admin:** Set `ALLOW_INTERNAL_NETWORK=true` in [Environment-Variables](Environment-Variables) before configuring Immich, Synology Photos, AirTrail, Dawarich or a document store on a LAN.
|
||||
> **Admin:** Set `ALLOW_INTERNAL_NETWORK=true` in [Environment-Variables](Environment-Variables) before configuring Immich, Synology Photos, AirTrail, Dawarich, wanderer or a document store on a LAN.
|
||||
|
||||
## A link-local address you need
|
||||
|
||||
@@ -66,7 +66,7 @@ Name that one address in `ALLOW_LINK_LOCAL_IPS`:
|
||||
ALLOW_LINK_LOCAL_IPS=169.254.1.2
|
||||
```
|
||||
|
||||
- The relaxed guard (OIDC, AI Parsing, plugin OAuth, your own routing engines) then reaches it with nothing else set.
|
||||
- The relaxed guard (OIDC, AI Parsing, the AI assistant's own server, plugin OAuth, your own routing engines) then reaches it with nothing else set.
|
||||
- The strict guard treats it as internal, like a `192.168.x` address, so Immich, a document store or any other integration behind it also needs `ALLOW_INTERNAL_NETWORK=true`.
|
||||
- Every other link-local address stays blocked. `169.254.169.x` and `169.254.170.x`, where AWS, GCP, Azure and the container services built on them hand out instance metadata and credentials, cannot be listed at all. TREK refuses to start with one of them in the list, and with any entry that is not a single IPv4 address such as `169.254.1.2`, so IPv6 link-local (`fe80::/10`) cannot be listed either.
|
||||
|
||||
@@ -84,7 +84,7 @@ A hostname can resolve to several addresses, and a LAN DNS server often hands ou
|
||||
|
||||
## Audit log
|
||||
|
||||
When a user saves an Immich URL that resolves to a private IP, TREK records an `immich.private_ip_configured` entry in the [Audit-Log](Audit-Log) including the URL and the resolved IP address. AirTrail does the same with `airtrail.private_ip_configured`, and Dawarich with `dawarich.private_ip_configured`. Synology Photos does not emit an equivalent event, and neither does document sync.
|
||||
When a user saves an Immich URL that resolves to a private IP, TREK records an `immich.private_ip_configured` entry in the [Audit-Log](Audit-Log) including the URL and the resolved IP address. AirTrail does the same with `airtrail.private_ip_configured`, and Dawarich with `dawarich.private_ip_configured`. Synology Photos does not emit an equivalent event, and neither do wanderer and document sync.
|
||||
|
||||
## See also
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Invite new users to register on your TREK instance, even when open registration
|
||||
|
||||
An invite link lets a person register a new TREK account without requiring the site to have open registration enabled. Visiting `/register?invite=<token>` pre-validates the token and switches the page to the Register form. The token's use count is incremented on successful registration, and the link stops working once the use limit is reached.
|
||||
|
||||
> Invite links here are for **registering new accounts**. To let people who *already* have an account join a specific trip, use the trip invite link in the trip's Share panel — see [Trip-Members-and-Sharing](Trip-Members-and-Sharing).
|
||||
> Invite links here are for **registering new accounts**. To let people who *already* have an account join a specific trip, use the trip invite link in the **Sharing** area of the trip's **Trip settings** (see [Trip-Members-and-Sharing](Trip-Members-and-Sharing)).
|
||||
|
||||
## Creating invite links
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ From the Journey list, click **Create journey**. Give it a title and optional su
|
||||
|
||||
A place brought in from a linked trip sits in the timeline as a **suggestion** until you write into it. One you will not use can be dismissed on its own, with **Dismiss this suggestion** on its card (on a phone, in its sheet). A dismissed suggestion leaves the journey without being deleted, and the trip sync does not offer the same place again. **Journey Settings** shows how many you dismissed and **Bring back dismissed suggestions** returns them all.
|
||||
|
||||
### Opening the journal from the trip
|
||||
|
||||
The link can also be made from the trip: **Trip settings**, **Journal** area, **Link a journal**. The journal then opens inside the trip, in its Journal tab, for the trip members you gave access. See [Trip-Members-and-Sharing](Trip-Members-and-Sharing#journal).
|
||||
|
||||
## Journal entries
|
||||
|
||||
Each entry corresponds to a day in your journey. The entry editor provides:
|
||||
@@ -172,15 +176,16 @@ While you travel, the stays of each day can be ready for review without you star
|
||||
|
||||
## TREK Studio
|
||||
|
||||
A journey can also be laid out as a printable photo book. Open a journey and click **Studio** in the header. The designer opens on top of the journey at `/journey/:id/studio`, so the journey stays open underneath and **Back to the journey** drops you straight back into it. Studio is marked **Beta**.
|
||||
A journey can also be laid out as a printable photo book. Open a journey and click **Studio** in the header. The designer opens on top of the journey at `/journey/:id/studio`, so the journey stays open underneath and **Back to the journey** drops you straight back into it.
|
||||
|
||||

|
||||
|
||||
- **Page format** — Square 21 × 21 cm (the default), Square 30 × 30 cm, A4 landscape, A4 portrait, A5 landscape, or a custom width × height in millimetres. Everything is drawn as a spread (two pages side by side) with 3 mm bleed and a 5 mm safe margin.
|
||||
- **The shape of the book** follows a bound one: a cover, a single first page on the right (page 1, where a title page or a dedication goes), the spreads, a single last page on the left, and a back cover. The first and last pages take the cover layouts and, like the covers, stay where they are; new spreads always go between them. Page numbers, when switched on, count from the first page, and the number on screen is the number that prints. Books made before this had no single pages and keep their numbering as it was.
|
||||
- **Auto layout** has two entries. **This spread** builds the spread on screen again from the journal entry it came from, and is only offered on a spread that came from one. **The whole book** replaces every page, keeping your title and page setup. Both are ordinary undo steps, so you can press one, look at it, and undo.
|
||||
- **Pages, Content, Layouts, Elements and Travel** are the sections of the left rail, in the order a book is made, with **Theme** and **Layers** set apart below them. The rail and the tabs inside its panels answer to the arrow keys. Content holds the journey's own photos and entries, with **Upload photos** and, when Immich or Synology Photos is connected, **From Immich** or **From Synology Photos** to add photos from your library the way the journey gallery does; Layouts opens on **Designed pages**, whole pages laid out by a designer: 48 covers in twelve styles (spine band, poster, cut-out, postcard, grid and badge, minimal, stamps, riso, editorial, vintage poster, night film, field notes) for the cover and the other single pages, and 60 double spreads for the pages between, five in each style. Each card shows the page you are on as the click will lay it, with its own photos and words in the template and in the book's theme, and the style chips narrow the set to one look. Below them come the book's own layouts and the built-in ones: thirteen spread layouts (Hero and story, Four up, Strip and text, Mosaic and so on) plus a separate set of five for the cover and back; Elements has six tabs: text styles, shapes, lines, empty frames with their frame styles and grids, a searchable icon library, and the stickers; Travel builds figures out of the journey itself: route maps, country outlines and lists, flags, date, day and distance marks, and a trip summary. Theme sets the look of the whole book, and Layers lists the page front to back.
|
||||
- **Pages, Content, Layouts, Elements and Travel** are the sections of the left rail, in the order a book is made, with **Theme** and **Layers** set apart below them. The rail and the tabs inside its panels answer to the arrow keys. Content holds the journey's own photos and entries, with **Upload photos** and, when Immich or Synology Photos is connected, **From Immich** or **From Synology Photos** to add photos from your library the way the journey gallery does; Layouts opens on **Designed pages**, whole pages laid out by a designer: 48 covers in twelve styles (spine band, poster, cut-out, postcard, grid and badge, minimal, stamps, riso, editorial, vintage poster, night film, field notes) for the cover and the other single pages, and 60 double spreads for the pages between, five in each style. Each card shows the page you are on as the click will lay it, with its own photos and words in the template and in the book's theme, and the style chips narrow the set to one look. Below them come the book's own layouts and the built-in ones: thirteen spread layouts (Hero and story, Four up, Strip and text, Mosaic and so on) plus a separate set of five for the cover and back; Elements has six tabs: text styles, shapes, lines, empty frames with their frame styles and grids, a searchable icon library, and the stickers; Travel builds figures out of the journey itself: route maps, country outlines and lists, flags, date, day and distance marks, and a trip summary. Theme sets the look of the whole book (**Choose a theme** at first, **Change the theme** afterwards), and Layers lists the page front to back.
|
||||
- **Properties** on the right edits whatever is selected, in the same order for every kind: what the element is or says (a text's words, a photo's crop and focal point, a shape), then its position and size, then its look (type, colour, fill, frame, corner), then its effects, and last **Arrange** (aligning, stacking, grouping, copying a style, and a button that shows the page in Layers). The groups you set rarely start folded and open by themselves on an element that already uses them. With nothing selected it shows the page background, the book's theme and the page numbers. An element that auto layout tied to a journal entry follows that entry until you edit it here, which breaks the link.
|
||||
- **Assistant**: with the AI assistant addon on, the **Assistant** toggle in the Studio bar (*Design the book together with the assistant*) opens a **Book assistant** window that you can move and resize. It can answer questions and change the book. Before it sees anything, a notice explains that only the page you are working on goes to your AI provider, as a picture showing just the photos you added yourself; **Show it pages** allows that, **Not now** keeps it closed. For someone who may only view the book, it answers questions but changes nothing.
|
||||
- **Copy and paste**: a selected element copies with Ctrl+C and pastes on any page with Ctrl+V or the paste button.
|
||||
- **My layouts**: **Save this page as a layout** keeps the arrangement of a page without its photos, for every editor of the book, and applying it lays another page out the same way while keeping that page's photos and words. A book keeps up to 24 layouts.
|
||||
- **Export** opens a print view that your browser turns into a PDF. Pick **Single pages** (one leaf per sheet, what a printer wants) or **Spreads** (two pages at a time, the way the book opens), with optional crop marks that add the bleed on every edge and mark where to cut.
|
||||
@@ -214,3 +219,5 @@ Both toggles matter. A photo's coordinates follow the **Map** switch: with Map o
|
||||
- [Addons-Overview](Addons-Overview)
|
||||
- [Admin-Addons](Admin-Addons)
|
||||
- [Public-Share-Links](Public-Share-Links)
|
||||
- [TREK-Studio](TREK-Studio)
|
||||
- [Trip-Settings](Trip-Settings)
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
# Login and Registration
|
||||
|
||||

|
||||

|
||||
|
||||
On a wide screen (1024 pixels and up) the left side of the page shows an animated dot map of the world on which routes light up between cities, with the tagline **Your Trips. Your Plan.** and a short description. The sign in card sits on the right. On narrower screens the panel is hidden and the card is shown under the TREK logo.
|
||||
|
||||
## Signing in
|
||||
|
||||
Navigate to `/login` and enter your email and password. On success, the server sets a `trek_session` cookie — httpOnly, sameSite=`lax`, and secure in production — that keeps you signed in across page reloads. How long it survives depends on the **Remember me** switch, described below. You do not need to sign in again until the session expires or you explicitly log out.
|
||||
Navigate to `/login` and enter your email and password. On success, the server sets a `trek_session` cookie (httpOnly, sameSite=`lax`, and secure in production) that keeps you signed in across page reloads. How long it survives depends on the **Remember me** switch, described below. You do not need to sign in again until the session expires or you explicitly log out.
|
||||
|
||||
> **Note:** The `secure` flag on the cookie can be overridden by setting `COOKIE_SECURE=false` in the server environment (useful for plain-HTTP dev setups), or force-enabled with `FORCE_HTTPS=true`.
|
||||
|
||||
@@ -16,16 +18,16 @@ If you have forgotten your password, click the **"Forgot password?"** link below
|
||||
|
||||
The **Remember me** switch below the password field decides how long the session lives:
|
||||
|
||||
- **Off** (the default) — a browser-session cookie with no `maxAge`, cleared when you close the browser, backed by a token valid for `SESSION_DURATION` (default `24h`).
|
||||
- **On** — a persistent cookie matching a token valid for `SESSION_DURATION_REMEMBER` (default `30d`), so the session survives browser restarts.
|
||||
- **Off** (the default): a browser-session cookie with no `maxAge`, cleared when you close the browser, backed by a token valid for `SESSION_DURATION` (default `24h`).
|
||||
- **On**: a persistent cookie matching a token valid for `SESSION_DURATION_REMEMBER` (default `30d`), so the session survives browser restarts.
|
||||
|
||||
Both durations are configurable per instance, see [Environment-Variables](Environment-Variables). Your choice is carried through the MFA step, through a password change, and through SSO sign-in. While you keep using TREK the cookie is silently re-issued once the token is past half its lifetime, with the same Remember me semantics, so an active session never expires mid-use. Only cookie sessions are renewed this way — API and MCP clients authenticating with a bearer token are not.
|
||||
Both durations are configurable per instance, see [Environment-Variables](Environment-Variables). Your choice is carried through the MFA step, through a password change, and through SSO sign-in. While you keep using TREK the cookie is silently re-issued once the token is past half its lifetime, with the same Remember me semantics, so an active session never expires mid-use. Only cookie sessions are renewed this way; API and MCP clients authenticating with a bearer token are not.
|
||||
|
||||
Sign-ins that never pass through this switch — registration, the demo button and passkey sign-in — get the historical default instead: a persistent cookie lasting `SESSION_DURATION`.
|
||||
Sign-ins that never pass through this switch (registration, the demo button and passkey sign-in) get the historical default instead: a persistent cookie lasting `SESSION_DURATION`.
|
||||
|
||||
### Forced password change
|
||||
|
||||
Some accounts are flagged as needing a new password: the admin account TREK seeds on first boot always is, and so is an account restored with the `reset-admin.js` recovery script (see [Troubleshooting](Troubleshooting)). For those accounts a **Set new password** form is shown immediately after a successful login (or after the MFA step). The session cookie has already been issued at that point — the app simply keeps you on the form until the new password is saved, and saving it re-issues the cookie and signs your other sessions out.
|
||||
Some accounts are flagged as needing a new password: the admin account TREK seeds on first boot always is, and so is an account restored with the `reset-admin.js` recovery script (see [Troubleshooting](Troubleshooting)). For those accounts a **Set new password** form is shown immediately after a successful login (or after the MFA step). The session cookie has already been issued at that point; the app simply keeps you on the form until the new password is saved, and saving it re-issues the cookie and signs your other sessions out.
|
||||
|
||||
There is no control in the Admin Panel that flags an existing account. An admin-set password (see [Admin-Users-and-Invites](Admin-Users-and-Invites)) neither raises the flag nor clears it, so a user who already carries it is still asked to choose their own password at the next sign-in.
|
||||
|
||||
@@ -39,9 +41,9 @@ To end sessions on other devices, the API offers `GET /api/auth/sessions` (the s
|
||||
|
||||
The Register form appears under one of these conditions:
|
||||
|
||||
- **Open registration** — the admin has enabled password registration for the instance (`password_registration` setting).
|
||||
- **Valid invite link** — you visited `/register?invite=TOKEN` with a valid token (see below).
|
||||
- **No accounts at all** — nobody has signed up yet; the registration form is shown automatically and the first account created becomes an admin. On a normal install this never happens, because TREK seeds an admin on first boot (see [First run](#first-run) below).
|
||||
- **Open registration**: the admin has enabled password registration for the instance (`password_registration` setting).
|
||||
- **Valid invite link**: you visited `/register?invite=TOKEN` with a valid token (see below).
|
||||
- **No accounts at all**: nobody has signed up yet; the registration form is shown automatically and the first account created becomes an admin. On a normal install this never happens, because TREK seeds an admin on first boot (see [First run](#first-run) below).
|
||||
|
||||
Registration fields: **username**, **email**, and **password**.
|
||||
|
||||
@@ -77,19 +79,25 @@ On a normal install TREK seeds an admin account on first boot, before anyone can
|
||||
|
||||
- With **both** `ADMIN_EMAIL` and `ADMIN_PASSWORD` set, those values are used.
|
||||
- With only one of the two set, both are ignored (a warning is logged) and the generated credentials below are used instead.
|
||||
- Otherwise the account is `admin@trek.local`, username `admin`, with a randomly generated password printed to the container log — run `docker logs trek` to retrieve it.
|
||||
- Otherwise the account is `admin@trek.local`, username `admin`, with a randomly generated password printed to the container log; run `docker logs trek` to retrieve it.
|
||||
|
||||
If no user exists at all, the page opens on a **Create Admin Account** form instead: "Set up the first admin account for TREK." The account created there is the admin.
|
||||
|
||||
The seeded admin is flagged as requiring a password change, so you are forced to set a new password on first sign-in. Until that happens the Register link stays hidden even though password registration is enabled by default; once the password is changed the link appears normally.
|
||||
|
||||
Two setups skip the seeder entirely. `DEMO_MODE=true` seeds the demo data instead (see [Demo-Mode](Demo-Mode)), and on an **OIDC-only** install no local account is created at all — there the first user who signs in through the identity provider is assigned the **admin** role.
|
||||
Two setups skip the seeder entirely. `DEMO_MODE=true` seeds the demo data instead (see [Demo-Mode](Demo-Mode)), and on an **OIDC-only** install no local account is created at all; there the first user who signs in through the identity provider is assigned the **admin** role.
|
||||
|
||||
See [Quick-Start](Quick-Start) for the full first-boot walkthrough.
|
||||
|
||||
## Sign-in over plain HTTP
|
||||
|
||||
If you reach TREK over plain HTTP, the browser drops the secure session cookie and the next request fails with "Access token required". After such a sign-in the page shows a warning, **Login won't stick over HTTP**, with an **Open the Troubleshooting guide** link. Use HTTPS, or for a home lab set `COOKIE_SECURE=false`. See [Troubleshooting](Troubleshooting).
|
||||
|
||||
## Rate limiting
|
||||
|
||||
Requests to the login endpoint are rate-limited to **10 per 15-minute window** per IP address. The counter is incremented before the credentials are checked, so successful sign-ins count against it too, not only failed ones. After exceeding the limit, further requests return HTTP 429 until the window resets. The window is fixed from the first counted request, and blocked requests do not extend it.
|
||||
|
||||
That counter is shared rather than per-endpoint. `POST /api/auth/login`, `POST /api/auth/register`, `GET /api/auth/invite/:token` and the passkey sign-in ceremony each allow 10 requests from it; `PUT /api/auth/me/password`, `POST /api/auth/mfa/disable`, `POST /api/auth/mcp-tokens` and passkey deletion draw on the same counter but are rejected once it reaches 5. Unrelated activity from the same IP therefore eats into the allowance — ten registration attempts will 429 the next login, and five requests of any kind will 429 a password change.
|
||||
That counter is shared rather than per-endpoint. `POST /api/auth/login`, `POST /api/auth/register`, `GET /api/auth/invite/:token` and the passkey sign-in ceremony each allow 10 requests from it; `PUT /api/auth/me/password`, `POST /api/auth/mfa/disable`, `POST /api/auth/mcp-tokens` and passkey deletion draw on the same counter but are rejected once it reaches 5. Unrelated activity from the same IP therefore eats into the allowance: ten registration attempts will 429 the next login, and five requests of any kind will 429 a password change.
|
||||
|
||||
MFA verification attempts are rate-limited separately to **5 attempts per 15-minute window** per IP address.
|
||||
|
||||
@@ -97,14 +105,16 @@ Forgot-password requests are rate-limited to **3 attempts per 15-minute window**
|
||||
|
||||
## Demo mode
|
||||
|
||||
When the server is started with `DEMO_MODE=true`, a **"Try the demo — no registration needed"** button appears below the login form. Clicking it signs you in as the demo user without entering credentials. The demo credentials (`demo@trek.app` / `demo12345`) are also displayed in the app config for reference, but the one-click button is the intended entry point.
|
||||
When the server is started with `DEMO_MODE=true`, a **Try the demo** button ("no registration needed") appears below the login form. Clicking it signs you in as the demo user without entering credentials. The demo credentials (`demo@trek.app` / `demo12345`) are also part of the app config for reference, but the one-click button is the intended entry point. See [Demo-Mode](Demo-Mode).
|
||||
|
||||
## SSO
|
||||
|
||||
If the admin has configured OpenID Connect, a **"Sign in with SSO"** button (labelled with the configured `OIDC_DISPLAY_NAME`, defaulting to `SSO`) appears below the login form. See [OIDC-SSO](OIDC-SSO) for details on setup and the sign-in flow.
|
||||
|
||||
If the identity provider's answer cannot be used, the login page shows why: registration is disabled for this instance, the provider sent no email address, the provider has not confirmed the email address so it cannot be linked to an existing account, or the sign-in could not be linked to the existing account with that email and your administrator has to confirm the address.
|
||||
|
||||
When OIDC-only mode is active (password login disabled), visiting `/login` automatically redirects the browser to the identity provider. The page only says where it is going ("Taking you to Keycloak…", with the configured display name) and offers nothing to fill in; should the redirect not have happened after eight seconds, a link to continue appears. The email/password form is never shown, not even while the page is still asking the server which sign-in it offers: until the answer arrives it shows a short wait, and on a repeat visit it announces the redirect straight away. The automatic redirect is suppressed when you have explicitly logged out, after a failed sign-in at the identity provider, and when the server could not be reached; the SSO button is shown instead so you can choose to sign back in.
|
||||
|
||||
---
|
||||
|
||||
**See also:** [OIDC-SSO](OIDC-SSO) · [Admin-Users-and-Invites](Admin-Users-and-Invites) · [Password-Reset](Password-Reset)
|
||||
**See also:** [OIDC-SSO](OIDC-SSO), [Admin-Users-and-Invites](Admin-Users-and-Invites), [Password-Reset](Password-Reset)
|
||||
|
||||
@@ -246,6 +246,17 @@ Requires `journey:read` or `journey:write` scope.
|
||||
|
||||
Every book write is one save of the whole book against its version: nothing is written when any part is refused, and every member's open Studio is told the book changed, the asking one included.
|
||||
|
||||
### Trip journal link _(Journey addon required)_
|
||||
|
||||
A trip can show one of your journals as its own. Requires `journey:read` to look and `journey:write` to change, and you must be allowed to edit the trip.
|
||||
|
||||
| Tool | Description |
|
||||
|---|---|
|
||||
| `get_trip_journal` | The journal a trip shows as its own, if any: its id and title, your access to it, and whether you may link, unlink or change who it is open to. Open the journal itself with `get_journey`. |
|
||||
| `link_trip_journal` | Show one of your own journals in a trip, replacing the one it showed. The trip members you list get into the journal as viewers or editors and see it in their own journal list; members left out do not. The journal has to be yours, and the trip permission to link journals applies. |
|
||||
| `set_trip_journal_members` | Change which trip members the linked journal is open to, and as viewer or editor. The list replaces the one before, and anyone left out loses the access the link gave them. Only the journal's owner can do this. |
|
||||
| `unlink_trip_journal` | Take the linked journal off a trip. The journal stays; members the link let in lose that access, while its owner and direct contributors keep theirs. |
|
||||
|
||||
### Dawarich _(Dawarich addon required)_
|
||||
|
||||
Each tool asks for the scope of what it writes, so the scopes differ per tool. The connection itself (address, API key, test, disconnect) has no MCP tool. See [Dawarich](Dawarich).
|
||||
@@ -290,6 +301,7 @@ The saved tours of a trip, as the Tours list and the tour detail show them, how
|
||||
| `find_tours_for_day` | The tours put on one day of a trip, with the same facts as `list_tours` | `trips:read` |
|
||||
| `get_city_walk_progress` | How far a city walk got on one day it is on: every station in order with its key, its status that day (planned, visited or skipped, as checked off in the day plan), importance, protection, stay and opening hours, what is still open, and the walking time of the whole walk. Visits belong to that day only. Reading changes nothing | `trips:read` |
|
||||
| `get_city_walk_remaining_time` | What is left of a city walk on one day it is on, counted from the last station checked off as visited (or the start): the walking time still ahead along the saved line, the stays still open and the open stations, kept apart from the walking time of the whole walk. Says what it counts from and that no live position is known; an upper bound while a station ahead is skipped; unknown, with the reason, without a line, a walking time or a clear order of visits. Reading changes nothing | `trips:read` |
|
||||
| `set_city_walk_visit` | Check off a station of a city walk on one day it is on, the way the travellers tap it in the day plan: visited, skipped, or planned to take a mark back. Use it when the travellers say where they are or what they did. `stationKey` is the key of the station from `get_city_walk_progress` or `get_tour_plan`. The mark belongs to that day only. The answer gives the status before and after and the walk as it now stands. Needs the right to edit the trip days. The route does not change | `trips:write` |
|
||||
| `export_tour_gpx` | One saved tour as a GPX file: its whole saved line as one track, with the heights it carries and none it lacks, and a file name. A tour without a line cannot be exported | `trips:read` |
|
||||
| `search_tour_pois` | Places along the saved line of a hike, run, ride, bike tour, paddle tour, ski and winter tour or city walk within a corridor (viewpoints, peaks, shelters, drinking water, food, toilets, picnic, campsites, sights, slipways, boat rental, bike repair, for a bike tour e-bike charging points, for a ski and winter tour coffee shops and places to eat as well, and for a city walk museums and galleries, parks and gardens, coffee shops, places to eat and markets): source (TREK places index or OpenStreetMap), kind, address, website, phone, opening hours as the source has them (a hint, never a promise), the distance straight across to the line (not a detour) and how far along the line; up to 60, the nearest to the line when more match, listed from the start. An e-bike charging point is one OpenStreetMap tags for bicycles (`bicycle=designated` or `yes`, never a charger for cars alone) and carries `charging`: bicycle, sockets, capacity, fee and access as OpenStreetMap states them, empty where it says nothing; whether it works or is free today is not known. When sights are asked for, the best known places near the line (by the page views of their Wikidata item) are searched too, so a famous square no category names is found as a sight, and the highlights among them carry `highlight: true` and come first. A place OpenStreetMap has no name for comes with an empty name. `unavailable` names the categories no source could be searched for right now, so their places are missing rather than absent. `retry_after_s`, when present beside `unavailable`, is how many seconds until asking again makes sense, because the OpenStreetMap mirrors failed and are only probed now and then. Says when stretches could not be searched, only the first part of a long line was, or more places matched. A tour saved with its points only (`route_pending`) has no line to search along yet. Nothing is added | `trips:read` |
|
||||
| `list_tour_library` | The saved tours of every trip the user can open, to choose one to take over into another trip: name, type, distance, ascent, descent, planned times and the trip each is in. Narrowed by a part of the name, a type or a trip; the trip being planned can be left out. Up to 100 tours, `truncated` says there were more | `trips:read` |
|
||||
|
||||
+13
-1
@@ -14,12 +14,24 @@ Once connected, an AI assistant can work with your TREK data in a single convers
|
||||
- Send collab messages and notes to other trip members
|
||||
- Mark countries and regions as visited in Atlas
|
||||
- Log vacation days in Vacay
|
||||
- Write journey entries across multiple trips
|
||||
- Write journey entries across multiple trips, and show a journal inside a trip
|
||||
- Plan, edit and check off tours: hikes, bike, paddle, ski and winter tours, rides and city walks
|
||||
- Plan road trips: route, hazards, charging stops and places along the way
|
||||
- Import flights from AirTrail and visits and routes from Dawarich
|
||||
- Import places from links and tracks from GPX files
|
||||
- Switch calendar feeds and trip invite links on or off
|
||||
- Keep school holiday regions up to date for Vacay
|
||||
- Upload documents to a trip, read them and link them to bookings, places or expenses
|
||||
- Look up how a TREK feature works in the bundled help
|
||||
|
||||
Changes made through MCP are broadcast to all connected clients in real-time — exactly like changes made in the web UI.
|
||||
|
||||
Many of these tools belong to an addon and only appear while an administrator has enabled it. See [MCP-Addon-Tools](MCP-Addon-Tools).
|
||||
|
||||
### MCP and the built-in AI Assistant
|
||||
|
||||
The **AI Assistant** addon is a chat inside TREK itself. It works on the same tools as an external MCP client and the same permission checks apply, but it does not connect through `/mcp`: its AI provider is set up inside TREK, not through OAuth clients. Changes it suggests wait for your confirmation. MCP is the way to let a different AI app, such as Claude.ai or Cursor, use TREK.
|
||||
|
||||
## Authentication options
|
||||
|
||||
| Use case | Method |
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ TREK defines 35 scopes across 17 groups.
|
||||
- `list_trips` and `get_trip_summary` are always available regardless of scope — they are navigation tools.
|
||||
- `plugins:use` grants no data access of its own. It lets a client call tools published by plugins your administrator installed and approved, and each plugin acts with the permissions the administrator granted it — which can reach further than the scopes on your token. The admin's `mcp:tools` grant is the real boundary, not this scope. No client preset selects it for you: a client has to ask for it by name.
|
||||
- Static tokens and web session JWTs have full access equivalent to all scopes, `plugins:use` included.
|
||||
- Addon-gated tools (Packing, To-dos, Budget, Collections, Atlas, Collab, Vacay, Journey, Road trip, Dawarich, Document sync and AirTrail) require both the relevant scope **and** the corresponding addon to be enabled by an admin. The to-do tools ride the **Packing** addon (listed as **Lists** under **Admin → Addons**), not an addon of their own. The Road trip tools sit on `trips:*` and `places:write`, the Dawarich tools on `journey:*`, `places:write` and `atlas:write`, the Document sync tools on `files:*` under the **Documents** addon, and the AirTrail tools on `reservations:*`; without the addon, a client holding those scopes does not see them.
|
||||
- Addon-gated tools (Packing, To-dos, Budget, Collections, Atlas, Collab, Vacay, Journey, Tours, Road trip, Dawarich, Document sync and AirTrail) require both the relevant scope **and** the corresponding addon to be enabled by an admin. The to-do tools ride the **Packing** addon (listed as **Lists** under **Admin → Addons**), not an addon of their own. The Tours tools sit on `trips:*` (and on `collections:*` for tours kept in a collection), the Road trip tools on `trips:*` and `places:write`, the Dawarich tools on `journey:*`, `places:write` and `atlas:write`, the Document sync tools on `files:*` under the **Documents** addon, and the AirTrail tools on `reservations:*`; without the addon, a client holding those scopes does not see them.
|
||||
|
||||
## Choosing the right scopes
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ Claude.ai (web) supports native MCP connections — no JSON config file required
|
||||
3. Give the client a name, adjust scopes if needed, and save. Copy the client ID and client secret (`trekcs_` prefix) — the secret is shown only once.
|
||||
4. In Claude.ai, open the MCP settings and add a new server using your TREK URL (`https://<your-trek-instance>/mcp`). Claude.ai will open your browser to complete the OAuth consent flow.
|
||||
|
||||
**Without a pre-created client.** Claude.ai can also identify itself by a metadata URL instead of a registered client. TREK fetches that small JSON document, checks it and shows the consent screen with the line **Verified domain**, naming the host the document came from. Only after you approve does TREK keep the client, and a client nobody uses is cleaned up again later. You do not have to do anything for this; it works when you add the server in Claude.ai and skip the steps above.
|
||||
|
||||
### Claude Desktop
|
||||
|
||||
Claude Desktop supports native MCP connections — no JSON config file required:
|
||||
|
||||
@@ -4,7 +4,7 @@ TREK exposes **tools** (read and write actions) and **resources** (read-only `tr
|
||||
|
||||
Every built-in tool checks its arguments against its published schema before anything runs. An argument the tool does not declare (a misspelt field such as `stopType` for `stop_type`) is refused with `Unrecognized key`, so the AI sees the mistake and can retry rather than reporting a change that never happened. Plugin-contributed tools follow the schema their manifest declares.
|
||||
|
||||
For addon-gated tools (Packing, To-Dos, Atlas, Collab, Collections, Vacay, Journey, Dawarich, Document sync, Road trip) and their resources, see [MCP-Addon-Tools](MCP-Addon-Tools).
|
||||
For addon-gated tools (Packing, To-Dos, Atlas, Collab, Collections, Vacay, Journey including the link between a trip and a journal, Dawarich, Document sync, Tours, Road trip) and their resources, see [MCP-Addon-Tools](MCP-Addon-Tools).
|
||||
|
||||
## Tools
|
||||
|
||||
|
||||
+12
-4
@@ -4,7 +4,7 @@ The map in the middle of the Plan tab shows your places, the route of the select
|
||||
|
||||
## Map renderer
|
||||
|
||||
TREK uses **Leaflet** by default. The renderer is picked in Settings → Map under **Map provider**: **Leaflet** for raster tiles, **MapLibre GL** for OpenFreeMap vector tiles (no token required), or **Mapbox GL** for vector tiles with 3D buildings and terrain, which additionally needs a Mapbox access token. If Mapbox GL is selected but no access token is present, TREK falls back to Leaflet automatically so the map is never blank.
|
||||
TREK uses **Leaflet** by default. The renderer is picked in Settings → Map under **Map provider**: **Leaflet** for raster tiles, **MapLibre GL** for OpenFreeMap vector tiles (no token required), or **Mapbox GL** for vector tiles with 3D buildings and terrain, which additionally needs a Mapbox access token. Mapbox GL carries the tag **Experimental** in the settings. If Mapbox GL is selected but no access token is present, TREK falls back to Leaflet automatically so the map is never blank.
|
||||
|
||||
The scopes required for Mapbox GL are:
|
||||
- STYLES:TILES
|
||||
@@ -23,6 +23,14 @@ On the desktop, a lock button sits on top of the satellite switcher in the botto
|
||||
|
||||
A round button in the bottom-left corner of the map flips the base layer between the normal map tiles and **satellite** imagery (ESRI World Imagery, no API key needed, usable up to zoom 19). The icon always shows the layer it switches to. The button is on all three renderers: Leaflet swaps its tile layer for the imagery, while MapLibre GL and Mapbox GL put the same imagery on as a raster layer of their own beneath everything TREK draws, so the route, the pins and the tracks stay on top of it. Your choice is stored on your account (`map_base_layer`), the same setting whichever renderer you use, so it carries over to every trip and survives a reload.
|
||||
|
||||
## Recorded route
|
||||
|
||||
With the [Dawarich](Dawarich) addon on and your Dawarich connected, a round Dawarich button sits at the bottom right of the desktop map, and among the map controls on a phone. **Show recorded route** draws the route your Dawarich recorded on the trip's dates, dashed and in one colour per day, underneath the planned route; **Hide recorded route** takes it off again. Its label also tells you why there is no line. See [The recorded route on the map](Dawarich#the-recorded-route-on-the-map).
|
||||
|
||||
## Map layers of the Tours tab
|
||||
|
||||
The map on the **Tours** tab has its own layer pill. Besides **Map** and **Satellite** it offers **Topo**, **Hiking** and **Cycling** base maps, depending on the type of the open tour, and overlays such as ski pistes, via ferratas and seamarks. They apply to that tab only and never change the map of the Plan tab. See [Tour map: base maps](Tours#tour-map-base-maps) and [Tour map: overlays](Tours#tour-map-overlays).
|
||||
|
||||
## Place markers
|
||||
|
||||
Each place is a round marker:
|
||||
@@ -35,7 +43,7 @@ Each place is a round marker:
|
||||
- **Unplanned places, compact:** with **Compact markers for unplanned places** switched on under **Settings > General > Travel & map**, places that no day holds are drawn as small markers without their photo, so the planned stops stand out. It is off by default, and the selected place always shows in full.
|
||||
- **Pending stay:** the place of an [accommodation](Accommodations) whose booking is still **Pending** is drawn with a dashed ring and a lighter face until the booking is confirmed.
|
||||
|
||||
Click a marker to open the [place inspector](Places-and-Search#the-place-inspector).
|
||||
Click a marker to open the [place inspector](Places-and-Search#the-place-inspector). Drag a marker onto a day, or between two rows of a day, in the days column to put the place on that day, the same as dragging its row from the places column. Markers do this on all three renderers.
|
||||
|
||||
When zoomed out, nearby markers are grouped into clusters. Clicking a cluster zooms the map to fit its members; at maximum zoom the cluster fans out to show the individual markers. Several stops at the very same spot, such as a hotel and the museum inside it, fold into one marker on MapLibre GL and Mapbox GL.
|
||||
|
||||
@@ -45,7 +53,7 @@ In the [Road trip](Road-Trip) view, results of the search along the route group
|
||||
|
||||
Rest the pointer on a place marker and a card follows the cursor with the place's photo (or its category tile), its name, the average member rating, the category and the address. It is the same card on every renderer and in [Collections](Collections), and it never gets in the way of a click.
|
||||
|
||||

|
||||

|
||||
|
||||
Markers that [plugins](Places-and-Search#categories-from-plugins) put on the map show their own name and up to six rows of the plugin's facts instead.
|
||||
|
||||
@@ -157,4 +165,4 @@ Right-click anywhere on the **Leaflet** map to open the place form with the clic
|
||||
|
||||
The **Mapbox GL** and **MapLibre GL** maps take the same right-click, and additionally **middle-click** and a **long-press** on touch. A right-button drag that rotates or pitches the map is not mistaken for a click, so the gesture and the shortcut coexist.
|
||||
|
||||
**See also:** [Places-and-Search](Places-and-Search) · [Day-Plans-and-Notes](Day-Plans-and-Notes) · [Route-Optimization](Route-Optimization) · [Map-Settings](Map-Settings) · [Reservations-and-Bookings](Reservations-and-Bookings) · [Road-Trip](Road-Trip)
|
||||
**See also:** [Places-and-Search](Places-and-Search), [Day-Plans-and-Notes](Day-Plans-and-Notes), [Route-Optimization](Route-Optimization), [Map-Settings](Map-Settings), [Reservations-and-Bookings](Reservations-and-Bookings), [Road-Trip](Road-Trip), [Tours](Tours)
|
||||
|
||||
@@ -163,6 +163,10 @@ For each trip map — Trip Planner, Collections and shared-trip links — TREK t
|
||||
|
||||
The small map preview on this settings page is the exception: it stays on a fixed city (Paris) — zoom 16 on the two GL previews, city-level zoom 12 under Leaflet — so you can judge label density, 3D buildings and satellite texture. It is not a setting and no real map opens there.
|
||||
|
||||
## Routing engines
|
||||
|
||||
The routes TREK draws and the travel times between stops come from a public OSRM router, and the avoidance of toll roads, motorways and ferries from a public Valhalla server. An admin can point TREK at engines of their own with **Own routing engine** and **Own Valhalla instance**, next to the map defaults under **Admin → User Defaults**. They are not part of this tab. See [Admin-User-Defaults](Admin-User-Defaults#own-routing-engine) and [Road-Trip](Road-Trip#routing-engines).
|
||||
|
||||
## See also
|
||||
|
||||
- [Map-Features](Map-Features)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# TREK on a Phone
|
||||
|
||||
TREK has a layout of its own for phones. It is the same app at the same address with the same data, drawn for one hand and a small screen: a floating bar at the bottom, sheets that slide up instead of dialogs, and a trip screen built around the day you are on. Install it to your home screen and it behaves like an app; see [Offline-Mode-and-PWA](Offline-Mode-and-PWA).
|
||||
|
||||
## When the phone layout applies
|
||||
|
||||
TREK switches to the phone layout when the window is narrower than 768 px, and also on a touch screen less than 500 px tall, so a phone turned on its side keeps the phone layout instead of jumping to the desktop planner. A tablet and a desktop window follow their width as usual. Turning the phone or resizing the window switches between the two layouts on the fly.
|
||||
|
||||
## The bottom bar
|
||||
|
||||
Outside a trip a floating bar sits at the bottom of every screen:
|
||||
|
||||
- **My Trips** (the dashboard) always comes first.
|
||||
- Two more destinations next to it, taken from the global addons your instance runs: by default the first two of Vacay, Journey, Atlas and Collections that are switched on.
|
||||
- **More** lists the rest: the other addons, page plugins, and the [AI Assistant](AI-Assistant) at the top when it is set up for you.
|
||||
- The raised button in the middle does what fits the screen: on the dashboard it creates a trip, on the journey list it starts a journey, inside a journey it adds an entry (or uploads a photo while the gallery is open), on Collections it adds a place to the open list, and on the Atlas it searches for a country. On Settings and the Admin screens it is a plain logo, and Vacay uses it for its own year and edit switch.
|
||||
|
||||
**Customising the bar.** On a phone, **Settings → Appearance** has a **Mobile** card with **Bottom navbar**: choose which items sit **In the bar** and which go **Under “More”**. **My Trips** stays first; two items fit next to it. The same card sets the **Dashboard order**. See [Appearance-Settings](Appearance-Settings#on-a-phone).
|
||||
|
||||
## The dashboard
|
||||
|
||||
The phone dashboard leads with the trip that is under way or comes next, then your other trips and the widgets you chose for the phone. At the top sit the bell for the [notifications inbox](Notifications-Inbox) and, when it is set up, the assistant. Which widgets show is set separately for desktop and phone in **Settings → Appearance**; see [Dashboard-Widgets](Dashboard-Widgets).
|
||||
|
||||
## A trip
|
||||
|
||||
A trip opens on its own screen with glass controls over the map, a row of day chips, and its own dock at the bottom.
|
||||
|
||||
**The trip dock** holds up to five of the trip's sections, in this order of priority: **Plan**, **Road trip**, **Transports**, **Bookings**, **Costs** and **Lists**. Only the sections switched on for the trip take a seat, and when there are more than five, the last ones move into **More**. Turning the road trip addon on, for example, moves the lists into **More** rather than leaving the drive without a seat.
|
||||
|
||||
**The Plan section** has three modes at the top:
|
||||
|
||||
| Mode | What it is for |
|
||||
|---|---|
|
||||
| **Travel** | Following the day on the road: the day's timeline with what is up next, **Jump to today**, and a way to navigate to each stop |
|
||||
| **Plan** | Changing the day: reorder stops by dragging, add places, notes and bookings, rename the day |
|
||||
| **Places** | Browsing the trip's places, filtering them, and adding one to a day; a switch at the top flips to the trip's saved tours |
|
||||
|
||||
Swipe sideways to go from day to day, or tap a day chip. A button switches between the list and the map; the map and the list are the same in every mode.
|
||||
|
||||
**The More sheet** of a trip starts with **Ask TREK** when the assistant is available, showing how many things in your plan are worth a check. Below come tiles for the sections that did not get a dock seat (such as Files, Collab and plugin tabs), then **Trip settings** ([Trip-Settings](Trip-Settings)), **Export** and, if you may edit the trip, **Edit Trip**.
|
||||
|
||||
**Export** on a phone offers the trip as a **PDF**, **My plan as PDF**, the GPX tracks of the **Whole trip**, **Download .ics**, and **Subscribe to calendar**, which keeps your calendar app up to date. See [PDF-Export](PDF-Export) and [Calendar-Feeds](Calendar-Feeds).
|
||||
|
||||
## The other screens
|
||||
|
||||
| Screen | On a phone |
|
||||
|---|---|
|
||||
| [Journey](Journey-Journal) | Your latest journey on top and the others below; entries as a timeline, photos from the device or from your photo library |
|
||||
| [Atlas](Atlas) | The world map with **Visited** and **Planned**, and the middle button as the country search |
|
||||
| [Vacay](Vacay) | The calendar month by month, with used and remaining days and **Edit calendar** in the middle button |
|
||||
| [Collections](Collections) | Your lists, with each place's status |
|
||||
| [Notifications](Notifications-Inbox) | The inbox as a full screen |
|
||||
| [Settings](User-Settings) | The same tabs as screens of their own |
|
||||
| [Admin](Admin-Panel-Overview) | One screen with the counters on top and a picker for the sections |
|
||||
|
||||
## What stays on the desktop
|
||||
|
||||
A few things need a bigger screen and are not offered on a phone:
|
||||
|
||||
- [TREK Studio](TREK-Studio), the photo book designer, and making its PDF.
|
||||
- Parts of the road trip planner: comparing route alternatives, making a day follow an imported track, and booking a night at a stop. The phone shows these as **Planned on desktop**.
|
||||
- The **Tours** tab, where tours are drawn and edited. Saved tours show on the phone under **Places**, ready to put on a day.
|
||||
- The **API Keys** section of **Settings → Integrations**.
|
||||
|
||||
## See also
|
||||
|
||||
- [Offline-Mode-and-PWA](Offline-Mode-and-PWA)
|
||||
- [Appearance-Settings](Appearance-Settings)
|
||||
- [AI-Assistant](AI-Assistant)
|
||||
- [Notifications-Inbox](Notifications-Inbox)
|
||||
- [Trip-Settings](Trip-Settings)
|
||||
@@ -36,17 +36,34 @@ Trips without dates are treated as past.
|
||||
|
||||
## Spotlight Card
|
||||
|
||||
The first ongoing trip — or the next upcoming trip if none is ongoing — is promoted to a full-width **Spotlight card** at the top of the grid on desktop, where it shows the travel companions, the trip dates, a countdown and the places as a boarding pass. On mobile this card appears as a hero at the top of the page, with a progress bar for ongoing trips and a stats strip (days, places, travel companions).
|
||||
The first ongoing trip, or the next upcoming trip if none is ongoing, is promoted to a full-width **Spotlight card** at the top of the grid on desktop, where it carries a badge for the state of the trip (**LIVE NOW**, **STARTS TODAY**, **TOMORROW**, **UP NEXT** or **RECENT**), the action buttons on the cover, and a boarding pass strip below the title: your **Buddies**, the **Trip dates**, a countdown (days left, or **Trip starts in** a number of days) and the number of places as destinations. On mobile this card appears as a hero at the top of the page, with a progress bar for ongoing trips and a stats strip (days, places, travel companions).
|
||||
|
||||
If you have no trips yet, the spotlight card is not shown.
|
||||
|
||||
## Stat tiles
|
||||
|
||||
Under the spotlight card on desktop, a row of four tiles sums up all your trips:
|
||||
|
||||
| Tile | What it shows |
|
||||
|---|---|
|
||||
| **Atlas · Countries visited** | The number of countries found in the places and transports of your trips, of 195, with the first flags. A country you removed in [Atlas](Atlas) stays removed here. |
|
||||
| **Trips total** | How many trips you have, and how many places are mapped on them. |
|
||||
| **Days traveled** | The days across all trips. |
|
||||
| **Distance flown** | The distance of your flights, and what that comes to in trips around the equator. |
|
||||
|
||||
Each tile is switched on or off under **Settings → Appearance → Dashboard widgets**, in the **Below the hero** group; see [Dashboard-Widgets](Dashboard-Widgets#showing-and-hiding-widgets). When all four are off the row disappears.
|
||||
|
||||
## Trips without dates
|
||||
|
||||
A trip with no dates is not past and not upcoming. Its card carries an **Idea** badge in place of a countdown, and, as described under Sort Order, it is sorted with the past trips.
|
||||
|
||||
## Archived Trips
|
||||
|
||||
Archived trips are kept out of the default list. The trips section header carries a **Planned / Archived / Completed** filter and the grid shows exactly one of those three sets — switch to **Archived** to see them. On desktop an archived card has the same four actions as any other card, with **Archive** turned into **Restore**. On mobile an archived card drops **Edit**: you can **Copy**, **Restore**, or permanently **Delete** the trip.
|
||||
|
||||
## Mobile Header
|
||||
|
||||
On mobile, the header is a floating glass bar: the TREK logo on the left (tap it to scroll back to the top), a **Notifications** button (bell icon, with a dot when something is unread) that navigates to `/notifications`, and your avatar on the right. The avatar opens the user menu — settings, the admin panel for admins, the dark/light/auto theme cycle, and sign out.
|
||||
On mobile, the header is a floating glass bar: the TREK logo on the left (tap it to scroll back to the top), a **Notifications** button (bell icon, with a dot when something is unread) that navigates to `/notifications`, and your avatar on the right. On a computer, the notifications page and the bell's panel show a coloured tile for what each notification is about and group the list under Today, Yesterday, the weekday or the date; see [Notifications](Notifications). The top of the mobile dashboard greets you (*Good morning,*, *Good afternoon,* or *Good evening,*), and an ongoing trip is marked **Live Now**. The avatar opens the user menu with settings, the admin panel for admins, the dark/light/auto theme cycle, and sign out.
|
||||
|
||||
## Dashboard Widgets Sidebar
|
||||
|
||||
@@ -79,3 +96,4 @@ When you have no trips, the dashboard shows the TREK mascot with the caption **N
|
||||
- [Trip-Planner-Overview](Trip-Planner-Overview)
|
||||
- [Dashboard-Widgets](Dashboard-Widgets)
|
||||
- [Calendar-Feeds](Calendar-Feeds)
|
||||
- [Notifications](Notifications)
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# Notifications Inbox
|
||||
|
||||
Everything TREK tells you in the app lands in one inbox: trip invitations, chat messages, booking changes, reminders, hints about your tours, update notices. You reach it through the bell in the navigation bar, and the full list opens as its own page at `/notifications`.
|
||||
|
||||
Which events reach the inbox, and which also go out by email, webhook, ntfy or Web Push, is set in **Settings → Notifications**; see [Notifications](Notifications).
|
||||
|
||||
## The bell
|
||||
|
||||
The bell in the navigation bar shows how many notifications you have not read yet, up to **99+**. A click opens a panel with the newest ones:
|
||||
|
||||
- The head shows **Notifications** with the number of unread ones, and the tools **Mark all read** and **Delete all**.
|
||||
- The list is cut into days, with the day's heading staying at the top while you scroll through it.
|
||||
- **Show all notifications** at the bottom opens the full inbox page.
|
||||
|
||||
Following a notification from the panel closes it. New notifications arrive live over TREK's connection, so the count and the panel update without a reload.
|
||||
|
||||
## The inbox page
|
||||
|
||||
The page lists every notification, newest first, and loads older ones as you scroll down.
|
||||
|
||||
- **The head** shows a tile, **Notifications**, how many are unread and how many there are in total, plus **Mark all read** and **Delete all**. **Delete all** asks first: *Every notification is removed for good. This cannot be undone.*
|
||||
- **All** and **Unread** above the list switch between every notification and only the unread ones.
|
||||
- **The days**: each day is a card of its own, headed *Today*, *Yesterday*, a weekday for the rest of the week, and the date for anything older (with the year when it is not this one).
|
||||
- **Nothing there** shows **No notifications** and *You're all caught up!*
|
||||
|
||||
## A notification
|
||||
|
||||
Each notification has a tile on the start side that says at a glance what it is about, with a small picture of who sent it on its corner:
|
||||
|
||||
| Tile | For |
|
||||
|---|---|
|
||||
| Plane | Trip invitations and trip reminders |
|
||||
| Speech bubble | Messages in a trip's chat |
|
||||
| Ticket | Booking changes |
|
||||
| Backpack | Packing items you were tagged on |
|
||||
| Checklist | To-dos coming due |
|
||||
| Calendar | Vacay invitations and shared calendars |
|
||||
| Bookmark | Collection invitations |
|
||||
| Photos | Photos shared with you |
|
||||
| Mountain | Hints on your tours, such as a [wanderer](Wanderer) trail that changed |
|
||||
| Sparkles | A new TREK version |
|
||||
| Warning | Something that needs your attention, such as a photo provider that was disconnected |
|
||||
| Bell | Everything else |
|
||||
|
||||
Next to the tile come the title, the message and the time: under an hour it reads like *5m*, after that the clock time, since the day heading says the rest. Unread notifications are set in bold with a dot in the accent colour.
|
||||
|
||||
What you can do with a notification:
|
||||
|
||||
- **Follow it.** A notification that points somewhere carries a button, such as **View Tour** or **View Details**, and the button marks it read on the way.
|
||||
- **Answer it.** Some ask a yes or no question, such as an invitation, and carry its two buttons. You answer once; afterwards the button you chose stays marked.
|
||||
- **Mark as read** or **Mark as unread**, and **Delete**. On the desktop these come forward when you point at the row or move to it with the keyboard, so the list reads as messages rather than as buttons.
|
||||
|
||||
## On a phone
|
||||
|
||||
On a phone the bell sits at the top of the dashboard and opens the same inbox as a full screen, with a back button and the bulk tools in its top bar, **All** and **Unread** below it, and the notifications as one card. Tapping an unread notification marks it read; its buttons sit as chips under the text, and **Delete** at the end of the row. See [Mobile-App](Mobile-App).
|
||||
|
||||
## See also
|
||||
|
||||
- [Notifications](Notifications): channels, events and the preferences matrix
|
||||
- [Admin-Notifications](Admin-Notifications)
|
||||
- [Mobile-App](Mobile-App)
|
||||
@@ -51,6 +51,7 @@ The following events are configurable in user settings:
|
||||
| `photos_shared` | Photos were shared with a trip |
|
||||
| `collab_message` | A new message in a collaborative trip |
|
||||
| `packing_tagged` | You were assigned to a packing category in a trip |
|
||||
| `wanderer_source_hint` | The wanderer watch found that the source of a tour you saved changed, may have changed, or can no longer be checked (shown as *wanderer: hints on your trails*). In-app it carries a **View Tour** button |
|
||||
| `plugin_notification` | An installed plugin sent you a notification (only plugins granted the `notify:send` capability can do this) |
|
||||
|
||||
All user-facing events support all five channels (in-app, email, webhook, ntfy, push). A dash in the matrix means that channel/event combination is not implemented.
|
||||
@@ -63,6 +64,7 @@ The following events are shown in the admin panel (Admin → Notifications) and
|
||||
|-------|-------------|---------|
|
||||
| `version_available` | A new TREK version is available | in-app, email, webhook, ntfy |
|
||||
| `replica_failure` | A write to a storage replica failed (repeats within the hour are suppressed and counted) | in-app, email, webhook, ntfy |
|
||||
| `paddle_region_requested` | Someone is planning a paddle tour in a region that is not loaded yet (*Paddle region requested*) | in-app, email, webhook, ntfy |
|
||||
|
||||
Admin-only events are never sent as Web Push, so the admin matrix has no Push column.
|
||||
|
||||
@@ -181,7 +183,7 @@ again once both variables hold your pair. See also [Encryption-Key-Rotation](Enc
|
||||
|
||||
## In-app notification center
|
||||
|
||||

|
||||

|
||||
|
||||
The bell icon in the navigation bar shows your unread notification count. Click it to open the notification panel where you can:
|
||||
|
||||
@@ -189,6 +191,7 @@ The bell icon in the navigation bar shows your unread notification count. Click
|
||||
- Mark all notifications read at once.
|
||||
- Delete individual notifications or clear all at once.
|
||||
- Answer **boolean notifications**, which ask a yes-or-no question, with their two buttons directly in the panel.
|
||||
- Click **Show all notifications** to open the full page at `/notifications`, with **All** and **Unread** pills, **Mark all read** and **Delete all** (which asks *Delete all notifications?* first). On a phone the inbox is its own screen. With nothing in it, the page reads *No notifications* and *You're all caught up!*.
|
||||
|
||||
In-app notifications are pushed in real time via WebSocket so the badge and panel update without a page refresh.
|
||||
|
||||
@@ -200,3 +203,4 @@ Notification preferences are configured globally in Settings → Notifications.
|
||||
|
||||
- [Environment-Variables](Environment-Variables)
|
||||
- [User-Settings](User-Settings)
|
||||
- [Notifications-Inbox](Notifications-Inbox)
|
||||
|
||||
+14
-12
@@ -4,7 +4,7 @@
|
||||
|
||||
## What OIDC gives you
|
||||
|
||||
OpenID Connect (OIDC) lets users log in with an existing identity provider — Google, Authentik, Keycloak, or any OIDC-compatible IdP — instead of a local email/password. On first SSO login, a TREK account is created automatically using the email from the provider.
|
||||
OpenID Connect (OIDC) lets users log in with an existing identity provider (Google, Authentik, Keycloak, or any OIDC-compatible IdP) instead of a local email/password. On first SSO login, a TREK account is created automatically using the email from the provider.
|
||||
|
||||
## User flow
|
||||
|
||||
@@ -16,7 +16,9 @@ OpenID Connect (OIDC) lets users log in with an existing identity provider — G
|
||||
The code is only half of what the exchange needs: the callback also sets a one-minute `HttpOnly` cookie (`trek_oidc_exchange`) holding a secret that never appears in a URL, and the exchange requires both. A code copied out of the address bar, out of history, or out of a proxy log is therefore worthless in any other browser, and it is spent by the first attempt to redeem it whether that attempt succeeds or not. If your reverse proxy strips cookies on the way back from the identity provider, SSO login will fail here with `Invalid or expired code`.
|
||||
6. Your `trek_session` cookie is set and you land on the dashboard.
|
||||
|
||||
**Remember me.** The Remember-me switch on the login page is carried into SSO as a query flag on the login URL: `GET /api/auth/oidc/login?remember=1` (or `remember=0`), appended with `&` when an invite token is already present. Only `0` and `1` are accepted; any other value — and starting SSO from the register tab, where the switch is not shown — is treated as if the parameter were absent. The choice is held in the server-side login state, survives the provider round-trip and the one-time-code exchange, and decides both the session lifetime and the cookie lifetime:
|
||||
If the sign-in fails, you are returned to the login page with a message: registration is disabled, the provider sent no email address, authentication failed, the session was invalid (try again), the provider has not confirmed your email address, or the sign-in could not be linked to the existing account with that email (ask your administrator to confirm the address, see [How an existing account gets linked](#how-an-existing-account-gets-linked)).
|
||||
|
||||
**Remember me.** The Remember-me switch on the login page is carried into SSO as a query flag on the login URL: `GET /api/auth/oidc/login?remember=1` (or `remember=0`), appended with `&` when an invite token is already present. Only `0` and `1` are accepted; any other value (and starting SSO from the register tab, where the switch is not shown) is treated as if the parameter were absent. The choice is held in the server-side login state, survives the provider round-trip and the one-time-code exchange, and decides both the session lifetime and the cookie lifetime:
|
||||
|
||||
| `remember` | Session lifetime | `trek_session` cookie |
|
||||
|---|---|---|
|
||||
@@ -34,7 +36,7 @@ Set the following environment variables before starting the server:
|
||||
|
||||
| Variable | Required | Description |
|
||||
|---|---|---|
|
||||
| `APP_URL` | Yes | Base URL of your TREK instance (e.g. `https://trek.example.com`). Used to build the redirect URI. **Env var only — not configurable via the admin panel.** If it is unset, TREK falls back to the first `ALLOWED_ORIGINS` entry, and only if that one is missing or unparseable to `http://localhost:{PORT}` — which produces a redirect URI your IdP will reject. A scheme-less `ALLOWED_ORIGINS=trek.example.com` does not parse, so it ends up on localhost too. A set but unparseable `APP_URL` does not fall back: the server refuses to start with `Invalid environment configuration` naming `APP_URL`. |
|
||||
| `APP_URL` | Yes | Base URL of your TREK instance (e.g. `https://trek.example.com`). Used to build the redirect URI. **Env var only, not configurable via the admin panel.** If it is unset, TREK falls back to the first `ALLOWED_ORIGINS` entry, and only if that one is missing or unparseable to `http://localhost:{PORT}`, which produces a redirect URI your IdP will reject. A scheme-less `ALLOWED_ORIGINS=trek.example.com` does not parse, so it ends up on localhost too. A set but unparseable `APP_URL` does not fall back: the server refuses to start with `Invalid environment configuration` naming `APP_URL`. |
|
||||
| `OIDC_ISSUER` | Yes | Issuer URL of your identity provider. Must use HTTPS in production. |
|
||||
| `OIDC_CLIENT_ID` | Yes | OAuth 2.0 client ID registered with your IdP. |
|
||||
| `OIDC_CLIENT_SECRET` | Yes | OAuth 2.0 client secret. |
|
||||
@@ -53,15 +55,15 @@ For example: `https://trek.example.com/api/auth/oidc/callback`
|
||||
|---|---|
|
||||
| `OIDC_DISPLAY_NAME` | Label shown on the SSO button. Defaults to `SSO`. |
|
||||
| `OIDC_ONLY` | Set to `true` to disable local password login and password registration. SSO login and SSO registration remain governed by their own toggles. This is an environment-variable-only setting and cannot be toggled at runtime via the admin panel. |
|
||||
| `OIDC_ADMIN_CLAIM` | OIDC claim to inspect for admin role mapping. Defaults to `groups`. The claim value may be an array or a plain string. The claim only reaches TREK if one of the scopes in `OIDC_SCOPE` carries it — see *Admin role mapping* below. **Env var only — not configurable via the admin panel.** |
|
||||
| `OIDC_ADMIN_VALUE` | Value that must be present in `OIDC_ADMIN_CLAIM` to grant the admin role. If unset, claim-based role mapping is disabled. When set, the role is re-evaluated on every login. **Env var only — not configurable via the admin panel.** |
|
||||
| `OIDC_ADMIN_CLAIM` | OIDC claim to inspect for admin role mapping. Defaults to `groups`. The claim value may be an array or a plain string. The claim only reaches TREK if one of the scopes in `OIDC_SCOPE` carries it (see *Admin role mapping* below). **Env var only, not configurable via the admin panel.** |
|
||||
| `OIDC_ADMIN_VALUE` | Value that must be present in `OIDC_ADMIN_CLAIM` to grant the admin role. If unset, claim-based role mapping is disabled. When set, the role is re-evaluated on every login. **Env var only, not configurable via the admin panel.** |
|
||||
| `OIDC_USERNAME_CLAIM` | Claim the username of a new account is built from. Defaults to `name`, then `preferred_username`, then the part of the email before the `@`. Set it to `preferred_username` for providers like Pocket ID whose `name` is the full "Jane Doe". Only read when the account is created, so a username changed later in TREK stays; when the provider leaves the claim empty, the default order applies. **Env var only, not configurable via the admin panel.** |
|
||||
| `OIDC_SCOPE` | Overrides the default scope list sent to the provider. Defaults to `openid email profile`. Ensure `openid` and `email` are always included, plus whichever scope carries your `OIDC_ADMIN_CLAIM`. **Env var only — not configurable via the admin panel.** |
|
||||
| `OIDC_SCOPE` | Overrides the default scope list sent to the provider. Defaults to `openid email profile`. Ensure `openid` and `email` are always included, plus whichever scope carries your `OIDC_ADMIN_CLAIM`. **Env var only, not configurable via the admin panel.** |
|
||||
| `OIDC_DISCOVERY_URL` | Full URL to the OIDC discovery document. Use this for providers with non-standard discovery paths (e.g. Authentik tenants). If unset, discovery is attempted at `<OIDC_ISSUER>/.well-known/openid-configuration`. The discovery document is cached for 1 hour. |
|
||||
|
||||
## Admin role mapping
|
||||
|
||||
TREK requests exactly the scopes listed in `OIDC_SCOPE` and nothing else, and a provider only emits a claim when a requested scope carries it. So a claim that is not covered by `OIDC_SCOPE` never arrives, and a claim that never arrives can never grant the admin role — no matter how `OIDC_ADMIN_CLAIM` is spelled.
|
||||
TREK requests exactly the scopes listed in `OIDC_SCOPE` and nothing else, and a provider only emits a claim when a requested scope carries it. So a claim that is not covered by `OIDC_SCOPE` never arrives, and a claim that never arrives can never grant the admin role, no matter how `OIDC_ADMIN_CLAIM` is spelled.
|
||||
|
||||
Authentik is the usual example: `groups` rides the default `profile` scope, so it works out of the box, while `entitlements` has a scope of its own. Mapping admins onto an entitlement therefore takes all three variables:
|
||||
|
||||
@@ -71,13 +73,13 @@ OIDC_ADMIN_VALUE=trek-admins
|
||||
OIDC_SCOPE=openid email profile entitlements
|
||||
```
|
||||
|
||||
Keycloak (group and role mappers carry their own "Add to userinfo" switch) and Entra ID (optional claims) behave the same way — whatever the claim is called, check that its scope is requested.
|
||||
Keycloak (group and role mappers carry their own "Add to userinfo" switch) and Entra ID (optional claims) behave the same way: whatever the claim is called, check that its scope is requested.
|
||||
|
||||
If the configured claim is missing from the userinfo response entirely, TREK leaves the stored role untouched — a claim that never arrived is not a statement that somebody is no longer an admin — and writes one line to the server log naming the claim it looked for and the claims it did receive. Read that line first when role mapping does not do what you expect. A claim that *does* arrive without `OIDC_ADMIN_VALUE` in it still demotes on the next login; that is how the mapping takes admin away. Every role change it makes is recorded in the admin audit log.
|
||||
If the configured claim is missing from the userinfo response entirely, TREK leaves the stored role untouched (a claim that never arrived is not a statement that somebody is no longer an admin) and writes one line to the server log naming the claim it looked for and the claims it did receive. Read that line first when role mapping does not do what you expect. A claim that *does* arrive without `OIDC_ADMIN_VALUE` in it still demotes on the next login; that is how the mapping takes admin away. Every role change it makes is recorded in the admin audit log.
|
||||
|
||||
### Taking admin away
|
||||
|
||||
Some providers omit a claim instead of sending it empty. Okta emits a filtered `groups` claim only when the filter matches at least one group, and Entra ID leaves `groups` out for a user who is in no group at all. **On those providers, removing somebody from the admin group does not demote them in TREK.** Their next login carries no claim, and no claim means no verdict, so the account keeps `admin` for as long as it exists. Take the role away in TREK as well, in **Admin → Users** ([Admin-Users-and-Invites](Admin-Users-and-Invites)) — the IdP side alone is not enough.
|
||||
Some providers omit a claim instead of sending it empty. Okta emits a filtered `groups` claim only when the filter matches at least one group, and Entra ID leaves `groups` out for a user who is in no group at all. **On those providers, removing somebody from the admin group does not demote them in TREK.** Their next login carries no claim, and no claim means no verdict, so the account keeps `admin` for as long as it exists. Take the role away in TREK as well, in **Admin → Users** ([Admin-Users-and-Invites](Admin-Users-and-Invites)); the IdP side alone is not enough.
|
||||
|
||||
TREK writes a warning to the server log on **every** login where this happens, naming the account, so `docker logs trek | grep OIDC` lists the users it affects:
|
||||
|
||||
@@ -89,7 +91,7 @@ A provider that sends the claim as an empty list instead of dropping it is not a
|
||||
|
||||
## New-user registration via SSO
|
||||
|
||||
When an SSO login matches an existing TREK account by OIDC subject (`sub`), that account is used directly. When it matches only by **email**, the OIDC identity is linked to that account only if the provider asserts `email_verified` for it; if the claim is missing or false the login is rejected with an `email_not_verified` error, so an unverified address can never take over a local account. Make sure your IdP includes `email_verified` in the userinfo response — it is part of the `email` scope. If no matching account exists, TREK attempts to create one. The outcome depends on the following:
|
||||
When an SSO login matches an existing TREK account by OIDC subject (`sub`), that account is used directly. When it matches only by **email**, the OIDC identity is linked to that account only if the provider asserts `email_verified` for it; if the claim is missing or false the login is rejected with an `email_not_verified` error, so an unverified address can never take over a local account. Make sure your IdP includes `email_verified` in the userinfo response; it is part of the `email` scope. If no matching account exists, TREK attempts to create one. The outcome depends on the following:
|
||||
|
||||
- **First user ever**: always created as admin, no invite required.
|
||||
- **Open SSO registration enabled** (**SSO Auto-Provisioning** in **Admin → Settings**, card **Authentication Methods**; setting `oidc_registration`): account is created as a regular user.
|
||||
@@ -132,4 +134,4 @@ When password login and password registration are both off, through `OIDC_ONLY`
|
||||
|
||||
---
|
||||
|
||||
**See also:** [Login-and-Registration](Login-and-Registration) · [Environment-Variables](Environment-Variables)
|
||||
**See also:** [Login-and-Registration](Login-and-Registration), [Environment-Variables](Environment-Variables)
|
||||
|
||||
@@ -16,6 +16,10 @@ TREK must be served over **HTTPS** — the install prompt does not appear on pla
|
||||
2. Tap the browser menu.
|
||||
3. Select **Install app** or **Add to Home Screen**.
|
||||
|
||||
**Desktop (Chrome / Edge):**
|
||||
1. Open TREK in the browser.
|
||||
2. Click the install icon at the end of the address bar, or choose **Install** from the browser menu.
|
||||
|
||||
Once installed, TREK launches in **standalone** mode (fullscreen, no browser UI) using the TREK icon.
|
||||
|
||||
The installed app starts at the app root, so the **Start page** setting decides what you see when you tap the icon: the dashboard, or straight into your active trip on a tab of your choice. See [Display-Settings](Display-Settings).
|
||||
@@ -46,6 +50,7 @@ TREK uses Workbox service-worker caching plus an IndexedDB database (Dexie) for
|
||||
| Mapbox GL glyphs, sprites and vector tiles | `mapbox-tiles` | StaleWhileRevalidate | 30 days | 3 000 |
|
||||
| OpenFreeMap glyphs, sprites and vector tiles | `gl-map-offline` | CacheFirst | 90 days | 6 000 |
|
||||
| Cover images and avatars (`/uploads/covers`, `/uploads/avatars`) | `user-uploads` | CacheFirst | 7 days | 300 |
|
||||
| Typefaces of TREK Studio books (`.woff2` build assets) | `book-fonts` | CacheFirst | 365 days | 600 |
|
||||
| App shell and every page of the app (HTML / JS / CSS) | precache | Precached | Until next deploy | — |
|
||||
|
||||
> **Note:** API responses are **never** stored in the service-worker cache. Workbox keys its entries by URL and cannot vary them on the session cookie, so on a shared device one account's cached data could be served to the next. Offline reads come from the per-user IndexedDB cache described below instead.
|
||||
@@ -78,6 +83,12 @@ The **Offline** tab gives you control over what is stored on this device and let
|
||||
|
||||

|
||||
|
||||
### Status pill
|
||||
|
||||
A small pill floats at the bottom centre of the window (just above the tab bar on a phone) while there is something to tell. In order of priority it reads **Failed to sync: N** (changes the server refused, see **Failed changes** below), **Conflicts: N** (changes that need your decision), **Offline** or, with **Force offline mode** on, **Offline mode** (with the number of queued changes added once there are any), and **Syncing N…** while queued changes are being sent. It is hidden when you are online and nothing is waiting.
|
||||
|
||||
On a phone, **Settings** has its own **Offline** screen with the same controls as the desktop tab.
|
||||
|
||||
### Offline mode
|
||||
|
||||
- **Force offline mode** — a switch that first downloads everything you need (see *Prepare for offline* below) and then routes the whole app to the local cache, queueing every change you make. Flip it back off to reconnect: queued changes are replayed and the cache is refreshed. The override is remembered across app restarts, so a session forced offline before a flight stays offline when the PWA relaunches.
|
||||
@@ -114,3 +125,4 @@ Changes waiting to sync remember which version of TREK queued them. After an upd
|
||||
- [User-Settings](User-Settings)
|
||||
- [Display-Settings](Display-Settings)
|
||||
- [Notifications](Notifications)
|
||||
- [Mobile-App](Mobile-App)
|
||||
|
||||
+8
-2
@@ -56,7 +56,7 @@ Under the header:
|
||||
|
||||
- **The stay**, when an accommodation covers that day: *Check-in* on the first day, *Check-out* on the last, *Accommodation* on the nights in between, with the time, the place name, the address, the notes, and the booking code on the check-in day only
|
||||
- **The day's entries**, in the order of the day plan:
|
||||
- **Places**: a photo (or a coloured category icon without one), a numbered badge, the name, the category, the address, the description, the time, the price and the notes
|
||||
- **Places**: a photo (or a coloured category icon without one), a numbered badge, the name, the category, the address, the description, the time, the price and the notes. The description, the notes of the place, the notes of the day entry and the notes of a transport are written in Markdown, and the PDF shows them as such: bold text, lists and links
|
||||
- **Notes**: the icon, the text and the time, if set
|
||||
- **Bookings**: the type icon, the title, the time, the notes of a transport (unless **Transport notes** is off), the details that fit the type (airline, flight number and route for a flight; train number, platform and seat for a train; party size for a restaurant; the venue for an event; the operator for a tour), the location and the booking code
|
||||
|
||||
@@ -80,7 +80,12 @@ Installed plugins can add sections of their own to the Trip Plan PDF through the
|
||||
|
||||
The Travel Journal has no fixed PDF template. Open a journey and click **Studio** in the journal header (the book icon in the top bar on phones) to open **TREK Studio**, the photo book designer. See [Journey-Journal](Journey-Journal#trek-studio).
|
||||
|
||||
Studio lays the journey out as spreads you can edit, rather than a fixed page template: five page presets (210 mm and 300 mm square, A4 landscape, A4 portrait, A5 landscape) or a custom size between 60 and 500 mm, and seven bundled font families.
|
||||
Studio lays the journey out as spreads you can edit, rather than a fixed page template: five page presets (210 mm and 300 mm square, A4 landscape, A4 portrait, A5 landscape) or a custom size between 60 and 500 mm.
|
||||
|
||||
- **Layouts**: the **Layouts** panel starts with **Designed pages**, whole covers and spreads set in the book's theme and drawn with the page's own photos and words. **My layouts** and the built in layouts follow below them. A click lays the page out on a design, and what it has no room for stays with the page. The **Style** chips narrow the designs to one look, such as Poster, Postcard, Riso, Editorial, Vintage poster, Night film or Field notes, and **All** shows them all.
|
||||
- **Themes**: the **Theme** panel picks a look for the whole book from seventeen, among them Poster pop, Riviera, Minimal serif, Tropical, Nordic, Alpine, Magazine and Midnight. Colours and type that follow the theme change with it, everything else stays as it is.
|
||||
- **Typefaces**: **Change typeface** opens a searchable picker grouped as Sans serif, Serif, Elegant display, Condensed and poster, Heavy and retro, Script and handwriting and Monospace, with the weights each one offers. **Used in this book** lists what the book already uses.
|
||||
- **Assistant**: with the AI assistant addon on, the assistant can design pages and the book together with you, see [Journey-Journal](Journey-Journal#trek-studio).
|
||||
|
||||
Printing works the same way as for the Trip Plan PDF, through the browser's print dialog, so nothing is rendered on the server. A browser writes no TrimBox or BleedBox, so the sheets can carry crop marks for a print shop instead. **Single pages** or **Spreads**, and crop marks on or off, are chosen in Studio's export panel.
|
||||
|
||||
@@ -98,3 +103,4 @@ The Trip Plan PDF and Studio's print view work the same way: the HTML document i
|
||||
- [Day-Plans-and-Notes](Day-Plans-and-Notes)
|
||||
- [Journey-Journal](Journey-Journal)
|
||||
- [Trip-Planner-Overview](Trip-Planner-Overview)
|
||||
- [TREK-Studio](TREK-Studio)
|
||||
|
||||
@@ -42,12 +42,14 @@ Items are grouped into categories, each a card with a coloured dot taken from a
|
||||
|
||||
The app calls these groups **lists**: **Add list** in the Lists bar asks for the name in a small dialog (*List name (e.g. Clothing)*), moving an item between them is **Move to List**, and removing one is **Delete List**. The REST API and this page call them categories.
|
||||
|
||||
Lists can be put in the order you like. Drag a list by the grip at the start of its head (the tooltip reads *Drag to reorder the category*) and drop it on another list to move it. While **A to Z** sorting is on, the lists keep their order and only the grip of a list stays draggable.
|
||||
|
||||
Each list's head has the name, a count of packed and total items (green once all are packed), a toggle to fold it, and a **⋯** menu with:
|
||||
|
||||
- **Rename**: rename the list.
|
||||
- **Check All**: tick every item in it.
|
||||
- **Uncheck All**: untick every item in it.
|
||||
- **Delete List**: delete the list and all its items. It does not ask first.
|
||||
- **Delete List**: delete the list and all its items. On the desktop it does not ask first. On the phone TREK asks (*Are you sure you want to delete the list "{name}" with {count} items?*).
|
||||
|
||||
**Rename** and **Delete List** need the `packing_edit` permission; **Check All** and **Uncheck All** are always there.
|
||||
|
||||
@@ -186,6 +188,10 @@ Packing lists can be saved and reused across trips:
|
||||
|
||||
Templates are managed by admins in [Admin-Packing-Templates](Admin-Packing-Templates). See also [Packing-Templates](Packing-Templates).
|
||||
|
||||
## AI assistant
|
||||
|
||||
The in-app AI assistant can propose packing lists and items as cards in the chat. Nothing is added until you confirm the card.
|
||||
|
||||
## Linked to a tour
|
||||
|
||||
With the Tours addon on, a tour can point at the packing list of its trip, as a whole or at one of its categories (say "Hiking gear" for a hike). The **Packing list** section of the tour's detail links one, shows its items with how many are packed, and opens the list here with **Open packing list**. It is only a link: the items stay in this list, are ticked off and edited here, and each traveller sees in the tour only the items this list shows them. Removing the link, or the tour, leaves the list and every item as they are. When a linked category is renamed or emptied, the tour says so instead of showing an empty list.
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
Reuse packing lists across trips using pre-built templates.
|
||||
|
||||

|
||||
The screenshot shows where admins build templates, the **Packing Templates** card on **Admin > Personalization**. Applying a template is described below.
|
||||
|
||||

|
||||
|
||||
## Applying a template
|
||||
|
||||
@@ -12,6 +14,8 @@ Applying a template copies all categories and items from the template into the c
|
||||
|
||||
Requires the `packing_edit` permission.
|
||||
|
||||
You do not need an admin for a template of your own: a list saved with **Export** as **CSV for import (.csv)** can be imported into the next trip, see [Packing-Lists](Packing-Lists#printing-and-exporting).
|
||||
|
||||
On the desktop planner the **Apply template** button appears as soon as at least one template exists; it is not permission-gated in the UI. A member without `packing_edit` still sees it; the server refuses the apply and the app shows a *Failed to apply template* toast. On the phone the packing tab does gate it: **Apply template** sits in the packing list's action menu and only shows for members who have `packing_edit`.
|
||||
|
||||
## Saving the current list as a template
|
||||
@@ -20,7 +24,7 @@ In the Lists bar, click **Save as template** when the list has items. A small di
|
||||
|
||||
The **Save as template** button only appears when there are items in the list, and you are an instance admin with the `packing_edit` permission. Non-admins can apply templates but not create them; the API answers a non-admin with `403 Admin access required`.
|
||||
|
||||
> **Admin:** Templates are created and managed in [Admin-Packing-Templates](Admin-Packing-Templates). Each template has a three-level structure: template → categories → items.
|
||||
> **Admin:** Templates are created and managed in [Admin-Packing-Templates](Admin-Packing-Templates), on the **Packing Templates** card of the admin panel's **Personalization** tab. Each template has a three-level structure: template → categories → items.
|
||||
|
||||
## See also
|
||||
|
||||
|
||||
+11
-11
@@ -8,22 +8,22 @@ Open **Settings** and select the **Account** tab. The **Passkeys** section sits
|
||||
|
||||
> **Admin:** Passkey login is off by default. Turn on **Enable passkey login** in **Admin → Settings**, under the **Passkey login** card.
|
||||
|
||||
The section is hidden entirely when the feature is off and you have no passkeys enrolled. If you already have passkeys, the list stays visible even after an admin turns the feature off, so you can always clean them up.
|
||||
The section is hidden entirely when the feature is off and you have no passkeys enrolled, and it is always hidden on the demo account. If you already have passkeys, the list stays visible even after an admin turns the feature off, so you can always clean them up.
|
||||
|
||||
## Enrolling a passkey
|
||||
|
||||
1. Click **Add a passkey**.
|
||||
2. Enter your **current password** — TREK asks for it so a hijacked session cannot silently plant a passkey.
|
||||
2. Enter your **current password**; TREK asks for it so a hijacked session cannot silently plant a passkey.
|
||||
3. Optionally give the passkey a name (the placeholder suggests something like `iPhone`). Leave it blank and TREK names it **Passkey (synced)** or **Passkey** depending on the authenticator.
|
||||
4. Click **Add a passkey** again and follow your device prompt (Touch ID, Windows Hello, Android screen lock, a YubiKey, and so on).
|
||||
|
||||
Every passkey is registered with *user verification required*, so a biometric or PIN check always happens — a bare "tap the key" gesture is not enough. The same authenticator cannot be enrolled twice on one account, and enrolment expires if you take longer than five minutes.
|
||||
Every passkey is registered with *user verification required*, so a biometric or PIN check always happens; a bare "tap the key" gesture is not enough. The same authenticator cannot be enrolled twice on one account, and enrolment expires if you take longer than five minutes.
|
||||
|
||||
If you dismiss the browser dialog you get **Passkey setup cancelled** and nothing is stored.
|
||||
|
||||
## Signing in with a passkey
|
||||
|
||||
On the login page, a **Sign in with a passkey** button appears below the password form (separated by an **or** divider). Click it, pick your passkey in the browser prompt, and you are signed straight in — no username, no password, no second step.
|
||||
On the login page, a **Sign in with a passkey** button appears below the password form (separated by an **or** divider). Click it, pick your passkey in the browser prompt, and you are signed straight in; no username, no password, no second step.
|
||||
|
||||
The button only shows when all of these hold:
|
||||
|
||||
@@ -38,16 +38,16 @@ TREK never reveals which accounts have passkeys: the login ceremony uses discove
|
||||
|
||||
Each entry in the list shows its name, a **Synced** or **This device** badge, the date it was **Added**, and either **Last used** with a date or **Never used**.
|
||||
|
||||
- **Rename** (pencil icon) — edit the name inline; press Enter to save, Escape to cancel. Names are capped at 60 characters.
|
||||
- **Delete** (trash icon) — confirms with *Remove this passkey? Confirm with your password.* and requires your current password.
|
||||
- **Rename** (pencil icon): edit the name inline; press Enter to save, Escape to cancel. Names are capped at 60 characters.
|
||||
- **Delete** (trash icon): confirms with *Remove this passkey? Confirm with your password.* and requires your current password.
|
||||
|
||||
Removing every passkey can never lock you out — your password always remains as a fallback.
|
||||
Removing every passkey can never lock you out; your password always remains as a fallback.
|
||||
|
||||
> **Admin:** In **Admin → Users**, editing a user exposes a **Reset passkeys** action that removes all of that user's passkeys at once (for a lost device). The user can still sign in with their password.
|
||||
|
||||
## Passkeys and two-factor authentication
|
||||
|
||||
A user-verified passkey is already two factors — possession of the device plus a biometric or PIN — so it mints a session directly and does **not** prompt for a TOTP code afterwards.
|
||||
A user-verified passkey is already two factors (possession of the device plus a biometric or PIN) so it mints a session directly and does **not** prompt for a TOTP code afterwards.
|
||||
|
||||
The same reasoning applies to the admin **Require two-factor authentication (2FA)** policy: owning at least one passkey satisfies that policy exactly like an enabled TOTP authenticator does. A brand-new user under the policy can enrol a passkey instead of setting up an authenticator app; the enrolment endpoints stay reachable while the rest of the API is blocked, so nobody gets stuck. See [Two-Factor-Authentication](Two-Factor-Authentication).
|
||||
|
||||
@@ -59,8 +59,8 @@ Passkeys are bound to a domain (the *Relying Party ID*). If no usable domain res
|
||||
|
||||
Both values can be pinned with environment variables, which take priority over the Admin panel fields:
|
||||
|
||||
- `WEBAUTHN_RP_ID` — the registrable domain, e.g. `trek.example.com`. A pinned value is used verbatim, so it has to be a real domain: browsers refuse a bare IP address as a Relying Party ID. TREK checks for one only on the RP ID it derives from `APP_URL` — an IP host there resolves to nothing and the feature reports itself as not configured.
|
||||
- `WEBAUTHN_ORIGINS` — comma-separated allowed origins, e.g. `https://trek.example.com`.
|
||||
- `WEBAUTHN_RP_ID`: the registrable domain, e.g. `trek.example.com`. A pinned value is used verbatim, so it has to be a real domain: browsers refuse a bare IP address as a Relying Party ID. TREK checks for one only on the RP ID it derives from `APP_URL`; an IP host there resolves to nothing and the feature reports itself as not configured.
|
||||
- `WEBAUTHN_ORIGINS`: comma-separated allowed origins, e.g. `https://trek.example.com`.
|
||||
|
||||
See [Environment-Variables](Environment-Variables) for the full description of both.
|
||||
|
||||
@@ -72,7 +72,7 @@ Login and enrolment attempts are rate limited per IP over a 15-minute window.
|
||||
|
||||
## Permissions
|
||||
|
||||
No TREK permission gates passkeys — any signed-in user can enrol and manage their own. Only the instance-wide toggle and the WebAuthn domain configuration are admin-controlled, and the **Reset passkeys** action is admin-only.
|
||||
No TREK permission gates passkeys: any signed-in user can enrol and manage their own. Only the instance-wide toggle and the WebAuthn domain configuration are admin-controlled, and the **Reset passkeys** action is admin-only.
|
||||
|
||||
## See also
|
||||
|
||||
|
||||
+10
-10
@@ -2,7 +2,7 @@
|
||||
|
||||
## Self-service reset (Forgot password?)
|
||||
|
||||
TREK supports email-based self-service password reset. On the login page, click the **"Forgot password?"** link to go to `/forgot-password`. Enter your email address and submit — if the address matches a local account, a reset link is sent to that inbox. The page always shows the same confirmation message regardless of whether the email was found, to prevent account enumeration.
|
||||
TREK supports email-based self-service password reset. On the login page, click the **"Forgot password?"** link to go to `/forgot-password`. Enter your email address and submit; if the address matches a local account, a reset link is sent to that inbox. The page always shows the same confirmation message regardless of whether the email was found, to prevent account enumeration.
|
||||
|
||||

|
||||
|
||||
@@ -12,20 +12,20 @@ TREK supports email-based self-service password reset. On the login page, click
|
||||
|
||||
1. Click **"Forgot password?"** on the login page.
|
||||
2. Enter your email address and submit.
|
||||
3. Open the reset link from your email (or console) — valid for **60 minutes**.
|
||||
4. Enter a new password. If your account has **MFA enabled**, you must also supply a valid TOTP code or backup code before the reset completes.
|
||||
5. After a successful reset the page shows a **Password updated** confirmation ("You can now sign in with your new password.") with a **Sign In** button back to the login page — there is no automatic redirect. **All existing sessions are invalidated** — every device is signed out immediately.
|
||||
3. Open the reset link from your email (or console), valid for **60 minutes**.
|
||||
4. The link opens a **Set a new password** page. Enter a new password; the rules appear as a checklist under the field. If your account has **MFA enabled**, the page asks for your 2FA code or a backup code first and the button reads **Verify & reset** instead of **Reset password**. A link that is missing or broken shows **Invalid reset link** with a button to request a new one.
|
||||
5. After a successful reset the page shows a **Password updated** confirmation ("You can now sign in with your new password.") with a **Sign In** button back to the login page, and there is no automatic redirect. **All existing sessions are invalidated** and every device is signed out immediately.
|
||||
|
||||
### Security properties
|
||||
|
||||
| Property | Detail |
|
||||
|---|---|
|
||||
| Token entropy | 256-bit cryptographically random, base64url-encoded |
|
||||
| Storage | Only the SHA-256 hash is stored in the database — never the raw token |
|
||||
| Storage | Only the SHA-256 hash is stored in the database, never the raw token |
|
||||
| Expiry | 60 minutes, single-use; any prior unconsumed token is invalidated when a new one is issued |
|
||||
| Enumeration safety | `/forgot-password` always returns `{ok:true}` with a minimum response latency pad |
|
||||
| Rate limiting | 3 requests / 15-min per IP on `/forgot-password`; 5 requests / 15-min per IP on `/reset-password` |
|
||||
| MFA gate | If the account has 2FA enabled, a valid TOTP code or backup code is required to complete the reset — a compromised mailbox alone cannot take over a 2FA-protected account |
|
||||
| MFA gate | If the account has 2FA enabled, a valid TOTP code or backup code is required to complete the reset; a compromised mailbox alone cannot take over a 2FA-protected account |
|
||||
| Session invalidation | Resetting the password ends every session of the account on the server and bumps the `password_version` on the account and the `pv` claim in all JWTs, so every live session is rejected immediately, including ones from before sessions were tracked |
|
||||
| Audit log | `user.password_reset_request`, `user.password_reset_success`, and `user.password_reset_fail` events are recorded |
|
||||
|
||||
@@ -35,15 +35,15 @@ The email delivery uses the same SMTP settings as other notification emails. See
|
||||
|
||||
### OIDC accounts
|
||||
|
||||
Any account linked to an identity provider cannot use the forgot-password flow — one created by SSO, but equally a local account that was auto-linked to the IdP on its first SSO login. The forgot-password page still shows the generic confirmation to avoid revealing whether the email is SSO-linked. Continue using [OIDC-SSO](OIDC-SSO) to sign in; a local password can still be set by an admin, or by you from **Settings → Account** if you know your current one.
|
||||
Any account linked to an identity provider cannot use the forgot-password flow: one created by SSO, but equally a local account that was auto-linked to the IdP on its first SSO login. The forgot-password page still shows the generic confirmation to avoid revealing whether the email is SSO-linked. Continue using [OIDC-SSO](OIDC-SSO) to sign in; a local password can still be set by an admin, or by you from **Settings → Account** if you know your current one.
|
||||
|
||||
### Password login disabled
|
||||
|
||||
If the admin has globally disabled password login, no reset link is ever issued. For enumeration safety the endpoint still answers with the same generic confirmation, so the page looks exactly as it always does — the email (or the console line) simply never arrives. The refusal is recorded in the audit log as `user.password_reset_request` with `reason: password_login_disabled`.
|
||||
If the admin has globally disabled password login, no reset link is ever issued. For enumeration safety the endpoint still answers with the same generic confirmation, so the page looks exactly as it always does; the email (or the console line) simply never arrives. The refusal is recorded in the audit log as `user.password_reset_request` with `reason: password_login_disabled`.
|
||||
|
||||
## Admin-initiated reset
|
||||
|
||||
An admin can set a new password for any user directly from the admin panel (**Admin → Users**, edit the user). Leaving the **New Password** field empty keeps the current password; entering one saves it immediately — no email is required. Setting a password this way also ends every session of the account and bumps its `password_version`, which signs the user out everywhere; separately, it deletes all of their MCP tokens and revokes their OAuth tokens.
|
||||
An admin can set a new password for any user directly from the admin panel (**Admin → Users**, edit the user). Leaving the **New Password** field empty keeps the current password; entering one saves it immediately, no email is required. Setting a password this way also ends every session of the account and bumps its `password_version`, which signs the user out everywhere; separately, it deletes all of their MCP tokens and revokes their OAuth tokens.
|
||||
|
||||
There is no **"Force password change on next login"** option in the Admin Panel. That prompt is raised only for the admin account TREK seeds on first boot and for accounts restored with the `reset-admin.js` recovery script (see [Troubleshooting](Troubleshooting)). An admin-set password neither raises the flag nor clears it, so a user who already carries it is still asked to choose their own password at the next sign-in.
|
||||
|
||||
@@ -73,4 +73,4 @@ While you type, the form lists the five character rules under the password field
|
||||
|
||||
---
|
||||
|
||||
**See also:** [Login-and-Registration](Login-and-Registration) · [Admin-Users-and-Invites](Admin-Users-and-Invites) · [Two-Factor-Authentication](Two-Factor-Authentication) · [OIDC-SSO](OIDC-SSO)
|
||||
**See also:** [Login-and-Registration](Login-and-Registration), [Admin-Users-and-Invites](Admin-Users-and-Invites), [Two-Factor-Authentication](Two-Factor-Authentication), [OIDC-SSO](OIDC-SSO)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Photo Providers
|
||||
|
||||
TREK can browse your personal photo library on Immich or Synology Photos and attach selected photos to trips. TREK never copies the original files — it stores only a reference (provider name + asset ID) and proxies all image streams through its own server, so your provider credentials are never sent to the browser.
|
||||
TREK can browse your personal photo library on Immich or Synology Photos and attach selected photos to your journeys and TREK Studio books. TREK never copies the original files. It stores only a reference (provider name + asset ID) and proxies all image streams through its own server, so your provider credentials are never sent to the browser.
|
||||
|
||||
> **Admin:** Enable at least one photo provider (Immich or Synology Photos) in **Admin → Addons** — photo provider toggles appear as sub-items under the **Journey** addon. Once a provider is on, its settings card appears in each user's **Settings → Integrations**. If your provider runs on a local or private network, the server must be configured to allow internal network access. See [Admin-Addons](Admin-Addons) and [Internal-Network-Access](Internal-Network-Access).
|
||||
|
||||
@@ -40,7 +40,7 @@ If your Immich server uses a self-signed certificate (for example behind a rever
|
||||
|
||||
- The setting is per user and only applies to your own Immich connection. Disconnecting Immich, or saving a different server URL without turning it on again, turns it off.
|
||||
- Only the certificate check is skipped. The connection is still encrypted, but TREK can no longer tell your server from an impostor on the same network, and your API key travels over that connection. Prefer a certificate from a trusted CA where you can.
|
||||
- Photos you share on a trip are loaded through your connection, so your setting applies when other trip members view them.
|
||||
- Photos you add to a journey are loaded through your connection, so your setting applies when other people view that journey.
|
||||
- A server on a local or private address still needs internal network access on the TREK server. See [Internal-Network-Access](Internal-Network-Access).
|
||||
|
||||
#### Required API key permissions
|
||||
@@ -92,13 +92,13 @@ For Synology, a successful test stores a session token so the OTP code is not re
|
||||
|
||||
## Multiple providers
|
||||
|
||||
You can configure both Immich and Synology simultaneously. TREK queries photos from all enabled providers when loading trip photos.
|
||||
You can configure both Immich and Synology simultaneously. TREK offers the photos of all connected providers side by side in the journey photo pickers.
|
||||
|
||||
---
|
||||
|
||||
## After setup
|
||||
|
||||
Once a provider is connected, you can browse and attach photos to your trips. See [Documents-and-Files](Documents-and-Files) for how to manage files after setup.
|
||||
Once a provider is connected, you can browse and attach its photos in your journeys and in TREK Studio. Providers are used there only; the trip planner itself has no photo tab. For files such as tickets and PDFs, see [Documents-and-Files](Documents-and-Files).
|
||||
|
||||
In the [Journey Journal](Journey-Journal) the same libraries are used in three places:
|
||||
|
||||
@@ -112,3 +112,4 @@ In the [Journey Journal](Journey-Journal) the same libraries are used in three p
|
||||
|
||||
- [Admin-Addons](Admin-Addons)
|
||||
- [Internal-Network-Access](Internal-Network-Access)
|
||||
- [TREK-Studio](TREK-Studio)
|
||||
|
||||
@@ -204,7 +204,7 @@ On desktop the place form carries a **Place details** column on its left. Pick a
|
||||
|
||||
The column shows what it can find:
|
||||
|
||||
- **Pick a picture**: pictures near or of the place. Click one to make it that place's thumbnail; click it again to clear the choice. The picture then appears everywhere the place does (list, map marker, itinerary, PDF export and shared trips), exactly like a [custom place image](#custom-place-image).
|
||||
- **Pick a picture**: the place's picture is chosen here, with the pictures near or of the place beside the tiles for your own. Click a tile to choose it; click a source's picture again to let go of it. See [Pick a picture](#custom-place-image) below for every tile. The picture then appears everywhere the place does (list, map marker, itinerary, PDF export and shared trips).
|
||||
- **A rating**, for a place that came from Google or Amap.
|
||||
- **Opening Hours**: today's hours up front and the whole week a click away, with an open or closed badge worked out in the place's own time zone. When the hours cannot be read reliably there is no badge rather than a wrong one.
|
||||
- **Good to know**: facts such as cuisine, outdoor seating, takeaway, step-free access, Wi-Fi or a menu link, where OpenStreetMap carries them.
|
||||
@@ -252,7 +252,7 @@ Click a place in the places column, in a day, or on the map, and its inspector o
|
||||
|
||||

|
||||
|
||||
- **The head band** shows the photo, with a green ring while the place is open and a red one while it is closed, the name (double-click it to rename the place), the address on one line with the full address in a tooltip, and pills: **Open** or **Closed**, the category, the time of the visit, the Google rating, the phone number to call, the e-mail address, and the coordinates. **X** closes the inspector.
|
||||
- **The head band** shows the photo (a click opens it in a gallery, see [The photo gallery](#the-photo-gallery)), with a green ring while the place is open and a red one while it is closed, the name (double-click it to rename the place), the address on one line with the full address in a tooltip, and pills: **Open** or **Closed**, the category, the time of the visit, the Google rating, the phone number to call, the e-mail address, and the coordinates. **X** closes the inspector.
|
||||
- **Rating**: every member's vote, see [Rating a place](#rating-a-place).
|
||||
- **Description**, **Notes** and **Notes for this day**, rendered as Markdown.
|
||||
- **Bookings** pinned to this stop, as small cards with the status, date, time and booking code. For a hotel, the stays booked there are listed too (see [Accommodations](Accommodations)). Click a card (*Open booking*) to open the booking's detail. Next to them, **Participants** says who joins this stop.
|
||||
@@ -272,11 +272,21 @@ Saved places in [Collections](Collections) are rated the same way. Saving a trip
|
||||
|
||||
> **AI / MCP:** `rate_place` sets or clears your own vote; see [MCP-Tools-and-Resources](MCP-Tools-and-Resources).
|
||||
|
||||
## The photo gallery
|
||||
|
||||
Click the round photo in the head band of the place inspector, or the photo in the phone's place sheet, to open a full screen gallery of the place's own picture and the photos its sources know, each with its credit. While there is nothing to show, the photo is just a picture and does not open.
|
||||
|
||||
## Custom place image
|
||||
|
||||
By default a place's thumbnail is fetched automatically (from Google or Wikimedia when the place was imported or matched, otherwise it shows a category icon). To use your own photo instead, click the round photo in the head band of the place inspector. When the place or one of its bookings has pictures attached (JPG, PNG, GIF or WebP), a small menu offers **Upload from device** and **From attached files**, so a photo already on the trip can be reused without uploading it again. Pick an image and it becomes that place's thumbnail everywhere (list, map marker, itinerary, PDF export and shared trips). A small remove button on the photo clears the custom image and restores the automatic default. Accepted formats are JPG, PNG, GIF and WebP (HEIC is converted automatically), up to 20 MB.
|
||||
By default a place's thumbnail is fetched automatically (from Google or Wikimedia when the place was imported or matched, otherwise it shows a category icon). The picture is changed in the place editor, under **Pick a picture** (open the place and click **Edit**). It is a grid of tiles:
|
||||
|
||||
A picture picked under **Pick a picture** in the place form works the same way, see [Place details while searching](#place-details-while-searching). The same control is available on saved places in [Collections](Collections#place-detail).
|
||||
- **Upload image** takes a picture from your device. It is left out when you may not upload files to the trip. Accepted formats are JPG, PNG, GIF and WebP (HEIC is converted automatically), up to 20 MB. Once you have chosen a file, the tile shows it as a preview.
|
||||
- **Current picture** is the picture the place has now. Click it again to drop it.
|
||||
- **Images attached to the place**, from the place or one of its bookings (JPG, PNG, GIF or WebP), so a photo already on the trip can be reused without uploading it again.
|
||||
- **The pictures its sources know**, with their credit line, see [Place details while searching](#place-details-while-searching).
|
||||
- **Remove image**, beside the credit line, leaves the place without a picture.
|
||||
|
||||
Nothing is saved before you click **Update**: **Cancel** keeps the old picture, and a new place can get one too. A picture needs a connection; offline, the form says *A new picture needs a connection. Save again once you are online.* The chosen picture becomes the place's thumbnail everywhere (list, map marker, itinerary, PDF export and shared trips). The same control is available on saved places in [Collections](Collections#place-detail). Where place details are switched off, the same tiles sit in the form itself under **Pick a picture**.
|
||||
|
||||
## Opening a place in a map app
|
||||
|
||||
|
||||
+3
-2
@@ -162,7 +162,7 @@ plus a toolbar:
|
||||
- **Sort** — Name / Recently updated, plus **Updates first** in Installed and **Most
|
||||
downloads** in Discover. The view-specific option falls back to Name when you switch
|
||||
views.
|
||||
- **Upload** — sideload a plugin from a `.zip`/`.tar.gz` (see [Installing](#installing-a-plugin)).
|
||||
- **Upload plugin**: sideload a plugin from a `.zip`/`.tar.gz` (see [Installing](#installing-a-plugin)).
|
||||
- **Rescan** — rediscovers the on-disk plugins directory **and** force-pulls the
|
||||
remote registry, bypassing the 30-minute server cache and GitHub's CDN so a
|
||||
just-published plugin (or update) shows up immediately rather than up to ~35
|
||||
@@ -221,7 +221,7 @@ Three ways, all from **Admin → Plugins**:
|
||||
one), safely unpacks it, re-validates the manifest, and registers it — **inactive**.
|
||||
Nothing runs yet.
|
||||
2. **By upload (sideload).** Drag a plugin `.zip`/`.tar.gz` onto the panel, or use
|
||||
the **Upload** button. TREK extracts it into staging with the same hard guards as
|
||||
the **Upload plugin** button. TREK extracts it into staging with the same hard guards as
|
||||
a registry install (slip/bomb-safe extract, strict manifest, no native binaries —
|
||||
only the registry SHA-256/signature checks don't apply, since there's no registry
|
||||
entry) and registers it **inactive**. A sideloaded plugin is marked **Sideloaded**,
|
||||
@@ -232,6 +232,7 @@ Three ways, all from **Admin → Plugins**:
|
||||
3. **From disk.** Drop a plugin directory into the plugins code directory
|
||||
(`server/data/plugins`, or your `TREK_PLUGINS_DIR` volume) and click **Rescan**
|
||||
(or restart). TREK discovers it and registers it inactive.
|
||||
4. **Dev link (plugin authors only).** With `TREK_PLUGINS_DEV_LINK` turned on, the panel shows **Link a local plugin**: enter the absolute path of your plugin's build directory and click **Link**. The plugin gets a **Dev-Link** badge, is hot-reloaded against real data and skips the install-time checks, so never switch this on for an instance other people rely on. Like any new plugin it starts inactive. See [[Plugin Development|Plugin-Development]].
|
||||
|
||||
## Activating a plugin
|
||||
|
||||
|
||||
+1
-1
@@ -254,7 +254,7 @@ A Homepage widget then needs no scripting:
|
||||
| `404` | no such trip, or not one of yours |
|
||||
| `429` | rate limit exceeded |
|
||||
|
||||
**Which TREK is running.** To check the running version, for example against the latest GitHub release, call `GET /api/auth/app-config`. It needs no key and no login, and the `version` field holds the running version (such as `4.3.3`). It is not part of `/api/v1`, so it follows the app's own release rather than the promise below.
|
||||
**Which TREK is running.** To check the running version, for example against the latest GitHub release, call `GET /api/auth/app-config`. It needs no key and no login, and the `version` field holds the running version (such as `5.0.0`). It is not part of `/api/v1`, so it follows the app's own release rather than the promise below.
|
||||
|
||||
**Versioning.** `/api/v1` may gain fields; it will not lose them or change their types. A breaking change ships as `/api/v2` and both run side by side for a transition period. Write your client to ignore fields it does not know.
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
Share a read-only view of your trip with people who do not have a TREK account. The viewer opens in a browser without logging in.
|
||||
|
||||

|
||||

|
||||
|
||||
## Creating a share link
|
||||
|
||||
Open your trip and click the **Share** button (Users icon) in the top navbar. This opens the **Share Trip** dialog. The **Public Link** card appears in its right column and is visible only to users with the `share_manage` permission (trip owner and admins by default).
|
||||
Open your trip and click the **Trip settings** pill beside the trip's title in the top navbar, then pick the **Sharing** area (on a phone: **More**, then **Trip settings**). The **Public Link** section, with the **Trip invite link** stacked under it, is visible only to users with the `share_manage` permission (trip owner and admins by default).
|
||||
|
||||
Click **Create link** to generate a token.
|
||||
|
||||
@@ -22,7 +22,7 @@ Copy this URL and send it to anyone you want to share the trip with. No TREK acc
|
||||
|
||||
A share link is valid for **90 days**, counted from the last time it was saved. Creating the link writes a 90-day expiry, and flipping one of the unlocked permission toggles re-saves the link and writes a new one, so a link you actively manage never lapses under you.
|
||||
|
||||
Once the 90 days are up, visitors get **Link expired or invalid**. Only an unknown, expired or deleted link shows that screen. When the page cannot be loaded for another reason (the server restarting, a proxy error, a viewer who is briefly offline), the visitor sees **This trip could not be loaded** with the hint that this does not mean the link has expired, and **Try again** reloads it in place. The **Public Link** card in the Share dialog does not show this: it keeps displaying the URL and the **Delete link** button, because the owner-side lookup ignores the expiry. There is no expired badge to warn you.
|
||||
Once the 90 days are up, visitors get **Link expired or invalid**. Only an unknown, expired or deleted link shows that screen. When the page cannot be loaded for another reason (the server restarting, a proxy error, a viewer who is briefly offline), the visitor sees **This trip could not be loaded** with the hint that this does not mean the link has expired, and **Try again** reloads it in place. The **Public Link** section in the Trip settings does not show this: it keeps displaying the URL and the **Delete link** button, because the owner-side lookup ignores the expiry. There is no expired badge to warn you.
|
||||
|
||||
To revive a lapsed link, flip one of the unlocked toggles — **Bookings**, **Packing**, **Costs** or **Chat** — and flip it back if you did not mean to change anything. **Map & Plan** is locked, so clicking it sends no request and will not revive the link. Flipping an unlocked toggle re-saves the **same** token for another 90 days and the old URL starts working again. If you want a genuinely different URL, because the old one leaked for instance, use **Delete link** and then **Create link**.
|
||||
|
||||
@@ -73,7 +73,7 @@ The Packing tab shows how much is packed and one card per category. The Costs ta
|
||||
|
||||
## Revoking a share link
|
||||
|
||||
Open the Share button in the navbar, then click **Delete link** in the share link section. The existing URL stops working immediately for anyone who has it.
|
||||
Open **Trip settings**, go to **Sharing** and click **Delete link** (on a phone: **More**, then **Trip settings**). The existing URL stops working immediately for anyone who has it.
|
||||
|
||||
## Journey public share
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ On first boot TREK automatically seeds an admin account before any user register
|
||||
|
||||
You will be prompted to change the password on first login.
|
||||
|
||||
Once an admin has set up [OIDC / SSO](OIDC-SSO) or [Passkeys](Passkeys), the login page offers those ways in as well, next to the password form (*Sign in with* followed by the provider's name, or *Sign in with a passkey*).
|
||||
|
||||
**Moving an existing TREK?** Instead of setting up a new admin, start the new install with `RESTORE_FROM_BACKUP` pointing at a backup ZIP inside the container (for example `-e RESTORE_FROM_BACKUP=/app/data/backup.zip` with the file placed in `./data`). On that first start TREK restores the backup before any setup and creates no admin account; sign in with an account from the backup. See [Backups](Backups#restoring-on-a-new-install-before-setup).
|
||||
|
||||
> **Admin:** As admin you unlock the Admin Panel — user management, addon toggles, packing templates, backups, and API key configuration.
|
||||
|
||||
@@ -32,7 +32,7 @@ The Collab addon (`collab`) must be enabled by an admin before the panel is visi
|
||||
|
||||
| Sub-feature | What it provides |
|
||||
|-------------|-----------------|
|
||||
| **Chat** | Group chat with reactions, replies, images, and URL previews |
|
||||
| **Chat** | Group chat with reactions, replies, images, and URL previews. With the AI assistant on, an answer can be shared into the chat, marked **from the assistant** |
|
||||
| **Notes** | Categorized, pinnable, markdown-formatted shared notes |
|
||||
| **Links** | Shared web addresses with a title, editable and pinnable, synced live between members |
|
||||
| **Polls** | Single- or multiple-choice votes with optional deadlines |
|
||||
@@ -40,7 +40,7 @@ The Collab addon (`collab`) must be enabled by an admin before the panel is visi
|
||||
|
||||
> **Admin:** enable the Collab addon and individual sub-features in [Admin-Addons](Admin-Addons). Links is on by default, like the other four.
|
||||
|
||||
On a **desktop** (1024 px and wider) each sub-feature is a card with a head band that carries its name, its count and its actions. Chat is a fixed 380 px column on the left when other sub-features are also enabled; if only Chat is on, it fills the full width. Notes, Links, Polls and What's Next share the space on the right; with three or more of them, Notes and Links form the upper row and Polls and What's Next the lower one. On a narrower window a tab bar at the top switches between the enabled sub-features one at a time, and the phone app has its own Collab tab. Disabled sub-features are hidden.
|
||||
On a **desktop** (1024 px and wider) each sub-feature is a card with a head band that carries its name, its count and its actions. Chat is a fixed 380 px column on the left when other sub-features are also enabled; if only Chat is on, it fills the full width. Notes, Links, Polls and What's Next share the space on the right; with three or more of them, Notes and Links form the upper row and Polls and What's Next the lower one. On a narrower window a tab bar at the top switches between the enabled sub-features one at a time, and the phone app has its own Collab tab with Chat, Notes, Links and Polls (What's Next is not shown on the phone). Disabled sub-features are hidden.
|
||||
|
||||
### Links
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ TREK knows seventeen types. Six of them belong to the Bookings tab and eleven to
|
||||
|
||||
A new booking made with **Manual Booking** starts as type **Other**. Change it with the type pill in the head of the editor.
|
||||
|
||||
Older data can still contain the type *Activity*. It is no longer offered in the editor, but such bookings keep showing on the Bookings tab as they always did.
|
||||
|
||||
## Views
|
||||
|
||||
The three buttons in the bar switch how the bookings are laid out. Each tab remembers its own choice in your browser.
|
||||
@@ -82,7 +84,7 @@ A number on the Filter button counts what is switched on, and a chip such as *3
|
||||
|
||||
**Export as spreadsheet (CSV)**, the spreadsheet icon after **View options**, downloads the bookings as a CSV file. It holds exactly what the tab shows: the search and the filters apply, and the rows follow **Sort by** from the view options (the grouping is left out, one row per booking). The columns are **Type**, **Title**, **Status**, **Start**, **End**, **From**, **To**, **Location**, **Confirmation** and **Notes**; **From** and **To** are filled for bookings with a route. The file is semicolon-separated with a UTF-8 byte-order mark, so Excel opens it cleanly, and is named after the trip and the tab, such as `berlin-2026-bookings.csv`. A cell that would start with `=`, `+`, `-` or `@` gets a leading apostrophe, so a spreadsheet never runs it as a formula.
|
||||
|
||||
The button is there for every member who can see the tab, as soon as it has at least one booking. The Transports tab exports its own list the same way.
|
||||
While a search or filter is active, the button's tooltip reads *Export the {shown} of {total} shown rows (CSV)*. The button is there for every member who can see the tab, as soon as it has at least one booking. The Transports tab exports its own list the same way.
|
||||
|
||||
## Pending and Confirmed
|
||||
|
||||
@@ -141,7 +143,7 @@ The bar at the foot holds:
|
||||
2. Type the title into the head band. It is the one required field; **Add** stays disabled until it has one.
|
||||
3. Pick the type with the pill in the head band: Accommodation, Restaurant, Event, Tour, Parking or Other. The pill next to it reads **Pending**; click it to make the booking **Confirmed**.
|
||||
4. Optionally pick **Link to day assignment**: a searchable list of every stop in the plan, grouped by day. It pins the booking to that stop, and an empty date is filled with that day.
|
||||
5. Set **Date**, **Start time**, **End date** and **End time**. The calendars only offer days inside the trip, and an end before the start is marked in red and blocks saving.
|
||||
5. Set **Date**, **Start time**, **End date** and **End time**. The calendars only offer days inside the trip. An end date that lies before the start is marked in red and blocks saving. If you set only an end time and it is earlier than the start time, an amber hint appears under the field (*The end time is before the start time. If it ends the next day, set an end date.*); it does not block saving.
|
||||
6. Optionally pick a **Place / Activity** from the trip. It fills the title and the address only where you left them empty. **Location / Address** takes any address.
|
||||
7. Enter the **Booking Code** and pick the **Travelers** from the trip roster, named guests included.
|
||||
8. Add **Notes**, a **Link** to the booking, and **Files**: **Attach file** uploads from your device (PDF, Word documents, text files, images), and on a saved booking **Link existing file** ties in a file the trip already has. Files picked before the first save are uploaded right after it.
|
||||
@@ -158,7 +160,7 @@ Click the pencil on a card or list row, or **Edit** in the booking detail. The e
|
||||
|
||||
If you have changed something and then press Escape or click beside the editor, TREK asks *Discard your changes?* before it closes. **Keep editing** takes you back to the form, **Discard** closes it without saving. The cross and **Cancel** close the editor straight away.
|
||||
|
||||
To delete a booking, click the bin on its card or row, or **Delete** in the detail. TREK asks once (*Delete booking?*) before it removes the booking.
|
||||
To delete a booking, click the bin on its card or row, or **Delete** in the detail. TREK asks once (*Delete booking?*) before it removes the booking. When the booking has linked costs, the question says so (*"{name}" will be permanently deleted, along with its linked costs.*) and the costs are removed with it.
|
||||
|
||||
## Import from booking confirmation
|
||||
|
||||
@@ -225,10 +227,18 @@ Creating, editing, importing and deleting bookings, switching their status and r
|
||||
|
||||
Some entry points in the day plan follow the plan's own right, `day_edit`: **Add booking** on a stop, the transport editor opened from the plan, and **Change route** on a public transit journey. See [Admin-Permissions](Admin-Permissions).
|
||||
|
||||
## Offline
|
||||
|
||||
Bookings, transports and stays you save while you are offline wait in a queue and are sent when TREK is back online. Files are the exception: they need a connection to upload. If you try to save a booking with new files while offline, the editor says *Files need a connection to upload. Remove the new ones to save the booking offline, or save once you are back online.* See [Offline-Mode-and-PWA](Offline-Mode-and-PWA).
|
||||
|
||||
## Real-time sync
|
||||
|
||||
Every change to a booking reaches all trip members who have the trip open, without a reload.
|
||||
|
||||
## AI assistant
|
||||
|
||||
The in-app AI assistant can create bookings and stays from the chat. It shows them as booking and stay cards that you confirm before anything is saved. Attach a confirmation to the chat and the assistant proposes **Add booking from file**; the file can be kept in the trip's Files together with the booking. The assistant is an addon, see [Addons-Overview](Addons-Overview).
|
||||
|
||||
## See also
|
||||
|
||||
- [Transport-Flights-Trains-Cars](Transport-Flights-Trains-Cars)
|
||||
|
||||
+37
-24
@@ -4,18 +4,18 @@ Putting TREK behind a TLS-terminating reverse proxy is strongly recommended for
|
||||
|
||||
## Why HTTPS Matters for TREK
|
||||
|
||||
- **PWA install** requires HTTPS — browsers block "Add to Home Screen" on plain HTTP.
|
||||
- **Session cookies** — the `trek_session` cookie is marked `secure` in production, so it won't be sent over HTTP.
|
||||
- **OIDC / SSO** — identity providers require the redirect URI to use HTTPS.
|
||||
- **MCP** — the MCP API requires HTTPS for OAuth 2.1 auth.
|
||||
- **PWA install** requires HTTPS; browsers block "Add to Home Screen" on plain HTTP.
|
||||
- **Session cookies**: the `trek_session` cookie is marked `secure` in production, so it won't be sent over HTTP.
|
||||
- **OIDC / SSO**: identity providers require the redirect URI to use HTTPS.
|
||||
- **MCP**: the MCP API requires HTTPS for OAuth 2.1 auth.
|
||||
|
||||
## Three Hard Requirements
|
||||
|
||||
Whatever proxy you use, it must satisfy three constraints:
|
||||
|
||||
1. **WebSocket upgrades on `/ws`** — TREK uses WebSockets for real-time sync. Set `proxy_read_timeout 86400` (Nginx) or rely on Caddy's automatic upgrade handling.
|
||||
2. **Body size ≥ 500 MB** — backup restore ZIPs can include the full uploads directory. Set `client_max_body_size 500m` (Nginx); Caddy imposes no request-body limit of its own, so it already passes them — just keep any `request_body { max_size … }` block you have at `500mb` or more.
|
||||
3. **Pass the `Mcp-Session-Id` header through on `/mcp`** — if you use MCP. See below.
|
||||
1. **WebSocket upgrades on `/ws`**: TREK uses WebSockets for real-time sync. Set `proxy_read_timeout 86400` (Nginx) or rely on Caddy's automatic upgrade handling.
|
||||
2. **Body size ≥ 500 MB**: backup restore ZIPs can include the full uploads directory. Set `client_max_body_size 500m` (Nginx); Caddy imposes no request-body limit of its own, so it already passes them; just keep any `request_body { max_size … }` block you have at `500mb` or more.
|
||||
3. **Pass the `Mcp-Session-Id` header through on `/mcp`**: if you use MCP. See below.
|
||||
|
||||
## Nginx
|
||||
|
||||
@@ -45,10 +45,10 @@ server {
|
||||
proxy_read_timeout 86400;
|
||||
# Documents are capped at 50 MB by default (FILE_UPLOAD_LIMIT_MB) and
|
||||
# photos/covers at 20 MB, but video
|
||||
# uploads go up to 500 MB — both journey gallery clips and videos in a
|
||||
# uploads go up to 500 MB, both journey gallery clips and videos in a
|
||||
# trip's file manager. Backup restore ZIPs can include the full uploads
|
||||
# directory and may exceed even that (see BACKUP_UPLOAD_LIMIT_MB, default
|
||||
# 500) — raise this value if uploads or restores fail.
|
||||
# 500). Raise this value if uploads or restores fail.
|
||||
client_max_body_size 500m;
|
||||
}
|
||||
|
||||
@@ -58,16 +58,16 @@ server {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
# Needed for backup restore uploads — can exceed the Nginx default of 1 MB.
|
||||
# Needed for backup restore uploads, which can exceed the Nginx default of 1 MB.
|
||||
client_max_body_size 500m;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Key lines:
|
||||
- `proxy_read_timeout 86400` — keeps WebSocket connections alive (86400 s = 24 h).
|
||||
- `proxy_read_timeout 86400`: keeps WebSocket connections alive (86400 s = 24 h).
|
||||
- `client_max_body_size 500m`: allows large backup restore uploads and video uploads; set in both locations. If you raise `FILE_UPLOAD_LIMIT_MB` or `BACKUP_UPLOAD_LIMIT_MB` above 500, raise this as well.
|
||||
- `X-Forwarded-Proto $scheme` — tells TREK whether the original request was HTTPS; required for `FORCE_HTTPS` redirect and cookie security to work correctly.
|
||||
- `X-Forwarded-Proto $scheme`: tells TREK whether the original request was HTTPS; required for `FORCE_HTTPS` redirect and cookie security to work correctly.
|
||||
|
||||
## Caddy
|
||||
|
||||
@@ -79,7 +79,7 @@ trek.yourdomain.com {
|
||||
}
|
||||
```
|
||||
|
||||
Caddy applies no request-body limit by default, so large backup restores already pass through the config above. Only add `request_body` if you want to cap uploads deliberately — and then keep the cap at 500 MB or more. It is a block, not a one-line directive:
|
||||
Caddy applies no request-body limit by default, so large backup restores already pass through the config above. Only add `request_body` if you want to cap uploads deliberately, and then keep the cap at 500 MB or more. It is a block, not a one-line directive:
|
||||
|
||||
```
|
||||
trek.yourdomain.com {
|
||||
@@ -94,7 +94,7 @@ trek.yourdomain.com {
|
||||
|
||||
Skip this section if you don't use the MCP addon.
|
||||
|
||||
MCP is session-based. On the first request the server replies with an `Mcp-Session-Id` response header, and the client sends that value back as a request header on every subsequent call. **Both directions must survive the proxy.** If the response header is stripped, the client never learns its session id, so every single tool call looks like a brand-new connection — the server opens a fresh session each time, sessions pile up, and once the user hits `MCP_MAX_SESSION_PER_USER` the oldest session is evicted to make room for each new one. The connection keeps working, but it is churning sessions instead of reusing one, and you will see this warning on every tool call:
|
||||
MCP is session-based. On the first request the server replies with an `Mcp-Session-Id` response header, and the client sends that value back as a request header on every subsequent call. **Both directions must survive the proxy.** If the response header is stripped, the client never learns its session id, so every single tool call looks like a brand-new connection; the server opens a fresh session each time, sessions pile up, and once the user hits `MCP_MAX_SESSION_PER_USER` the oldest session is evicted to make room for each new one. The connection keeps working, but it is churning sessions instead of reusing one, and you will see this warning on every tool call:
|
||||
|
||||
```
|
||||
[MCP] POST without mcp-session-id for user 1 — starting a new session. If this
|
||||
@@ -105,10 +105,10 @@ the client (check that your reverse proxy forwards it).
|
||||
Nginx and Caddy both forward custom headers in both directions by default, so **the standard configs above already work**. You only need to act if you have deliberately restricted headers:
|
||||
|
||||
- Don't list `/mcp` under a `proxy_hide_header` directive, and don't run it through a response-header allowlist that omits `Mcp-Session-Id`.
|
||||
- If your proxy rewrites or lowercases headers, that's fine — HTTP header names are case-insensitive and both TREK and MCP clients treat them as such.
|
||||
- The browser-facing `Access-Control-Expose-Headers: Mcp-Session-Id` response header is what permits browser-based clients (Claude.ai, Claude Desktop connectors, MCP Inspector) to *read* the session id at all. TREK sends it automatically — don't strip or overwrite it in the proxy.
|
||||
- If your proxy rewrites or lowercases headers, that's fine, HTTP header names are case-insensitive and both TREK and MCP clients treat them as such.
|
||||
- The browser-facing `Access-Control-Expose-Headers: Mcp-Session-Id` response header is what permits browser-based clients (Claude.ai, Claude Desktop connectors, MCP Inspector) to *read* the session id at all. TREK sends it automatically, don't strip or overwrite it in the proxy.
|
||||
|
||||
TREK 3.3.0 and earlier did not send `Access-Control-Expose-Headers` at all, which caused exactly the symptom above regardless of proxy configuration. If you are on an older version and see a new session per tool call, upgrade — no proxy change will fix it.
|
||||
TREK 3.3.0 and earlier did not send `Access-Control-Expose-Headers` at all, which caused exactly the symptom above regardless of proxy configuration. If you are on an older version and see a new session per tool call, upgrade; no proxy change will fix it.
|
||||
|
||||
### Streaming responses
|
||||
|
||||
@@ -121,12 +121,25 @@ location /mcp {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_buffering off; # SSE — deliver tool results as they stream
|
||||
proxy_buffering off; # SSE: deliver tool results as they stream
|
||||
proxy_read_timeout 3600s; # long-lived streams between tool calls
|
||||
}
|
||||
```
|
||||
|
||||
TREK sends an SSE keep-alive comment every 25 seconds (`MCP_SSE_KEEPALIVE`) precisely so proxies with a short idle timeout — nginx defaults to 60 s — don't drop an idle stream between tool calls. Lower the interval if your proxy's timeout is tighter than that.
|
||||
TREK sends an SSE keep-alive comment every 25 seconds (`MCP_SSE_KEEPALIVE`) precisely so proxies with a short idle timeout (nginx defaults to 60 s) don't drop an idle stream between tool calls. Lower the interval if your proxy's timeout is tighter than that.
|
||||
|
||||
## Paths that must reach TREK
|
||||
|
||||
The standard configs above send everything (`location /`) to TREK, which is the simplest and safest setup. If you restrict the proxy to specific paths instead, these must all reach TREK:
|
||||
|
||||
| Path | Used for |
|
||||
|---|---|
|
||||
| `/api`, `/uploads` | The app itself and uploaded files |
|
||||
| `/ws` | Real-time sync (needs the WebSocket upgrade headers) |
|
||||
| `/mcp` | The MCP server |
|
||||
| `/oauth/authorize`, `/oauth/token`, `/oauth/register`, `/oauth/revoke` and `/.well-known` | MCP sign-in for AI apps (OAuth 2.1). Without them an app such as Claude cannot connect |
|
||||
| `/oauth/consent` | The consent screen an AI app sends you to, served by the web app like any other page |
|
||||
| `/plugin-frame` | The sandboxed pages of plugins |
|
||||
|
||||
## HTTPS Environment Variables
|
||||
|
||||
@@ -137,12 +150,12 @@ Five variables control how TREK behaves behind a proxy. They work as a group:
|
||||
| `FORCE_HTTPS` | When `true`: 301-redirects HTTP→HTTPS (except `/api/health`), sends HSTS (`max-age=31536000`), adds CSP `upgrade-insecure-requests`, forces cookie `secure` flag | `false` |
|
||||
| `HSTS_INCLUDE_SUBDOMAINS` | When `true`: adds the `includeSubDomains` directive to the HSTS header, extending HTTPS enforcement to all subdomains. Only effective while HSTS is active. Leave `false` if you run other services on sibling subdomains over plain HTTP. | `false` |
|
||||
| `TRUST_PROXY` | Number of trusted proxy hops. Lets Express read the real client IP from `X-Forwarded-For`. Automatically set to `1` in production even if not explicitly configured. | `1` (production), off (development) |
|
||||
| `COOKIE_SECURE` | Controls the `secure` flag on `trek_session`. Auto-derived as `true` when `NODE_ENV=production`, when `FORCE_HTTPS=true`, or when the request itself arrived over TLS — Express sets `req.secure` once your proxy sends `X-Forwarded-Proto: https` and `TRUST_PROXY` is configured. Set to `false` explicitly to allow cookies over plain HTTP (e.g. LAN testing without TLS). | auto |
|
||||
| `COOKIE_SECURE` | Controls the `secure` flag on `trek_session`. Auto-derived as `true` when `NODE_ENV=production`, when `FORCE_HTTPS=true`, or when the request itself arrived over TLS, Express sets `req.secure` once your proxy sends `X-Forwarded-Proto: https` and `TRUST_PROXY` is configured. Set to `false` explicitly to allow cookies over plain HTTP (e.g. LAN testing without TLS). | auto |
|
||||
| `ALLOWED_ORIGINS` | Comma-separated list of allowed CORS origins (e.g. `https://trek.example.com`). The address TREK is opened under is always allowed, even when the list does not name it; a request from any other origin gets `403 Not allowed by CORS` and a `CORS: refused origin ...` line in the log. In production without this set, all cross-origin requests are blocked. In development without this set, all origins are allowed. | blocked in prod, open in dev |
|
||||
|
||||
> **Note on HSTS:** The `max-age=31536000` header goes out whenever `FORCE_HTTPS=true` **or** `NODE_ENV=production`, and `NODE_ENV=production` is the default in the Docker image, the compose file and the Helm chart — so a standard install sends HSTS even with `FORCE_HTTPS` unset. Browsers ignore the header on a plain-HTTP response, so an instance you only ever reach over HTTP is unaffected. Once a browser has seen it over HTTPS, though, it refuses plain HTTP to that hostname for a year, so don't plan on falling back to `http://` for a hostname you have already served over HTTPS.
|
||||
> **Note on HSTS:** The `max-age=31536000` header goes out whenever `FORCE_HTTPS=true` **or** `NODE_ENV=production`, and `NODE_ENV=production` is the default in the Docker image, the compose file and the Helm chart, so a standard install sends HSTS even with `FORCE_HTTPS` unset. Browsers ignore the header on a plain-HTTP response, so an instance you only ever reach over HTTP is unaffected. Once a browser has seen it over HTTPS, though, it refuses plain HTTP to that hostname for a year, so don't plan on falling back to `http://` for a hostname you have already served over HTTPS.
|
||||
|
||||
> **Note on `FORCE_HTTPS` and proxy headers:** The HTTPS redirect reads `X-Forwarded-Proto` directly from the incoming headers — it does not depend on Express's `trust proxy` setting. If you set `FORCE_HTTPS=true` and your reverse proxy correctly sends `X-Forwarded-Proto: https`, the redirect will work regardless of `TRUST_PROXY`. However, you still need `TRUST_PROXY` set so Express resolves the correct client IP from `X-Forwarded-For`.
|
||||
> **Note on `FORCE_HTTPS` and proxy headers:** The HTTPS redirect reads `X-Forwarded-Proto` directly from the incoming headers; it does not depend on Express's `trust proxy` setting. If you set `FORCE_HTTPS=true` and your reverse proxy correctly sends `X-Forwarded-Proto: https`, the redirect will work regardless of `TRUST_PROXY`. However, you still need `TRUST_PROXY` set so Express resolves the correct client IP from `X-Forwarded-For`.
|
||||
|
||||
If you access TREK directly on `http://<host>:3000` without a proxy, leave `FORCE_HTTPS` unset and do not set `TRUST_PROXY`.
|
||||
|
||||
@@ -150,5 +163,5 @@ See [Environment-Variables](Environment-Variables) for full documentation of the
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Environment-Variables](Environment-Variables) — full variable reference including OIDC
|
||||
- [Install-Docker-Compose](Install-Docker-Compose) — production compose file with proxy-ready env vars
|
||||
- [Environment-Variables](Environment-Variables): full variable reference including OIDC
|
||||
- [Install-Docker-Compose](Install-Docker-Compose): production compose file with proxy-ready env vars
|
||||
|
||||
@@ -356,6 +356,10 @@ The tab shows the open day as a chain: where it starts and where it ends, each s
|
||||
|
||||
Planning is done on the desktop: the other Driving settings, reordering and deleting stops, following a track and booking a night. The phone reads the plan and handles what a passenger decides on the road.
|
||||
|
||||
## The AI assistant
|
||||
|
||||
With the AI Assistant addon on, the assistant can shape the drive for you: send it through a point, move or remove a via point, change the driving settings, set where a day ends and import a Google Maps route. Each of these arrives as a proposal you confirm, and what it changes is what this page describes.
|
||||
|
||||
## MCP tools
|
||||
|
||||
With the [MCP](MCP-Overview) addon on as well, an assistant can plan and check a road trip without an open browser. The server uses the same scheduling, range and day-ending rules as the planner. The road trip tools exist only while the addon is on (`set_assignment_end_day` and `import_trip_gpx` are general tools and always there), and each write needs the same permission as in the browser.
|
||||
|
||||
@@ -74,4 +74,6 @@ Both buttons are on the phone as well, in the day sheet.
|
||||
|
||||
For a trip that is one long drive, the [Road-Trip](Road-Trip) addon adds a **Road trip** view beside **Days**: the whole trip as one chain of legs with arrival times, daily travel times, driving limits, search along the route, via points and avoidance of toll roads, motorways and ferries.
|
||||
|
||||
**See also:** [Day-Plans-and-Notes](Day-Plans-and-Notes) · [Map-Features](Map-Features) · [Display-Settings](Display-Settings) · [Road-Trip](Road-Trip)
|
||||
Avoiding toll roads, motorways and ferries is done by a Valhalla server and is documented under [Road-Trip](Road-Trip#routing-engines), together with the routing engines.
|
||||
|
||||
**See also:** [Day-Plans-and-Notes](Day-Plans-and-Notes), [Map-Features](Map-Features), [Display-Settings](Display-Settings), [Road-Trip](Road-Trip)
|
||||
|
||||
+15
-15
@@ -5,7 +5,7 @@ A production TREK deployment checklist. All items reference actual TREK configur
|
||||
## Encryption & Secrets
|
||||
|
||||
- [ ] Set a strong `ENCRYPTION_KEY` (generate with `openssl rand -hex 32`). See [Encryption-Key-Rotation](Encryption-Key-Rotation).
|
||||
- [ ] Back up `ENCRYPTION_KEY` separately from the database backup ZIP — losing it makes all stored API keys and secrets unreadable. Stored secrets use AES-256-GCM encryption derived from this key.
|
||||
- [ ] Back up `ENCRYPTION_KEY` separately from the database backup ZIP: losing it makes all stored API keys and secrets unreadable. Stored secrets use AES-256-GCM encryption derived from this key.
|
||||
- [ ] Rotate `ENCRYPTION_KEY` if it may have been exposed. See [Encryption-Key-Rotation](Encryption-Key-Rotation).
|
||||
|
||||
## HTTPS & Network
|
||||
@@ -13,23 +13,23 @@ A production TREK deployment checklist. All items reference actual TREK configur
|
||||
- [ ] Run TREK behind a TLS-terminating reverse proxy (nginx, Caddy, Traefik). See [Reverse-Proxy](Reverse-Proxy).
|
||||
- [ ] Set `TRUST_PROXY=1` so client IPs are captured correctly in the audit log. In `NODE_ENV=production` this defaults to `1` automatically, but set it explicitly if you use a non-standard proxy hop count.
|
||||
- [ ] Set `FORCE_HTTPS=true` to 301-redirect HTTP to HTTPS and add `upgrade-insecure-requests` to the CSP. Your proxy must send `X-Forwarded-Proto: https` (or terminate TLS on the same connection), otherwise the redirect fires on every request and loops.
|
||||
- [ ] Know that HSTS (`max-age=31536000`) does not depend on `FORCE_HTTPS`: it is sent whenever `FORCE_HTTPS=true` **or** `NODE_ENV=production`, which the Docker image sets by default — so an instance behind Traefik, Caddy or a Cloudflare Tunnel advertises HSTS without setting `FORCE_HTTPS` at all. Set `HSTS_INCLUDE_SUBDOMAINS=true` to add `includeSubDomains`; it is off by default so an install on an apex domain does not force HTTPS onto sibling subdomains you may still serve over plain HTTP.
|
||||
- [ ] Keep `ALLOW_INTERNAL_NETWORK=false` unless a strict-guard integration — Immich, Synology Photos, AirTrail, Dawarich, a document store bound through [Document-Sync](Document-Sync) (Paperless-ngx, Papra, Nextcloud, OpenCloud, Synology Drive), a notification webhook or ntfy — is on your LAN. See [Internal-Network-Access](Internal-Network-Access). Note: loopback (`127.x`, `::1`) addresses are always blocked regardless of this setting, and so are link-local (`169.254.x`) addresses, apart from a single one you name in `ALLOW_LINK_LOCAL_IPS`, which the strict guard then treats as internal. See [A link-local address you need](Internal-Network-Access#a-link-local-address-you-need).
|
||||
- [ ] Know that HSTS (`max-age=31536000`) does not depend on `FORCE_HTTPS`: it is sent whenever `FORCE_HTTPS=true` **or** `NODE_ENV=production`, which the Docker image sets by default, so an instance behind Traefik, Caddy or a Cloudflare Tunnel advertises HSTS without setting `FORCE_HTTPS` at all. Set `HSTS_INCLUDE_SUBDOMAINS=true` to add `includeSubDomains`; it is off by default so an install on an apex domain does not force HTTPS onto sibling subdomains you may still serve over plain HTTP.
|
||||
- [ ] Keep `ALLOW_INTERNAL_NETWORK=false` unless a strict-guard integration such as Immich, Synology Photos, AirTrail, Dawarich, wanderer, a document store bound through [Document-Sync](Document-Sync) (Paperless-ngx, Papra, Nextcloud, OpenCloud, Synology Drive), a notification webhook or ntfy, is on your LAN. See [Internal-Network-Access](Internal-Network-Access). Note: loopback (`127.x`, `::1`) addresses are always blocked regardless of this setting, and so are link-local (`169.254.x`) addresses, apart from a single one you name in `ALLOW_LINK_LOCAL_IPS`, which the strict guard then treats as internal. See [A link-local address you need](Internal-Network-Access#a-link-local-address-you-need).
|
||||
|
||||
## Authentication
|
||||
|
||||
- [ ] Enable two-factor authentication for your admin account. See [Two-Factor-Authentication](Two-Factor-Authentication).
|
||||
- [ ] Require MFA for all users if your use case demands it: Admin Panel → Settings → **Require two-factor authentication (2FA)**. Note: you must secure your own admin account first, with either TOTP or a registered passkey — the server refuses the toggle otherwise. A passkey satisfies the policy for everyone else too, so nobody is forced onto TOTP specifically.
|
||||
- [ ] Require MFA for all users if your use case demands it: Admin Panel → Settings → **Require two-factor authentication (2FA)**. Note: you must secure your own admin account first, with either TOTP or a registered passkey; the server refuses the toggle otherwise. A passkey satisfies the policy for everyone else too, so nobody is forced onto TOTP specifically.
|
||||
- [ ] Disable open registration if you control who can access the instance. See [Admin-Users-and-Invites](Admin-Users-and-Invites).
|
||||
- [ ] If one account's session may have been leaked, end that account's sessions rather than everyone's: the user signs out the other sessions (`POST /api/auth/sessions/revoke-others`) or changes the password, or an admin sets a new password for them. See [Ending sessions](#ending-sessions) below.
|
||||
- [ ] Rotate the JWT signing secret if the secret itself may have been leaked: Admin Panel → Settings → Danger Zone → **Rotate** (`POST /api/admin/rotate-jwt-secret`). This invalidates all active sessions immediately, including your own.
|
||||
|
||||
## Session Security
|
||||
|
||||
TREK stores sessions as JWTs in an httpOnly `trek_session` cookie (SameSite=Lax). A normal login expires after `SESSION_DURATION` (default 24 hours) and rides in a browser-session cookie that the browser drops when it closes; ticking **Remember me** issues a persistent cookie whose lifetime and JWT expiry are `SESSION_DURATION_REMEMBER` (default 30 days) — shorten it if a 30-day window is too wide for your threat model. The `secure` flag is set automatically when `NODE_ENV=production`, when `FORCE_HTTPS=true`, or when Express sees that the request arrived over TLS (`X-Forwarded-Proto: https`) — the last of those needs `trust proxy` active, which is automatic in production and otherwise means setting `TRUST_PROXY` yourself. Tokens are also accepted via `Authorization: Bearer` header for MCP and API clients.
|
||||
TREK stores sessions as JWTs in an httpOnly `trek_session` cookie (SameSite=Lax). A normal login expires after `SESSION_DURATION` (default 24 hours) and rides in a browser-session cookie that the browser drops when it closes; ticking **Remember me** issues a persistent cookie whose lifetime and JWT expiry are `SESSION_DURATION_REMEMBER` (default 30 days); shorten it if a 30-day window is too wide for your threat model. The `secure` flag is set automatically when `NODE_ENV=production`, when `FORCE_HTTPS=true`, or when Express sees that the request arrived over TLS (`X-Forwarded-Proto: https`); the last of those needs `trust proxy` active, which is automatic in production and otherwise means setting `TRUST_PROXY` yourself. Tokens are also accepted via `Authorization: Bearer` header for MCP and API clients.
|
||||
|
||||
- [ ] Ensure `FORCE_HTTPS=true` (or `NODE_ENV=production`) so the `trek_session` cookie carries the `secure` flag and is never sent over plain HTTP.
|
||||
- [ ] Set `COOKIE_SECURE=false` only as a temporary escape hatch for LAN testing without TLS — do not use in production.
|
||||
- [ ] Set `COOKIE_SECURE=false` only as a temporary escape hatch for LAN testing without TLS; do not use in production.
|
||||
|
||||
### Ending sessions
|
||||
|
||||
@@ -47,7 +47,7 @@ A session ends when:
|
||||
| Admin sets a new password for a user | Every session of that user. |
|
||||
| Recovery script `reset-admin.js` | Every session of the account it resets. |
|
||||
| Disabling two-factor authentication | Every other session; the one that proved the password and code stays. |
|
||||
| Admin clears a user's two-factor authentication | Every session of that user. |
|
||||
| Admin clears a user's two-factor authentication (**Reset 2FA** in **Admin → Users**) | Every session of that user. |
|
||||
| Account deletion | Every session, with the account. |
|
||||
|
||||
`GET /api/auth/sessions` lists the active sessions of your account, most recently used first, with when each started, when it was last used (refreshed at most every few minutes), when it expires, the browser's User-Agent at sign-in (cut to 256 characters) and which one is the current one. No IP address is stored. The settings screen does not show this list yet; the routes are there for it and for API clients. On a demo instance the shared demo account sees only its own session in the list and cannot end sessions (403), since its sessions are other visitors' browsers.
|
||||
@@ -97,22 +97,22 @@ Helmet applies a strict CSP on all responses. Key directives:
|
||||
|
||||
## Plugin Runtime Hardening
|
||||
|
||||
Installed plugins run **untrusted third-party code**. TREK contains a plugin in several independent layers so a hostile or buggy plugin can neither read TREK's data nor take the instance down. Nothing here needs configuration — it is all on by default — but the escape hatches below exist for tuning.
|
||||
Installed plugins run **untrusted third-party code**. TREK contains a plugin in several independent layers so a hostile or buggy plugin can neither read TREK's data nor take the instance down. Nothing here needs configuration (it is all on by default), but the escape hatches below exist for tuning.
|
||||
|
||||
- [ ] Leave the plugin system's defaults in place. It is **on by default** but installed plugins still have to be **activated one by one**, so no third-party code runs until an admin turns a specific plugin on. Set `TREK_PLUGINS_ENABLED=false` (accepts `false`/`0`/`off`/`no`) to switch the whole system off — installed plugins stay on disk, deactivated, and the runtime is idle.
|
||||
- [ ] Keep the **OS permission jail** enabled (the default). In production each plugin runs in an isolated child process launched with Node's `--permission` model: filesystem **writes**, `child_process`, worker threads and native addons are denied outright, and reads are scoped to just the plugin's own code — so a plugin cannot read `trek.db` or the secret files, or shell out. The child's environment is scrubbed (no `JWT_SECRET`, no DB credentials). Setting `TREK_PLUGIN_PERMISSIONS=off` disables this jail (isolation then falls back to crash-only) and logs a loud warning — only ever do this on a machine you fully trust.
|
||||
- [ ] Rely on the **private-egress block** (SSRF backstop). Even a plugin that declared an outbound host cannot reach a destination that resolves to a loopback, private, link-local, ULA, carrier-grade-NAT, cloud-metadata (`169.254.169.254`), multicast or reserved address — the guard re-checks the resolved IP, so a plugin can't pivot to internal services or DNS-rebind to them. This is independent of `ALLOW_INTERNAL_NETWORK` (which governs the core integrations reached through the strict guard — Immich, Synology Photos, AirTrail, Dawarich, the Document-Sync stores, notification webhooks and ntfy — not plugin egress). The one escape hatch is `TREK_PLUGIN_ALLOW_PRIVATE_EGRESS=on`, for a plugin that has to reach a service on your LAN (a Gotify, an ntfy, an Ollama). It is instance-wide rather than per plugin, and it lifts the block entirely rather than narrowing it: a declared host may then resolve to any address, the `169.254.169.254` metadata IP included, and unix-socket or named-pipe connects (`docker.sock`, a local database socket) are permitted without even being declared, since the OS jail does not gate socket connects. Leave it unset unless a specific plugin genuinely needs a LAN target.
|
||||
- [ ] The supervisor caps each plugin's **resident memory** (default 300 MB, `TREK_PLUGIN_MAX_RSS_MB`) — measured host-side from the OS, never the plugin's self-report — and kills a plugin that blows the ceiling or stops sending heartbeats; repeat offenders auto-disable. Every `ctx.*` capability call is also **rate-limited** at the dispatch boundary (a token bucket: ~60-call burst, 20 calls/sec sustained, 16 concurrent; `TREK_PLUGIN_RPC_BURST` / `TREK_PLUGIN_RPC_PER_SEC` / `TREK_PLUGIN_RPC_INFLIGHT`), so one plugin in a tight loop gets throttled instead of freezing the instance.
|
||||
- [ ] Leave the plugin system's defaults in place. It is **on by default** but installed plugins still have to be **activated one by one**, so no third-party code runs until an admin turns a specific plugin on. Set `TREK_PLUGINS_ENABLED=false` (accepts `false`/`0`/`off`/`no`) to switch the whole system off; installed plugins stay on disk, deactivated, and the runtime is idle.
|
||||
- [ ] Keep the **OS permission jail** enabled (the default). In production each plugin runs in an isolated child process launched with Node's `--permission` model: filesystem **writes**, `child_process`, worker threads and native addons are denied outright, and reads are scoped to just the plugin's own code, so a plugin cannot read `trek.db` or the secret files, or shell out. The child's environment is scrubbed (no `JWT_SECRET`, no DB credentials). Setting `TREK_PLUGIN_PERMISSIONS=off` disables this jail (isolation then falls back to crash-only) and logs a loud warning. Only ever do this on a machine you fully trust.
|
||||
- [ ] Rely on the **private-egress block** (SSRF backstop). Even a plugin that declared an outbound host cannot reach a destination that resolves to a loopback, private, link-local, ULA, carrier-grade-NAT, cloud-metadata (`169.254.169.254`), multicast or reserved address; the guard re-checks the resolved IP, so a plugin can't pivot to internal services or DNS-rebind to them. This is independent of `ALLOW_INTERNAL_NETWORK` (which governs the core integrations reached through the strict guard: Immich, Synology Photos, AirTrail, Dawarich, wanderer, the Document-Sync stores, notification webhooks, ntfy and the cloud hosts of the AI assistant sign-ins, not plugin egress). The one escape hatch is `TREK_PLUGIN_ALLOW_PRIVATE_EGRESS=on`, for a plugin that has to reach a service on your LAN (a Gotify, an ntfy, an Ollama). It is instance-wide rather than per plugin, and it lifts the block entirely rather than narrowing it: a declared host may then resolve to any address, the `169.254.169.254` metadata IP included, and unix-socket or named-pipe connects (`docker.sock`, a local database socket) are permitted without even being declared, since the OS jail does not gate socket connects. Leave it unset unless a specific plugin genuinely needs a LAN target.
|
||||
- [ ] The supervisor caps each plugin's **resident memory** (default 300 MB, `TREK_PLUGIN_MAX_RSS_MB`), measured host-side from the OS, never the plugin's self-report, and kills a plugin that blows the ceiling or stops sending heartbeats; repeat offenders auto-disable. Every `ctx.*` capability call is also **rate-limited** at the dispatch boundary (a token bucket: ~60-call burst, 20 calls/sec sustained, 16 concurrent; `TREK_PLUGIN_RPC_BURST` / `TREK_PLUGIN_RPC_PER_SEC` / `TREK_PLUGIN_RPC_INFLIGHT`), so one plugin in a tight loop gets throttled instead of freezing the instance.
|
||||
- [ ] Review the **capability audit** if you grant plugins broad data access. Every host-mediated core-data read and broadcast a plugin makes is recorded at the RPC boundary against the real acting user (not a value the plugin supplies) in a per-plugin, hash-chained, tamper-evident log. Admins see it per plugin; each user can see "what have plugins done in my name?". Retention is capped per plugin (default 20 000 rows, `TREK_PLUGIN_AUDIT_MAX_ROWS`).
|
||||
|
||||
> The developer **dev-link** feature (`TREK_PLUGINS_DEV_LINK=1`) loads unsigned local code and, under `npm run dev`, runs with the OS jail off — keep it off on any instance that isn't a throwaway dev box you control. See [Plugins](Plugins) and [Plugin Permissions](Plugin-Permissions).
|
||||
> The developer **dev-link** feature (`TREK_PLUGINS_DEV_LINK=1`) loads unsigned local code and, under `npm run dev`, runs with the OS jail off; keep it off on any instance that isn't a throwaway dev box you control. See [Plugins](Plugins) and [Plugin Permissions](Plugin-Permissions).
|
||||
>
|
||||
> Likewise leave `TREK_PLUGINS_IGNORE_TREK_RANGE` unset. It turns the plugin TREK-version gate into a warning so a plugin whose author has not updated its `trek` range can still be installed and activated — the admin panel warns at every step, but a plugin running on a TREK it was never tested against can misbehave and, in rare cases, corrupt data. Set it only for a specific plugin you need, and remove it once the author ships a release that admits your TREK.
|
||||
> Likewise leave `TREK_PLUGINS_IGNORE_TREK_RANGE` unset. It turns the plugin TREK-version gate into a warning so a plugin whose author has not updated its `trek` range can still be installed and activated; the admin panel warns at every step, but a plugin running on a TREK it was never tested against can misbehave and, in rare cases, corrupt data. Set it only for a specific plugin you need, and remove it once the author ships a release that admits your TREK.
|
||||
|
||||
## Backups
|
||||
|
||||
- [ ] Enable auto-backup with an appropriate retention window. See [Backups](Backups).
|
||||
- [ ] Store backups off-site — copy backup ZIPs to a separate location outside the TREK host.
|
||||
- [ ] Store backups off-site: copy backup ZIPs to a separate location outside the TREK host.
|
||||
|
||||
## Monitoring
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ Names are the ones the index has, which are the names used on the spot. The inde
|
||||
| The [Road trip](Road-Trip#search-along-the-route) addon's search along the drive | Fuel, charging, rest areas, campsites and the other kinds it looks for | The public Overpass mirrors |
|
||||
| Tours: the trail grades, surfaces and kinds of way along a planned tour | The OpenStreetMap tags of the ways the tour runs on, from its ways layer | The public Overpass mirrors |
|
||||
| Tours: the signposted horse routes around the map view | The horse route relations in the view with their ways, from its routes layer | The public Overpass mirrors |
|
||||
| Tours: the ski piste router (**Ski & winter** tours) | The winter layer: which build it serves, the index of ski areas, and the graph of runs, lifts and trails of one area, which your server keeps and checks once a day | A ski area already kept on your server still plans; a leg that cannot be planned gets a red row, *The piste data cannot be reached right now.*, with **Draw straight** |
|
||||
| Booking imports, and stops given only by name in an imported Google Maps route | The coordinate of a venue, found by its name | OpenStreetMap's search service, which also resolves street addresses |
|
||||
| Preparing a trip for offline use | Up to 3000 places around the trip, in one request | Nothing is cached, and offline search has nothing to answer from |
|
||||
| MCP: `search_place` and `search_pois` | The same as the full search and the category buttons | The same fallbacks |
|
||||
@@ -76,6 +77,7 @@ Every request goes out from your TREK server, never from a browser, so the servi
|
||||
| A venue name | Booking imports and route imports |
|
||||
| The OpenStreetMap way ids a planned tour runs on | Tours trail grades, surfaces and kinds of way |
|
||||
| The map view as a box, grown to a 0.05 degree grid | Tours horse routes |
|
||||
| The id of a ski area | Tours ski piste router. No coordinate goes along: the service learns which area a planner loaded, never where anyone clicked. |
|
||||
| An `X-TREK-Instance` header | Every request |
|
||||
|
||||
The header carries an opaque token derived from your instance's own address, so the service can rate-limit each instance on its own instead of everyone behind one IP. Set `APP_URL` (or `ALLOWED_ORIGINS`): without either, the token is derived from the port alone, and two unconfigured installs on the same port share one rate-limit bucket.
|
||||
@@ -97,12 +99,13 @@ services:
|
||||
|
||||
`false`, `0`, `off` and `no` in any casing switch the index off, as on every other boolean switch. A value that is not boolean-like at all aborts startup, and unset or blank leaves the index on.
|
||||
|
||||
With the index off, TREK stops asking it for suggestions, searches, category buttons, the Road trip search, import geocoding, offline downloads and the ways and horse routes of Tours, and place search works the way it did before 4.3.0:
|
||||
With the index off, TREK stops asking it for suggestions, searches, category buttons, the Road trip search, import geocoding, offline downloads, the ways and horse routes of Tours and the piste data of ski tours, and place search works the way it did before 4.3.0:
|
||||
|
||||
- **Full search** goes to OpenStreetMap on an install without a key. With a Google key, Google answers every search, and with Amap selected, Amap does; OpenStreetMap is then no longer asked beside them.
|
||||
- **Suggestions** come from Google or Amap when one holds the keyed slot, otherwise from OpenStreetMap's public search service. That service's usage policy does not allow autocomplete, so on a keyless install consider pointing `NOMINATIM_URL` at a Nominatim of your own.
|
||||
- **Category buttons** and the **Road trip search** are answered by the Overpass mirrors.
|
||||
- **Tours** read the grades of the ways under a tour and the horse routes around the map from the Overpass mirrors.
|
||||
- **Ski & winter tours** have no piste data to plan on. The winter layer is the only source of it, so there is no Overpass fallback: no ski leg can be planned, even in an area kept earlier. Each leg gets a red row, *The piste data cannot be reached right now.*, and **Draw straight** draws it as a straight line. Nothing is downloaded or refreshed in the background. Hikes, bike tours and the other types are not affected. See [Ski data and its limits](Tours#ski-data-and-its-limits).
|
||||
- **Imports** geocode through OpenStreetMap's search service.
|
||||
- **Offline search** has nothing to answer from, because no places are downloaded.
|
||||
|
||||
@@ -129,7 +132,7 @@ Defaults and details for each are on [Environment Variables](Environment-Variabl
|
||||
|
||||
## When the service cannot be reached
|
||||
|
||||
Nothing breaks. Every call has a short deadline, 3.5 seconds for a search, 10 seconds per batch of tour ways, 20 seconds for an offline download or a view of routes, and every call site falls back to what TREK did before the index existed. After four calls in a row that got no answer or a server error, TREK stops asking for a minute and takes the fallback straight away, so an instance that cannot reach the service does not pay the deadline on every keystroke. The first call after that minute tries again, and one answer resets the count. Place search and the ways and routes of Tours are counted apart, so a busy answer to a heavy tour never pauses the search. When a tour's ways stop answering part way, Tours keeps the batches that came and asks the Overpass mirrors only for the rest.
|
||||
Nothing breaks. Every call has a short deadline, 3.5 seconds for a search, 10 seconds per batch of tour ways, 20 seconds for an offline download or a view of routes, and for the winter layer 5 seconds for its build, 15 for the index of ski areas and 30 for one area, and every call site falls back to what TREK did before the index existed. After four calls in a row that got no answer or a server error, TREK stops asking for a minute and takes the fallback straight away, so an instance that cannot reach the service does not pay the deadline on every keystroke. The first call after that minute tries again, and one answer resets the count. Place search and the layers (the ways and routes of Tours and the winter layer) are counted apart, so a busy answer to a heavy tour never pauses the search. When a tour's ways stop answering part way, Tours keeps the batches that came and asks the Overpass mirrors only for the rest. Ski tours have no such second source.
|
||||
|
||||
| What you see | What it usually means |
|
||||
|---|---|
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
# TREK Studio
|
||||
|
||||
TREK Studio turns a [journey](Journey-Journal) into a photo book you can print. It lays the journey's entries, photos and route out as pages, lets you change every one of them, and makes a print ready PDF at the end. A book belongs to its journey: the photos, words, places and figures it shows come from there, and several people can design it at the same time.
|
||||
|
||||
## Opening Studio
|
||||
|
||||
Open a journey and press **Studio** in its header. The designer opens over the journey at `/journey/:id/studio`, so the journey stays open underneath and **Back to the journey** returns you straight to it.
|
||||
|
||||
Studio needs room to work. It is desktop only and needs a window at least 1024 px wide. In a narrower window, or on a tablet, it shows *Studio needs a bigger screen* with a way back, and on a phone it is not offered at all. Making the PDF is desktop only as well.
|
||||
|
||||
Who may do what follows the journey exactly: anyone who may read the journey may open its book, and only those who may edit the journey may change or delete it. A reader sees **Read-only, not saved** in the header.
|
||||
|
||||
## The screen
|
||||
|
||||
| Area | What it holds |
|
||||
|---|---|
|
||||
| Header | **Page format**, **Auto layout**, undo and redo, paste, the **Assistant**, help, and **Export** |
|
||||
| Left rail | The sections that put things on a page: **Pages**, **Content**, **Layouts**, **Elements**, **Travel**, and set apart below them **Theme** and **Layers** |
|
||||
| Workbench | The spread you are working on, with zoom (**Zoom in**, **Zoom out**, **Fit to view**) and **Book view** |
|
||||
| Properties | Everything about what is selected, on the right |
|
||||
|
||||
The rail and the tabs inside its panels answer to the arrow keys.
|
||||
|
||||
## Page format and the shape of the book
|
||||
|
||||
**Page format** offers **Square 21 × 21 cm** (the default), **Square 30 × 30 cm**, **A4 landscape**, **A4 portrait**, **A5 landscape** and **Custom size** in millimetres. Every page has 3 mm of bleed (what is cut off at the edge) and a 5 mm safe area, both of which the header can show as guides.
|
||||
|
||||
A book follows the shape of a bound one:
|
||||
|
||||
1. the **Cover**, whose inside stays blank,
|
||||
2. a single first page on the right, page 1, where a title page or a dedication goes,
|
||||
3. the double pages (spreads) in between,
|
||||
4. a single last page on the left,
|
||||
5. the **Back cover**, whose inside stays blank too.
|
||||
|
||||
The covers and the single first and last pages stay where they are; new spreads always go between them. **Page numbers** can be switched on with nothing selected: outer, inner or centred, with where they start and their margin. They count from the first page, and the number on screen is the number that prints.
|
||||
|
||||
## Pages
|
||||
|
||||
The **Pages** panel lists the book. **Add spread** adds one after the last, and each spread offers **Insert a spread after this one**, **Duplicate spread**, **Move earlier**, **Move later** and **Delete spread**. **Book view**, beside the zoom buttons, draws the fold down the middle of each spread on the workbench and in the page list; it is on by default.
|
||||
|
||||
### Auto layout
|
||||
|
||||
**Auto layout** in the header builds pages out of the journey for you:
|
||||
|
||||
- **This spread** lays the spread on screen out again from the journal entry it came from, on another design. It is only offered on a spread that auto layout made.
|
||||
- **The whole book** replaces every page, keeping your title and page setup.
|
||||
|
||||
Both are ordinary undo steps: press one, look at the result, and undo it if you liked the old one better.
|
||||
|
||||
An element that auto layout tied to a journal entry follows that entry, so a corrected caption in the journal reaches the book. Editing the element in Studio breaks the link (*Follows the journal entry. Editing it here breaks that link.*).
|
||||
|
||||
## Content
|
||||
|
||||
**Content** holds the journey's own **Photos** and **Entries**. **Search photos and entries** finds one, and **Filter photos** narrows the photos to **All photos**, **Not in an entry**, **Just uploaded** or **This page**. Drag a photo onto the page or onto an empty frame, or use **Add to this page**. An entry adds its title, story, place or **Pros & Cons** as blocks of their own.
|
||||
|
||||
- **Upload photos** adds pictures from your computer. They go into the open entry, or into the journey's gallery when none is open. Videos are left out: a book holds pictures.
|
||||
- With Immich or Synology Photos connected, **From Immich** or **From Synology Photos** picks photos from your library the way the journey gallery does. See [Photo-Providers](Photo-Providers).
|
||||
|
||||
## Layouts
|
||||
|
||||
**Layouts** arranges a whole page at once, with that page's own photos and words.
|
||||
|
||||
**Designed pages** come first: pages laid out by a designer, 48 for the cover and the other single pages and 60 double spreads, in twelve styles (**Spine band**, **Poster**, **Cut-out**, **Postcard**, **Grid and badge**, **Minimal**, **Stamps**, **Riso**, **Editorial**, **Vintage poster**, **Night film** and **Field notes**). Each card shows the page you are on as the click would lay it, with its own photos and words and in the book's theme. The **Style** chips narrow the set to one look. What a design has no room for stays with the page.
|
||||
|
||||
Below come **My layouts** and the **Built in** ones: thirteen spread layouts (**Hero and story**, **Four up**, **Strip and text**, **Mosaic** and more) and five for the cover and back.
|
||||
|
||||
**Save this page as a layout** keeps the arrangement of a page without its photos, for every editor of this book. Applying it lays another page out the same way and keeps that page's photos and words. A book keeps up to 24 layouts.
|
||||
|
||||
## Elements
|
||||
|
||||
**Elements** adds things to a page, in six tabs:
|
||||
|
||||
| Tab | What it adds |
|
||||
|---|---|
|
||||
| Text styles | Ready made titles, badges and stamps, chapter numbers, quotes, captions and coordinates, set in your book's title and sized to fit. A style arrives selected as one set; click a single part to change its words. |
|
||||
| Shapes | Basic shapes, polygons, stars, arrows, speech bubbles, travel shapes, decoration and banners |
|
||||
| Lines | Straight and drawn lines in several strokes |
|
||||
| Frames | **Empty frame**, frame styles (**Plain**, **Polaroid**, **White border**, **Drop shadow**, **Film**, **Taped**), frame shapes and **Grids** of empty frames |
|
||||
| Icons | A searchable icon library, **For travel** or **All icons** |
|
||||
| Stickers | A sticker library in twelve themes, from travel things and landmarks to doodles and ornaments, with **Recently used**. Click one to place it in the middle of the page, or drag it where it should go. |
|
||||
|
||||
An empty frame marks where a picture goes; drop a photo on it from **Content**.
|
||||
|
||||
## Travel
|
||||
|
||||
**Travel** builds figures out of the journey itself. When the journey changed since they were taken, **Update from journey** refreshes them.
|
||||
|
||||
- **Maps**: a **Route map** of the journey, either **Whole journey** or **One trip at a time**, in the styles **Minimal**, **Outline**, **Paper** or **Dark**. The source can be outlines, relief, satellite or map tiles. **Roads** asks a routing service for the way each leg was driven and keeps it in the book, so it prints the same line offline. A map can sit **In a box** or be **Cut to shape** of a country, and shows how sharp it prints at its size.
|
||||
- **Figures**: distance, days, steps, photos, countries, places and the furthest point, as single figures or together, in looks from **Classic** and **Ticket** to **Odometer**, **Road sign** and **Sketch**.
|
||||
- **Countries**: the countries of the journey as outlines, lists or flags, in looks such as **Visa**, **Stamp**, **Postcard** or **Luggage label**.
|
||||
- **Marks**: **Date**, **Day counter**, **Coordinates**, **Flag** and **Distance**.
|
||||
- **Stops**: every stop counts toward the route, the distance and the countries. Switch one off to leave it out, your home airport for instance.
|
||||
|
||||
## Theme
|
||||
|
||||
**Theme** sets the look of the whole book. Pick one of seventeen themes, such as **Poster pop**, **Postcard**, **Riviera**, **Nordic**, **Alpine**, **Riso print**, **Magazine**, **Midnight** or **Field notes**, then **Apply to the book** or **Apply to this page**. Colours and type that follow the theme change with it; everything else stays as it is.
|
||||
|
||||
- **Palette**: the paper, ink, muted and accent colours. **Colours from the photos** takes them from your pictures.
|
||||
- **Typefaces**: the display, heading, body and script faces.
|
||||
- **Motifs**: the sticker themes that suit the look.
|
||||
- **Decoration**: **None**, **Light** or **Rich**.
|
||||
- **Also restyle what isn't linked yet** first links backgrounds, text and shapes to the theme. White words over photos stay as they are.
|
||||
|
||||
A colour that follows the theme reads **Theme colour** in the properties; **Stop following the theme** frees it. **Back to the original theme** undoes a theme change.
|
||||
|
||||
## Properties
|
||||
|
||||
**Properties** on the right edits whatever is selected, in the same order for every kind: what the element is or says, then its position and size, then its look, then its effects, and last **Arrange**. The groups you use are open, and a group opens by itself on an element that already uses it. With nothing selected the panel shows the page background, the book's theme and the page numbers.
|
||||
|
||||
### Photos
|
||||
|
||||
- **Crop**: **Fill** or **Fit**, zoom, **Mirror**, and a focal point you drag to choose what stays in frame.
|
||||
- **Look**: the filters **Original**, **Black & white**, **Warm**, **Cool**, **Faded** and **Punchy**, and **Adjust** for brightness, contrast, saturation and warmth.
|
||||
- **Border and shadow**, a **Cutout edge**, a corner radius, and **Cut to shape** to put the photo in a shape.
|
||||
- **Fill page** or **Fill spread** stretches the picture over the whole page, bleed included, and sends it behind everything else.
|
||||
- Studio says how sharp a photo prints (*Prints at about* so many dpi) and warns when it would look soft.
|
||||
|
||||
### Text
|
||||
|
||||
- Typeface, weight, size, line height, tracking, alignment (including **Justified**) and colour. **Change typeface** searches the faces by kind: sans serif, serif, elegant display, condensed and poster, heavy and retro, script and handwriting, monospace. **Used in this book** lists the faces you already have.
|
||||
- **Case and placement**: **As typed**, **Capitals**, **Lower case** or **Small caps**; the text's place in its frame; and **Shrink to fit**, which treats the size you set as the largest.
|
||||
- **Effects**: **Hard shadow**, **Marker band**, **Curve** (**Arc**, **Circle** or **Bend**), **Hollow** letters, and **Photo inside the letters**, where a photo shows through the type.
|
||||
|
||||
### Shapes, lines and backgrounds
|
||||
|
||||
A shape, a sticker's colours and the page background take a fill: **Solid**, **Gradient** (linear or radial, with colour stops) or **Pattern**. Shapes also take an outline (**Solid**, **Dashed** or **Dotted**), opacity and rotation.
|
||||
|
||||
### Arrange
|
||||
|
||||
**Arrange** aligns and stacks: **Bring to front**, **Bring forward**, **Send backward**, **Send to back**, **Lock**, **Duplicate**, **Delete**, grouping, **Copy style** and **Paste style**, and **Show in Layers**. Several selected elements can be aligned to each other, to the page or to the safe area, and spaced evenly.
|
||||
|
||||
## Layers
|
||||
|
||||
**Layers** lists the page front to back. Drag a row to restack it, double click a name to rename it, **Hide** or **Show** an element, and **Group** or **Ungroup** several. Double click an element on the page to work inside its group.
|
||||
|
||||
## Keyboard shortcuts
|
||||
|
||||
| Keys | Action |
|
||||
|---|---|
|
||||
| Ctrl+Z, Ctrl+Shift+Z | Undo, redo |
|
||||
| Ctrl+C, Ctrl+V | Copy and paste elements, onto any page |
|
||||
| Ctrl+D | Duplicate |
|
||||
| Ctrl+A | Select everything on the page |
|
||||
| Ctrl+G, Ctrl+Shift+G | Group, ungroup |
|
||||
| Ctrl+Alt+C, Ctrl+Alt+V | Copy style, paste style |
|
||||
| Ctrl+], Ctrl+[ | Bring forward, send backward; with Shift to the front or the back |
|
||||
| Arrow keys | Move by 1 mm, by 10 mm with Shift |
|
||||
| Delete or Backspace | Remove what is selected and not locked |
|
||||
| Escape | Inside a group, back to the whole group |
|
||||
|
||||
On a Mac, Ctrl is Cmd. While you type in a field or a text on the page, the keys are the text's.
|
||||
|
||||
## Saving and designing together
|
||||
|
||||
Studio saves as you go. The header shows **Saving**, **Saved**, or **Not saved** with **Try again**.
|
||||
|
||||
Several people can design the same book at once. Everyone sees the others' pointers with their names, and who is **here**. A save is passed to the others live. When a save lands on a version somebody else changed in the meantime, Studio does not overwrite their work: *Someone else saved this book* offers **Take theirs** or **Keep mine**.
|
||||
|
||||
**Download this spread** saves the design of the spread you are on as a file, without the photographs, and **Import** adds such a spread to another book.
|
||||
|
||||
## Export and printing
|
||||
|
||||
**Export** opens the print settings:
|
||||
|
||||
- **Layout**: **Single pages** (one leaf per sheet, in reading order, what a printer wants) or **Spreads** (two pages at a time, the way the book opens, for reading).
|
||||
- **Finishing**: **Crop marks** adds the bleed on every edge and marks where to cut.
|
||||
|
||||
The note under it says how many sheets at what size you get. **Print view** opens the book in your browser's print view, and **Save as PDF** turns it into a PDF there. The button waits (**Preparing**) until every photo and typeface has loaded, so nothing prints as an empty box or in the wrong font.
|
||||
|
||||
## The book assistant
|
||||
|
||||
With the [AI Assistant](AI-Assistant) set up, **Assistant** in the Studio header opens the **Book assistant** beside the page (*Design the book together with the assistant*). Ask it *What should the book look like?* and it can:
|
||||
|
||||
- start the book, add, change, move, duplicate and delete pages, change the cover, the page format and the theme, and save a page as a layout,
|
||||
- propose a whole book design in a style such as **Classic design**, **Minimal design**, **Editorial design**, **Journal design**, **Bold design** or **Scrapbook design**, with its colours and typefaces. You choose per page which pages take the new design,
|
||||
- check a page and list what to fix, such as text running past its frame, something in the fold or past the edge, an empty photo frame, a photo that may print blurry, text that is hard to read, too many typefaces or the same layout again and again.
|
||||
|
||||
Every change arrives as a card you apply or discard, with **Show this page**, and can be undone, the same as in a trip. Someone who can only read the book can ask questions, but the assistant changes nothing for them.
|
||||
|
||||
**Pictures of your pages.** The assistant always reads a page as a description. To let it look at the page itself, Studio asks once: *The assistant can look at the page you are working on. Only that page goes to the provider, as a picture showing just the photos you added yourself.* **Show it pages** allows it for that connection, **Not now** keeps to descriptions. Photos added by other people are drawn as empty frames, and nothing of the picture is stored.
|
||||
|
||||
## See also
|
||||
|
||||
- [Journey-Journal](Journey-Journal)
|
||||
- [AI-Assistant](AI-Assistant)
|
||||
- [Photo-Providers](Photo-Providers)
|
||||
- [Help-Center](Help-Center)
|
||||
@@ -17,15 +17,15 @@ Categories classify places across all trips. Every user sees the same set of cat
|
||||
|
||||
Categories appear in:
|
||||
|
||||
- The **place form** when adding or editing a place.
|
||||
- The **places sidebar** as filter options.
|
||||
- The **place form** when adding or editing a place: the category is the pill in the head band, and the **+** next to it (*New category*) creates one on the spot.
|
||||
- The **places column** as filter options: the tag icon opens the categories, and a badge on it counts those in force. In select mode, **Change category** gives every ticked place the same category.
|
||||
- **Map markers**: the category icon and color are used to style each place's marker pin.
|
||||
- **Map hover cards**: resting the pointer on a marker shows the category with the place's name and address.
|
||||
- **Saved places** in [Collections](Collections), which use the same set.
|
||||
|
||||
A place picked from the search or from a marker of the map's category buttons comes with a matching category already picked, when the palette has one whose name or icon fits (a hotel goes to a category such as Hotel or Accommodation, a museum to Sights or Museum). Pick another one and it stays yours. See [The place form](Places-and-Search#the-place-form).
|
||||
|
||||
> **Admin:** Create and manage categories in [Admin-Categories](Admin-Categories), or create one on the spot with the **+** (*New category*) next to the category pill of the place form. Only admins can create, edit, or delete categories. All users can read them.
|
||||
> **Admin:** Create and manage categories in [Admin-Categories](Admin-Categories), or create one on the spot with the **+** (*New category*) next to the category pill in the head band of the place form. Only admins can create, edit, or delete categories. All users can read them.
|
||||
|
||||
> **AI / MCP:** `list_categories` lists the palette; `create_category`, `update_category` and `delete_category` are for admins only.
|
||||
|
||||
|
||||
@@ -34,6 +34,12 @@ Click a task row to open the detail pane, where every field can be changed. **Sa
|
||||
|
||||
The description understands Markdown: bold text, lists and links render as such, in the task list (shortened to one line) and in the detail pane. In the detail pane a click on the text switches it back to the editing box (the tooltip reads *Click to edit, links open directly*); a click on a link opens the link instead. An empty description is the editing box straight away.
|
||||
|
||||
**Delete** in the detail pane removes the task straight away, without asking.
|
||||
|
||||
## On the phone
|
||||
|
||||
On a phone the to-dos have their own layout: a filter row with **All**, **My Tasks**, **Overdue** and **Done**, the priority sort and the lists, then the tasks as cards. A task opens in a sheet with the same fields as the detail pane. The filters and the task form are the same ones the desktop uses, so both behave alike.
|
||||
|
||||
## Priority levels
|
||||
|
||||
| Level | Label | Colour |
|
||||
@@ -67,6 +73,10 @@ The sort sits in the head of the task list. **Priority** orders the tasks from P
|
||||
|
||||
**Create task** stays greyed out until the task has a name.
|
||||
|
||||
## AI assistant
|
||||
|
||||
The in-app AI assistant can propose to-dos as cards in the chat. Nothing is added until you confirm a card.
|
||||
|
||||
## Permissions
|
||||
|
||||
Every write needs the `packing_edit` permission, the same one as the packing list. Without it the tasks can be read but not changed.
|
||||
|
||||
+3
-1
@@ -4,7 +4,9 @@ The **Tours** add-on plans routes inside a trip: hikes and runs, city walks, bik
|
||||
|
||||
Tours is a trip add-on and on by default; an administrator switches it under **Admin > Add-ons**. While it is on, the Plan tab gets a **Places / Tours** switch in its right column and the trip gets a **Tours** tab for drawing and editing. The Tours tab needs a tablet or a computer; on a phone you see and plan tours, but do not draw them.
|
||||
|
||||
This page follows the app: the Plan tab first, then the tour card, the Tours tab and its tools, and at the end what is special about each kind of tour.
|
||||
This page follows the app: the Plan tab first, then the tour card, the Tours tab and its tools, and at the end what is special about each kind of tour. The **?** in the navbar opens the [Help Center](Help-Center) on the tour screen you are on, with a picture of each step.
|
||||
|
||||
With the AI Assistant addon on, the assistant can look for tours and propose them in the trip. A proposed tour comes as a card with **Plan this** (or **Plan way A**, **Plan way B** when it found several ways), and **Open in Tours** takes you to the planner once it is added. Nothing is saved until you confirm.
|
||||
|
||||
|
||||
## Tours on the Plan tab
|
||||
|
||||
@@ -8,7 +8,7 @@ Flights, trains, rental cars, ferries and every other ride of a trip, with their
|
||||
|
||||
There are several ways to add a transport:
|
||||
|
||||
- On the **Transports** tab, click **Transport** at the top right. The editor opens as **Add transport**.
|
||||
- On the **Transports** tab, click **Transport** at the top right. The editor opens as **Add transport**. On a tab without transports, the page offers **Transport**, **Import from file** and, with the AirTrail addon on, **AirTrail** as buttons.
|
||||
- In the day plan, click the **+** in a day's head band (*Add to day*) and pick **Add transport** for that day, or **Public transit** to search a connection on it.
|
||||
- Click the travel-time connector between two stops in the day plan and pick **Public transit**. The search opens with that leg's start and end filled in and the departure time taken from the stop you are leaving.
|
||||
- Import the confirmation with **Import booking confirmations**, or bring flights in from AirTrail. See [Import from booking confirmation](Reservations-and-Bookings#import-from-booking-confirmation) and [Import from AirTrail](Reservations-and-Bookings#import-from-airtrail).
|
||||
@@ -118,6 +118,10 @@ Self-hosters can point the `TRANSIT_API_URL` environment variable at their own M
|
||||
|
||||
> **Admin:** which service answers the search is set under **Admin → Settings → API Keys → Transit Provider**. **Transitous (free)** is the default: community GTFS feeds, keyless, with the best coverage in Europe. **Google** runs the stop search and the route plan through the Google Maps API key in the same card, for regions Transitous has no data for. Google bills per search, and the key has to be allowed to call the **Routes API** and the **Places API (New)** (text search); the legacy Directions API is not used. A key saved only in a member's own settings serves that member alone, so save it as an admin to apply it to the whole instance. While no Google key is available, the search stays on Transitous even with Google selected, which is why an empty result names the service that answered (*No connections found via Google*).
|
||||
|
||||
## Offline
|
||||
|
||||
A transport you save while offline waits in a queue and is sent when TREK is back online. A transport that carries new files needs a connection, because files cannot be uploaded offline: remove the new files to save it, or save once you are back online.
|
||||
|
||||
## Opening a transport
|
||||
|
||||
Click a transport anywhere, on its card, in the day plan, on the map or in the road trip rail, and its detail opens.
|
||||
@@ -158,8 +162,14 @@ Drag a transport row to move it within its day or onto another day. The rows of
|
||||
|
||||

|
||||
|
||||
A booking that is pinned to a stop on another day shows at that stop only, not on two days. The dashboard's upcoming reservations leave out planned public transit.
|
||||
|
||||
See [Day-Plans-and-Notes](Day-Plans-and-Notes#multi-day-reservations) for how the days are put together.
|
||||
|
||||
## AI assistant
|
||||
|
||||
The in-app AI assistant can read and add transports. A transport it proposes appears as a booking card in the chat that you confirm before it is saved.
|
||||
|
||||
## See also
|
||||
|
||||
- [Reservations-and-Bookings](Reservations-and-Bookings)
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
# Trip Members and Sharing
|
||||
|
||||

|
||||

|
||||
|
||||
## Opening the Members Panel
|
||||
## Opening the Trip settings
|
||||
|
||||
- From the **trip planner**: click the Share button in the top navigation bar.
|
||||
- On **mobile**: open the trip, then **More** → **Share Trip**.
|
||||
- From the **trip planner**: click the **Trip settings** pill beside the trip's title in the top navigation bar.
|
||||
- On **mobile**: open the trip, then **More** and the **Trip settings** row.
|
||||
|
||||
The dialog carries the trip's name in its head band, with the number of people on the trip and, once there are any, of its guests. When you have the `share_manage` permission it opens in two columns (members and guests on the left, the two links on the right). Without that permission only the members column is shown. On a narrow window the columns stack.
|
||||
The dialog is headed **Trip settings**, with the trip's name under it and pills for the number of people on the trip and, once there are any, of its guests. A side navigation splits it into areas:
|
||||
|
||||
## Members List
|
||||
| Area | What it holds | Who sees it |
|
||||
|---|---|---|
|
||||
| **People** | Inviting users, the access list and the guests | Everyone on the trip |
|
||||
| **Sharing** | The **Public Link** and the **Trip invite link** | Users with the `share_manage` permission |
|
||||
| **Journal** | The journal linked to this trip | When the Journey addon is on and you may link a journal, or the trip already has one |
|
||||
|
||||
The left column lists everyone who has access to the trip.
|
||||
When only one area applies to you, the side navigation is hidden. On a narrow window the areas become pills above the content.
|
||||
|
||||
## People
|
||||
|
||||
The **Access** section lists everyone who has access to the trip, with a count.
|
||||
|
||||
- The **trip owner** is marked with an **Owner** badge and a crown.
|
||||
- Your own entry carries a **you** badge (on the phone it reads **(you)**).
|
||||
@@ -19,7 +27,7 @@ The left column lists everyone who has access to the trip.
|
||||
|
||||
### Inviting Members
|
||||
|
||||
If you have the `member_manage` permission (default: trip owner), an invite control appears above the list. Select a user from the searchable dropdown and click **Invite**. The user is looked up by username or email on the server, added immediately, and the list refreshes. The invited user also receives an in-app notification.
|
||||
If you have the `member_manage` permission (default: trip owner), an **Invite User** control appears above the list. Select a user from the searchable dropdown and click **Invite**. The user is looked up by username or email on the server, added immediately, and the list refreshes. The invited user also receives an in-app notification.
|
||||
|
||||
### Removing a Member
|
||||
|
||||
@@ -86,7 +94,7 @@ There is no limit on the number of guests per trip.
|
||||
|
||||
## Public Share Link
|
||||
|
||||
The right column is only visible to users with the `share_manage` permission (default: trip owner).
|
||||
The **Sharing** area is only visible to users with the `share_manage` permission (default: trip owner). Its first section is **Public Link**.
|
||||
|
||||
A share link creates a **read-only, token-based URL**:
|
||||
|
||||
@@ -122,7 +130,7 @@ Click **Delete link** (red button below the URL) to revoke access. The token is
|
||||
|
||||
## Trip Invite Link
|
||||
|
||||
Below the public share link, users with the `share_manage` permission can also create a **trip invite link** — a single rotating link that lets people **join the trip as members**:
|
||||
Below the public link, in the same **Sharing** area, users with the `share_manage` permission can also create a **trip invite link**: a single rotating link that lets people **join the trip as members**:
|
||||
|
||||
```
|
||||
<your-instance>/join/<token>
|
||||
@@ -133,7 +141,7 @@ Unlike the read-only share link, this one is **not anonymous**:
|
||||
- Whoever opens it must have a TREK account and be **signed in**. If they are not, they are sent to the login page and returned to the invite afterwards — there is **no registration** from this link.
|
||||
- Opening it while signed in shows a confirmation card naming the trip. Clicking **Join trip** adds you as a **member** (the same access a manually-added member gets) and opens the trip. The owner and existing members see the same card and are simply taken to the trip when they accept.
|
||||
- To invite people who do **not** yet have an account, use an admin invite link with an optional trip binding instead — see [Invite-Links](Invite-Links).
|
||||
- Someone another member **removed** from the trip cannot rejoin through the invite link, old or regenerated; they see that they were removed. Adding them again by name in the Share dialog lets them back in. Someone who **left** the trip on their own can still rejoin through the link.
|
||||
- Someone another member **removed** from the trip cannot rejoin through the invite link, old or regenerated; they see that they were removed. Adding them again by name in the Trip settings lets them back in. Someone who **left** the trip on their own can still rejoin through the link.
|
||||
|
||||
### Creating and revoking
|
||||
|
||||
@@ -143,9 +151,21 @@ Unlike the read-only share link, this one is **not anonymous**:
|
||||
|
||||
> **Admin:** To invite users who do not yet have an account, create invite links in the admin panel. See [Invite-Links](Invite-Links).
|
||||
|
||||
## Journal
|
||||
|
||||
With the Journey addon on, the **Journal** area links one of your journals to the trip. Whoever you let in opens it right inside the trip, in its Journal tab, live.
|
||||
|
||||
- **Link a journal** shows your journals; pick one and click **Link journal**. Only the journal's owner can link it, and on the trip side the **Link a journal** permission (`journal_link`) decides who may.
|
||||
- Under **Access for trip members** you choose, per person, **Read**, **Edit** or **No access**, or set everyone at once with **Everyone can read** or **Nobody**. People who get access to the journal for the first time are flagged before you save.
|
||||
- Once linked, the card shows a **Linked** badge and your role (**Your journal**, **You can edit** or **You can read**). **Change journal** swaps it, **Edit access** reopens the access list, and **Unlink** removes the Journal tab from the trip. People you added in the journal itself keep their access when you unlink.
|
||||
- Linking needs a connection.
|
||||
|
||||
See [Journey-Journal](Journey-Journal) for the journal itself.
|
||||
|
||||
## Related Pages
|
||||
|
||||
- [Public-Share-Links](Public-Share-Links)
|
||||
- [Invite-Links](Invite-Links)
|
||||
- [Creating-a-Trip](Creating-a-Trip)
|
||||
- [Trip-Planner-Overview](Trip-Planner-Overview)
|
||||
- [Trip-Settings](Trip-Settings)
|
||||
|
||||
@@ -16,7 +16,7 @@ On a desktop or a tablet (768 px and wider) the **Plan** tab has three parts:
|
||||
└─────────────────┴──────────────────────────┴──────────────────┘
|
||||
```
|
||||
|
||||
- **Days** on the left: the trip day by day. Every day is a card with its places, bookings, transports and notes. See [Day Plans and Notes](Day-Plans-and-Notes).
|
||||
- **Days** on the left: the trip day by day. Every day is a card with its places, bookings, transports, tours and notes. See [Day Plans and Notes](Day-Plans-and-Notes).
|
||||
- **Map** in the centre: the places of the trip, the route of the selected day and the booking routes you switched on. The lock on the map (*Lock the map view*) keeps the view where it is, so picking a day or a place no longer zooms or pans; click it again to let the map follow the selection. See [Map Features](Map-Features).
|
||||
- **Places** on the right: every place of the trip, with search, filters, import and a select mode. See [Places and Search](Places-and-Search).
|
||||
|
||||
@@ -31,21 +31,29 @@ Opening a day also narrows the places column. With a day open, **Planned** in th
|
||||
|
||||
With the [Road trip](Road-Trip) addon on, a **Days** / **Road trip** switch sits above the days column. See [Road trip view](#road-trip-view).
|
||||
|
||||
## The top bar
|
||||
|
||||
Inside a trip the top bar carries the way back as a pill: an arrow and the trip's name, which takes you back to the [dashboard](My-Trips-Dashboard). Beside it sits the **Trip settings** pill, which opens People, Sharing and, with the Journey addon on, Journal: who is on the trip, the read-only link and the invite link, and the journal the trip shows. On the right are the **?** help button on windows at least 640 px wide (see [Help Center](Help-Center)), the assistant launcher when the AI Assistant addon is on, the notification bell and your user menu.
|
||||
|
||||
## Tabs
|
||||
|
||||
The tab bar sits directly below the main navigation bar.
|
||||
The tab bar sits in the middle of the top bar.
|
||||
|
||||
| Tab | What it holds |
|
||||
|---|---|
|
||||
| **Plan** | Days, map and places, as described on this page. Always shown. |
|
||||
| **Tours** | The trip's tour planner: draw a tour or import a GPX, KML or KMZ track. Second after **Plan**, on a computer or tablet, while the Tours addon is on. See [Tours](Tours). |
|
||||
| **Transports** | Flights, trains, buses, cars, taxis, bicycles, ferries, cruises, cable cars and public transit, as cards, a list or a timeline. See [Transport: Flights, Trains, Cars](Transport-Flights-Trains-Cars). |
|
||||
| **Bookings** | Stays, restaurants, events, tours, parking and other bookings, in the same three views. See [Reservations and Bookings](Reservations-and-Bookings). |
|
||||
| **Lists** | Packing list and to-dos. See [Packing Lists](Packing-Lists) and [Todos and Tasks](Todos-and-Tasks). |
|
||||
| **Costs** | Expenses, splits and settling up, as a list or a table. See [Costs](Budget-Tracking). |
|
||||
| **Files** | Tickets, receipts and other documents. See [Documents and Files](Documents-and-Files). |
|
||||
| **Collab** | Chat, shared notes, polls and What's Next. See [Real-Time Collaboration](Real-Time-Collaboration). |
|
||||
| **Journal** | The journal from Journey that is linked to the trip, for whoever the link lets in. Shown only while one is linked. See [Journey Journal](Journey-Journal). |
|
||||
|
||||
> **Admin:** The **Lists**, **Costs**, **Files** and **Collab** tabs only appear when the matching addon is enabled. See [Admin-Addons](Admin-Addons).
|
||||
On a phone the **Road trip** tab takes the place of the **Days** / **Road trip** switch, and the **Tours** tab is left out; tours are listed on the **Plan** tab there. An installed [plugin](Plugins) can add a tab of its own and, if its manifest says so, hide core tabs while it is active.
|
||||
|
||||
> **Admin:** The **Tours**, **Lists**, **Costs**, **Files** and **Collab** tabs only appear when the matching addon is enabled. See [Admin-Addons](Admin-Addons).
|
||||
|
||||
The active tab is saved in `sessionStorage` per trip, so switching between trips brings you back to where you were. The installed app (PWA) goes further: after the system closed it, it reopens on the trip and the tab it was on, and on a phone on the plan day as well.
|
||||
|
||||
@@ -111,4 +119,7 @@ When you open a trip, a short loading screen shows the trip title while the plan
|
||||
- [Accommodations](Accommodations)
|
||||
- [Reservations and Bookings](Reservations-and-Bookings)
|
||||
- [Road Trip](Road-Trip)
|
||||
- [Tours](Tours)
|
||||
- [Admin-Addons](Admin-Addons)
|
||||
- [Trip Settings](Trip-Settings)
|
||||
- [AI Assistant](AI-Assistant)
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
# Trip Settings
|
||||
|
||||
**Trip settings** gathers who is on a trip, how others get in, and which journal the trip shows, in one dialog with three areas: **People**, **Sharing** and **Journal**. The trip's own details (title, description, dates, currency, cover) are edited with **Edit Trip** instead; see [Creating-a-Trip](Creating-a-Trip).
|
||||
|
||||
## Opening it
|
||||
|
||||
- **On the desktop**, open a trip and press **Trip settings** in the navigation bar, the pill right beside the trip's name.
|
||||
- **On a phone**, open the trip's **More** sheet and tap **Trip settings**. The same areas open as a sheet. **Edit Trip** sits in the same sheet for those who may edit the trip. See [Mobile-App](Mobile-App).
|
||||
|
||||
On a wide screen the areas are listed down the left side, each with a line saying what it is for; on a narrow one they are a row of pills above the content. The head of the dialog shows how many people and guests the trip has.
|
||||
|
||||
## People
|
||||
|
||||
*Who is on this trip, and the guests without an account.*
|
||||
|
||||
- **Invite User** adds someone with a TREK account straight away: pick them and press **Invite**. When everyone already has access, the dialog says *All users already have access.*
|
||||
- **Access** lists the members with their role. The owner carries a crown. **Make owner** hands the trip to another member, **Remove access** takes someone off the trip, and on your own row **Leave trip** takes you off.
|
||||
- **Guests** are *people without an account. They can be assigned to costs, packing and tasks, but cannot sign in.* **Add guest** names one; a guest can be renamed or removed later.
|
||||
|
||||
Adding and removing members needs the **Add / remove members** permission, which by default only the trip owner has. Everything about members, guests and ownership is on [Trip-Members-and-Sharing](Trip-Members-and-Sharing).
|
||||
|
||||
## Sharing
|
||||
|
||||
*A read-only link for anyone, and an invite link to join.*
|
||||
|
||||
- **Public Link**: *Create a link anyone can use to view this trip without logging in.* **Create link** makes it. The chips choose which parts it shows (**Map & Plan** always, then **Bookings**, **Packing**, **Costs** and **Chat**), and **Options** narrow it to **Travel & stays only** or **Without photos**. **Delete link** turns it off. See [Public-Share-Links](Public-Share-Links).
|
||||
- **Trip invite link**: *Anyone with a TREK account who opens this link joins the trip as a member.* **Create invite link** makes one, **Regenerate** replaces it so the old one stops working, and **Disable** turns it off. See [Trip-Members-and-Sharing](Trip-Members-and-Sharing#trip-invite-link).
|
||||
|
||||
Each link has a **Copy** button. Managing the links needs the **Manage share links** permission, by default the trip owner's.
|
||||
|
||||
## Journal
|
||||
|
||||
*Link one of your journals to this trip. Whoever you let in opens it right here in the Journal tab, live.*
|
||||
|
||||
A trip can show one journal from the [Journey](Journey-Journal) addon. Once linked, the trip gets a **Journal** tab, marked with a book with a link on its corner, and the journal opens inside the trip for everyone you let in. It is the real journal, not a copy: what is written there appears in the tab as it happens.
|
||||
|
||||
### Linking a journal
|
||||
|
||||
1. Open **Trip settings → Journal** and press **Link a journal**.
|
||||
2. **Choose a journal** from your own journals. A journal you only write in is not yours to give away, so it is not listed. Without a journal of your own the dialog says *You have no journal yet. Create one in Journey first.*
|
||||
3. Under **Access for trip members**, give each member **No access**, **Read** or **Edit**. **Everyone can read** and **Nobody** set the whole list at once.
|
||||
4. Press **Link journal**.
|
||||
|
||||
Before saving, the dialog names the people the link would let in for the first time: *they will get access to this journal for the first time and from then on also see it in their own journal list.*
|
||||
|
||||
Guests cannot sign in, so they are never on this list, and neither is the journal's owner, who has access anyway.
|
||||
|
||||
### Once it is linked
|
||||
|
||||
The area then shows the journal's cover and title, **Linked**, and what you may do in it: **Your journal**, **You can edit** or **You can read**. When only you can open it, it says *Nobody else from this trip has access yet.*
|
||||
|
||||
- **Edit access** changes who of the trip may read or edit. **Access saved** confirms it.
|
||||
- **Change journal** links another of your journals instead.
|
||||
- **Unlink** removes the link. *The Journal tab disappears from this trip. Members who could only open the journal through this trip lose access; people you added in the journal itself keep theirs.*
|
||||
|
||||
The access a link gives lasts as long as the link holds a member and that member stays on the trip. Someone who leaves the trip loses the access they had through it.
|
||||
|
||||
### Who may link
|
||||
|
||||
Linking a journal, or changing who may open it, gives other people access to that journal, so it needs both: you own the journal, and you hold the trip's **Link a journal** permission (by default the trip owner; an administrator can widen it to all members, see [Admin-Permissions](Admin-Permissions)). Taking the link down only takes access away, so either one is enough for **Unlink**.
|
||||
|
||||
A member the journal is closed to, and who can do nothing about the link, does not see that the trip has one. Linking needs a connection; offline the dialog says *Linking a journal needs a connection.* With the Journey addon switched off, the Journal area and the tab are not shown.
|
||||
|
||||
The [AI Assistant](AI-Assistant) can propose the link as a card too (*Show the journal in this trip*), which you apply like any other change.
|
||||
|
||||
## See also
|
||||
|
||||
- [Trip-Members-and-Sharing](Trip-Members-and-Sharing)
|
||||
- [Public-Share-Links](Public-Share-Links)
|
||||
- [Invite-Links](Invite-Links)
|
||||
- [Journey-Journal](Journey-Journal)
|
||||
- [Creating-a-Trip](Creating-a-Trip)
|
||||
+59
-1
@@ -382,7 +382,7 @@ If `ALLOWED_ORIGINS` is not set, the default is **same-origin only** — cross-o
|
||||
|
||||
**Cause:** The browser Clipboard API (`navigator.clipboard`) is only available in a [secure context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts), so on plain HTTP at a non-localhost address it is undefined.
|
||||
|
||||
TREK works around this where it matters most. The share-link and invite-link buttons in the trip's **Share Trip** and **Members** dialogs, the journey share link, and the calendar-subscribe URLs fall back to a hidden textarea plus the deprecated `document.execCommand('copy')`, which is not secure-context gated, so **those keep working over plain HTTP**, on desktop and mobile alike.
|
||||
TREK works around this where it matters most. The share-link and invite-link buttons in the trip's **Trip settings** dialog, the journey share link, and the calendar-subscribe URLs fall back to a hidden textarea plus the deprecated `document.execCommand('copy')`, which is not secure-context gated, so **those keep working over plain HTTP**, on desktop and mobile alike.
|
||||
|
||||
The remaining copy buttons call `navigator.clipboard` directly and have no fallback:
|
||||
|
||||
@@ -567,3 +567,61 @@ Create a WAF skip rule that bypasses bot management only for the MCP and OAuth p
|
||||
4. Save and deploy.
|
||||
|
||||
This allows MCP and OAuth traffic through while keeping Cloudflare bot protection active for all other paths.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Web Push notifications do not arrive
|
||||
|
||||
**Cause:** Push depends on several things at once, and the card under **Settings → Notifications** tells you which one is missing.
|
||||
|
||||
**Fix:** Check them in this order:
|
||||
|
||||
- TREK has to be opened over **HTTPS**. On any `http://` address other than `localhost` the card says that push needs HTTPS.
|
||||
- On an iPhone or iPad, push only works in the Home Screen app. Add TREK to the Home Screen, open it from there and turn push on there.
|
||||
- Push is per device. Press **Turn on for this device** on every device that should receive it, and use **Send test** to check. Logging out, or changing your password, removes the device, so turn it on again afterwards.
|
||||
- The admin has to switch the **Web Push** channel on in **Admin → Notifications**, and the **Push** column of your matrix has to allow the event.
|
||||
- If you set `VAPID_PUBLIC_KEY` and `VAPID_PRIVATE_KEY` yourself, both have to be set and belong together. If only one is set, or the stored key cannot be decrypted because `ENCRYPTION_KEY` changed, push is off and the server log says why.
|
||||
- Notifications must not be blocked for TREK in the browser or the system settings.
|
||||
|
||||
See [Notifications](Notifications#web-push) for the details.
|
||||
|
||||
---
|
||||
|
||||
## The app shows an old version after an update
|
||||
|
||||
**Cause:** The installed app and open tabs keep running the build they loaded. TREK does not reload a page under your hands.
|
||||
|
||||
**Fix:** When a release is deployed while TREK is open, a notice reads **A new version is available** with a **Reload page** button. Click it. If you closed the notice, reload the page, or close the installed app and open it again. Changes you made offline with the newer version wait in the queue until a tab on the current version is open, then they are sent. See [Offline-Mode-and-PWA](Offline-Mode-and-PWA#stats--cache).
|
||||
|
||||
---
|
||||
|
||||
## TREK refuses to start after an update or a rollback
|
||||
|
||||
**Cause:** There are two different refusals. TREK 5.0 and later refuse to start on a database that a newer TREK has already migrated, and they refuse to migrate when they cannot write the safety copy of the database first (a full disk or a read-only data directory).
|
||||
|
||||
**Fix:** Read the first lines of the server log, which name the problem and the path. For a full disk, free space and start again. To go back to the previous image, restore the `data/pre-migrate-<schema>-<time>.db` copy over `data/travel.db`, delete `travel.db-wal` and `travel.db-shm`, and start the older image. The exact steps, and the `TREK_DB_PRE_MIGRATE_SNAPSHOT` switch, are in [Updating](Updating#database-migrations).
|
||||
|
||||
---
|
||||
|
||||
## AI booking import times out or comes back cut off
|
||||
|
||||
**Cause:** One AI parsing call is limited in time and in answer length. A local model on a slow host can need minutes, and a document with many bookings needs a long answer.
|
||||
|
||||
**Fix:** Raise `LLM_TIMEOUT_MS` (default 900000, which is 15 minutes) for a timeout, and `LLM_MAX_OUTPUT_TOKENS` (default 4096, or 8192 on Anthropic) when the import says the answer was cut off. See [AI-Booking-Import](AI-Booking-Import) and [Environment-Variables](Environment-Variables).
|
||||
|
||||
---
|
||||
|
||||
## Place search only shows OpenStreetMap results
|
||||
|
||||
**Cause:** TREK asks its own place index, the [TREK Places API](TREK-Places-API), first. When that service cannot be reached, the server logs `TREK Places ... failed, falling back` and search carries on with OpenStreetMap alone. The same happens when `TREK_PLACES_ENABLED` is set to `false`.
|
||||
|
||||
**Fix:** Check that `TREK_PLACES_ENABLED` is not `false` and that the server can reach `https://places.liketrek.com`, or your own copy named in `TREK_PLACES_URL`. See [Environment-Variables](Environment-Variables#place-search-trek-places-api).
|
||||
|
||||
---
|
||||
|
||||
## Offline changes do not sync
|
||||
|
||||
**Cause:** The server kept refusing a queued change (after eight attempts it counts as failed), or an edit you made offline collided with a newer one on the server.
|
||||
|
||||
**Fix:** The status pill at the bottom of the window reads **Failed to sync: N** or **Conflicts: N**. Open **Settings → Offline**. Under **Failed changes**, use **Try again** or **Discard** on each item. Under conflicts, choose **Keep mine** or **Keep theirs**. If the local copy itself looks wrong, **Clear cache** empties it and the next sync downloads it again. Unsynced changes are kept when a trip is cleared from the device. See [Offline-Mode-and-PWA](Offline-Mode-and-PWA).
|
||||
|
||||
@@ -8,9 +8,9 @@ TREK supports Time-based One-Time Password (TOTP) two-factor authentication, com
|
||||
|
||||
## Setting up 2FA
|
||||
|
||||
Go to **Settings → Account**, find the **Two-factor authentication (2FA)** section and click **Set up authenticator**.
|
||||
Go to **Settings → Account**, find the **Two-factor authentication (2FA)** card (it is a card of its own, below Change Password) and click **Set up authenticator**.
|
||||
|
||||
1. A QR code and a text secret are displayed. Scan the QR code with your authenticator app.
|
||||
1. A QR code and a **Secret key (manual entry)** are displayed. Scan the QR code with your authenticator app, or type the secret in by hand.
|
||||
> **Note:** The setup session expires after **15 minutes**. If you do not complete setup within that window, start again.
|
||||
2. Enter the 6-digit code shown in your authenticator app and click **Enable 2FA**.
|
||||
3. Save your **10 backup codes**. These are single-use codes shown only once, so store them somewhere safe (a password manager, printed paper). Each code has the format `XXXX-XXXX`. The **Backup codes** box offers **Copy codes**, **Download TXT** and **Print / PDF**.
|
||||
@@ -28,7 +28,7 @@ After entering your email and password, TREK shows a second prompt for your TOTP
|
||||
Go to **Settings → Account** and use the **Disable 2FA** form. You must provide both:
|
||||
|
||||
- Your current account **password**
|
||||
- A valid **TOTP code** from your authenticator app
|
||||
- A current **6-digit code** from your authenticator app, or an unused **backup code**
|
||||
|
||||
Disabling 2FA signs out every other session of your account: the second factor is what kept a stolen password out of them. The session you disabled it from stays signed in, since it just proved both the password and the code.
|
||||
|
||||
@@ -36,15 +36,15 @@ Disabling 2FA signs out every other session of your account: the second factor i
|
||||
|
||||
## Admin-enforced 2FA
|
||||
|
||||
An admin can require 2FA for all users. Before enabling this setting the admin must have secured their own account with either an authenticator app or a passkey — the server rejects the change otherwise with *Secure your own account with two-factor authentication or a passkey before requiring it for all users.*
|
||||
An admin can require 2FA for all users. Before enabling this setting the admin must have secured their own account with either an authenticator app or a passkey; the server rejects the change otherwise with *Secure your own account with two-factor authentication or a passkey before requiring it for all users.*
|
||||
|
||||
If the setting is active and your account has neither 2FA nor a passkey, any API request after login returns a 403 error and the client redirects you to **Settings → Account** with a prompt to complete 2FA setup. You cannot use the app until setup is complete. See [Admin-Permissions](Admin-Permissions).
|
||||
If the setting is active and your account has neither 2FA nor a passkey, any API request after login returns a 403 error and the client redirects you to **Settings → Account** with a prompt to complete 2FA setup. The 2FA card also carries a notice that your administrator requires it. You cannot use the app until setup is complete. See [Admin-Permissions](Admin-Permissions).
|
||||
|
||||
A user-verified **passkey** satisfies this policy the way a TOTP authenticator does: with at least one passkey on your account the API stops blocking you and you never need an authenticator app. That holds even if an admin later turns passkey login off again — an existing passkey keeps satisfying the policy. Real-time sync is the one exception: the WebSocket handshake accepts only TOTP, so a passkey-only account under this policy can use TREK normally but never receives live updates from other members. Nothing tells you — the client simply keeps retrying the connection.
|
||||
A user-verified **passkey** satisfies this policy the way a TOTP authenticator does: with at least one passkey on your account the API stops blocking you and you never need an authenticator app. That holds even if an admin later turns passkey login off again: an existing passkey keeps satisfying the policy. Real-time sync is the one exception: the WebSocket handshake accepts only TOTP, so a passkey-only account under this policy can use TREK normally but never receives live updates from other members. Nothing tells you; the client simply keeps retrying the connection.
|
||||
|
||||
Whether enrolling a passkey is a way *out* of the lockout depends on the instance. Passkey login is off by default (see [Passkeys](Passkeys)); where an admin has turned it on, the enrolment endpoints stay reachable while the rest of the API is blocked, so you can add a passkey from **Settings → Account** instead of setting up an authenticator app. Where it is off, TOTP setup is the only way to unblock yourself — or ask an admin to reset your 2FA.
|
||||
Whether enrolling a passkey is a way *out* of the lockout depends on the instance. Passkey login is off by default (see [Passkeys](Passkeys)); where an admin has turned it on, the enrolment endpoints stay reachable while the rest of the API is blocked, so you can add a passkey from **Settings → Account** instead of setting up an authenticator app. Where it is off, TOTP setup is the only way to unblock yourself, or ask an admin to reset your 2FA.
|
||||
|
||||
> **Admin:** You can clear a locked-out user's 2FA with `DELETE /api/admin/users/<id>/mfa` (admin session required; it refuses your own account). It also signs that user out of every session. The admin panel has no button for it: the user modal offers only **Reset passkeys**. See [Troubleshooting](Troubleshooting#locked-out-of-mfa--lost-authenticator).
|
||||
> **Admin:** You can clear a locked-out user's 2FA from **Admin → Users**: open the user and use **Reset 2FA** (it is not offered for your own account). It switches 2FA off for that user and signs them out of every session, and they can set it up again after logging in with their password. The same action is available as `DELETE /api/admin/users/<id>/mfa`. See [Troubleshooting](Troubleshooting#locked-out-of-mfa--lost-authenticator).
|
||||
|
||||
## Rate limits
|
||||
|
||||
@@ -63,4 +63,4 @@ The demo user account cannot enable or disable MFA.
|
||||
|
||||
---
|
||||
|
||||
**See also:** [Login-and-Registration](Login-and-Registration) · [Passkeys](Passkeys) · [Admin-Permissions](Admin-Permissions) · [Admin-Users-and-Invites](Admin-Users-and-Invites) · [User-Settings](User-Settings)
|
||||
**See also:** [Login-and-Registration](Login-and-Registration), [Passkeys](Passkeys), [Admin-Permissions](Admin-Permissions), [Admin-Users-and-Invites](Admin-Users-and-Invites), [User-Settings](User-Settings)
|
||||
|
||||
+13
-6
@@ -11,16 +11,16 @@ Back up your data first. Go to Admin Panel → **Backup** and create a manual ba
|
||||
| Tag | Example | Behavior |
|
||||
|---|---|---|
|
||||
| `latest` | `mauriceboe/trek:latest` | Always the newest release across all major versions |
|
||||
| Major version | `mauriceboe/trek:4` | Latest release pinned to that major version |
|
||||
| Major version | `mauriceboe/trek:5` | Latest release pinned to that major version |
|
||||
| Minor version | `mauriceboe/trek:5.0` | Latest patch of that minor version; never moves to the next minor. Published from 5.0.0 on: 4.x releases have no minor tag, so pin those by major or full version |
|
||||
| Full version | `mauriceboe/trek:4.0.0` | Exact release; never changes |
|
||||
| Full version | `mauriceboe/trek:5.0.0` | Exact release; never changes |
|
||||
| Prerelease | `mauriceboe/trek:latest-pre` | The newest test build of the next version. For trying it out on a copy of your data, not for the instance you rely on |
|
||||
|
||||
Use `latest` or a major-version tag if you want updates on each redeploy. A minor-version tag still brings fixes but waits for you to move to the next minor, which is where larger changes and database upgrades usually land. Use a full version tag for explicit control: update by changing the tag, not by re-pulling.
|
||||
|
||||
## Docker Compose (Recommended)
|
||||
|
||||
**`latest` or major-version tag:**
|
||||
**`latest`, major-version or minor-version tag:**
|
||||
|
||||
```bash
|
||||
docker compose pull && docker compose up -d
|
||||
@@ -30,7 +30,7 @@ This pulls the newest matching image and recreates the container with your exist
|
||||
|
||||
**Pinned full-version tag:**
|
||||
|
||||
Edit `docker-compose.yml`, update the tag in the `image:` line (e.g. `4.0.0` → `4.0.1`), then redeploy:
|
||||
Edit `docker-compose.yml`, update the tag in the `image:` line (e.g. `5.0.0` → `5.0.1`), then redeploy:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
@@ -122,6 +122,13 @@ Two things change with 4.3.1. Neither needs a manual step on Docker, but they ar
|
||||
|
||||
## Upgrading to 5.0
|
||||
|
||||
5.0 is a large release. Apart from the point below about the Places API, updating needs no manual step on any install method: migrations run at startup, and TREK copies the database first (see [Database Migrations](#database-migrations)).
|
||||
|
||||
- **A new look, and a phone interface of its own.** Dialogs are redesigned and the phone gets its own screens instead of a squeezed desktop layout. Open apps switch over after **Reload page** (see [Open apps after an update](#open-apps-after-an-update)).
|
||||
- **New features.** Tours, TREK Studio for journeys, the AI Assistant addon, notifications in an inbox, trip settings and a Help Center inside the app. The addons are switched on or off under **Admin → Addons**; see [Addons-Overview](Addons-Overview) and [Help-Center](Help-Center).
|
||||
- **AI assistant secrets are encrypted** with your `ENCRYPTION_KEY` like the other stored secrets, and the connections need no action on update. A key rotation covers them; see [Encryption-Key-Rotation](Encryption-Key-Rotation).
|
||||
- **Web Push needs no VAPID setup.** TREK generates its key pair on first start and keeps it in the database. See [Environment-Variables](Environment-Variables#web-push).
|
||||
- **Remove any `APP_VERSION` override.** The version now comes from the image itself. A leftover `APP_VERSION=` line in your compose file, `.env` or Portainer stack only gets in the way.
|
||||
- **Tours asks the TREK Places API first.** The grades, surfaces and kinds of way under a planned tour and the horse routes around the map are read from `https://places.liketrek.com`, and the Overpass mirrors are asked only when it has no answer. An `OVERPASS_URL` pointed at an internal Overpass therefore no longer keeps these lookups inside your network: set `TREK_PLACES_ENABLED=false`, or point `TREK_PLACES_URL` at a copy you run yourself. [TREK-Places-API](TREK-Places-API#what-leaves-your-instance) lists what is sent.
|
||||
|
||||
## Encryption Key Note
|
||||
@@ -153,11 +160,11 @@ journalctl -u trek -n 50
|
||||
|
||||
Open the **Stacks** list, click the TREK stack, then click **Redeploy**.
|
||||
|
||||
**`latest` or major-version tag** — enable the **Re-pull image and redeploy** switch before confirming. Portainer pulls the newest matching image and recreates the container.
|
||||
**`latest`, major-version or minor-version tag**: enable the **Re-pull image and redeploy** switch before confirming. Portainer pulls the newest matching image and recreates the container.
|
||||
|
||||

|
||||
|
||||
**Pinned full-version tag** (e.g. `4.0.0`) — edit the stack, update the tag in the `image:` line, then click **Update the stack**. No re-pull switch needed; the tag change forces a fresh pull.
|
||||
**Pinned full-version tag** (e.g. `5.0.0`), edit the stack, update the tag in the `image:` line, then click **Update the stack**. No re-pull switch needed; the tag change forces a fresh pull.
|
||||
|
||||

|
||||
|
||||
|
||||
+44
-39
@@ -6,7 +6,7 @@ The Settings page lets you personalise TREK: appearance, maps, notifications, of
|
||||
|
||||
Open the user menu in the top navigation bar and select **Settings**. The page opens on the **General** tab by default.
|
||||
|
||||
On desktop the tabs are a side navigation on the left and each tab is a set of cards: one card per group of settings, with a switch, segmented control or dropdown at the end of each row. Anything that cannot be undone (deleting your account, removing a passkey, clearing the offline cache) asks for confirmation in TREK's own dialog. On a phone the same settings open as the mobile settings screens.
|
||||
On desktop the tabs are a side navigation on the left and each tab is a set of cards: one card per group of settings, with a switch, segmented control or dropdown at the end of each row. Anything that cannot be undone (deleting your account, removing a passkey, clearing the offline cache) asks for confirmation in TREK's own dialog. On a phone the same settings open as their own mobile screens: General, Appearance, Map, Notifications, Integrations, Offline, Plugins, Account and About, plus a separate screen for MCP.
|
||||
|
||||
A link can open a tab directly with `?tab=`, for example `/settings?tab=notifications`.
|
||||
|
||||
@@ -19,11 +19,11 @@ If your account requires MFA setup, TREK redirects you directly to the **Account
|
||||
| General | Start page and start tab, display currency, language, place names, temperature unit, distance unit, time format, week start, the map app places open in, date first in day headings, booking route labels, always show booking routes, compact markers for unplanned places, explore places on the map, blur booking codes, and optimize route from accommodation | Always |
|
||||
| Appearance | Color mode, color scheme / accent, readability (transparency, reduce motion, density, text size), and which widgets appear on your dashboard | Always |
|
||||
| Map | Map provider (Leaflet, Mapbox GL, or MapLibre GL), tile presets, map style and Mapbox token, 3D buildings, high-quality mode | Always |
|
||||
| Notifications | Email, webhook, ntfy, push and in-app notification preferences, plus switching push on or off for this device (every device is switched on separately) | Always |
|
||||
| Integrations | Photo providers (Immich, Synology, etc.), the AirTrail connection, the Dawarich connection, your own AI parsing model, public API keys, and MCP OAuth clients / API tokens | Always on desktop, because API keys need no addon. In the phone layout only when a photo provider (Immich or Synology Photos), MCP, AirTrail, AI Parsing or Dawarich is enabled |
|
||||
| Notifications | Email, webhook, ntfy, push and in-app notification preferences, plus switching push on or off for this device (every device is switched on separately). The webhook and ntfy forms have a test button, and an event your administrator turned off for everyone shows a lock | Always |
|
||||
| Integrations | Photo providers (Immich, Synology, etc.), the AirTrail, Dawarich and wanderer connections, your AI connection for the assistant and AI parsing, public API keys, and MCP OAuth clients / API tokens | Always on desktop, because API keys need no addon. In the phone layout only when a photo provider (Immich or Synology Photos), MCP, AirTrail, AI Parsing, the AI Assistant or Dawarich is enabled |
|
||||
| Plugins | Per-user settings for installed plugins | Only when at least one plugin is installed |
|
||||
| Offline | Cached trips, pending changes, re-sync and clear cache | Always |
|
||||
| Account | Username, email, password, MFA (TOTP + backup codes), passkeys, avatar, delete account | Always |
|
||||
| Account | One card each for your profile (avatar, username, email, delete account), Change Password, two-factor authentication (TOTP + backup codes) and passkeys | Always |
|
||||
| About | App version, links to Ko-fi / Buy Me a Coffee / Discord / GitHub (bug reports, feature requests) / Wiki | Only when version metadata is available |
|
||||
|
||||
## General tab
|
||||
@@ -32,36 +32,36 @@ The General tab controls the following preferences, all saved immediately on cha
|
||||
|
||||
**Startup**
|
||||
|
||||
- **Start page** — open TREK on the dashboard (the default) or straight in your active trip.
|
||||
- **Start tab** — which planner tab that trip opens on, e.g. Costs for entering expenses on the road.
|
||||
- **Start page**: open TREK on the dashboard (the default) or straight in your active trip.
|
||||
- **Start tab**: which planner tab that trip opens on, e.g. Costs for entering expenses on the road.
|
||||
|
||||
**Language & region**
|
||||
|
||||
- **Display currency**: your display currency; **Trip currency** (the default) shows each trip in its own. See [Currencies](Currencies).
|
||||
- **Language** — displayed as a button grid on desktop and a dropdown on mobile.
|
||||
- **Language**: displayed as a button grid on desktop and a dropdown on mobile.
|
||||
- **Place names**: the language place search, suggestions and addresses answer in. **Same as the app** follows the language above; picking another one keeps the interface as it is and asks for place names in that language. Where a place has no name in it, the local name is shown.
|
||||
- **Temperature unit** — Celsius (°C) or Fahrenheit (°F).
|
||||
- **Distance unit** — Metric (km) or Imperial (mi).
|
||||
- **Time format** — 24h (14:30) or 12h (2:30 PM).
|
||||
- **Temperature unit**: Celsius (°C) or Fahrenheit (°F).
|
||||
- **Distance unit**: Metric (km) or Imperial (mi).
|
||||
- **Time format**: 24h (14:30) or 12h (2:30 PM).
|
||||
- **Week starts on**: Monday (the default), Sunday or Saturday: the first column of every date picker. See [Display-Settings](Display-Settings#week-starts-on).
|
||||
|
||||
**Travel & map**
|
||||
|
||||
- **Open places in**: the map app the navigate buttons open straight away, or **Ask every time** (the default) for the full list.
|
||||
- **Date first in day headings**: lead each day in the day plan with its date and show "Day 1" or the day's title next to it.
|
||||
- **Booking route labels** — show or hide station / airport names on booking route endpoint markers.
|
||||
- **Always show booking routes** — draw the route for every flight, train and other booking on the map automatically, instead of switching it on per item.
|
||||
- **Booking route labels**: show or hide station / airport names on booking route endpoint markers.
|
||||
- **Always show booking routes**: draw the route for every flight, train and other booking on the map automatically, instead of switching it on per item.
|
||||
- **Compact markers for unplanned places**: places not planned into any day show as small markers without a photo.
|
||||
- **Explore places on the map** — show a POI category pill on the trip map for finding nearby places from OpenStreetMap.
|
||||
- **Blur booking codes** — blur confirmation codes and reference numbers (useful when screen-sharing).
|
||||
- **Optimize route from accommodation** — when optimizing a day, start the route at the hotel you wake up in and end it at the one you check into that evening.
|
||||
- **Explore places on the map**: show a POI category pill on the trip map for finding nearby places from OpenStreetMap.
|
||||
- **Blur booking codes**: blur confirmation codes and reference numbers (useful when screen-sharing).
|
||||
- **Optimize route from accommodation**: when optimizing a day, start the route at the hotel you wake up in and end it at the one you check into that evening.
|
||||
|
||||
## Appearance tab
|
||||
|
||||
- **Color mode** — Light, Dark, or Auto (follows your operating system / browser preference).
|
||||
- **Color scheme** — a preset accent, or **Custom** with your own light and dark accent colors.
|
||||
- **Readability** *(Experimental)* — transparency, reduce motion, density, and text size.
|
||||
- **Dashboard widgets** — which widgets appear on the dashboard, independently for desktop and mobile.
|
||||
- **Color mode**: Light, Dark, or Auto (follows your operating system / browser preference).
|
||||
- **Color scheme**: a preset accent, or **Custom** with your own light and dark accent colors.
|
||||
- **Readability** *(Experimental)*: transparency, reduce motion, density, and text size.
|
||||
- **Dashboard widgets**: which widgets appear on the dashboard, independently for desktop and mobile.
|
||||
|
||||
See [Appearance-Settings](Appearance-Settings) for the detail.
|
||||
|
||||
@@ -69,48 +69,50 @@ See [Appearance-Settings](Appearance-Settings) for the detail.
|
||||
|
||||
The Map tab requires an explicit **Save** action after making changes.
|
||||
|
||||
**Provider** — choose between:
|
||||
**Provider**: choose between:
|
||||
|
||||
- **Leaflet** — The default. Pick from built-in presets (OpenStreetMap, OpenStreetMap DE, OpenFreeMap Positron/Bright, CartoDB Light/Dark, Stadia Smooth, Amap (高德地图) road and satellite) or enter a custom tile URL template. The Amap presets draw in the offset GCJ-02 datum, which TREK corrects for; see [Map-Settings](Map-Settings). OpenFreeMap Positron is what an unconfigured map draws; the CartoDB presets need an API key.
|
||||
- **Mapbox GL** (Experimental) — Vector tiles with 3D buildings and terrain. Requires a public Mapbox access token (`pk.*`). Supports built-in style presets (Mapbox Standard, Standard Satellite, Streets, Outdoors, Light, Dark, Satellite, Satellite Streets, Navigation Day, Navigation Night) or a custom `mapbox://styles/USER/ID` URL. Additional options:
|
||||
- **3D Buildings & Terrain** — Pitch and real 3D building extrusions (works on every style including satellite).
|
||||
- **High Quality Mode** (Experimental) — Antialiasing + globe projection for sharper edges. May impact performance on lower-end devices.
|
||||
- **MapLibre GL** — Vector tiles from **OpenFreeMap**, and the reason to pick it over Mapbox GL: **it needs no access token**. Styles are OpenFreeMap Liberty, Bright, and Positron, or any `https://tiles.openfreemap.org/…` style URL. The 3D and high-quality toggles are Mapbox-only and are not shown here.
|
||||
- **Leaflet**: The default. Pick from built-in presets (OpenStreetMap, OpenStreetMap DE, OpenFreeMap Positron/Bright, CartoDB Light/Dark, Stadia Smooth, Amap (高德地图) road and satellite) or enter a custom tile URL template. The Amap presets draw in the offset GCJ-02 datum, which TREK corrects for; see [Map-Settings](Map-Settings). OpenFreeMap Positron is what an unconfigured map draws; the CartoDB presets need an API key.
|
||||
- **Mapbox GL** (Experimental): Vector tiles with 3D buildings and terrain. Requires a public Mapbox access token (`pk.*`). Supports built-in style presets (Mapbox Standard, Standard Satellite, Streets, Outdoors, Light, Dark, Satellite, Satellite Streets, Navigation Day, Navigation Night) or a custom `mapbox://styles/USER/ID` URL. Additional options:
|
||||
- **3D Buildings & Terrain**: Pitch and real 3D building extrusions (works on every style including satellite).
|
||||
- **High Quality Mode** (Experimental): Antialiasing + globe projection for sharper edges. May impact performance on lower-end devices.
|
||||
- **MapLibre GL**: Vector tiles from **OpenFreeMap**, and the reason to pick it over Mapbox GL: **it needs no access token**. Styles are OpenFreeMap Liberty, Bright, and Positron, or any `https://tiles.openfreemap.org/…` style URL. The 3D and high-quality toggles are Mapbox-only and are not shown here.
|
||||
|
||||
Each GL provider keeps its own saved style, so switching between Mapbox GL and MapLibre GL never overwrites the other one's choice.
|
||||
|
||||
> Atlas always uses Leaflet regardless of the provider setting.
|
||||
|
||||
**Opening view** — there is no default map center or zoom setting. Every map frames itself on the places it is showing. See [Map-Settings](Map-Settings).
|
||||
**Opening view**: there is no default map center or zoom setting. Every map frames itself on the places it is showing. See [Map-Settings](Map-Settings).
|
||||
|
||||
## Account tab summary
|
||||
|
||||

|
||||
|
||||
The Account tab lets you:
|
||||
The Account tab is a stack of separate cards:
|
||||
|
||||
- Edit your **username** and **email address**.
|
||||
- Change your **password** (hidden when the server runs in OIDC-only mode, see [OIDC-SSO](OIDC-SSO)). The password rules are shown as a checklist under the new password and tick off as you type.
|
||||
- Set up or disable **two-factor authentication** (TOTP). After enabling MFA, backup codes are shown once and can be copied, downloaded, or printed. See [Two-Factor-Authentication](Two-Factor-Authentication).
|
||||
- Manage your **passkeys** — add one (confirm your password, then follow your device prompt), rename it, or remove it. **Add a passkey** only appears when the instance has passkeys switched on and a WebAuthn domain resolves; an existing passkey stays listed either way so you can always clean it up. See [Passkeys](Passkeys).
|
||||
- Upload or remove your **profile avatar**.
|
||||
- **Delete your account** (irreversible; blocked if you are the only admin).
|
||||
- **Account**: your **profile avatar** (upload or remove), a role badge (admin or user), and your **username** and **email address**. Edits are saved with **Save Profile**. **Delete account** is irreversible and is blocked if you are the only admin.
|
||||
- **Change Password**: current password, new password and confirmation. This card is hidden when the server runs in OIDC-only mode, see [OIDC-SSO](OIDC-SSO). The password rules are shown as a checklist under the new password and tick off as you type.
|
||||
- **Two-factor authentication (2FA)**: set up or disable TOTP. After enabling it, backup codes are shown once and can be copied, downloaded, or printed. If your administrator requires 2FA, a notice at the top of the card says so. See [Two-Factor-Authentication](Two-Factor-Authentication).
|
||||
- **Passkeys**: add one (confirm your password, then follow your device prompt), rename it, or remove it. **Add a passkey** only appears when the instance has passkeys switched on and a WebAuthn domain resolves; an existing passkey stays listed either way so you can always clean it up. See [Passkeys](Passkeys).
|
||||
|
||||
On the demo instance, changing the password and deleting the account are refused, the 2FA card says it is not available in demo mode and the Passkeys card is hidden, see [Demo-Mode](Demo-Mode).
|
||||
|
||||
If your account was linked via SSO, an **SSO** badge appears next to your role and the OIDC issuer domain is shown below it.
|
||||
|
||||
## Integrations tab
|
||||
|
||||
On desktop the Integrations tab is always there, because **API Keys** need no addon. Every other section appears with its own addon, so the tab holds only what your instance actually runs. The phone layout has no API Keys section and shows the tab only when a **photo provider** (Immich or Synology Photos), **MCP**, **AirTrail**, **AI Parsing** or **Dawarich** is enabled:
|
||||
On desktop the Integrations tab is always there, because **API Keys** need no addon. Every other section appears with its own addon, so the tab holds only what your instance actually runs. The phone layout has no API Keys section and shows the tab only when a **photo provider** (Immich or Synology Photos), **MCP**, **AirTrail**, **AI Parsing**, the **AI Assistant** or **Dawarich** is enabled:
|
||||
|
||||
- **Photo Providers** (only when a photo provider is enabled) — Configure Immich, Synology Photos, and other photo integrations. One card appears per enabled provider.
|
||||
- **AirTrail** (only when the AirTrail addon is enabled) — Instance URL and API key for your self-hosted AirTrail, plus a self-signed-certificate switch and a **Write changes back to AirTrail** toggle (off by default: AirTrail is the source of truth and TREK only reads from it). **Test connection** reports how many flights it can see. The key is stored encrypted and never prefilled — leaving the field blank keeps the stored one.
|
||||
- **Photo Providers** (only when a photo provider is enabled): Configure Immich, Synology Photos, and other photo integrations. One card appears per enabled provider.
|
||||
- **AirTrail** (only when the AirTrail addon is enabled): Instance URL and API key for your self-hosted AirTrail, plus a self-signed-certificate switch and a **Write changes back to AirTrail** toggle (off by default: AirTrail is the source of truth and TREK only reads from it). **Test connection** reports how many flights it can see. The key is stored encrypted and never prefilled; leaving the field blank keeps the stored one.
|
||||
- **Dawarich** (only when the Dawarich addon is enabled): the **Instance address** and **API key** of your own Dawarich, a self-signed-certificate switch, **Test connection** and **Disconnect**. The key is stored encrypted and never handed back. See [Dawarich](Dawarich).
|
||||
- **AI parsing** (only when the AI Parsing addon is enabled): the provider (OpenAI or Anthropic), model and API key used to extract bookings from your uploaded files, plus **Model reads images**. Turn that on for a model that reads images: a photo of a ticket can then be imported as a booking, and a receipt scanned in Costs. This is the per-user fallback: it only takes effect when your administrator has not configured a model for the whole instance. A local Ollama endpoint is not offered here; that is set up once, instance-wide, in the admin settings (#1772). See [AI-Booking-Import](AI-Booking-Import#photos) and [Budget-Tracking](Budget-Tracking#scanning-a-receipt).
|
||||
- **wanderer** (only when your administrator has switched wanderer on under Tours): the **Instance URL** and **API token** of your own wanderer, a self-signed-certificate switch, **Test connection** (it reports how many trails you can import) and **Disconnect**. The token stays on the server and is never shown again. It feeds the trail import in [Tours](Tours).
|
||||
- **AI assistant** (only when the AI Assistant or AI Parsing addon is enabled; the card is titled **AI parsing** when only parsing is on): your AI connection. Connect a provider with a sign-in (ChatGPT, OpenRouter) or by pasting an API key, pick a **Model** (only models that can use tools are listed), and **Sign out** or **Disconnect** again. When your administrator provides a connection for everyone, the card says so and shows how much of your daily allowance is used. The same connection reads the bookings you import with AI parsing.
|
||||
- **AI parsing** (shown only to someone who saved a personal model before the shared connection existed): the provider (OpenAI or Anthropic), model and API key used to extract bookings from your uploaded files, plus **Model reads images**. Turn that on for a model that reads images: a photo of a ticket can then be imported as a booking, and a receipt scanned in Costs. This is the per-user fallback: it only takes effect when your administrator has not configured a model for the whole instance. A local Ollama endpoint is not offered here; that is set up once, instance-wide, in the admin settings (#1772). See [AI-Booking-Import](AI-Booking-Import#photos) and [Budget-Tracking](Budget-Tracking#scanning-a-receipt).
|
||||
- **API Keys** (always, desktop layout only): read-only keys for the public API, so other software can read your trips. **Create key** names the key and lets you narrow **what this key may read** to single areas; the key is shown once. See [Public-API](Public-API).
|
||||
- **MCP section** (only when MCP addon is enabled):
|
||||
- Shows the MCP server endpoint URL.
|
||||
- **OAuth Clients** sub-tab — Create and manage OAuth 2.1 clients (with redirect URIs and scopes). Quick-fill presets are provided for Claude.ai, Claude Desktop, Cursor, VS Code, Windsurf, and Zed. Active OAuth sessions can be viewed and revoked here.
|
||||
- **API Tokens** sub-tab (Deprecated) — Create and manage personal bearer tokens for direct MCP access.
|
||||
- **OAuth Clients** sub-tab: create and manage OAuth 2.1 clients (with redirect URIs and scopes). Quick-fill presets are provided for Claude.ai, Claude Desktop, Cursor, VS Code, Windsurf, and Zed. Active OAuth sessions can be viewed and revoked here.
|
||||
- **API Tokens** sub-tab (Deprecated): create and manage personal bearer tokens for direct MCP access.
|
||||
|
||||
## See also
|
||||
|
||||
@@ -121,3 +123,6 @@ On desktop the Integrations tab is always there, because **API Keys** need no ad
|
||||
- [Offline-Mode-and-PWA](Offline-Mode-and-PWA)
|
||||
- [Two-Factor-Authentication](Two-Factor-Authentication)
|
||||
- [Languages](Languages)
|
||||
- [AI-Connections](AI-Connections)
|
||||
- [Wanderer](Wanderer)
|
||||
- [Mobile-App](Mobile-App)
|
||||
|
||||
+2
-2
@@ -20,9 +20,9 @@ Vacay is organised by year. You can have multiple years active at once and navig
|
||||
|
||||
For each year, your entitlement panel shows:
|
||||
|
||||
- **Entitlement days** — your vacation allowance for that year (editable inline by clicking the field).
|
||||
- **Days**: your vacation allowance for that year (editable inline by clicking the field).
|
||||
- **Used** — days you have logged on the calendar.
|
||||
- **Remaining** — entitlement plus any carried-over days, minus used days.
|
||||
- **Left**: entitlement plus any carried-over days, minus used days.
|
||||
|
||||
**Carry-over** — when `carry_over_enabled` is on, unused days from the previous period are automatically added to the next one's total. When you toggle this setting, the carry-over amount is recalculated across all existing year records. Turn it off to zero out all carry-over balances.
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
# wanderer
|
||||
|
||||
[wanderer](https://wanderer.to) is a self-hosted trail library: you keep your hikes, rides and routes there with their GPX files, photos and descriptions. TREK can read your own wanderer instance and bring a trail into a trip as a [tour](Tours), ready to put on a day. Each person connects their own instance; TREK only reads from it and never writes anything back.
|
||||
|
||||
> **Admin:** wanderer is a switch inside the **Tours** addon. In **Admin → Addons**, open the Tours tile and turn on **wanderer** (*Users can connect their own wanderer instance and import its trails as tours*). Without it the connection section and the import button are not shown, and a request says *Your admin has not enabled wanderer for Tours.* See [Admin-Addons](Admin-Addons).
|
||||
|
||||
## Connecting your instance
|
||||
|
||||
1. In wanderer, open **Settings → Account → API tokens** and create a token. A wanderer token starts with `wanderer_key_`.
|
||||
2. In TREK, open **Settings → Integrations** and find the **wanderer** section.
|
||||
3. Enter the **Instance URL**, the address of your wanderer, and paste the **API token**.
|
||||
4. Press **Test connection**. On success TREK says how many of your trails you can import, for example *Connected. You can import 12 of your trails.*
|
||||
5. Press **Save**. The section then reads **Connected**.
|
||||
|
||||
| Field | Notes |
|
||||
|---|---|
|
||||
| Instance URL | The address of wanderer itself. An answer that does not come from wanderer is refused with a hint to check the address. |
|
||||
| API token | Checked for the `wanderer_key_` prefix before it is sent. Stored encrypted on the server and never shown again; the field is never filled back in. |
|
||||
| Allow a self-signed certificate | *Only for an instance on your own network.* Relaxes the certificate check, nothing else. |
|
||||
|
||||
**Changing the host clears the token.** A token belongs to the instance that issued it, so pointing the connection at a different address drops the stored token; type it in again before you test or save.
|
||||
|
||||
**Disconnect** removes the address and the token. Tours you already imported stay in their trips exactly as they are.
|
||||
|
||||
### Instances on your own network
|
||||
|
||||
An address in a private network is accepted with a note: *If TREK cannot reach it, the administrator has to allow internal networks.* TREK reaches wanderer through the same strict guard as Immich, AirTrail and Dawarich, so an instance on your LAN needs `ALLOW_INTERNAL_NETWORK=true` on the TREK server. Until then a test answers *TREK may not reach that address.* See [Internal-Network-Access](Internal-Network-Access).
|
||||
|
||||
## Importing a trail
|
||||
|
||||
With a connection saved, the **Tours** tab of a trip shows a **wanderer** button next to **Plan new tour** while no tour is open. It opens **Your trails**:
|
||||
|
||||
- **Search trails** searches your own trails. Other people's trails, public ones included, are not offered: *Only your own wanderer trails can be imported.*
|
||||
- **Search this map area** limits the list to trails that reach into the part of the map you see.
|
||||
- Each trail shows its grade, time, distance and ascent, and whether it is **Public** or **Private** in wanderer. One you already imported into this trip is marked **In this trip**.
|
||||
- Clicked, a trail is drawn on the map with what its GPX file measures (**From the GPX file**) and its description. **Open in wanderer** opens it on your instance.
|
||||
- **Import into trip** copies it into the trip as a tour of its own, marked **wanderer**.
|
||||
|
||||
The import is a snapshot: *later changes in wanderer leave it as it is.* For a trail already in the trip the button reads **Open the tour**; when the trail changed in wanderer since, the preview says what changed (name, description, route) and **Import as new version** adds the new version beside the old one. A trail without a track or route cannot be imported, and neither can a trail file larger than 10 MB. Searching and importing need a connection.
|
||||
|
||||
More on working with the imported tour is on [Tours](Tours#importing-a-trail-from-wanderer).
|
||||
|
||||
## Checking the source of a tour
|
||||
|
||||
An imported tour's **Origin** names wanderer as its source, with the date wanderer gave as its last change. **Check source** asks wanderer whether the trail changed since the import. Nothing in the trip changes:
|
||||
|
||||
| Result | Meaning |
|
||||
|---|---|
|
||||
| **Unchanged since the import** | Nothing to do. |
|
||||
| **Changed on wanderer** | The name, description or route differ. **Import as new snapshot** brings in the current version beside the tour. |
|
||||
| **No longer available** | The trail is gone or can no longer be read with your connection. The tour stays as it was imported. |
|
||||
| **No wanderer connection** | Connect your wanderer under **Settings → Integrations** to check. |
|
||||
| **Another wanderer is connected** | Your connection points to a different instance than the one the tour came from. |
|
||||
| **Cannot compare** | The import carries nothing to compare against. |
|
||||
|
||||
## The background check
|
||||
|
||||
**Check my trails for changes** in the wanderer section sends you a notification when a trail you imported may have changed. It is off by default, and dimmed until you connect.
|
||||
|
||||
At most once a day, TREK reads the short record of each trail you imported, never its GPX file. It only tells you: whether a change comes in is up to you, through the tour's source check. What it can say:
|
||||
|
||||
- **May have changed**: wanderer changed the trail's time stamp. Only the source check shows whether its content differs.
|
||||
- **Changed**: wanderer's record shows another name or description.
|
||||
- **Not checkable**: TREK could not judge this trail, for example because it is out of reach.
|
||||
|
||||
The row shows when TREK last looked and how many hints are open; **Hints** opens **Hints on your trails**, where **Open the tour** goes to each one. The hints arrive as notifications too, under the event *wanderer: hints on your trails*, with a **View Tour** button; see [Notifications](Notifications).
|
||||
|
||||
When wanderer does not answer, the check waits longer after each failure and the row says **Paused until** a time. When wanderer refuses the token, the row reads **Token refused** and the check resumes once a connection test passes or a new token is saved.
|
||||
|
||||
## What TREK keeps
|
||||
|
||||
- Your instance address, the encrypted token and the switches. The token is encrypted with the server's encryption key, and the rotation script does not carry it over: after a key rotation, enter the token again. See [Encryption-Key-Rotation](Encryption-Key-Rotation).
|
||||
- The tours you imported, as ordinary tours of the trip, with where they came from.
|
||||
- For the background check, when it last looked and the open hints.
|
||||
|
||||
Connecting, changing and removing the connection, and switching the background check on or off, are recorded in the [Audit-Log](Audit-Log).
|
||||
|
||||
## See also
|
||||
|
||||
- [Tours](Tours)
|
||||
- [Internal-Network-Access](Internal-Network-Access)
|
||||
- [Notifications](Notifications)
|
||||
- [Admin-Addons](Admin-Addons)
|
||||
- [Dawarich](Dawarich)
|
||||
@@ -39,4 +39,4 @@ Temperature follows **Temperature Unit** under Settings > General > Language & r
|
||||
|
||||
The reading on the day cards is kept in `sessionStorage` for the length of your browser session, so moving between days does not ask for the same weather again. A cached forecast older than an hour is shown at once and refreshed in the background. The day details fetch the detailed forecast each time they open.
|
||||
|
||||
**See also:** [Day-Plans-and-Notes](Day-Plans-and-Notes) · [Display-Settings](Display-Settings) · [Road-Trip](Road-Trip#weather-warnings-and-disaster-alerts)
|
||||
**See also:** [Day-Plans-and-Notes](Day-Plans-and-Notes), [Display-Settings](Display-Settings), [Road-Trip](Road-Trip#weather-warnings-and-disaster-alerts)
|
||||
|
||||
+47
-34
@@ -11,36 +11,50 @@
|
||||
- [[Environment Variables|Environment-Variables]]
|
||||
- [[Updating]]
|
||||
|
||||
## Account & Auth
|
||||
## Account & Security
|
||||
- [[Login and Registration|Login-and-Registration]]
|
||||
- [[OIDC SSO|OIDC-SSO]]
|
||||
- [[Two-Factor Authentication|Two-Factor-Authentication]]
|
||||
- [[Passkeys]]
|
||||
- [[Password Reset|Password-Reset]]
|
||||
|
||||
## Using TREK
|
||||
- [[My Trips Dashboard|My-Trips-Dashboard]]
|
||||
- [[Dashboard Widgets|Dashboard-Widgets]]
|
||||
- [[Notifications Inbox|Notifications-Inbox]]
|
||||
- [[TREK on a Phone|Mobile-App]]
|
||||
- [[Offline Mode and PWA|Offline-Mode-and-PWA]]
|
||||
- [[Languages]]
|
||||
|
||||
## Settings
|
||||
- [[User Settings|User-Settings]]
|
||||
- [[General Settings|Display-Settings]]
|
||||
- [[Appearance Settings|Appearance-Settings]]
|
||||
- [[Map Settings|Map-Settings]]
|
||||
- [[Notifications]]
|
||||
- [[Offline Mode and PWA|Offline-Mode-and-PWA]]
|
||||
- [[Languages]]
|
||||
|
||||
## Planning Trips
|
||||
- [[My Trips Dashboard|My-Trips-Dashboard]]
|
||||
- [[Creating a Trip|Creating-a-Trip]]
|
||||
- [[Trip Settings|Trip-Settings]]
|
||||
- [[Trip Members and Sharing|Trip-Members-and-Sharing]]
|
||||
- [[Invite Links|Invite-Links]]
|
||||
- [[Public Share Links|Public-Share-Links]]
|
||||
- [[Trip Planner Overview|Trip-Planner-Overview]]
|
||||
- [[Places and Search|Places-and-Search]]
|
||||
- [[TREK Places API|TREK-Places-API]]
|
||||
- [[Day Plans and Notes|Day-Plans-and-Notes]]
|
||||
- [[Map Features|Map-Features]]
|
||||
- [[Tours|Tours]]
|
||||
- [[Route Optimization|Route-Optimization]]
|
||||
- [[Weather Forecasts|Weather-Forecasts]]
|
||||
- [[Tags and Categories|Tags-and-Categories]]
|
||||
- [[Calendar Feeds|Calendar-Feeds]]
|
||||
|
||||
## Tours and Road Trips
|
||||
- [[Tours|Tours]]
|
||||
- [[wanderer|Wanderer]]
|
||||
- [[Road Trip|Road-Trip]]
|
||||
|
||||
## Travel Management
|
||||
- [[Reservations and Bookings|Reservations-and-Bookings]]
|
||||
- [[AI Booking Import|AI-Booking-Import]]
|
||||
- [[Transport: Flights, Trains, Cars|Transport-Flights-Trains-Cars]]
|
||||
- [[Accommodations]]
|
||||
- [[Costs|Budget-Tracking]]
|
||||
@@ -50,11 +64,6 @@
|
||||
- [[Todos and Tasks|Todos-and-Tasks]]
|
||||
- [[Documents and Files|Documents-and-Files]]
|
||||
- [[Document Sync|Document-Sync]]
|
||||
- [[Tags and Categories|Tags-and-Categories]]
|
||||
- [[Calendar Feeds|Calendar-Feeds]]
|
||||
|
||||
## Photos & Media
|
||||
- [[Photo Providers|Photo-Providers]]
|
||||
- [[PDF Export|PDF-Export]]
|
||||
|
||||
## Collaboration
|
||||
@@ -63,17 +72,33 @@
|
||||
- [[Collab Notes|Collab-Notes]]
|
||||
- [[Collab Polls|Collab-Polls]]
|
||||
- [[What's Next Widget|Whats-Next-Widget]]
|
||||
- [[Public Share Links|Public-Share-Links]]
|
||||
- [[Invite Links|Invite-Links]]
|
||||
|
||||
## Journey and Studio
|
||||
- [[Journey Journal|Journey-Journal]]
|
||||
- [[TREK Studio|TREK-Studio]]
|
||||
- [[Photo Providers|Photo-Providers]]
|
||||
|
||||
## Addons
|
||||
- [[Addons Overview|Addons-Overview]]
|
||||
- [[Vacay]]
|
||||
- [[Atlas]]
|
||||
- [[Journey Journal|Journey-Journal]]
|
||||
- [[Collections]]
|
||||
- [[Road Trip|Road-Trip]]
|
||||
- [[Dashboard Widgets|Dashboard-Widgets]]
|
||||
|
||||
## AI and MCP
|
||||
- [[AI Assistant|AI-Assistant]]
|
||||
- [[AI Connections|AI-Connections]]
|
||||
- [[AI Booking Import|AI-Booking-Import]]
|
||||
- [[MCP Overview|MCP-Overview]]
|
||||
- [[MCP Setup|MCP-Setup]]
|
||||
- [[MCP Scopes|MCP-Scopes]]
|
||||
- [[MCP Tools and Resources|MCP-Tools-and-Resources]]
|
||||
- [[MCP Addon Tools|MCP-Addon-Tools]]
|
||||
- [[MCP Prompts|MCP-Prompts]]
|
||||
|
||||
## Integrations
|
||||
- [[Dawarich]]
|
||||
- [[Public API|Public-API]]
|
||||
- [[TREK Places API|TREK-Places-API]]
|
||||
|
||||
## Plugins
|
||||
- [[Plugins Overview|Plugins]]
|
||||
@@ -82,39 +107,27 @@
|
||||
- [[Plugin Permissions|Plugin-Permissions]]
|
||||
- [[Publishing a Plugin|Plugin-Publishing]]
|
||||
|
||||
## Integrations
|
||||
- [[Public API|Public-API]]
|
||||
- [[Dawarich]]
|
||||
|
||||
## AI / MCP
|
||||
- [[MCP Overview|MCP-Overview]]
|
||||
- [[MCP Setup|MCP-Setup]]
|
||||
- [[MCP Scopes|MCP-Scopes]]
|
||||
- [[MCP Tools and Resources|MCP-Tools-and-Resources]]
|
||||
- [[MCP Addon Tools|MCP-Addon-Tools]]
|
||||
- [[MCP Prompts|MCP-Prompts]]
|
||||
|
||||
## Admin Panel
|
||||
- [[Admin Panel Overview|Admin-Panel-Overview]]
|
||||
- [[Admin: Users and Invites|Admin-Users-and-Invites]]
|
||||
- [[Admin: Permissions|Admin-Permissions]]
|
||||
- [[Admin: User Defaults|Admin-User-Defaults]]
|
||||
- [[Admin: Settings|Admin-Settings]]
|
||||
- [[Admin: Addons|Admin-Addons]]
|
||||
- [[Admin: Categories|Admin-Categories]]
|
||||
- [[Admin: Packing Templates|Admin-Packing-Templates]]
|
||||
- [[Admin: Permissions|Admin-Permissions]]
|
||||
- [[Admin: Settings|Admin-Settings]]
|
||||
- [[Admin: Addons|Admin-Addons]]
|
||||
- [[Admin: Plugins|Admin-Plugins]]
|
||||
- [[Admin: Storage|Admin-Storage]]
|
||||
- [[Admin: Notifications|Admin-Notifications]]
|
||||
- [[Admin: MCP Tokens|Admin-MCP-Tokens]]
|
||||
- [[Admin: GitHub Releases|Admin-GitHub-Releases]]
|
||||
- [[Backups]]
|
||||
- [[Audit Log|Audit-Log]]
|
||||
|
||||
## Operations
|
||||
- [[Backups]]
|
||||
- [[Demo Mode|Demo-Mode]]
|
||||
- [[Encryption Key Rotation|Encryption-Key-Rotation]]
|
||||
- [[Internal Network Access|Internal-Network-Access]]
|
||||
- [[Audit Log|Audit-Log]]
|
||||
- [[Security Hardening|Security-Hardening]]
|
||||
|
||||
## Help
|
||||
|
||||
Reference in New Issue
Block a user