Improved passing of req, res, and tokens
This commit is contained in:
parent
a8e5b57363
commit
39ddf8fde9
17 changed files with 134 additions and 170 deletions
|
@ -1,19 +1,17 @@
|
||||||
import { Player } from "@prisma/client"
|
import { Player } from "@prisma/client"
|
||||||
import bcrypt from "bcrypt"
|
import bcrypt from "bcrypt"
|
||||||
import errors from "../errors"
|
import errors from "../errors"
|
||||||
import sendError from "./sendError"
|
import sendError, { API } from "./sendError"
|
||||||
import { NextApiRequest, NextApiResponse } from "next"
|
|
||||||
|
|
||||||
export default async function checkPasswordIsValid(
|
export default async function checkPasswordIsValid(
|
||||||
req: NextApiRequest,
|
context: API,
|
||||||
res: NextApiResponse,
|
|
||||||
player: Player,
|
player: Player,
|
||||||
password: string,
|
password: string,
|
||||||
next: () => void
|
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(req, res, errors.wrongPassword)
|
if (!result) return sendError(context, errors.wrongPassword)
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,29 @@
|
||||||
import { TokenType } from "@prisma/client"
|
|
||||||
import jwt from "jsonwebtoken"
|
import jwt from "jsonwebtoken"
|
||||||
import errors from "../errors"
|
import errors from "../errors"
|
||||||
import jwtVerifyCatch from "../jwtVerifyCatch"
|
import jwtVerifyCatch from "../jwtVerifyCatch"
|
||||||
import { NextApiRequest, NextApiResponse } from "next"
|
import sendError, { API } from "./sendError"
|
||||||
import sendError from "./sendError"
|
import { IdToken, RawToken } from "./createTokenDB"
|
||||||
|
|
||||||
async function checkTokenIsValid(
|
async function checkTokenIsValid(
|
||||||
req: NextApiRequest,
|
context: API,
|
||||||
res: NextApiResponse,
|
rawToken: RawToken,
|
||||||
rawToken: [string, TokenType],
|
next: (token: IdToken) => void
|
||||||
next: (tokenBody: jwt.JwtPayload) => void
|
|
||||||
) {
|
) {
|
||||||
const [tokenValue, tokenType] = rawToken
|
const { value, type } = rawToken
|
||||||
|
|
||||||
// Verify the token and get the payload
|
// Verify the token and get the payload
|
||||||
let tokenData: string | jwt.JwtPayload
|
let data: string | jwt.JwtPayload
|
||||||
try {
|
try {
|
||||||
tokenData = jwt.verify(
|
data = jwt.verify(value, process.env.ACCESS_TOKEN_SECRET as string)
|
||||||
tokenValue,
|
|
||||||
process.env.ACCESS_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(req, res, jwtVerifyCatch(tokenType, err))
|
return 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 tokenData === "string")
|
if (typeof data === "string")
|
||||||
return sendError(req, res, errors.tokenWasString(tokenType, tokenValue))
|
return sendError(context, errors.tokenWasString(type, value))
|
||||||
|
|
||||||
return next(tokenData)
|
return next({ id: data.id, type })
|
||||||
}
|
}
|
||||||
|
|
||||||
export default checkTokenIsValid
|
export default checkTokenIsValid
|
||||||
|
|
|
@ -2,6 +2,15 @@ import { Player, Token, TokenType } from "@prisma/client"
|
||||||
import jwt from "jsonwebtoken"
|
import jwt from "jsonwebtoken"
|
||||||
import prisma from "../../prisma"
|
import prisma from "../../prisma"
|
||||||
|
|
||||||
|
export interface RawToken {
|
||||||
|
value: string
|
||||||
|
type: TokenType
|
||||||
|
}
|
||||||
|
export interface IdToken {
|
||||||
|
id: string
|
||||||
|
type: TokenType
|
||||||
|
}
|
||||||
|
|
||||||
const tokenLifetime = {
|
const tokenLifetime = {
|
||||||
REFRESH: 172800,
|
REFRESH: 172800,
|
||||||
ACCESS: 15,
|
ACCESS: 15,
|
||||||
|
@ -10,7 +19,7 @@ const tokenLifetime = {
|
||||||
export default async function createTokenDB(
|
export default async function createTokenDB(
|
||||||
player: Player,
|
player: Player,
|
||||||
newTokenType: TokenType,
|
newTokenType: TokenType,
|
||||||
next: (token: [string, Token]) => void
|
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({
|
||||||
|
@ -32,5 +41,5 @@ export default async function createTokenDB(
|
||||||
{ expiresIn: tokenLifetime[newTokenType] }
|
{ expiresIn: tokenLifetime[newTokenType] }
|
||||||
)
|
)
|
||||||
|
|
||||||
return next([newToken, newTokenDB])
|
return next({ value: newToken, type: "ACCESS" }, newTokenDB)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
import { Player, Token } from "@prisma/client"
|
import { Player, Token } from "@prisma/client"
|
||||||
import errors from "../errors"
|
import errors from "../errors"
|
||||||
import prisma from "../../prisma"
|
import prisma from "../../prisma"
|
||||||
import { NextApiRequest, NextApiResponse } from "next"
|
import sendError, { API } from "./sendError"
|
||||||
import sendError from "./sendError"
|
|
||||||
|
|
||||||
export default async function getPlayerByIdDB(
|
export default async function getPlayerByIdDB(
|
||||||
req: NextApiRequest,
|
context: API,
|
||||||
res: NextApiResponse,
|
|
||||||
tokenDB: Token,
|
tokenDB: Token,
|
||||||
next: (player: Player) => void
|
next: (player: Player) => void
|
||||||
) {
|
) {
|
||||||
|
@ -17,7 +15,7 @@ export default async function getPlayerByIdDB(
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (!player) {
|
if (!player) {
|
||||||
return sendError(req, res, errors.playerNotFound)
|
return sendError(context, errors.playerNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
return next(player)
|
return next(player)
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
import { Player } from "@prisma/client"
|
import { Player } from "@prisma/client"
|
||||||
import errors from "../errors"
|
import errors from "../errors"
|
||||||
import prisma from "../../prisma"
|
import prisma from "../../prisma"
|
||||||
import sendError from "./sendError"
|
import sendError, { API } from "./sendError"
|
||||||
import { NextApiRequest, NextApiResponse } from "next"
|
|
||||||
|
|
||||||
export default async function getPlayerByNameDB(
|
export default async function getPlayerByNameDB(
|
||||||
req: NextApiRequest,
|
context: API,
|
||||||
res: NextApiResponse,
|
|
||||||
username: string,
|
username: string,
|
||||||
next: (player: Player) => void
|
next: (player: Player) => void
|
||||||
) {
|
) {
|
||||||
|
@ -23,7 +21,7 @@ export default async function getPlayerByNameDB(
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
]).catch(() => null)
|
]).catch(() => null)
|
||||||
if (player === null) return sendError(req, res, errors.playerNotFound)
|
if (player === null) return sendError(context, errors.playerNotFound)
|
||||||
|
|
||||||
return next(player)
|
return next(player)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,28 @@
|
||||||
import prisma from "../../prisma"
|
import prisma from "../../prisma"
|
||||||
import jwt from "jsonwebtoken"
|
import { Token } from "@prisma/client"
|
||||||
import { Token, TokenType } from "@prisma/client"
|
|
||||||
import errors from "../errors"
|
import errors from "../errors"
|
||||||
import sendError from "./sendError"
|
import sendError, { API } from "./sendError"
|
||||||
import { NextApiRequest, NextApiResponse } from "next"
|
import { IdToken } from "./createTokenDB"
|
||||||
|
|
||||||
async function getTokenDB(
|
async function getTokenDB(
|
||||||
req: NextApiRequest,
|
context: API,
|
||||||
res: NextApiResponse,
|
token: IdToken,
|
||||||
tokenBody: jwt.JwtPayload,
|
|
||||||
tokenType: TokenType,
|
|
||||||
next: (tokenDB: Token) => void
|
next: (tokenDB: Token) => void
|
||||||
) {
|
) {
|
||||||
|
const { id, type } = token
|
||||||
// Find refresh token in DB
|
// Find refresh token in DB
|
||||||
const tokenDB = await prisma.token.findUnique({
|
const tokenDB = await prisma.token.findUnique({
|
||||||
where: {
|
where: {
|
||||||
id: tokenBody.id,
|
id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (!tokenDB) return sendError(req, res, errors.tokenNotFound(tokenType))
|
if (!tokenDB) return sendError(context, errors.tokenNotFound(type))
|
||||||
|
|
||||||
if (tokenDB.used) return sendError(req, res, errors.tokenUsed)
|
if (tokenDB.used) return sendError(context, errors.tokenUsed)
|
||||||
|
|
||||||
await prisma.token.update({
|
await prisma.token.update({
|
||||||
where: {
|
where: {
|
||||||
id: tokenBody.id,
|
id,
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
used: true,
|
used: true,
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
import { TokenType } from "@prisma/client"
|
import sendError, { API } from "./sendError"
|
||||||
import { NextApiRequest, NextApiResponse } from "next"
|
import { RawToken } from "./createTokenDB"
|
||||||
import sendError from "./sendError"
|
|
||||||
|
|
||||||
async function getTokenFromBody(
|
async function getTokenFromBody(
|
||||||
req: NextApiRequest,
|
context: API,
|
||||||
res: NextApiResponse,
|
next: (accessToken: RawToken) => void
|
||||||
next: (refreshToken: [string, TokenType]) => void
|
|
||||||
) {
|
) {
|
||||||
const body = JSON.parse(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
|
||||||
if (
|
if (
|
||||||
typeof body !== "object" ||
|
typeof body !== "object" ||
|
||||||
|
@ -15,14 +13,14 @@ async function getTokenFromBody(
|
||||||
!("token" in body) ||
|
!("token" in body) ||
|
||||||
typeof body.token !== "string"
|
typeof body.token !== "string"
|
||||||
)
|
)
|
||||||
return sendError(req, res, {
|
return sendError(context, {
|
||||||
message: "Unauthorized. No Access-Token.",
|
message: "Unauthorized. No Access-Token.",
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
solved: true,
|
solved: true,
|
||||||
})
|
})
|
||||||
const tokenValue = body.token
|
const value = body.token
|
||||||
|
|
||||||
return next([tokenValue, "ACCESS"])
|
return next({ value, type: "ACCESS" })
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getTokenFromBody
|
export default getTokenFromBody
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
import { TokenType } from "@prisma/client"
|
|
||||||
import { NextApiRequest, NextApiResponse } from "next"
|
|
||||||
import errors from "../errors"
|
import errors from "../errors"
|
||||||
import sendError from "./sendError"
|
import { RawToken } from "./createTokenDB"
|
||||||
|
import sendError, { API } from "./sendError"
|
||||||
|
|
||||||
async function getTokenFromCookie(
|
async function getTokenFromCookie(
|
||||||
req: NextApiRequest,
|
context: API,
|
||||||
res: NextApiResponse,
|
next: (refreshToken: RawToken) => void
|
||||||
next: (refreshToken: [string, TokenType]) => void
|
|
||||||
) {
|
) {
|
||||||
const tokenValue = 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 (!tokenValue) return sendError(req, res, errors.noCookie)
|
if (!value) return sendError(context, errors.noCookie)
|
||||||
|
|
||||||
return next([tokenValue, "REFRESH"])
|
return next({ value, type: "REFRESH" })
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getTokenFromCookie
|
export default getTokenFromCookie
|
||||||
|
|
|
@ -1,23 +1,21 @@
|
||||||
import { NextApiRequest, NextApiResponse } from "next"
|
import sendError, { API } from "./sendError"
|
||||||
import sendError from "./sendError"
|
|
||||||
import errors from "../errors"
|
import errors from "../errors"
|
||||||
|
|
||||||
async function getUserFromBody(
|
async function getUserFromBody(
|
||||||
req: NextApiRequest,
|
context: API,
|
||||||
res: NextApiResponse,
|
|
||||||
next: (username: string, password: string) => void
|
next: (username: string, password: string) => void
|
||||||
) {
|
) {
|
||||||
const body = JSON.parse(req.body)
|
const body = JSON.parse(context.req.body)
|
||||||
if (
|
if (
|
||||||
typeof body !== "object" ||
|
typeof body !== "object" ||
|
||||||
!body ||
|
!body ||
|
||||||
!("username" in body) ||
|
!("username" in body) ||
|
||||||
typeof body.username !== "string"
|
typeof body.username !== "string"
|
||||||
)
|
)
|
||||||
return sendError(req, res, errors.noUsername)
|
return sendError(context, errors.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(req, res, errors.noPassword)
|
return sendError(context, errors.noPassword)
|
||||||
const { password } = body
|
const { password } = body
|
||||||
|
|
||||||
return next(username, password)
|
return next(username, password)
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import { NextApiRequest, NextApiResponse } from "next"
|
import { NextApiRequest, NextApiResponse } from "next"
|
||||||
import logging from "../logging"
|
import logging from "../logging"
|
||||||
|
|
||||||
export default function sendError(
|
export interface API {
|
||||||
req: NextApiRequest,
|
req: NextApiRequest
|
||||||
res: NextApiResponse,
|
res: NextApiResponse
|
||||||
err: any
|
}
|
||||||
) {
|
|
||||||
|
export default function sendError(context: API, err: any) {
|
||||||
|
const { res, req } = context
|
||||||
// If something went wrong, let the client know with status 500
|
// If something went wrong, let the client know with status 500
|
||||||
res.status(err.statusCode ?? 500).end()
|
res.status(err.statusCode ?? 500).end()
|
||||||
logging(err.message, [err.type ?? (err.solved ? "debug" : "error")], req)
|
logging(err.message, [err.type ?? (err.solved ? "debug" : "error")], req)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { NextApiRequest, NextApiResponse } from "next"
|
|
||||||
import logging, { Logging } from "../logging"
|
import logging, { Logging } from "../logging"
|
||||||
|
import type { API } from "./sendError"
|
||||||
|
|
||||||
export interface Result<T> {
|
export interface Result<T> {
|
||||||
message: string
|
message: string
|
||||||
|
@ -8,11 +8,8 @@ export interface Result<T> {
|
||||||
type?: Logging[]
|
type?: Logging[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function sendResponse<T>(
|
export default function sendResponse<T>(context: API, result: Result<T>) {
|
||||||
req: NextApiRequest,
|
const { req, res } = context
|
||||||
res: NextApiResponse<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)
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
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<ParsedUrlQuery, PreviewData>
|
|
||||||
) {
|
|
||||||
const req: any = context.req
|
|
||||||
const res: any = context.res
|
|
||||||
|
|
||||||
const isLoggedIn = await getTokenFromCookie(req, res, (token) =>
|
|
||||||
checkTokenIsValid(req, res, token, (tokenBody) =>
|
|
||||||
getTokenDB(req, res, tokenBody, token[1], (tokenDB) =>
|
|
||||||
getPlayerByIdDB(req, res, tokenDB, (player) => !!player)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
).catch(() => false)
|
|
||||||
|
|
||||||
logging(
|
|
||||||
"loginCheck " + (isLoggedIn ? true : "-> loggedIn: " + false),
|
|
||||||
["debug", "infoCyan"],
|
|
||||||
req
|
|
||||||
)
|
|
||||||
|
|
||||||
return isLoggedIn
|
|
||||||
}
|
|
|
@ -6,7 +6,9 @@ import getTokenFromCookie from "../../lib/backend/components/getTokenFromCookie"
|
||||||
import checkTokenIsValid from "../../lib/backend/components/checkTokenIsValid"
|
import checkTokenIsValid from "../../lib/backend/components/checkTokenIsValid"
|
||||||
import getTokenDB from "../../lib/backend/components/getTokenDB"
|
import getTokenDB from "../../lib/backend/components/getTokenDB"
|
||||||
import getPlayerByIdDB from "../../lib/backend/components/getPlayerByIdDB"
|
import getPlayerByIdDB from "../../lib/backend/components/getPlayerByIdDB"
|
||||||
import createTokenDB from "../../lib/backend/components/createTokenDB"
|
import createTokenDB, {
|
||||||
|
RawToken,
|
||||||
|
} from "../../lib/backend/components/createTokenDB"
|
||||||
import sendResponse from "../../lib/backend/components/sendResponse"
|
import sendResponse from "../../lib/backend/components/sendResponse"
|
||||||
|
|
||||||
interface Data {
|
interface Data {
|
||||||
|
@ -17,26 +19,26 @@ export default async function auth(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
res: NextApiResponse<Data>
|
res: NextApiResponse<Data>
|
||||||
) {
|
) {
|
||||||
getTokenFromCookie(req, res, (token) => {
|
const context = { req, res }
|
||||||
checkTokenIsValid(req, res, token, (tokenBody) => {
|
|
||||||
getTokenDB(req, res, tokenBody, token[1], (tokenDB) => {
|
getTokenFromCookie(context, (refreshToken) => {
|
||||||
getPlayerByIdDB(req, res, tokenDB, (player) => {
|
checkTokenIsValid(context, refreshToken, (token) => {
|
||||||
createTokenDB(player, "ACCESS", (newToken) => {
|
getTokenDB(context, token, (tokenDB) => {
|
||||||
sendResponse(req, res, authResponse(newToken, tokenDB))
|
getPlayerByIdDB(context, tokenDB, (player) => {
|
||||||
|
createTokenDB(player, "ACCESS", (newToken, newTokenDB) => {
|
||||||
|
sendResponse(context, authResponse(newToken, newTokenDB, tokenDB))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}).catch((err) => sendError(req, res, err))
|
}).catch((err) => sendError(context, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
function authResponse(newToken: [string, Token], tokenDB: Token) {
|
function authResponse(newToken: RawToken, newTokenDB: Token, tokenDB: Token) {
|
||||||
const [newTokenValue, newTokenDB] = newToken
|
|
||||||
|
|
||||||
// Successfull response
|
// Successfull response
|
||||||
return {
|
return {
|
||||||
message: `Access-Token generated: ${newTokenDB.id} with Refreshtoken-Token: ${tokenDB.id}`,
|
message: `Access-Token generated: ${newTokenDB.id} with Refreshtoken-Token: ${tokenDB.id}`,
|
||||||
body: { token: newTokenValue },
|
body: { token: newToken.value },
|
||||||
type: ["debug", "info.cyan"] as Logging[],
|
type: ["debug", "info.cyan"] as Logging[],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,17 @@ export default async function data(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
res: NextApiResponse<Data>
|
res: NextApiResponse<Data>
|
||||||
) {
|
) {
|
||||||
return getTokenFromBody(req, res, (token) => {
|
const context = { req, res }
|
||||||
checkTokenIsValid(req, res, token, (tokenBody) => {
|
|
||||||
getTokenDB(req, res, tokenBody, token[1], (tokenDB) => {
|
return getTokenFromBody(context, (accessToken) => {
|
||||||
getPlayerByIdDB(req, res, tokenDB, (player) => {
|
checkTokenIsValid(context, accessToken, (token) => {
|
||||||
sendResponse(req, res, dataResponse(player, tokenDB))
|
getTokenDB(context, token, (tokenDB) => {
|
||||||
|
getPlayerByIdDB(context, tokenDB, (player) => {
|
||||||
|
sendResponse(context, dataResponse(player, tokenDB))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}).catch((err) => sendError(req, res, err))
|
}).catch((err) => sendError(context, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
function dataResponse<T>(player: Player, tokenDB: Token) {
|
function dataResponse<T>(player: Player, tokenDB: Token) {
|
||||||
|
|
|
@ -2,14 +2,17 @@ import { NextApiRequest, NextApiResponse } from "next"
|
||||||
import logging, { Logging } from "../../lib/backend/logging"
|
import logging, { Logging } from "../../lib/backend/logging"
|
||||||
import getPlayerByNameDB from "../../lib/backend/components/getPlayerByNameDB"
|
import getPlayerByNameDB from "../../lib/backend/components/getPlayerByNameDB"
|
||||||
import checkPasswordIsValid from "../../lib/backend/components/checkPasswordIsValid"
|
import checkPasswordIsValid from "../../lib/backend/components/checkPasswordIsValid"
|
||||||
import createTokenDB from "../../lib/backend/components/createTokenDB"
|
import createTokenDB, {
|
||||||
|
IdToken,
|
||||||
|
RawToken,
|
||||||
|
} from "../../lib/backend/components/createTokenDB"
|
||||||
import sendResponse from "../../lib/backend/components/sendResponse"
|
import sendResponse from "../../lib/backend/components/sendResponse"
|
||||||
import { setCookie } from "cookies-next"
|
import { setCookie } from "cookies-next"
|
||||||
import { Player, Token } from "@prisma/client"
|
import { Player, Token } from "@prisma/client"
|
||||||
import prisma from "../../lib/prisma"
|
import prisma from "../../lib/prisma"
|
||||||
import jwt from "jsonwebtoken"
|
import jwt from "jsonwebtoken"
|
||||||
import errors from "../../lib/backend/errors"
|
import errors from "../../lib/backend/errors"
|
||||||
import sendError from "../../lib/backend/components/sendError"
|
import sendError, { API } from "../../lib/backend/components/sendError"
|
||||||
import getUserFromBody from "../../lib/backend/components/getUserFromBody"
|
import getUserFromBody from "../../lib/backend/components/getUserFromBody"
|
||||||
|
|
||||||
interface Data {
|
interface Data {
|
||||||
|
@ -18,30 +21,32 @@ interface Data {
|
||||||
|
|
||||||
export default async function login(
|
export default async function login(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
res: NextApiResponse<any>
|
res: NextApiResponse<Data>
|
||||||
) {
|
) {
|
||||||
return preCheck(req, res, () =>
|
const context = { req, res }
|
||||||
getUserFromBody(req, res, (username, password) =>
|
|
||||||
getPlayerByNameDB(req, res, username, (player) => {
|
return preCheck(context, () =>
|
||||||
checkPasswordIsValid(req, res, player, password, () => {
|
getUserFromBody(context, (username, password) =>
|
||||||
createTokenDB(player, "REFRESH", (newToken) => {
|
getPlayerByNameDB(context, username, (player) => {
|
||||||
sendResponse(req, res, loginResponse(player, newToken, req, res))
|
checkPasswordIsValid(context, player, password, () => {
|
||||||
|
createTokenDB(player, "REFRESH", (newToken, newTokenDB) => {
|
||||||
|
sendResponse(
|
||||||
|
context,
|
||||||
|
loginResponse(context, player, newToken, newTokenDB)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
).catch((err) => sendError(req, res, err))
|
).catch((err) => sendError(context, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function preCheck(
|
async function preCheck(context: API, next: () => void) {
|
||||||
req: NextApiRequest,
|
const { req } = context
|
||||||
res: NextApiResponse,
|
|
||||||
next: () => void
|
|
||||||
) {
|
|
||||||
const oldRefreshToken = req.cookies.token
|
const oldRefreshToken = req.cookies.token
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!oldRefreshToken) return sendError(req, res, errors.noCookie)
|
if (!oldRefreshToken) return sendError(context, errors.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,
|
||||||
|
@ -76,17 +81,18 @@ async function preCheck(
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
function loginResponse<T>(
|
function loginResponse(
|
||||||
|
context: API,
|
||||||
player: Player,
|
player: Player,
|
||||||
newToken: [string, Token],
|
newToken: RawToken,
|
||||||
req: NextApiRequest,
|
newTokenDB: Token
|
||||||
res: NextApiResponse<T>
|
|
||||||
) {
|
) {
|
||||||
|
const { req, res } = context
|
||||||
// const { player, req, res } = payload
|
// const { player, req, res } = payload
|
||||||
const [newTokenValue, newTokenDB] = newToken
|
const { value } = newToken
|
||||||
|
|
||||||
// Set login cookie
|
// Set login cookie
|
||||||
setCookie("token", newTokenValue, {
|
setCookie("token", value, {
|
||||||
req,
|
req,
|
||||||
res,
|
res,
|
||||||
maxAge: 172800,
|
maxAge: 172800,
|
||||||
|
@ -96,15 +102,6 @@ function loginResponse<T>(
|
||||||
path: "/api",
|
path: "/api",
|
||||||
})
|
})
|
||||||
|
|
||||||
// deleteCookie("token", {
|
|
||||||
// req,
|
|
||||||
// res,
|
|
||||||
// httpOnly: true,
|
|
||||||
// sameSite: true,
|
|
||||||
// secure: true,
|
|
||||||
// path: "/api",
|
|
||||||
// })
|
|
||||||
|
|
||||||
// Successfull response
|
// Successfull response
|
||||||
return {
|
return {
|
||||||
message:
|
message:
|
||||||
|
|
|
@ -16,13 +16,15 @@ export default async function logout(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
res: NextApiResponse<any>
|
res: NextApiResponse<any>
|
||||||
) {
|
) {
|
||||||
return getTokenFromCookie(req, res, (token) => {
|
const context = { req, res }
|
||||||
checkTokenIsValid(req, res, token, (tokenBody) => {
|
|
||||||
getTokenDB(req, res, tokenBody, token[1], (tokenDB) => {
|
return getTokenFromCookie(context, (refreshToken) => {
|
||||||
sendResponse(req, res, logoutResponse(tokenDB, req, res))
|
checkTokenIsValid(context, refreshToken, (token) => {
|
||||||
|
getTokenDB(context, token, (tokenDB) => {
|
||||||
|
sendResponse(context, logoutResponse(tokenDB, req, res))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}).catch((err) => sendError(req, res, err))
|
}).catch((err) => sendError(context, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
function logoutResponse<T>(
|
function logoutResponse<T>(
|
||||||
|
|
|
@ -14,10 +14,12 @@ export default async function register(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
res: NextApiResponse<Data>
|
res: NextApiResponse<Data>
|
||||||
) {
|
) {
|
||||||
return getUserFromBody(req, res, (username, password) =>
|
const context = { req, res }
|
||||||
|
|
||||||
|
return getUserFromBody(context, (username, password) =>
|
||||||
createPlayerDB(username, password, (player) => {
|
createPlayerDB(username, password, (player) => {
|
||||||
sendResponse(req, res, registerResponse(player))
|
sendResponse(context, registerResponse(player))
|
||||||
}).catch((err) => sendError(req, res, err))
|
}).catch((err) => sendError(context, err))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue