Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions app/components/Login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ export const Login = () => {
const data = await response.json();

if (!data.success) return setErrMsg(data.msg);

localStorage.setItem("token", data.token);
if (data.token) {
document.cookie = `token=${
data.token
};SameSite=None; Secure; path=/; max-age=${3600 * 24 * 31}; `;
}
router.push("/dashboard");
} catch (err) {
console.log(err);
Expand Down
7 changes: 6 additions & 1 deletion app/components/Register.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ export const Register = () => {
const data = await response.json();

if (!data.success) return setErrMsg(data.msg);

if (data.token) {
document.cookie = `token=${
data.token
};SameSite=None; Secure; path=/; max-age=${3600 * 24 * 31}; `;
}
console.log(data);
router.push("/dashboard");
} catch (err) {
console.log(err);
Expand Down
27 changes: 27 additions & 0 deletions middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { NextResponse } from "next/server";
import { jwtVerify } from "jose";
// This function can be marked `async` if using `await` inside
export async function middleware(request) {
const token = request.cookies.get("token");
if (token) {
try {
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
console.log("secret", secret);

// Verify the token using jose in Edge Middleware
const { payload } = await jwtVerify(token.value, secret);
console.log("payload", payload);
if (payload) {
return NextResponse.next();
}
} catch (error) {
console.error("Token verification failed:", error);
}
}
return NextResponse.redirect(new URL("/", request.url));
}

// See "Matching Paths" below to learn more
export const config = {
matcher: "/dashboard",
};
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"dependencies": {
"bcrypt": "^5.1.1",
"jose": "^5.9.6",
"jsonwebtoken": "^9.0.2",
"mongodb": "^6.9.0",
"next": "14.2.13",
Expand Down
131 changes: 74 additions & 57 deletions pages/api/add-user.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,89 @@
import {addUserModel, getUserModel} from "@/app/models/userModel";
import { addUserModel, getUserModel } from "@/app/models/userModel";
import bcrypt from "bcrypt";

import jwt from "jsonwebtoken";

export default function addUser(req, res) {

const result = validateRequest(req);

if(!result.success){
return res.json(result);
}

handleRequest({req, res});
};
const result = validateRequest(req);

if (!result.success) {
return res.json(result);
}

async function handleRequest(param){
const {req, res} = param;
handleRequest({ req, res });
}

//check if user exists already
try{
const query = {
$or: [
{username: req.body.username},
{emailAddress: req.body.emailAddress}
]
};
async function handleRequest(param) {
const { req, res } = param;

const result = await getUserModel(query);
if(result){
res.status(400).json({success: false, msg: "Username or e-mail exists already"});
return;
}
}
catch(err){
console.log(err);
res.status(500).json({success: false, msg: "Internal server error."});
return;
}
//check if user exists already
try {
const query = {
$or: [
{ username: req.body.username },
{ emailAddress: req.body.emailAddress },
],
};

//add user to db
try{
const hashedPassword = await bcrypt.hash(req.body.password, 10);
const doc = {
username: req.body.username,
emailAddress: req.body.emailAddress,
password: hashedPassword
};
const result = await getUserModel(query);
if (result) {
res
.status(400)
.json({ success: false, msg: "Username or e-mail exists already" });
return;
}
} catch (err) {
console.log(err);
res.status(500).json({ success: false, msg: "Internal server error." });
return;
}

const result = await addUserModel(doc);
}
catch(err){
console.log(err);
res.status(500).json({success: false, msg: "Internal server error."});
return;
}
//add user to db
try {
const hashedPassword = await bcrypt.hash(req.body.password, 10);
const doc = {
username: req.body.username,
emailAddress: req.body.emailAddress,
password: hashedPassword,
};

res.status(200).json({success: true, msg: "User has been added to db."});
const result = await addUserModel(doc);
let token = null;
try {
token = jwt.sign(
{
_id: result.insertedId,
username: req.body.username,
emailAddress: req.body.emailAddress,
password: hashedPassword,
},
process.env.JWT_SECRET
);
} catch (err) {
console.log(err);
return res.status(200).json({
success: true,
msg: "User added to db but failed to create token.",
token,
});
}
return res
.status(200)
.json({ success: true, msg: "User has been added to db.", token });
} catch (err) {
console.log(err);
res.status(500).json({ success: false, msg: "Internal server error." });
return;
}
}

function validateRequest(req) {
if (req.method !== "POST") {
return { success: false, msg: "Only POST requests are allowed" };
}

function validateRequest(req){
if(req.method !== "POST"){
return {success: false, msg: "Only POST requests are allowed"};
}

if(!req.body.username || !req.body.emailAddress || !req.body.password){
return {success: false, msg: "Not all credentials have been provided."};
}
if (!req.body.username || !req.body.emailAddress || !req.body.password) {
return { success: false, msg: "Not all credentials have been provided." };
}

return {success: true};
return { success: true };
}
94 changes: 54 additions & 40 deletions pages/api/sign-in.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,65 @@
import jwt from "jsonwebtoken";
import bcrypt from "bcrypt";
import {getUserModel} from "@/app/models/userModel";
import { getUserModel } from "@/app/models/userModel";

export default function signIn(req, res){

handleRequest({req, res});
export default function signIn(req, res) {
handleRequest({ req, res });
}

async function handleRequest(param) {
const { req, res } = param;

async function handleRequest(param){
const {req, res} = param;

//get user
let user = null;
try{
const query = {
$or: [
{username: req.body.nameOrEmail},
{emailAddress: req.body.nameOrEmail},
],
}
//get user
let user = null;
try {
const query = {
$or: [
{ username: req.body.nameOrEmail },
{ emailAddress: req.body.nameOrEmail },
],
};

user = await getUserModel(query);
if(!user){
return res.status(400).json({success: false, msg: "No user has been found:"});
}
user = await getUserModel(query);
console.log(user);
if (!user) {
return res
.status(400)
.json({ success: false, msg: "No user has been found:" });
}

const isCorrectPwd = await bcrypt.compare(req.body.password, user.password);
if(!isCorrectPwd){
return res.status(400).json({success: false, msg: "Wrong password."});
}
}
catch(err){
console.log(err);
return res.status(500).json({success: false, msg: "Internal server error."});
}
const isCorrectPwd = await bcrypt.compare(req.body.password, user.password);
if (!isCorrectPwd) {
return res.status(400).json({ success: false, msg: "Wrong password." });
}
} catch (err) {
console.log(err);
return res
.status(500)
.json({ success: false, msg: "Internal server error." });
}

//create token
let token = null;
try{
token = await jwt.sign(user, process.env.JWT_SECRET);
}
catch(err){
console.log(err);
return res.status(500).json({success: false, msg: "Internal server error."});
}
//create token
let token = null;
console.log(user._id);
try {
token = jwt.sign(
{
_id: user._id,
username: user.username,
emailAddress: user.emailAddress,
password: user.password,
},
process.env.JWT_SECRET
);
} catch (err) {
console.log(err);
return res
.status(500)
.json({ success: false, msg: "Internal server error." });
}

res.setHeader("Authorization", `Bearer ${token}`);
res.status(200).json({success: true, msg: "Authorization header set.", token});
res.setHeader("Authorization", `Bearer ${token}`);
res
.status(200)
.json({ success: true, msg: "Authorization header set.", token });
}