28 lines
1.5 KiB
TypeScript
28 lines
1.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { sanitizeNextPath } from "@/utils/external-file";
|
|
|
|
// N8 D5 — path วนกลับหลัง login ต้องเป็น path ใน app เท่านั้น (กัน open-redirect)
|
|
describe("sanitizeNextPath", () => {
|
|
it("path ใน app (มี query ก็ได้) ผ่านตรง ๆ", () => {
|
|
expect(sanitizeNextPath("/")).toBe("/");
|
|
expect(sanitizeNextPath("/annotate")).toBe("/annotate");
|
|
expect(sanitizeNextPath("/annotate/abc-123")).toBe("/annotate/abc-123");
|
|
expect(sanitizeNextPath("/?fileUrl=https://x&fileId=1")).toBe(
|
|
"/?fileUrl=https://x&fileId=1",
|
|
);
|
|
});
|
|
|
|
it("absolute URL / protocol-relative / backslash → null กัน open-redirect", () => {
|
|
expect(sanitizeNextPath("//evil.com")).toBeNull();
|
|
expect(sanitizeNextPath("/\\evil.com")).toBeNull(); // browser ตีความ \ เป็น /
|
|
expect(sanitizeNextPath("https://evil.com")).toBeNull();
|
|
expect(sanitizeNextPath("http://evil.com/path")).toBeNull();
|
|
expect(sanitizeNextPath("/\\//evil.com")).toBeNull();
|
|
});
|
|
|
|
it("ค่าว่าง/ไม่ขึ้นต้น / ขาด ๆ เกิน ๆ → null", () => {
|
|
expect(sanitizeNextPath("")).toBeNull();
|
|
expect(sanitizeNextPath("annotate")).toBeNull(); // ไม่มี / นำหน้า
|
|
expect(sanitizeNextPath(" /annotate")).toBeNull(); // space นำหน้าไม่ผ่าน startsWith
|
|
});
|
|
});
|