From 247c0645e527d199421784cd292afa3abf163845 Mon Sep 17 00:00:00 2001 From: wolfy1339 Date: Thu, 22 Feb 2024 20:19:47 -0500 Subject: [PATCH 1/3] style: prettier --- src/node/sign.ts | 5 ++++- src/web.ts | 5 ++++- test/tsconfig.test.json | 1 - 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/node/sign.ts b/src/node/sign.ts index cd57330..e67bd4b 100644 --- a/src/node/sign.ts +++ b/src/node/sign.ts @@ -3,7 +3,10 @@ import { Algorithm, type SignOptions } from "../types.js"; import { VERSION } from "../version.js"; export async function sign(secret: string, payload: string): Promise; -export async function sign(options: SignOptions, payload: string): Promise; +export async function sign( + options: SignOptions, + payload: string, +): Promise; export async function sign( options: SignOptions | string, payload: string, diff --git a/src/web.ts b/src/web.ts index e923a39..42c34e3 100644 --- a/src/web.ts +++ b/src/web.ts @@ -46,7 +46,10 @@ async function importKey(secret: string, algorithm: AlgorithmLike) { } export async function sign(secret: string, payload: string): Promise; -export async function sign(options: SignOptions, payload: string): Promise; +export async function sign( + options: SignOptions, + payload: string, +): Promise; export async function sign(options: SignOptions | string, payload: string) { const { secret, algorithm } = typeof options === "object" diff --git a/test/tsconfig.test.json b/test/tsconfig.test.json index 5e8dc24..cf1f200 100644 --- a/test/tsconfig.test.json +++ b/test/tsconfig.test.json @@ -3,7 +3,6 @@ "compilerOptions": { "emitDeclarationOnly": false, "noEmit": true, - "verbatimModuleSyntax": false, "allowImportingTsExtensions": true }, "include": ["src/**/*"] From 815352dc1f2c35b9db3194814c8be7b4333f5d3a Mon Sep 17 00:00:00 2001 From: wolfy1339 Date: Thu, 22 Feb 2024 20:20:06 -0500 Subject: [PATCH 2/3] test: update jest config for ESM --- package.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 139e9c8..8d3161e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "lint:fix": "prettier --write '{src,test,scripts}/**/*' README.md package.json", "pretest": "npm run -s lint", "test": "npm run -s test:node && npm run -s test:web", - "test:node": "jest --coverage", + "test:node": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" npx jest --coverage", "test:web": "npm run test:deno && npm run test:browser", "pretest:web": "npm run -s build", "test:deno": "cd test/deno && deno test", @@ -42,11 +42,15 @@ "typescript": "^5.0.0" }, "jest": { + "extensionsToTreatAsEsm": [ + ".ts" + ], "transform": { "^.+\\.(ts|tsx)$": [ "ts-jest", { - "tsconfig": "test/tsconfig.test.json" + "tsconfig": "test/tsconfig.test.json", + "useESM": true } ] }, From 30b204486839cdcc949ac89efdb77d2d73882fa6 Mon Sep 17 00:00:00 2001 From: wolfy1339 Date: Thu, 22 Feb 2024 20:56:21 -0500 Subject: [PATCH 3/3] feat: remove SHA1 support BREAKING CHANGE: remove SHA1 support --- src/node/sign.ts | 2 +- src/node/verify.ts | 3 +-- src/types.ts | 3 +-- src/utils.ts | 3 --- src/web.ts | 6 ++---- test/sign.test.ts | 10 +--------- test/verify.test.ts | 44 -------------------------------------------- 7 files changed, 6 insertions(+), 65 deletions(-) delete mode 100644 src/utils.ts diff --git a/src/node/sign.ts b/src/node/sign.ts index e67bd4b..c04c7b1 100644 --- a/src/node/sign.ts +++ b/src/node/sign.ts @@ -31,7 +31,7 @@ export async function sign( if (!Object.values(Algorithm).includes(algorithm as Algorithm)) { throw new TypeError( - `[@octokit/webhooks] Algorithm ${algorithm} is not supported. Must be 'sha1' or 'sha256'`, + `[@octokit/webhooks] Algorithm ${algorithm} is not supported. Must be 'sha256'`, ); } diff --git a/src/node/verify.ts b/src/node/verify.ts index f155f18..ef1f106 100644 --- a/src/node/verify.ts +++ b/src/node/verify.ts @@ -3,7 +3,6 @@ import { Buffer } from "node:buffer"; import { sign } from "./sign.js"; import { VERSION } from "../version.js"; -import { getAlgorithm } from "../utils.js"; export async function verify( secret: string, @@ -23,7 +22,7 @@ export async function verify( } const signatureBuffer = Buffer.from(signature); - const algorithm = getAlgorithm(signature); + const algorithm = "sha256"; const verificationBuffer = Buffer.from( await sign({ secret, algorithm }, eventPayload), diff --git a/src/types.ts b/src/types.ts index ce72b46..01b6f7a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,9 +1,8 @@ export enum Algorithm { - SHA1 = "sha1", SHA256 = "sha256", } -export type AlgorithmLike = Algorithm | "sha1" | "sha256"; +export type AlgorithmLike = Algorithm | "sha256"; export type SignOptions = { secret: string; diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index d1e6444..0000000 --- a/src/utils.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const getAlgorithm = (signature: string) => { - return signature.startsWith("sha256=") ? "sha256" : "sha1"; -}; diff --git a/src/web.ts b/src/web.ts index 42c34e3..83f1679 100644 --- a/src/web.ts +++ b/src/web.ts @@ -1,5 +1,4 @@ import { Algorithm, type AlgorithmLike, type SignOptions } from "./types.js"; -import { getAlgorithm } from "./utils.js"; const enc = new TextEncoder(); @@ -24,7 +23,6 @@ function UInt8ArrayToHex(signature: ArrayBuffer) { function getHMACHashName(algorithm: AlgorithmLike) { return ( { - [Algorithm.SHA1]: "SHA-1", [Algorithm.SHA256]: "SHA-256", } as { [key in Algorithm]: string } )[algorithm]; @@ -71,7 +69,7 @@ export async function sign(options: SignOptions | string, payload: string) { if (!Object.values(Algorithm).includes(algorithm as Algorithm)) { throw new TypeError( - `[@octokit/webhooks] Algorithm ${algorithm} is not supported. Must be 'sha1' or 'sha256'`, + `[@octokit/webhooks] Algorithm ${algorithm} is not supported. Must be 'sha256'`, ); } @@ -101,7 +99,7 @@ export async function verify( ); } - const algorithm = getAlgorithm(signature); + const algorithm = "sha256"; return await crypto.subtle.verify( "HMAC", await importKey(secret, algorithm), diff --git a/test/sign.test.ts b/test/sign.test.ts index acd3463..6004625 100644 --- a/test/sign.test.ts +++ b/test/sign.test.ts @@ -40,7 +40,7 @@ describe("sign", () => { // @ts-expect-error sign({ secret, algorithm: "sha2" }, JSON.stringify(eventPayload)), ).rejects.toThrow( - "[@octokit/webhooks] Algorithm sha2 is not supported. Must be 'sha1' or 'sha256'", + "[@octokit/webhooks] Algorithm sha2 is not supported. Must be 'sha256'", ); }); @@ -59,14 +59,6 @@ describe("sign", () => { "sha256=4864d2759938a15468b5df9ade20bf161da9b4f737ea61794142f3484236bda3", ); }); - - test("sign({secret, algorithm: 'sha1'}, eventPayload)", async () => { - const signature = await sign( - { secret, algorithm: "sha1" }, - JSON.stringify(eventPayload), - ); - expect(signature).toBe("sha1=d03207e4b030cf234e3447bac4d93add4c6643d8"); - }); }); describe("returns expected sha256 signature", () => { diff --git a/test/verify.test.ts b/test/verify.test.ts index 3b8e386..a901dc3 100644 --- a/test/verify.test.ts +++ b/test/verify.test.ts @@ -11,7 +11,6 @@ function toNormalizedJsonString(payload: object) { const JSONeventPayload = { foo: "bar" }; const eventPayload = toNormalizedJsonString(JSONeventPayload); const secret = "mysecret"; -const signatureSHA1 = "sha1=640c0ea7402a3f74e1767338fa2dba243b1f2d9c"; const signatureSHA256 = "sha256=e3eccac34c43c7dc1cbb905488b1b81347fcc700a7b025697a9d07862256023f"; @@ -52,49 +51,6 @@ describe("verify", () => { ); }); - test("verify(secret, eventPayload, signatureSHA1) returns true for correct signature", async () => { - const signatureMatches = await verify(secret, eventPayload, signatureSHA1); - expect(signatureMatches).toBe(true); - }); - - test("verify(secret, eventPayload, signatureSHA1) returns false for incorrect signature", async () => { - const signatureMatches = await verify(secret, eventPayload, "foo"); - expect(signatureMatches).toBe(false); - }); - - test("verify(secret, eventPayload, signatureSHA1) returns false for correct secret", async () => { - const signatureMatches = await verify("foo", eventPayload, signatureSHA1); - expect(signatureMatches).toBe(false); - }); - - test("verify(secret, eventPayload, signatureSHA1) returns true if eventPayload contains special characters (#71)", async () => { - // https://github.com/octokit/webhooks.js/issues/71 - const signatureMatchesLowerCaseSequence = await verify( - "development", - toNormalizedJsonString({ - foo: "Foo\n\u001b[34mbar: ♥♥♥♥♥♥♥♥\nthis-is-lost\u001b[0m\u001b[2K", - }), - "sha1=82a91c5aacc9cdc2eea893bc828bd03d218df79c", - ); - expect(signatureMatchesLowerCaseSequence).toBe(true); - const signatureMatchesUpperCaseSequence = await verify( - "development", - toNormalizedJsonString({ - foo: "Foo\n\u001B[34mbar: ♥♥♥♥♥♥♥♥\nthis-is-lost\u001B[0m\u001B[2K", - }), - "sha1=82a91c5aacc9cdc2eea893bc828bd03d218df79c", - ); - expect(signatureMatchesUpperCaseSequence).toBe(true); - const signatureMatchesEscapedSequence = await verify( - "development", - toNormalizedJsonString({ - foo: "\\u001b", - }), - "sha1=bdae4705bdd827d026bb227817ca025b5b3a6756", - ); - expect(signatureMatchesEscapedSequence).toBe(true); - }); - test("verify(secret, eventPayload, signatureSHA256) returns true for correct signature", async () => { const signatureMatches = await verify( secret,