Backend rewrite using async/await

This commit is contained in:
aronmal 2023-04-15 12:09:25 +02:00
parent 2862f94f1c
commit 549d0f1d77
Signed by: aronmal
GPG key ID: 816B7707426FC612
26 changed files with 259 additions and 322 deletions

View file

@ -6,12 +6,11 @@ import bcrypt from "bcrypt"
export default async function checkPasswordIsValid<T>( export default async function checkPasswordIsValid<T>(
context: API<T>, context: API<T>,
player: Player, player: Player,
password: string, password: string
next: () => void
) { ) {
// Validate for correct password // Validate for correct password
const result = await bcrypt.compare(password, player.passwordHash ?? "") const result = await bcrypt.compare(password, player.passwordHash ?? "")
if (!result) return sendError(context, rejectionErrors.wrongPassword) if (!result) throw sendError(context, rejectionErrors.wrongPassword)
return next() return
} }

View file

@ -4,11 +4,7 @@ import type { IdToken, RawToken } from "./createTokenDB"
import sendError, { API } from "./sendError" import sendError, { API } from "./sendError"
import jwt from "jsonwebtoken" import jwt from "jsonwebtoken"
async function checkTokenIsValid<T>( async function checkTokenIsValid<T>(context: API<T>, rawToken: RawToken) {
context: API<T>,
rawToken: RawToken,
next: (token: IdToken) => void
) {
const { value, type } = rawToken const { value, type } = rawToken
// Verify the token and get the payload // Verify the token and get the payload
@ -17,13 +13,13 @@ async function checkTokenIsValid<T>(
data = jwt.verify(value, process.env.TOKEN_SECRET as string) data = jwt.verify(value, process.env.TOKEN_SECRET as string)
} catch (err: any) { } catch (err: any) {
// Deal with the problem in more detail // Deal with the problem in more detail
return sendError(context, jwtVerifyCatch(type, err)) throw sendError(context, jwtVerifyCatch(type, err))
} }
// Making sure the token data is not a string (because it should be an object) // Making sure the token data is not a string (because it should be an object)
if (typeof data === "string") if (typeof data === "string")
return sendError(context, rejectionErrorFns.tokenWasString(type, value)) throw sendError(context, rejectionErrorFns.tokenWasString(type, value))
return next({ id: data.id, type }) return { id: data.id, type }
} }
export default checkTokenIsValid export default checkTokenIsValid

View file

@ -2,11 +2,11 @@ import prisma from "../../prisma"
import logging from "../logging" import logging from "../logging"
import type { Player } from "@prisma/client" import type { Player } from "@prisma/client"
async function createPlayerDB(next: (player: Player) => void) { async function createPlayerDB() {
const player = await prisma.player.create({ data: {} }) const player = await prisma.player.create({ data: {} })
logging("Anonymous player created: " + player.id, ["debug"]) logging("Anonymous player created: " + player.id, ["debug"])
return next(player) return player
} }
export default createPlayerDB export default createPlayerDB

View file

