Commit b10502cd authored by Viacheslav Pavlov's avatar Viacheslav Pavlov
Browse files

Google+ login

Google+ login fixed imports

Fixed SSR Google+ login

Fixed imports for Google+ login, moved GOOGLE_CLIENT_ID to dev webpack config
parent 69dcc419
......@@ -5,6 +5,7 @@ var stylelint = require('stylelint');
var postcssAssets = require('postcss-assets');
var postcssNext = require('postcss-cssnext');
const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID;
const commonConfig = require('./webpack-base.config.js');
module.exports = webpackMerge(commonConfig, {
......@@ -29,7 +30,11 @@ module.exports = webpackMerge(commonConfig, {
}
}
}),
new webpack.DefinePlugin({
'process.env': {
GOOGLE_CLIENT_ID: JSON.stringify(GOOGLE_CLIENT_ID)
}
}),
// hot module replacement for webpack-dev-server
new webpack.HotModuleReplacementPlugin()
],
......
......@@ -7,6 +7,7 @@ apps:
--client-id=${CLIENT_ID}
--client-secret=${CLIENT_SECRET}
--geonames-username=${GEONAMES_USERNAME}
--google-client-id=${GOOGLE_CLIENT_ID}
name: genesysui
exec_mode: cluster
instances: 3
......
......@@ -14227,6 +14227,15 @@
"prop-types": "^15.5.6"
}
},
"react-google-login": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/react-google-login/-/react-google-login-3.2.1.tgz",
"integrity": "sha512-9+OFbdGDr6vazlcCkLbtN92Wwfb+aG/RJ0ScypTK6Ox5g642z1aDrnmal2V5AqWl2+Ph53sBhRnk0KTvUdNXpA==",
"requires": {
"@types/react": "*",
"prop-types": "^15.6.0"
}
},
"react-hot-loader": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.3.3.tgz",
......
......@@ -3,7 +3,7 @@ import * as minimist from 'minimist';
// console.log(process.argv);
const argv = minimist(process.argv.slice(2), {
string: [
'--api-url', '--client-id', '--client-secret', '--frontend-path',
'--api-url', '--client-id', '--client-secret', '--frontend-path', '--google-client-id',
],
});
console.dir(argv);
......@@ -19,6 +19,7 @@ const config = {
apiUrl: argv['api-url'] || 'localhost:8080',
clientId: argv['client-id'] || 'defaultclient@localhost',
clientSecret: argv['client-secret'] || 'changeme',
googleClientId: argv['google-client-id'] || '',
};
if (config.frontendPath.endsWith('/')) {
......
......@@ -26,6 +26,7 @@ import detectLocaleFromPath from './detectLocaleFromPath';
import getDir from './detectDirection';
import config from '../config';
import checkAuthToken from './checkAuthToken';
import {configure} from 'actions/applicationConfig';
const prerenderer = (html) => (req, res) => {
console.log('Init prerenderer, request url:', req.url);
......@@ -33,6 +34,7 @@ const prerenderer = (html) => (req, res) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'X-Requested-With');
const store = createStore(rootReducer, {} as any, applyMiddleware(thunk, routerMiddleware(createMemoryHistory)));
store.dispatch(configure(config));
console.log(`Processing request`, req._parsedOriginalUrl);
const pathname = req._parsedOriginalUrl.pathname;
const search = req._parsedOriginalUrl.search;
......
import {CONFIGURE_APPLICATION} from 'constants/applicationConfig';
export const configure = (config: object) => ({
type: CONFIGURE_APPLICATION,
payload: config,
});
......@@ -75,11 +75,11 @@ function checkTokenRequest(token) {
};
}
function verifyGoogleTokenRequest(accessToken, googleClientId) {
function verifyGoogleTokenRequest(accessToken) {
return (dispatch, getState) => {
const token = getState().login.access_token;
return LoginService.verifyGoogleToken(token, accessToken, googleClientId)
return LoginService.verifyGoogleToken(token, accessToken)
.then((data) => {
saveCookies(data);
return dispatch(loginApp(data));
......
export const CONFIGURE_APPLICATION = 'CONFIGURE_APPLICATION';
import update from 'immutability-helper';
import {CONFIGURE_APPLICATION} from 'constants/applicationConfig';
const INITIAL_STATE: {
googleClientId: string;
} = {
googleClientId: process.env.GOOGLE_CLIENT_ID || '',
};
export default function configure(state = INITIAL_STATE, action: { type?: string, payload?: any } = {type: '', payload: {}}) {
switch (action.type) {
case CONFIGURE_APPLICATION: {
return update(state, {
$set: action.payload,
});
}
default:
return state;
}
}
......@@ -10,6 +10,7 @@ import snackbar from './snackbar';
import filterCode from './filterCode';
import subsets from './subsets';
import accessions from './accessions';
import applicationConfig from './applicationConfig';
const rootReducer = combineReducers({
login,
......@@ -23,6 +24,7 @@ const rootReducer = combineReducers({
form: formReducer,
subsets,
accessions,
applicationConfig,
});
export default rootReducer;
......@@ -62,13 +62,12 @@ export class LoginService {
});
}
public static verifyGoogleToken(token: string, accessToken, googleClientId) {
public static verifyGoogleToken(token: string, accessToken) {
return authenticatedRequest(token, {
url: VERIFY_GOOGLE_TOKEN_URL,
method: 'GET',
params: {
accessToken,
googleClientId,
},
})
.then(({ data }) => data);
......
......@@ -6,7 +6,7 @@ import * as _ from 'lodash';
import {log} from 'utilities/debug';
import {loginRequest, checkTokenRequest} from 'actions/login';
import {loginRequest, checkTokenRequest, verifyGoogleTokenRequest} from 'actions/login';
import ContentHeader from 'ui/common/heading/ContentHeader';
......@@ -19,7 +19,9 @@ interface ILoginContainerProps extends React.ClassAttributes<any> {
login: any;
loginRequest: (u, p) => Promise<any>;
checkTokenRequest: (t) => Promise<any>;
verifyGoogleTokenRequest: (aT) => Promise<any>;
history: any;
googleClientId: string;
}
class LoginContainer extends React.Component<ILoginContainerProps, void> {
......@@ -44,6 +46,26 @@ class LoginContainer extends React.Component<ILoginContainerProps, void> {
});
}
private onGoogleLogin = (response): any => {
const { verifyGoogleTokenRequest, checkTokenRequest, history } = this.props;
log('Trying google login');
return verifyGoogleTokenRequest(response.accessToken)
.then(({access_token}) => {
log('Access token', access_token);
return checkTokenRequest(access_token);
})
.then((data) => {
saveCookies(data);
history.push('/dashboard');
return false;
}).catch((e) => {
const data = _.get(e, 'response.data');
if (data && data.error) {
return ({error: data.error, errorDescription: data.error_description});
}
});
}
public render() {
return (
<PageLayout>
......@@ -53,7 +75,7 @@ class LoginContainer extends React.Component<ILoginContainerProps, void> {
<Card>
<CardHeader title="Login" />
<CardContent>
<LoginForm onTryLogin={ this.onLogin } />
<LoginForm onTryLogin={ this.onLogin } onTryGoogleLogin={ this.onGoogleLogin } googleClientId={ this.props.googleClientId } />
</CardContent>
</Card>
</Grid>
......@@ -65,11 +87,13 @@ class LoginContainer extends React.Component<ILoginContainerProps, void> {
const mapStateToProps = (state) => ({
login: state.login,
googleClientId: state.applicationConfig.googleClientId,
});
const mapDispatchToProps = (dispatch) => bindActionCreators({
loginRequest,
checkTokenRequest,
verifyGoogleTokenRequest,
}, dispatch);
export default connect(mapStateToProps, mapDispatchToProps)(LoginContainer);
import * as React from 'react';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import GoogleLogin from 'react-google-login';
interface ILoginProps extends React.ClassAttributes<any> {
onTryLogin: (username, password) => Promise<any>;
onTryGoogleLogin: (response) => Promise<any>;
googleClientId: string;
}
class Login extends React.Component<ILoginProps, any> {
......@@ -31,6 +34,19 @@ class Login extends React.Component<ILoginProps, any> {
}
}
private onGoogleLoginSuccess = (response) => {
const {onTryGoogleLogin} = this.props;
if (response) {
onTryGoogleLogin(response).then((res) => {
if (res) {
this.setState(res);
}
});
}
}
private onGoogleLoginError = (e) => this.setState({...this.state, error: e.error, errorDescription : e.details });
private handleUsername = (e) => this.setState({...this.state, username: e.target.value});
private handlePassword = (e) => this.setState({...this.state, password: e.target.value});
......@@ -57,6 +73,13 @@ class Login extends React.Component<ILoginProps, any> {
<Button variant="raised" type="submit" style={ { margin: '1rem 0 1rem 0' } } >
Login
</Button>
<br/>
<GoogleLogin
clientId={ this.props.googleClientId }
buttonText="Login with Google"
onSuccess={ this.onGoogleLoginSuccess }
onFailure={ this.onGoogleLoginError }
/>
</form>
);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment