import { nanoid } from 'nanoid'; import * as z from 'zod'; import { invites } from '~~/drizzle/schema'; import { db } from '~~/server/lib/db'; const TOKEN_LENGTH = 32; const HOUR_MS = 60 * 60 * 1000; const MAX_USES = 1000; const MAX_HOURS = 24 * 365; /** Creates an invite link that works for the given time and number of people. */ export default defineEventHandler(async (event) => { await protectAdminRoute(event); const result = await readValidatedBody(event, (body) => z .object({ maxUses: z.int().min(1).max(MAX_USES), expiresInHours: z.int().min(1).max(MAX_HOURS), }) .safeParse(body), ); if (!result.success) { throw createError({ statusCode: 400, message: result.error.issues[0]!.message, }); } const { maxUses, expiresInHours } = result.data; const [invite] = await db.insert(invites) .values({ token: nanoid(TOKEN_LENGTH), createdBy: event.context.user!.id as string, maxUses, expiresAt: new Date(Date.now() + expiresInHours * HOUR_MS), }) .returning({ id: invites.id, token: invites.token, maxUses: invites.maxUses, uses: invites.uses, expiresAt: invites.expiresAt, createdAt: invites.createdAt, }); return invite!; });