Ctrl K
ComunidadGuías…

server/validation.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { randomUUID } from "node:crypto";
import { Buckets } from "./models/helpers/AttachmentHelper";
import { ValidateKey, isISO8601Duration } from "./validation";

describe("#ValidateKey.isValid", () => {
  it("should return false if number of key components is incorrect", () => {
    expect(
      ValidateKey.isValid(
        `${Buckets.uploads}/${randomUUID()}/${randomUUID()}/foo/bar`
      )
    ).toBe(false);
  });

  it("should return false if the first key component is not a valid bucket", () => {
    expect(
      ValidateKey.isValid(`foo/${randomUUID()}/${randomUUID()}/bar.png`)
    ).toBe(false);
  });

  it("should return false if second and third key components are not UUID", () => {
    expect(
      ValidateKey.isValid(`${Buckets.uploads}/foo/${randomUUID()}/bar.png`)
    ).toBe(false);
    expect(
      ValidateKey.isValid(`${Buckets.uploads}/${randomUUID()}/foo/bar.png`)
    ).toBe(false);
  });

  it("should return true successfully validating key", () => {
    expect(
      ValidateKey.isValid(
        `${Buckets.public}/${randomUUID()}/${randomUUID()}/foo.png`
      )
    ).toBe(true);
    expect(
      ValidateKey.isValid(
        `${Buckets.uploads}/${randomUUID()}/${randomUUID()}/foo.png`
      )
    ).toBe(true);
    expect(
      ValidateKey.isValid(`${Buckets.avatars}/${randomUUID()}/${randomUUID()}`)
    ).toBe(true);
  });
});

describe("#ValidateKey.sanitize", () => {
  it("should sanitize malicious looking keys", () => {
    const uuid1 = randomUUID();
    const uuid2 = randomUUID();
    expect(
      ValidateKey.sanitize(`public/${uuid1}/${uuid2}/~.\u0000malicious_key`)
    ).toEqual(`public/${uuid1}/${uuid2}/~.malicious_key`);
  });

  it("should remove potential path traversal", () => {
    const uuid1 = randomUUID();
    const uuid2 = randomUUID();
    expect(
      ValidateKey.sanitize(`public/${uuid1}/${uuid2}/../../malicious_key`)
    ).toEqual(`public/${uuid1}/${uuid2}/malicious_key`);
  });

  it("should remove problematic characters", () => {
    const uuid1 = randomUUID();
    const uuid2 = randomUUID();
    expect(ValidateKey.sanitize(`public/${uuid1}/${uuid2}/test#:*?`)).toEqual(
      `public/${uuid1}/${uuid2}/test`
    );
  });
});

describe("#isISO8601Duration", () => {
  describe("valid cases", () => {
    it.each([
      "P1Y",
      "P1M",
      "P1D",
      "P1W",
      "P52W",
      "P0D",
      "P10Y",
      "P365D",
      "PT1H",
      "PT30M",
      "PT45S",
      "PT1H30M",
      "PT1H30M45S",
      "PT24H",
      "PT1500S",
      "PT0S",
      "P1Y2M",
      "P1Y2M3D",
      "P2M3D",
      "P1DT12H",
      "P1Y2M3DT4H5M6S",
      "-P1D",
      "-P7D",
      "-PT1H",
      "-P1Y2M3DT4H5M6S",
      "-P1W",
    ])("accepts %s", (value) => {
      expect(isISO8601Duration(value)).toBe(true);
    });
  });

  describe("invalid cases", () => {
    it.each([
      // Missing prefix
      "1D",
      "T1H",
      "Y1",
      // Empty / lone prefix
      "",
      "P",
      "PT",
      "-P",
      "-PT",
      // Missing number
      "PD",
      "PMW",
      "PT H",
      // Missing unit
      "P1",
      "PT1",
      "P1Y2",
      // Unknown unit
      "P1Z",
      "P1X",
      "PT1Q",
      // Wrong section (date vs time)
      "P1H",
      "PT1Y",
      "PT1D",
      // Trailing T
      "P1DT",
      "P1YT",
      // Weeks combined with other units
      "P1W1D",
      "P1Y1W",
      // Decimals
      "P1.5D",
      "P0.5W",
      "PT1.5H",
      // Sign in wrong place
      "P-1D",
      "PT-1H",
      "--P1D",
      "+P1D",
      // Whitespace
      "P 1D",
      "P1D ",
      " P1D",
      "- P1D",
      // Lowercase
      "p1d",
      "P1d",
      "pt1h",
      // Quotes / SQL metacharacters
      "P1D'",
      "P1D; DROP TABLE",
      "P1D--",
      "P1D OR 1=1",
      // Order swap
      "P1D1Y",
      "P1M1Y",
    ])("rejects %j", (value) => {
      expect(isISO8601Duration(value)).toBe(false);
    });
  });
});

describe("#ValidateKey.sanitizeSegment", () => {
  it("should leave an ordinary name untouched", () => {
    expect(ValidateKey.sanitizeSegment("My Document")).toEqual("My Document");
  });

  it("should remove path separators", () => {
    expect(ValidateKey.sanitizeSegment("../../../public/foo")).not.toContain(
      "/"
    );
    expect(ValidateKey.sanitizeSegment("..\\..\\public\\foo")).not.toContain(
      "\\"
    );
  });

  it("should remove problematic characters", () => {
    expect(ValidateKey.sanitizeSegment("test#:*?")).toEqual("test");
  });
});