// server/api/auth/login.post.ts /** * POST /api/auth/login * * Direct login with email and password (no OAuth2 redirect) * * Request body: * { * "email": "user@example.com", * "password": "SecureP@ssw0rd" * } * * Response: * { * "success": true * } * * Creates session cookie on success */ import { z } from 'zod' import { eq } from 'drizzle-orm' const loginSchema = z.object({ email: z.string().email('Invalid email address'), password: z.string().min(1, 'Password is required'), }) export default defineEventHandler(async (event) => { // 1. Validate request body const body = await readBody(event) const { email, password } = loginSchema.parse(body) try { // 2. Authenticate with Cidaas (Resource Owner Password Credentials flow) const tokens = await loginWithPassword(email, password) // 3. Validate ID token (JWT) const idTokenPayload = await verifyIdToken(tokens.id_token) // 4. Fetch user info from Cidaas const cidaasUser = await fetchUserInfo(tokens.access_token) // 5. Create/update user in local database const db = useDatabase() let user = await db.query.users.findFirst({ where: eq(users.experimentaId, cidaasUser.sub), }) if (!user) { // First time login - create user profile const [newUser] = await db .insert(users) .values({ experimentaId: cidaasUser.sub, email: cidaasUser.email, firstName: cidaasUser.given_name || '', lastName: cidaasUser.family_name || '', }) .returning() user = newUser } else { // Update last login timestamp await db .update(users) .set({ updatedAt: new Date(), }) .where(eq(users.id, user.id)) } // 6. Create encrypted session await setUserSession(event, { user: { id: user.id, experimentaId: user.experimentaId, email: user.email, firstName: user.firstName, lastName: user.lastName, }, loggedInAt: new Date().toISOString(), }) // 7. Return success return { success: true, } } catch (error: any) { console.error('Login error:', error) // Handle specific error cases if (error.statusCode === 401) { throw createError({ statusCode: 401, statusMessage: 'Ungültige E-Mail-Adresse oder Passwort', }) } throw createError({ statusCode: 500, statusMessage: 'Anmeldung fehlgeschlagen', }) } })