Files
stats/apps/dashboard/src/app/api/clerk/webhook/route.ts
Carl-Gerhard Lindesvärd 0bc0af8177 fixes
2024-07-01 22:37:38 +02:00

124 lines
3.2 KiB
TypeScript

import type { WebhookEvent } from '@clerk/nextjs/server';
import { pathOr } from 'ramda';
import { AccessLevel, db } from '@openpanel/db';
export async function POST(request: Request) {
const payload: WebhookEvent = await request.json();
if (payload.type === 'user.created') {
const email = payload.data.email_addresses[0]?.email_address;
const emails = payload.data.email_addresses.map((e) => e.email_address);
if (!email) {
return Response.json(
{ message: 'No email address found' },
{ status: 400 }
);
}
const user = await db.user.create({
data: {
id: payload.data.id,
email,
firstName: payload.data.first_name,
lastName: payload.data.last_name,
},
});
const memberships = await db.member.findMany({
where: {
email: {
in: emails,
},
userId: null,
},
});
for (const membership of memberships) {
const access = pathOr<string[]>([], ['meta', 'access'], membership);
await db.$transaction([
// Update the member to link it to the user
// This will remove the item from invitations
db.member.update({
where: {
id: membership.id,
},
data: {
userId: user.id,
},
}),
db.projectAccess.createMany({
data: access
.filter((a) => typeof a === 'string')
.map((projectId) => ({
organizationSlug: membership.organizationId,
organizationId: membership.organizationId,
projectId: projectId,
userId: user.id,
level: AccessLevel.read,
})),
}),
]);
}
}
if (payload.type === 'organizationMembership.created') {
const access = payload.data.public_metadata.access;
if (Array.isArray(access)) {
await db.projectAccess.createMany({
data: access
.filter((a): a is string => typeof a === 'string')
.map((projectId) => ({
organizationSlug: payload.data.organization.slug,
organizationId: payload.data.organization.slug,
projectId: projectId,
userId: payload.data.public_user_data.user_id,
level: AccessLevel.read,
})),
});
}
}
if (payload.type === 'user.deleted') {
await db.$transaction([
db.user.update({
where: {
id: payload.data.id,
},
data: {
deletedAt: new Date(),
firstName: null,
lastName: null,
email: `deleted+${payload.data.id}@openpanel.dev`,
},
}),
db.projectAccess.deleteMany({
where: {
userId: payload.data.id,
},
}),
db.member.deleteMany({
where: {
userId: payload.data.id,
},
}),
]);
}
if (payload.type === 'organizationMembership.deleted') {
await db.projectAccess.deleteMany({
where: {
organizationSlug: payload.data.organization.slug,
userId: payload.data.public_user_data.user_id,
},
});
}
return Response.json({ message: 'Webhook received!' });
}
export function GET() {
return Response.json({ message: 'Hello World!' });
}