import { ActionError, defineAction } from 'astro:actions'; import { z } from 'astro:schema'; import { db } from '@db/database.ts'; import { getJavaUuid } from '@util/minecraft.ts'; import { getSetting, SettingKey } from '@util/settings.ts'; import { sendWebhook, WebhookAction } from '@util/webhook.ts'; function getClientIp(context: { request: Request; clientAddress: string }) { const forwardedFor = context.request.headers.get('x-forwarded-for'); if (forwardedFor) { const ip = forwardedFor.split(',')[0].trim(); if (ip) return ip; } return context.clientAddress; } export const signup = { signup: defineAction({ input: z.object({ firstname: z.string().trim().min(2), lastname: z.string().trim().min(2), birthday: z .string() .date() // this will be inaccurate as it is evaluated only once .max(Date.now() - 1000 * 60 * 60 * 24 * 365 * 6), phone: z.string().trim().nullable(), username: z.string().trim(), edition: z.enum(['java', 'bedrock']), code: z.string().nullish() }), handler: async (input, context) => { // check if code given and if so, if it's valid and nobody has already used it if (input.code) { const directSignup = await db.getDirectSignupByCode({ code: input.code }); if (!directSignup) { throw new ActionError({ code: 'NOT_FOUND' }); } else if (directSignup.user) { throw new ActionError({ code: 'CONFLICT' }); } } // check if signup is allowed else if (!(await getSetting(db, SettingKey.SignupEnabled))) { throw new ActionError({ code: 'FORBIDDEN', message: 'Die Anmeldung ist derzeit deaktiviert' }); } // check if the user were already signed up else if (await db.getUserByUsername({ username: input.username })) { throw new ActionError({ code: 'CONFLICT', message: 'Du hast dich bereits registriert' }); } let uuid = null; if (input.edition == 'java') { try { uuid = await getJavaUuid(input.username); } catch (_) { throw new ActionError({ code: 'NOT_FOUND', message: `Es wurde kein Minecraft Java Account mit dem Username ${input.username} gefunden` }); } } await db.transaction(async (tx) => { const user = await tx.addUser({ firstname: input.firstname, lastname: input.lastname, birthday: input.birthday, telephone: input.phone, username: input.username, edition: input.edition, uuid: uuid }); if (input.code) { await tx.setDirectSignupUser({ code: input.code, userId: user.id }); } if (uuid) { await tx.linkDirectSignupUserByUuid({ uuid: uuid, userId: user.id }); } }); sendWebhook(WebhookAction.Signup, { firstname: input.firstname, lastname: input.lastname, birthday: new Date(input.birthday).toISOString().slice(0, 10), telephone: input.phone, username: input.username, edition: input.edition, uuid: uuid, ip: getClientIp(context) }); } }) };