Skip to content

Commit

Permalink
Merge be2be9d into b6a5be6
Browse files Browse the repository at this point in the history
  • Loading branch information
truestbyheart committed Jun 26, 2019
2 parents b6a5be6 + be2be9d commit d708cec
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 14 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
"passport-twitter": "^1.0.4",
"sinon": "^7.3.2",
"sinon-chai": "^3.3.0",
"joi": "^14.3.1",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.11",
"morgan": "^1.9.1",
Expand Down
9 changes: 9 additions & 0 deletions src/api/controllers/authController.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import status from '../../helpers/constants/status.codes';
import env from '../../configs/environments';
import sendError from '../../helpers/error.sender';
import errors from '../../helpers/constants/error.messages';
import mailer from '../../helpers/Mailer/index';

const { User } = models;
/**
Expand Down Expand Up @@ -34,6 +35,14 @@ export default class Auth {
email,
password: hashedPassword
});
await mailer('Please verify your email', 'Email verification', email, 'notifications', {
email,
buttonText: 'Verify',
userName: username,
message: "Please click on the link to verify your email for authors haven.If you didn't request this, simply ignore this e-mail.",
link: `${env.baseUrl}/users/verifyEmail`

});
const tokenData = { id: user.dataValues.id, username, email };
const token = generateToken(tokenData, env.secret);
return sendResult(res, status.CREATED, 'user created successfully', user, token);
Expand Down
38 changes: 38 additions & 0 deletions src/api/controllers/verifyEmail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import decodejwt from '../../helpers/tokens/decode.token';
import status from '../../helpers/constants/status.codes';
import models from '../models/index';
import error from '../../helpers/error.sender';
import errorMessages from '../../helpers/constants/error.messages';
/**
* @class
*/
export default class {
/**
* @description verification link controller
* @param {*} req
* @param {*} res
* @returns {*} void
*/
static async verifyEmail(req, res) {
const { token } = req.params;
const result = decodejwt(token);
if (result !== undefined) {
const action = await models.User.update({ verified: true }, {
where: {
email: result.user.email,
}
});
const ZERO = 0;
if (!action.includes(ZERO)) {
res.status(status.OK).json({
status: 200,
message: 'Your email is successfully verified'
});
} else {
error(status.NOT_FOUND, res, 'user', errorMessages.noUser);
}
} else {
error(status.BAD_REQUEST, res, 'link', errorMessages.emailLinkInvalid);
}
}
}
2 changes: 2 additions & 0 deletions src/api/routes/authRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import validateToken from '../../middlewares/checkValidToken';
import socialAuthController from '../controllers/socialAuth';
import passport from '../../configs/passport';
import social from '../../middlewares/social/social';
import EmailVerifier from '../controllers/verifyEmail';

const authRouter = new Router();

Expand All @@ -31,5 +32,6 @@ authRouter.get('/twitter', passport.authenticate('twitter', { scope: ['email', '
authRouter.get('/twitter/callback',
passport.authenticate('twitter'),
socialAuthController.twitterAuth);
authRouter.get('/verifyEmail/:token', EmailVerifier.verifyEmail);

export default authRouter;
75 changes: 63 additions & 12 deletions src/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "Authors Heaven",
"description": "Authors Heaven Appi Documentation",
"title": "usersors Heaven",
"description": "usersors Heaven Appi Documentation",
"license": {
"name": "MIT",
"url": "https://opensource.org/licenses/MIT"
Expand Down Expand Up @@ -295,19 +295,70 @@
}
}
},
"resetPassword": {
"type": "object",
"properties": {
"email": {
"type": "string"
"/users/verifyEmail": {
"get": {
"tags": ["Users"],
"summary": "Verify user's email",
"description": "",
"produces": ["application/json"],
"consumes": ["application/json"],
"parameters": [
{
"in": "path",
"name": "token",
"description": "",
"required": true
}
],
"responses": {
"200": {
"description": "Your email is successfully verified"
},
"400": {
"description": "The link provided is corrupt, please request a new one or try to click it again"
},
"404": {
"description": "User doesn't exist."
},
"default": {
"description": "Something went wrong"
}
}
}
},
"updatePassword": {
"type": "object",
"properties": {
"email": {
"type": "string"
"externalDocs": {
"description": "Find out more about Swagger",
"url": "http://swagger.io"
},
"definitions": {
"signup": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"email": {
"type": "string"
},
"password": {
"type": "string"
}
}
},
"resetPassword": {
"type": "object",
"properties": {
"email": {
"type": "string"
}
}
},
"updatePassword": {
"type": "object",
"properties": {
"email": {
"type": "string"
}
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/helpers/constants/error.messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ export default {
emptyBody: 'Server unable to process the recieved data',
unkownEmail: "A user with the provided email doesn't exist",
invalidLink: 'Invalid link provided',
incorectPassword: 'Incorect password provided'
incorectPassword: 'Incorect password provided',
emailLinkInvalid: 'The link provided is corrupt, please request a new one or try to click it again',
noUser: "User doesn't exist."
};
90 changes: 90 additions & 0 deletions tests/verify.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import chai from 'chai';
import chaihttp from 'chai-http';
import createToken from '../src/helpers/tokens/generate.token';
import env from '../src/configs/environments';
import server from '../src/index';
import status from '../src/helpers/constants/status.codes';
import errorMessages from '../src/helpers/constants/error.messages';


chai.use(chaihttp);
chai.should();


describe('GET /verifyEmail', () => {
it('Should return a success message if the link is valid', (done) => {
const user = {
username: 'BurindiAlain',
email: 'alain@gmail.com',
password: 'password23423',
confirmPassword: 'password23423'
};

const { username, email } = user;

const verifytoken = createToken({ username, email }, env.secret);
chai
.request(server)
.get(`/api/users/verifyEmail/${verifytoken}`)
.end(async (err, res) => {
await res.should.have.status(status.OK);
await res.body.message.should.be.eq('Your email is successfully verified');
done();
});
});

it('Should return a message if a user doesn\'t exist', (done) => {
const user = {
username: 'BurindiAlain',
email: 'alain@gmail.com',
password: 'password23423',
confirmPassword: 'password23423'
};
chai
.request(server)
.post('/api/users/signup')
.send(user)
.end();

const { username } = user;

const verifytoken = createToken({ username, email: 'dummy@email.com' }, env.secret);

chai
.request(server)
.get(`/api/users/verifyEmail/${verifytoken}`)
.end((err, res) => {
res.should.have.status(status.NOT_FOUND);
res.body.errors.user.should.be.eq(errorMessages.noUser);
done();
});
});

it('Should respond with a message if the token is invalid', (done) => {
const user = {
username: 'BurindiAlain',
email: 'alain@gmail.com',
password: 'password23423',
confirmPassword: 'password23423'
};

chai
.request(server)
.post('/api/users/signup')
.send(user)
.end();

const { username } = user;

const verifytoken = createToken({ username }, 'env.secret');

chai
.request(server)
.get(`/api/users/verifyEmail/${verifytoken}`)
.end((err, res) => {
res.should.have.status(status.BAD_REQUEST);
res.body.errors.link.should.be.eq(errorMessages.emailLinkInvalid);
done();
});
});
});

0 comments on commit d708cec

Please sign in to comment.