Database auth is fully fixed and functional except for outbound firebase.

This commit is contained in:
Patrick Fic
2019-12-06 12:05:33 -08:00
parent ab1e4d5424
commit 78c43fa1e5
58 changed files with 8435 additions and 140 deletions

View File

@@ -10,8 +10,8 @@ export default function Auth() {
useEffect(() => {
return firebase.auth().onAuthStateChanged(async user => {
console.log("User in App Container.js: ", user);
if (user) {
console.log('Current User:', user)
const token = await user.getIdToken();
const idTokenResult = await user.getIdTokenResult();
const hasuraClaim =
@@ -24,17 +24,12 @@ export default function Auth() {
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 });
});
}
console.log("#####Logged In. make a gql call to upsert", user);
} else {
setAuthState({ status: "out" });
}

View File

@@ -3,6 +3,7 @@ import { ApolloProvider } from "react-apollo";
import { HttpLink } from "apollo-link-http";
import ApolloClient from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { resolvers, typeDefs } from "../graphql/resolvers";
//Styling imports
import "./App.css";
@@ -18,22 +19,18 @@ const graphqlEndpoint =
"https://bodyshop-dev-db.herokuapp.com/v1/graphql";
export default function App({ authState }) {
console.log("graphqlEndpoint", graphqlEndpoint);
const isIn = authState.status === "in";
const headers = isIn ? { Authorization: `Bearer ${authState.token}` } : {};
const httpLink = new HttpLink({
uri: graphqlEndpoint,
headers
});
const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache()
cache: new InMemoryCache(),
resolvers,
typeDefs
});
client.writeData({
data: initialState
});
@@ -41,7 +38,7 @@ export default function App({ authState }) {
return (
<ApolloProvider client={client}>
<HeaderAppBarContainer />
<SignIn />
{isIn ? null : <SignIn />}
<JobListContainer />
</ApolloProvider>
);

View File

@@ -18,9 +18,11 @@ class HeaderAppBar extends Component {
selectedKeys={selectedNavItem}
mode="horizontal"
>
{navItems.map(navItem => (
{
navItems.map(navItem => (
<Menu.Item key={navItem.title}>{navItem.title}</Menu.Item>
))}
))
}
</Menu>
// <Menu.Item key="mail">

View File

@@ -3,7 +3,6 @@ import { Query } from "react-apollo";
import { gql } from "apollo-boost";
import { Spin, Alert } from "antd";
import HeaderAppBar from "./header-app-bar.component";
const GET_NAV_ITEMS = gql`
@@ -23,16 +22,16 @@ const GET_SELECTED_NAV_ITEM = gql`
const HeaderAppBarContainer = () => (
<Query query={GET_SELECTED_NAV_ITEM}>
{({ loading, error, data: { selectedNavItem } }) => {
console.log("Selected Nav item", selectedNavItem);
return (
<Query query={GET_NAV_ITEMS}>
{({ loading, error, data }) => {
if (loading) return <Spin size="large" />;
if (error) return <Alert message={error.message} />;
const parsedNavItems = JSON.parse(data.masterdata_by_pk.value)
return (
<HeaderAppBar
selectedNavItem={selectedNavItem}
navItems={data.masterdata_by_pk.value}
navItems={parsedNavItems}
/>
);
}}

View File

@@ -1,6 +1,12 @@
import React from "react";
export default function JobList() {
//console.log("JobList props", this.props);
return <div>JobList</div>;
}
export default ({ jobs }) => (
<div>
<span>Job List</span>
<div>
{jobs.map(job => (
<p key={job.est_number}>{job.est_number}</p>
))}
</div>
</div>
);

View File

@@ -8,8 +8,8 @@ import JobList from "./job-list.component";
const GET_JOBS = gql`
query get_jobs {
estimates {
ro_number
jobs {
est_number
}
}
`;
@@ -20,7 +20,8 @@ const JobListContainer = () => (
if (loading) return <Spin size="large" />;
if (error) return <Alert message={error.message} />;
console.log("JobListContainer Data:", data);
return <JobList jobs={data} />;
return <JobList jobs={data.jobs} />;
}}
</Query>
);

View File

@@ -1,6 +1,7 @@
import firebase from "firebase/app";
import "firebase/firestore";
import "firebase/auth";
import "firebase/database"
const config = {
apiKey: "AIzaSyDV9MsSHZmpLtjoaTK_ObvjFaJ-nMSd2KA",

View File

@@ -1,42 +1,31 @@
// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
// response.send("Hello from Firebase!");
// });
// const functions = require("firebase-functions");
// const admin = require("firebase-admin");
// admin.initializeApp(functions.config().firebase);
// // On sign up.
// exports.processSignUp = functions.auth.user().onCreate(user => {
// const customClaims = {
// "https://hasura.io/jwt/claims": {
// "x-hasura-default-role": "user",
// "x-hasura-allowed-roles": ["user"],
// "x-hasura-user-id": user.uid
// }
// };
// return admin
// .auth()
// .setCustomUserClaims(user.uid, customClaims)
// .then(() => {
// // Update real-time database to notify client to force refresh.
// const metadataRef = admin.database().ref("metadata/" + user.uid);
// // Set the refresh time to the current UTC timestamp.
// // This will be captured on the client to force a token refresh.
// return metadataRef.set({ refreshTime: new Date().getTime() });
// })
// .catch(error => {
// console.log(error);
// });
// });
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
const fetch = require("node-fetch");
//Todo: Move this to an environment parameter.
const GRAPHQL_ENDPOINT = functions.config().auth.graphql_endpoint;
const HASURA_SECRET_ADMIN_KEY = functions.config().auth.hasura_secret_admin_key;
const UPSERT_USER = `
mutation upsert_user($authEmail: String!, $authToken: String!) {
insert_users(
objects: [
{
email:$authEmail,
authid:$authToken
}
],
on_conflict: {
constraint: users_pkey,
update_columns: [authid]
}
) {
returning {
authid
}
}
}
`;
// On sign up.
exports.processSignUp = functions.auth.user().onCreate(user => {
@@ -44,32 +33,51 @@ exports.processSignUp = functions.auth.user().onCreate(user => {
// Check if user meets role criteria:
// Your custom logic here: to decide what roles and other `x-hasura-*` should the user get
let customClaims;
if (user.email && user.email.indexOf('@thinkimex.com') !== -1) {
if (user.email && user.email.indexOf("@thinkimex.com") !== -1) {
customClaims = {
'https://hasura.io/jwt/claims': {
'x-hasura-default-role': 'admin',
'x-hasura-allowed-roles': ['user', 'admin'],
'x-hasura-user-id': user.uid
}
};
}
else {
customClaims = {
'https://hasura.io/jwt/claims': {
'x-hasura-default-role': 'user',
'x-hasura-allowed-roles': ['user'],
'x-hasura-user-id': user.uid
"https://hasura.io/jwt/claims": {
"x-hasura-default-role": "admin",
"x-hasura-allowed-roles": ["user", "admin"],
"x-hasura-user-id": user.uid
}
};
} else {
customClaims = {
"https://hasura.io/jwt/claims": {
"x-hasura-default-role": "user",
"x-hasura-allowed-roles": ["user"],
"x-hasura-user-id": user.uid
}
};
}
//update the AuthId in the graphql server.
fetch(GRAPHQL_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
"x-hasura-admin-secret": HASURA_SECRET_ADMIN_KEY
},
body: JSON.stringify({
query: UPSERT_USER,
variables: { authEmail: user.email, authToken: user.uid }
})
});
// .then(r => r.json())
// .then(data => {
// console.log("data returned:", data);
// });
// Set custom user claims on this newly created user.
return admin.auth().setCustomUserClaims(user.uid, customClaims)
return admin
.auth()
.setCustomUserClaims(user.uid, customClaims)
.then(() => {
// Update real-time database to notify client to force refresh.
const metadataRef = admin.database().ref("metadata/" + user.uid);
// Set the refresh time to the current UTC timestamp.
// This will be captured on the client to force a token refresh.
return metadataRef.set({refreshTime: new Date().getTime()});
return metadataRef.set({ refreshTime: new Date().getTime() });
})
.catch(error => {
console.log(error);

4
firebase/readme.md Normal file
View File

@@ -0,0 +1,4 @@
Must set the environment variables using:
firebase functions:config:set auth.graphql_endpoint="https://bodyshop-dev-db.herokuapp.com/v1/graphql" auth.hasura_secret_admin_key="Dev-BodyShopAppBySnaptSoftware!"

View File

@@ -1,11 +0,0 @@
- args:
sql: CREATE TABLE "public"."associations"("shopid" uuid NOT NULL, "useremail"
text NOT NULL, "active" boolean NOT NULL DEFAULT false, PRIMARY KEY ("shopid","useremail")
, FOREIGN KEY ("shopid") REFERENCES "public"."bodyshops"("shopid") ON UPDATE
restrict ON DELETE restrict, FOREIGN KEY ("useremail") REFERENCES "public"."users"("email")
ON UPDATE restrict ON DELETE restrict);
type: run_sql
- args:
name: associations
schema: public
type: add_existing_table_or_view

View File

@@ -1,13 +0,0 @@
- args:
sql: CREATE EXTENSION IF NOT EXISTS pgcrypto;
type: run_sql
- args:
sql: CREATE TABLE "public"."jobs"("jobid" uuid NOT NULL DEFAULT gen_random_uuid(),
"ro_number" text NOT NULL, "est_number" text NOT NULL, "shopid" uuid NOT NULL,
PRIMARY KEY ("jobid") , FOREIGN KEY ("shopid") REFERENCES "public"."bodyshops"("shopid")
ON UPDATE restrict ON DELETE restrict);
type: run_sql
- args:
name: jobs
schema: public
type: add_existing_table_or_view

View File

@@ -0,0 +1,3 @@
- args:
sql: DROP TABLE "public"."navitems"
type: run_sql

View File

@@ -0,0 +1,8 @@
- args:
sql: CREATE TABLE "public"."navitems"("key" text NOT NULL, "value" text NOT NULL,
PRIMARY KEY ("key") );
type: run_sql
- args:
name: navitems
schema: public
type: add_existing_table_or_view

View File

@@ -0,0 +1,3 @@
- args:
sql: DROP TABLE "public"."navitems"
type: run_sql

View File

@@ -1,5 +1,5 @@
- args:
sql: CREATE TABLE "public"."masterdata"("key" text NOT NULL, "value" jsonb NOT
sql: CREATE TABLE "public"."masterdata"("key" text NOT NULL, "value" text NOT
NULL, PRIMARY KEY ("key") );
type: run_sql
- args:

View File

@@ -0,0 +1,6 @@
- args:
role: anonymous
table:
name: masterdata
schema: public
type: drop_select_permission

View File

@@ -0,0 +1,11 @@
- args:
permission:
allow_aggregations: false
columns: []
filter: {}
limit: null
role: anonymous
table:
name: masterdata
schema: public
type: create_select_permission

View File

@@ -2,8 +2,8 @@
sql: CREATE EXTENSION IF NOT EXISTS pgcrypto;
type: run_sql
- args:
sql: CREATE TABLE "public"."bodyshops"("shopid" uuid NOT NULL DEFAULT gen_random_uuid(),
"name" text NOT NULL, PRIMARY KEY ("shopid") );
sql: CREATE TABLE "public"."bodyshops"("id" uuid NOT NULL DEFAULT gen_random_uuid(),
"shopname" text NOT NULL, PRIMARY KEY ("id") );
type: run_sql
- args:
name: bodyshops

View File

@@ -0,0 +1,14 @@
- args:
sql: CREATE EXTENSION IF NOT EXISTS pgcrypto;
type: run_sql
- args:
sql: CREATE TABLE "public"."associations"("id" uuid NOT NULL DEFAULT gen_random_uuid(),
"shopid" uuid NOT NULL, "useremail" text NOT NULL, PRIMARY KEY ("id") , FOREIGN
KEY ("shopid") REFERENCES "public"."bodyshops"("id") ON UPDATE restrict ON DELETE
restrict, FOREIGN KEY ("useremail") REFERENCES "public"."users"("email") ON
UPDATE restrict ON DELETE restrict);
type: run_sql
- args:
name: associations
schema: public
type: add_existing_table_or_view

View File

@@ -0,0 +1,24 @@
- args:
relationship: user
table:
name: associations
schema: public
type: drop_relationship
- args:
relationship: bodyshop
table:
name: associations
schema: public
type: drop_relationship
- args:
relationship: associations
table:
name: bodyshops
schema: public
type: drop_relationship
- args:
relationship: associations
table:
name: users
schema: public
type: drop_relationship

View File

@@ -0,0 +1,40 @@
- args:
name: user
table:
name: associations
schema: public
using:
foreign_key_constraint_on: useremail
type: create_object_relationship
- args:
name: bodyshop
table:
name: associations
schema: public
using:
foreign_key_constraint_on: shopid
type: create_object_relationship
- args:
name: associations
table:
name: bodyshops
schema: public
using:
foreign_key_constraint_on:
column: shopid
table:
name: associations
schema: public
type: create_array_relationship
- args:
name: associations
table:
name: users
schema: public
using:
foreign_key_constraint_on:
column: useremail
table:
name: associations
schema: public
type: create_array_relationship

View File

@@ -0,0 +1,19 @@
- args:
sql: CREATE EXTENSION IF NOT EXISTS pgcrypto;
type: run_sql
- args:
sql: "CREATE TABLE \"public\".\"jobs\"(\"id\" uuid NOT NULL DEFAULT gen_random_uuid(),
\"created_at\" timestamptz NOT NULL DEFAULT now(), \"updated_at\" timestamptz
NOT NULL DEFAULT now(), \"shopid\" uuid NOT NULL, \"est_number\" text NOT NULL,
PRIMARY KEY (\"id\") , FOREIGN KEY (\"shopid\") REFERENCES \"public\".\"bodyshops\"(\"id\")
ON UPDATE restrict ON DELETE restrict);\nCREATE OR REPLACE FUNCTION \"public\".\"set_current_timestamp_updated_at\"()\nRETURNS
TRIGGER AS $$\nDECLARE\n _new record;\nBEGIN\n _new := NEW;\n _new.\"updated_at\"
= NOW();\n RETURN _new;\nEND;\n$$ LANGUAGE plpgsql;\nCREATE TRIGGER \"set_public_jobs_updated_at\"\nBEFORE
UPDATE ON \"public\".\"jobs\"\nFOR EACH ROW\nEXECUTE PROCEDURE \"public\".\"set_current_timestamp_updated_at\"();\nCOMMENT
ON TRIGGER \"set_public_jobs_updated_at\" ON \"public\".\"jobs\" \nIS 'trigger
to set value of column \"updated_at\" to current timestamp on row update';\n"
type: run_sql
- args:
name: jobs
schema: public
type: add_existing_table_or_view

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: users
schema: public
type: drop_select_permission

View File

@@ -0,0 +1,13 @@
- args:
permission:
allow_aggregations: false
columns:
- authid
- email
filter: {}
limit: null
role: user
table:
name: users
schema: public
type: create_select_permission

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: users
schema: public
type: drop_update_permission

View File

@@ -0,0 +1,13 @@
- args:
permission:
columns: []
filter: {}
localPresets:
- key: ""
value: ""
set: {}
role: user
table:
name: users
schema: public
type: create_update_permission

View File

@@ -0,0 +1,17 @@
- args:
role: anonymous
table:
name: masterdata
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: false
columns: []
computed_fields: []
filter: {}
role: anonymous
table:
name: masterdata
schema: public
type: create_select_permission

View File

@@ -0,0 +1,19 @@
- args:
role: anonymous
table:
name: masterdata
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: false
columns:
- key
- value
computed_fields: []
filter: {}
role: anonymous
table:
name: masterdata
schema: public
type: create_select_permission

View File

@@ -0,0 +1,12 @@
- args:
relationship: jobs
table:
name: bodyshops
schema: public
type: drop_relationship
- args:
relationship: bodyshop
table:
name: jobs
schema: public
type: drop_relationship

View File

@@ -0,0 +1,20 @@
- args:
name: jobs
table:
name: bodyshops
schema: public
using:
foreign_key_constraint_on:
column: shopid
table:
name: jobs
schema: public
type: create_array_relationship
- args:
name: bodyshop
table:
name: jobs
schema: public
using:
foreign_key_constraint_on: shopid
type: create_object_relationship

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: jobs
schema: public
type: drop_insert_permission

View File

@@ -0,0 +1,24 @@
- args:
permission:
allow_upsert: true
check:
bodyshop:
associations:
user:
authid:
_eq: X-Hasura-User-Id
columns:
- id
- created_at
- updated_at
- shopid
- est_number
localPresets:
- key: ""
value: ""
set: {}
role: user
table:
name: jobs
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: jobs
schema: public
type: drop_select_permission

View File

@@ -0,0 +1,21 @@
- args:
permission:
allow_aggregations: false
columns:
- est_number
- created_at
- updated_at
- id
- shopid
filter:
bodyshop:
associations:
user:
authid:
_eq: X-Hasura-User-Id
limit: null
role: user
table:
name: jobs
schema: public
type: create_select_permission

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: jobs
schema: public
type: drop_update_permission

View File

@@ -0,0 +1,23 @@
- args:
permission:
columns:
- est_number
- created_at
- updated_at
- id
- shopid
filter:
bodyshop:
associations:
user:
authid:
_eq: X-Hasura-User-Id
localPresets:
- key: ""
value: ""
set: {}
role: user
table:
name: jobs
schema: public
type: create_update_permission

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: jobs
schema: public
type: drop_delete_permission

View File

@@ -0,0 +1,13 @@
- args:
permission:
filter:
bodyshop:
associations:
user:
authid:
_eq: X-Hasura-User-Id
role: user
table:
name: jobs
schema: public
type: create_delete_permission

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: bodyshops
schema: public
type: drop_select_permission

View File

@@ -0,0 +1,17 @@
- args:
permission:
allow_aggregations: false
columns:
- id
- shopname
filter:
associations:
user:
authid:
_eq: X-Hasura-User-Id
limit: null
role: user
table:
name: bodyshops
schema: public
type: create_select_permission

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: bodyshops
schema: public
type: drop_update_permission

View File

@@ -0,0 +1,18 @@
- args:
permission:
columns:
- shopname
filter:
associations:
user:
authid:
_eq: X-Hasura-User-Id
localPresets:
- key: ""
value: ""
set: {}
role: user
table:
name: bodyshops
schema: public
type: create_update_permission

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: associations
schema: public
type: drop_select_permission

View File

@@ -0,0 +1,17 @@
- args:
permission:
allow_aggregations: false
columns:
- id
- shopid
- useremail
filter:
user:
authid:
_eq: X-Hasura-User-Id
limit: null
role: user
table:
name: associations
schema: public
type: create_select_permission

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: masterdata
schema: public
type: drop_select_permission

View File

@@ -0,0 +1,11 @@
- args:
permission:
allow_aggregations: false
columns: []
filter: {}
limit: null
role: user
table:
name: masterdata
schema: public
type: create_select_permission

View File

@@ -0,0 +1,17 @@
- args:
role: user
table:
name: masterdata
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: false
columns: []
computed_fields: []
filter: {}
role: user
table:
name: masterdata
schema: public
type: create_select_permission

View File

@@ -0,0 +1,19 @@
- args:
role: user
table:
name: masterdata
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: false
columns:
- key
- value
computed_fields: []
filter: {}
role: user
table:
name: masterdata
schema: public
type: create_select_permission

5046
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -20,10 +20,13 @@
"cors": "2.8.5",
"dotenv": "7.0.0",
"express": "^4.16.4",
"express-sslify": "^1.2.0"
"express-sslify": "^1.2.0",
"firebase-tools": "^7.9.0"
},
"devDependencies": {
"concurrently": "^4.0.1",
"eslint": "^6.7.2",
"eslint-plugin-promise": "^4.2.1",
"hasura-cli": "^1.0.0-beta.10"
}
}

2856
yarn.lock

File diff suppressed because it is too large Load Diff