Skip to content

Commit

Permalink
Xmas working hard (#20)
Browse files Browse the repository at this point in the history
* JSAEM2-10 create end point (#5)

* JSAEM-2_7_Sign_up_page,endpoint for register (#6)

JSAEM-2_7_Sign_up_page,endpoint for register

* JSAEM2-35 implement a end-point to get a list of user names (#7)

* JSAEM2-35 implement a end-point to get a list of user names

* JSAEM2-35 fixed: add new line

* JSAEM2-35 add prefix-search for users end point (#8)

* JSA-DB-RECONFIGURE : using mongoDB instead (#9)

* JSAEM2-31 signup backend (#11)

* JSAEM2-31 signup backend

* JSAEM2-31 lint issue

* JSAEM 2-31 return error message

* JSAEM2-32 feat: signIn back end (#12)

* JSAEM2-32 feat: signIn back end

* JSAEM2-32 fixed: status code update

* JSAEM2-33 family creation endpoint with no email (#13)

* JSAEM2-33 family creation endpoint with no email

* JSAEM2-33 add email service to family creation endpoint

* JSAEM2-33 fixed: lint issue

* JSAEM2-33 Feat: email notification added

* JSAEM2-36 feat: add family transactions (#15)

* JSAEM2-37 add get family transactions endpoint (#16)

* Jsaem2 10 user is able to backup/restore their data (#17)

* JSAEM2-10 fixed: fix bcrypt bug

* JSAEM2-10 update: user is able to backup data

* JSAEM2-10 update: update restore function

* JSAEM2-10 update: update try catch

* JSAEM2-10 update: update backup and restore func

* update: finish backend backup and restore

* JSAEM2-10 fixed: fixed rebase problem

* JSAEM2-42 fixed: return model instance (#18)

* JSAEM2-42 fixed: return model instance

* JSAEM2-42 fixed: removed the useless file

* Jsaem2 43 test coverage (#19)

* JSAEM2-43 feat: add tests

* JSAEM2-43 feat: improve test coverage to 70%

* JSAEM2-43 fixed: lint issue

* JSAEM2-43 feat: improve test coverage to 90%

* JSAEM2-43 feat: enabled mock email test

Co-authored-by: Katy Tao <[email protected]>
Co-authored-by: Wen Zaiquan <[email protected]>
  • Loading branch information
3 people authored and ikarasz committed Jan 7, 2020
1 parent 545514e commit c0e7e38
Show file tree
Hide file tree
Showing 16 changed files with 6,241 additions and 225 deletions.
8 changes: 7 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,11 @@
"ecmaVersion": 2018
},
"rules": {
}
},
"overrides": [
{
"files":["**/*.test.js"],
"env": { "jest": true }
}
]
}
7 changes: 6 additions & 1 deletion ENV_EXAMPLE
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
EXPRESS_PORT=
DB_HOST=
DB_PORT=
DB_USER=
DB_PASS=
DB_DATABASE=
JWT_SECRET=
EMAIL_USER=
EMAIL_PASS=
9 changes: 9 additions & 0 deletions Models/Families.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const mongoose = require('mongoose');

const families = new mongoose.Schema({
members: Array,
creator: mongoose.Schema.Types.ObjectId,
transactions: Array,
});

module.exports = mongoose.model('families', families);
11 changes: 11 additions & 0 deletions Models/Transaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const mongoose = require('mongoose');

const transactions = new mongoose.Schema({
creator: mongoose.Schema.Types.ObjectId,
amount: Number,
labelName: String,
date: String,
type: String,
});

module.exports = mongoose.model('transactions', transactions);
11 changes: 11 additions & 0 deletions Models/Users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const mongoose = require('mongoose');

const users = new mongoose.Schema({
username: String,
email: String,
hashedPass: String,
transactions: Array,
cusLabels: Array,
});

module.exports = mongoose.model('users', users);
45 changes: 45 additions & 0 deletions Utils/Auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const moment = require('moment');

const getReqToken = (req) => {
let token = '';
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
[, token] = req.headers.authorization.split(' ');
}
return token;
};

const verifyToken = (req, res, next) => {
const token = getReqToken(req);
if (token === '') {
return res.sendStatus(401);
}
req.token = token;
return next();
};

const passwordHash = (password) => {
const salt = bcrypt.genSaltSync(10);
return bcrypt.hashSync(password, salt);
};

const signature60min = (obj, secret) => jwt.sign(obj, secret, { expiresIn: '1h' });

const signature30day = (obj, secret) => jwt.sign(obj, secret, { expiresIn: '30d' });

const getTokenSet = (obj, secret) => ({
accessToken: signature60min(obj, secret),
accessTokenExpiresAt: moment().add(1, 'hours').format(),
refreshToken: signature30day(obj, secret),
refreshTokenExpiresAt: moment().add(30, 'days').format(),
});

module.exports = {
getReqToken,
verifyToken,
passwordHash,
signature60min,
signature30day,
getTokenSet,
};
98 changes: 98 additions & 0 deletions Utils/Auth.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const {
getReqToken,
verifyToken,
passwordHash,
signature60min,
signature30day,
getTokenSet,
} = require('./Auth');

describe('Auth Utility File', () => {
it('getReqToken Null', () => {
const token = '';
const testObj = { headers: { } };
const res = getReqToken(testObj);
expect(res).toEqual(token);
});

it('getReqToken Empty', () => {
const token = '';
const testObj = { headers: { authorization: `Bearer ${token}` } };
const res = getReqToken(testObj);
expect(res).toEqual(token);
});

it('getReqToken', () => {
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9';
const testObj = { headers: { authorization: `Bearer ${token}` } };
const res = getReqToken(testObj);
expect(res).toEqual(token);
});

it('passwordHash Empty', () => {
const password = '';
const res = passwordHash(password);
expect(bcrypt.compareSync(password, res)).toEqual(true);
});

it('passwordHash', () => {
const password = '123456678';
const res = passwordHash(password);
expect(bcrypt.compareSync(password, res)).toEqual(true);
});

it('signature60min', () => {
const obj = { name: 'mike', email: '[email protected]' };
const secret = 'SECRET';
const res = signature60min(obj, secret);
const resObj = jwt.verify(res, secret);
expect(resObj.name).toEqual(obj.name);
expect(resObj.email).toEqual(obj.email);
});

it('signature30day', () => {
const obj = { name: 'mike', email: '[email protected]' };
const secret = 'SECRET';
const res = signature30day(obj, secret);
const resObj = jwt.verify(res, secret);
expect(resObj.name).toEqual(obj.name);
expect(resObj.email).toEqual(obj.email);
});

it('getTokenSet', () => {
const obj = { name: 'mike', email: '[email protected]' };
const secret = 'SECRET';
const res = getTokenSet(obj, secret);
const resObj60min = jwt.verify(res.accessToken, secret);
const resObj30day = jwt.verify(res.refreshToken, secret);
expect(resObj60min.name).toEqual(obj.name);
expect(resObj60min.email).toEqual(obj.email);
expect(resObj30day.name).toEqual(obj.name);
expect(resObj30day.email).toEqual(obj.email);
});


const mockResponse = () => {
const res = {};
res.sendStatus = jest.fn((val) => { res.status = val; });
return res;
};

it('verifyToken Empty', async () => {
const token = '';
const req = { headers: { authorization: `Bearer ${token}` } };
const res = mockResponse();
await verifyToken(req, res, () => {});
expect(res.status).toEqual(401);
});

it('verifyToken', async () => {
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9';
const req = { headers: { authorization: `Bearer ${token}` } };
const res = mockResponse();
await verifyToken(req, res, () => {});
expect(req.token).toEqual(token);
});
});
17 changes: 17 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,34 @@ const express = require('express');
const debug = require('debug')('Emerald');
const cors = require('cors');
require('dotenv').config();
const mongooseInit = require('./mongoDB');

const app = express();
const indexRouter = require('./routes/index');
const userRouter = require('./routes/users');

// DB Init
mongooseInit();

// middleware setup
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

// Route
app.use('/', indexRouter);
app.use('/users', userRouter);

app.get('*', (req, res) => {
res.sendStatus(404);
});

app.post('*', (req, res) => {
res.sendStatus(404);
});

app.listen(process.env.EXPRESS_PORT, () => {
debug(`Server is running at port::${process.env.EXPRESS_PORT}`);
});

module.exports = app;
12 changes: 12 additions & 0 deletions mongoDB.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const mongoose = require('mongoose');

const mongooseInit = () => {
mongoose.connect(`mongodb://${process.env.DB_HOST}/${process.env.DB_DATABASE}`, {
user: process.env.DB_USER,
pass: process.env.DB_PASS,
useNewUrlParser: true,
useUnifiedTopology: true,
});
};

module.exports = mongooseInit;
11 changes: 11 additions & 0 deletions mongoDB.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const mongoose = require('mongoose');
const mongooseInit = require('./mongoDB');

describe('mongoDB', () => {
it('Mongo DB Connection', () => {
mongooseInit();
setTimeout(() => {
expect(mongoose.connection.readyState).toEqual(1);
}, 1500);
});
});
Loading

0 comments on commit c0e7e38

Please sign in to comment.