Refactored app.js and index.js to follow hasura examples of managing state. Now using hooks for user auth and only user auth.
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
API_URL=https://bodyshop-dev-db.herokuapp.com/v1/graphql
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "bodyshop",
|
"name": "bodyshop",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "Copyright Snapt Software (C) 2019",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"antd": "^3.26.0",
|
"antd": "^3.26.0",
|
||||||
"apollo-boost": "^0.4.4",
|
"apollo-boost": "^0.4.4",
|
||||||
|
|||||||
1
client/src/.env
Normal file
1
client/src/.env
Normal file
@@ -0,0 +1 @@
|
|||||||
|
REACT_APP_GRAPHQL_ENDPOINT=https://bodyshop-dev-db.herokuapp.com/v1/graphql
|
||||||
@@ -1,36 +1,73 @@
|
|||||||
import React from "react";
|
//Baselined on https://blog.hasura.io/authentication-and-authorization-using-hasura-and-firebase/
|
||||||
import { Mutation, Query } from "react-apollo";
|
|
||||||
import { gql } from "apollo-boost";
|
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import firebase from "../firebase/firebase.utils";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
|
import { Spin } from "antd";
|
||||||
|
|
||||||
const SET_CURRENT_USER = gql`
|
export default function Auth() {
|
||||||
mutation SetCurrentUser($user: User!) {
|
const [authState, setAuthState] = useState({ status: "loading" });
|
||||||
setCurrentUser(user: $user) @client
|
|
||||||
|
useEffect(() => {
|
||||||
|
return firebase.auth().onAuthStateChanged(async user => {
|
||||||
|
console.log("user", user);
|
||||||
|
if (user) {
|
||||||
|
const token = await user.getIdToken();
|
||||||
|
const idTokenResult = await user.getIdTokenResult();
|
||||||
|
const hasuraClaim =
|
||||||
|
idTokenResult.claims["https://hasura.io/jwt/claims"];
|
||||||
|
|
||||||
|
if (hasuraClaim) {
|
||||||
|
setAuthState({ status: "in", user, token });
|
||||||
|
} else {
|
||||||
|
// Check if refresh is required.
|
||||||
|
const metadataRef = firebase
|
||||||
|
.database()
|
||||||
|
.ref("metadata/" + user.uid + "/refreshTime");
|
||||||
|
|
||||||
|
metadataRef.on("value", async () => {
|
||||||
|
// Force refresh to pick up the latest custom claims changes.
|
||||||
|
const token = await user.getIdToken(true);
|
||||||
|
setAuthState({ status: "in", user, token });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setAuthState({ status: "out" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const signOut = async () => {
|
||||||
|
try {
|
||||||
|
setAuthState({ status: "loading" });
|
||||||
|
await firebase.auth().signOut();
|
||||||
|
setAuthState({ status: "out" });
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let content;
|
||||||
|
if (authState.status === "loading") {
|
||||||
|
content = <Spin size="large" />;
|
||||||
|
} else {
|
||||||
|
content = (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
{authState.status === "in" ? (
|
||||||
|
<div>
|
||||||
|
<h2>Welcome, {authState.user.displayName}</h2>
|
||||||
|
<button onClick={signOut}>Sign out</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div>Sign in</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<App authState={authState} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
`;
|
|
||||||
|
|
||||||
const GET_CURRENT_USER = gql`
|
return <div className="auth">{content}</div>;
|
||||||
{
|
}
|
||||||
currentUser @client
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const AppContainer = () => (
|
|
||||||
<Query query={GET_CURRENT_USER}>
|
|
||||||
{({ data: { currentUser } }) => (
|
|
||||||
<Mutation mutation={SET_CURRENT_USER}>
|
|
||||||
{setCurrentUser => (
|
|
||||||
<App
|
|
||||||
currentUser={currentUser}
|
|
||||||
setCurrentUser={user => {
|
|
||||||
setCurrentUser({ variables: { user } });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Mutation>
|
|
||||||
)}
|
|
||||||
</Query>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default AppContainer;
|
|
||||||
|
|||||||
@@ -1,24 +1 @@
|
|||||||
@import '~antd/dist/antd.css';
|
@import '~antd/dist/antd.css';
|
||||||
|
|
||||||
.App {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-logo {
|
|
||||||
height: 40vmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-header {
|
|
||||||
background-color: #282c34;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: calc(10px + 2vmin);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-link {
|
|
||||||
color: #09d3ac;
|
|
||||||
}
|
|
||||||
@@ -1,88 +1,46 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { ApolloProvider } from "react-apollo";
|
||||||
|
import { gql } from "apollo-boost";
|
||||||
|
import { HttpLink } from "apollo-link-http";
|
||||||
|
import { getMainDefinition } from "apollo-utilities";
|
||||||
|
import ApolloClient from "apollo-client";
|
||||||
|
import { InMemoryCache } from "apollo-cache-inmemory";
|
||||||
|
|
||||||
|
//Styling imports
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
|
|
||||||
import { auth, createUserProfileDocument } from "../firebase/firebase.utils";
|
|
||||||
// import { gql } from "apollo-boost";
|
|
||||||
|
|
||||||
import firebase from "../firebase/firebase.utils"
|
|
||||||
|
|
||||||
import HeaderAppBar from "../components/header-app-bar/header-app-bar.component";
|
import HeaderAppBar from "../components/header-app-bar/header-app-bar.component";
|
||||||
import SignIn from "../components/sign-in/sign-in.component";
|
import SignIn from "../components/sign-in/sign-in.component";
|
||||||
|
import initialState from "../graphql/initial-state";
|
||||||
|
|
||||||
// const SET_CURRENT_USER = gql`
|
const graphqlEndpoint = process.env.REACT_APP_GRAPHQL_ENDPOINT || "https://bodyshop-dev-db.herokuapp.com/v1/graphql";
|
||||||
// mutation SetCurrentUser($user: User!) {
|
|
||||||
// setCurrentUser(user: $user) @client
|
|
||||||
// }
|
|
||||||
// `;
|
|
||||||
|
|
||||||
// const GET_CURRENT_USER = gql`
|
export default function App({ authState }) {
|
||||||
// {
|
console.log("graphqlEndpoint", graphqlEndpoint);
|
||||||
// currentUser @client
|
|
||||||
// }
|
|
||||||
// `;
|
|
||||||
|
|
||||||
class App extends React.Component {
|
const isIn = authState.status === "in";
|
||||||
unsubscribeFromAuth = null;
|
|
||||||
|
|
||||||
componentDidMount() {
|
const headers = isIn ? { Authorization: `Bearer ${authState.token}` } : {};
|
||||||
const { setCurrentUser } = this.props;
|
|
||||||
this.unsubscribeFromAuth = auth.onAuthStateChanged(async userAuth => {
|
|
||||||
if (userAuth) {
|
|
||||||
const token = await userAuth.getIdToken();
|
|
||||||
console.log("User auth token", token);
|
|
||||||
const idTokenResult = await userAuth.getIdTokenResult();
|
|
||||||
const hasuraClaim =
|
|
||||||
idTokenResult.claims["https://hasura.io/jwt/claims"];
|
|
||||||
|
|
||||||
if (hasuraClaim) {
|
const httpLink = new HttpLink({
|
||||||
console.log("status should be in1", hasuraClaim);
|
uri: graphqlEndpoint,
|
||||||
//setAuthState({ status: "in", user, token });
|
headers
|
||||||
} else {
|
});
|
||||||
// Check if refresh is required.
|
|
||||||
const metadataRef = firebase
|
|
||||||
.database()
|
|
||||||
.ref("metadata/" + userAuth.uid + "/refreshTime");
|
|
||||||
|
|
||||||
metadataRef.on("value", async () => {
|
const client = new ApolloClient({
|
||||||
// Force refresh to pick up the latest custom claims changes.
|
link: httpLink,
|
||||||
const token = await userAuth.getIdToken(true);
|
cache: new InMemoryCache()
|
||||||
//setAuthState({ status: "in", user, token });
|
});
|
||||||
console.log("status should be in2");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("else statement.")
|
|
||||||
//setAuthState({ status: "out" });
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (userAuth) {
|
client.writeData({
|
||||||
// const userRef = await createUserProfileDocument(userAuth);
|
data: initialState
|
||||||
|
});
|
||||||
|
|
||||||
// userRef.onSnapshot(snapShot => {
|
console.log(client)
|
||||||
// setCurrentUser({
|
return (
|
||||||
// id: snapShot.id,
|
<ApolloProvider client={client}>
|
||||||
// ...snapShot.data()
|
<HeaderAppBar />
|
||||||
// });
|
<SignIn />
|
||||||
// });
|
</ApolloProvider>
|
||||||
// } else {
|
);
|
||||||
// setCurrentUser(userAuth);
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this.unsubscribeFromAuth();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<HeaderAppBar />
|
|
||||||
|
|
||||||
{this.props.currentUser ? "Logged In!" : <SignIn />}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
export default {
|
export default {
|
||||||
currentSelectedNavItem: null,
|
currentSelectedNavItem: "wat",
|
||||||
currentUser: null,
|
|
||||||
token: null
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ import { InMemoryCache } from "apollo-cache-inmemory";
|
|||||||
import { ApolloClient } from "apollo-boost";
|
import { ApolloClient } from "apollo-boost";
|
||||||
import { typeDefs, resolvers } from "./graphql/resolvers";
|
import { typeDefs, resolvers } from "./graphql/resolvers";
|
||||||
import initialState from "./graphql/initial-state";
|
import initialState from "./graphql/initial-state";
|
||||||
// require('dotenv').config()
|
|
||||||
|
|
||||||
import * as serviceWorker from "./serviceWorker";
|
import * as serviceWorker from "./serviceWorker";
|
||||||
|
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import { default as App } from "./App/App.container";
|
import { default as App } from "./App/App.container";
|
||||||
|
|
||||||
|
require("dotenv").config();
|
||||||
|
|
||||||
const httpLink = createHttpLink({
|
const httpLink = createHttpLink({
|
||||||
uri: "https://bodyshop-dev-db.herokuapp.com/v1/graphql"
|
uri: "https://bodyshop-dev-db.herokuapp.com/v1/graphql"
|
||||||
});
|
});
|
||||||
|
|||||||
843
client/yarn.lock
843
client/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
|||||||
|
- args:
|
||||||
|
sql: DROP TABLE "public"."masterdata"
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
- args:
|
||||||
|
sql: CREATE TABLE "public"."masterdata"("key" text NOT NULL, "value" jsonb NOT
|
||||||
|
NULL, PRIMARY KEY ("key") , UNIQUE ("key"));
|
||||||
|
type: run_sql
|
||||||
|
- args:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: add_existing_table_or_view
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
- args:
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
allow_upsert: true
|
||||||
|
check: {}
|
||||||
|
columns: []
|
||||||
|
localPresets:
|
||||||
|
- key: ""
|
||||||
|
value: ""
|
||||||
|
set: {}
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
- args:
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check: {}
|
||||||
|
columns: []
|
||||||
|
localPresets:
|
||||||
|
- key: ""
|
||||||
|
value: ""
|
||||||
|
set: {}
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
- args:
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check: {}
|
||||||
|
columns:
|
||||||
|
- value
|
||||||
|
- key
|
||||||
|
localPresets:
|
||||||
|
- key: ""
|
||||||
|
value: ""
|
||||||
|
set: {}
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
- args:
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check: {}
|
||||||
|
columns: []
|
||||||
|
localPresets:
|
||||||
|
- key: ""
|
||||||
|
value: ""
|
||||||
|
set: {}
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
- args:
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check: {}
|
||||||
|
columns: []
|
||||||
|
localPresets:
|
||||||
|
- key: ""
|
||||||
|
value: ""
|
||||||
|
set: {}
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check: {}
|
||||||
|
columns: []
|
||||||
|
localPresets:
|
||||||
|
- key: ""
|
||||||
|
value: ""
|
||||||
|
set: {}
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
- args:
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: drop_select_permission
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
allow_aggregations: false
|
||||||
|
columns:
|
||||||
|
- value
|
||||||
|
- key
|
||||||
|
filter: {}
|
||||||
|
limit: null
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: create_select_permission
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
- args:
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: drop_select_permission
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
allow_aggregations: false
|
||||||
|
columns:
|
||||||
|
- value
|
||||||
|
- key
|
||||||
|
filter: {}
|
||||||
|
limit: null
|
||||||
|
role: anonymous
|
||||||
|
table:
|
||||||
|
name: masterdata
|
||||||
|
schema: public
|
||||||
|
type: create_select_permission
|
||||||
Reference in New Issue
Block a user