mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
import {
|
|
ExpressResponse,
|
|
NextFunction,
|
|
OneUptimeRequest,
|
|
} from "../Utils/Express";
|
|
import Response from "../Utils/Response";
|
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
import GlobalConfig from "../../Models/DatabaseModels/GlobalConfig";
|
|
import GlobalConfigService from "../Services/GlobalConfigService";
|
|
import ObjectID from "../../Types/ObjectID";
|
|
import crypto from "crypto";
|
|
import logger from "../Utils/Logger";
|
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
|
|
export default class WhatsAppAuthorization {
|
|
@CaptureSpan()
|
|
public static async isAuthorizedWhatsAppRequest(
|
|
req: OneUptimeRequest,
|
|
res: ExpressResponse,
|
|
next: NextFunction,
|
|
): Promise<void> {
|
|
logger.debug("Starting WhatsApp webhook signature verification");
|
|
|
|
const signature: string | undefined = req.headers["x-hub-signature-256"] as
|
|
| string
|
|
| undefined;
|
|
|
|
if (!signature) {
|
|
logger.error(
|
|
"WhatsApp webhook request missing X-Hub-Signature-256 header.",
|
|
);
|
|
return Response.sendErrorResponse(
|
|
req,
|
|
res,
|
|
new BadDataException("Missing X-Hub-Signature-256 header."),
|
|
);
|
|
}
|
|
|
|
const globalConfig: GlobalConfig | null =
|
|
await GlobalConfigService.findOneBy({
|
|
query: {
|
|
_id: ObjectID.getZeroObjectID().toString(),
|
|
},
|
|
props: {
|
|
isRoot: true,
|
|
},
|
|
select: {
|
|
metaWhatsAppAppSecret: true,
|
|
},
|
|
});
|
|
|
|
const appSecret: string | undefined =
|
|
globalConfig?.metaWhatsAppAppSecret?.trim() || undefined;
|
|
|
|
if (!appSecret) {
|
|
logger.error(
|
|
"Meta WhatsApp App Secret is not configured. Cannot verify webhook signature.",
|
|
);
|
|
return Response.sendErrorResponse(
|
|
req,
|
|
res,
|
|
new BadDataException("Meta WhatsApp App Secret is not configured."),
|
|
);
|
|
}
|
|
|
|
const rawBody: string = req.rawBody || "";
|
|
|
|
const expectedSignature: string = `sha256=${crypto.createHmac("sha256", appSecret).update(rawBody).digest("hex")}`;
|
|
|
|
if (
|
|
!crypto.timingSafeEqual(
|
|
Buffer.from(expectedSignature) as Uint8Array,
|
|
Buffer.from(signature) as Uint8Array,
|
|
)
|
|
) {
|
|
logger.error("WhatsApp webhook signature verification failed.");
|
|
return Response.sendErrorResponse(
|
|
req,
|
|
res,
|
|
new BadDataException("WhatsApp webhook signature verification failed."),
|
|
);
|
|
}
|
|
|
|
logger.debug("WhatsApp webhook signature verified successfully");
|
|
next();
|
|
}
|
|
}
|