feat: LINEWORKS Webhook署名検証ロジックを追加
This commit is contained in:
parent
20396f465d
commit
66f31d5dee
@ -0,0 +1,24 @@
|
||||
const crypto = require("node:crypto");
|
||||
|
||||
function normalizeSignature(value) {
|
||||
return String(value || "").trim().replace(/^sha256=/i, "");
|
||||
}
|
||||
|
||||
function safeEqual(a, b) {
|
||||
const ab = Buffer.from(String(a), "utf8");
|
||||
const bb = Buffer.from(String(b), "utf8");
|
||||
if (ab.length !== bb.length) return false;
|
||||
return crypto.timingSafeEqual(ab, bb);
|
||||
}
|
||||
|
||||
function verifySignature(rawBody, headerSignature, botSecret) {
|
||||
const headerSig = normalizeSignature(headerSignature);
|
||||
if (!headerSig || !botSecret) return false;
|
||||
|
||||
const payload = Buffer.isBuffer(rawBody) ? rawBody : Buffer.from(String(rawBody), "utf8");
|
||||
const expected = crypto.createHmac("sha256", botSecret).update(payload).digest("base64");
|
||||
|
||||
return safeEqual(headerSig, expected);
|
||||
}
|
||||
|
||||
module.exports = { verifySignature };
|
||||
@ -0,0 +1,27 @@
|
||||
// test/signatureVerify.test.js
|
||||
const { test } = require("node:test");
|
||||
const assert = require("node:assert");
|
||||
const crypto = require("node:crypto");
|
||||
const { verifySignature } = require("../src/lib/signatureVerify");
|
||||
|
||||
test("正しい署名はtrueを返す", () => {
|
||||
const secret = "test-secret";
|
||||
const body = JSON.stringify({ hello: "world" });
|
||||
const signature = crypto.createHmac("sha256", secret).update(body).digest("base64");
|
||||
assert.strictEqual(verifySignature(body, signature, secret), true);
|
||||
});
|
||||
|
||||
test("sha256=プレフィックス付き署名も検証できる", () => {
|
||||
const secret = "test-secret";
|
||||
const body = JSON.stringify({ hello: "world" });
|
||||
const signature = crypto.createHmac("sha256", secret).update(body).digest("base64");
|
||||
assert.strictEqual(verifySignature(body, `sha256=${signature}`, secret), true);
|
||||
});
|
||||
|
||||
test("不正な署名はfalseを返す", () => {
|
||||
assert.strictEqual(verifySignature("body", "invalid-signature", "secret"), false);
|
||||
});
|
||||
|
||||
test("署名ヘッダーが空ならfalseを返す", () => {
|
||||
assert.strictEqual(verifySignature("body", "", "secret"), false);
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user