82 lines
2.4 KiB
TypeScript
82 lines
2.4 KiB
TypeScript
import { describe, expect, test } from "vitest";
|
|
|
|
import {
|
|
onboardingCompleteSetupSchema,
|
|
onboardingCreateIntegrationSchema,
|
|
onboardingDiscoveredAppSchema,
|
|
} from "./onboarding";
|
|
|
|
describe("onboarding URL validation", () => {
|
|
test.each(["javascript:alert(1)", "data:text/html,hello", "file:///etc/passwd"])(
|
|
"rejects the %s scheme for integrations",
|
|
(url) => {
|
|
expect(onboardingCreateIntegrationSchema.safeParse({ name: "Unsafe", url }).success).toBe(false);
|
|
},
|
|
);
|
|
|
|
test("accepts HTTP services and icon identifiers", () => {
|
|
expect(
|
|
onboardingDiscoveredAppSchema.safeParse({
|
|
name: "Sonarr",
|
|
sourceId: "docker:sonarr",
|
|
href: "http://sonarr:8989",
|
|
pingUrl: "https://sonarr.example.com/ping",
|
|
iconUrl: "sonarr",
|
|
description: "TV automation",
|
|
}).success,
|
|
).toBe(true);
|
|
});
|
|
|
|
test("accepts bounded integration metadata and rejects invalid metadata", () => {
|
|
expect(
|
|
onboardingCreateIntegrationSchema.safeParse({
|
|
name: "Sonarr",
|
|
url: "http://sonarr:8989",
|
|
pingUrl: "https://sonarr.example.com/ping",
|
|
iconUrl: "https://icons.example/sonarr.svg",
|
|
description: "TV automation",
|
|
}).success,
|
|
).toBe(true);
|
|
expect(
|
|
onboardingCreateIntegrationSchema.safeParse({
|
|
name: "Sonarr",
|
|
url: "http://sonarr:8989",
|
|
pingUrl: "file:///etc/passwd",
|
|
description: "x".repeat(513),
|
|
}).success,
|
|
).toBe(false);
|
|
});
|
|
|
|
test("rejects non-web app and ping URLs", () => {
|
|
expect(
|
|
onboardingDiscoveredAppSchema.safeParse({
|
|
name: "Unsafe",
|
|
href: "javascript:alert(1)",
|
|
pingUrl: "file:///etc/passwd",
|
|
iconUrl: null,
|
|
}).success,
|
|
).toBe(false);
|
|
});
|
|
|
|
test("requires every app submitted to completeSetup to have an HTTP(S) href", () => {
|
|
const input = {
|
|
server: { defaultLocale: "en", defaultColorScheme: "dark" },
|
|
board: {
|
|
name: "dashboard",
|
|
primaryColor: "#228BE6",
|
|
secondaryColor: "#15AABF",
|
|
itemRadius: "md",
|
|
},
|
|
apps: [{ sourceId: "docker:status", name: "Status", href: null, iconUrl: null }],
|
|
};
|
|
|
|
expect(onboardingCompleteSetupSchema.safeParse(input).success).toBe(false);
|
|
expect(
|
|
onboardingCompleteSetupSchema.safeParse({
|
|
...input,
|
|
apps: [{ ...input.apps[0], href: "https://status.example.com" }],
|
|
}).success,
|
|
).toBe(true);
|
|
});
|
|
});
|