Validate hookdeck webhooks

This commit is contained in:
2025-06-02 12:05:41 +03:00
parent 0cd5c6cb69
commit 80fe63b82e
6 changed files with 31 additions and 0 deletions

View File

@@ -4,3 +4,4 @@ NUXT_SESSION_PASSWORD=
NUXT_WEBHOOKS_URL= NUXT_WEBHOOKS_URL=
NUXT_STRAVA_VERIFY_TOKEN= NUXT_STRAVA_VERIFY_TOKEN=
NUXT_HUB_PROJECT_KEY= NUXT_HUB_PROJECT_KEY=
NUXT_HOOKDECK_KEY=

View File

@@ -11,6 +11,7 @@ export default defineNuxtConfig({
runtimeConfig: { runtimeConfig: {
webhooksUrl: "", webhooksUrl: "",
stravaVerifyToken: "", stravaVerifyToken: "",
hookdeckKey: "",
openaiApiKey: "", openaiApiKey: "",
databaseUrl: "", databaseUrl: "",
public: { public: {

View File

@@ -1,6 +1,8 @@
import { createActivityContent } from "~~/server/utils/create-content"; import { createActivityContent } from "~~/server/utils/create-content";
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
await validateHookdeck(event);
const body = await readBody(event); const body = await readBody(event);
const db = useDrizzle(); const db = useDrizzle();

View File

@@ -2,6 +2,8 @@ import { get } from "radash";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
await validateHookdeck(event);
const body = await readBody(event); const body = await readBody(event);
const db = useDrizzle(); const db = useDrizzle();

View File

@@ -1,6 +1,9 @@
import { get } from "radash"; import { get } from "radash";
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
await validateHookdeck(event);
const config = useRuntimeConfig();
const body = await readBody(event); const body = await readBody(event);
const aspectType = get(body, "aspect_type"); const aspectType = get(body, "aspect_type");
@@ -9,5 +12,8 @@ export default defineEventHandler(async (event) => {
await $fetch(`/webhooks/strava/${objectType}-${aspectType}`, { await $fetch(`/webhooks/strava/${objectType}-${aspectType}`, {
method: "post", method: "post",
body, body,
headers: {
"X-Hookdeck-Key": config.hookdeckKey,
},
}); });
}); });

View File

@@ -0,0 +1,19 @@
import type { H3Event } from "h3";
import { isEmpty } from "radash";
export const validateHookdeck = async (event: H3Event) => {
const hookdeckKeyHeader = getHeader(event, "X-Hookdeck-Key");
const config = useRuntimeConfig();
if (isEmpty(hookdeckKeyHeader)) {
throw createError({
status: 401,
});
}
if (hookdeckKeyHeader !== config.hookdeckKey) {
throw createError({
status: 401,
});
}
};