Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ module.exports = {
siteMetadata: {
title: `Gatsby Firebase Authentication`,
},
plugins: [`gatsby-plugin-react-helmet`, `gatsby-plugin-react-next`],
plugins: [`gatsby-plugin-react-helmet`],
}
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
"version": "1.0.0",
"author": "Robin Wieruch <wrobin@gmx.net>",
"dependencies": {
"bluebird": "^3.5.1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ckj do you know where Bluebird is used in the application?

"firebase": "^5.0.4",
"gatsby": "^1.9.266",
"gatsby-link": "^1.6.44",
"gatsby-plugin-react-helmet": "^2.0.11",
"gatsby-plugin-react-next": "^1.0.11",
"gatsby": "next",
"gatsby-plugin-react-helmet": "next",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-helmet": "^5.2.0"
},
"keywords": [
Expand All @@ -19,7 +20,7 @@
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --trailing-comma es5 --no-semi --single-quote --write \"src/**/*.js\"",
"format": "prettier --trailing-comma es5 --single-quote --write \"src/**/*.js\"",
"test": "echo \"No test specified\" && exit 0"
},
"devDependencies": {
Expand Down
45 changes: 31 additions & 14 deletions src/components/App/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import React from 'react';
import {
BrowserRouter as Router,
Route,
} from 'react-router-dom';
import { BrowserRouter as Router, Route } from 'react-router-dom';

import Navigation from '../Navigation';
import LandingPage from '../Landing';
Expand All @@ -16,24 +13,44 @@ import * as routes from '../../constants/routes';

import './index.css';

const App = () =>
const App = () => (
<Router>
<div className="app">
<Navigation />

<hr/>

<hr />
<Route exact path={routes.LANDING} component={() => <LandingPage />} />
<Route exact path={routes.SIGN_UP} component={() => <SignUpPage />} />
<Route exact path={routes.SIGN_IN} component={() => <SignInPage />} />
<Route exact path={routes.PASSWORD_FORGET} component={() => <PasswordForgetPage />} />
<Route
exact
path={routes.PASSWORD_FORGET}
component={() => <PasswordForgetPage />}
/>
<Route exact path={routes.HOME} component={() => <HomePage />} />
<Route exact path={routes.ACCOUNT} component={() => <AccountPage />} />

<hr/>

<span>Found in <a href="https://roadtoreact.com/course-details?courseId=TAMING_THE_STATE">Taming the State in React</a></span> | <span>Star the <a href="https://github.com/rwieruch/react-firebase-authentication">Repository</a></span> | <span>Receive a <a href="https://www.getrevue.co/profile/rwieruch">Developer's Newsletter</a></span>
<hr />
<span>
Found in{' '}
<a href="https://roadtoreact.com/course-details?courseId=TAMING_THE_STATE">
Taming the State in React
</a>
</span>{' '}
|{' '}
<span>
Star the{' '}
<a href="https://github.com/rwieruch/react-firebase-authentication">
Repository
</a>
</span>{' '}
|{' '}
<span>
Receive a{' '}
<a href="https://www.getrevue.co/profile/rwieruch">
Developer's Newsletter
</a>
</span>
</div>
</Router>
);

export default withAuthentication(App);
export default withAuthentication(App);
40 changes: 26 additions & 14 deletions src/components/Navigation/index.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
import React from 'react';
import Link from 'gatsby-link';
import { Link } from 'gatsby';

import AuthUserContext from '../Session/AuthUserContext';
import SignOutButton from '../SignOut';
import * as routes from '../../constants/routes';

const Navigation = () =>
const Navigation = () => (
<AuthUserContext.Consumer>
{authUser => authUser
? <NavigationAuth />
: <NavigationNonAuth />
}
{authUser => (authUser ? <NavigationAuth /> : <NavigationNonAuth />)}
</AuthUserContext.Consumer>
);

const NavigationAuth = () =>
const NavigationAuth = () => (
<ul>
<li><Link to={routes.LANDING}>Landing</Link></li>
<li><Link to={routes.HOME}>Home</Link></li>
<li><Link to={routes.ACCOUNT}>Account</Link></li>
<li><SignOutButton /></li>
<li>
<Link to={routes.LANDING}>Landing</Link>
</li>
<li>
<Link to={routes.HOME}>Home</Link>
</li>
<li>
<Link to={routes.ACCOUNT}>Account</Link>
</li>
<li>
<SignOutButton />
</li>
</ul>
);

const NavigationNonAuth = () =>
const NavigationNonAuth = () => (
<ul>
<li><Link to={routes.LANDING}>Landing</Link></li>
<li><Link to={routes.SIGN_IN}>Sign In</Link></li>
<li>
<Link to={routes.LANDING}>Landing</Link>
</li>
<li>
<Link to={routes.SIGN_IN}>Sign In</Link>
</li>
</ul>
);

export default Navigation;
33 changes: 18 additions & 15 deletions src/components/PasswordChange/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ class PasswordChangeForm extends Component {
this.state = { ...INITIAL_STATE };
}

onSubmit = (event) => {
onSubmit = event => {
const { passwordOne } = this.state;

auth.doPasswordUpdate(passwordOne)
auth
.doPasswordUpdate(passwordOne)
.then(() => {
this.setState(() => ({ ...INITIAL_STATE }));
})
Expand All @@ -31,41 +32,43 @@ class PasswordChangeForm extends Component {
});

event.preventDefault();
}
};

