import { redisEnabled } from '@umami/redis-client'; import { saveAuth } from 'lib/auth'; import { secret } from 'lib/crypto'; import { useValidate } from 'lib/middleware'; import { NextApiRequestQueryBody, User } from 'lib/types'; import { NextApiResponse } from 'next'; import { checkPassword, createSecureToken, forbidden, methodNotAllowed, ok, unauthorized, } from 'next-basics'; import { getUserByUsername } from 'queries'; import * as yup from 'yup'; import { ROLES } from 'lib/constants'; export interface LoginRequestBody { username: string; password: string; } export interface LoginResponse { token: string; user: User; } const schema = { POST: yup.object().shape({ username: yup.string().required(), password: yup.string().required(), }), }; export default async ( req: NextApiRequestQueryBody, res: NextApiResponse, ) => { if (process.env.DISABLE_LOGIN) { return forbidden(res); } await useValidate(schema, req, res); if (req.method === 'POST') { const { username, password } = req.body; const user = await getUserByUsername(username, { includePassword: true }); if (user && checkPassword(password, user.password)) { if (redisEnabled) { const token = await saveAuth({ userId: user.id }); return ok(res, { token, user }); } const token = createSecureToken({ userId: user.id }, secret()); const { id, username, role, createdAt } = user; return ok(res, { token, user: { id, username, role, createdAt, isAdmin: role === ROLES.admin }, }); } return unauthorized(res, 'message.incorrect-username-password'); } return methodNotAllowed(res); };