diff --git a/packages/cli/src/config/trustedFolders.test.ts b/packages/cli/src/config/trustedFolders.test.ts index 122ba95b15..436e300957 100644 --- a/packages/cli/src/config/trustedFolders.test.ts +++ b/packages/cli/src/config/trustedFolders.test.ts @@ -424,3 +424,52 @@ describe('Trusted Folders Caching', () => { expect(readSpy).toHaveBeenCalledTimes(2); }); }); + +describe('invalid trust levels', () => { + const mockCwd = '/user/folder'; + const mockRules: Record = {}; + + beforeEach(() => { + resetTrustedFoldersForTesting(); + vi.spyOn(process, 'cwd').mockImplementation(() => mockCwd); + vi.spyOn(fs, 'readFileSync').mockImplementation((p) => { + if (p === getTrustedFoldersPath()) { + return JSON.stringify(mockRules); + } + return '{}'; + }); + vi.spyOn(fs, 'existsSync').mockImplementation( + (p) => p === getTrustedFoldersPath(), + ); + }); + + afterEach(() => { + vi.restoreAllMocks(); + // Clear the object + Object.keys(mockRules).forEach((key) => delete mockRules[key]); + }); + + it('should create a comprehensive error message for invalid trust level', () => { + mockRules[mockCwd] = 'INVALID_TRUST_LEVEL' as TrustLevel; + + const { errors } = loadTrustedFolders(); + const possibleValues = Object.values(TrustLevel).join(', '); + expect(errors.length).toBe(1); + expect(errors[0].message).toBe( + `Invalid trust level "INVALID_TRUST_LEVEL" for path "${mockCwd}". Possible values are: ${possibleValues}.`, + ); + }); + + it('should throw a fatal error for invalid trust level', () => { + const mockSettings: Settings = { + security: { + folderTrust: { + enabled: true, + }, + }, + }; + mockRules[mockCwd] = 'INVALID_TRUST_LEVEL' as TrustLevel; + + expect(() => isWorkspaceTrusted(mockSettings)).toThrow(FatalConfigError); + }); +}); diff --git a/packages/cli/src/config/trustedFolders.ts b/packages/cli/src/config/trustedFolders.ts index d308404ba3..684a91639c 100644 --- a/packages/cli/src/config/trustedFolders.ts +++ b/packages/cli/src/config/trustedFolders.ts @@ -36,6 +36,13 @@ export enum TrustLevel { DO_NOT_TRUST = 'DO_NOT_TRUST', } +export function isTrustLevel(value: unknown): value is TrustLevel { + return ( + typeof value === 'string' && + Object.values(TrustLevel).includes(value as TrustLevel) + ); +} + export interface TrustRule { path: string; trustLevel: TrustLevel; @@ -151,7 +158,7 @@ export function loadTrustedFolders(): LoadedTrustedFolders { } const errors: TrustedFoldersError[] = []; - let userConfig: Record = {}; + const userConfig: Record = {}; const userPath = getTrustedFoldersPath(); @@ -171,7 +178,17 @@ export function loadTrustedFolders(): LoadedTrustedFolders { path: userPath, }); } else { - userConfig = parsed as Record; + for (const [path, trustLevel] of Object.entries(parsed)) { + if (isTrustLevel(trustLevel)) { + userConfig[path] = trustLevel; + } else { + const possibleValues = Object.values(TrustLevel).join(', '); + errors.push({ + message: `Invalid trust level "${trustLevel}" for path "${path}". Possible values are: ${possibleValues}.`, + path: userPath, + }); + } + } } } } catch (error: unknown) {