mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
This commit is contained in:
@@ -17,6 +17,7 @@ vi.mock('node:fs', () => ({
|
|||||||
writeFile: vi.fn(),
|
writeFile: vi.fn(),
|
||||||
unlink: vi.fn(),
|
unlink: vi.fn(),
|
||||||
mkdir: vi.fn(),
|
mkdir: vi.fn(),
|
||||||
|
rename: vi.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ describe('FileTokenStorage', () => {
|
|||||||
writeFile: ReturnType<typeof vi.fn>;
|
writeFile: ReturnType<typeof vi.fn>;
|
||||||
unlink: ReturnType<typeof vi.fn>;
|
unlink: ReturnType<typeof vi.fn>;
|
||||||
mkdir: ReturnType<typeof vi.fn>;
|
mkdir: ReturnType<typeof vi.fn>;
|
||||||
|
rename: ReturnType<typeof vi.fn>;
|
||||||
};
|
};
|
||||||
const existingCredentials: OAuthCredentials = {
|
const existingCredentials: OAuthCredentials = {
|
||||||
serverName: 'existing-server',
|
serverName: 'existing-server',
|
||||||
@@ -105,12 +107,48 @@ describe('FileTokenStorage', () => {
|
|||||||
expect(result).toEqual(credentials);
|
expect(result).toEqual(credentials);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw error for corrupted files', async () => {
|
it('should throw error with file path when file is corrupted', async () => {
|
||||||
mockFs.readFile.mockResolvedValue('corrupted-data');
|
mockFs.readFile.mockResolvedValue('corrupted-data');
|
||||||
|
|
||||||
await expect(storage.getCredentials('test-server')).rejects.toThrow(
|
try {
|
||||||
'Token file corrupted',
|
await storage.getCredentials('test-server');
|
||||||
);
|
expect.fail('Expected error to be thrown');
|
||||||
|
} catch (error) {
|
||||||
|
expect(error).toBeInstanceOf(Error);
|
||||||
|
const err = error as Error;
|
||||||
|
expect(err.message).toContain('Corrupted token file detected at:');
|
||||||
|
expect(err.message).toContain('mcp-oauth-tokens-v2.json');
|
||||||
|
expect(err.message).toContain('delete or rename');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('auth type switching', () => {
|
||||||
|
it('should throw error when trying to save credentials with corrupted file', async () => {
|
||||||
|
// Simulate corrupted file on first read
|
||||||
|
mockFs.readFile.mockResolvedValue('corrupted-data');
|
||||||
|
|
||||||
|
// Try to save new credentials (simulating switch from OAuth to API key)
|
||||||
|
const newCredentials: OAuthCredentials = {
|
||||||
|
serverName: 'new-auth-server',
|
||||||
|
token: {
|
||||||
|
accessToken: 'new-api-key',
|
||||||
|
tokenType: 'ApiKey',
|
||||||
|
},
|
||||||
|
updatedAt: Date.now(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Should throw error with file path
|
||||||
|
try {
|
||||||
|
await storage.setCredentials(newCredentials);
|
||||||
|
expect.fail('Expected error to be thrown');
|
||||||
|
} catch (error) {
|
||||||
|
expect(error).toBeInstanceOf(Error);
|
||||||
|
const err = error as Error;
|
||||||
|
expect(err.message).toContain('Corrupted token file detected at:');
|
||||||
|
expect(err.message).toContain('mcp-oauth-tokens-v2.json');
|
||||||
|
expect(err.message).toContain('delete or rename');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,12 @@ export class FileTokenStorage extends BaseTokenStorage {
|
|||||||
'Unsupported state or unable to authenticate data',
|
'Unsupported state or unable to authenticate data',
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
throw new Error('Token file corrupted');
|
// Decryption failed - this can happen when switching between auth types
|
||||||
|
// or if the file is genuinely corrupted.
|
||||||
|
throw new Error(
|
||||||
|
`Corrupted token file detected at: ${this.tokenFilePath}\n` +
|
||||||
|
`Please delete or rename this file to resolve the issue.`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user