Skip to content

Commit 86eef5b

Browse files
author
gondzo
committed
Merge branch 'improveLogin' into dev
# Conflicts: # README.md # package.json # src/routes/DronesMap/modules/DronesMap.js # src/routes/index.js # src/services/APIService.js
2 parents 046ed5a + afa8296 commit 86eef5b

File tree

17 files changed

+575
-93
lines changed

17 files changed

+575
-93
lines changed

.env.example

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
REACT_APP_API_BASE_PATH=https://kb-dsp-server.herokuapp.com
2-
REACT_APP_SOCKET_URL=https://kb-dsp-server.herokuapp.com
3-
REACT_APP_AUTH0_CLIEND_ID=3CGKzjS2nVSqHxHHE64RhvvKY6e0TYpK
4-
REACT_APP_AUTH0_DOMAIN=dronetest.auth0.com
5-
REACT_APP_GOOGLE_API_KEY=AIzaSyCR3jfBdv9prCBYBOf-fPUDhjPP4K05YjE
1+
GOOGLE_API_KEY=AIzaSyCrL-O319wNJK8kk8J_JAYsWgu6yo5YsDI
2+
API_BASE_PATH=http://localhost:3500
3+
REACT_APP_AUTH0_CLIENT_ID=h7p6V93Shau3SSvqGrl6V4xrATlkrVGm
4+
REACT_APP_AUTH0_CLIENT_DOMAIN=spanhawk.auth0.com
5+
REACT_APP_SOCKET_URL=http://localhost:3500

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@ See Guild https://github.com/lorenwest/node-config/wiki/Configuration-Files
2424
|`REACT_APP_AUTH0_DOMAIN`| The React app auth0 domain`|
2525

2626
Environment variables will be loaded from the .env file during build. Create the .env file based on the provided env.example
27+
### Auth0 setup
28+
- Create an account on auth0.
29+
- Click on clients in left side menu, it will redirect you to client page. Click on CREATE CLIENT button
30+
to create a new client.
31+
- Copy the client id and client domain and export them as environment variables.
32+
- Add `http://localhost:3000` as Allowed callback url's in client settings.
33+
34+
### Add social connections
35+
36+
### Facebook social connection
37+
- To add facebook social connection to auth0, you have to create a facebook app.
38+
Go to facebook [developers](https://developers.facebook.com/apps) and create a new app.
39+
- Copy the app secret and app id to auth0 social connections facebook tab.
40+
- You have to setup the oauth2 callback in app oauth settings.
41+
- For more information visit auth0 [docs](https://auth0.com/docs/connections/social/facebook)
42+
43+
### Google social connection
44+
- For more information on how to connect google oauth2 client, visit official [docs](https://auth0.com/docs/connections/social/google)
2745

2846
## Install dependencies
2947
`npm i`

config/default.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable import/no-commonjs */
22
/**
3-
* Main config file
3+
* Main config file for the server which is hosting the reat app
44
*/
55
module.exports = {
66
// below env variables are NOT visible in frontend

src/api/User.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,17 @@ class UserApi {
5656
})});
5757
}
5858

