mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-19 13:21:46 +00:00
fix(synology): paginate all three album sources past 100 albums and tighten targetUserId type
- Extract _fetchAllSynologyAlbums helper that loops until the source is exhausted; listSynologyAlbums now uses it for personal, shared-out, and shared-with-me instead of a hard-capped single request of 100 - Make getSynologyAssetInfo targetUserId required (number, not number|undefined) to match every call site and eliminate an implicit any at the _requestSynologyApi boundary
This commit is contained in:
@@ -1149,9 +1149,15 @@ describe('Synology SSRF blocked error handling', () => {
|
||||
|
||||
const { SsrfBlockedError: SsrfErr } = await import('../../src/utils/ssrfGuard');
|
||||
|
||||
// Auth succeeds, but the first album-list call throws SsrfBlockedError.
|
||||
// The other two parallel album sources fall through to the default mock and succeed.
|
||||
// listSynologyAlbums uses Promise.allSettled so a partial failure is logged and skipped.
|
||||
const emptyAlbumResponse = {
|
||||
ok: true, status: 200,
|
||||
headers: { get: () => 'application/json' },
|
||||
json: async () => ({ success: true, data: { list: [{ id: 99, name: 'Shared Album', item_count: 2, passphrase: 'pp-test' }] } }),
|
||||
body: null,
|
||||
} as any;
|
||||
|
||||
// Auth succeeds, personal album source throws SSRF, shared + shared-with-me succeed.
|
||||
// listSynologyAlbums uses Promise.allSettled so the SSRF failure is logged and skipped.
|
||||
vi.mocked(safeFetch)
|
||||
.mockResolvedValueOnce({
|
||||
ok: true, status: 200,
|
||||
@@ -1159,15 +1165,17 @@ describe('Synology SSRF blocked error handling', () => {
|
||||
json: async () => ({ success: true, data: { sid: 'sid-x' } }),
|
||||
body: null,
|
||||
} as any)
|
||||
.mockRejectedValueOnce(new SsrfErr('Private IP detected'));
|
||||
.mockRejectedValueOnce(new SsrfErr('Private IP detected'))
|
||||
.mockResolvedValueOnce(emptyAlbumResponse)
|
||||
.mockResolvedValueOnce(emptyAlbumResponse);
|
||||
|
||||
const res = await request(app)
|
||||
.get(`${SYNO}/albums`)
|
||||
.set('Cookie', authCookie(user.id));
|
||||
|
||||
// The personal album source failed, but the other sources succeeded via the default mock.
|
||||
// listSynologyAlbums is resilient: partial failure is logged, remaining albums returned.
|
||||
// Personal failed (SSRF), shared sources returned an album — 200 with non-empty list.
|
||||
expect(res.status).toBe(200);
|
||||
expect(Array.isArray(res.body.albums)).toBe(true);
|
||||
expect(res.body.albums.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user