mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-21 06:11:45 +00:00
fix(synology): correct multi-album passphrase assignment and stale trek_photos
- ProviderPicker now tracks per-asset album passphrase in a Map; on confirm, assets are grouped by passphrase and submitted as separate batches so each asset receives its own album's passphrase instead of the last-selected one - getOrCreateTrekPhoto unconditionally overwrites the stored passphrase when a fresh one is supplied, allowing re-adds to heal a stuck bad passphrase - deleteTrekPhotoIfOrphan purges the trek_photos row for provider assets when no trip_photos or journey_photos reference it anymore; wired into removeTripPhoto, removeAlbumLink, and deletePhoto so remove + re-add is a clean slate - Three new integration tests: SYNO-090 (passphrase overwrite), SYNO-091 (orphan cleanup), SYNO-092 (remove + re-add restores correct passphrase)
This commit is contained in:
@@ -1169,3 +1169,74 @@ describe('Synology SSRF blocked error handling', () => {
|
||||
expect(res.body.albums.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Passphrase persistence fixes ─────────────────────────────────────────────
|
||||
|
||||
import { getOrCreateTrekPhoto, deleteTrekPhotoIfOrphan } from '../../src/services/memories/photoResolverService';
|
||||
import { decrypt_api_key } from '../../src/services/apiKeyCrypto';
|
||||
|
||||
describe('trek_photos passphrase healing (SYNO-090)', () => {
|
||||
it('SYNO-090 — getOrCreateTrekPhoto overwrites an existing bad passphrase when a new one is supplied', () => {
|
||||
const { user } = createUser(testDb);
|
||||
|
||||
const wrongPass = 'wrong-passphrase';
|
||||
const correctPass = 'correct-passphrase';
|
||||
|
||||
const id1 = getOrCreateTrekPhoto('synologyphotos', 'asset-heal-test', user.id, wrongPass);
|
||||
const row1 = testDb.prepare('SELECT passphrase FROM trek_photos WHERE id = ?').get(id1) as { passphrase: string };
|
||||
expect(decrypt_api_key(row1.passphrase)).toBe(wrongPass);
|
||||
|
||||
const id2 = getOrCreateTrekPhoto('synologyphotos', 'asset-heal-test', user.id, correctPass);
|
||||
expect(id2).toBe(id1);
|
||||
const row2 = testDb.prepare('SELECT passphrase FROM trek_photos WHERE id = ?').get(id2) as { passphrase: string };
|
||||
expect(decrypt_api_key(row2.passphrase)).toBe(correctPass);
|
||||
});
|
||||
});
|
||||
|
||||
describe('trek_photos orphan cleanup (SYNO-091)', () => {
|
||||
it('SYNO-091 — deleteTrekPhotoIfOrphan removes the trek_photos row when no trip_photos or journey_photos reference it', () => {
|
||||
const { user } = createUser(testDb);
|
||||
const trip = createTrip(testDb, user.id);
|
||||
testDb.prepare("UPDATE photo_providers SET enabled = 1 WHERE id = 'synologyphotos'").run();
|
||||
|
||||
const trekPhotoId = getOrCreateTrekPhoto('synologyphotos', 'asset-orphan-test', user.id, 'pass-A');
|
||||
|
||||
testDb.prepare(
|
||||
'INSERT OR IGNORE INTO trip_photos (trip_id, user_id, photo_id, shared) VALUES (?, ?, ?, 1)'
|
||||
).run(trip.id, user.id, trekPhotoId);
|
||||
|
||||
// Still referenced — must not be deleted.
|
||||
deleteTrekPhotoIfOrphan(trekPhotoId);
|
||||
expect(testDb.prepare('SELECT id FROM trek_photos WHERE id = ?').get(trekPhotoId)).toBeDefined();
|
||||
|
||||
// Remove the reference, then orphan-cleanup should delete the trek_photos row.
|
||||
testDb.prepare('DELETE FROM trip_photos WHERE photo_id = ?').run(trekPhotoId);
|
||||
deleteTrekPhotoIfOrphan(trekPhotoId);
|
||||
expect(testDb.prepare('SELECT id FROM trek_photos WHERE id = ?').get(trekPhotoId)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('SYNO-092 — re-adding a previously removed Synology photo stores the new passphrase correctly', () => {
|
||||
const { user } = createUser(testDb);
|
||||
const trip = createTrip(testDb, user.id);
|
||||
testDb.prepare("UPDATE photo_providers SET enabled = 1 WHERE id = 'synologyphotos'").run();
|
||||
|
||||
const firstPass = 'first-passphrase';
|
||||
const secondPass = 'second-passphrase';
|
||||
|
||||
// Add with wrong passphrase, then remove (simulating the bug scenario).
|
||||
const id1 = getOrCreateTrekPhoto('synologyphotos', 'asset-readd-test', user.id, firstPass);
|
||||
testDb.prepare(
|
||||
'INSERT OR IGNORE INTO trip_photos (trip_id, user_id, photo_id, shared) VALUES (?, ?, ?, 1)'
|
||||
).run(trip.id, user.id, id1);
|
||||
testDb.prepare('DELETE FROM trip_photos WHERE photo_id = ?').run(id1);
|
||||
deleteTrekPhotoIfOrphan(id1);
|
||||
|
||||
// trek_photos row should be gone.
|
||||
expect(testDb.prepare('SELECT id FROM trek_photos WHERE id = ?').get(id1)).toBeUndefined();
|
||||
|
||||
// Re-add with the correct passphrase.
|
||||
const id2 = getOrCreateTrekPhoto('synologyphotos', 'asset-readd-test', user.id, secondPass);
|
||||
const row = testDb.prepare('SELECT passphrase FROM trek_photos WHERE id = ?').get(id2) as { passphrase: string };
|
||||
expect(decrypt_api_key(row.passphrase)).toBe(secondPass);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user