Skip to content

Commit b4fd439

Browse files
authored
Merge pull request #26 from codebuddies/refactor-auth-routes
WIP: Refactor authenticated routes
2 parents acafccf + 87277c3 commit b4fd439

File tree

8 files changed

+106
-67
lines changed

8 files changed

+106
-67
lines changed

client/routes.jsx

Lines changed: 18 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';
2+
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
33
import Login from '../imports/ui/components/login.jsx';
44
import Landing from '../imports/ui/components/landing.jsx';
55
import Navbar from '../imports/ui/components/navbar.jsx';
@@ -8,48 +8,28 @@ import Woohoo from '../imports/ui/components/woohoo.jsx';
88
import Apply from '../imports/ui/components/apply.jsx';
99
import ForgotPassword from '../imports/ui/components/forgot_password.jsx';
1010
import SetPassword from '../imports/ui/components/set_password.jsx';
11-
import Profile from '../imports/ui/components/dashboard/profile.jsx';
1211
import Moderator from '../imports/ui/components/moderator.jsx';
13-
import withUser from '../imports/ui/components/hoc/with-user.jsx';
12+
import Profile from '../imports/ui/components/dashboard/profile';
13+
import AuthenticatedRoute from '../imports/ui/components/hoc/AuthenticatedRoute';
14+
import { AuthProvider } from '../imports/ui/components/hoc/AuthProvider';
1415

1516
export const renderRoutes = () => (
1617
<Router>
17-
<Switch>
18+
<AuthProvider>
1819
<Navbar>
19-
<Route exact path="/" component={Landing} />
20-
<RouteWithUser exact path="/dashboard" component={Profile} />
21-
<RouteWithOutUser exact path="/login" component={Login} />
22-
<RouteWithOutUser exact path="/forgot-password" component={ForgotPassword} />
23-
<RouteWithOutUser exact path="/enroll-account/:token" component={SetPassword} />
24-
<RouteWithOutUser exact path="/reset-password/:token" component={SetPassword} />
25-
<RouteWithUser exact path="/moderator" component={Moderator} />
26-
<Route exact path="/faq" component={Faq} />
27-
<RouteWithOutUser path="/apply" component={Apply} />
28-
<Route path="/woohoo" component={withUser(Woohoo)} />
20+
<Switch>
21+
<AuthenticatedRoute path="/dashboard" component={Profile} />
22+
<AuthenticatedRoute path="/moderator" component={Moderator} />
23+
<Route path="/login" component={Login} />
24+
<Route path="/forgot-password" component={ForgotPassword} />
25+
<Route exact path="/enroll-account/:token" component={SetPassword} />
26+
<Route exact path="/reset-password/:token" component={SetPassword} />
27+
<Route exact path="/faq" component={Faq} />
28+
<Route path="/apply" component={Apply} />
29+
<Route path="/woohoo" component={Woohoo} />
30+
<Route exact path="/" component={Landing} />
31+
</Switch>
2932
</Navbar>
30-
</Switch>
33+
</AuthProvider>
3134
</Router>
3235
);
33-
34-
// All routes where user supposed to be logged in
35-
// If user is not logged in, redirect them to login page
36-
const RouteWithUser = withUser(({ user, component: Component, ...rest }) => {
37-
const { pathname } = window.location;
38-
39-
if (user) {
40-
return <Route {...rest} render={props => <Component {...props} user={user} />} />;
41-
} else if (pathname !== '/login' && pathname === rest.path) {
42-
return <Redirect push to="/login" />;
43-
}
44-
return null;
45-
});
46-
47-
const RouteWithOutUser = withUser(({ user, component: Component, ...rest }) => {
48-
const { pathname } = window.location;
49-
if (!user) {
50-
return <Route {...rest} render={props => <Component {...props} user={user} />} />;
51-
} else if (pathname !== '/dashboard' && pathname === rest.path) {
52-
return <Redirect push to="/dashboard" />;
53-
}
54-
return null;
55-
});

imports/ui/components/forgot_password.jsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { Link } from 'react-router-dom';
33
import { Alert, Container, Button, Form, Row, Col } from 'react-bootstrap';
44
import { Accounts } from 'meteor/accounts-base';
55
import { EMAIL_REGEX } from '/imports/constants/regex';
6+
import { AuthContext } from './hoc/AuthProvider';
7+
import { Redirect } from 'react-router-dom';
68

