mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 05:26:47 +00:00
fix: follow-ups from the review of the price, Immich, moving day and import fixes
Saved place price (#2471) - A price above zero that would be left without a currency is refused with a 400, over REST and through update_collection_place alike. A list has no base currency, so such an amount was read in each viewer's own default currency and went into a trip as the trip's. A price sent alone keeps the stored currency, and a zero price or clearing both fields still goes through. The check sits in the service because the MCP tool spreads the contract's shape, where a refine would never arrive. - An older row that holds an amount without a currency shows it as a bare number instead of in the viewer's own currency. - The Hungarian hint uses the informal register of its file, which is now prettier clean. Immich certificate switch (#2475) - The switch trusts one server. Saving a different URL without sending it turns it off; saving the same URL keeps it as before. The wiki says so. Moving day (#2476) - Google Maps and CoMaps are left out only when there is nothing to hand over. A day with a single stop opens it as a pin again, on the desktop and on the phone, as it did before. - Desktop: a moving day whose flight or train has no stations shows no route tools, since there is nothing left to draw. With stations they stay. - Phone: the drive between two stays on a day without stops or bookings shows once at the top instead of again at the bottom. - The export helpers take the carrier flags as one object instead of two booleans in a row. Import card (#2477) - The success and error marks use the theme tokens. - The e2e test names its upload with a made-up booking number. Tests: COLLECTIONS-SVC-132 and 133, COLLECTIONS-E2E-088, update_collection_place with a price and no currency, FE-COMP-COLEXTRAS-013 (011 adjusted), IMMICH-TLS-010, IMMICH-103 extended, FE-PLANNER-DAYPLAN-222 adjusted and 224, FE-MOB-PLTL-051, FE-MOB-PTLM-047, FE-W4BGT-023 and 024 check the mark colours.
This commit is contained in:
@@ -995,6 +995,7 @@ export class CollectionsService {
|
||||
async updatePlace(userId: number, placeId: number, body: CollectionPlaceUpdateRequest, socketId?: string): Promise<CollectionPlace> {
|
||||
const currentCollection = this.collectionIdOfPlace(placeId);
|
||||
this.assertCanEdit(userId, currentCollection);
|
||||
if (body.price !== undefined || body.currency !== undefined) this.assertPriceHasCurrency(placeId, body);
|
||||
|
||||
// Capture the previous thumbnail so a replaced/cleared custom upload (#1136)
|
||||
// can be reclaimed once nothing references it any more.
|
||||
@@ -1056,6 +1057,23 @@ export class CollectionsService {
|
||||
return this.getPlaceById(placeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* A list has no base currency, so a price that names none would be read in
|
||||
* each viewer's own default currency and carried into a trip as the trip's
|
||||
* (#2471). Checked here rather than in the contract so REST and the MCP tool,
|
||||
* which spreads the contract's shape, refuse it alike. Only the row as it
|
||||
* would look after this update counts, so a zero price or clearing both
|
||||
* fields still goes through.
|
||||
*/
|
||||
private assertPriceHasCurrency(placeId: number, body: Pick<CollectionPlaceUpdateRequest, 'price' | 'currency'>): void {
|
||||
const stored = this.db.get<{ price: number | null; currency: string | null }>(
|
||||
'SELECT price, currency FROM collection_places WHERE id = ?', placeId,
|
||||
);
|
||||
const price = body.price === undefined ? stored?.price ?? null : body.price;
|
||||
const currency = body.currency === undefined ? stored?.currency ?? null : body.currency;
|
||||
if (price != null && price > 0 && !currency) httpError(400, 'A price needs a currency: send its three-letter code along');
|
||||
}
|
||||
|
||||
setStatus(userId: number, placeId: number, status: CollectionStatus, socketId?: string): CollectionPlace {
|
||||
const collectionId = this.collectionIdOfPlace(placeId);
|
||||
this.assertCanEdit(userId, collectionId);
|
||||
|
||||
@@ -115,9 +115,10 @@ export class ImmichService {
|
||||
}
|
||||
|
||||
/**
|
||||
* `allowInsecureTls` left undefined keeps the stored choice, so a client that
|
||||
* does not know the switch cannot clear it by saving. Disconnecting (no URL)
|
||||
* always turns it off again.
|
||||
* `allowInsecureTls` left undefined keeps the stored choice while the URL
|
||||
* stays the same, so a client that does not know the switch cannot clear it
|
||||
* by saving. The switch trusts one server, so a new URL without it starts
|
||||
* off, and disconnecting (no URL) always turns it off again.
|
||||
*/
|
||||
async saveImmichSettings(
|
||||
userId: number,
|
||||
@@ -134,16 +135,17 @@ export class ImmichService {
|
||||
if (!ssrf.allowed) {
|
||||
return { success: false, error: `Invalid Immich URL: ${ssrf.error}` };
|
||||
}
|
||||
const url = immichUrl.trim();
|
||||
const insecure = allowInsecureTls === undefined ? null : Number(allowInsecureTls);
|
||||
// SET expressions read the row as it was, so `immich_url IS ?` compares the
|
||||
// stored URL with the new one.
|
||||
this.db
|
||||
.prepare(
|
||||
'UPDATE users SET immich_url = ?, immich_api_key = ?, immich_allow_insecure_tls = COALESCE(?, immich_allow_insecure_tls) WHERE id = ?',
|
||||
`UPDATE users SET immich_url = ?, immich_api_key = ?,
|
||||
immich_allow_insecure_tls = CASE WHEN immich_url IS ? THEN COALESCE(?, immich_allow_insecure_tls) ELSE COALESCE(?, 0) END
|
||||
WHERE id = ?`,
|
||||
)
|
||||
.run(
|
||||
immichUrl.trim(),
|
||||
maybe_encrypt_api_key(immichApiKey),
|
||||
allowInsecureTls === undefined ? null : Number(allowInsecureTls),
|
||||
userId,
|
||||
);
|
||||
.run(url, maybe_encrypt_api_key(immichApiKey), url, insecure, insecure, userId);
|
||||
if (ssrf.isPrivate) {
|
||||
this.audit.writeAudit({
|
||||
userId,
|
||||
|
||||
Reference in New Issue
Block a user