diff --git a/package-lock.json b/package-lock.json index f8aed44..301b0ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "exif-be-gone": "^1.5.1", "fast-zlib": "^2.0.1", "fido2-lib": "^3.5.3", - "file-type": "~16.5.4", + "file-type": "^21.0.0", "form-data": "^4.0.4", "i18next": "^25.5.2", "i18next-fs-backend": "^2.6.0", @@ -1428,6 +1428,16 @@ "node": ">=6.9.0" } }, + "node_modules/@borewit/text-codec": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.1.1.tgz", + "integrity": "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", @@ -1863,6 +1873,60 @@ "node": ">=18" } }, + "node_modules/@jimp/core/node_modules/file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "license": "MIT", + "optional": true, + "dependencies": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/@jimp/core/node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@jimp/core/node_modules/token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/@jimp/diff": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@jimp/diff/-/diff-1.6.0.tgz", @@ -3965,6 +4029,24 @@ "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==", "license": "MIT" }, + "node_modules/@tokenizer/inflate": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", + "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "fflate": "^0.8.2", + "token-types": "^6.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/@tokenizer/token": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", @@ -4646,6 +4728,7 @@ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "license": "MIT", + "optional": true, "dependencies": { "event-target-shim": "^5.0.0" }, @@ -6560,6 +6643,7 @@ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "license": "MIT", + "optional": true, "engines": { "node": ">=6" } @@ -6569,6 +6653,7 @@ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", + "optional": true, "engines": { "node": ">=0.8.x" } @@ -6826,6 +6911,12 @@ "reusify": "^1.0.4" } }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" + }, "node_modules/fido2-lib": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/fido2-lib/-/fido2-lib-3.5.3.tgz", @@ -6859,17 +6950,18 @@ } }, "node_modules/file-type": { - "version": "16.5.4", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", - "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.0.0.tgz", + "integrity": "sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==", "license": "MIT", "dependencies": { - "readable-web-to-node-stream": "^3.0.0", - "strtok3": "^6.2.4", - "token-types": "^4.1.1" + "@tokenizer/inflate": "^0.2.7", + "strtok3": "^10.2.2", + "token-types": "^6.0.0", + "uint8array-extras": "^1.4.0" }, "engines": { - "node": ">=10" + "node": ">=20" }, "funding": { "url": "https://github.com/sindresorhus/file-type?sponsor=1" @@ -9711,6 +9803,7 @@ "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", "license": "MIT", + "optional": true, "engines": { "node": ">=8" }, @@ -10048,6 +10141,7 @@ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "license": "MIT", + "optional": true, "engines": { "node": ">= 0.6.0" } @@ -10299,6 +10393,7 @@ "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", "license": "MIT", + "optional": true, "dependencies": { "readable-stream": "^4.7.0" }, @@ -10329,6 +10424,7 @@ } ], "license": "MIT", + "optional": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -10339,6 +10435,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", + "optional": true, "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -11099,16 +11196,15 @@ "license": "MIT" }, "node_modules/strtok3": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", - "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz", + "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", "license": "MIT", "dependencies": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^4.1.0" + "@tokenizer/token": "^0.3.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "type": "github", @@ -11592,16 +11688,17 @@ } }, "node_modules/token-types": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", - "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.1.tgz", + "integrity": "sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==", "license": "MIT", "dependencies": { + "@borewit/text-codec": "^0.1.0", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" }, "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "type": "github", @@ -11987,6 +12084,18 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "license": "MIT" }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/undici": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici/-/undici-7.16.0.tgz", diff --git a/package.json b/package.json index c87c3dc..4c40015 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "exif-be-gone": "^1.5.1", "fast-zlib": "^2.0.1", "fido2-lib": "^3.5.3", - "file-type": "~16.5.4", + "file-type": "^21.0.0", "form-data": "^4.0.4", "i18next": "^25.5.2", "i18next-fs-backend": "^2.6.0", diff --git a/src/cdn/routes/attachments.ts b/src/cdn/routes/attachments.ts index 4c65bbb..1f3bc9f 100644 --- a/src/cdn/routes/attachments.ts +++ b/src/cdn/routes/attachments.ts @@ -18,7 +18,7 @@ import { Config, hasValidSignature, NewUrlUserSignatureData, Snowflake, UrlSignResult } from "@spacebar/util"; import { Request, Response, Router } from "express"; -import FileType from "file-type"; +import { fileTypeFromBuffer } from "file-type"; import imageSize from "image-size"; import { HTTPError } from "lambert-server"; import { multer } from "../util/multer"; @@ -92,7 +92,7 @@ const file = await storage.get(path); if (!file) throw new HTTPError("File not found"); - const type = await FileType.fromBuffer(file); + const type = await fileTypeFromBuffer(file); let content_type = type?.mime || "application/octet-stream"; if (SANITIZED_CONTENT_TYPE.includes(content_type)) { @@ -153,7 +153,7 @@ let mimeType = att.userOriginalContentType; if (att.userOriginalContentType === null) { - const ft = await FileType.fromBuffer(buffer); + const ft = await fileTypeFromBuffer(buffer); mimeType = att.contentType = ft?.mime || "application/octet-stream"; } diff --git a/src/cdn/routes/avatars.ts b/src/cdn/routes/avatars.ts index 6af3243..7e96dde 100644 --- a/src/cdn/routes/avatars.ts +++ b/src/cdn/routes/avatars.ts @@ -19,7 +19,7 @@ import { Router, Response, Request } from "express"; import { Config, Snowflake } from "@spacebar/util"; import { storage } from "../util/Storage"; -import FileType from "file-type"; +import { fileTypeFromBuffer } from "file-type"; import { HTTPError } from "lambert-server"; import crypto from "crypto"; import { multer } from "../util/multer"; @@ -56,7 +56,7 @@ .update(Snowflake.generate()) .digest("hex"); - const type = await FileType.fromBuffer(buffer); + const type = await fileTypeFromBuffer(buffer); if (!type || !ALLOWED_MIME_TYPES.includes(type.mime)) throw new HTTPError("Invalid file type"); if (ANIMATED_MIME_TYPES.includes(type.mime)) hash = `a_${hash}`; // animated icons have a_ infront of the hash @@ -83,7 +83,7 @@ const file = await storage.get(path); if (!file) throw new HTTPError("not found", 404); - const type = await FileType.fromBuffer(file); + const type = await fileTypeFromBuffer(file); res.set("Content-Type", type?.mime); res.set("Cache-Control", "public, max-age=31536000"); @@ -99,7 +99,7 @@ const file = await storage.get(path); if (!file) throw new HTTPError("not found", 404); - const type = await FileType.fromBuffer(file); + const type = await fileTypeFromBuffer(file); res.set("Content-Type", type?.mime); res.set("Cache-Control", "public, max-age=31536000"); diff --git a/src/cdn/routes/badge-icons.ts b/src/cdn/routes/badge-icons.ts index 04e96f2..44dd4c8 100644 --- a/src/cdn/routes/badge-icons.ts +++ b/src/cdn/routes/badge-icons.ts @@ -18,7 +18,7 @@ import { Router, Response, Request } from "express"; import { storage } from "../util/Storage"; -import FileType from "file-type"; +import { fileTypeFromBuffer } from "file-type"; import { HTTPError } from "lambert-server"; const router = Router(); @@ -29,7 +29,7 @@ const file = await storage.get(path); if (!file) throw new HTTPError("not found", 404); - const type = await FileType.fromBuffer(file); + const type = await fileTypeFromBuffer(file); res.set("Content-Type", type?.mime); res.set("Cache-Control", "public, max-age=31536000, must-revalidate"); diff --git a/src/cdn/routes/embed.ts b/src/cdn/routes/embed.ts index 95ac720..d0bb620 100644 --- a/src/cdn/routes/embed.ts +++ b/src/cdn/routes/embed.ts @@ -17,7 +17,7 @@ */ import { Request, Response, Router } from "express"; -import FileType from "file-type"; +import { fileTypeFromBuffer } from "file-type"; import fs from "fs/promises"; import { HTTPError } from "lambert-server"; import { join } from "path"; @@ -75,7 +75,7 @@ const file = await getFile(path); if (!file) throw new HTTPError("not found", 404); - const type = await FileType.fromBuffer(file); + const type = await fileTypeFromBuffer(file); res.set("Content-Type", type?.mime); res.set("Cache-Control", "public, max-age=31536000"); @@ -100,7 +100,7 @@ const file = await getFile(path); if (!file) throw new HTTPError("not found", 404); - const type = await FileType.fromBuffer(file); + const type = await fileTypeFromBuffer(file); res.set("Content-Type", type?.mime); res.set("Cache-Control", "public, max-age=31536000"); diff --git a/src/cdn/routes/guild-profiles.ts b/src/cdn/routes/guild-profiles.ts index 1ee5eec..4fcf1f3 100644 --- a/src/cdn/routes/guild-profiles.ts +++ b/src/cdn/routes/guild-profiles.ts @@ -19,7 +19,7 @@ import { Config, Snowflake } from "@spacebar/util"; import crypto from "crypto"; import { Request, Response, Router } from "express"; -import FileType from "file-type"; +import { fileTypeFromBuffer } from "file-type"; import { HTTPError } from "lambert-server"; import { multer } from "../util/multer"; import { storage } from "../util/Storage"; @@ -53,7 +53,7 @@ .update(Snowflake.generate()) .digest("hex"); - const type = await FileType.fromBuffer(buffer); + const type = await fileTypeFromBuffer(buffer); if (!type || !ALLOWED_MIME_TYPES.includes(type.mime)) throw new HTTPError("Invalid file type"); if (ANIMATED_MIME_TYPES.includes(type.mime)) hash = `a_${hash}`; // animated icons have a_ infront of the hash @@ -79,7 +79,7 @@ const file = await storage.get(path); if (!file) throw new HTTPError("not found", 404); - const type = await FileType.fromBuffer(file); + const type = await fileTypeFromBuffer(file); res.set("Content-Type", type?.mime); res.set("Cache-Control", "public, max-age=31536000"); @@ -95,7 +95,7 @@ const file = await storage.get(path); if (!file) throw new HTTPError("not found", 404); - const type = await FileType.fromBuffer(file); + const type = await fileTypeFromBuffer(file); res.set("Content-Type", type?.mime); res.set("Cache-Control", "public, max-age=31536000"); diff --git a/src/cdn/routes/role-icons.ts b/src/cdn/routes/role-icons.ts index 8040405..2d4f662 100644 --- a/src/cdn/routes/role-icons.ts +++ b/src/cdn/routes/role-icons.ts @@ -19,7 +19,7 @@ import { Router, Response, Request } from "express"; import { Config, Snowflake } from "@spacebar/util"; import { storage } from "../util/Storage"; -import FileType from "file-type"; +import { fileTypeFromBuffer } from "file-type"; import { HTTPError } from "lambert-server"; import crypto from "crypto"; import { multer } from "../util/multer"; @@ -56,7 +56,7 @@ .update(Snowflake.generate()) .digest("hex"); - const type = await FileType.fromBuffer(buffer); + const type = await fileTypeFromBuffer(buffer); if (!type || !ALLOWED_MIME_TYPES.includes(type.mime)) throw new HTTPError("Invalid file type"); @@ -82,7 +82,7 @@ const file = await storage.get(path); if (!file) throw new HTTPError("not found", 404); - const type = await FileType.fromBuffer(file); + const type = await fileTypeFromBuffer(file); res.set("Content-Type", type?.mime); res.set("Cache-Control", "public, max-age=31536000, must-revalidate"); @@ -114,7 +114,7 @@ } if (!file) throw new HTTPError("not found", 404); - const type = await FileType.fromBuffer(file); + const type = await fileTypeFromBuffer(file); res.set("Content-Type", type?.mime); res.set("Cache-Control", "public, max-age=31536000, must-revalidate");