@hookflo/tern
Version:
A robust, scalable webhook verification framework supporting multiple platforms and signature algorithms
71 lines (70 loc) • 2.43 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenBasedVerifier = void 0;
exports.createCustomVerifier = createCustomVerifier;
const base_1 = require("./base");
// Token-based verifier for platforms like Supabase
class TokenBasedVerifier extends base_1.WebhookVerifier {
constructor(secret, config, toleranceInSeconds = 300) {
super(secret, toleranceInSeconds);
this.config = config;
}
async verify(request) {
try {
const token = request.headers.get(this.config.headerName);
const id = request.headers.get(this.config.customConfig?.idHeader || "x-webhook-id");
if (!token) {
return {
isValid: false,
error: `Missing token header: ${this.config.headerName}`,
platform: "custom",
};
}
// Simple token comparison
const isValid = this.safeCompare(token, this.secret);
if (!isValid) {
return {
isValid: false,
error: "Invalid token",
platform: "custom",
};
}
const rawBody = await request.text();
let payload;
try {
payload = JSON.parse(rawBody);
}
catch (e) {
payload = rawBody;
}
return {
isValid: true,
platform: "custom",
payload,
metadata: {
id,
algorithm: "token-based",
},
};
}
catch (error) {
return {
isValid: false,
error: `Token-based verification error: ${error.message}`,
platform: "custom",
};
}
}
}
exports.TokenBasedVerifier = TokenBasedVerifier;
// Factory function to create custom verifiers
function createCustomVerifier(secret, config, toleranceInSeconds = 300) {
const customType = config.customConfig?.type;
switch (customType) {
case "token-based":
return new TokenBasedVerifier(secret, config, toleranceInSeconds);
default:
// Fallback to token-based for unknown custom types
return new TokenBasedVerifier(secret, config, toleranceInSeconds);
}
}