Merge pull request #881 from opensupports/google-social-login
Google social login
This commit is contained in:
commit
6e6d2d83e7
|
@ -68,11 +68,13 @@ export default {
|
|||
logout() {
|
||||
return {
|
||||
type: 'LOGOUT',
|
||||
payload: API.call({
|
||||
path: '/user/logout',
|
||||
data: {}
|
||||
})
|
||||
};
|
||||
payload: Promise.resolve()
|
||||
.then(() => gapi && gapi.auth2 && gapi.auth2.getAuthInstance().signOut())
|
||||
.then(() => API.call({
|
||||
path: '/user/logout',
|
||||
data: {}
|
||||
}))
|
||||
}
|
||||
},
|
||||
|
||||
getUserData(userId, token, staff) {
|
||||
|
|
|
@ -35,6 +35,11 @@ describe('Login/Recover Widget', function () {
|
|||
let dispatch = stub();
|
||||
|
||||
function renderComponent(props = {session: {pending: false, failed: false}}) {
|
||||
window.gapi = {
|
||||
load() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
component = reRenderIntoDocument(
|
||||
<MainHomePageLoginWidget dispatch={dispatch} {...props}/>
|
||||
);
|
||||
|
@ -116,6 +121,11 @@ describe('Login/Recover Widget', function () {
|
|||
let dispatch = stub();
|
||||
|
||||
beforeEach(function () {
|
||||
window.gapi = {
|
||||
load() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
component = TestUtils.renderIntoDocument(
|
||||
<MainHomePageLoginWidget dispatch={dispatch} session={{pending: false, failed: false}} />
|
||||
);
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import {connect} from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
import _ from 'lodash';
|
||||
|
||||
import SessionActions from 'actions/session-actions';
|
||||
import API from 'lib-app/api-call';
|
||||
import focus from 'lib-core/focus';
|
||||
import i18n from 'lib-app/i18n';
|
||||
|
||||
import PasswordRecovery from 'app-components/password-recovery';
|
||||
|
@ -35,6 +33,10 @@ class MainHomePageLoginWidget extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.renderGoogleButton();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<WidgetTransition sideToShow={this.state.sideToShow} className={classNames('login-widget__container', this.props.className)}>
|
||||
|
@ -49,6 +51,7 @@ class MainHomePageLoginWidget extends React.Component {
|
|||
<Widget className="main-home-page__widget" title={i18n('LOG_IN')} ref="loginWidget">
|
||||
<Form {...this.getLoginFormProps()}>
|
||||
<div className="login-widget__inputs">
|
||||
<div id="google-oauth-id">Loading Google Login ...</div>
|
||||
<FormField placeholder={i18n('EMAIL_LOWERCASE')} name="email" className="login-widget__input" validation="EMAIL" required/>
|
||||
<FormField placeholder={i18n('PASSWORD_LOWERCASE')} name="password" className="login-widget__input" required fieldProps={{password: true}}/>
|
||||
<FormField name="remember" label={i18n('REMEMBER_ME')} className="login-widget__input" field="checkbox"/>
|
||||
|
@ -64,6 +67,23 @@ class MainHomePageLoginWidget extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderGoogleButton() {
|
||||
window.gapi.load('auth2', () => {
|
||||
gapi.auth2.init({client_id: '50174278643-gtvjdpm5rmkv75lf3jsp95iv77a2usgu.apps.googleusercontent.com'})
|
||||
gapi.signin2.render('google-oauth-id', {
|
||||
scope: 'email',
|
||||
width: 200,
|
||||
height: 30,
|
||||
longtitle: true,
|
||||
theme: 'dark',
|
||||
onsuccess: this.onGoogleLoginSuccess.bind(this),
|
||||
onfailure: (response) => {
|
||||
console.log(response);
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
renderPasswordRecovery() {
|
||||
return (
|
||||
<PasswordRecovery ref="passwordRecovery" recoverSent={this.state.recoverSent} formProps={this.getRecoverFormProps()} onBackToLoginClick={this.onBackToLoginClick.bind(this)}/>
|
||||
|
@ -126,6 +146,12 @@ class MainHomePageLoginWidget extends React.Component {
|
|||
this.props.dispatch(SessionActions.login(formState));
|
||||
}
|
||||
|
||||
onGoogleLoginSuccess(googleUser) {
|
||||
let id_token = googleUser.getAuthResponse().id_token;
|
||||
console.log(id_token);
|
||||
this.props.dispatch(SessionActions.login({'googleId': id_token, 'remember': 1}));
|
||||
}
|
||||
|
||||
onForgotPasswordSubmit(formState) {
|
||||
this.setState({
|
||||
loadingRecover: true,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<script>
|
||||
window.customTicketList = [];
|
||||
</script>
|
||||
<script src="https://apis.google.com/js/platform.js" async defer></script>
|
||||
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=String.prototype.startsWith,Array.from,Array.prototype.fill,Array.prototype.keys,Array.prototype.find,Array.prototype.findIndex,Array.prototype.includes,String.prototype.repeat,Number.isInteger,Promise&flags=gated"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -10,7 +10,7 @@ build:
|
|||
@docker network create os-net || true
|
||||
|
||||
install:
|
||||
@docker exec -it opensupports-srv bash -c "cd /var/www/html && composer install" || echo "${red}Please execute 'make run' first${reset}"
|
||||
@docker exec -it opensupports-srv bash -c "cd /var/www/html && composer update && composer install" || echo "${red}Please execute 'make run' first${reset}"
|
||||
@docker exec -it opensupports-db bash -c "mysql -u root -e \"CREATE DATABASE IF NOT EXISTS development;\" " || echo "${red}Please execute 'make run' first${reset}"
|
||||
|
||||
run: stop
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
"codeguy/upload": "^1.3",
|
||||
"php-imap/php-imap": "^3.0",
|
||||
"willdurand/email-reply-parser": "^2.8",
|
||||
"ext-fileinfo": "^1.0"
|
||||
"ext-fileinfo": "^1.0",
|
||||
"google/apiclient": "^2.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7"
|
||||
|
|
|
@ -19,6 +19,7 @@ use RedBeanPHP\Facade as RedBean;
|
|||
* @apiParam {Boolean} remember Indicates if the session wants to be remembered.
|
||||
* @apiParam {Number} userId The id of the user to login.
|
||||
* @apiParam {String} rememberToken Token to login automatically. It replaces the password.
|
||||
* @apiParam {String} googleId Token to log in with Google.
|
||||
*
|
||||
* @apiUse UNVERIFIED_USER
|
||||
* @apiUse INVALID_CREDENTIALS
|
||||
|
@ -49,6 +50,24 @@ class LoginController extends Controller {
|
|||
|
||||
public function handler() {
|
||||
$this->clearOldRememberTokens();
|
||||
|
||||
if ($this->checkGoogleLogin()) {
|
||||
$client = new Google_Client(['client_id' => '50174278643-gtvjdpm5rmkv75lf3jsp95iv77a2usgu.apps.googleusercontent.com']);
|
||||
$payload = $client->verifyIdToken(Controller::request('googleId'));
|
||||
if ($payload && $payload['email_verified']) {
|
||||
$this->userInstance = User::getUser($payload['email'], 'email');
|
||||
|
||||
if ($this->userInstance->isNull()) {
|
||||
$this->userInstance = $this->createGoogleUser($payload);
|
||||
}
|
||||
|
||||
Session::getInstance()->createSession($this->userInstance->id, false);
|
||||
Response::respondSuccess($this->getUserData());
|
||||
return;
|
||||
} else {
|
||||
throw new Exception("Invalid GoogleID token or unverified Google account");
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->checkInputCredentials() || $this->checkRememberToken()) {
|
||||
if($this->userInstance->verificationToken !== null) {
|
||||
|
@ -73,6 +92,36 @@ class LoginController extends Controller {
|
|||
}
|
||||
}
|
||||
|
||||
private function checkGoogleLogin() {
|
||||
return !!Controller::request('googleId');
|
||||
}
|
||||
|
||||
private function createGoogleUser($payload) {
|
||||
Controller::setDataRequester(function ($key) use ($payload) {
|
||||
switch ($key) {
|
||||
case 'email':
|
||||
return $payload['email'];
|
||||
case 'password':
|
||||
return Hashing::generateRandomToken();
|
||||
case 'name':
|
||||
return $payload['name'];
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
$signupController = new SignUpController(true);
|
||||
|
||||
try {
|
||||
$signupController->validate();
|
||||
$signupController->handler();
|
||||
} catch (\Exception $exception) {
|
||||
throw new Exception("OpenSupports doesn't accept this Google account, failed validations: " . $exception);
|
||||
}
|
||||
|
||||
return User::getUser($payload['email'], 'email');
|
||||
}
|
||||
|
||||
private function checkInputCredentials() {
|
||||
$this->userInstance = $this->getUserByInputCredentials();
|
||||
|
||||
|
|
Loading…
Reference in New Issue