From 0507309ab1596a5cb9317b5d9f86c0e1a7f2e54c Mon Sep 17 00:00:00 2001 From: aronmal Date: Sat, 4 Feb 2023 00:29:06 +0100 Subject: [PATCH] First prisma integration step --- .../components/checkPasswordIsValid.ts | 22 +++++ .../backend/components/checkTokenIsValid.ts | 28 ++++++ .../backend/components/createAnonymousDB.ts | 28 ++++++ .../lib/backend/components/createPlayerDB.ts | 34 ++++++++ .../lib/backend/components/createTokenDB.ts | 36 ++++++++ .../lib/backend/components/getPlayerByIdDB.ts | 24 ++++++ .../backend/components/getPlayerByNameDB.ts | 29 +++++++ .../lib/backend/components/getTokenDB.ts | 52 +++++++++++ .../backend/components/getTokenFromBody.ts | 19 ++++ .../backend/components/getTokenFromCookie.ts | 20 +++++ .../lib/backend/components/loginCheck.ts | 15 ++++ .../lib/backend/components/sendError.ts | 12 +++ .../lib/backend/components/sendResponse.ts | 22 +++++ leaky-ships/lib/backend/jwtVerifyCatch.ts | 4 +- leaky-ships/lib/frontend/checkIsLoggedIn.ts | 23 +++++ leaky-ships/lib/frontend/getAccessToken.ts | 7 ++ leaky-ships/pages/api/auth.ts | 49 +++++++++++ leaky-ships/pages/api/data.ts | 48 +++++++++++ leaky-ships/pages/api/login.ts | 86 +++++++++++++++++++ leaky-ships/pages/api/logout.ts | 47 ++++++++++ leaky-ships/pages/api/register.ts | 41 +++++++++ 21 files changed, 645 insertions(+), 1 deletion(-) create mode 100644 leaky-ships/lib/backend/components/checkPasswordIsValid.ts create mode 100644 leaky-ships/lib/backend/components/checkTokenIsValid.ts create mode 100644 leaky-ships/lib/backend/components/createAnonymousDB.ts create mode 100644 leaky-ships/lib/backend/components/createPlayerDB.ts create mode 100644 leaky-ships/lib/backend/components/createTokenDB.ts create mode 100644 leaky-ships/lib/backend/components/getPlayerByIdDB.ts create mode 100644 leaky-ships/lib/backend/components/getPlayerByNameDB.ts create mode 100644 leaky-ships/lib/backend/components/getTokenDB.ts create mode 100644 leaky-ships/lib/backend/components/getTokenFromBody.ts create mode 100644 leaky-ships/lib/backend/components/getTokenFromCookie.ts create mode 100644 leaky-ships/lib/backend/components/loginCheck.ts create mode 100644 leaky-ships/lib/backend/components/sendError.ts create mode 100644 leaky-ships/lib/backend/components/sendResponse.ts create mode 100644 leaky-ships/lib/frontend/checkIsLoggedIn.ts create mode 100644 leaky-ships/lib/frontend/getAccessToken.ts create mode 100644 leaky-ships/pages/api/auth.ts create mode 100644 leaky-ships/pages/api/data.ts create mode 100644 leaky-ships/pages/api/login.ts create mode 100644 leaky-ships/pages/api/logout.ts create mode 100644 leaky-ships/pages/api/register.ts diff --git a/leaky-ships/lib/backend/components/checkPasswordIsValid.ts b/leaky-ships/lib/backend/components/checkPasswordIsValid.ts new file mode 100644 index 0000000..eb4d3f1 --- /dev/null +++ b/leaky-ships/lib/backend/components/checkPasswordIsValid.ts @@ -0,0 +1,22 @@ +import { Player } from "@prisma/client" +import bcrypt from "bcrypt" + +export default async function checkPasswordIsValid(payload: T & { player: Player, password: string }) { + const { player, password } = payload + + // Validate for correct password + return bcrypt.compare(password, player.passwordHash) + .then(async result => { + if (!result) { + return Promise.reject({ + message: 'Passwords do not match!', + statusCode: 401, + solved: true, + }) + } + return { + ...payload, + passwordIsValid: true + } + }) +} \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/checkTokenIsValid.ts b/leaky-ships/lib/backend/components/checkTokenIsValid.ts new file mode 100644 index 0000000..3fb5001 --- /dev/null +++ b/leaky-ships/lib/backend/components/checkTokenIsValid.ts @@ -0,0 +1,28 @@ +import { Token } from "@prisma/client" +import jwt from "jsonwebtoken" +import jwtVerifyCatch from "../jwtVerifyCatch" + +async function checkTokenIsValid(payload: T & { token: string, tokenType: Token['type'] }) { + const { token, tokenType } = payload + + // Verify the token and get the payload + let tokenData: string | jwt.JwtPayload + try { + tokenData = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET as string) + } catch (err: any) { + // Deal with the problem in more detail + return Promise.reject(jwtVerifyCatch(tokenType, err)) + } + // Making sure the token data is not a string (because it should be an object) + if (typeof tokenData === 'string') { + return Promise.reject({ + message: tokenType + '-Token data was a string. Token: ' + token, + statusCode: 401, + solved: false + }) + } + + return { ...payload, tokenBody: token, tokenIsValid: true } +} + +export default checkTokenIsValid \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/createAnonymousDB.ts b/leaky-ships/lib/backend/components/createAnonymousDB.ts new file mode 100644 index 0000000..65c486d --- /dev/null +++ b/leaky-ships/lib/backend/components/createAnonymousDB.ts @@ -0,0 +1,28 @@ +import prisma from "../../prisma" + +async function createAnonymousDB(payload: T) { + const player = await prisma.player.create({ + data: { + anonymous: true + } + }) + // .catch((err: any) => { + // if (err.code === 11000) { + // return Promise.reject({ + // message: `Duplicate key error while creating Player in DB!`, + // statusCode: 409, + // solved: true, + // type: 'warn' + // }) + // } else { + // console.log(err) + // return Promise.reject({ + // message: `Unknown error while creating Player in DB.`, + // solved: false + // }) + // } + // }) + return { ...payload, player } +} + +export default createAnonymousDB \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/createPlayerDB.ts b/leaky-ships/lib/backend/components/createPlayerDB.ts new file mode 100644 index 0000000..ba5ea01 --- /dev/null +++ b/leaky-ships/lib/backend/components/createPlayerDB.ts @@ -0,0 +1,34 @@ +import bcrypt from "bcrypt" +import prisma from "../../prisma" + +async function createPlayerDB(payload: T & { username: string, password: string }) { + const { username, password } = payload + + return await prisma.player.create({ + data: { + username, + passwordHash: await bcrypt.hash(password, 10), + anonymous: false + } + }) + .then(player => { + return { ...payload, player } + }).catch((err: any) => { + if (err.code === 11000) { + return Promise.reject({ + message: `Duplicate key error while creating Player in DB!`, + statusCode: 409, + solved: true, + type: 'warn' + }) + } else { + console.log(err) + return Promise.reject({ + message: `Unknown error while creating Player in DB.`, + solved: false + }) + } + }) +} + +export default createPlayerDB \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/createTokenDB.ts b/leaky-ships/lib/backend/components/createTokenDB.ts new file mode 100644 index 0000000..cdee377 --- /dev/null +++ b/leaky-ships/lib/backend/components/createTokenDB.ts @@ -0,0 +1,36 @@ +import { Player, Token } from "@prisma/client" +import jwt from "jsonwebtoken" +import { v4 as uuidv4 } from "uuid" +import prisma from "../../prisma" + +const tokenLifetime = { + REFRESH: 172800, + ACCESS: 15 +}; + +export default async function createTokenDB(payload: T & { player: Player, newTokenType: Token['type'] }) { + const { player, newTokenType } = payload + + // Sign a new access token + const newToken = jwt.sign({ uuid: uuidv4(), user: player.id }, process.env.ACCESS_TOKEN_SECRET as string, { expiresIn: tokenLifetime[newTokenType] }) + + // Save token to DB + const newTokenDB = await prisma.token.create({ + data: { + token: newToken, + type: newTokenType, + expires: new Date(Date.now() + tokenLifetime[newTokenType] + '000'), + owner: { + connect: { + id: player.id + } + } + } + }) + + return { + ...payload, + newToken, + newTokenDB + } +} \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/getPlayerByIdDB.ts b/leaky-ships/lib/backend/components/getPlayerByIdDB.ts new file mode 100644 index 0000000..ec1a5d9 --- /dev/null +++ b/leaky-ships/lib/backend/components/getPlayerByIdDB.ts @@ -0,0 +1,24 @@ +import { Token } from "@prisma/client" +import prisma from "../../prisma" + +export default async function getPlayerByIdDB(payload: T & { tokenDB: Token }) { + const { tokenDB } = payload + // Find Host in DB if it still exists (just to make sure) + const player = await prisma.player.findUnique({ + where: { + id: tokenDB.ownerId + } + }) + if (!player) { + return Promise.reject({ + message: 'Player not found in DB!', + statusCode: 401, + solved: false + }) + } + + return { + ...payload, + player + } +} \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/getPlayerByNameDB.ts b/leaky-ships/lib/backend/components/getPlayerByNameDB.ts new file mode 100644 index 0000000..82d79d6 --- /dev/null +++ b/leaky-ships/lib/backend/components/getPlayerByNameDB.ts @@ -0,0 +1,29 @@ +import prisma from "../../prisma" + +export default async function getPlayerByNameDB(payload: T & { username: string }) { + const { username } = payload + // Find Player in DB if it still exists (just to make sure) + const player = await Promise.any([ + prisma.player.findUnique({ + where: { + username: username + } + }), prisma.player.findUnique({ + where: { + email: username + } + }) + ]) + if (!player) { + return Promise.reject({ + message: 'Player not found in DB!', + statusCode: 401, + solved: false + }) + } + + return { + ...payload, + player + } +} \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/getTokenDB.ts b/leaky-ships/lib/backend/components/getTokenDB.ts new file mode 100644 index 0000000..69d8456 --- /dev/null +++ b/leaky-ships/lib/backend/components/getTokenDB.ts @@ -0,0 +1,52 @@ +import { NextApiRequest, NextApiResponse } from "next" +import prisma from "../../prisma" + +async function getTokenDB(payload: T & { + tokenBody: string + tokenIsValid: boolean, + req: NextApiRequest, + res: NextApiResponse, +}) { + const { tokenBody } = payload + + // Find refresh token in DB + const tokenDB = await prisma.token.findUnique({ + where: { + token: tokenBody + } + }) + if (!tokenDB) { + return Promise.reject({ + message: 'Access-Token not found in DB!', + statusCode: 401, + solved: true, + type: 'warn' + }) + } + + if (tokenDB.used) { + return Promise.reject({ + message: 'DBToken was already used!', + statusCode: 401, + solved: true + }) + } + + await prisma.token.update({ + where: { + token: tokenBody + }, + data: { + used: true + } + }) + + // await logging('Old token has been invalidated.', ['debug'], req) + + return { + ...payload, + tokenDB + } +} + +export default getTokenDB \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/getTokenFromBody.ts b/leaky-ships/lib/backend/components/getTokenFromBody.ts new file mode 100644 index 0000000..61ebd9d --- /dev/null +++ b/leaky-ships/lib/backend/components/getTokenFromBody.ts @@ -0,0 +1,19 @@ +import { NextApiRequest } from "next" + +async function getTokenFromBody(payload: T & { req: NextApiRequest }) { + const { req } = payload + const token: string = req.body.token + + // Checking for cookie presens, because it is necessary + if (!token) { + return Promise.reject({ + message: 'Unauthorized. No Access-Token.', + statusCode: 401, + solved: true, + }) + } + + return { ...payload, token } +} + +export default getTokenFromBody \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/getTokenFromCookie.ts b/leaky-ships/lib/backend/components/getTokenFromCookie.ts new file mode 100644 index 0000000..e8caa89 --- /dev/null +++ b/leaky-ships/lib/backend/components/getTokenFromCookie.ts @@ -0,0 +1,20 @@ +import { Token } from "@prisma/client" +import { NextApiRequest } from "next" + +async function getTokenFromCookie(payload: T & { req: NextApiRequest }) { + const { req } = payload + const token = req.cookies.token + + // Checking for cookie presens, because it is necessary + if (!token) { + return Promise.reject({ + message: 'Unauthorized. No cookie.', + statusCode: 401, + solved: true, + }) + } + + return { ...payload, token, tokenType: 'REFRESH' as Token['type'] } +} + +export default getTokenFromCookie \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/loginCheck.ts b/leaky-ships/lib/backend/components/loginCheck.ts new file mode 100644 index 0000000..36ef428 --- /dev/null +++ b/leaky-ships/lib/backend/components/loginCheck.ts @@ -0,0 +1,15 @@ +import { Token } from "@prisma/client" +import { Logging } from "../logging" + +export default async function loginCheck(payload: T & { loginCheck: boolean, tokenDB: Token, tokenType: 'REFRESH' }) { + const { loginCheck, tokenDB } = payload + // True login check response + if (loginCheck) { + return Promise.resolve({ + message: 'loginCheck ' + loginCheck + ' of ' + tokenDB.id, + body: { loggedIn: true }, + type: ['debug', 'info.cyan'] as Logging[] + }) + } + return payload +} \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/sendError.ts b/leaky-ships/lib/backend/components/sendError.ts new file mode 100644 index 0000000..7d54118 --- /dev/null +++ b/leaky-ships/lib/backend/components/sendError.ts @@ -0,0 +1,12 @@ +import { NextApiRequest, NextApiResponse } from "next" +import logging from "../logging" + +export default function sendError( + req: NextApiRequest, + res: NextApiResponse, + err: any +) { + // If something went wrong, let the client know with status 500 + res.status(err.statusCode ?? 500).end() + logging(err.message, [err.type ?? (err.solved ? 'debug' : 'error')], req) +} \ No newline at end of file diff --git a/leaky-ships/lib/backend/components/sendResponse.ts b/leaky-ships/lib/backend/components/sendResponse.ts new file mode 100644 index 0000000..e3b2eda --- /dev/null +++ b/leaky-ships/lib/backend/components/sendResponse.ts @@ -0,0 +1,22 @@ +import { NextApiRequest, NextApiResponse } from "next" +import logging, { Logging } from "../logging" + +export interface Result { + message: string, + statusCode?: number, + body?: T, + type?: Logging[], +} + +export default function sendResponse(payload: { + req: NextApiRequest, + res: NextApiResponse, + result: Result +}) { + const { req, res, result } = payload + res.status(result.statusCode ?? 200) + result.body ? + res.json(result.body) : + res.end() + logging(result.message, result.type ?? ['debug'], req) +} diff --git a/leaky-ships/lib/backend/jwtVerifyCatch.ts b/leaky-ships/lib/backend/jwtVerifyCatch.ts index 1b43515..2f89e8f 100644 --- a/leaky-ships/lib/backend/jwtVerifyCatch.ts +++ b/leaky-ships/lib/backend/jwtVerifyCatch.ts @@ -1,5 +1,7 @@ +import { Token } from "@prisma/client" + export default async function jwtVerifyCatch( - tokenType: 'refreshToken' | 'accessToken', + tokenType: Token['type'], err: Error ) { switch (err.message) { diff --git a/leaky-ships/lib/frontend/checkIsLoggedIn.ts b/leaky-ships/lib/frontend/checkIsLoggedIn.ts new file mode 100644 index 0000000..a90efae --- /dev/null +++ b/leaky-ships/lib/frontend/checkIsLoggedIn.ts @@ -0,0 +1,23 @@ +import { GetServerSidePropsContext, PreviewData } from "next" +import { ParsedUrlQuery } from "querystring" +import getTokenFromCookie from "../backend/components/getTokenFromCookie" +import checkTokenIsValid from "../backend/components/checkTokenIsValid" +import getTokenDB from "../backend/components/getTokenDB" +import getPlayerByIdDB from "../backend/components/getPlayerByIdDB" +import logging from "../backend/logging" + +export default async function checkIsLoggedIn(context: GetServerSidePropsContext) { + const req: any = context.req + const res: any = context.res + + const isLoggedIn = await getTokenFromCookie({ req, res }) + .then(checkTokenIsValid) + .then(getTokenDB) + .then(getPlayerByIdDB) + .then(({ player }) => !!player) + .catch(() => false) + + logging('loginCheck ' + (isLoggedIn ? true : '-> loggedIn: ' + false), ['debug', 'info.cyan'], req) + + return isLoggedIn +} \ No newline at end of file diff --git a/leaky-ships/lib/frontend/getAccessToken.ts b/leaky-ships/lib/frontend/getAccessToken.ts new file mode 100644 index 0000000..85919f3 --- /dev/null +++ b/leaky-ships/lib/frontend/getAccessToken.ts @@ -0,0 +1,7 @@ +export default function getAccessToken(): Promise { + return fetch('/api/auth', { + method: 'GET', + }) + .then(res => res.json()) + .then(res => res.newAccessToken) +} \ No newline at end of file diff --git a/leaky-ships/pages/api/auth.ts b/leaky-ships/pages/api/auth.ts new file mode 100644 index 0000000..502aafe --- /dev/null +++ b/leaky-ships/pages/api/auth.ts @@ -0,0 +1,49 @@ +import { NextApiRequest, NextApiResponse } from "next" +import getTokenFromCookie from "../../lib/backend/components/getTokenFromCookie" +import checkTokenIsValid from "../../lib/backend/components/checkTokenIsValid" +import getTokenDB from "../../lib/backend/components/getTokenDB" +import getPlayerByIdDB from "../../lib/backend/components/getPlayerByIdDB" +import createTokenDB from "../../lib/backend/components/createTokenDB" +import sendResponse from "../../lib/backend/components/sendResponse" +import sendError from "../../lib/backend/components/sendError" +import { Logging } from "../../lib/backend/logging" +import { Token } from "@prisma/client" + +interface Data { + token: string +} + +export default async function auth( + req: NextApiRequest, + res: NextApiResponse +) { + return getTokenFromCookie({ req, res, newTokenType: 'ACCESS' as Token['type'] }) + .then(checkTokenIsValid) + .then(getTokenDB) + .then(getPlayerByIdDB) + .then(createTokenDB) + .then(authResponse) + .then(sendResponse) + .catch(err => sendError(req, res, err)) +} + +async function authResponse(payload: { + newToken: string, + newTokenDB: Token, + tokenDB: Token, + req: NextApiRequest, + res: NextApiResponse +}) { + const { newToken, newTokenDB, tokenDB, req, res } = payload + + // Successfull response + return { + req, + res, + result: { + message: 'Access-Token generated: ' + newTokenDB.id + ' with Refreshtoken-Token: ' + tokenDB.id, + body: { token: newToken }, + type: ['debug', 'info.cyan'] as Logging[] + } + } +} \ No newline at end of file diff --git a/leaky-ships/pages/api/data.ts b/leaky-ships/pages/api/data.ts new file mode 100644 index 0000000..5a452ef --- /dev/null +++ b/leaky-ships/pages/api/data.ts @@ -0,0 +1,48 @@ +import { NextApiRequest, NextApiResponse } from "next" +import getTokenFromBody from "../../lib/backend/components/getTokenFromBody" +import checkTokenIsValid from "../../lib/backend/components/checkTokenIsValid" +import getTokenDB from "../../lib/backend/components/getTokenDB" +import getPlayerByIdDB from "../../lib/backend/components/getPlayerByIdDB" +import sendResponse from "../../lib/backend/components/sendResponse" +import sendError from "../../lib/backend/components/sendError" +import { Logging } from "../../lib/backend/logging" +import { Game, Player, Token } from "@prisma/client" + +interface Data { + games: Game[] +} + +export default async function data( + req: NextApiRequest, + res: NextApiResponse +) { + return getTokenFromBody({ req, res, tokenType: 'ACCESS' as Token['type'] }) + .then(checkTokenIsValid) + .then(getTokenDB) + .then(getPlayerByIdDB) + .then(dataResponse) + .then(sendResponse) + .catch(err => sendError(req, res, err)) +} + +async function dataResponse(payload: { + player: Player, + tokenDB: Token, + // games: Game[], + req: NextApiRequest, + res: NextApiResponse +}) { + const { player, tokenDB, req, res } = payload + + const games: any = {} + // Successfull response + return { + req, + res, + result: { + message: 'Requested data of user: ' + player.id + ' with Access-Token: ' + tokenDB.id, + body: { games }, + type: ['debug', 'info.cyan'] as Logging[] + } + } +} \ No newline at end of file diff --git a/leaky-ships/pages/api/login.ts b/leaky-ships/pages/api/login.ts new file mode 100644 index 0000000..34d7573 --- /dev/null +++ b/leaky-ships/pages/api/login.ts @@ -0,0 +1,86 @@ +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 +) { + const { username, password } = req.body + return preCheck({ req, res, username, password, newTokenType: 'REFRESH' as Token['type'] }) + .then(getPlayerByNameDB) + .then(checkPasswordIsValid) + .then(createTokenDB) + .then(loginResponse) + .then(sendResponse) + .catch(err => sendError(req, res, err)) +} + +async function preCheck(payload: T & { + req: NextApiRequest, + res: NextApiResponse +}) { + 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(payload: { + player: Player, + passwordIsValid: boolean, + refreshToken: string, + refreshTokenDB: Token, + req: NextApiRequest, + res: NextApiResponse +}) { + 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[] + } + } +} \ No newline at end of file diff --git a/leaky-ships/pages/api/logout.ts b/leaky-ships/pages/api/logout.ts new file mode 100644 index 0000000..c3e03db --- /dev/null +++ b/leaky-ships/pages/api/logout.ts @@ -0,0 +1,47 @@ +import { NextApiRequest, NextApiResponse } from "next" +import checkTokenIsValid from "../../lib/backend/components/checkTokenIsValid" +import sendResponse from "../../lib/backend/components/sendResponse" +import sendError from "../../lib/backend/components/sendError" +import { deleteCookie } from "cookies-next" +import { Token } from "@prisma/client" +import getTokenDB from "../../lib/backend/components/getTokenDB" +import getTokenFromCookie from "../../lib/backend/components/getTokenFromCookie" +import logging, { Logging } from "../../lib/backend/logging" + +interface Data { + loggedOut: boolean +} + +export default async function logout( + req: NextApiRequest, + res: NextApiResponse +) { + return getTokenFromCookie({ req, res }) + .then(checkTokenIsValid) + .then(getTokenDB) + .then(logoutResponse) + .then(sendResponse) + .catch(err => sendError(req, res, err)) +} + +async function logoutResponse(payload: { + tokenDB: Token, + req: NextApiRequest, + res: NextApiResponse +}) { + const { tokenDB, req, res } = payload + + // Set login cookie + deleteCookie('token', { req, res }) + + // Successfull response + return { + req, + res, + result: { + message: 'User of Token ' + tokenDB.id + ' logged out.', + body: { loggedOut: true }, + type: ['debug', 'info.cyan'] as Logging[] + } + } +} \ No newline at end of file diff --git a/leaky-ships/pages/api/register.ts b/leaky-ships/pages/api/register.ts new file mode 100644 index 0000000..7895e33 --- /dev/null +++ b/leaky-ships/pages/api/register.ts @@ -0,0 +1,41 @@ +import { NextApiRequest, NextApiResponse } from "next" +import createPlayerDB from "../../lib/backend/components/createPlayerDB" +import sendError from "../../lib/backend/components/sendError" +import sendResponse from "../../lib/backend/components/sendResponse" +import { Logging } from "../../lib/backend/logging" +import { Player } from "@prisma/client" + +interface Data { + registered: boolean +} + +export default async function register( + req: NextApiRequest, + res: NextApiResponse +) { + const { username, password } = req.body + return createPlayerDB({ req, res, username, password }) + .then(registerResponse) + .then(sendResponse) + .catch(err => sendError(req, res, err)) +} + +async function registerResponse(payload: { + player: Player, + req: NextApiRequest, + res: NextApiResponse +}) { + const { player, req, res } = payload + + // Successfull response + return { + req, + res, + result: { + message: 'Player created : ' + player.id, + statusCode: 201, + body: { registered: true }, + type: ['debug', 'info.cyan'] as Logging[] + } + } +} \ No newline at end of file