Skip to content

Commit db270dd

Browse files
committed
WIP: updating to context API. Created 'create admin' console command. Fixed x-csrf-token issue.
1 parent ccc3ddf commit db270dd

File tree

8 files changed

+277
-85
lines changed

8 files changed

+277
-85
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module.exports = {
2+
friendlyName: 'Create API Token',
3+
4+
description: 'Get an API token, which replaces CSRF token usage.',
5+
6+
inputs: {},
7+
8+
exits: {
9+
ok: {
10+
responseType: 'ok'
11+
},
12+
badRequest: {
13+
responseType: 'badRequest'
14+
},
15+
serverError: {
16+
responseType: 'serverError'
17+
}
18+
},
19+
20+
fn: (inputs, exits) => {
21+
22+
return exits.ok();
23+
}
24+
};

assets/src/Admin/AdminRouter.jsx

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,38 @@ import SidebarNav from './SidebarNav';
1313
import Upgrade from './Upgrade';
1414

1515
import {APIProvider} from '../data/api';
16+
import {UserProvider, UserConsumer} from '../data/user';
1617

1718
class AdminRouter extends React.Component {
1819
constructor(props) {
1920
super(props);
2021

21-
this.state = {
22-
isAuthenticated: false,
23-
user: sessionStorage.getItem('user')
24-
};
22+
// this.state = {
23+
// isAuthenticated: false,
24+
// user: sessionStorage.getItem('user')
25+
// };
2526

26-
this.userLogin = this.userLogin.bind(this);
27-
this.userLogout = this.userLogout.bind(this);
27+
// this.userLogin = this.userLogin.bind(this);
28+
// this.userLogout = this.userLogout.bind(this);
2829
}
2930

30-
userLogin(user) {
31-
this.setState({user, isAuthenticated: true});
32-
sessionStorage.setItem('user', user);
33-
}
34-
35-
userLogout() {
36-
this.setState({user: {}, isAuthenticated: false});
37-
sessionStorage.removeItem('user');
38-
}
31+
// userLogin(user) {
32+
// this.setState({user, isAuthenticated: true});
33+
// sessionStorage.setItem('user', user);
34+
// }
35+
//
36+
// userLogout() {
37+
// this.setState({user: {}, isAuthenticated: false});
38+
// sessionStorage.removeItem('user');
39+
// }
3940

4041
render() {
4142
const that = this;
4243

4344
function RenderOrLogin(props) {
44-
if (that.state.isAuthenticated) {
45-
return props.children;
46-
}
45+
// if (that.state.isAuthenticated) {
46+
// return props.children;
47+
// }
4748

4849
// return (
4950
// <Redirect
@@ -53,29 +54,46 @@ class AdminRouter extends React.Component {
5354
// }}
5455
// />
5556
// );
56-
return (<Login location={props.location} userLogin={that.userLogin} />);
57+
58+
return (
59+
<UserConsumer>
60+
{
61+
(userContext) => {
62+
if (userContext.isLoggedIn) {
63+
return props.children;
64+
}
65+
66+
return (
67+
<Login />
68+
);
69+
}
70+
}
71+
</UserConsumer>
72+
);
5773
}
5874

5975
return (
6076
<Router>
6177
<Route
6278
render={({location}) => (
6379
<APIProvider>
64-
<RenderOrLogin location={location}>
65-
<SidebarNav>
66-
<Switch>
67-
<Route path="/admin/dashboard">
68-
<Dashboard api={this.state.api} user={this.state.user} />
69-
</Route>
70-
<Route path="/admin/upgrade">
71-
<Upgrade />
72-
</Route>
73-
<Route>
74-
<Redirect to="/admin/dashboard" />
75-
</Route>
76-
</Switch>
77-
</SidebarNav>
78-
</RenderOrLogin>
80+
<UserProvider>
81+
<RenderOrLogin location={location}>
82+
<SidebarNav>
83+
<Switch>
84+
<Route path="/admin/dashboard">
85+
<Dashboard />
86+
</Route>
87+
<Route path="/admin/upgrade">
88+
<Upgrade />
89+
</Route>
90+
<Route>
91+
<Redirect to="/admin/dashboard" />
92+
</Route>
93+
</Switch>
94+
</SidebarNav>
95+
</RenderOrLogin>
96+
</UserProvider>
7997
</APIProvider>
8098
)}
8199
/>

assets/src/Admin/Login.jsx

Lines changed: 82 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,26 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33

44
import {APIConsumer} from '../data/api';
5+
import {UserConsumer} from '../data/user';
56

67
class Login extends React.Component {
78
constructor(props) {
89
super(props);
910

1011
this.state = {
11-
isLoggedIn: false,
1212
email: localStorage.getItem('email') || '',
1313
password: '',
14-
rememberMe: false
14+
autoFocusPassword: false
1515
};
1616

17+
if (this.state.email !== '') {
18+
this.state.autoFocusPassword = true;
19+
}
20+
1721
this.goBack = this.goBack.bind(this);
1822
this.handleLogin = this.handleLogin.bind(this);
1923
this.handleEmail = this.handleEmail.bind(this);
2024
this.handlePassword = this.handlePassword.bind(this);
21-
this.handleRememberMe = this.handleRememberMe.bind(this);
2225
}
2326

2427
goBack() {
@@ -27,15 +30,26 @@ class Login extends React.Component {
2730
// this.props.location.history.push(dest);
2831
}
2932

30-
handleLogin(e, api) {
33+
handleLogin(e, api, done) {
3134
e.preventDefault();
3235

3336
localStorage.setItem('email', this.state.email);
3437

35-
console.log(api);
36-
37-
// TODO: actually hit API to login, then call this function
38-
this.props.userLogin({email: this.state.email});
38+
api.post({
39+
url: '/login',
40+
body: {
41+
email: this.state.email,
42+
password: this.state.password
43+
}
44+
}, (body) => {
45+
if (body.success) {
46+
return done({email: this.state.email});
47+
}
48+
49+
alert('Bad email / password.');
50+
}, (err) => {
51+
alert(err.errorMessages);
52+
});
3953

4054
return false;
4155
}
@@ -48,53 +62,77 @@ class Login extends React.Component {
4862
this.setState({password: e.target.value});
4963
}
5064

51-
handleRememberMe() {
52-
this.setState((current) => ({rememberMe: !current.rememberMe}));
53-
}
54-
5565
render() {
5666
return (
57-
<div id="main-wrapper" className="container">
58-
<h2>Admin</h2>
67+
<UserConsumer>
5968
{
60-
this.state.isLoggedIn &&
61-
<div>You are logged in</div>
62-
}
63-
{
64-
!this.state.isLoggedIn &&
65-
<div className="row justify-content-center">
66-
<APIConsumer>
69+
(userContext) => (
70+
<div id="main-wrapper" className="container">
71+
<h2>Admin</h2>
72+
{
73+
userContext.isLoggedIn &&
74+
<div>You are logged in</div>
75+
}
6776
{
68-
(api) => (
69-
<form onSubmit={(e) => this.handleLogin(e, api)} className="col-3">
70-
<h3 className="row">Login</h3>
71-
<div className="row pb-2">
72-
<input type="email" className="form-control" placeholder="Email" value={this.state.email} onChange={this.handleEmail} />
73-
</div>
74-
<div className="row pb-4">
75-
<input type="password" className="form-control" placeholder="Password" value={this.state.password} onChange={this.handlePassword} />
76-
</div>
77-
<div className="row pb-4 form-check">
78-
<input type="checkbox" className="form-check-input" id="rememberMe" value={this.state.rememberMe} onChange={this.handleRememberMe} />
79-
<label htmlFor="rememberMe">Remember Me</label>
80-
</div>
81-
<div className="row">
82-
<button type="submit" className="btn btn-primary">Login</button>
83-
</div>
84-
</form>
85-
)
77+
!userContext.isLoggedIn &&
78+
<div className="row justify-content-center">
79+
<APIConsumer>
80+
{
81+
(api) => (
82+
83+
<form onSubmit={(e) => this.handleLogin(e, api, userContext.login)} className="col-3">
84+
<h3 className="row">Login</h3>
85+
<div className="row pb-2">
86+
<input
87+
type="email"
88+
className="form-control"
89+
placeholder="Email"
90+
value={this.state.email}
91+
name="email"
92+
onChange={this.handleEmail}
93+
autoFocus={!this.state.autoFocusPassword}
94+
/>
95+
</div>
96+
<div className="row pb-4">
97+
<input
98+
type="password"
99+
className="form-control"
100+
placeholder="Password"
101+
name="password"
102+
value={this.state.password}
103+
onChange={this.handlePassword}
104+
autoFocus={this.state.autoFocusPassword}
105+
/>
106+
</div>
107+
<div className="row pb-4 form-check">
108+
<input
109+
type="checkbox"
110+
className="form-check-input"
111+
id="rememberMe"
112+
defaultChecked={userContext.isRememberMeOn}
113+
onChange={() => userContext.setRememberMe(!userContext.isRememberMeOn)}
114+
/>
115+
<label htmlFor="rememberMe">Remember Me</label>
116+
</div>
117+
<div className="row">
118+
<button type="submit" className="btn btn-primary">Login</button>
119+
</div>
120+
</form>
121+
)
122+
}
123+
</APIConsumer>
124+
</div>
86125
}
87-
</APIConsumer>
88-
</div>
126+
</div>
127+
)
89128
}
90-
</div>
129+
</UserConsumer>
91130
);
92131
}
93132
}
94133

95134
Login.propTypes = {
96-
location: PropTypes.object.isRequired,
97-
userLogin: PropTypes.func.isRequired
135+
// userLogin: PropTypes.func.isRequired
98136
};
99137

100138
Login.defaultProps = {};

assets/src/common/api.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ class api {
66
constructor(baseUrl) {
77
this.baseUrl = baseUrl || process.env.baseUrl; // process.env is coming from webpack
88

9+
this.baseUrl += '/api/v1';
10+
911
this.get = this.get.bind(this);
1012
this.post = this.post.bind(this);
1113
this.put = this.put.bind(this);

assets/src/data/user.jsx

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import {isObject} from 'lodash';
23

34
const userContext = React.createContext();
45

@@ -9,23 +10,48 @@ export class UserProvider extends React.Component {
910
this.state = {
1011
user: {},
1112
isLoggedIn: false,
12-
isRememberMeOn: JSON.parse(localStorage.getItem('user_remember_me')) || false
13+
isRememberMeOn: localStorage.getItem('user_remember_me') === 'true'
1314
};
1415

15-
if (this.state.isRememberMeOn) {
16-
this.state.user.email = localStorage.getItem('user_email') || '';
17-
} else {
18-
this.state.user.email = '';
16+
// if (this.state.isRememberMeOn) {
17+
// this.state.user.email = localStorage.getItem('user_email') || '';
18+
// } else {
19+
// this.state.user.email = '';
20+
// }
21+
22+
this.handleLogin = this.handleLogin.bind(this);
23+
this.handleRememberMe = this.handleRememberMe.bind(this);
24+
this.handleLogout = this.handleLogout.bind(this);
25+
}
26+
27+
handleLogin(user) {
28+
if (user && isObject(user)) {
29+
this.setState({
30+
isLoggedIn: true,
31+
user
32+
});
1933
}
2034
}
2135

36+
handleRememberMe(onOrOff) {
37+
localStorage.setItem('user_remember_me', onOrOff);
38+
this.setState({isRememberMeOn: onOrOff});
39+
}
40+
41+
handleLogout() {
42+
this.setState({user: {}, isLoggedIn: false});
43+
}
44+
2245
render() {
2346
return (
2447
<userContext.Provider
2548
value={{
2649
user: this.state.user,
2750
isLoggedIn: this.state.isLoggedIn,
28-
isRememberMeOn: this.state.isRememberMeOn
51+
isRememberMeOn: this.state.isRememberMeOn,
52+
login: this.handleLogin,
53+
setRememberMe: this.handleRememberMe,
54+
logout: this.handleLogout
2955
}}
3056
>
3157
{/* eslint-disable-next-line react/prop-types */}

0 commit comments

Comments
 (0)