Implement authentication, waitlist, and logging upgrades

This commit is contained in:
Remi
2025-09-16 17:28:34 +02:00
parent e155434b57
commit fe66a4c04c
29 changed files with 1847 additions and 64 deletions

View File

@@ -0,0 +1,15 @@
import { requireUserSession } from '../../utils/auth'
import { InvitationCode } from '../../models/InvitationCode'
export default defineEventHandler(async (event) => {
const user = await requireUserSession(event)
const codes = await InvitationCode.find({ createdBy: user._id }).sort({ createdAt: -1 }).lean()
return codes.map((code) => ({
code: code.code,
createdAt: code.createdAt,
expiresAt: code.expiresAt,
usedAt: code.usedAt,
usedBy: code.usedBy ? String(code.usedBy) : null,
}))
})

View File

@@ -0,0 +1,49 @@
import { createError } from 'h3'
import { randomBytes } from 'node:crypto'
import { requireUserSession } from '../../utils/auth'
import { InvitationCode } from '../../models/InvitationCode'
function generateCode() {
return randomBytes(4).toString('hex').toUpperCase()
}
export default defineEventHandler(async (event) => {
const user = await requireUserSession(event)
const accountAgeMs = Date.now() - new Date(user.createdAt).getTime()
const twoWeeksMs = 1000 * 60 * 60 * 24 * 14
if (accountAgeMs < twoWeeksMs) {
throw createError({ statusCode: 403, statusMessage: 'Einladungscodes stehen nach 14 Tagen zur Verfügung' })
}
if (user.invitationCodesIssued >= 2) {
throw createError({ statusCode: 403, statusMessage: 'Limit von zwei Einladungscodes erreicht' })
}
const activeCodes = await InvitationCode.countDocuments({ createdBy: user._id, usedBy: { $exists: false } })
if (activeCodes >= 2) {
throw createError({ statusCode: 403, statusMessage: 'Bitte vorhandene Einladungscodes zuerst nutzen' })
}
const code = generateCode()
const now = new Date()
const expiresAt = new Date(now.getTime() + 1000 * 60 * 60 * 24 * 30)
await InvitationCode.create({
code,
createdBy: user._id,
createdAt: now,
expiresAt,
})
user.invitationCodesIssued += 1
await user.save()
return {
success: true,
code,
expiresAt,
}
})

View File

@@ -0,0 +1,10 @@
import { clearRefreshTokenCookie, requireUserSession } from '../../utils/auth'
export default defineEventHandler(async (event) => {
const user = await requireUserSession(event)
user.tokenVersion += 1
await user.save()
clearRefreshTokenCookie(event)
return { success: true }
})

15
server/api/auth/me.get.ts Normal file
View File

@@ -0,0 +1,15 @@
import { requireUserSession } from '../../utils/auth'
export default defineEventHandler(async (event) => {
const user = await requireUserSession(event)
return {
id: String(user._id),
email: user.email,
name: user.name,
role: user.role,
createdAt: user.createdAt,
lastLoginAt: user.lastLoginAt,
invitationCodesIssued: user.invitationCodesIssued,
}
})