chore: 保存 Agent 安全优化前基线
This commit is contained in:
1 parent
08696896f9
commit
ff016347cd
116 files changed
+3858
-2485
No files matched your search
@@ -31,6 +31,14 @@ describe('Agent command guardrail', () => {
|
||||
expect(agentCommandNeedsConfirmation('critical', 'strict')).toBe(false)
|
||||
})
|
||||
|
||||
it('confirm-all still auto-runs only the read-only whitelist', () => {
|
||||
expect(agentCommandNeedsConfirmation('safe', 'relaxed', true)).toBe(false)
|
||||
expect(agentCommandNeedsConfirmation('low', 'relaxed', true)).toBe(true)
|
||||
expect(agentCommandNeedsConfirmation('medium', 'strict', true)).toBe(true)
|
||||
expect(agentCommandNeedsConfirmation('high', 'relaxed', true)).toBe(true)
|
||||
expect(agentCommandNeedsConfirmation('critical', 'relaxed', true)).toBe(false)
|
||||
})
|
||||
|
||||
it('fingerprints similar temp-path commands for session Always', () => {
|
||||
expect(agentCommandAllowFingerprint('rm /tmp/tmp.3RUZRHTwk2', 'high')).toBe(
|
||||
agentCommandAllowFingerprint('rm /tmp/tmp.ABCDEFG123', 'high')
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { compareBySortOrder, groupSessionsInDisplayOrder } from '../../src/utils/sessionGroups'
|
||||
import type { Session } from '../../src/stores/sessionStore'
|
||||
|
||||
function session(id: string, sortOrder?: number, group?: string): Session {
|
||||
return {
|
||||
id,
|
||||
name: id,
|
||||
host: `${id}.example.com`,
|
||||
port: 22,
|
||||
username: 'root',
|
||||
authType: 'key',
|
||||
...(sortOrder !== undefined ? { sortOrder } : {}),
|
||||
...(group !== undefined ? { group } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
describe('compareBySortOrder', () => {
|
||||
it('sorts explicit sortOrder ascending', () => {
|
||||
const rows = [{ sortOrder: 2 }, { sortOrder: 0 }, { sortOrder: 1 }]
|
||||
expect([...rows].sort(compareBySortOrder).map((r) => r.sortOrder)).toEqual([0, 1, 2])
|
||||
})
|
||||
|
||||
it('keeps rows without sortOrder after ordered rows', () => {
|
||||
const rows = [{ sortOrder: undefined }, { sortOrder: 0 }, {}, { sortOrder: 1 }]
|
||||
const sorted = [...rows].sort(compareBySortOrder)
|
||||
expect(sorted.map((r) => r.sortOrder ?? null)).toEqual([0, 1, null, null])
|
||||
})
|
||||
})
|
||||
|
||||
describe('groupSessionsInDisplayOrder', () => {
|
||||
it('filters one group and orders by manual order with legacy rows last', () => {
|
||||
const sessions = [
|
||||
session('legacy-a'),
|
||||
session('ordered-b', 1, 'prod'),
|
||||
session('ordered-a', 0, 'prod'),
|
||||
session('legacy-b'),
|
||||
session('other', 0, 'staging'),
|
||||
]
|
||||
expect(groupSessionsInDisplayOrder(sessions, 'prod').map((s) => s.id)).toEqual(['ordered-a', 'ordered-b'])
|
||||
expect(groupSessionsInDisplayOrder(sessions, 'default').map((s) => s.id)).toEqual(['legacy-a', 'legacy-b'])
|
||||
})
|
||||
|
||||
it('preserves storage order among legacy rows (stable sort)', () => {
|
||||
const sessions = [session('first'), session('second'), session('third')]
|
||||
expect(groupSessionsInDisplayOrder(sessions, 'default').map((s) => s.id)).toEqual(['first', 'second', 'third'])
|
||||
})
|
||||
|
||||
it('rewriting 0..n-1 makes the manual order authoritative', () => {
|
||||
const sessions = [session('a'), session('b'), session('c')]
|
||||
const reordered = ['c', 'a', 'b']
|
||||
const rewritten = reordered.map((id, index) => ({
|
||||
...sessions.find((s) => s.id === id)!,
|
||||
sortOrder: index,
|
||||
}))
|
||||
expect(rewritten.sort(compareBySortOrder).map((s) => s.id)).toEqual(['c', 'a', 'b'])
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,31 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { flushShellBootstrap } from '../../src/utils/shellIO'
|
||||
|
||||
describe('flushShellBootstrap', () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(window.opsxApi.localOpenOutput).mockClear()
|
||||
vi.mocked(window.opsxApi.sshShellOpenOutput).mockClear()
|
||||
vi.mocked(window.opsxApi.localOpenOutput).mockResolvedValue({
|
||||
success: true,
|
||||
data: [98, 97, 115, 104],
|
||||
})
|
||||
vi.mocked(window.opsxApi.sshShellOpenOutput).mockResolvedValue({
|
||||
success: true,
|
||||
data: [109, 111, 116, 100],
|
||||
})
|
||||
})
|
||||
|
||||
it('opens buffered local PTY output for local-* ids', async () => {
|
||||
const boot = await flushShellBootstrap('local-abc')
|
||||
expect(window.opsxApi.localOpenOutput).toHaveBeenCalledWith('local-abc')
|
||||
expect(window.opsxApi.sshShellOpenOutput).not.toHaveBeenCalled()
|
||||
expect(boot).toEqual(new Uint8Array([98, 97, 115, 104]))
|
||||
})
|
||||
|
||||
it('opens buffered SSH output for remote shell ids', async () => {
|
||||
const boot = await flushShellBootstrap('shell-abc')
|
||||
expect(window.opsxApi.sshShellOpenOutput).toHaveBeenCalledWith('shell-abc')
|
||||
expect(window.opsxApi.localOpenOutput).not.toHaveBeenCalled()
|
||||
expect(boot).toEqual(new Uint8Array([109, 111, 116, 100]))
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user