Skip to content

Commit ebf773c

Browse files
committed
feat: always assume sha256, remove SignOptions
BREAKING CHANGE: The `verify()` and `sign()` methods no longer accept an options object
1 parent 30b2044 commit ebf773c

File tree

5 files changed

+10
-91
lines changed

5 files changed

+10
-91
lines changed

src/node/sign.ts

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,7 @@
11
import { createHmac } from "node:crypto";
2-
import { Algorithm, type SignOptions } from "../types.js";
32
import { VERSION } from "../version.js";
43

5-
export async function sign(secret: string, payload: string): Promise<string>;
6-
export async function sign(
7-
options: SignOptions,
8-
payload: string,
9-
): Promise<string>;
10-
export async function sign(
11-
options: SignOptions | string,
12-
payload: string,
13-
): Promise<string> {
14-
const { secret, algorithm } =
15-
typeof options === "object"
16-
? {
17-
secret: options.secret,
18-
algorithm: options.algorithm || Algorithm.SHA256,
19-
}
20-
: { secret: options, algorithm: Algorithm.SHA256 };
21-
4+
export async function sign(secret: string, payload: string): Promise<string> {
225
if (!secret || !payload) {
236
throw new TypeError(
247
"[@octokit/webhooks-methods] secret & payload required for sign()",
@@ -29,11 +12,7 @@ export async function sign(
2912
throw new TypeError("[@octokit/webhooks-methods] payload must be a string");
3013
}
3114

32-
if (!Object.values(Algorithm).includes(algorithm as Algorithm)) {
33-
throw new TypeError(
34-
`[@octokit/webhooks] Algorithm ${algorithm} is not supported. Must be 'sha256'`,
35-
);
36-
}
15+
const algorithm = "sha256";
3716

3817
return `${algorithm}=${createHmac(algorithm, secret)
3918
.update(payload)

src/node/verify.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ export async function verify(
2222
}
2323

2424
const signatureBuffer = Buffer.from(signature);
25-
const algorithm = "sha256";
2625

27-
const verificationBuffer = Buffer.from(
28-
await sign({ secret, algorithm }, eventPayload),
29-
);
26+
const verificationBuffer = Buffer.from(await sign(secret, eventPayload));
3027

3128
if (signatureBuffer.length !== verificationBuffer.length) {
3229
return false;

src/types.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/web.ts

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { Algorithm, type AlgorithmLike, type SignOptions } from "./types.js";
2-
31
const enc = new TextEncoder();
42

53
function hexToUInt8Array(string: string) {
@@ -20,43 +18,22 @@ function UInt8ArrayToHex(signature: ArrayBuffer) {
2018
.join("");
2119
}
2220

23-
function getHMACHashName(algorithm: AlgorithmLike) {
24-
return (
25-
{
26-
[Algorithm.SHA256]: "SHA-256",
27-
} as { [key in Algorithm]: string }
28-
)[algorithm];
29-
}
30-
31-
async function importKey(secret: string, algorithm: AlgorithmLike) {
21+
async function importKey(secret: string) {
3222
// ref: https://developer.mozilla.org/en-US/docs/Web/API/HmacImportParams
3323
return crypto.subtle.importKey(
3424
"raw", // raw format of the key - should be Uint8Array
3525
enc.encode(secret),
3626
{
3727
// algorithm details
3828
name: "HMAC",
39-
hash: { name: getHMACHashName(algorithm) },
29+
hash: { name: "sha256" },
4030
},
4131
false, // export = false
4232
["sign", "verify"], // what this key can do
4333
);
4434
}
4535

46-
export async function sign(secret: string, payload: string): Promise<string>;
47-
export async function sign(
48-
options: SignOptions,
49-
payload: string,
50-
): Promise<string>;
51-
export async function sign(options: SignOptions | string, payload: string) {
52-
const { secret, algorithm } =
53-
typeof options === "object"
54-
? {
55-
secret: options.secret,
56-
algorithm: options.algorithm || Algorithm.SHA256,
57-
}
58-
: { secret: options, algorithm: Algorithm.SHA256 };
59-
36+
export async function sign(secret: string, payload: string): Promise<string> {
6037
if (!secret || !payload) {
6138
throw new TypeError(
6239
"[@octokit/webhooks-methods] secret & payload required for sign()",
@@ -67,15 +44,10 @@ export async function sign(options: SignOptions | string, payload: string) {
6744
throw new TypeError("[@octokit/webhooks-methods] payload must be a string");
6845
}
6946

70-
if (!Object.values(Algorithm).includes(algorithm as Algorithm)) {
71-
throw new TypeError(
72-
`[@octokit/webhooks] Algorithm ${algorithm} is not supported. Must be 'sha256'`,
73-
);
74-
}
75-
47+
const algorithm = "sha256";
7648
const signature = await crypto.subtle.sign(
7749
"HMAC",
78-
await importKey(secret, algorithm),
50+
await importKey(secret),
7951
enc.encode(payload),
8052
);
8153

@@ -102,7 +74,7 @@ export async function verify(
10274
const algorithm = "sha256";
10375
return await crypto.subtle.verify(
10476
"HMAC",
105-
await importKey(secret, algorithm),
77+
await importKey(secret),
10678
hexToUInt8Array(signature.replace(`${algorithm}=`, "")),
10779
enc.encode(eventPayload),
10880
);

test/sign.test.ts

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,32 +45,13 @@ describe("sign", () => {
4545
});
4646

4747
describe("with eventPayload as string", () => {
48-
describe("returns expected sha1 signature", () => {
48+
describe("returns expected sha256 signature", () => {
4949
test("sign(secret, eventPayload)", async () => {
5050
const signature = await sign(secret, JSON.stringify(eventPayload));
5151
expect(signature).toBe(
5252
"sha256=4864d2759938a15468b5df9ade20bf161da9b4f737ea61794142f3484236bda3",
5353
);
5454
});
55-
56-
test("sign({secret}, eventPayload)", async () => {
57-
const signature = await sign({ secret }, JSON.stringify(eventPayload));
58-
expect(signature).toBe(
59-
"sha256=4864d2759938a15468b5df9ade20bf161da9b4f737ea61794142f3484236bda3",
60-
);
61-
});
62-
});
63-
64-
describe("returns expected sha256 signature", () => {
65-
test("sign({secret, algorithm: 'sha256'}, eventPayload)", async () => {
66-
const signature = await sign(
67-
{ secret, algorithm: "sha256" },
68-
JSON.stringify(eventPayload),
69-
);
70-
expect(signature).toBe(
71-
"sha256=4864d2759938a15468b5df9ade20bf161da9b4f737ea61794142f3484236bda3",
72-
);
73-
});
7455
});
7556
});
7657

0 commit comments

Comments
 (0)