Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tony yang2 #48

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
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
103 changes: 52 additions & 51 deletions api/auth/auth-router.js
Original file line number Diff line number Diff line change
@@ -1,59 +1,60 @@
const router = require('express').Router();
const bcryptjs = require('bcryptjs');
const db = require('../../data/dbConfig')
const makeToken = require('../middleware/token')



router.post('/register', (req, res) => {
res.end('implement register, please!');
/*
IMPLEMENT
You are welcome to build additional middlewares to help with the endpoint's functionality.
DO NOT EXCEED 2^8 ROUNDS OF HASHING!

1- In order to register a new account the client must provide `username` and `password`:
{
"username": "Captain Marvel", // must not exist already in the `users` table
"password": "foobar" // needs to be hashed before it's saved
}

2- On SUCCESSFUL registration,
the response body should have `id`, `username` and `password`:
{
"id": 1,
"username": "Captain Marvel",
"password": "2a$08$jG.wIGR2S4hxuyWNcBf9MuoC4y0dNy7qC/LbmtuFBSdIhWks2LhpG"
}

3- On FAILED registration due to `username` or `password` missing from the request body,
the response body should include a string exactly as follows: "username and password required".

4- On FAILED registration due to the `username` being taken,
the response body should include a string exactly as follows: "username taken".
*/
const user = req.body
if(isValid(user)) {
const rounds = process.env.BCRYPT_ROUNDS || 8;
const hash = bcryptjs.hashSync(user.password, rounds )

user.password = hash;

return db('users').insert(user)
.then(user => {
res.status(201).json({data: user})
})
.catch(err => {
res.status(500).json({message: err.message});
})
} else {
res.status(400).json({message:"username taken" })
}
function isValid(user){
return Boolean(user.username && user.password && typeof user.password === "string");
}

});

router.post('/login', (req, res) => {
res.end('implement login, please!');
/*
IMPLEMENT
You are welcome to build additional middlewares to help with the endpoint's functionality.

1- In order to log into an existing account the client must provide `username` and `password`:
{
"username": "Captain Marvel",
"password": "foobar"
}

2- On SUCCESSFUL login,
the response body should have `message` and `token`:
{
"message": "welcome, Captain Marvel",
"token": "eyJhbGciOiJIUzI ... ETC ... vUPjZYDSa46Nwz8"
}

3- On FAILED login due to `username` or `password` missing from the request body,
the response body should include a string exactly as follows: "username and password required".

4- On FAILED login due to `username` not existing in the db, or `password` being incorrect,
the response body should include a string exactly as follows: "invalid credentials".
*/
router.post('/login', async (req, res, next) => {
const { username, password } = req.body

if(isValid(req.body)) {
await db('users').where( "username", username)
.then(([user]) => {
if(user && bcryptjs.compareSync( password, user.password)) {
const token = makeToken(user)
res.status(200).json({ message:"Welcome," + user.username, token })
} else {
res.status(401).json({ message: 'Invalid Credentials' })
}
})
.catch( err => {
res.status(500).json({ message: err.message})
})
} else {
res.status(400).json({
message: "Username and password required"
})

}
function isValid(user){
return Boolean(user.username && user.password && typeof user.password === "string");
}

});

module.exports = router;
26 changes: 15 additions & 11 deletions api/middleware/restricted.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
module.exports = (req, res, next) => {
next();
/*
IMPLEMENT

1- On valid token in the Authorization header, call next.
const jwt = require('jsonwebtoken');

2- On missing token in the Authorization header,
the response body should include a string exactly as follows: "token required".
module.exports = (req, res, next) => {
const token = req.headers.authorization

3- On invalid or expired token in the Authorization header,
the response body should include a string exactly as follows: "token invalid".
*/
if (!token){
res.status(401).json({ message: "token required" })
} else {
jwt.verify(token, jwtSecret, ( err , decoded) => {
if (err){
res.status(401).json({ message: "token invalid"})
} else {
req.decodedJwt = decoded
next()
}
})
}
};
16 changes: 16 additions & 0 deletions api/middleware/token.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const jwt = require('jsonwebtoken');
const jwtSecret = "TBOSS";

module.exports = function makeToken(user){

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

const options = {
expiresIn: "100000s",
}
return jwt.sign( payload, jwtSecret, options);

}
1 change: 1 addition & 0 deletions api/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const express = require('express');
const cors = require('cors');
const helmet = require('helmet');


const restrict = require('./middleware/restricted.js');

const authRouter = require('./auth/auth-router.js');
Expand Down
51 changes: 50 additions & 1 deletion api/server.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,53 @@
// Write your tests here

const request = require('supertest')
const db = require('./../data/dbConfig')
const server = require('./server')

const tony = { username: "Tony", password: "12345" }
beforeAll( async() => {
await db.migrate.rollback()
await db.migrate.latest()
})

beforeEach( async() => {
await db('users').truncate()
})

afterAll( async() => {
await db.destroy()
})

test('sanity', () => {
expect(true).toBe(false)
expect(true).toBe(true)
})

describe('server', () => {
describe('[GET] /jokes', () => {
it('Returns a 403 if not user', async() => {
const res = await request(server).get('/api/jokes')
expect(res.status).toBe(401)
})
})

describe("[POST] /users", () => {
it('Returns new user', async() => {
let res
res = await request(server).post("/api/auth/register").send(tony)

expect(res.status).toEqual(201)
})
})

describe('[POST] /login', () => {
it('Good stuff', async () => {
await request(server).post('/api/auth/register').send(tony)
let res
res = await request(server).post('/api/auth/login').send(tony)
expect(res.status).toEqual(200)
})
})


})

Binary file modified data/auth.db3
Binary file not shown.
Loading