mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-10 18:36:15 -08:00
fix(backup): reject incomplete local Xtream credentials
This commit is contained in:
1 parent
9204f400bb
commit
1961952f48
2 files changed
+68
-9
No files matched your search
@@ -646,7 +646,9 @@ export class PlaylistBackupService {
|
||||
playlist._id === entry.exportedId &&
|
||||
this.getPlaylistPortalType(playlist) === 'xtream' &&
|
||||
this.normalizeUrlIdentity(playlist.serverUrl ?? '') ===
|
||||
this.normalizeUrlIdentity(entry.connection.serverUrl)
|
||||
this.normalizeUrlIdentity(entry.connection.serverUrl) &&
|
||||
this.normalizeIdentityValue(playlist.username ?? '') !== '' &&
|
||||
this.normalizeIdentityValue(playlist.password ?? '') !== ''
|
||||
);
|
||||
if (exactLocalMatch) {
|
||||
return entry;
|
||||
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
import { createPlaylistBackupService } from './playlist-backup.service.test-helpers';
|
||||
|
||||
describe('PlaylistBackupService redacted Xtream credential validation', () => {
|
||||
it('does not persist the entry when the normal connection check rejects the supplied credentials', async () => {
|
||||
const manifest: PlaylistBackupManifestV1 = {
|
||||
function redactedManifest(): PlaylistBackupManifestV1 {
|
||||
return {
|
||||
kind: PLAYLIST_BACKUP_KIND,
|
||||
version: PLAYLIST_BACKUP_VERSION,
|
||||
exportedAt: '2026-07-27T00:00:00.000Z',
|
||||
@@ -33,6 +33,9 @@ describe('PlaylistBackupService redacted Xtream credential validation', () => {
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
it('does not persist the entry when the normal connection check rejects the supplied credentials', async () => {
|
||||
const playlistsService = {
|
||||
addPlaylist: jest.fn((playlist: Playlist) => of(playlist)),
|
||||
getAllData: jest.fn(() => of([])),
|
||||
@@ -47,12 +50,15 @@ describe('PlaylistBackupService redacted Xtream credential validation', () => {
|
||||
portalStatusService,
|
||||
});
|
||||
|
||||
const summary = await service.importBackup(JSON.stringify(manifest), {
|
||||
resolveXtreamCredentials: async () => ({
|
||||
username: 'restored-user',
|
||||
password: 'wrong-password',
|
||||
}),
|
||||
});
|
||||
const summary = await service.importBackup(
|
||||
JSON.stringify(redactedManifest()),
|
||||
{
|
||||
resolveXtreamCredentials: async () => ({
|
||||
username: 'restored-user',
|
||||
password: 'wrong-password',
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
expect(summary).toEqual(
|
||||
expect.objectContaining({ failed: 1, imported: 0 })
|
||||
@@ -62,4 +68,55 @@ describe('PlaylistBackupService redacted Xtream credential validation', () => {
|
||||
);
|
||||
expect(playlistsService.addPlaylist).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it.each([
|
||||
['username', '', 'local-password'],
|
||||
['password', 'local-user', ' '],
|
||||
])(
|
||||
'does not treat an exact local row with a blank %s as usable credentials',
|
||||
async (_field, username, password) => {
|
||||
const local = {
|
||||
_id: 'xtream-redacted',
|
||||
title: 'Incomplete local Xtream',
|
||||
count: 1,
|
||||
importDate: '2026-07-01T00:00:00.000Z',
|
||||
lastUsage: '2026-07-01T00:00:00.000Z',
|
||||
autoRefresh: false,
|
||||
serverUrl: 'https://portal.test/base',
|
||||
username,
|
||||
password,
|
||||
} as Playlist;
|
||||
const playlistsService = {
|
||||
addPlaylist: jest.fn((playlist: Playlist) => of(playlist)),
|
||||
getAllData: jest.fn(() => of([local])),
|
||||
getRawPlaylistById: jest.fn(() => of('#EXTM3U')),
|
||||
handlePlaylistParsing: jest.fn(),
|
||||
};
|
||||
const resolveXtreamCredentials = jest
|
||||
.fn()
|
||||
.mockResolvedValue(null);
|
||||
const service = createPlaylistBackupService({
|
||||
playlistsService,
|
||||
});
|
||||
|
||||
const summary = await service.importBackup(
|
||||
JSON.stringify(redactedManifest()),
|
||||
{ resolveXtreamCredentials }
|
||||
);
|
||||
|
||||
expect(resolveXtreamCredentials).toHaveBeenCalledWith({
|
||||
exportedId: 'xtream-redacted',
|
||||
serverUrl: 'https://portal.test/base/',
|
||||
title: 'Redacted Xtream',
|
||||
});
|
||||
expect(summary).toEqual({
|
||||
imported: 0,
|
||||
merged: 0,
|
||||
skipped: 1,
|
||||
failed: 0,
|
||||
errors: [],
|
||||
});
|
||||
expect(playlistsService.addPlaylist).not.toHaveBeenCalled();
|
||||
}
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user