Files
homarr/packages/api/src/router/test/custom-widget/legacy-migration.spec.ts
T
+12 fcd7c979df feat!: release v2 (#6545)
Co-authored-by: Artur <145776561+arturict@users.noreply.github.com>
Co-authored-by: arturict <arturict@users.noreply.github.com>
Co-authored-by: Thomas <thomas@ajnart.fr>
Co-authored-by: Afonso Jorge Ramos <afonsojorgeramos@gmail.com>
Co-authored-by: Danura30082 <danura30082+github@gmail.com>
Co-authored-by: Kushie <122986913+kushiemoon-dev@users.noreply.github.com>
Co-authored-by: ajnart <thomas@ajnart.fr>
Co-authored-by: ajnart <thomas@ajnart.dev>
Co-authored-by: chenjun <chenjun@foxmail.com>
Co-authored-by: Wikibear <wikibear@users.noreply.github.com>
Co-authored-by: Bergasha <bergasha@gmail.com>
Co-authored-by: leafyelin <43306196+leafyelin@users.noreply.github.com>
Co-authored-by: Lucas Araujo <lucas.lra@gmail.com>
Co-authored-by: GreenMonito <86085570+GreenMonito@users.noreply.github.com>
Co-authored-by: Nerdy-Technician <roffo@nerdy-technician.social>
Co-authored-by: Jun <34545896+jcstrong@users.noreply.github.com>
Co-authored-by: Edmond Abraham <54119952+gitedmond@users.noreply.github.com>
Co-authored-by: thrawnx <tight.bulb9384@fastmail.com>
Co-authored-by: Chris <58918656+nordada@users.noreply.github.com>
Co-authored-by: yi111 <153097222+Yi-111-a@users.noreply.github.com>
Co-authored-by: Yanis <naamaneyanis@gmail.com>
Co-authored-by: Wikibear <me@sej.de>
Co-authored-by: alessiottavo <93441886+alessiottavo@users.noreply.github.com>
2026-10-02 21:00:14 +02:00

106 lines
3.8 KiB
TypeScript

import { describe, expect, test } from "vitest";
import { stringify as stringifySuperJson } from "superjson";
import { buildLegacyCustomWidgetMigrationPrompt } from "../../custom-widget/legacy-migration";
describe("legacy custom widget migration prompt", () => {
test("preserves ordinary request values while redacting credential-like values", () => {
const prompt = buildLegacyCustomWidgetMigrationPrompt(
{
id: "legacy",
name: "Private service",
description: "Status",
iconUrl: "https://icons:password@example.test/private/icon.svg?access_token=icon-secret",
url: "https://admin:password@example.test/api/v1/path-token/status?api_key=top-secret&mode=full&page=2",
authType: "bearer",
headerName: null,
method: "POST",
requestBody: JSON.stringify({ token: "body-secret", limit: 5, label: "CPU" }),
displayType: "singleValue",
displayConfig: "corrupted-config-with-display-secret",
enabled: true,
createdAt: new Date(0),
updatedAt: new Date(0),
creatorId: null,
},
["apiKey"],
);
expect(prompt).toContain("homarr-custom-widget-v1");
expect(prompt).toContain("homarr-custom-widget-v2");
expect(prompt).toContain('"path": "/api/v1/[REDACTED]/status"');
expect(prompt).toContain('"mode": "full"');
expect(prompt).toContain('"page": "2"');
expect(prompt).toContain("https://example.test/private/icon.svg");
expect(prompt).toContain('"limit": 5');
expect(prompt).toContain('"label": "CPU"');
expect(prompt).toContain("display configuration is unavailable");
expect(prompt).not.toContain("top-secret");
expect(prompt).not.toContain("body-secret");
expect(prompt).not.toContain("admin:password");
expect(prompt).not.toContain("path-token");
expect(prompt).not.toContain("icon-secret");
expect(prompt).not.toContain("icons:password");
expect(prompt).not.toContain("display-secret");
expect(prompt).not.toContain('"requestBody"');
});
test("redacts a custom api-key query value without losing its parameter name", () => {
const prompt = buildLegacyCustomWidgetMigrationPrompt(
{
id: "legacy-api-key-query",
name: "Query-key service",
description: "Status",
iconUrl: null,
url: "https://example.test/api/status?sig=custom-query-secret&mode=full",
authType: "apiKeyQuery",
headerName: "sig",
method: "GET",
requestBody: null,
displayType: "singleValue",
displayConfig: "{}",
enabled: true,
createdAt: new Date(0),
updatedAt: new Date(0),
creatorId: null,
},
["apiKey"],
);
expect(prompt).toContain('"sig": "[REDACTED]"');
expect(prompt).toContain('"mode": "full"');
expect(prompt).toContain('"headerName": "sig"');
expect(prompt).not.toContain("custom-query-secret");
});
test("preserves valid JSX display configuration while redacting literals", () => {
const prompt = buildLegacyCustomWidgetMigrationPrompt(
{
id: "legacy-custom-jsx",
name: "Private service",
description: "Status",
iconUrl: null,
url: "https://example.test/api/status",
authType: "bearer",
headerName: null,
method: "GET",
requestBody: null,
displayType: "customJsx",
displayConfig: stringifySuperJson({
type: "customJsx",
template: "<Text>LEGACY_PRIVATE_MARKER Bearer sk-secret-123456</Text>",
}),
enabled: true,
createdAt: new Date(0),
updatedAt: new Date(0),
creatorId: null,
},
["apiKey"],
);
expect(prompt).toContain("LEGACY_PRIVATE_MARKER");
expect(prompt).not.toContain("Bearer sk-secret-123456");
expect(prompt).not.toContain("sk-secret-123456");
});
});