leaky-ships/leaky-ships/pages/api/login.ts

98 lines
2.4 KiB
TypeScript

import { NextApiRequest, NextApiResponse } from "next"
import logging, { Logging } from "../../lib/backend/logging"
import getPlayerByNameDB from "../../lib/backend/components/getPlayerByNameDB"
import checkPasswordIsValid from "../../lib/backend/components/checkPasswordIsValid"
import createTokenDB from "../../lib/backend/components/createTokenDB"
import sendResponse from "../../lib/backend/components/sendResponse"
import sendError from "../../lib/backend/components/sendError"
import { setCookie } from "cookies-next"
import { Player, Token } from "@prisma/client"
import prisma from "../../lib/prisma"
interface Data {
loggedIn: boolean
}
export default async function login(
req: NextApiRequest,
res: NextApiResponse<any>
) {
const { username, password } = req.body
return preCheck({
req,
res,
username,
password,
newTokenType: "REFRESH" as Token["type"],
})
.then(getPlayerByNameDB)
.then(checkPasswordIsValid)
.then(createTokenDB)
.then(loginResponse<Data>)
.then(sendResponse<Data>)
.catch((err) => sendError(req, res, err))
}
async function preCheck<T>(
payload: T & {
req: NextApiRequest
res: NextApiResponse<T>
}
) {
const { req } = payload
const oldRefreshToken = req.cookies.token
// Check for old cookie, if unused invalidate it
const oldDBToken = await prisma.token.findUnique({
where: {
token: oldRefreshToken,
},
})
if (oldDBToken?.used) {
await prisma.token.update({
where: {
token: oldRefreshToken,
},
data: {
used: true,
},
})
await logging("Old token has been invalidated.", ["debug"], req)
}
return { ...payload, noCookiePresent: true }
}
async function loginResponse<T>(payload: {
player: Player
passwordIsValid: boolean
refreshToken: string
refreshTokenDB: Token
req: NextApiRequest
res: NextApiResponse<T>
}) {
const { player, refreshToken, refreshTokenDB, req, res } = payload
// Set login cookie
setCookie("token", refreshToken, {
req,
res,
maxAge: 172800000,
httpOnly: true,
sameSite: true,
secure: true,
})
// Successfull response
return {
req,
res,
result: {
message:
"User " +
player.id +
" logged in and generated Refresh-Token: " +
refreshTokenDB.id,
body: { loggedIn: true },
type: ["debug", "info.cyan"] as Logging[],
},
}
}