import jwt from 'jsonwebtoken' import PreRegistration from '../../models/preRegistration.js' import Member from '../../models/member.js' import { connectDB } from '../../utils/mongoose.js' import { assignMemberNumber } from '../../utils/memberNumber.js' export default defineEventHandler(async (event) => { const body = await validateBody(event, inviteAcceptSchema) const config = useRuntimeConfig(event) await connectDB() // Re-verify the token is still valid (not expired) let decoded try { decoded = jwt.verify(body.token, config.jwtSecret) } catch { throw createError({ statusCode: 401, statusMessage: 'Invalid or expired invitation link' }) } if (decoded.type !== 'prereg-invite' || decoded.preRegistrationId !== body.preRegistrationId) { throw createError({ statusCode: 401, statusMessage: 'Invalid or expired invitation link' }) } const preReg = await PreRegistration.findById(body.preRegistrationId) if (!preReg) { throw createError({ statusCode: 404, statusMessage: 'Pre-registration not found' }) } if (preReg.status === 'accepted') { throw createError({ statusCode: 400, statusMessage: 'This invitation has already been accepted' }) } // Check no existing member with this email const existingMember = await Member.findOne({ email: preReg.email }) if (existingMember) { throw createError({ statusCode: 409, statusMessage: 'A member with this email already exists' }) } // Create the member const member = await Member.create({ email: preReg.email, name: body.name, pronouns: body.pronouns || undefined, location: body.location || undefined, circle: body.circle, contributionTier: body.contributionTier, bio: body.motivation || undefined, status: body.contributionTier === '0' ? 'active' : 'pending_payment', }) await assignMemberNumber(member._id) // Update pre-registration await PreRegistration.findByIdAndUpdate(preReg._id, { $set: { status: 'accepted', acceptedAt: new Date(), memberId: member._id, } }) logActivity(member._id, 'member_joined', { source: 'pre-registration', preRegistrationId: preReg._id, }) // For free tier, issue session and redirect to welcome if (body.contributionTier === '0') { const sessionToken = jwt.sign( { memberId: member._id, email: member.email, tv: member.tokenVersion }, config.jwtSecret, { expiresIn: '7d' }, ) setCookie(event, 'auth-token', sessionToken, { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', path: '/', maxAge: 60 * 60 * 24 * 7, }) return { success: true, requiresPayment: false, redirectUrl: '/member/dashboard', member: { id: member._id, email: member.email, name: member.name, circle: member.circle, contributionTier: member.contributionTier, status: member.status, } } } // For paid tiers, return member info so frontend can proceed to Helcim payment return { success: true, requiresPayment: true, member: { id: member._id, email: member.email, name: member.name, circle: member.circle, contributionTier: member.contributionTier, status: member.status, } } })