79
class ForgotPassword extends React.Component {
810
constructor(props) {
@@ -36,8 +38,11 @@ class ForgotPassword extends React.Component {
3638

3739
render() {
3840
const { validated, error, success, processing } = this.state;
41+
const { user } = this.context;
3942

40-
return (
43+
return user ? (
44+
<Redirect to="/home" />
45+
) : (
4146
<Container fluid>
4247
<Row>
4348
<Col sm={{ span: 6, offset: 3 }} lg={{ span: 4, offset: 4 }}>
@@ -76,5 +81,5 @@ class ForgotPassword extends React.Component {
7681
);
7782
}
7883
}
79-
84+
ForgotPassword.contextType = AuthContext;
8085
export default ForgotPassword;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import { Meteor } from 'meteor/meteor';
3+
import { Accounts } from 'meteor/accounts-base';
4+
const AuthContext = React.createContext();
5+
6+
class AuthProvider extends React.Component {
7+
constructor() {
8+
super();
9+
}
10+
state = {
11+
user: null,
12+
};
13+
14+
componentDidMount() {
15+
Accounts.onLogout(() => this.setState({ user: null }));
16+
Accounts.onLogin(() => this.setState({ user: Meteor.user() }));
17+
}
18+
19+
render() {
20+
return <AuthContext.Provider value={{ user: this.state.user }}> {this.props.children} </AuthContext.Provider>;
21+
}
22+
}
23+
24+
const AuthConsumer = AuthContext.Consumer;
25+
export { AuthProvider, AuthConsumer, AuthContext };
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react';
2+
import { Route, Redirect } from 'react-router-dom';
3+
import { AuthConsumer } from './AuthProvider';
4+
5+
const AuthenticatedRoute = ({ component: Component, ...rest }) => (
6+
<AuthConsumer>
7+
{({ user }) => <Route render={props => (user ? <Component {...props} /> : <Redirect to="/login" />)} {...rest} />}
8+
</AuthConsumer>
9+
);
10+
11+
export default AuthenticatedRoute;

imports/ui/components/landing.jsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
import React from 'react';
2-
import { Link } from 'react-router-dom';
2+
import { Link, Redirect } from 'react-router-dom';
33
import { Container, Row, Col } from 'react-bootstrap';
44
import BoardContainer from '/imports/ui/containers/board.jsx';
5+
import { AuthContext } from './hoc/AuthProvider';
56

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

1112
render() {
12-
return (
13+
const { user } = this.context;
14+
15+
return user ? (
16+
<Redirect to="/dashboard" />
17+
) : (
1318
<Container>
1419
<Row>
1520
<Col className="h-100" style={{ marginTop: 140 }}>
@@ -65,5 +70,5 @@ class Landing extends React.Component {
6570
);
6671
}
6772
}
68-
73+
Landing.contextType = AuthContext;
6974
export default Landing;

imports/ui/components/login.jsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React from 'react';
2-
import { Link } from 'react-router-dom';
2+
import { Link, Redirect } from 'react-router-dom';
33
import { Alert, Container, Button, Form, Row, Col } from 'react-bootstrap';
44
import { Meteor } from 'meteor/meteor';
55
import { EMAIL_REGEX } from '/imports/constants/regex';
6-
6+
import { AuthContext } from './hoc/AuthProvider';
77
class Login extends React.Component {
88
constructor(props) {
99
super(props);
@@ -33,8 +33,11 @@ class Login extends React.Component {
3333

3434
render() {
3535
const { validated, error } = this.state;
36+
const { user } = this.context;
3637

37-
return (
38+
return user ? (
39+
<Redirect to="/dashboard" />
40+
) : (
3841
<Container fluid>
3942
<Row>
4043
<Col sm={{ span: 6, offset: 3 }} lg={{ span: 4, offset: 4 }}>
@@ -77,5 +80,5 @@ class Login extends React.Component {
7780
);
7881
}
7982
}
80-
83+
Login.contextType = AuthContext;
8184
export default Login;
Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,31 @@
11
import React from 'react';
22
import { Container, Row, Col } from 'react-bootstrap';
3+
import { AuthContext } from './hoc/AuthProvider';
34
import BoardContainer from '/imports/ui/containers/board.jsx';
45

5-
const Moderator = props => {
6-
const { user } = props;
7-
const { name } = (user && user.profile) || {};
8-
return (
9-
<Container>
10-
<Row>
11-
<Col className="h-100" style={{ marginTop: 40 }}>
12-
<hgroup className="mx-auto p-4 text-center">
13-
<h3>Hello {name}! You are logged in!</h3>
14-
</hgroup>
15-
<BoardContainer />
16-
</Col>
17-
</Row>
18-
</Container>
19-
);
20-
};
6+
class Moderator extends React.Component {
7+
constructor(props) {
8+
super(props);
9+
}
2110

11+
render() {
12+
const { user } = this.context;
13+
const { name } = (user && user.profile) || {};
14+
15+
return (
16+
<Container>
17+
<Row>
18+
<Col className="h-100" style={{ marginTop: 40 }}>
19+
<hgroup className="mx-auto p-4 text-center">
20+
<h3>Hello {name}! You are logged in!</h3>
21+
</hgroup>
22+
<BoardContainer />
23+
</Col>
24+
</Row>
25+
</Container>
26+
);
27+
}
28+
}
29+
30+
Moderator.contextType = AuthContext;
2231
export default Moderator;

imports/ui/components/navbar.jsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import React from 'react';
22
import { Link } from 'react-router-dom';
33
import { Navbar, Nav, Button, Container } from 'react-bootstrap';
44
import { Meteor } from 'meteor/meteor';
5-
import withUser from '/imports/ui/components/hoc/with-user.jsx';
5+
import { AuthContext } from './hoc/AuthProvider';
66

7-
class NavbarWrapper extends React.Component {
7+
class NavigationBar extends React.Component {
88
constructor(props) {
99
super(props);
1010
}
@@ -14,7 +14,7 @@ class NavbarWrapper extends React.Component {
1414
}
1515

1616
render() {
17-
const { user } = this.props;
17+
const { user } = this.context;
1818

1919
return (
2020
<React.Fragment>
@@ -61,4 +61,5 @@ class NavbarWrapper extends React.Component {
6161
}
6262
}
6363

64-
export default withUser(NavbarWrapper);
64+
NavigationBar.contextType = AuthContext;
65+
export default NavigationBar;

0 commit comments

Comments
 (0)