render() {
const {
passwordOne,
passwordTwo,
error,
} = this.state;
const { passwordOne, passwordTwo, error } = this.state;

const isInvalid =
passwordOne !== passwordTwo ||
passwordOne === '';
const isInvalid = passwordOne !== passwordTwo || passwordOne === '';

return (
<form onSubmit={this.onSubmit}>
<input
value={passwordOne}
onChange={event => this.setState(updateByPropertyName('passwordOne', event.target.value))}
onChange={event =>
this.setState(
updateByPropertyName('passwordOne', event.target.value)
)
}
type="password"
placeholder="New Password"
/>
<input
value={passwordTwo}
onChange={event => this.setState(updateByPropertyName('passwordTwo', event.target.value))}
onChange={event =>
this.setState(
updateByPropertyName('passwordTwo', event.target.value)
)
}
type="password"
placeholder="Confirm New Password"
/>
<button disabled={isInvalid} type="submit">
Reset My Password
</button>

{ error && <p>{error.message}</p> }
{error && <p>{error.message}</p>}
</form>
);
}
}

export default PasswordChangeForm;
export default PasswordChangeForm;
28 changes: 13 additions & 15 deletions src/components/PasswordForget/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { Link } from 'gatsby';

import { auth } from '../../firebase';
import * as routes from '../../constants/routes';
Expand All @@ -20,10 +20,11 @@ class PasswordForgetForm extends Component {
this.state = { ...INITIAL_STATE };
}

onSubmit = (event) => {
onSubmit = event => {
const { email } = this.state;

auth.doPasswordReset(email)
auth
.doPasswordReset(email)
.then(() => {
this.setState(() => ({ ...INITIAL_STATE }));
})
Expand All @@ -32,40 +33,37 @@ class PasswordForgetForm extends Component {
});

event.preventDefault();
}
};

render() {
const {
email,
error,
} = this.state;
const { email, error } = this.state;

const isInvalid = email === '';

return (
<form onSubmit={this.onSubmit}>
<input
value={this.state.email}
onChange={event => this.setState(updateByPropertyName('email', event.target.value))}
onChange={event =>
this.setState(updateByPropertyName('email', event.target.value))
}
type="text"
placeholder="Email Address"
/>
<button disabled={isInvalid} type="submit">
Reset My Password
</button>

{ error && <p>{error.message}</p> }
{error && <p>{error.message}</p>}
</form>
);
}
}

const PasswordForgetLink = () =>
const PasswordForgetLink = () => (
<p>
<Link to={routes.PASSWORD_FORGET}>Forgot Password?</Link>
</p>
);

export {
PasswordForgetForm,
PasswordForgetLink,
};
export { PasswordForgetForm, PasswordForgetLink };
2 changes: 1 addition & 1 deletion src/components/Session/AuthUserContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ import React from 'react';

const AuthUserContext = React.createContext(null);

export default AuthUserContext;
export default AuthUserContext;
20 changes: 11 additions & 9 deletions src/components/Session/withAuthentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import AuthUserContext from './AuthUserContext';
import { firebase } from '../../firebase';

const withAuthentication = (Component) =>
const withAuthentication = Component =>
class WithAuthentication extends React.Component {
constructor(props) {
super(props);
Expand All @@ -14,22 +14,24 @@ const withAuthentication = (Component) =>
}

componentDidMount() {
firebase.auth.onAuthStateChanged(authUser => {
authUser
? this.setState(() => ({ authUser }))
: this.setState(() => ({ authUser: null }));
});
if (typeof window !== 'undefined') {
firebase.auth.onAuthStateChanged(authUser => {
authUser
? this.setState(() => ({ authUser }))
: this.setState(() => ({ authUser: null }));
});
}
}

render() {
const { authUser } = this.state;

return (
<AuthUserContext.Provider value={authUser}>
<Component { ...this.props } />
<Component {...this.props} />
</AuthUserContext.Provider>
);
}
}
};

export default withAuthentication;
export default withAuthentication;
20 changes: 11 additions & 9 deletions src/components/Session/withAuthorization.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,28 @@ import AuthUserContext from '../Session/AuthUserContext';
import { firebase } from '../../firebase';
import * as routes from '../../constants/routes';

const withAuthorization = (condition) => (Component) => {
const withAuthorization = condition => Component => {
class WithAuthorization extends React.Component {
componentDidMount() {
firebase.auth.onAuthStateChanged(authUser => {
if (!condition(authUser)) {
this.props.history.push(routes.SIGN_IN);
}
});
if (typeof window !== 'undefined') {
firebase.auth.onAuthStateChanged(authUser => {
if (!condition(authUser)) {
this.props.history.push(routes.SIGN_IN);
}
});
}
}

render() {
return (
<AuthUserContext.Consumer>
{authUser => authUser ? <Component { ...this.props } /> : null}
{authUser => (authUser ? <Component {...this.props} /> : null)}
</AuthUserContext.Consumer>
);
}
}

return withRouter(WithAuthorization);
}
};

export default withAuthorization;
export default withAuthorization;
Loading