Skip to content

Commit ccaaa60

Browse files
committed
Merge branch 'feature/social-auth' into dev
2 parents 9af2719 + d9de2de commit ccaaa60

File tree

15 files changed

+230
-49
lines changed

15 files changed

+230
-49
lines changed

configs/project/server.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,9 @@ if (process.env.TRAVIS) {
1414
},
1515
mongo: require('./mongo/credential'),
1616
firebase: require('./firebase/credential.json'),
17+
passportStrategy: {
18+
facebook: require('./passportStrategy/facebook/credential'),
19+
linkedin: require('./passportStrategy/linkedin/credential'),
20+
},
1721
};
1822
}

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@
107107
"multer": "^1.1.0",
108108
"object-assign": "^4.1.0",
109109
"passport": "^0.3.2",
110+
"passport-facebook": "^2.1.1",
110111
"passport-jwt": "^2.0.0",
112+
"passport-linkedin-oauth2": "^1.4.1",
111113
"pm2": "^2.0.18",
112114
"react": "^15.3.2",
113115
"react-bootstrap": "^0.30.5",

specs/endToEnd/apis/user.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ describe('#user', () => {
5050
expect(res).to.not.be.undefined;
5151
expect(res.status).to.equal(200);
5252
expect(res.body.errors[0].code)
53-
.to.equal(Errors.ODM_VALIDATION.code);
53+
.to.equal(Errors.USER_EXISTED.code);
5454
done();
5555
});
5656
});

src/common/components/pages/user/LoginPage.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,41 @@
11
import React from 'react';
22
import PageHeader from 'react-bootstrap/lib/PageHeader';
3+
import Grid from 'react-bootstrap/lib/Grid';
4+
import Row from 'react-bootstrap/lib/Row';
5+
import Col from 'react-bootstrap/lib/Col';
36
import PageLayout from '../../layouts/PageLayout';
7+
import Head from '../../widgets/Head';
48
import LoginForm from '../../forms/LoginForm';
59

610
const LoginPage = (props) => (
711
<PageLayout>
12+
<Head
13+
links={[
14+
'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-social/5.0.0/bootstrap-social.min.css',
15+
]}
16+
/>
817
<PageHeader>Login</PageHeader>
9-
<LoginForm location={props.location} />
18+
<Grid>
19+
<Row>
20+
<Col md={9}>
21+
<LoginForm location={props.location} />
22+
</Col>
23+
<Col md={3}>
24+
<a
25+
href="/auth/facebook"
26+
className="btn btn-block btn-social btn-facebook"
27+
>
28+
<span className="fa fa-facebook"></span>Login with Facebook
29+
</a>
30+
<a
31+
href="/auth/linkedin"
32+
className="btn btn-block btn-social btn-linkedin"
33+
>
34+
<span className="fa fa-linkedin"></span>Login with LinkedIn
35+
</a>
36+
</Col>
37+
</Row>
38+
</Grid>
1039
</PageLayout>
1140
);
1241

src/common/constants/ErrorCodes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export default {
33
ODM_OPERATION_FAIL: 'ODM_OPERATION_FAIL',
44
STATE_PRE_FETCHING_FAIL: 'STATE_PRE_FETCHING_FAIL',
55
USER_UNAUTHORIZED: 'USER_UNAUTHORIZED',
6+
USER_EXISTED: 'USER_EXISTED',
67
PERMISSION_DENIED: 'PERMISSION_DENIED',
78
LOCALE_NOT_SUPPORTED: 'LOCALE_NOT_SUPPORTED',
89
USER_TOKEN_EXPIRATION: 'USER_TOKEN_EXPIRATION',

src/common/constants/Errors.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ export default {
3131
title: 'User Unauthorized',
3232
detail: 'Please login to access the resource.',
3333
},
34+
[ErrorCodes.USER_EXISTED]: {
35+
code: ErrorCodes.USER_EXISTED,
36+
status: 400,
37+
title: 'User Existed',
38+
detail: 'This user is already registered.',
39+
},
3440
[ErrorCodes.PERMISSION_DENIED]: {
3541
code: ErrorCodes.PERMISSION_DENIED,
3642
status: 403,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import passport from 'passport';
2+
3+
export default {
4+
initFacebook: passport.authenticate('facebook', {
5+
scope: ['public_profile', 'email'],
6+
}),
7+
initLinkedin: passport.authenticate('linkedin', {
8+
state: Math.random(),
9+
}),
10+
};

src/server/controllers/user.js

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import Errors from '../../common/constants/Errors';
12
import { handleDbError } from '../decorators/handleError';
23
import User from '../models/User';
34
import filterAttribute from '../utils/filterAttribute';
5+
import { loginUser } from '../../common/actions/userActions';
46

57
export default {
68
list(req, res) {
@@ -20,17 +22,25 @@ export default {
2022
},
2123

2224
create(req, res) {
23-
const user = User({
24-
name: req.body.name,
25-
email: {
26-
value: req.body.email,
27-
},
28-
password: req.body.password,
29-
});
30-
user.save(handleDbError(res)((user) => {
31-
res.json({
32-
user: user,
33-
});
25+
User.findOne({
26+
'email.value': req.body.email,
27+
}, handleDbError(res)((user) => {
28+
if (user) {
29+
res.errors([Errors.USER_EXISTED]);
30+
} else {
31+
const user = User({
32+
name: req.body.name,
33+
email: {
34+
value: req.body.email,
35+
},
36+
password: req.body.password,
37+
});
38+
user.save(handleDbError(res)((user) => {
39+
res.json({
40+
user: user,
41+
});
42+
}));
43+
}
3444
}));
3545
},
3646

@@ -61,6 +71,26 @@ export default {
6171
}));
6272
},
6373

74+
socialLogin(req, res, next) {
75+
let { user } = req;
76+
let token = user.toJwtToken();
77+
78+
user.save(handleDbError(res)(() => {
79+
req.store
80+
.dispatch(loginUser({
81+
token: token,
82+
data: user,
83+
}))
84+
.then(() => {
85+
let { token, user } = req.store.getState().cookies;
86+
87+
res.cookie('token', token);
88+
res.cookie('user', user);
89+
res.redirect('/');
90+
});
91+
}));
92+
},
93+
6494
logout(req, res) {
6595
req.logout();
6696
res.json({});

src/server/middlewares/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import path from 'path';
33
import express from 'express';
44
import favicon from 'serve-favicon';
55
import morgan from './morgan';
6-
import passport from './passport';
6+
import passportInit from './passportInit';
77
import mountStore from './mountStore';
88
import mountHelper from './mountHelper';
99
import initCookie from './initCookie';
@@ -44,5 +44,5 @@ export default ({ app }) => {
4444
app.use(initCookie);
4545

4646
// setup passport
47-
app.use(passport);
47+
app.use(passportInit);
4848
};

src/server/middlewares/passport.js

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)