finalized adding support for access tokens

This commit is contained in:
daniel31x13
2024-01-24 15:48:40 -05:00
parent 05563134b4
commit 5be194235c
18 changed files with 366 additions and 106 deletions
+3 -4
View File
@@ -1,14 +1,13 @@
import { prisma } from "@/lib/api/db";
import { KeyExpiry } from "@/types/global";
import bcrypt from "bcrypt";
import crypto from "crypto";
export default async function getToken(userId: number) {
const getTokens = await prisma.apiKey.findMany({
const getTokens = await prisma.accessToken.findMany({
where: {
userId,
revoked: false,
},
select: {
id: true,
name: true,
expires: true,
createdAt: true,
+14 -10
View File
@@ -1,12 +1,12 @@
import { prisma } from "@/lib/api/db";
import { KeyExpiry } from "@/types/global";
import { TokenExpiry } from "@/types/global";
import crypto from "crypto";
import { decode, encode, getToken } from "next-auth/jwt";
import { decode, encode } from "next-auth/jwt";
export default async function postToken(
body: {
name: string;
expires: KeyExpiry;
expires: TokenExpiry;
},
userId: number
) {
@@ -20,9 +20,10 @@ export default async function postToken(
status: 400,
};
const checkIfTokenExists = await prisma.apiKey.findFirst({
const checkIfTokenExists = await prisma.accessToken.findFirst({
where: {
name: body.name,
revoked: false,
userId,
},
});
@@ -39,16 +40,16 @@ export default async function postToken(
const oneDayInSeconds = 86400;
let expiryDateSecond = 7 * oneDayInSeconds;
if (body.expires === KeyExpiry.oneMonth) {
if (body.expires === TokenExpiry.oneMonth) {
expiryDate.setDate(expiryDate.getDate() + 30);
expiryDateSecond = 30 * oneDayInSeconds;
} else if (body.expires === KeyExpiry.twoMonths) {
} else if (body.expires === TokenExpiry.twoMonths) {
expiryDate.setDate(expiryDate.getDate() + 60);
expiryDateSecond = 60 * oneDayInSeconds;
} else if (body.expires === KeyExpiry.threeMonths) {
} else if (body.expires === TokenExpiry.threeMonths) {
expiryDate.setDate(expiryDate.getDate() + 90);
expiryDateSecond = 90 * oneDayInSeconds;
} else if (body.expires === KeyExpiry.never) {
} else if (body.expires === TokenExpiry.never) {
expiryDate.setDate(expiryDate.getDate() + 73000); // 200 years (not really never)
expiryDateSecond = 73050 * oneDayInSeconds;
} else {
@@ -72,7 +73,7 @@ export default async function postToken(
secret: process.env.NEXTAUTH_SECRET,
});
const createToken = await prisma.apiKey.create({
const createToken = await prisma.accessToken.create({
data: {
name: body.name,
userId,
@@ -82,7 +83,10 @@ export default async function postToken(
});
return {
response: token,
response: {
secretKey: token,
token: createToken,
},
status: 200,
};
}
@@ -1,16 +1,24 @@
import { prisma } from "@/lib/api/db";
import { KeyExpiry } from "@/types/global";
export default async function deleteToken(userId: number, tokenId: number) {
if (!tokenId)
return { response: "Please choose a valid token.", status: 401 };
const deletedToken = await prisma.apiKey.delete({
const tokenExists = await prisma.accessToken.findFirst({
where: {
id: tokenId,
userId,
},
});
return { response: deletedToken, status: 200 };
const revokedToken = await prisma.accessToken.update({
where: {
id: tokenExists?.id,
},
data: {
revoked: true,
},
});
return { response: revokedToken, status: 200 };
}
+36
View File
@@ -0,0 +1,36 @@
import { NextApiRequest } from "next";
import { JWT, getToken } from "next-auth/jwt";
import { prisma } from "./db";
type Props = {
req: NextApiRequest;
};
export default async function verifyToken({
req,
}: Props): Promise<JWT | string> {
const token = await getToken({ req });
const userId = token?.id;
if (!userId) {
return "You must be logged in.";
}
if (token.exp < Date.now() / 1000) {
return "Your session has expired, please log in again.";
}
// check if token is revoked
const revoked = await prisma.accessToken.findFirst({
where: {
token: token.jti,
revoked: true,
},
});
if (revoked) {
return "Your session has expired, please log in again.";
}
return token;
}
+8 -14
View File
@@ -1,8 +1,8 @@
import { NextApiRequest, NextApiResponse } from "next";
import { getToken } from "next-auth/jwt";
import { prisma } from "./db";
import { User } from "@prisma/client";
import verifySubscription from "./verifySubscription";
import verifyToken from "./verifyToken";
type Props = {
req: NextApiRequest;
@@ -15,21 +15,15 @@ export default async function verifyUser({
req,
res,
}: Props): Promise<User | null> {
const token = await getToken({ req });
const token = await verifyToken({ req });
if (typeof token === "string") {
res.status(401).json({ response: token });
return null;
}
const userId = token?.id;
if (!userId) {
res.status(401).json({ response: "You must be logged in." });
return null;
}
if (token.exp < Date.now() / 1000) {
res
.status(401)
.json({ response: "Your session has expired, please log in again." });
return null;
}
const user = await prisma.user.findUnique({
where: {
id: userId,