Skip to content

Commit

Permalink
feature-[167573212]: implement login feature
Browse files Browse the repository at this point in the history
- added login route
- tested login route
- created user model, migration and seeds file
- added a findUser helper function
- added a password helper function that compares password

[finishes #167573212]
  • Loading branch information
henryade committed Aug 2, 2019
1 parent c3dd0ed commit fd3a317
Show file tree
Hide file tree
Showing 18 changed files with 340 additions and 13 deletions.
17 changes: 12 additions & 5 deletions package-lock.json

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

77 changes: 77 additions & 0 deletions server/controllers/Session.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import bcrypt from 'bcryptjs';
import {
findUser,
generateToken,
serverResponse,
serverError,
expiryDate
} from '../helpers';
import models from '../database/models';

const { Sessions } = models;
const mobileDeviceIndicator = [
'mobile',
'andriod',
'iphone',
'tablet',
'ipad',
'ipod'
];

/**
*
*
* @class Session
*/
class Session {
/**
*
*
* @static
* @param {object} req - request object
* @param {object} res - response object
* @memberof User
* @returns {json} object
*/
static async create(req, res) {
try {
const { userLogin, password } = req.body;
if (!/\D/.test(userLogin)) {
return serverResponse(res, 400, {
message: 'user login must be a string'
});
}
const user = await findUser(userLogin);
let verifyPassword;
if (user) verifyPassword = bcrypt.compareSync(password, user.password);
if (!user || !verifyPassword) {
return serverResponse(res, 403, {
message: 'incorrect username or password'
});
}
const userAgent = req.headers['user-agent'];
const devicePlatform = mobileDeviceIndicator.some(
device => userAgent.toLowerCase().indexOf(device) > 0
)
? 'mobile'
: 'browser';
const { id, dataValues } = user;
const expiresAt = expiryDate(devicePlatform);
const token = generateToken(id);
await Sessions.create({
userId: id,
token,
expiresAt,
userAgent,
ipAddress: req.ip,
devicePlatform
});
delete dataValues.password;
return serverResponse(res, 200, { user: { ...dataValues }, token });
} catch (error) {
serverError(res);
}
}
}

export default Session;
3 changes: 2 additions & 1 deletion server/database/seeds/20190730180408-my-seed-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export default {
lastName: 'JayZ',
userName: 'JhayX',
email: 'abiola.jz@andela.com',
password: 'incorrect',
password:
'$2y$12$3t1adkk7/grjsz2cG5hlXOTO8LwZUmGeG7zs6udoH78MeoPNmXQ.y',
createdAt: new Date(),
updatedAt: new Date()
}
Expand Down
34 changes: 34 additions & 0 deletions server/docs/authors-haven-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ paths:
description: Conflict. Email or username exists
500:
description: Internal server error
"/api/v1/sessions/create":
summary: Login Route
post:
description: Login Route
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/UserSignUp'
description: user to be created
responses:
201:
description: new user created successfully
409:
description: Conflict. Email or username exists
500:
description: Internal server error

components:
securitySchemes:
Expand Down Expand Up @@ -80,3 +98,19 @@ components:
password:
type: string
example: incorrect
schemas:
loginResponse:
type: object
properties:
user:
type: object
errorResponse:
type: object
properties:
message:
type: string
serverResponse:
type: object
properties:
error:
type: string
14 changes: 14 additions & 0 deletions server/helpers/dateHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* @name expiryDate
* @param {string} platform - platform that apps is accessed from
* @returns {date} date object
*/
const expiryDate = (platform) => {
const todaysDate = new Date(Date.now());
const expirationDate = new Date();
const timeExtension = platform === 'browser' ? 8 : 24;
expirationDate.setHours(todaysDate.getHours() + timeExtension);
return expirationDate;
};

export default { expiryDate };
21 changes: 21 additions & 0 deletions server/helpers/findUser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import models from '../database/models';

const { User } = models;
/**
* @name findUser
* @param {string} parameter - user input
* @returns {object} user object
*/
const findUser = async (parameter) => {
let param;
if (!/\D/.test(parameter)) {
param = { id: parameter };
} else if (/\D/.test(parameter) && /@.{2,15}\./.test(parameter)) {
param = { email: parameter };
} else {
param = { userName: parameter };
}
return User.findOne({ where: param });
};

export default findUser;
6 changes: 6 additions & 0 deletions server/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ import { checkEmail, checkUserName, checkId } from './checkExistingUser';
import findToken from './findToken';
import generateToken from './generateToken';
import { setCustomMessage, validateInputs } from './validationHelper';
import findUser from './findUser';
import dateHelper from './dateHelper';

const { expiryDate } = dateHelper;

export {
findUser,
expiryDate,
serverResponse,
serverError,
checkEmail,
Expand Down
2 changes: 2 additions & 0 deletions server/routes/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import express from 'express';
import users from './user';
import session from './session';

const route = express.Router();

route.use('/users', users);
route.use('/', session);

export default route;
8 changes: 8 additions & 0 deletions server/routes/session.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import express from 'express';
import Session from '../controllers/Session';

const router = express.Router();

router.post('/sessions/create', Session.create);

export default router;
13 changes: 13 additions & 0 deletions test/helpers/dateHelper.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { expect } from 'chai';
import { expiryDate } from '../../server/helpers';

describe('Find User Test', () => {
it('find user by id', async () => {
const date = await expiryDate('browser');
expect(date).to.be.a('date');
});
it('find user by id', async () => {
const date = await expiryDate('mobile');
expect(date).to.be.a('date');
});
});
9 changes: 9 additions & 0 deletions test/helpers/findUser.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { expect } from 'chai';
import { findUser } from '../../server/helpers';

describe('Find User Test', () => {
it('find user by id', async () => {
const user = await findUser(1);
expect(user).to.have.property('dataValues');
});
});
7 changes: 6 additions & 1 deletion test/helpers/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import * as generateToken from './generateToken.test';
import * as findToken from './findToken.test';
import * as sessionMigration from './sessionMigration.test';
import * as findUSer from './findUser.test';
import * as dateHelper from './dateHelper.test';

export { generateToken, findToken };
export {
generateToken, findToken, sessionMigration, findUSer, dateHelper
};
3 changes: 0 additions & 3 deletions test/helpers/index.test.js

This file was deleted.

File renamed without changes.
26 changes: 26 additions & 0 deletions test/users/__mocks__/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const rightUserWithEmail = {
userLogin: 'abiola.jz@andela.com',
password: 'incorrect'
};

const rightUserWithUserName = {
userLogin: 'JhayX',
password: 'incorrect'
};

const userWithId = {
userLogin: 1,
password: 'incorrect'
};

const wrongUser = {
userLogin: 'a54678yujkomnibvr5fgrht6y78umiouh@gmail.com',
password: 'incorrect'
};

export default {
rightUserWithUserName,
rightUserWithEmail,
userWithId,
wrongUser
};
5 changes: 3 additions & 2 deletions test/users/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './signup.test';
import * as signUp from './signup.test';
import * as sessions from './sessions.test';

export default './signup.test';
export { signUp, sessions };
Loading

0 comments on commit fd3a317

Please sign in to comment.