Vérifier la signature HMAC du webhook StoryBlok avant de déclencher le rebuild
This commit is contained in:
parent
789f85609d
commit
1183f140a1
3 changed files with 18 additions and 5 deletions
|
|
@ -6,6 +6,8 @@ PUBLIC_STORYBLOK_TOKEN=
|
||||||
# PUBLIC_STORYBLOK_IS_PREVIEW=true
|
# PUBLIC_STORYBLOK_IS_PREVIEW=true
|
||||||
|
|
||||||
# Webhook rebuild — uniquement sur l'instance preview
|
# Webhook rebuild — uniquement sur l'instance preview
|
||||||
|
# Secret partagé avec StoryBlok (Settings > Webhooks > Secret du Webhook)
|
||||||
|
# STORYBLOK_WEBHOOK_SECRET=
|
||||||
# Token OAuth Clever Cloud (généré via clever login puis ~/.config/clever-cloud/clever-tools.json)
|
# Token OAuth Clever Cloud (généré via clever login puis ~/.config/clever-cloud/clever-tools.json)
|
||||||
# CLEVER_TOKEN=
|
# CLEVER_TOKEN=
|
||||||
# ID de l'application Clever Cloud de production (app_xxxxxxxx)
|
# ID de l'application Clever Cloud de production (app_xxxxxxxx)
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ Le serveur démarre sur le port `8080` par défaut (configurable via `PORT`).
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `PUBLIC_STORYBLOK_TOKEN` | Public Access Token | Preview Access Token |
|
| `PUBLIC_STORYBLOK_TOKEN` | Public Access Token | Preview Access Token |
|
||||||
| `PUBLIC_STORYBLOK_IS_PREVIEW` | *(non défini)* | `true` |
|
| `PUBLIC_STORYBLOK_IS_PREVIEW` | *(non défini)* | `true` |
|
||||||
|
| `STORYBLOK_WEBHOOK_SECRET` | - | Secret du webhook StoryBlok |
|
||||||
| `CLEVER_TOKEN` | - | Token OAuth Clever Cloud |
|
| `CLEVER_TOKEN` | - | Token OAuth Clever Cloud |
|
||||||
| `CLEVER_APP_ID_PRODUCTION` | - | ID de l'app production (app_xxx) |
|
| `CLEVER_APP_ID_PRODUCTION` | - | ID de l'app production (app_xxx) |
|
||||||
| `CC_POST_BUILD_HOOK` | `npm run build` | `npm run build` |
|
| `CC_POST_BUILD_HOOK` | `npm run build` | `npm run build` |
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,21 @@
|
||||||
import type { APIRoute } from 'astro';
|
import type { APIRoute } from 'astro';
|
||||||
|
import { createHmac, timingSafeEqual } from 'node:crypto';
|
||||||
|
|
||||||
export const POST: APIRoute = async () => {
|
export const POST: APIRoute = async ({ request }) => {
|
||||||
|
const webhookSecret = import.meta.env.STORYBLOK_WEBHOOK_SECRET;
|
||||||
const token = import.meta.env.CLEVER_TOKEN;
|
const token = import.meta.env.CLEVER_TOKEN;
|
||||||
const appId = import.meta.env.CLEVER_APP_ID_PRODUCTION;
|
const appId = import.meta.env.CLEVER_APP_ID_PRODUCTION;
|
||||||
|
|
||||||
if (!token || !appId) {
|
if (!webhookSecret || !token || !appId) {
|
||||||
return new Response('Missing CLEVER_TOKEN or CLEVER_APP_ID_PRODUCTION', { status: 500 });
|
return new Response('Missing server configuration', { status: 500 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = await request.text();
|
||||||
|
const signature = request.headers.get('webhook-signature') ?? '';
|
||||||
|
const expected = createHmac('sha1', webhookSecret).update(body).digest('hex');
|
||||||
|
|
||||||
|
if (!timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
|
||||||
|
return new Response('Invalid signature', { status: 401 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
|
|
@ -17,8 +27,8 @@ export const POST: APIRoute = async () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const body = await response.text();
|
const error = await response.text();
|
||||||
return new Response(`Clever Cloud API error: ${response.status} ${body}`, { status: 502 });
|
return new Response(`Clever Cloud API error: ${response.status} ${error}`, { status: 502 });
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Response('Rebuild triggered', { status: 200 });
|
return new Response('Rebuild triggered', { status: 200 });
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue