Support Webshare guest downloads without login.

Credentials optional: empty WEBSHARE_* uses file_link without wst (free CDN). Verified against live API; docs and tests updated. Includes cancel→dequeue fix for queued downloads.
This commit is contained in:
2026-08-07 11:31:19 +02:00
parent 97b9215917
commit 798d7d7251
9 changed files with 259 additions and 88 deletions

View File

@@ -16,6 +16,44 @@ describe('WebshareClient', () => {
client = new WebshareClient('user', 'pass');
});
describe('guest mode', () => {
it('marks guest when username/password missing', () => {
expect(new WebshareClient('', '').guest).toBe(true);
expect(new WebshareClient(undefined, undefined).guest).toBe(true);
expect(new WebshareClient('u', '').guest).toBe(true);
expect(new WebshareClient('', 'p').guest).toBe(true);
expect(new WebshareClient('u', 'p').guest).toBe(false);
});
it('ensureAuth is a no-op in guest mode', async () => {
const guest = new WebshareClient('', '');
await guest.ensureAuth();
expect(axios.post).not.toHaveBeenCalled();
expect(guest.wst).toBeNull();
});
it('getFileLink works without login and omits wst', async () => {
const guest = new WebshareClient();
mockResponse({ status: 'OK', link: 'https://free.1.dl.wsfiles.cz/file.mkv' });
const link = await guest.getFileLink('identGuest');
expect(link).toBe('https://free.1.dl.wsfiles.cz/file.mkv');
expect(axios.post).toHaveBeenCalledTimes(1);
const [url, body] = axios.post.mock.calls[0];
expect(url).toContain('file_link');
const params = new URLSearchParams(body);
expect(params.get('ident')).toBe('identGuest');
expect(params.get('wst')).toBeNull();
expect(params.get('download_type')).toBe('file_download');
});
it('getFileLink does not re-login when guest request fails', async () => {
const guest = new WebshareClient('', '');
mockResponse({ status: 'FATAL', message: 'File not found' });
await expect(guest.getFileLink('missing')).rejects.toThrow('file_link() FATAL: File not found');
expect(axios.post).toHaveBeenCalledTimes(1);
});
});
// ── ensureAuth / _login ─────────────────────────────────────────────────
describe('ensureAuth()', () => {
@@ -157,7 +195,7 @@ describe('WebshareClient', () => {
mockResponse({ status: 'OK', salt: 'salt123a' });
mockResponse({ status: 'OK', token: 'tok2' });
mockResponse({ status: 'FATAL', message: 'File unavailable' });
await expect(client.getFileLink('badident')).rejects.toThrow('file_link() failed: File unavailable');
await expect(client.getFileLink('badident')).rejects.toThrow('file_link() FATAL: File unavailable');
});
it('calls ensureAuth before requesting link', async () => {