Skip to content

Commit

Permalink
Lesson 5
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanszeto committed Sep 12, 2023
1 parent 698fd51 commit 68f474b
Show file tree
Hide file tree
Showing 15 changed files with 728 additions and 79 deletions.
7 changes: 7 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ import express from "express";
import cors from "cors";
import helmet from "helmet";
import route from "./routes/pages.route.js";
import bodyParser from "body-parser";
import cookieParser from "cookie-parser";
import path from "path";

const app = express();

app.set("view engine", "ejs");
app.set("views", path.resolve() + "/views");

app.use(cors());
app.use(helmet());
app.use(express.json());
app.use(cookieParser())
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use("/", route);

Expand Down
23 changes: 23 additions & 0 deletions auth/authorization.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import dotenv from "dotenv";
import jwt from "jsonwebtoken";

const authorize = (req, res, next) => {
dotenv.config();
if(req.cookies.token) {
const payload = jwt.verify(req.cookies.token, process.env.TOKEN_KEY);
if(payload) {
req.user = payload;
next();
} else {
//Forbidden - tampered token
req.error = 403;
next();
}
} else {
//Unauthorized - not logged in
req.error = 401;
next();
}
}

export default authorize;
26 changes: 26 additions & 0 deletions controllers/error.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const errorHandler = (req, res) => {
if(req.error) {
switch(req.error) {
case 400:
res.cookie("error", "Bad Request. Try again.", {maxAge: 1000});
res.redirect("/login-page");
break;
case 401:
res.cookie("error", "Login to have full access.", {maxAge: 1000});
res.redirect("/login-page");
break;
case 403:
res.cookie("error", "Forbidden. Log out and try again.", {maxAge: 1000});
res.redirect("/login-page");
break;
default:
res.cookie("error", "There was an error.", {maxAge: 1000});
res.redirect("/");
break;
}
} else {
res.redirect("/");
}
}

export default errorHandler;
103 changes: 102 additions & 1 deletion controllers/user.controller.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,110 @@
import UserAccessor from "../db_accessor/user.accessor.js";
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";

export default class UserController {
static async getAllUsers(req, res) {
const users = await UserAccessor.getAllUsers();
console.log(users);
res.render("index", { users: users } );
}

static async followUser(req, res, next) {
if(!req.error) {
const toFollow = req.body.follow;
const username = req.user.username;
const following = req.user.following;

if(!following.some((follower) => {follower === toFollow}) && toFollow != username) {
await UserAccessor.addFollower(username, toFollow);
}

res.redirect('/');
} else {
return next();
}
}

static getProfile(req, res, next) {
if(!req.error) {
const user = req.user;
res.render('profile',
{
name: user.username,
email: user.email,
bio: user.bio,
followers: user.followers,
following: user.following,
});
} else {
return next();
}
}

static getLogout(req, res) {
res.clearCookie("token");
res.redirect('/');
console.log("Signed out");
}

static getLoginPage(req, res) {
if(req.cookies.token) {
res.redirect('/profile');
} else {
res.render('login_page', {error: req.cookies.error});
}
}

static getSignUpPage(req, res) {
if(req.cookies.token) {
res.redirect('/profile');
} else {
res.render('sign_up');
}
}

static async postLogin(req, res, next) {
try {
if(!req.cookies.token) {
const user = await UserAccessor.getUser(req.body.username);
if(user) {
const result = await bcrypt.compare(req.body.password, user.password);
if(result) {
const token = jwt.sign(
{
username: user.username,
email: user.email,
bio: user.bio,
followers: user.followers,
following: user.following
},
process.env.TOKEN_KEY
);
res.cookie('token', token, {httpOnly: true, maxAge: 60 * 60 * 1000});
res.redirect('/profile');
} else {
req.error = 400;
next();
}
} else {
req.error = 400;
next();
}
} else {
res.redirect('/profile');
}
} catch(e) {
req.error = 400;
next();
}
}

static async postSignUp(req, res, next) {
try {
req.body.password = await bcrypt.hash(req.body.password, 10);
await UserAccessor.createUser(req.body);
res.redirect("/login-page");
} catch (e) {
return next();
}
}
}
45 changes: 0 additions & 45 deletions css/index.css
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
body {
background-color: #000000;
color: #eeeeee;
font-family: 'Trebuchet MS', sans-serif;
}

.profile-container {
justify-items: center;
display: grid;
grid-template-columns: 300px 300px 300px;
column-gap: 20px;
row-gap: 20px;
background-color: #0e142e;
padding: 20px 40px 30px 40px;
border-radius: 20px;
position: absolute;
left: 50%;
transform: translate(-50%);
}

.profile-block {
Expand All @@ -25,37 +13,4 @@ body {
width: 250px;
border-radius: 20px;
margin-top: 10px;
}

.btn {
min-width: 130px;
height: 40px;
color: #ffffff;
padding: 5px 10px;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
display: inline-block;
outline: none;
border-radius: 5px;
border: 2px solid #3c51b0;
background: #3c51b0;
}

.btn:hover {
background: #b4bef0;
color: #2c51b0;
}

.hr {
width: 50%;
}

#header {
text-align: center;
}

#description {
text-align: center;
}
66 changes: 66 additions & 0 deletions css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
body {
background-color: #000000;
color: #eeeeee;
font-family: 'Trebuchet MS', sans-serif;
}

.btn {
min-width: 130px;
height: 40px;
color: #ffffff;
padding: 5px 10px;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
display: inline-block;
outline: none;
border-radius: 5px;
border: 2px solid #3c51b0;
background: #3c51b0;
}

.btn:hover {
background: #b4bef0;
color: #2c51b0;
}

.hr {
width: 50%;
}

.header {
text-align: center;
}

.text-input {
background-color: #000000;
color: #ffffff;
}

.input-break {
display: block;
content: "";
margin-top: 20px;
}

.page-content {
min-width: 25%;
text-align: center;
background-color: #0e142e;
padding: 20px 40px 30px 40px;
border-radius: 20px;
position: absolute;
left: 50%;
transform: translate(-50%);
}

.description {
text-align: center;
}

.page-buttons {
position: fixed;
top: 10px;
right: 10px;
}
38 changes: 38 additions & 0 deletions db_accessor/user.accessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,42 @@ export default class UserAccessor {
throw e;
}
}

static async getUser(username) {
try {
await Connection.open("users");
const user = await User.findOne({ username: username });
return user;
} catch (e) {
throw e;
}
}

static async createUser(userDoc) {
try {
await Connection.open("users");
const user = await User.create(userDoc);
return user;
} catch (e) {
throw e;
}
}

static async addFollower(userWhoFollowed, userToFollow) {
try {
const follower = await UserAccessor.getUser(userWhoFollowed);
const followee = await UserAccessor.getUser(userToFollow);

const followerList = follower.following;
followerList.push(userToFollow);

const followeeList = followee.followers;
followeeList.push(userWhoFollowed);

await User.findOneAndUpdate({ username: userWhoFollowed }, { following: followerList });
await User.findOneAndUpdate({ username: userToFollow }, { followers: followeeList });
} catch (e) {
throw e;
}
}
}
12 changes: 0 additions & 12 deletions login.html

This file was deleted.

Loading

0 comments on commit 68f474b

Please sign in to comment.