Skip to content

Commit

Permalink
fix: validate files to be uploaded (#3872)
Browse files Browse the repository at this point in the history
* Only allow certain file types to be uploaded

* refactor file type checking

* move file type check to docs-validator

* Add file types rule to all rules list

* Split out validator function and add a test

* Check if file exists before checking its type
  • Loading branch information
trevorblades authored Jun 21, 2024
1 parent 1ae3090 commit a262eb7
Show file tree
Hide file tree
Showing 18 changed files with 264 additions and 1 deletion.
91 changes: 91 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 2 additions & 0 deletions packages/cli/yaml/docs-validator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
"@fern-api/workspace-loader": "workspace:*",
"@fern-api/yaml-schema": "workspace:*",
"@types/tinycolor2": "^1.4.6",
"file-type": "^19.0.0",
"is-svg": "^5.0.1",
"next-mdx-remote": "^4.4.1",
"remark-gfm": "^3.0.1",
"tinycolor2": "^1.6.0",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { readFile } from "fs/promises";
import path from "path";
import { isValidFileType } from "../../rules/valid-file-types/valid-file-types";

describe("isValidFileType", () => {
it("should return true for valid file types", async () => {
const file = await readFile(path.join(__dirname, "bird.jpg"));
const isValid = await isValidFileType(file);
expect(isValid).toBe(true);
});

it("should return false for invalid file types", async () => {
const file = await readFile(path.join(__dirname, "bird.zip"));
const isValid = await isValidFileType(file);
expect(isValid).toBe(false);
});
});
4 changes: 3 additions & 1 deletion packages/cli/yaml/docs-validator/src/getAllRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Rule } from "./Rule";
import { AccentColorContrastRule } from "./rules/accent-color-contrast";
import { FilepathsExistRule } from "./rules/filepaths-exist";
import { OnlyVersionedNavigation } from "./rules/only-versioned-navigation";
import { ValidFileTypes } from "./rules/valid-file-types";
import { ValidMarkdownRule } from "./rules/valid-markdown";
import { ValidMarkdownLinks } from "./rules/valid-markdown-link";
import { ValidateVersionFileRule } from "./rules/validate-version-file";
Expand All @@ -13,6 +14,7 @@ export function getAllRules(): Rule[] {
OnlyVersionedNavigation,
ValidateVersionFileRule,
AccentColorContrastRule,
ValidMarkdownLinks
ValidMarkdownLinks,
ValidFileTypes
];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ValidFileTypes } from "./valid-file-types";
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { doesPathExist } from "@fern-api/fs-utils";
import { fileTypeFromBuffer } from "file-type";
import { readFile } from "fs/promises";
import isSvg from "is-svg";
import { Rule } from "../../Rule";

const ALLOWED_FILE_TYPES = [
// image files
"image/jpeg",
"image/png",
"image/gif",
"image/webp",
"image/tiff",
// video files
"video/quicktime",
"video/mp4",
"video/webm",
// audio files
"audio/mpeg",
"audio/ogg",
"audio/wav",
// document files
"application/pdf"
];

export const ValidFileTypes: Rule = {
name: "valid-file-types",
create: () => {
return {
filepath: async ({ absoluteFilepath, value }) => {
const doesExist = await doesPathExist(absoluteFilepath);

if (doesExist) {
const file = await readFile(absoluteFilepath);
const isValid = await isValidFileType(file);

if (!isValid) {
return [
{
severity: "error",
message: `File type of ${value} is invalid`
}
];
}
}

return [];
}
};
}
};

export const isValidFileType = async (file: Buffer): Promise<boolean> => {
if (isSvg(file.toString("utf-8"))) {
// exit early if the file is an SVG
return true;
}

// otherwise, check the file type
const fileType = await fileTypeFromBuffer(file);
if (fileType && ALLOWED_FILE_TYPES.includes(fileType.mime)) {
return true;
}

// in all other cases, return false
return false;
};
Loading

0 comments on commit a262eb7

Please sign in to comment.