Skip to content

Commit d08e263

Browse files
author
Gustavo Marin
committed
Merge pull request #9 from IGZgustavomarin/feature/email-available
Added public endpoint to check email availability.
2 parents c59293d + ee430d2 commit d08e263

File tree

4 files changed

+149
-3
lines changed

4 files changed

+149
-3
lines changed

src/cipherlayer.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ function startListener(publicPort, internalPort, cbk){
102102
"/auth/google",
103103
"/auth/google/*",
104104
"/user/activate*",
105-
"/heartbeat"
105+
"/heartbeat",
106+
"/user/email/available"
106107
];
107108
publicServer.use(versionControl(versionControlOptions));
108109

src/managers/dao.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ var escapeRegexp = require('escape-regexp');
66
var config = require(process.cwd() + '/config.json');
77
var mongoClient = require('mongodb').MongoClient;
88
var ObjectID = require('mongodb').ObjectID;
9+
var _ = require('lodash');
910

1011
var ERROR_USER_NOT_FOUND = 'user_not_found';
1112
var ERROR_USERNAME_ALREADY_EXISTS = 'username_already_exists';
@@ -117,6 +118,28 @@ function countUsers(cbk){
117118
});
118119
}
119120

121+
function findByEmail(email, callback) {
122+
123+
var targetEmail = new RegExp("^"+escapeRegexp(email.toLowerCase())+"$", "i");
124+
125+
126+
usersCollection.find({username: targetEmail}, {password: 0}).toArray(function(error, foundUsers) {
127+
128+
if (error) {
129+
return callback({statusCode: 500, body: {
130+
err: 'InternalError',
131+
des: 'User lookup failed'
132+
}});
133+
}
134+
135+
if (_.isEmpty(foundUsers)) {
136+
return callback(null, {available: true});
137+
}
138+
139+
return callback(null, {available: false});
140+
});
141+
}
142+
120143
function getFromUsername(username, cbk){
121144
if(!username){
122145
return cbk({err:'invalid_username'}, null);
@@ -346,6 +369,6 @@ module.exports = {
346369
getRealms: getRealms,
347370
resetRealmsVariables: resetRealmsVariables,
348371
deleteAllRealms: deleteAllRealms,
349-
372+
findByEmail:findByEmail,
350373
getStatus: getStatus
351374
};

src/public_routes/user.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ var checkAccessTokenParam = require('../middlewares/accessTokenParam.js');
1313
var checkAuthHeader = require('../middlewares/authHeader.js');
1414
var decodeToken = require('../middlewares/decodeToken.js');
1515
var findUser = require('../middlewares/findUser.js');
16+
var _ = require('lodash');
17+
var log = require('../logger/service.js');
1618

1719
function sendNewPassword(req, res, next) {
1820
if (!req.params.email) {
@@ -272,13 +274,36 @@ function setPassword(req, res, next) {
272274
});
273275
}
274276

277+
function checkEmailAvailable(req, res, next) {
278+
var email = req.body.email;
279+
280+
if (_.isEmpty(email)) {
281+
res.send(400, {
282+
err: 'BadRequestError',
283+
des: 'Missing email in request body'
284+
});
285+
return next();
286+
}
287+
288+
289+
daoMng.findByEmail(email, function(error, output) {
290+
if (error) {
291+
res.send(error.statusCode, error.body);
292+
return next();
293+
}
294+
295+
res.send(200, output);
296+
return next();
297+
});
298+
}
299+
275300
function addRoutes(service) {
276301
service.get('/user/:email/password', sendNewPassword);
277302

278303
service.post(config.passThroughEndpoint.path, createUserEndpoint);
279304
service.get('/user/activate', createUserByToken);
280305
service.post('/user/activate', createUserByToken);
281-
306+
service.post('/user/email/available', checkEmailAvailable);
282307
service.put('/user/me/password', checkAccessTokenParam, checkAuthHeader, decodeToken, checkBody, findUser, validateOldPassword, setPassword);
283308
}
284309

tests/emailAvailable.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
var assert = require('assert');
2+
var request = require('request');
3+
4+
var cipherlayer = require('../src/cipherlayer');
5+
var config = require('../config.json');
6+
var userDao = require('../src/managers/dao');
7+
8+
var baseUser = {
9+
id: 'a1b2c3d4e5f6',
10+
username: 'user@example.com',
11+
password: 'pass1'
12+
};
13+
14+
describe('Check Email Available endpoint', function() {
15+
16+
beforeEach(function(done) {
17+
cipherlayer.start(config.public_port, config.internal_port, function(error) {
18+
assert.equal(error, null);
19+
userDao.deleteAllUsers(function(error) {
20+
assert.equal(error, null);
21+
return done();
22+
});
23+
});
24+
});
25+
26+
afterEach(function(done) {
27+
cipherlayer.stop(done);
28+
});
29+
30+
it('should indicate that requested email is available', function(done) {
31+
32+
var requestOptions = {
33+
url: 'http://localhost:' + config.public_port + '/user/email/available',
34+
headers: {
35+
'Content-Type': 'application/json; charset=utf-8'
36+
},
37+
method: 'POST',
38+
json: true,
39+
body: {
40+
email: baseUser.username
41+
}
42+
};
43+
44+
request(requestOptions, function(err, res, body) {
45+
assert.equal(err, null);
46+
assert.equal(res.statusCode, 200);
47+
assert.equal(body.available, true);
48+
return done();
49+
});
50+
});
51+
52+
it('should indicate that requested email is unavailable', function(done) {
53+
var requestOptions = {
54+
url: 'http://localhost:' + config.public_port + '/user/email/available',
55+
headers: {
56+
'Content-Type': 'application/json; charset=utf-8'
57+
},
58+
method: 'POST',
59+
json: true,
60+
body: {
61+
email: baseUser.username
62+
}
63+
};
64+
65+
userDao.addUser()(baseUser, function(error) {
66+
67+
assert.equal(error, null);
68+
69+
request(requestOptions, function(err, res, body) {
70+
assert.equal(err, null);
71+
assert.equal(res.statusCode, 200);
72+
assert.equal(body.available, false);
73+
return done();
74+
});
75+
});
76+
});
77+
78+
it('should return a BadRequestError on missing email component', function(done) {
79+
var requestOptions = {
80+
url: 'http://localhost:' + config.public_port + '/user/email/available',
81+
headers: {
82+
'Content-Type': 'application/json; charset=utf-8'
83+
},
84+
method: 'POST',
85+
json: true,
86+
body: {}
87+
};
88+
89+
request(requestOptions, function(err, res) {
90+
assert.equal(err, null);
91+
assert.equal(res.statusCode, 400);
92+
assert.equal(res.body.err, 'BadRequestError');
93+
assert.equal(res.body.des, 'Missing email in request body');
94+
return done();
95+
});
96+
});
97+
});

0 commit comments

Comments
 (0)