Files
chrome-use/src/confirmation.test.ts
T
Chris Tate bc1e917e87 add security hardening features (#543)
* add security hardening features

- Add authentication vault (`auth save/login/list/show/delete`) so credentials are stored locally and never exposed to the LLM (fixes Snyk W007)
- Add `--content-boundaries` flag to wrap page-sourced output in structural markers, helping LLMs distinguish tool output from untrusted page content (fixes Snyk W011)
- Add `--allowed-domains` flag to restrict browser navigation to trusted domains
- Add `--action-policy` for static allow/deny gating of action categories, with opt-in `--confirm-actions`/`--confirm-interactive` for orchestrator or human-in-the-loop confirmation
- Add `--max-output` flag to truncate large page outputs, preventing context flooding
- New docs page at /security, updated README, SKILL.md, CLI help text, and templates

* fixes

* fixes

* fixes

* fixes

* fixes

* fixes

* fixes

* docs
2026-02-25 15:33:20 -06:00

68 lines
2.3 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { requestConfirmation, getAndRemovePending } from './confirmation.js';
describe('confirmation', () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
});
describe('requestConfirmation', () => {
it('should return a confirmation ID', () => {
const result = requestConfirmation('evaluate', 'eval', 'Evaluate JS', { script: 'test' });
expect(result.confirmationId).toBeTruthy();
expect(result.confirmationId).toMatch(/^c_[0-9a-f]{16}$/);
});
it('should generate unique IDs', () => {
const r1 = requestConfirmation('evaluate', 'eval', 'desc', {});
const r2 = requestConfirmation('click', 'click', 'desc', {});
expect(r1.confirmationId).not.toBe(r2.confirmationId);
});
});
describe('getAndRemovePending', () => {
it('should retrieve and remove a pending confirmation', () => {
const { confirmationId } = requestConfirmation('evaluate', 'eval', 'desc', {
action: 'evaluate',
script: 'test',
});
const entry = getAndRemovePending(confirmationId);
expect(entry).not.toBeNull();
expect(entry!.action).toBe('evaluate');
expect(entry!.command).toEqual({ action: 'evaluate', script: 'test' });
});
it('should return null on second retrieval (already removed)', () => {
const { confirmationId } = requestConfirmation('evaluate', 'eval', 'desc', {});
getAndRemovePending(confirmationId);
expect(getAndRemovePending(confirmationId)).toBeNull();
});
it('should return null for non-existent ID', () => {
expect(getAndRemovePending('c_nonexistent')).toBeNull();
});
it('should auto-deny after 60 seconds', () => {
const { confirmationId } = requestConfirmation('evaluate', 'eval', 'desc', {});
vi.advanceTimersByTime(60_000);
expect(getAndRemovePending(confirmationId)).toBeNull();
});
it('should still be retrievable before 60 second timeout', () => {
const { confirmationId } = requestConfirmation('evaluate', 'eval', 'desc', {});
vi.advanceTimersByTime(59_999);
const entry = getAndRemovePending(confirmationId);
expect(entry).not.toBeNull();
});
});
});