A tile that draws whatever an address serves: no binding, no flow, just an iframe. Only http(s) loads — a `javascript:` src would run in the app's own origin, and a dashboard is a document several people can edit.
40 lines
1.0 KiB
TypeScript
40 lines
1.0 KiB
TypeScript
/**
|
|
* Which addresses an embed widget will load, checked.
|
|
*
|
|
* ponytail: a script rather than a suite, as with the other `.check.ts` files:
|
|
*
|
|
* cd frontend && bun run src/components/Dashboard/embed.check.ts
|
|
*
|
|
* The guard is the point. An `<iframe src>` of `javascript:` or `data:` runs
|
|
* in this app's own origin, so anything but `http(s)` has to come out empty.
|
|
*/
|
|
|
|
import assert from "node:assert/strict"
|
|
|
|
import type { WidgetDef } from "@/client"
|
|
import { embedUrl } from "./widgets"
|
|
|
|
const widget = (url: unknown): WidgetDef =>
|
|
({ id: "e", type: "embed", config: { url } }) as WidgetDef
|
|
|
|
for (const url of [
|
|
"https://embed.ventusky.com/?p=49.41;8.93;9",
|
|
"http://camera.local/ui",
|
|
" https://example.com/page ",
|
|
]) {
|
|
assert.equal(embedUrl(widget(url)), url.trim(), url)
|
|
}
|
|
|
|
for (const url of [
|
|
"javascript:alert(1)",
|
|
"data:text/html,<script>alert(1)</script>",
|
|
"//example.com",
|
|
"/panel/main",
|
|
"",
|
|
undefined,
|
|
]) {
|
|
assert.equal(embedUrl(widget(url)), "", String(url))
|
|
}
|
|
|
|
console.log("embed: ok")
|