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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions server/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.env
node_modules/
3 changes: 3 additions & 0 deletions server/config/default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"jwtSecret": "mysecrettoken"
}
60 changes: 60 additions & 0 deletions server/controllers/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
import User from "../models/user.js";
import config from "config";
import pkg from "express-validator";

const { validationResult } = pkg;
//log in user and get token
export const login = async (req, res) => {
//check for errors returned by express validator
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}

const { email, password } = req.body;

try {
let user = await User.findOne({ email });

if (!user) {
return res.status(400).json({ errors: [{ msg: "Invalid Credentials" }] });
}

const isMatch = await bcrypt.compare(password, user.password);

if (!isMatch) {
return res.status(400).json({ errors: [{ msg: "Invalid Credentials" }] });
}

//return token

const payload = {
user: {
id: user.id,
},
};

jwt.sign(payload, config.get("jwtSecret"), { expiresIn: 36000 }, (err, token) => {
if (err) throw err;

res.json({ token });
});
} catch (err) {
console.error(err.message);
res.status(500).send("Server error");
}
};

//authenticate logged in user with token. req.user.id comes from auth middleware

export const authenticateUser = async (req, res) => {
try {
const user = await User.findById(req.user.id).select("-password");
res.json(user);
} catch (err) {
console.error(err.message);
err.status(500).send("Server Error");
}
};
54 changes: 54 additions & 0 deletions server/controllers/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
import User from "../models/user.js";
import config from "config";
import pkg from "express-validator";

const { validationResult } = pkg;
//register a new user
export const register = async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { name, email, password } = req.body;
try {
//check for existing user
let user = await User.findOne({ email });

if (user) {
return res.status(400).json({ errors: [{ msg: "User already exists" }] });
}

user = new User({
name,
email,
password,
});

//encrypt password
const salt = await bcrypt.genSalt(10);

user.password = await bcrypt.hash(password, salt);

//add to database
await user.save();

//return token
//initialize payload which includes id added to the User object by mongoose
const payload = {
user: {
id: user.id,
},
};

jwt.sign(payload, config.get("jwtSecret"), { expiresIn: 36000 }, (err, token) => {
if (err) throw err;

res.json({ token });
});
} catch (error) {
console.error(err.message);
res.status(500).send("Server error");
}
};
37 changes: 37 additions & 0 deletions server/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import express from "express";
import bodyParser from "body-parser";
import mongoose from "mongoose";
//import cors from 'cors';
import dotenv from "dotenv";

import userRouter from "./routes/user.js";
import authRouter from "./routes/auth.js";

const app = express();
//dotenv is required to access .env variables
dotenv.config();

app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));
//app.use(cors());

app.use("/user", userRouter);
app.use("/auth", authRouter);

//mongo

const CONNECTION_URL = process.env.CONNECTION;
const PORT = process.env.PORT;

mongoose
.connect(CONNECTION_URL, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => app.listen(PORT, () => console.log(`Server running on port: ${PORT}`)))
.catch((error) => console.log(error.message));

//mongoose.set('useFindAndModify', false);

//todo
// return error if all fields are not entered during user registration
// check if email is valid during registration
//require password length?
// use express validator library for this
23 changes: 23 additions & 0 deletions server/middleware/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import jwt from "jsonwebtoken";
import config from "config";

export const auth = async (req, res, next) => {
//get token from req header
const token = req.header("x-auth-token");

if (!token) {
return res.status(401).json({ msg: "No token, authorization denied" });
}

//verify token

try {
const decoded = jwt.verify(token, config.get("jwtSecret"));
//when we assigned the token, the userId is included in the encoded token
req.user = decoded.user;
//pass userId to authenticateUser function
next();
} catch (err) {
res.status(401).json({ msg: "Token is invalid" });
}
};
24 changes: 24 additions & 0 deletions server/models/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import mongoose from "mongoose";

const UserSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
},
{
timestamps: true,
}
);

export default mongoose.model("User", UserSchema);
1 change: 1 addition & 0 deletions server/node_modules/.bin/is-ci

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

1 change: 1 addition & 0 deletions server/node_modules/.bin/json5

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

1 change: 1 addition & 0 deletions server/node_modules/.bin/mime

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

1 change: 1 addition & 0 deletions server/node_modules/.bin/nodemon

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

1 change: 1 addition & 0 deletions server/node_modules/.bin/nodetouch

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

1 change: 1 addition & 0 deletions server/node_modules/.bin/nopt

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

1 change: 1 addition & 0 deletions server/node_modules/.bin/rc

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

1 change: 1 addition & 0 deletions server/node_modules/.bin/semver

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

Loading