Skip to content

Commit

Permalink
feat: add content
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderLapygin committed Feb 12, 2019
1 parent 2f5efa0 commit 7b6e3d7
Show file tree
Hide file tree
Showing 11 changed files with 242 additions and 7 deletions.
9 changes: 2 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
# gatsby-auth

Example of authentication in Gatsby.js with [Reach Router](https://reach.tech/router) with privat client-only routes.

## Under construction
Example of authentication in Gatsby.js with [Reach Router](https://reach.tech/router) and private client-only routes.

## Direct Descendants

Yet absent

## Direct Ancestors
[Mimimalistic Gatsby.js](https://github.com/softspider/gatsby.js)


## Inspired by

- [Gatsby Authentication Demo](https://github.com/gatsbyjs/gatsby/tree/master/examples/simple-auth)
- [Making a site with user authentication](https://www.gatsbyjs.org/docs/authentication-tutorial/)



14 changes: 14 additions & 0 deletions gatsby-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Implement the Gatsby API “onCreatePage”. This is
// called after every page is created.
exports.onCreatePage = async ({ page, actions }) => {
const { createPage } = actions

// page.matchPath is a special key that's used for matching pages
// only on the client.
if (page.path.match(/^\/app/)) {
page.matchPath = "/app/*"

// Update the page.
createPage(page)
}
}
15 changes: 15 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "gatsby-auth-hello-world",
"description": "gatsby-auth hello-world with Reach Router and client-only private routes",
"version": "0.1.0",
"license": "MIT",
"scripts": {
"develop": "gatsby develop",
"start": "npm run develop"
},
"dependencies": {
"gatsby": "^2.0.118",
"react": "^16.8.0",
"react-dom": "^16.8.0"
}
}
12 changes: 12 additions & 0 deletions src/components/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react"

import NavBar from "./nav-bar"

const Layout = ({ children }) => (
<>
<NavBar />
{children}
</>
)

export default Layout
56 changes: 56 additions & 0 deletions src/components/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from "react"
import { navigate } from "gatsby"
import { handleLogin, isLoggedIn } from "../services/auth"

class Login extends React.Component {
state = {
username: ``,
password: ``,
}

handleUpdate = event => {
this.setState({
[event.target.name]: event.target.value,
})
}

handleSubmit = event => {
event.preventDefault()
handleLogin(this.state)
}

render() {
if (isLoggedIn()) {
navigate(`/app/profile`)
}

return (
<>
<h1>Log in</h1>
<form
method="post"
onSubmit={event => {
this.handleSubmit(event)
navigate(`/app/profile`)
}}
>
<label>
Username
<input type="text" name="username" onChange={this.handleUpdate} />
</label>
<label>
Password
<input
type="password"
name="password"
onChange={this.handleUpdate}
/>
</label>
<input type="submit" value="Log In" />
</form>
</>
)
}
}

export default Login
41 changes: 41 additions & 0 deletions src/components/nav-bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from "react"
import { Link, navigate } from "gatsby"
import { getUser, isLoggedIn, logout } from "../services/auth"

export default () => {
const content = { message: "", login: true }
if (isLoggedIn()) {
content.message = `Hello, ${getUser().name}`
} else {
content.message = "You are not logged in"
}
return (
<div
style={{
display: "flex",
flex: "1",
justifyContent: "space-between",
borderBottom: "1px solid #d1c1e0",
}}
>
<span>{content.message}</span>
<nav>
<Link to="/">Home</Link>
{` `}
<Link to="/app/profile">Profile</Link>
{` `}
{isLoggedIn() ? (
<a
href="/"
onClick={event => {
event.preventDefault()
logout(() => navigate(`/app/login`))
}}
>
Logout
</a>
) : null}
</nav>
</div>
)
}
15 changes: 15 additions & 0 deletions src/components/privateRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from "react"
import { navigate } from "gatsby"
import { isLoggedIn } from "../services/auth"

const PrivateRoute = ({ component: Component, location, ...rest }) => {
if (!isLoggedIn() && location.pathname !== `/app/login`) {
// If the user is not logged in, redirect to the login page.
navigate(`/app/login`)
return null
}

return <Component {...rest} />
}

export default PrivateRoute
14 changes: 14 additions & 0 deletions src/components/profile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from "react"
import { getUser } from "../services/auth"

const Profile = () => (
<>
<h1>Your profile</h1>
<ul>
<li>Name: {getUser().name}</li>
<li>E-mail: {getUser().email}</li>
</ul>
</>
)

export default Profile
17 changes: 17 additions & 0 deletions src/pages/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from "react"
import { Router } from "@reach/router"
import Layout from "../components/layout"
import PrivateRoute from "../components/privateRoute"
import Profile from "../components/profile"
import Login from "../components/login"

const App = () => (
<Layout>
<Router>
<PrivateRoute path="/app/profile" component={Profile} />
<Login path="/app/login" />
</Router>
</Layout>
)

export default App
24 changes: 24 additions & 0 deletions src/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react"
import { Link } from "gatsby"
import { getUser, isLoggedIn } from "../services/auth"

import Layout from "../components/layout"

export default () => (
<Layout>
<h1>Hello {isLoggedIn() ? getUser().name : "world"}!</h1>
<p>
{isLoggedIn() ? (
<>
You are logged in, so check your{" "}
<Link to="/app/profile">profile</Link>
</>
) : (
<>
You should <Link to="/app/login">log in</Link> to see restricted
content
</>
)}
</p>
</Layout>
)
32 changes: 32 additions & 0 deletions src/services/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export const isBrowser = () => typeof window !== "undefined"

export const getUser = () =>
isBrowser() && window.localStorage.getItem("gatsbyUser")
? JSON.parse(window.localStorage.getItem("gatsbyUser"))
: {}

const setUser = user =>
window.localStorage.setItem("gatsbyUser", JSON.stringify(user))

export const handleLogin = ({ username, password }) => {
if (username === `john` && password === `pass`) {
return setUser({
username: `john`,
name: `Johnny`,
email: `[email protected]`,
})
}

return false
}

export const isLoggedIn = () => {
const user = getUser()

return !!user.username
}

export const logout = callback => {
setUser({})
callback()
}

0 comments on commit 7b6e3d7

Please sign in to comment.