pstream-backend/server/routes/auth/login/complete/index.ts
2025-05-05 09:53:17 -06:00

74 lines
1.7 KiB
TypeScript

import { z } from 'zod';
import { useChallenge } from '~/utils/challenge';
import { useAuth } from '~/utils/auth';
const completeSchema = z.object({
publicKey: z.string(),
challenge: z.object({
code: z.string(),
signature: z.string(),
}),
device: z.string().max(500).min(1),
});
export default defineEventHandler(async event => {
const body = await readBody(event);
const result = completeSchema.safeParse(body);
if (!result.success) {
throw createError({
statusCode: 400,
message: 'Invalid request body',
});
}
const challenge = useChallenge();
await challenge.verifyChallengeCode(
body.challenge.code,
body.publicKey,
body.challenge.signature,
'login',
'mnemonic'
);
const user = await prisma.users.findUnique({
where: { public_key: body.publicKey },
});
if (!user) {
throw createError({
statusCode: 401,
message: 'User cannot be found',
});
}
await prisma.users.update({
where: { id: user.id },
data: { last_logged_in: new Date() },
});
const auth = useAuth();
const userAgent = getRequestHeader(event, 'user-agent') || '';
const session = await auth.makeSession(user.id, body.device, userAgent);
const token = auth.makeSessionToken(session);
return {
user: {
id: user.id,
publicKey: user.public_key,
namespace: user.namespace,
profile: user.profile,
permissions: user.permissions,
},
session: {
id: session.id,
user: session.user,
createdAt: session.created_at,
accessedAt: session.accessed_at,
expiresAt: session.expires_at,
device: session.device,
userAgent: session.user_agent,
},
token,
};
});