Skip to content

Commit f9cede6

Browse files
committed
Added resend account confirmation otp functionality.
1 parent abed53d commit f9cede6

File tree

4 files changed

+160
-26
lines changed

4 files changed

+160
-26
lines changed

controllers/AuthController.js

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const { body,validationResult } = require("express-validator");
33
const { sanitizeBody } = require("express-validator");
44
//helper file to prepare responses.
55
const apiResponse = require("../helpers/apiResponse");
6+
const utility = require("../helpers/utility");
67
const bcrypt = require("bcrypt");
78
const jwt = require("jsonwebtoken");
89
const mailer = require("../helpers/mailer");
@@ -50,7 +51,7 @@ exports.register = [
5051
//hash input password
5152
bcrypt.hash(req.body.password,10,function(err, hash) {
5253
// generate OTP for confirmation
53-
let otp = randomNumber(4);
54+
let otp = utility.randomNumber(4);
5455
// Create User object with escaped and trimmed data
5556
var user = new UserModel(
5657
{
@@ -157,23 +158,6 @@ exports.login = [
157158
}
158159
}];
159160

160-
/**
161-
* OTP generator.
162-
*
163-
* @param {intiger} length
164-
*
165-
* @returns {Interger}
166-
*/
167-
function randomNumber(length) {
168-
var text = "";
169-
var possible = "123456789";
170-
for (var i = 0; i < length; i++) {
171-
var sup = Math.floor(Math.random() * possible.length);
172-
text += i > 0 && sup == i ? "0" : possible.charAt(sup);
173-
}
174-
return Number(text);
175-
}
176-
177161
/**
178162
* Verify Confirm otp.
179163
*
@@ -197,14 +181,18 @@ exports.verifyConfirm = [
197181
var query = {email : req.body.email};
198182
UserModel.findOne(query).then(user => {
199183
if (user) {
200-
//Compare given password with db's hash.
201-
if(user.isConfirmed){
184+
//Check already confirm or not.
185+
if(!user.isConfirmed){
202186
//Check account confirmation.
203187
if(user.confirmOTP == req.body.otp){
204-
UserModel.findOneAndUpdate(query, {
205-
name: 'jason bourne'
206-
}, options, callback)
207-
return apiResponse.successResponseWithData(res,"Login Success.", userData);
188+
//Update user as confirmed
189+
UserModel.findOneAndUpdate(query, {
190+
isConfirmed: 1,
191+
confirmOTP: null
192+
}).catch(err => {
193+
return apiResponse.ErrorResponse(res, err);
194+
});
195+
return apiResponse.successResponse(res,"Account confirmed success.");
208196
}else{
209197
return apiResponse.unauthorizedResponse(res, "Otp does not match");
210198
}
@@ -220,3 +208,57 @@ exports.verifyConfirm = [
220208
return apiResponse.ErrorResponse(res, err);
221209
}
222210
}];
211+
212+
/**
213+
* Resend Confirm otp.
214+
*
215+
* @param {string} email
216+
*
217+
* @returns {Object}
218+
*/
219+
exports.resendConfirmOtp = [
220+
body("email").isLength({ min: 1 }).trim().withMessage("Email must be specified.")
221+
.isEmail().withMessage("Email must be a valid email address."),
222+
sanitizeBody("email").escape(),
223+
(req, res, next) => {
224+
try {
225+
const errors = validationResult(req);
226+
if (!errors.isEmpty()) {
227+
return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array());
228+
}else {
229+
var query = {email : req.body.email};
230+
UserModel.findOne(query).then(user => {
231+
if (user) {
232+
//Check already confirm or not.
233+
if(!user.isConfirmed){
234+
// Generate otp
235+
let otp = utility.randomNumber(4);
236+
// Html email body
237+
let html = '<p>Please Confirm your Account.</p><p>OTP: '+otp+'</p>';
238+
// Send confirmation email
239+
mailer.send(
240+
constants.confirmEmails.from,
241+
req.body.email,
242+
'Confirm Account',
243+
html
244+
).then(function(response){
245+
user.isConfirmed = 0;
246+
user.confirmOTP = otp;
247+
// Save user.
248+
user.save(function (err) {
249+
if (err) { return apiResponse.ErrorResponse(res, err); }
250+
return apiResponse.successResponse(res,"Confirm otp sent.");
251+
});
252+
});
253+
}else{
254+
return apiResponse.unauthorizedResponse(res, "Account already confirmed.");
255+
}
256+
}else{
257+
return apiResponse.unauthorizedResponse(res, "Specified email not found.");
258+
}
259+
});
260+
}
261+
} catch (err) {
262+
return apiResponse.ErrorResponse(res, err);
263+
}
264+
}];

helpers/utility.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
exports.randomNumber = function (length) {
2+
var text = "";
3+
var possible = "123456789";
4+
for (var i = 0; i < length; i++) {
5+
var sup = Math.floor(Math.random() * possible.length);
6+
text += i > 0 && sup == i ? "0" : possible.charAt(sup);
7+
}
8+
return Number(text);
9+
}

postman-collection/REST API NodeJS.postman_collection.json

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"info": {
3-
"_postman_id": "2dc87226-1700-456c-8c91-134be87d7283",
3+
"_postman_id": "b59237a7-b99e-401e-b0c6-39203c202949",
44
"name": "REST API NodeJS",
55
"description": "A boilerplate for REST API Development with Node.js and Expressjs",
66
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
@@ -47,7 +47,7 @@
4747
]
4848
},
4949
"url": {
50-
"raw": "http://localhost:3000/api/auth/register",
50+
"raw": "http://localhost:3000/api/auth/register?=",
5151
"protocol": "http",
5252
"host": [
5353
"localhost"
@@ -110,6 +110,87 @@
110110
}
111111
},
112112
"response": []
113+
},
114+
{
115+
"name": "Verify Confirm OTP",
116+
"request": {
117+
"method": "POST",
118+
"header": [
119+
{
120+
"key": "Content-Type",
121+
"name": "Content-Type",
122+
"value": "application/x-www-form-urlencoded",
123+
"type": "text"
124+
}
125+
],
126+
"body": {
127+
"mode": "urlencoded",
128+
"urlencoded": [
129+
{
130+
"key": "email",
131+
"value": "[email protected]",
132+
"type": "text"
133+
},
134+
{
135+
"key": "otp",
136+
"value": "6442",
137+
"type": "text"
138+
}
139+
]
140+
},
141+
"url": {
142+
"raw": "http://localhost:3000/api/auth/verify-otp",
143+
"protocol": "http",
144+
"host": [
145+
"localhost"
146+
],
147+
"port": "3000",
148+
"path": [
149+
"api",
150+
"auth",
151+
"verify-otp"
152+
]
153+
}
154+
},
155+
"response": []
156+
},
157+
{
158+
"name": "Resend Confirm OTP",
159+
"request": {
160+
"method": "POST",
161+
"header": [
162+
{
163+
"key": "Content-Type",
164+
"name": "Content-Type",
165+
"value": "application/x-www-form-urlencoded",
166+
"type": "text"
167+
}
168+
],
169+
"body": {
170+
"mode": "urlencoded",
171+
"urlencoded": [
172+
{
173+
"key": "email",
174+
"value": "[email protected]",
175+
"type": "text"
176+
}
177+
]
178+
},
179+
"url": {
180+
"raw": "http://localhost:3000/api/auth/resend-verify-otp",
181+
"protocol": "http",
182+
"host": [
183+
"localhost"
184+
],
185+
"port": "3000",
186+
"path": [
187+
"api",
188+
"auth",
189+
"resend-verify-otp"
190+
]
191+
}
192+
},
193+
"response": []
113194
}
114195
]
115196
},

routes/auth.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ var router = express.Router();
55

66
router.post("/register", AuthController.register);
77
router.post("/login", AuthController.login);
8+
router.post("/verify-otp", AuthController.verifyConfirm);
9+
router.post("/resend-verify-otp", AuthController.resendConfirmOtp);
810

911
module.exports = router;

0 commit comments

Comments
 (0)