fix(settings): harden locations and site login matching

This commit is contained in:
NimBold
2026-07-02 22:38:25 +03:30
parent 98be029203
commit ae9f14ad6e
5 changed files with 128 additions and 20 deletions
+20 -1
View File
@@ -11,9 +11,11 @@ vi.mock('@tauri-apps/api/path', () => ({
import {
downloadLocationEquals,
DEFAULT_CATEGORY_SUBFOLDERS,
formatDerivedCategoryPath,
normalizeCategorySubfolder,
normalizeDownloadLocationSettings,
resolveCategoryDestination
resolveCategoryDestination,
subfolderFromDerivedCategoryPath
} from './downloadLocations';
describe('download locations', () => {
@@ -68,4 +70,21 @@ describe('download locations', () => {
expect(normalizeCategorySubfolder('C:\\Media\\Movies', 'Movies')).toBe('Media/Movies');
expect(normalizeCategorySubfolder('../../', 'Movies')).toBe('Movies');
});
it('formats and parses derived category paths with platform path separators', () => {
expect(formatDerivedCategoryPath('/Users/test/Downloads', 'Video Files'))
.toBe('/Users/test/Downloads/Video Files');
expect(formatDerivedCategoryPath('D:\\Downloads', 'Video Files'))
.toBe('D:\\Downloads\\Video Files');
expect(subfolderFromDerivedCategoryPath(
'D:\\Downloads\\Video Files',
'd:\\downloads'
)).toBe('Video Files');
expect(subfolderFromDerivedCategoryPath(
'/Users/test/Downloads/Video Files',
'/Users/test/Downloads'
)).toBe('Video Files');
expect(subfolderFromDerivedCategoryPath('/Volumes/Media', '/Users/test/Downloads'))
.toBeNull();
});
});
+25
View File
@@ -61,6 +61,31 @@ const normalizedForComparison = (value: string): string =>
const legacyDerivedPath = (base: string, subfolder: string): string =>
`${normalizedForComparison(base)}/${subfolder.replace(/^[\\/]+|[\\/]+$/g, '')}`;
const isWindowsLikePath = (value: string): boolean =>
/^[a-z]:[\\/]/i.test(value) || value.startsWith('\\\\') || value.includes('\\');
export const formatDerivedCategoryPath = (base: string, subfolder: string): string => {
const trimmedBase = base.trim() || '~/Downloads';
const relative = subfolder.replace(/^[\\/]+|[\\/]+$/g, '');
const separator = isWindowsLikePath(trimmedBase) ? '\\' : '/';
return `${trimmedBase.replace(/[\\/]+$/, '')}${separator}${relative}`;
};
export const subfolderFromDerivedCategoryPath = (
value: string,
base: string
): string | null => {
const normalizedValue = normalizedForComparison(value.trim());
const normalizedBase = normalizedForComparison((base.trim() || '~/Downloads'));
const isWindows = isWindowsLikePath(base);
const comparableValue = isWindows ? normalizedValue.toLocaleLowerCase() : normalizedValue;
const comparableBase = isWindows ? normalizedBase.toLocaleLowerCase() : normalizedBase;
if (comparableValue === comparableBase) return '';
if (!comparableValue.startsWith(`${comparableBase}/`)) return null;
return normalizedValue.slice(normalizedBase.length + 1);
};
export const normalizeCategorySubfolder = (
value: string,
fallback: string