Files
formbricks/apps/web/app/api/v1/webhooks/route.ts
T
Dhruwang Jariwala 939fedfca4 feat: Formbricks 5 (#8017)
Signed-off-by: gulshank0 <gulshanbahadur002@gmail.com>
Co-authored-by: Tiago Farto <tiago@formbricks.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
Co-authored-by: pandeymangg <anshuman.pandey9999@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Tiago <1585571+xernobyl@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Theodór Tómas <theodortomas@gmail.com>
Co-authored-by: Anshuman Pandey <54475686+pandeymangg@users.noreply.github.com>
Co-authored-by: Bhagya Amarasinghe <b.sithumini@yahoo.com>
Co-authored-by: Chowdhury Tafsir Ahmed Siddiki <ctafsiras@gmail.com>
Co-authored-by: neila <40727091+neila@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Harsh Bhat <90265455+harshsbhat@users.noreply.github.com>
Co-authored-by: Harsh Bhat <harshbhat@Harshs-MacBook-Air.local>
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Balázs Úr <balazs@urbalazs.hu>
Co-authored-by: Gulshan <gulshanbahadur002@gmail.com>
Co-authored-by: Harsh Bhat <harsh121102@gmail.com>
Co-authored-by: Javi Aguilar <122741+itsjavi@users.noreply.github.com>
Co-authored-by: Johannes <jobenjada@users.noreply.github.com>
2026-05-15 16:43:27 +00:00

105 lines
3.2 KiB
TypeScript

import { DatabaseError, InvalidInputError } from "@formbricks/types/errors";
import { resolveBodyIds } from "@/app/api/v1/management/lib/workspace-resolver";
import { createWebhook, getWebhooks } from "@/app/api/v1/webhooks/lib/webhook";
import { ZWebhookInput } from "@/app/api/v1/webhooks/types/webhooks";
import { responses } from "@/app/lib/api/response";
import { transformErrorToDetails } from "@/app/lib/api/validator";
import { THandlerParams, withV1ApiWrapper } from "@/app/lib/api/with-api-logging";
import { hasPermission } from "@/modules/organization/settings/api-keys/lib/utils";
export const GET = withV1ApiWrapper({
handler: async ({ authentication }: THandlerParams) => {
if (!authentication || !("apiKeyId" in authentication)) {
return { response: responses.notAuthenticatedResponse() };
}
try {
const workspaceIds = [
...new Set(authentication.workspacePermissions.map((permission) => permission.workspaceId)),
];
const webhooks = await getWebhooks(workspaceIds);
return {
response: responses.successResponse(webhooks),
};
} catch (error) {
if (error instanceof DatabaseError) {
return {
response: responses.internalServerErrorResponse(error.message),
};
}
throw error;
}
},
});
export const POST = withV1ApiWrapper({
handler: async ({ req, auditLog, authentication }: THandlerParams) => {
if (!authentication || !("apiKeyId" in authentication)) {
return { response: responses.notAuthenticatedResponse() };
}
let webhookInput;
try {
webhookInput = await req.json();
} catch {
return {
response: responses.badRequestResponse("Malformed JSON input, please check your request body"),
};
}
// Accept workspaceId as alternative to environmentId
const resolved = await resolveBodyIds(webhookInput, authentication.workspacePermissions, "POST");
if (!resolved.ok) return { response: resolved.response };
webhookInput = resolved.body;
const inputValidation = ZWebhookInput.safeParse(webhookInput);
if (!inputValidation.success) {
return {
response: responses.badRequestResponse(
"Fields are missing or incorrectly formatted",
transformErrorToDetails(inputValidation.error),
true
),
};
}
const { workspaceId } = inputValidation.data;
if (
!resolved.alreadyAuthorized &&
!hasPermission(authentication.workspacePermissions, workspaceId, "POST")
) {
return {
response: responses.unauthorizedResponse(),
};
}
try {
const webhook = await createWebhook(inputValidation.data);
if (auditLog) {
auditLog.targetId = webhook.id;
auditLog.newObject = webhook;
}
return {
response: responses.successResponse(webhook),
};
} catch (error) {
if (error instanceof InvalidInputError) {
return {
response: responses.badRequestResponse(error.message),
};
}
if (error instanceof DatabaseError) {
return {
response: responses.internalServerErrorResponse(error.message),
};
}
throw error;
}
},
action: "created",
targetType: "webhook",
});