mirror of
https://github.com/luxfi/aml.git
synced 2026-09-24 00:25:20 +00:00
The console now renders through @hanzo/gui — the Hanzo design system — instead of a set of primitives written here over the raw tokens. Layout, surfaces, controls and type are the kit's. Two things deliberately are not: the four state colours, which must not change with a theme because a supervisor's copy of a screenshot has to mean what the screen meant, and the meter, which is drawn in SVG so a width that varies with data is an attribute rather than a style. The kit is imported at the part rather than at the barrel. @hanzo/gui's index re-exports every component it has, including ones built on react-native primitives this bundle never renders — Sheet's pan responder and the spinner's ActivityIndicator are the two that pulled a native runtime into a browser build. It is still one kit at one version. The whole CSP question is now in ui/src/gui.ts, stated once. GuiProvider would write the config's stylesheet as an inline <style>, which style-src governs and which would need 'unsafe-inline' or a hash that moves whenever the theme does. disableInjectCSS turns that off and the same CSS goes on through a constructed stylesheet — CSP does not govern the CSSOM, because the script that reached it had already passed script-src. The kit's per-component rules take the same route into empty <style> holders, which the SHA-256 of the empty string allows and which allows nothing else. ui/e2e is the part that was previously a claim. It builds the bundle, serves it under ui/csp.txt — byte-identical to the chart's HANZO_STATIC_CSP — seeds a session before the first script runs, and drives Chromium through every screen the rail offers. It carries a positive control: a style attribute parsed from markup is asserted to be REFUSED, because "no violations" means nothing without evidence that a violation would have been noticed. Writing it found two things a claim would not have: the kit's theme root does carry a style attribute (React writes it through element.style, so it applies and raises nothing — which is the distinction that matters and is now written down), and a stray server on the default preview port had been answering for a build nobody was testing. origin() is now apiOrigin(protocol, host), a pure function with a table for a test. It requires the first label to be `aml`, so evil.aml.hanzo.ai — a four-label host the old rule read as a domain to derive from, and one that resolves inside *.hanzo.ai — derives nothing. The certificate and the ingress host rule were the only things standing there before. @hanzo/iam is 0.21.5: logout ends the session (credentials + RFC 7009 revocation) and the callback error branch checks state before it reads the query string. The console-side proof of the second is in the harness. Co-authored-by: Hanzo Dev <[email protected]>
30 lines
1.1 KiB
TypeScript
30 lines
1.1 KiB
TypeScript
import { defineConfig, devices } from '@playwright/test'
|
|
|
|
// The bundle is built first, then served by e2e/serve.mjs with the deployed
|
|
// CSP. Nothing here relaxes the policy — see e2e/serve.mjs for why the mock API
|
|
// can live on the same origin without doing so.
|
|
// A port of this harness's own, so a stray server cannot be mistaken for it.
|
|
const PORT = 4319
|
|
|
|
export default defineConfig({
|
|
testDir: './e2e',
|
|
fullyParallel: true,
|
|
forbidOnly: !!process.env.CI,
|
|
retries: 0,
|
|
reporter: process.env.CI ? 'line' : 'list',
|
|
use: {
|
|
baseURL: `http://127.0.0.1:${PORT}`,
|
|
trace: 'retain-on-failure',
|
|
},
|
|
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
|
|
webServer: {
|
|
command: `npm run build && PORT=${PORT} node e2e/serve.mjs`,
|
|
url: `http://127.0.0.1:${PORT}/v1/aml/health`,
|
|
// Never reuse. A server already listening on the port is not this build —
|
|
// it is somebody else's, and a harness that quietly tests somebody else's
|
|
// bundle reports on the wrong thing. This cost an afternoon once.
|
|
reuseExistingServer: false,
|
|
timeout: 180_000,
|
|
},
|
|
})
|