95 lines
3.4 KiB
Python
95 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
from re import Pattern
|
|
|
|
from playwright.sync_api import Page, expect
|
|
|
|
from tests.wasm_ext.helpers import LiveLNbitsServer
|
|
|
|
|
|
def test_public_wasm_page_loads_sandboxed_frame(
|
|
page: Page,
|
|
lnbits_server: LiveLNbitsServer,
|
|
) -> None:
|
|
public_url = (
|
|
f"{lnbits_server.base_url}/ext/{lnbits_server.extension_id}/public/item-123"
|
|
"?source=test"
|
|
)
|
|
frame_url_part = f"/ext-frame/{lnbits_server.extension_id}/1"
|
|
|
|
with page.expect_response(lambda response: frame_url_part in response.url) as info:
|
|
page.goto(public_url)
|
|
|
|
frame_response = info.value
|
|
assert frame_response.status == 200
|
|
assert "sandbox allow-scripts" in frame_response.headers["content-security-policy"]
|
|
assert frame_response.headers["cache-control"] == "no-store"
|
|
assert frame_response.headers["x-content-type-options"] == "nosniff"
|
|
|
|
frame = page.locator("iframe.wasm-extension-frame")
|
|
expect(frame).to_have_attribute("sandbox", "allow-scripts")
|
|
expect(frame).to_have_attribute("allow", "clipboard-write")
|
|
expect(frame).to_have_attribute("referrerpolicy", "no-referrer")
|
|
expect(frame).to_have_attribute("src", _frame_src_pattern(frame_url_part))
|
|
expect(
|
|
page.frame_locator("iframe.wasm-extension-frame").locator("body")
|
|
).to_contain_text("WASM Test Public")
|
|
|
|
|
|
def test_frame_token_is_route_bound_required_and_single_use(
|
|
page: Page,
|
|
lnbits_server: LiveLNbitsServer,
|
|
) -> None:
|
|
frame_config = page.request.post(
|
|
f"{lnbits_server.base_url}/api/v1/ext/"
|
|
f"{lnbits_server.extension_id}/_ui/frame",
|
|
data={
|
|
"path": f"/ext/{lnbits_server.extension_id}/public/item-123",
|
|
"query": {"source": "test"},
|
|
},
|
|
)
|
|
assert frame_config.status == 200
|
|
frame_url = frame_config.json()["frameUrl"]
|
|
|
|
missing_token = page.request.get(
|
|
f"{lnbits_server.base_url}/ext-frame/{lnbits_server.extension_id}/1"
|
|
)
|
|
assert missing_token.status == 404
|
|
|
|
wrong_route = page.request.get(
|
|
f"{lnbits_server.base_url}{frame_url.replace('/1?', '/0?')}"
|
|
)
|
|
assert wrong_route.status == 404
|
|
|
|
first_use = page.request.get(f"{lnbits_server.base_url}{frame_url}")
|
|
assert first_use.status == 200
|
|
assert "form-action 'none'" in first_use.headers["content-security-policy"]
|
|
|
|
second_use = page.request.get(f"{lnbits_server.base_url}{frame_url}")
|
|
assert second_use.status == 404
|
|
|
|
|
|
def test_private_wasm_page_uses_lnbits_shell_and_private_frame(
|
|
authenticated_page: Page,
|
|
lnbits_server: LiveLNbitsServer,
|
|
) -> None:
|
|
page = authenticated_page
|
|
frame_url_part = f"/ext-frame/{lnbits_server.extension_id}/0"
|
|
|
|
with page.expect_response(lambda response: frame_url_part in response.url) as info:
|
|
page.goto(f"{lnbits_server.base_url}/ext/{lnbits_server.extension_id}")
|
|
|
|
assert info.value.status == 200
|
|
expect(page.locator("body")).to_contain_text("LNbits")
|
|
frame = page.locator("iframe.wasm-extension-frame")
|
|
expect(frame).to_have_attribute("sandbox", "allow-scripts")
|
|
expect(frame).to_have_attribute("src", _frame_src_pattern(frame_url_part))
|
|
expect(
|
|
page.frame_locator("iframe.wasm-extension-frame").locator("body")
|
|
).to_contain_text("WASM Test Admin")
|
|
|
|
|
|
def _frame_src_pattern(frame_url_part: str) -> Pattern[str]:
|
|
return re.compile(f"^{re.escape(frame_url_part)}\\?frame_token=[a-f0-9]{{32}}$")
|