You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

107 lines
2.5 KiB

// 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',
})
}
})