Skip to content
This repository was archived by the owner on Mar 23, 2020. It is now read-only.
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
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
JWT_SECRET="this super secure"
83 changes: 83 additions & 0 deletions auth/auth-router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');

const secrets = require('../config/secrets.js');

const Users = require('../users/users-model.js');
const restrict = require('../middleware/restrict.js');

const router = express.Router();

router.post('/login', async (req, res, next) => {
const authError = {
message:"You shall not pass!",
}

try{
let { username, password } = req.body;

const user = await Users.findBy({ username }).first();

if (!user) {
return res.status(401). json(authError)
}

const passwordValid = await bcrypt.compare(password, user.password)
if (!passwordValid) {
return res.status(401).json(authError)
}
console.log("got past username and password, ", passwordValid, user.id)
const payload = {
userId: user.id,
userRole: 'admin',
}

const token = jwt.sign(payload, process.env.JWT_SECRET)
console.log(token)

res.cookie('token', token)

res.json({
message:`Welcome ${user.username}!`,
})
} catch(err) {

}
})

function generateToken(user) {
const payload = {
subject: user.id,
username: user.username,
}


const options = {
expiresIn: '1d',
}

return jwt.sign(payload, secrets.jwtSecret, options);
}

router.post('/register', async (req, res, next) => {
try{
const { username } = req.body;
const user = await Users.findBy({ username }).first();

if(user){
return res.status(409).json({
message: "Username is already taken"
})
}

res.status(201).json(await Users.add(req.body));

} catch(err) {
next(err);
}

})

module.exports = router;
5 changes: 5 additions & 0 deletions config/secrets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@


module.exports = {
jwtSecret: process.env.JWT_SECRET || 'this super secure',
}
4 changes: 4 additions & 0 deletions database/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const knex = require("knex")
const knexfile = require("../knexfile")

module.exports = knex(knexfile)
12 changes: 12 additions & 0 deletions database/migrations/20200318180253_create-accounts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
exports.up = async function(knex) {
await knex.schema.createTable("users", (table) => {
table.increments()
table.text("username").notNull().unique()
table.text("password").notNull()
table.text("department", 30)
})
}

exports.down = async function(knex) {
await knex.schema.dropTableIfExists("users")
}
Binary file added database/users.db3
Binary file not shown.
36 changes: 36 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const express = require("express")
const helmet = require("helmet")
const cors = require("cors")
const cookieParser = require("cookie-parser")
const authRouter = require("./auth/auth-router.js")
const usersRouter = require("./users/users-router.js")

const server = express()
const port = process.env.PORT || 5000

server.use(cors())
server.use(helmet())
server.use(express.json())

server.use(cookieParser())


server.use("/api/users", usersRouter)
server.use("/api", authRouter)

server.get("/", (req, res, next) => {
res.json({
message: "Welcome to our API",
})
})

server.use((err, req, res, next) => {
console.log(err)
res.status(500).json({
message: "Something went wrong",
})
})

server.listen(port, () => {
console.log(`Running at http://localhost:${port}`)
})
18 changes: 18 additions & 0 deletions knexfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
client: "sqlite3",
useNullAsDefault: true,
connection: {
filename: "./database/users.db3",
},
migrations: {
directory: "./database/migrations",
},
seeds: {
directory: "./database/seeds",
},
pool: {
afterCreate: (conn, done) => {
conn.run("PRAGMA foreign_keys = ON", done)
},
},
}
16 changes: 16 additions & 0 deletions middleware/restrict-role.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function restrictRole(role) {
return (req, res, next) => {
// restrict() has to be called before this or these values will be undefined
if (req.token && req.token.userRole === role) {
// user is authorized and matches the role we're looking for
next()
} else {
// user does not match the role we're looking for
return res.status(403).json({
message: "You are not allowed here",
})
}
}
}

module.exports = restrictRole
36 changes: 36 additions & 0 deletions middleware/restrict.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const bcrypt = require("bcryptjs")
const jwt = require("jsonwebtoken")
const Users = require("../users/users-model")

function restrict() {
const authError = {
message: "You shall not Pass!",
}

return async (req, res, next) => {
try {

const { token } = req.cookies

if (!token) {
return res.status(401).json(authError)
}

jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
if (err) {

return res.status(401).json(authError)
}

req.token = decoded
console.log(decoded)

next()
})
} catch(err) {
next(err)
}
}
}

module.exports = restrict
36 changes: 36 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "auth3-project",
"version": "1.0.0",
"description": "- Authentication.\r - Express Middleware.\r - JSON Web Tokens (JWTs).\r - Hashing Passwords.",
"main": "index.js",
"private": true,
"scripts": {
"server": "nodemon -r dotenv/config index.js",
"start": "node index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/littleonetwo/node-auth3-project.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/littleonetwo/node-auth3-project/issues"
},
"homepage": "https://github.com/littleonetwo/node-auth3-project#readme",
"dependencies": {
"bcrypt": "^4.0.1",
"bcryptjs": "^2.4.3",
"cookie-parser": "^1.4.5",
"cookieparser": "^0.1.0",
"cor": "^0.0.0",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"helmet": "^3.21.3",
"jsonwebtoken": "^8.5.1",
"knex": "^0.20.11",
"nodemon": "^2.0.2",
"sqlite3": "^4.1.1"
}
}
34 changes: 34 additions & 0 deletions users/users-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const bcrypt = require("bcryptjs")
const db = require("../database/config")

async function add(user) {
user.password = await bcrypt.hash(user.password, 14)

const [id] = await db("users").insert(user)
return findById(id)
}

function find() {
return db("users").select("id", "username")
}

function findBy(filter) {
console.log(filter);
return db("users")
.select("id", "username", "password")
.where(filter)
}

function findById(id) {
return db("users")
.select("id", "username")
.where({ id })
.first()
}

module.exports = {
add,
find,
findBy,
findById,
}
17 changes: 17 additions & 0 deletions users/users-router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const express = require("express")
const Users = require("./users-model")
const restrict = require("../middleware/restrict")
const restrictRole = require("../middleware/restrict-role")

const router = express.Router()

// Order of the middleware chain here is very important
router.get("/", restrict(), restrictRole("admin"), async (req, res, next) => {
try {
res.json(await Users.find())
} catch(err) {
next(err)
}
})

module.exports = router
Loading