@ -18,8 +18,7 @@ export const tokenLifetime = {
export default async function createTokenDB( export default async function createTokenDB(
player: Player, player: Player,
newTokenType: TokenType, newTokenType: TokenType
next: (newToken: RawToken, newTokenDB: Token) => void
) { ) {
// Create token entry in DB // Create token entry in DB
const newTokenDB = await prisma.token.create({ const newTokenDB = await prisma.token.create({
@ -41,5 +40,5 @@ export default async function createTokenDB(
{ expiresIn: tokenLifetime[newTokenType] } { expiresIn: tokenLifetime[newTokenType] }
) )
return next({ value: newToken, type: newTokenType }, newTokenDB) return { newToken: { value: newToken, type: newTokenType }, newTokenDB }
} }

View file

@ -5,11 +5,7 @@ import type { IdToken, RawToken } from "./createTokenDB"
import sendError, { API } from "./sendError" import sendError, { API } from "./sendError"
import jwt from "jsonwebtoken" import jwt from "jsonwebtoken"
async function decodeToken<T>( async function decodeToken<T>(context: API<T>, rawToken: RawToken) {
context: API<T>,
rawToken: RawToken,
next: (token: IdToken) => void
) {
const { value, type } = rawToken const { value, type } = rawToken
// Verify the token and get the payload // Verify the token and get the payload
@ -22,14 +18,14 @@ async function decodeToken<T>(
const fallbackData = jwt.decode(value) const fallbackData = jwt.decode(value)
// Making sure the token data is not a string (because it should be an object) // Making sure the token data is not a string (because it should be an object)
if (typeof fallbackData === "string") if (typeof fallbackData === "string")
return sendError(context, rejectionErrorFns.tokenWasString(type, value)) throw sendError(context, rejectionErrorFns.tokenWasString(type, value))
return next({ id: fallbackData?.id, type }) return { id: fallbackData?.id, type }
} }
// Making sure the token data is not a string (because it should be an object) // Making sure the token data is not a string (because it should be an object)
if (typeof data === "string") if (typeof data === "string")
return sendError(context, rejectionErrorFns.tokenWasString(type, value)) throw sendError(context, rejectionErrorFns.tokenWasString(type, value))
return next({ id: data.id, type }) return { id: data.id, type }
} }
export default decodeToken export default decodeToken

View file

@ -1,6 +1,6 @@
import sendError, { API } from "./sendError" import sendError, { API } from "./sendError"
async function getPinFromBody<T>(context: API<T>, next: (pin: string) => void) { async function getPinFromBody<T>(context: API<T>) {
const body = JSON.parse(context.req.body) const body = JSON.parse(context.req.body)
if ( if (
typeof body !== "object" || typeof body !== "object" ||
@ -8,7 +8,7 @@ async function getPinFromBody<T>(context: API<T>, next: (pin: string) => void) {
!("pin" in body) || !("pin" in body) ||
typeof body.pin !== "string" typeof body.pin !== "string"
) )
return sendError(context, { throw sendError(context, {
rejected: true, rejected: true,
message: "No pin in request body!", message: "No pin in request body!",
statusCode: 401, statusCode: 401,
@ -17,7 +17,7 @@ async function getPinFromBody<T>(context: API<T>, next: (pin: string) => void) {
}) })
const { pin } = body const { pin } = body
return next(pin) return pin
} }
export default getPinFromBody export default getPinFromBody

View file

@ -3,19 +3,13 @@ import getPlayerByIdDB from "./getPlayerByIdDB"
import getTokenDB from "./getTokenDB" import getTokenDB from "./getTokenDB"
import getTokenFromBody from "./getTokenFromBody" import getTokenFromBody from "./getTokenFromBody"
import { API } from "./sendError" import { API } from "./sendError"
import { Player, Token } from "@prisma/client"
function getPlayer<T>( async function getPlayer<T>(context: API<T>) {
context: API<T>, const accessToken = await getTokenFromBody(context)
next: (player: Player, tokenDB: Token) => void const token = await checkTokenIsValid(context, accessToken)
) { const tokenDB = await getTokenDB(context, token)
return getTokenFromBody(context, (accessToken) => { const player = await getPlayerByIdDB(context, tokenDB)
checkTokenIsValid(context, accessToken, (token) => { return { player, tokenDB }
getTokenDB(context, token, (tokenDB) => {
getPlayerByIdDB(context, tokenDB, (player) => next(player, tokenDB))
})
})
})
} }
export default getPlayer export default getPlayer

View file

@ -5,8 +5,7 @@ import type { Player, Token } from "@prisma/client"
export default async function getPlayerByIdDB<T>( export default async function getPlayerByIdDB<T>(
context: API<T>, context: API<T>,
tokenDB: Token, tokenDB: Token
next: (player: Player) => void
) { ) {
// Find Host in DB if it still exists (just to make sure) // Find Host in DB if it still exists (just to make sure)
const player = await prisma.player.findUnique({ const player = await prisma.player.findUnique({
@ -15,8 +14,8 @@ export default async function getPlayerByIdDB<T>(
}, },
}) })
if (!player) { if (!player) {
return sendError(context, rejectionErrors.playerNotFound) throw sendError(context, rejectionErrors.playerNotFound)
} }
return next(player) return player
} }

View file

@ -5,8 +5,7 @@ import type { Player } from "@prisma/client"
export default async function getPlayerByNameDB<T>( export default async function getPlayerByNameDB<T>(
context: API<T>, context: API<T>,
username: string, username: string
next: (player: Player) => void
) { ) {
// Find Player in DB if it still exists (just to make sure) // Find Player in DB if it still exists (just to make sure)
const player = await Promise.any([ const player = await Promise.any([
@ -21,7 +20,7 @@ export default async function getPlayerByNameDB<T>(
}, },
}), }),
]).catch(() => null) ]).catch(() => null)
if (player === null) return sendError(context, rejectionErrors.playerNotFound) if (player === null) throw sendError(context, rejectionErrors.playerNotFound)
return next(player) return player
} }

