summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/tests')
-rw-r--r--packages/meshbay-hub/tests/harness/session_harness.mjs6
-rw-r--r--packages/meshbay-hub/tests/test_desktop_shell.py49
2 files changed, 43 insertions, 12 deletions
diff --git a/packages/meshbay-hub/tests/harness/session_harness.mjs b/packages/meshbay-hub/tests/harness/session_harness.mjs
index f0d0cb2..3be862e 100644
--- a/packages/meshbay-hub/tests/harness/session_harness.mjs
+++ b/packages/meshbay-hub/tests/harness/session_harness.mjs
@@ -110,6 +110,12 @@ const ctx = {
localStorage, AUTH_KEY, HUB, TOKEN_RENEW_MARGIN_S,
loadAuth, saveAuth, fetch: fakeFetch, atob: (s) => Buffer.from(s, 'base64').toString('binary'),
console,
+ // Hub calls go through the platform adapter since the interface started
+ // shipping in a package: in a browser it is `fetch`, in the application it is
+ // the main process, because an `app://` origin is refused by CORS. The
+ // harness models the browser side, which is the one whose renewal logic this
+ // exercises.
+ platform: { apiFetch: (...args) => fakeFetch(...args) },
};
const fns = new Function(...Object.keys(ctx),
sessionBlock + '\n' + hubFetchFn +
diff --git a/packages/meshbay-hub/tests/test_desktop_shell.py b/packages/meshbay-hub/tests/test_desktop_shell.py
index 13d194e..c4f5b08 100644
--- a/packages/meshbay-hub/tests/test_desktop_shell.py
+++ b/packages/meshbay-hub/tests/test_desktop_shell.py
@@ -85,11 +85,18 @@ def test_no_permission_is_granted_to_the_page():
])
def test_the_scheme_is_privileged(privilege):
"""
- Without `secure` the scheme is not a secure context, the service worker
- silently refuses to register, and streamed downloads break with no error —
- the same failure mode as an uncontrolled page, which this codebase has
- already learned once. `standard` gives a real origin, so IndexedDB survives
- an update instead of being keyed to something that moves.
+ `secure` is what makes it a secure context, and without it **the whole of
+ `crypto.subtle` is undefined** — measured, not assumed: the first probe
+ loaded a `data:` URL and every algorithm failed with TypeError, AES-GCM
+ included. `standard` gives a real origin, so IndexedDB survives an update
+ instead of being keyed to something that moves.
+
+ An earlier version of this docstring said `secure` was what let the service
+ worker register. That is wrong: Chromium refuses to register a worker on a
+ custom scheme whatever its privileges — "The URL protocol of the current
+ origin ('app://meshbay') is not supported". The application therefore has no
+ service worker and does not need one; it saves files through a native
+ dialog, which is better than the path the worker exists to provide.
"""
assert privilege in _main(), f"{privilege} missing from the scheme privileges"
@@ -107,6 +114,18 @@ def test_the_protocol_handler_cannot_be_walked_out_of():
# ── Content Security Policy ─────────────────────────────────────────────────
+def test_the_policy_is_sent_as_a_header():
+ """
+ A <meta> policy cannot carry `frame-ancestors`, and having it there means
+ one directive of the policy is decoration. The handler is also the only
+ thing that serves the interface, so this is one source rather than two.
+ """
+ source = _main()
+ assert "'Content-Security-Policy': CSP" in source
+ assert "Content-Security-Policy" not in INDEX.read_text(encoding="utf-8") \
+ .split("-->")[1], "the packaged page still carries a policy of its own"
+
+
def test_the_policy_keeps_wasm_unsafe_eval():
"""
The bundle key is Argon2id in WebAssembly. A policy that forbids it does not
@@ -116,14 +135,20 @@ def test_the_policy_keeps_wasm_unsafe_eval():
def _policy() -> str:
- """The meta tag's content, not the file — the comment above it names the
- same directives and would satisfy a naive search."""
+ """
+ The policy the protocol handler sends, read out of the CSP constant.
+
+ Not a <meta> tag: `frame-ancestors` is ignored there, and a directive that
+ silently does nothing is worse than one that is absent. Chromium said so in
+ the console the first time the application was launched.
+ """
import re
- page = INDEX.read_text(encoding="utf-8")
- match = re.search(
- r'http-equiv="Content-Security-Policy"\s+content="([^"]*)"', page)
- assert match, "no Content-Security-Policy meta tag"
- return match.group(1)
+ source = _main()
+ match = re.search(r"const CSP = \[(.*?)\]\.join", source, re.S)
+ assert match, "no CSP constant in the main process"
+ return "; ".join(
+ line.strip().strip('",').strip('"')
+ for line in match.group(1).splitlines() if line.strip())
def _directive(name: str) -> str: