Skip to content

Commit 0308251

Browse files
author
gondzo
committed
Merge branch 'improveLogin' into dev
2 parents cd5a951 + 5f2f295 commit 0308251

File tree

9 files changed

+85
-30
lines changed

9 files changed

+85
-30
lines changed

README.md

+32-2
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,45 @@ DRONE SERIES - WEBAPI IMPLEMENT PRODUCER API
1414
3. To create random test data run `npm run testdata`
1515
4. run server `npm start`
1616

17+
## Configuration
18+
19+
Configuration files are located under `config` dir.
20+
See https://github.com/lorenwest/node-config/wiki/Configuration-Files
21+
22+
|Name|Description|
23+
|----|-----------|
24+
|`LOG_LEVEL`| The logging level for the api's|
25+
|`PORT`| The port to listen|
26+
|`AUTH0_CLIENT_ID`| The auth0 client id |
27+
|`JWT_SECRET`| The jwt secret |
28+
|`mail.SMTP_HOST`| The smtp hostname |
29+
|`mail.SMTP_PORT`| The smtp port |
30+
|`mail.SMTP_USERNAME`| The smtp username |
31+
|`mail.SMTP_PASSWORD`| The smtp password |
32+
33+
## Mail service configuration
34+
35+
[mailgun](https://mailgun.com) is used as mail service.
36+
37+
- Create an account on mailgun.
38+
- By default a sandbox domain is created. Click on sandbox domain and copy the `Default SMTP Login`
39+
and `Default Password` and set them as environment variables.
40+
export SMTP_USERNAME=<copied from mailgun sandbox domain>
41+
export SMTP_PASSWORD=<copied from mailgun sandbox domain>
42+
- The host and port are configured for mailgun.
43+
44+
45+
When we create an account on mailgun, by default only sandbox domain is enabled.
46+
To successfully send email from this sandbox domain you have to add the user to authorized recipients list.
1747

1848
#test
19-
1. open postman
49+
1. open postman
2050
2. import `test/Provider-dsp.postman_collection` , `test/Provider-dsp-env.postman_environment.json`.
2151
3. test data create 6 provider with user , use username `provider1` - `provder6`, password `123456` login , when login success ,the token will be injected to postman env.
2252
4. test other api endpoints.
2353

2454
# test nfx
25-
import `test/NFZ.postman_collection.json`
55+
import `test/NFZ.postman_collection.json`
2656
it contains only endpoints for No Fly Zone endpoints
2757

2858
# env

common/Auth.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ const jwt = require('express-jwt');
1414
const config = require('config');
1515

1616
const jwtCheck = jwt({
17-
secret: new Buffer(config.JWT_SECRET, 'base64'),
17+
// the auth0 doesn't base 64 encode the jwt secret now
18+
secret: config.JWT_SECRET,
1819
audience: config.AUTH0_CLIENT_ID,
1920
requestProperty: 'auth',
2021
getToken: function fromHeaderOrQuerystring(req) {

config/default.js

+14-5
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,27 @@ module.exports = {
1414

1515
LOG_LEVEL: process.env.LOG_LEVEL || 'debug',
1616
PORT: process.env.PORT || 3500,
17-
AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID || 'nope',
17+
AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID || 'h7p6V93Shau3SSvqGrl6V4xrATlkrVGm',
1818
JWT_SECRET: process.env.JWT_SECRET || 'JWT_SECRET',
1919
SALT_WORK_FACTOR: 2,
2020
TOKEN_EXPIRES: 10 * 60 * 60,
2121
API_VERSION: 1,
2222
RESET_CODE_EXPIRES: 60 * 60,
23-
24-
2523
db: {
2624
url: process.env.MONGOLAB_URI || 'mongodb://localhost:27017/drones',
2725
poolSize: 5,
2826
},
29-
30-
27+
mail: {
28+
SMTP_HOST: 'smtp.mailgun.org',
29+
SMTP_PORT: 587,
30+
FROM_EMAIL: '[email protected]',
31+
SMTP_USERNAME: process.env.SMTP_USERNAME,
32+
SMTP_PASSWORD: process.env.SMTP_PASSWORD,
33+
},
34+
RESET_PASSWORD_SUBJECT: 'Reset your password',
35+
RESET_PASSWORD_TEMPLATE: 'You received this email because you send a reset password request to us, ' +
36+
'if you never registered, please ignore. ' +
37+
'To reset your password <a href=":link">click here</a><br><br> -- Dsp Server Team',
38+
// this is a frontend url, the user is redirected to this url from user's mailbox
39+
RESET_PASSWORD_LINK: 'http://localhost:3000/reset-password?token=:token',
3140
};

controllers/UserController.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function* register(req, res) {
5050
* @param res the response
5151
*/
5252
function* registerSocialUser(req, res) {
53-
res.json(yield UserService.registerSocialUser(req.body));
53+
res.json(yield UserService.registerSocialUser(req.auth, req.body));
5454
}
5555

5656
/**

enum.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
* Contains app enums and constants
88
*/
99
const SocialType = {
10-
GOOGLE: 'Google',
11-
FACEBOOK: 'Facebook',
10+
GOOGLE: 'google-oauth2',
11+
FACEBOOK: 'facebook',
1212
};
1313

1414
const DroneStatus = {

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"mongoose-auto-increment": "^5.0.1",
3838
"mongoose-timestamp": "^0.6.0",
3939
"nodemailer": "^2.6.4",
40+
"nodemailer-smtp-transport": "^2.7.2",
4041
"socket.io": "^1.5.1",
4142
"swagger-ui-express": "^1.0.2",
4243
"winston": "^2.2.0"

routes.js

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ module.exports = {
2929
'/login/social': {
3030
post: {
3131
controller: 'UserController',
32+
middleware: [auth()],
3233
method: 'registerSocialUser',
3334
},
3435
},

services/MailService.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,25 @@
1212

1313
const nodemailer = require('nodemailer');
1414
const logger = require('../common/logger');
15+
const smtpTransport = require('nodemailer-smtp-transport');
16+
const config = require('config');
1517

1618
// create reusable transporter object using the default SMTP transport
1719
const transporter = nodemailer.createTransport({
18-
service: 'qq',
19-
port: 465,
20-
host: 'smtp.qq.com',
21-
secureConnection: true,
20+
port: config.mail.SMTP_PORT,
21+
host: config.mail.SMTP_HOST,
2222
auth: {
23-
24-
pass: 'vafsjkvrnyakbjfh',
23+
user: config.mail.SMTP_USERNAME,
24+
pass: config.mail.SMTP_PASSWORD,
2525
},
2626
});
2727

28-
function* sendMessage(mailTo, html, text) {
28+
function* sendMessage(mailTo, html, text, subject) {
2929
// setup e-mail data with unicode symbols
3030
const mailOptions = {
31-
from: '"do not reply" <[email protected]>', // sender address
31+
from: config.mail.FROM_EMAIL, // sender address
3232
to: mailTo, // list of receivers
33-
subject: 'Reset your password please', // Subject line
33+
subject, // Subject line
3434
text, // plaintext body
3535
html, // html body
3636
};

services/UserService.js

+23-10
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ register.schema = {
7676

7777
// the joi schema for register user via social login
7878
registerSocialUser.schema = {
79+
auth: joi.object().required(),
7980
entity: joi.object().keys({
8081
name: joi.string().required(),
8182
email: joi.string().email().required(),
@@ -125,16 +126,22 @@ function* register(entity) {
125126
/**
126127
* Register a user via social login
127128
*
129+
* @param {Object} auth the currently logged in user context
128130
* @param {Object} entity the post entity from the client
129131
*/
130-
function* registerSocialUser(entity) {
132+
function* registerSocialUser(auth, entity) {
131133
// make sure the email is unique
132-
const existingUser = yield User.findOne({email: entity.email});
133-
134+
// we don't need to check here for social network type, as social network id itself
135+
// embed the social network type
136+
const existingUser = yield User.findOne({ $or: [{email: entity.email}, {socialNetworkId: auth.sub}] });
134137
let user;
135138
if (existingUser) {
136-
user = existingUser;
139+
// update social network type
140+
existingUser.socialNetworkType = auth.sub.substring(0, auth.sub.indexOf('|'));
141+
user = yield existingUser.save();
137142
} else {
143+
entity.socialNetworkId = auth.sub;
144+
entity.socialNetworkType = auth.sub.substring(0, auth.sub.indexOf('|'));
138145
entity.role = Role.CONSUMER;
139146
user = yield User.create(entity);
140147
}
@@ -211,24 +218,26 @@ forgotPassword.schema = {
211218
*/
212219
function* forgotPassword(entity) {
213220
const code = Math.floor(Math.random() * 100000).toString(16);
214-
// print out code for debug purpose
215-
logger.debug(`reset password code is ${code}`);
216-
const text = 'You received this email because you send a reset password request to us, ' +
217-
'if you never registered, please ignore. ' +
218-
`The verify code is ${code}\n -- example.com`;
221+
const subject = config.RESET_PASSWORD_SUBJECT;
222+
const link = config.RESET_PASSWORD_LINK.replace(':token', code);
223+
const text = config.RESET_PASSWORD_TEMPLATE.replace(':link', link);
219224
const html = `<p>${text}</p>`;
220225

221226
const user = yield User.findOne({email: entity.email});
222227
if (!user) {
223228
throw new errors.NotFoundError('user not found with the specified email');
224229
}
230+
// check if the user is social network user, and if yes than don't allow forgot password
231+
if (user.socialNetworkId) {
232+
throw new errors.ValidationError('social network user cannot reset password', httpStatus.BAD_REQUEST);
233+
}
225234

226235
user.resetPasswordCode = code;
227236
const date = new Date();
228237
user.resetPasswordExpiration = date.setSeconds(date.getSeconds() + config.RESET_CODE_EXPIRES);
229238
yield user.save();
230239

231-
yield MailService.sendMessage(user.email, html, text);
240+
yield MailService.sendMessage(user.email, html, text, subject);
232241
}
233242

234243
// the joi schema for resetPassword
@@ -254,6 +263,10 @@ function* resetPassword(entity) {
254263
user.resetPasswordExpiration.getTime() - new Date().getTime() < 0) {
255264
throw new errors.HttpStatusError(400, 'invalid code');
256265
}
266+
// check if the user is social network user, and if yes than don't allow forgot password
267+
if (user.socialNetworkId) {
268+
throw new errors.ValidationError('social network user cannot reset password', httpStatus.BAD_REQUEST);
269+
}
257270

258271
user.password = yield helper.hashString(entity.password, config.SALT_WORK_FACTOR);
259272
user.resetPasswordCode = null;

0 commit comments

Comments
 (0)