View file

@ -2,13 +2,12 @@ import prisma from "../../prisma"
import { rejectionErrorFns, rejectionErrors } from "../errors" import { rejectionErrorFns, rejectionErrors } from "../errors"
import type { IdToken } from "./createTokenDB" import type { IdToken } from "./createTokenDB"
import sendError, { API } from "./sendError" import sendError, { API } from "./sendError"
import type { Token } from "@prisma/client"
import { deleteCookie } from "cookies-next" import { deleteCookie } from "cookies-next"
async function getTokenDB<T>( async function getTokenDB<T>(
context: API<T>, context: API<T>,
token: IdToken, token: IdToken,
next: (tokenDB: Token) => void,
ignoreChecks?: boolean ignoreChecks?: boolean
) { ) {
const { id, type } = token const { id, type } = token
@ -20,11 +19,11 @@ async function getTokenDB<T>(
}) })
if (!tokenDB) { if (!tokenDB) {
deleteCookie("token", { ...context, path: "/api" }) deleteCookie("token", { ...context, path: "/api" })
return sendError(context, rejectionErrorFns.tokenNotFound(type)) throw sendError(context, rejectionErrorFns.tokenNotFound(type))
} }
if (tokenDB.used && !ignoreChecks) if (tokenDB.used && !ignoreChecks)
return sendError(context, rejectionErrors.tokenUsed) throw sendError(context, rejectionErrors.tokenUsed)
await prisma.token.update({ await prisma.token.update({
where: { where: {
@ -37,7 +36,7 @@ async function getTokenDB<T>(
// await logging('Old token has been invalidated.', ['debug'], req) // await logging('Old token has been invalidated.', ['debug'], req)
return next(tokenDB) return tokenDB
} }
export default getTokenDB export default getTokenDB

View file

@ -2,10 +2,7 @@ import { rejectionErrorFns } from "../errors"
import type { RawToken } from "./createTokenDB" import type { RawToken } from "./createTokenDB"
import sendError, { API } from "./sendError" import sendError, { API } from "./sendError"
async function getTokenFromBody<T>( async function getTokenFromBody<T>(context: API<T>): Promise<RawToken> {
context: API<T>,
next: (accessToken: RawToken) => void
) {
const type = "ACCESS" const type = "ACCESS"
const body = JSON.parse(context.req.body) const body = JSON.parse(context.req.body)
// Checking for cookie presens, because it is necessary // Checking for cookie presens, because it is necessary
@ -16,11 +13,11 @@ async function getTokenFromBody<T>(
typeof body.token === "string" typeof body.token === "string"
) { ) {
const value = body.token const value = body.token
return next({ value, type }) return { value, type }
} }
console.log(body) console.log(body)
return sendError(context, rejectionErrorFns.noToken(type)) throw sendError(context, rejectionErrorFns.noToken(type))
} }
export default getTokenFromBody export default getTokenFromBody

View file

@ -3,25 +3,29 @@ import createTokenDB, { RawToken } from "./createTokenDB"
import type { API } from "./sendError" import type { API } from "./sendError"
import { Player, Token } from "@prisma/client" import { Player, Token } from "@prisma/client"
async function getTokenFromCookie<T>( interface Returning {
context: API<T>, refreshToken: RawToken
next: ( newPlayer?: { player: Player; newToken: RawToken; newTokenDB: Token }
refreshToken: RawToken, }
newPlayer?: { player: Player; newToken: RawToken; newTokenDB: Token }
) => void async function getTokenFromCookie<T>(context: API<T>): Promise<Returning> {
) {
const type = "REFRESH" const type = "REFRESH"
const value = context.req.cookies.token const value = context.req.cookies.token
// Checking for cookie presens, because it is necessary // Checking for cookie presens, because it is necessary
if (!value) { if (!value) {
return createPlayerDB((player) => const player = await createPlayerDB()
createTokenDB(player, type, (newToken, newTokenDB) => const { newToken, newTokenDB } = await createTokenDB(player, type)
next(newToken, { player, newToken, newTokenDB }) return {
) refreshToken: newToken,
) newPlayer: {
player,
newToken,
newTokenDB,
},
}
} }
return next({ value, type }) return { refreshToken: { value, type } }
} }
export default getTokenFromCookie export default getTokenFromCookie

View file

@ -1,10 +1,7 @@
import { rejectionErrors } from "../errors" import { rejectionErrors } from "../errors"
import sendError, { API } from "./sendError" import sendError, { API } from "./sendError"
async function getUserFromBody<T>( async function getUserFromBody<T>(context: API<T>) {
context: API<T>,
next: (username: string, password: string) => void
) {
const body = JSON.parse(context.req.body) const body = JSON.parse(context.req.body)
if ( if (
typeof body !== "object" || typeof body !== "object" ||
@ -12,13 +9,13 @@ async function getUserFromBody<T>(
!("username" in body) || !("username" in body) ||
typeof body.username !== "string" typeof body.username !== "string"
) )
return sendError(context, rejectionErrors.noUsername) throw sendError(context, rejectionErrors.noUsername)
const { username } = body const { username } = body
if (!("password" in body) || typeof body.password !== "string") if (!("password" in body) || typeof body.password !== "string")
return sendError(context, rejectionErrors.noPassword) throw sendError(context, rejectionErrors.noPassword)
const { password } = body const { password } = body
return next(username, password) return { username, password }
} }
export default getUserFromBody export default getUserFromBody

View file

@ -37,4 +37,5 @@ export default function sendResponse<T>(context: API<T>, result: Result<T>) {
res.status(result.statusCode ?? 200) res.status(result.statusCode ?? 200)
result.body ? res.json(result.body) : res.end() result.body ? res.json(result.body) : res.end()
logging(result.message, result.type ?? ["debug"], req) logging(result.message, result.type ?? ["debug"], req)
return "done" as const
} }

View file

@ -6,16 +6,15 @@ import type { Player, Prisma } from "@prisma/client"
async function updatePlayerDB<T>( async function updatePlayerDB<T>(
context: API<T>, context: API<T>,
player: Player, player: Player,
data: Prisma.PlayerUpdateInput, data: Prisma.PlayerUpdateInput
next: (updatedPlayer: Player) => void
) { ) {
if (!player.anonymous) return sendError(context, rejectionErrors.registered) if (!player.anonymous) throw sendError(context, rejectionErrors.registered)
const updatedPlayer = await prisma.player.update({ const updatedPlayer = await prisma.player.update({
where: { id: player.id }, where: { id: player.id },
data, data,
}) })
return next(updatedPlayer) return updatedPlayer
} }
export default updatePlayerDB export default updatePlayerDB

View file

@ -28,7 +28,7 @@ async function getAccessToken() {
.then(successfulResponse) .then(successfulResponse)
.then((response) => { .then((response) => {
try { try {
const token = tokenSchema.parse(response) const { token } = tokenSchema.parse(response)
return token return token
} catch (err: any) { } catch (err: any) {

View file

@ -1,8 +1,6 @@
import sendError from "@backend/components/sendError"
import sendResponse from "@backend/components/sendResponse" import sendResponse from "@backend/components/sendResponse"
import getPlayer from "@lib/backend/components/getPlayer" import getPlayer from "@lib/backend/components/getPlayer"
import prisma from "@lib/prisma" import prisma from "@lib/prisma"
import { Game, Gamepin, Player_Game } from "@prisma/client"
import type { NextApiRequest, NextApiResponse } from "next" import type { NextApiRequest, NextApiResponse } from "next"
import { z } from "zod" import { z } from "zod"
@ -36,25 +34,40 @@ export default async function create(
) { ) {
const context = { req, res } const context = { req, res }
return getPlayer(context, async (player) => { const { player } = await getPlayer(context)
// Generate a random 4-digit code // Generate a random 4-digit code
const pin = Math.floor(Math.random() * 10000) const pin = Math.floor(Math.random() * 10000)
.toString() .toString()
.padStart(4, "0") .padStart(4, "0")
let created = false let created = false
let game:
| (Game & {
pin: Gamepin | null
players: Player_Game[]
})
| null
game = await prisma.game.findFirst({ let game = await prisma.game.findFirst({
where: { where: {
running: true, running: true,
players: {
some: {
playerId: player.id,
},
},
},
include: {
pin: true,
players: true,
},
})
if (!game) {
created = true
game = await prisma.game.create({
data: {
pin: {
create: {
pin,
},
},
players: { players: {
some: { create: {
isOwner: true,
playerId: player.id, playerId: player.id,
}, },
}, },
@ -64,42 +77,20 @@ export default async function create(
players: true, players: true,
}, },
}) })
if (!game) { }
created = true
game = await prisma.game.create({
data: {
pin: {
create: {
pin,
},
},
players: {
create: {
isOwner: true,
playerId: player.id,
},
},
},
include: {
pin: true,
players: true,
},
})
}
return sendResponse(context, { return sendResponse(context, {
message: `Player: ${player.id} created game: ${game.id}`, message: `Player: ${player.id} created game: ${game.id}`,
statusCode: created ? 201 : 200, statusCode: created ? 201 : 200,
body: { body: {
game, game,
pin: game.pin?.pin, pin: game.pin?.pin,
player: { player: {
id: player.id, id: player.id,
username: player.username ?? undefined, username: player.username ?? undefined,
isOwner: true, isOwner: true,
},
}, },
type: ["debug", "infoCyan"], },
}) type: ["debug", "infoCyan"],
}).catch((err) => sendError(context, err)) })
} }

View file

@ -17,63 +17,61 @@ export default async function join(
) { ) {
const context = { req, res } const context = { req, res }
return getPinFromBody(context, (pin) => const pin = await getPinFromBody(context)
getPlayer(context, async (player) => { const { player } = await getPlayer(context)
try { try {
const pinDB = await prisma.gamepin.update({ const pinDB = await prisma.gamepin.update({
where: { where: {
pin, pin,
}, },
data: { data: {
game: { game: {
update: { update: {
players: { players: {
create: { create: {
isOwner: false, isOwner: false,
playerId: player.id, playerId: player.id,
},
},
}, },
}, },
}, },
},
},
include: {
game: {
include: { include: {
game: { players: {
include: { include: {
players: { player: true,
include: {
player: true,
},
},
}, },
}, },
}, },
}) },
},
const enemy = pinDB.game.players.find(
(enemy) => enemy.player.id !== player.id
)
return sendResponse(context, {
message: `Player: ${player.id} joined game: ${pinDB.game.id}`,
body: {
game: pinDB.game,
pin: pinDB.pin,
player: {
id: player.id,
username: player.username ?? undefined,
isOwner: true,
},
enemy: {
id: enemy?.player.id,
username: enemy?.player.username ?? undefined,
isOwner: false,
},
},
type: ["debug", "infoCyan"],
})
} catch (err: any) {
console.log("HERE".red, err.code, err.meta, err.message)
return sendError(context, rejectionErrors.gameNotFound)
}
}) })
).catch((err) => sendError(context, err))
const enemy = pinDB.game.players.find(
(enemy) => enemy.player.id !== player.id
)
return sendResponse(context, {
message: `Player: ${player.id} joined game: ${pinDB.game.id}`,
body: {
game: pinDB.game,
pin: pinDB.pin,
player: {
id: player.id,
username: player.username ?? undefined,
isOwner: true,
},
enemy: {
id: enemy?.player.id,
username: enemy?.player.username ?? undefined,
isOwner: false,
},
},
type: ["debug", "infoCyan"],
})
} catch (err: any) {
console.log("HERE".red, err.code, err.meta, err.message)
throw sendError(context, rejectionErrors.gameNotFound)
}
} }

View file

@ -19,24 +19,25 @@ export default async function auth(
const context = { req, res } const context = { req, res }
const type = "ACCESS" const type = "ACCESS"
return getTokenFromCookie(context, (refreshToken, newPlayer) => { const { refreshToken, newPlayer } = await getTokenFromCookie(context)
const next = (player: Player, tokenDB: Token, cookie?: string) =>
createTokenDB(player, type, (newToken, newTokenDB) => let player: Player, tokenDB: Token, cookie: string | undefined
sendResponse(context, {
message: `Access-Token generated: ${newTokenDB.id} with Refreshtoken-Token: ${tokenDB.id}`, if (!newPlayer) {
body: { token: newToken.value }, const token = await checkTokenIsValid(context, refreshToken)
type: ["debug", "infoCyan"], tokenDB = await getTokenDB(context, token)
cookie, player = await getPlayerByIdDB(context, tokenDB)
}) } else {
) player = newPlayer.player
if (!newPlayer) { tokenDB = newPlayer.newTokenDB
return checkTokenIsValid(context, refreshToken, (token) => cookie = newPlayer.newToken.value
getTokenDB(context, token, (tokenDB) => }
getPlayerByIdDB(context, tokenDB, (player) => next(player, tokenDB))
) const { newToken, newTokenDB } = await createTokenDB(player, type)
) return sendResponse(context, {
} message: `Access-Token generated: ${newTokenDB.id} with Refreshtoken-Token: ${tokenDB.id}`,
const { player, newToken, newTokenDB } = newPlayer body: { token: newToken.value },
return next(player, newTokenDB, newToken.value) type: ["debug", "infoCyan"],
}).catch((err) => sendError(context, err)) cookie,
})
} }

View file

@ -1,4 +1,3 @@
import sendError from "@backend/components/sendError"
import sendResponse from "@backend/components/sendResponse" import sendResponse from "@backend/components/sendResponse"
import getPlayer from "@lib/backend/components/getPlayer" import getPlayer from "@lib/backend/components/getPlayer"
import type { Game } from "@prisma/client" import type { Game } from "@prisma/client"
@ -14,12 +13,11 @@ export default async function data(
) { ) {
const context = { req, res } const context = { req, res }
return getPlayer(context, (player, tokenDB) => { const { player, tokenDB } = await getPlayer(context)
const games: any = {} const games: any = {}
sendResponse(context, { return sendResponse(context, {
message: `Requested data of user: ${player.id} with Access-Token: ${tokenDB.id}`, message: `Requested data of user: ${player.id} with Access-Token: ${tokenDB.id}`,
body: { games }, body: { games },
type: ["debug", "infoCyan"], type: ["debug", "infoCyan"],
}) })
}).catch((err) => sendError(context, err))
} }

View file

@ -7,7 +7,6 @@ import sendResponse from "@backend/components/sendResponse"
import logging from "@backend/logging" import logging from "@backend/logging"
import { rejectionErrors } from "@lib/backend/errors" import { rejectionErrors } from "@lib/backend/errors"
import prisma from "@lib/prisma" import prisma from "@lib/prisma"
import { setCookie } from "cookies-next"
import jwt from "jsonwebtoken" import jwt from "jsonwebtoken"
import type { NextApiRequest, NextApiResponse } from "next" import type { NextApiRequest, NextApiResponse } from "next"
@ -21,34 +20,29 @@ export default async function login(
) { ) {
const context = { req, res } const context = { req, res }
return preCheck(context, () => await preCheck(context)
getUserFromBody(context, (username, password) => const { username, password } = await getUserFromBody(context)
getPlayerByNameDB(context, username, (player) => { const player = await getPlayerByNameDB(context, username)
checkPasswordIsValid(context, player, password, () => { await checkPasswordIsValid(context, player, password)
createTokenDB(player, "REFRESH", (newToken, newTokenDB) => { const { newToken, newTokenDB } = await createTokenDB(player, "REFRESH")
sendResponse(context, { return sendResponse(context, {
message: message:
"User " + "User " +
player.id + player.id +
" logged in and generated Refresh-Token: " + " logged in and generated Refresh-Token: " +
newTokenDB.id, newTokenDB.id,
body: { loggedIn: true }, body: { loggedIn: true },
type: ["debug", "infoCyan"], type: ["debug", "infoCyan"],
cookie: newToken.value, cookie: newToken.value,
}) })
})
})
})
)
).catch((err) => sendError(context, err))
} }
async function preCheck<T>(context: API<T>, next: () => void) { async function preCheck<T>(context: API<T>) {
const { req } = context const { req } = context
const oldRefreshToken = req.cookies.token const oldRefreshToken = req.cookies.token
try { try {
if (!oldRefreshToken) return sendError(context, rejectionErrors.noCookie) if (!oldRefreshToken) throw sendError(context, rejectionErrors.noCookie)
// Check for old cookie, if unused invalidate it // Check for old cookie, if unused invalidate it
const tokenData = jwt.verify( const tokenData = jwt.verify(
oldRefreshToken, oldRefreshToken,
@ -80,5 +74,5 @@ async function preCheck<T>(context: API<T>, next: () => void) {
// err is expected if no correct cookie, just continue, otherwise it has been invalidated above // err is expected if no correct cookie, just continue, otherwise it has been invalidated above
} }
return next() return
} }

View file

@ -2,7 +2,6 @@ import checkTokenIsValid from "@backend/components/checkTokenIsValid"
import getPlayerByIdDB from "@backend/components/getPlayerByIdDB" import getPlayerByIdDB from "@backend/components/getPlayerByIdDB"
import getTokenDB from "@backend/components/getTokenDB" import getTokenDB from "@backend/components/getTokenDB"
import getTokenFromCookie from "@backend/components/getTokenFromCookie" import getTokenFromCookie from "@backend/components/getTokenFromCookie"
import sendError from "@backend/components/sendError"
import sendResponse from "@backend/components/sendResponse" import sendResponse from "@backend/components/sendResponse"
import type { NextApiRequest, NextApiResponse } from "next" import type { NextApiRequest, NextApiResponse } from "next"
@ -16,16 +15,12 @@ export default async function auth(
) { ) {
const context = { req, res } const context = { req, res }
getTokenFromCookie(context, (refreshToken) => { const { refreshToken } = await getTokenFromCookie(context)
checkTokenIsValid(context, refreshToken, (token) => { const token = await checkTokenIsValid(context, refreshToken)
getTokenDB(context, token, (tokenDB) => { const tokenDB = await getTokenDB(context, token)
getPlayerByIdDB(context, tokenDB, (player) => { const player = await getPlayerByIdDB(context, tokenDB)
sendResponse(context, { return sendResponse(context, {
message: "loginCheck -> true : " + player.id, message: "loginCheck -> true : " + player.id,
type: ["debug", "infoCyan"], type: ["debug", "infoCyan"],
}) })
})
})
})
}).catch((err) => sendError(context, err))
} }

View file

@ -15,21 +15,14 @@ export default async function logout(
) { ) {
const context = { req, res } const context = { req, res }
return getTokenFromCookie(context, (refreshToken) => const { refreshToken } = await getTokenFromCookie(context)
decodeToken(context, refreshToken, (token) => const token = await decodeToken(context, refreshToken)
getTokenDB( const tokenDB = await getTokenDB(context, token, true)
context,
token, return sendResponse(context, {
(tokenDB) => { message: "User of Token " + tokenDB.id + " logged out.",
return sendResponse(context, { body: { loggedOut: true },
message: "User of Token " + tokenDB.id + " logged out.", type: ["debug", "infoCyan"],
body: { loggedOut: true }, cookie: "",
type: ["debug", "infoCyan"], })
cookie: "",
})
},
true
)
)
).catch((err) => sendError(context, err))
} }

View file

@ -19,32 +19,22 @@ export default async function register(
) { ) {
const context = { req, res } const context = { req, res }
return getTokenFromCookie(context, (refreshToken) => { const { refreshToken } = await getTokenFromCookie(context)
checkTokenIsValid(context, refreshToken, (token) => { const token = await checkTokenIsValid(context, refreshToken)
getTokenDB(context, token, (tokenDB) => { const tokenDB = await getTokenDB(context, token)
getUserFromBody(context, (username, password) => const { username, password } = await getUserFromBody(context)
getPlayerByIdDB(context, tokenDB, async (player) => let player = await getPlayerByIdDB(context, tokenDB)
updatePlayerDB( player = await updatePlayerDB(context, player, {
context, username,
player, email: "arst",
{ passwordHash: await bcrypt.hash(password, 10),
username, anonymous: false,
email: "arst", })
passwordHash: await bcrypt.hash(password, 10),
anonymous: false, return sendResponse(context, {
}, message: "Player registered : " + player.id,
(player) => { statusCode: 201,
sendResponse(context, { body: { registered: true },
message: "Player registered : " + player.id, type: ["debug", "infoCyan"],
statusCode: 201, })
body: { registered: true },
type: ["debug", "infoCyan"],
})
}
)
)
)
})
})
}).catch((err) => sendError(context, err))
} }

View file

@ -16,25 +16,23 @@ export default async function remove(
) { ) {
const context = { req, res } const context = { req, res }
return getUserFromBody(context, (username, password) => const { username, password } = await getUserFromBody(context)
getPlayerByNameDB(context, username, (player) => { const player = await getPlayerByNameDB(context, username)
checkPasswordIsValid(context, player, password, () => { await checkPasswordIsValid(context, player, password)
prisma.player.update({ prisma.player.update({
where: { where: {
id: player.id, id: player.id,
}, },
data: { data: {
deleted: true, deleted: true,
username: null, username: null,
email: null, email: null,
passwordHash: null, passwordHash: null,
}, },
}) })
sendResponse(context, {
message: "User successfully deleted: " + player.id, return sendResponse(context, {
type: ["debug", "infoCyan"], message: "User successfully deleted: " + player.id,
}) type: ["debug", "infoCyan"],
}) })
})
).catch((err) => sendError(context, err))
} }

View file

@ -34,7 +34,7 @@ interface SocketData {
// const authenticate = (socket, next) => { // const authenticate = (socket, next) => {
// socket.isAuthenticated = false // socket.isAuthenticated = false
// next() //
// } // }
async function checkTokenIsValid(rawToken: string) { async function checkTokenIsValid(rawToken: string) {