107 lines
4.0 KiB
Markdown
107 lines
4.0 KiB
Markdown
# Toolbox Portal requirements
|
|
|
|
av-tools is built and packaged independently. Toolbox Portal consumes the
|
|
exact ZIP and SHA-256 from a reviewed release lock; it must never import the
|
|
app source into its React build.
|
|
|
|
## Required serving behavior
|
|
|
|
All app, wrapper, core, WASM and worker responses are same-origin and served
|
|
over HTTPS (or trusted localhost). Apply:
|
|
|
|
```text
|
|
Cross-Origin-Opener-Policy: same-origin
|
|
Cross-Origin-Embedder-Policy: require-corp
|
|
Cross-Origin-Resource-Policy: same-origin
|
|
X-Content-Type-Options: nosniff
|
|
```
|
|
|
|
Serve `.wasm` as `application/wasm`, JavaScript modules as a JavaScript MIME
|
|
type and JSON as `application/json`. Test real responses under
|
|
`/apps/av/vendor/ffmpeg/0.12.10-reviewed-stack5m.1/...`; a file-extension allowlist alone does not
|
|
prove the MIME type.
|
|
|
|
Suggested CSP:
|
|
|
|
```text
|
|
default-src 'self';
|
|
script-src 'self' 'wasm-unsafe-eval';
|
|
worker-src 'self' blob:;
|
|
connect-src 'self';
|
|
img-src 'self' blob: data:;
|
|
media-src 'self' blob:;
|
|
font-src 'self';
|
|
style-src 'self';
|
|
object-src 'none';
|
|
frame-src 'none';
|
|
frame-ancestors 'none';
|
|
base-uri 'none';
|
|
form-action 'none';
|
|
```
|
|
|
|
`'wasm-unsafe-eval'` is the narrow WebAssembly permission; broad
|
|
`'unsafe-eval'` is unnecessary. `worker-src blob:` covers the wrapper-created
|
|
worker path. `media-src blob:` permits local source/result previews.
|
|
|
|
## Reviewed Portal state
|
|
|
|
Portal revision `5c052bc6d1073a66600cfddc44c0e16da34bede8` (tag `v0.6.0`)
|
|
already sends COOP `same-origin`, COEP `require-corp`, CORP `same-origin`,
|
|
`script-src 'self' 'wasm-unsafe-eval'`, `worker-src 'self' blob:` and
|
|
`media-src 'self' blob:`. Its nginx profile also maps `.wasm` explicitly to
|
|
`application/wasm`. Local source and result Blob previews therefore require no
|
|
CSP exception beyond that reviewed narrow media directive.
|
|
|
|
As inspected on 2026-07-26, the active
|
|
`/mnt/DATA/git/toolbox-portal/deploy/nginx.conf` has an additional worktree
|
|
patch that extends the immutable FFmpeg cache rule from plain semantic versions
|
|
to the one exact reviewed build profile
|
|
`0.12.10-reviewed-stack5m.1`. The corresponding deployment tests accept the
|
|
five reviewed core files and `version.json` while rejecting mutable-looking
|
|
suffixes, malformed versions and unexpected paths. A clean temporary clone
|
|
containing that exact patch passed the AV release assembly smoke without a
|
|
known-header-gap override.
|
|
|
|
Until the cache extension is committed, cite it only as staged integration
|
|
evidence, not as a published Portal revision. The clean `v0.6.0` rule leaves
|
|
the reviewed profile at `no-cache`; that affects performance, not loading,
|
|
MIME type, isolation or preview correctness.
|
|
|
|
## Caching
|
|
|
|
The staged Portal cache map makes Vite content-hashed assets, plain semantic
|
|
versions and the explicitly reviewed profile immutable. For performance, the
|
|
exact directory
|
|
`apps/av/vendor/ffmpeg/0.12.10-reviewed-stack5m.1/{st,mt}/` may receive:
|
|
|
|
```text
|
|
Cache-Control: public, max-age=31536000, immutable
|
|
```
|
|
|
|
Only do this while a version path is immutable and verified against
|
|
`version.json`. Keep `index.html`, manifest/catalog/release JSON and legal
|
|
notices revalidated.
|
|
|
|
## Nested path and context
|
|
|
|
The artifact uses `base: './'`, `entry: './'`, a relative icon, a relative
|
|
manifest URL and relative core URLs. Portal may therefore target `av`, yielding
|
|
`apps/av/`. Do not rewrite files to root-absolute `/assets` or `/vendor`.
|
|
Use top-level navigation; embedding is unsupported.
|
|
|
|
The app remains usable without valid Toolbox context. It validates context
|
|
version/origin and falls back to standalone shell behavior without moving or
|
|
duplicating suite controls.
|
|
|
|
## Fallback contract
|
|
|
|
MT requires all isolation headers plus secure context and
|
|
`SharedArrayBuffer`. When any prerequisite or MT load fails, the app terminates
|
|
that instance and loads ST. The manifest intentionally declares
|
|
`crossOriginIsolated: false` because isolation is not an unconditional
|
|
requirement; it declares workers, secure context, IndexedDB and top-level
|
|
context.
|
|
|
|
See `scripts/portal-assembly-smoke.mjs` and `docs/RELEASE.md` for the temporary,
|
|
non-mutating assembly procedure.
|