diff --git a/src/methods/generateImageInfoUrl.test.ts b/src/methods/generateImageInfoUrl.test.ts index 00a9007..add0de1 100644 --- a/src/methods/generateImageInfoUrl.test.ts +++ b/src/methods/generateImageInfoUrl.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest"; import { OptionsImageInfo } from "@imgproxy/imgproxy-js-core"; import generateImageInfoUrl from "./generateImageInfoUrl"; -describe("generateImageInfourl", () => { +describe("generateImageInfoUrl", () => { it("should generate a valid URL", () => { const options: OptionsImageInfo = { average: { average: 1, ignore_transparent: "f" }, @@ -43,7 +43,7 @@ describe("generateImageInfourl", () => { }); expect(result).toBe( - "https://imgproxy.example.com/info/insecure/bh:4:3/d:f/f:t/xmp:f/aHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZS5qcGc=" + "https://imgproxy.example.com/info/insecure/bh:4:3/d:f/f:t/xmp:f/aHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZS5qcGc" ); }); @@ -56,7 +56,7 @@ describe("generateImageInfourl", () => { }); expect(result).toBe( - "https://imgproxy.example.com/info/S27LCUL9UqVzUUEh4PuP2fMuoszQetA6qj5T07tlmZ4/aHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZS5qcGc=" + "https://imgproxy.example.com/info/xOner18d7-LJwkl4bifXGbC1_4kZXxsPLnuuvsMtcWo/aHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZS5qcGc" ); }); diff --git a/src/methods/generateImageUrl.test.ts b/src/methods/generateImageUrl.test.ts index e30a5c0..2ec77df 100644 --- a/src/methods/generateImageUrl.test.ts +++ b/src/methods/generateImageUrl.test.ts @@ -22,7 +22,7 @@ describe("generateImageUrl", () => { }); expect(result).toBe( - "https://imgproxy.example.com/OISSn9zHS-E-xpsQPcsvKaTLVJePQgHG3MvDBbvk5lU/el:t/f:png/g:no/h:300/rt:fit/w:300/aHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZS5qcGc=" + "https://imgproxy.example.com/zsdsCjFCqcAniKFCygMBToRh6l5jVZbL0bhrnnUGK58/el:t/f:png/g:no/h:300/rt:fit/w:300/aHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZS5qcGc" ); }); @@ -44,7 +44,7 @@ describe("generateImageUrl", () => { }); expect(result).toBe( - "https://imgproxy.example.com/insecure/ar:t/cb:clear/ex:t/f:webp/g:noea:10:10/sa:10/w:300/aHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZS5qcGc=" + "https://imgproxy.example.com/insecure/ar:t/cb:clear/ex:t/f:webp/g:noea:10:10/sa:10/w:300/aHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZS5qcGc" ); }); @@ -57,7 +57,7 @@ describe("generateImageUrl", () => { }); expect(result).toBe( - "https://imgproxy.example.com/S27LCUL9UqVzUUEh4PuP2fMuoszQetA6qj5T07tlmZ4/aHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZS5qcGc=" + "https://imgproxy.example.com/xOner18d7-LJwkl4bifXGbC1_4kZXxsPLnuuvsMtcWo/aHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZS5qcGc" ); }); diff --git a/src/utils/bufferToBase64.test.ts b/src/utils/bufferToBase64.test.ts new file mode 100644 index 0000000..e8fbe24 --- /dev/null +++ b/src/utils/bufferToBase64.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, it } from "vitest"; +import bufferToBase64 from "./bufferToBase64"; + +describe("bufferToBase64", () => { + it("should return a base64 string", () => { + const result = bufferToBase64(Buffer.from("Hello, World!")); + + expect(result).toBe("SGVsbG8sIFdvcmxkIQ"); + }); + + it("should return a base64 string without padding", () => { + const result = bufferToBase64(Buffer.from("Hello, World!")); + + expect(result).not.toContain("="); + }); + + it("should return a base64 string with - instead of +", () => { + const result = bufferToBase64(Buffer.from("Hello World!")); + + expect(result).not.toContain("+"); + }); + + it("should return a base64 string with _ instead of /", () => { + const result = bufferToBase64(Buffer.from("attached/attachment.jpg")); + + expect(result).not.toContain("/"); + }); +}); diff --git a/src/utils/bufferToBase64.ts b/src/utils/bufferToBase64.ts new file mode 100644 index 0000000..fc031e6 --- /dev/null +++ b/src/utils/bufferToBase64.ts @@ -0,0 +1,9 @@ +const bufferToBase64 = (buffer: Buffer): string => { + return buffer + .toString("base64") + .replace(/=/g, "") + .replace(/\+/g, "-") + .replace(/\//g, "_"); +}; + +export default bufferToBase64; diff --git a/src/utils/getEncryptedUrl.ts b/src/utils/getEncryptedUrl.ts index ac367d1..aec4d14 100644 --- a/src/utils/getEncryptedUrl.ts +++ b/src/utils/getEncryptedUrl.ts @@ -1,5 +1,6 @@ import crypto from "crypto"; import { ICryptPair } from "../types.js"; +import bufferToBase64 from "./bufferToBase64.js"; import withCache from "./withCache.js"; const getEncryptedUrl = (url: string, pair: ICryptPair): string => { @@ -13,11 +14,7 @@ const getEncryptedUrl = (url: string, pair: ICryptPair): string => { "binary" ); - return Buffer.concat([iv, encrypted]) - .toString("base64") - .replace(/=/g, "") - .replace(/\+/g, "-") - .replace(/\//g, "_"); + return bufferToBase64(Buffer.concat([iv, encrypted])); }; const withCacheGetEncryptedUrl = withCache(getEncryptedUrl); diff --git a/src/utils/normalizeUrl.ts b/src/utils/normalizeUrl.ts index 31b6e89..0a1bb12 100644 --- a/src/utils/normalizeUrl.ts +++ b/src/utils/normalizeUrl.ts @@ -1,5 +1,6 @@ import type { URL } from "@imgproxy/imgproxy-js-core"; import type { IRawUrl } from "../types"; +import bufferToBase64 from "./bufferToBase64.js"; import getEncryptPair from "./getEncryptPair.js"; import getEncryptedUrl from "./getEncryptedUrl.js"; @@ -17,7 +18,7 @@ const normalizeUrl = ({ url, encryptKey, encryptIV }: INormalizeUrl): URL => { //encoded url to base64 if (changedUrl.type === "base64") { - changedUrl.value = btoa(changedUrl.value); + changedUrl.value = bufferToBase64(Buffer.from(changedUrl.value)); } //encrypting url