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