Package JavaScript
Utilisez le package JavaScript de cside pour vérifier les signatures webhook et gérer les événements de notification avec un support TypeScript complet.
Installer le package
Installez le package webhooks de cside :
npm i @cside.dev/webhooks
Utiliser le package
constructEvent(body, signature, secret) vérifie l’en-tête x-cside-signature
par rapport au corps brut de la requête et renvoie l’événement analysé. Il lève
Error("Invalid signature") lorsque la signature ne correspond pas : entourez
donc l’appel d’un try/catch et répondez 400 dans ce cas.
import { constructEvent } from "@cside.dev/webhooks";
const rawBody = req.rawBody; // The raw request body as a string; how you get it depends on your HTTP framework
const signature = req.headers["x-cside-signature"]; // Sent with every cside webhook request
const event = await constructEvent(
rawBody,
signature,
process.env.CSIDE_WEBHOOK_SECRET, // The secret you configured on the webhook destination
);
switch (event.event) {
case "alert.created": {
const alert = event.data;
console.log({
domainId: event.domain_id,
target: alert.target,
action: alert.action,
});
}
}
Le package exporte aussi verifyHmac(body, signature, secret) si vous n’avez
besoin que de la vérification de signature et souhaitez analyser le corps
vous-même.
Les types Event et AlertCreatedObject fournis dans @cside.dev/webhooks
décrivent un ancien payload. Le moteur envoie timestamp (et non sent_at),
ainsi que domain et trigger_type au premier niveau, et l’objet data
utilise target_type et contient des champs ruleset_* et vuln_*. Le
package ne type également que alert.created, pas les événements de digest.
Consultez la référence du
payload pour les champs
réellement envoyés, et castez ou validez l’événement renvoyé en conséquence.
Exemples
import Fastify from 'fastify';
import { constructEvent } from "@cside.dev/webhooks";
const fastify = Fastify({ logger: true });
await fastify.register(import('@fastify/raw-body'), {
field: 'rawBody',
global: false,
routes: ['/webhook']
});
fastify.post('/webhook', {
config: { rawBody: true }
}, async (request, reply) => {
const signature = request.headers['x-cside-signature'];
const webhookEvent = await constructEvent(
request.rawBody,
signature,
process.env.CSIDE_WEBHOOK_SECRET!,
);
switch (webhookEvent.event) {
case "alert.created": {
const alert = webhookEvent.data;
console.log({
domainId: webhookEvent.domain_id,
target: alert.target,
action: alert.action,
});
}
}
});import { createKaitoHandler, KaitoError } from "@kaito-http/core";
import { constructEvent } from "@cside.dev/webhooks";
const app = router()
.get("/", async ({ ctx }) => {
return {
uptime: ctx.uptime,
time_now: Date.now(),
};
})
.post("/", async ({ ctx }) => {
const signature = ctx.req.headers.get("x-cside-signature");
if (!signature) {
throw new KaitoError(400, "Missing signature");
}
const rawBody = await ctx.req.text();
const webhookEvent = await constructEvent(
rawBody,
signature,
process.env.CSIDE_WEBHOOK_SECRET!,
);
switch (webhookEvent.event) {
case "alert.created": {
const alert = webhookEvent.data;
console.log({
domainId: webhookEvent.domain_id,
target: alert.target,
action: alert.action,
});
}
}
return {
message: "OK!",
};
});Thanks for your feedback!