Qualify firewall layouts and keep device names compatible with JS target
This commit is contained in:
@@ -27,9 +27,29 @@ local JSON. They are not exposed as controls that claim to open or close real po
|
|||||||
The existing OpenWrt management screen remains linked. Actual node firewall rule
|
The existing OpenWrt management screen remains linked. Actual node firewall rule
|
||||||
inspection/editing and the complete app exposure workflow are still separate work.
|
inspection/editing and the complete app exposure workflow are still separate work.
|
||||||
|
|
||||||
Validation checkpoint: 21 focused UI tests passed before the final background
|
Validation: current focused tests pass 25/25 (22 component cases plus three
|
||||||
resolver and pending-operation display additions. Those additions, the complete
|
background resolver cases), and the full app typecheck passes. Typecheck exposed
|
||||||
app typecheck, responsive rendered-route/background checks and production build
|
an unsupported replaceAll call and a test-wrapper assertion; both were corrected
|
||||||
remain queued behind IndeeHub recovery qualification. No live acceptance is claimed.
|
and the changed device test file was rerun successfully (16/16).
|
||||||
The backend peer-safety changes are isolated separately and also require tests and
|
|
||||||
paired helper deployment before these new mutation controls can be enabled.
|
Source browser fixtures pass at 320, 390, 768 and 1440 pixels: full content width,
|
||||||
|
right-aligned values, no horizontal overflow, QR containment and unavailable
|
||||||
|
mutation controls against the old-backend fixture. A routed source fixture using
|
||||||
|
the same background resolver preserved the rendered Network background when
|
||||||
|
entering Firewalls & tunnels. This is not a full production Dashboard acceptance
|
||||||
|
or a live-node test. All RPC replies were synthetic; no node mutation occurred.
|
||||||
|
|
||||||
|
Local receipts:
|
||||||
|
- `/tmp/archy-firewall-focused-current-20261008.log` — three background tests.
|
||||||
|
- `/tmp/archy-firewall-focused-components-20261008.log` — 22 component tests.
|
||||||
|
- `/tmp/archy-firewall-device-final-20261008.log` — corrected device tests.
|
||||||
|
- `/tmp/archy-firewall-typecheck-20261008.log` — successful exit 0, no diagnostics.
|
||||||
|
- `/tmp/archy-firewall-responsive-20261008.log` — all four rendered viewport cases.
|
||||||
|
- `/tmp/archy-firewall-fixture-server.mjs` and
|
||||||
|
`/tmp/archy-firewall-responsive.cjs` — the source fixture harnesses.
|
||||||
|
|
||||||
|
Production build and live acceptance remain pending. The backend peer-safety
|
||||||
|
changes are isolated separately; actual ephemeral-kernel helper qualification
|
||||||
|
passed, but Rust compilation/tests and paired helper deployment remain required
|
||||||
|
before the new mutation controls can be enabled on a node. Task 18 remains open
|
||||||
|
for broader host firewall management, persistence and rollback.
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ describe('Private device management', () => {
|
|||||||
const w = view(); await flushPromises(); await w.get('[aria-label="Remove Phone"]').trigger('click')
|
const w = view(); await flushPromises(); await w.get('[aria-label="Remove Phone"]').trigger('click')
|
||||||
expect(vi.mocked(rpcClient.call).mock.calls.filter(([a]) => a.method === 'vpn.remove-peer')).toHaveLength(0)
|
expect(vi.mocked(rpcClient.call).mock.calls.filter(([a]) => a.method === 'vpn.remove-peer')).toHaveLength(0)
|
||||||
await button(w, 'Remove device').trigger('click'); await flushPromises()
|
await button(w, 'Remove device').trigger('click'); await flushPromises()
|
||||||
expect(w.text()).toContain('Could not confirm removal'); expect(w.get('[aria-label="Remove Phone"]').exists()).toBe(true); w.unmount()
|
expect(w.text()).toContain('Could not confirm removal'); expect(w.find('[aria-label="Remove Phone"]').exists()).toBe(true); w.unmount()
|
||||||
})
|
})
|
||||||
it('keeps a failed list distinct from no devices and disables creation', async () => {
|
it('keeps a failed list distinct from no devices and disables creation', async () => {
|
||||||
vi.mocked(rpcClient.call).mockRejectedValue(new Error('offline'))
|
vi.mocked(rpcClient.call).mockRejectedValue(new Error('offline'))
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const removeName = ref('')
|
|||||||
const copied = ref(false)
|
const copied = ref(false)
|
||||||
const needsRefresh = ref(false)
|
const needsRefresh = ref(false)
|
||||||
const safeName = (value: string) => /^[A-Za-z0-9][A-Za-z0-9 _-]{0,63}$/.test(value)
|
const safeName = (value: string) => /^[A-Za-z0-9][A-Za-z0-9 _-]{0,63}$/.test(value)
|
||||||
const filename = (value: string) => value.toLowerCase().replaceAll(' ', '-')
|
const filename = (value: string) => value.toLowerCase().replace(/ /g, '-')
|
||||||
const canCreate = computed(() => props.statusKnown && props.configured && props.managementVerified && devices.value !== null && !needsRefresh.value && safeName(name.value.trim()) && !devices.value.some(d => filename(d.name) === filename(name.value.trim())))
|
const canCreate = computed(() => props.statusKnown && props.configured && props.managementVerified && devices.value !== null && !needsRefresh.value && safeName(name.value.trim()) && !devices.value.some(d => filename(d.name) === filename(name.value.trim())))
|
||||||
let active = true
|
let active = true
|
||||||
let request = 0
|
let request = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user