59-
registerSocialUser(name, email) {
59+
registerSocialUser(name, email, token) {
6060
const url = `${this.basePath}/api/v1/login/social`;
6161

6262
return reqwest({
6363
url,
6464
method: 'post',
6565
type: 'json',
6666
contentType: 'application/json',
67+
headers: {
68+
Authorization: `Bearer ${token}`,
69+
},
6770
data: JSON.stringify({
6871
name,
6972
email,

src/components/TextField/TextField.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
width: 100%;
33
border: 1px solid #ebebeb;
44

5+
input[type="password"],
56
input[type="text"] {
67
width: 100%;
78
padding: 0 10px;

src/config/index.js

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
1+
/* eslint-disable import/no-commonjs */
12
/**
2-
* Copyright (c) 2016 Topcoder Inc, All rights reserved.
3+
* Main config file for the react app
34
*/
4-
5-
/**
6-
* Webapp configuration
7-
*
8-
* @author TCSCODER
9-
* @version 1.0.0
10-
*/
11-
12-
const config = {
13-
api: {
14-
basePath: process.env.REACT_APP_API_BASE_PATH || 'http://localhost:3500',
15-
},
5+
module.exports = {
6+
// below env variables are visible in frontend
7+
API_BASE_PATH: process.env.API_BASE_PATH || 'http://localhost:3500',
8+
REACT_APP_AUTH0_CLIENT_ID: process.env.REACT_APP_AUTH0_CLIENT_ID || 'h7p6V93Shau3SSvqGrl6V4xrATlkrVGm',
9+
REACT_APP_AUTH0_CLIENT_DOMAIN: process.env.REACT_APP_AUTH0_CLIENT_DOMAIN || 'spanhawk.auth0.com',
10+
AUTH0_CALLBACK: 'http://localhost:3000',
1611
socket: {
1712
url: process.env.REACT_APP_SOCKET_URL || 'http://localhost:3500',
1813
},
19-
AUTH0_CLIEND_ID: process.env.REACT_APP_AUTH0_CLIEND_ID || '3CGKzjS2nVSqHxHHE64RhvvKY6e0TYpK',
20-
AUTH0_DOMAIN: process.env.REACT_APP_AUTH0_DOMAIN || 'dronetest.auth0.com',
2114
};
22-
23-
export default config;

src/routes/Home/components/LoginModal/LoginModal.jsx

Lines changed: 142 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import Button from 'components/Button';
77
import Checkbox from 'components/Checkbox';
88
import TextField from 'components/TextField';
99
import styles from './LoginModal.scss';
10+
import APIService from '../../../../services/APIService';
11+
import {toastr} from 'react-redux-toastr';
12+
import {defaultAuth0Service} from '../../../../services/AuthService';
13+
14+
const EMAIL_REGEX = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
15+
1016
/*
1117
* customStyles
1218
*/
@@ -50,10 +56,11 @@ FormField.propTypes = {
5056
*/
5157

5258
class LogInModal extends React.Component {
53-
constructor() {
54-
super();
59+
constructor(props) {
60+
super(props);
5561
this.state = {
5662
modalLoginIsOpen: false,
63+
showForgetPassword: false,
5764
};
5865
}
5966

@@ -62,15 +69,14 @@ class LogInModal extends React.Component {
6269
}
6370

6471
closeLoginModal() {
65-
this.setState({modalLoginIsOpen: false});
72+
this.setState({modalLoginIsOpen: false, showForgetPassword: false});
6673
}
6774

6875
login() {
6976
this.setState({modalLoginIsOpen: true});
7077
}
7178

7279
handleLogin(handleLoggedIn, loggedUser) {
73-
handleLoggedIn();
7480
const _self = this;
7581
setTimeout(() => {
7682
handleLoggedIn();
@@ -81,9 +87,53 @@ class LogInModal extends React.Component {
8187
}, 100);
8288
}
8389

90+
forgetPassword() {
91+
this.setState({showForgetPassword: true});
92+
}
93+
94+
/**
95+
* Login using google social network,
96+
* this method internally uses auth0 service
97+
*/
98+
googleLogin() {
99+
defaultAuth0Service.login({connection: 'google-oauth2'}, (error) => {
100+
if (error) {
101+
const message = error.message || 'something went wrong, please try again';
102+
toastr.error(message);
103+
}
104+
});
105+
}
106+
107+
/**
108+
* Login using facebook social network,
109+
* this method internally uses auth0 service
110+
*/
111+
facebookLogin() {
112+
defaultAuth0Service.login({connection: 'facebook'}, (error) => {
113+
if (error) {
114+
const message = error.message || 'something went wrong, please try again';
115+
toastr.error(message);
116+
}
117+
});
118+
}
119+
120+
/**
121+
* This method is invoked when reset password request is submitted
122+
*/
123+
handleForgetPassword(data) {
124+
APIService.forgotPassword({email: data.emailUp}).then(() => {
125+
toastr.success('', 'Reset password link emailed to your email address');
126+
this.closeLoginModal();
127+
}).catch((reason) => {
128+
const message = reason.response.body.error || 'something went wrong, please try again';
129+
toastr.error(message);
130+
this.closeLoginModal();
131+
});
132+
}
133+
84134
render() {
135+
const _self = this;
85136
const {handleSubmit, fields, handleLoggedIn, loggedUser, hasError, errorText} = this.props;
86-
87137
return (
88138
<div styleName="signin-modal">
89139
<div styleName="login-signup">
@@ -100,71 +150,88 @@ class LogInModal extends React.Component {
100150

101151
<div styleName="modal-header">
102152
<div onClick={this.closeLoginModal.bind(this)} styleName="icon-close-modal" />
103-
<div styleName="title">Login to Your Account</div>
153+
{this.state.showForgetPassword === false && <div styleName="title">Login to Your Account</div>}
154+
{this.state.showForgetPassword === true && <div styleName="title">Reset forgotten password</div>}
104155
</div>
156+
{this.state.showForgetPassword === false &&
157+
<form styleName="login-form" onSubmit={handleSubmit}>
158+
<div styleName="login-with-fb">
159+
<a href="javascript:;" onClick={this.facebookLogin.bind(this)}>
160+
<i styleName="icon-facebook" />
161+
<span>Log In with Facebook</span>
162+
</a>
163+
</div>
105164

106-
<form styleName="login-form" onSubmit={handleSubmit}>
107-
<div styleName="login-with-fb">
108-
<a href="javascript:;">
109-
<i styleName="icon-facebook" />
110-
<span>Log In with Facebook</span>
111-
</a>
112-
</div>
113-
114-
<div styleName="login-with-gplus">
115-
<a href="javascript:;">
116-
<i styleName="icon-gplus" />
117-
<span>Log In with Google Plus</span>
118-
</a>
119-
</div>
120-
{/* login with end */}
121-
<div styleName="or-border">
122-
<div styleName="left-line" />
123-
<div styleName="or">or</div>
124-
<div styleName="right-line" />
125-
</div>
126-
{/* or end */}
127-
<div>
128-
{hasError && <span className="error-msg">{errorText.error}</span>}
129-
<div styleName="email-input">
130-
<FormField {...fields.email}>
131-
<TextField {...fields.email} login type="email" label="Email" />
132-
</FormField>
165+
<div styleName="login-with-gplus">
166+
<a href="javascript:;" onClick={this.googleLogin.bind(this)}>
167+
<i styleName="icon-gplus" />
168+
<span>Log In with Google Plus</span>
169+
</a>
170+
</div>
171+
{/* login with end */}
172+
<div styleName="or-border">
173+
<div styleName="left-line" />
174+
<div styleName="or">or</div>
175+
<div styleName="right-line" />
133176
</div>
177+
{/* or end */}
134178
<div>
135-
<FormField {...fields.password}>
136-
<TextField {...fields.password} login type="password" label="Password" />
137-
</FormField>
179+
{hasError && <span className="error-msg">{errorText.error}</span>}
180+
<div styleName="email-input">
181+
<FormField {...fields.email}>
182+
<TextField {...fields.email} login type="email" label="Email" />
183+
</FormField>
184+
</div>
185+
<div>
186+
<FormField {...fields.password}>
187+
<TextField {...fields.password} login type="password" label="Password" />
188+
</FormField>
189+
</div>
138190
</div>
139-
</div>
140-
{/* input end */}
141-
<div styleName="rem-forget">
142-
<div styleName="rem-checkbox">
143-
<Checkbox
144-
checked={!this.props.fields.remember.value}
145-
onChange={() => this.props.fields.remember.onChange(!this.props.fields.remember.value)}
146-
id="remember"
191+
{/* input end */}
192+
<div styleName="rem-forget">
193+
<div styleName="rem-checkbox">
194+
<Checkbox
195+
checked={!this.props.fields.remember.value}
196+
onChange={() => this.props.fields.remember.onChange(!this.props.fields.remember.value)}
197+
id="remember"
198+
>
199+
Remember me
200+
</Checkbox>
201+
</div>
202+
<div styleName="forget"><a href="javascript:;" onClick={this.forgetPassword.bind(this)}>Forget Password?</a></div>
203+
</div>
204+
<div styleName="login-btn">
205+
<Button
206+
type="submit" color="black"
207+
className={styles.btnLogin} onClick={() => this.handleLogin(handleLoggedIn, loggedUser)}
147208
>
148-
Remember me
149-
</Checkbox>
209+
Log In
210+
</Button>
211+
</div>
212+
<div styleName="dont-have">
213+
Don&#8217;t have an account? <a href="javascript:;" className="singup">Sign Up</a>
214+
</div>
215+
</form>
216+
}
217+
{ this.state.showForgetPassword === true &&
218+
<form styleName="login-form" onSubmit={handleSubmit((data) => _self.handleForgetPassword(data))}>
219+
<div>
220+
{hasError && <span className="error-msg">{errorText.error}</span>}
221+
<div styleName="email-input">
222+
<FormField {...fields.emailUp}>
223+
<TextField {...fields.emailUp} login type="email" label="Email" />
224+
</FormField>
225+
</div>
226+
</div>
227+
<div styleName="login-btn">
228+
<Button type="submit" color="black" className={styles.btnLogin}>
229+
Reset Password
230+
</Button>
150231
</div>
151-
<div styleName="forget"><a href="javascript:;">Forget Password?</a></div>
152-
</div>
153-
<div styleName="login-btn">
154-
<Button
155-
type="submit" color="black"
156-
className={styles.btnLogin} onClick={() => this.handleLogin(handleLoggedIn, loggedUser)}
157-
>
158-
Log In
159-
</Button>
160-
</div>
161-
<div styleName="dont-have">
162-
Don&#8217;t have an account? <a href="javascript:;" className="singup" >Sign Up</a>
163-
</div>
164-
</form>
232+
</form>
233+
}
165234
</Modal>
166-
167-
168235
</div>
169236
);
170237
}
@@ -183,9 +250,21 @@ const fields = ['remember', 'email', 'password', 'emailUp', 'passwordUp'];
183250

184251
const validate = (values) => {
185252
const errors = {};
253+
if (!values.emailUp && !values.email) {
254+
errors.emailUp = 'Email is required';
255+
} else if (!EMAIL_REGEX.test(values.emailUp) && !values.email) {
256+
errors.emailUp = 'Invalid email address';
257+
}
258+
259+
if (errors.emailUp && (values.emailUp || values.email)) {
260+
return errors;
261+
} else if (values.emailUp) {
262+
return errors;
263+
}
264+
186265
if (!values.email) {
187266
errors.email = 'Email is required';
188-
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
267+
} else if (!EMAIL_REGEX.test(values.email)) {
189268
errors.email = 'Invalid email address';
190269
}
191270
if (!values.password) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy