Skip to content

Commit

Permalink
feat(social): social login
Browse files Browse the repository at this point in the history
- Users should be able to login using Google, Facebook, Twitter
[Maintains #164798166]
  • Loading branch information
Daniel Lwetabe authored and Daniel Lwetabe committed May 14, 2019
1 parent b74be53 commit 4c3031e
Show file tree
Hide file tree
Showing 26 changed files with 410 additions and 13 deletions.
7 changes: 7 additions & 0 deletions .env-sample
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
baseURL=
appId=
redirectUri=
googleSocialUrl=
ClientId=
ClientSecret=
AppUrl=
AppId=
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: node_js

node_js:
- "stable"
- "9"

cache:
directories:
Expand Down
51 changes: 51 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Authors Haven Project Front End",
"main": "index.js",
"scripts": {
"start:dev": "webpack-dev-server --mode development --open --hot",
"start:dev": "webpack-dev-server --mode development --open --hot --https",
"start": "node server.js",
"build": "webpack --mode production",
"lint": "eslint src --fix",
Expand Down Expand Up @@ -34,16 +34,20 @@
"express": "^4.16.4",
"file-loader": "^3.0.1",
"moment": "^2.24.0",
"moxios": "^0.4.0",
"node-sass": "^4.12.0",
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-facebook-login": "^4.1.1",
"react-google-login": "^5.0.4",
"prop-types": "^15.7.2",
"react-notify-toast": "^0.5.0",
"react-redux": "^7.0.3",
"react-router-dom": "^5.0.0",
"react-toolbox": "^2.0.0-beta.13",
"redux": "^4.0.1",
"redux-devtools-extension": "^2.13.8",
"redux-mock-store": "^1.5.3",
"redux-thunk": "^2.3.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1"
Expand Down
26 changes: 26 additions & 0 deletions src/actions/facebookActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import axios from 'axios';
import {
IS_AUTHENTICATING_WITH_FB_STARTED,
FB_AUTH_DONE_SUCCESS,
} from './types';
import { AppUrl } from '../components/socialLogin/FacebookConfig';

const loginWithFb = token => (dispatch) => {
dispatch({
type: IS_AUTHENTICATING_WITH_FB_STARTED,
});
return axios.post(AppUrl, {
user_token: {
auth_token: token,
},
}).then((resp) => {
dispatch({
type: FB_AUTH_DONE_SUCCESS,
payload: resp.data.auth_token.token,
});
localStorage.setItem('accessToken', resp.data.auth_token.token);
document.location.href = '/';
});
};

export default loginWithFb;
2 changes: 2 additions & 0 deletions src/actions/types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const IS_AUTHENTICATING_WITH_FB_STARTED = 'IS_AUTHENTICATING_WITH_FB_STARTED';
export const FB_AUTH_DONE_SUCCESS = 'FB_AUTH_DONE_SUCCESS';
28 changes: 27 additions & 1 deletion src/assets/scss/Login.scss
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ body {
font-family: $roboto-font;

.signStr, .socialDiv {
display: block;
display: flex;
flex-direction: row;
font-size: rem(18);
margin-bottom: rem(15);
text-align: center;
Expand Down Expand Up @@ -128,3 +129,28 @@ body {
font-size: rem(16);
color: #f00
}

.innerSocial {
display: flex;
align-items: center;
margin-top: 0.625rem;
}

.content-continue {
padding:0;
margin:0;
}

.google-login {
margin-top:1.25rem;
}

.facebookbutton{
padding: 0;
margin-right: 0.9375rem;
display: block;
}
.google-login{
align-content: center;
margin-top: 1.4375rem;
}
15 changes: 15 additions & 0 deletions src/components/socialLogin/FaceBook.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
button.kep-login-facebook {
background-color: #14243B;
font-size: 3.125rem;
border: none;
}

.fa-facebook {
font-size: 2.1875rem;
border-radius: 1.25rem;
color: #28589c;
}

button.kep-login-facebook {
padding:0;
}
29 changes: 29 additions & 0 deletions src/components/socialLogin/FaceBookButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { Component } from 'react';
import FacebookLogin from 'react-facebook-login';
import loginWithFb from '../../actions/facebookActions';
import store from '../../store';
import './FaceBook.css';


class FaceBookButton extends Component {
responseFacebook = (response) => {
const FbToken = response.accessToken;
store.dispatch(loginWithFb(FbToken));
};

render() {
return (
<div className="facebookbutton">
<FacebookLogin
appId={process.env.appId}
fields="name,email,picture"
callback={this.responseFacebook}
textButton={false}
icon={<i className="fab fa-facebook" />}
/>
</div>
);
}
}

export default FaceBookButton;
2 changes: 2 additions & 0 deletions src/components/socialLogin/FacebookConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const AppId = `${process.env.AppId}`;
export const AppUrl = `${process.env.AppUrl}`;
5 changes: 5 additions & 0 deletions src/components/socialLogin/Google.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.fa-google-plus {
font-size: 2.1875rem !important;
color: #CD574B;
cursor: pointer;
}
36 changes: 36 additions & 0 deletions src/components/socialLogin/GoogleButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import PropTypes from 'prop-types';
import GoogleLogin from 'react-google-login';
import { ClientId } from './GoogleConfig';
import './Google.css';

const Google = ({ responseGoogle }) => (
<>
<div className="google-login">
<GoogleLogin
clientId={ClientId}
render={renderProps => (
<span
onClick={renderProps.onClick}
disabled={renderProps.disabled}
className="fab fa-google-plus"
role="presentation"
/>
)}
redirectUri={process.env.redirectUri}
onSuccess={responseGoogle}
onFailure={responseGoogle}
/>
</div>
</>
);

Google.propTypes = {
responseGoogle: PropTypes.func,
};

Google.defaultProps = {
responseGoogle: () => {},
};

export default Google;
2 changes: 2 additions & 0 deletions src/components/socialLogin/GoogleConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const ClientId = `${process.env.ClientId}`;
export const ClientSecret = `${process.env.ClientSecret}`;
45 changes: 45 additions & 0 deletions src/components/socialLogin/tests/FaceBookActions.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import moxios from 'moxios';
import loginWithFb from '../../../actions/facebookActions';
import {
IS_AUTHENTICATING_WITH_FB_STARTED,
FB_AUTH_DONE_SUCCESS,
} from '../../../actions/types';

const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);

describe('authentication process', () => {
beforeEach(() => {
moxios.install();
});

afterEach(() => {
moxios.uninstall();
});

it('logs in successfully', () => {
const store = mockStore({});
moxios.wait(() => {
const requestM = moxios.requests.mostRecent();
requestM.respondWith({
status: 200,
response: {
auth_token: {
token: 'test_token',
},
},
});
});
const expectedActions = [
{ type: IS_AUTHENTICATING_WITH_FB_STARTED },
{
payload: 'test_token',
type: FB_AUTH_DONE_SUCCESS,
}];
return store.dispatch(loginWithFb('eyJ0eXAiOiJKV1QiLCJ')).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
});
19 changes: 19 additions & 0 deletions src/components/socialLogin/tests/FacebookButton.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import { shallow } from 'enzyme';
import FaceBookButton from '../FaceBookButton';


describe('Facebook Button Tests', () => {
it('should not regress', () => {
const componentWrapper = shallow(<FaceBookButton />);
const response = {
accessToken: 'testToken',
};
componentWrapper.instance().responseFacebook(response);
});

it('snapshot test', () => {
const componentWrapper = shallow(<FaceBookButton />);
expect(componentWrapper).toMatchSnapshot();
});
});
19 changes: 19 additions & 0 deletions src/components/socialLogin/tests/Google.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { shallow } from 'enzyme';
import GoogleButton from '../GoogleButton';
import SignUpPage from '../../../pages/Signup/index';

describe('Google sign in', () => {
it('should render without crashing', () => {
const wrapper = renderer.create(<GoogleButton />);
expect(wrapper.toJSON()).toMatchSnapshot();
});
});

describe('Signup', () => {
it('should should render correctly', () => {
const wrapper = shallow(<SignUpPage />);
expect(wrapper).toMatchSnapshot();
});
});
Loading

0 comments on commit 4c3031e

Please sign in to comment.