From a2b0a6a90a8ddb5f773a89466bc59e97a4551f1c Mon Sep 17 00:00:00 2001 From: shamsmosowi Date: Wed, 8 Sep 2021 22:37:29 +1000 Subject: [PATCH 1/2] rowyRun --- src/App.tsx | 11 ++--- .../Settings/ProjectSettings/CloudRun.tsx | 2 +- src/constants/runRoutes.ts | 9 ++++ src/contexts/ProjectContext.tsx | 42 +++++++++++++++++++ src/firebase/callables.ts | 4 -- src/pages/Auth/ImpersonatorAuth.tsx | 24 +++++++---- 6 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 src/constants/runRoutes.ts diff --git a/src/App.tsx b/src/App.tsx index f613cefc..ac519f01 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -66,11 +66,6 @@ export default function App() { path={routes.auth} render={() => } /> - } - /> ( + } + /> updateSettings({ cloudRunUrl: e.target.value })} fullWidth placeholder="https://.run.app" diff --git a/src/constants/runRoutes.ts b/src/constants/runRoutes.ts new file mode 100644 index 00000000..9b999e9b --- /dev/null +++ b/src/constants/runRoutes.ts @@ -0,0 +1,9 @@ +export type RunRoute = { + path: string; + method: "POST" | "GET"; +}; +export const RunRoutes: { [key: string]: RunRoute } = { + impersonateUser: { path: "/impersonateUser", method: "GET" }, + version: { path: "/version", method: "GET" }, + listCollections: { path: "/listCollections", method: "GET" }, +}; diff --git a/src/contexts/ProjectContext.tsx b/src/contexts/ProjectContext.tsx index ab104257..b4f651d8 100644 --- a/src/contexts/ProjectContext.tsx +++ b/src/contexts/ProjectContext.tsx @@ -11,6 +11,7 @@ import { useAppContext } from "./AppContext"; import { SideDrawerRef } from "components/SideDrawer"; import { ColumnMenuRef } from "components/Table/ColumnMenu"; import { ImportWizardRef } from "components/Wizards/ImportWizard"; +import { RunRoute } from "@src/constants/runRoutes"; export type Table = { id: string; @@ -66,6 +67,12 @@ interface ProjectContextProps { columnMenuRef: React.MutableRefObject; // A ref ot the import wizard. Prevents unnecessary re-renders importWizardRef: React.MutableRefObject; + + rowyRun: (args: { + route: RunRoute; + body?: any; + params: string[]; + }) => Promise; } const ProjectContext = React.createContext>({}); @@ -96,6 +103,7 @@ export const ProjectContextProvider: React.FC = ({ children }) => { const [userClaims, setUserClaims] = useState(); const { currentUser } = useAppContext(); + const [authToken, setAuthToken] = useState(""); useEffect(() => { const { tables } = settings; if (tables && userRoles && !sections) { @@ -131,6 +139,7 @@ export const ProjectContextProvider: React.FC = ({ children }) => { useEffect(() => { if (currentUser && !userClaims) { currentUser.getIdTokenResult(true).then((results) => { + setAuthToken(results.token); setUserRoles(results.claims.roles || []); setUserClaims(results.claims); }); @@ -172,6 +181,38 @@ export const ProjectContextProvider: React.FC = ({ children }) => { ); }; + // rowyRun access + const rowyRun = async ({ + route, + body, + params, + }: { + route: RunRoute; + body?: any; + params: string[]; + }) => { + const { method, path } = route; + let url = + //'http://localhost:8080' + settings.doc.rowyRunUrl + route.path; + if (params && params.length > 0) url = url + "/" + params.join("/"); + console.log(url, settings); + const response = await fetch(url, { + method: method, // *GET, POST, PUT, DELETE, etc. + mode: "cors", // no-cors, *cors, same-origin + cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached + credentials: "same-origin", // include, *same-origin, omit + headers: { + "Content-Type": "application/json", + // 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: "Bearer " + authToken, + }, + redirect: "follow", // manual, *follow, error + referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url + body: method !== "GET" ? JSON.stringify(body) : null, // body data type must match "Content-Type" header + }); + return response.json(); // parses JSON response into native JavaScript objects + }; // A ref to the data grid. Contains data grid functions const dataGridRef = useRef(null); const sideDrawerRef = useRef(); @@ -193,6 +234,7 @@ export const ProjectContextProvider: React.FC = ({ children }) => { sideDrawerRef, columnMenuRef, importWizardRef, + rowyRun, }} > {children} diff --git a/src/firebase/callables.ts b/src/firebase/callables.ts index 7f582dea..24af74f6 100644 --- a/src/firebase/callables.ts +++ b/src/firebase/callables.ts @@ -1,7 +1,6 @@ import { functions } from "./index"; export enum CLOUD_FUNCTIONS { - ImpersonatorAuth = "callable-ImpersonatorAuth", getAlgoliaSearchKey = "getAlgoliaSearchKey", } @@ -26,8 +25,5 @@ export const cloudFunction = ( }); }); -export const ImpersonatorAuth = (email: string) => - functions.httpsCallable(CLOUD_FUNCTIONS.ImpersonatorAuth)({ email }); - export const getAlgoliaSearchKey = (index: string) => functions.httpsCallable(CLOUD_FUNCTIONS.getAlgoliaSearchKey)({ index }); diff --git a/src/pages/Auth/ImpersonatorAuth.tsx b/src/pages/Auth/ImpersonatorAuth.tsx index fe177ac9..2b08ee26 100644 --- a/src/pages/Auth/ImpersonatorAuth.tsx +++ b/src/pages/Auth/ImpersonatorAuth.tsx @@ -7,15 +7,17 @@ import AuthLayout from "components/Auth/AuthLayout"; import FirebaseUi from "components/Auth/FirebaseUi"; import { signOut } from "utils/auth"; -import { ImpersonatorAuth } from "../../firebase/callables"; import { auth } from "../../firebase"; +import { useProjectContext } from "@src/contexts/ProjectContext"; +import { RunRoutes } from "@src/constants/runRoutes"; export default function ImpersonatorAuthPage() { const { enqueueSnackbar } = useSnackbar(); + const { rowyRun } = useProjectContext(); useEffect(() => { //sign out user on initial load - signOut(); + // signOut(); }, []); const [loading, setLoading] = useState(false); @@ -23,15 +25,23 @@ export default function ImpersonatorAuthPage() { const [email, setEmail] = useState(""); const handleAuth = async (email: string) => { + console.log("!rowyRun"); + + if (!rowyRun) return; + console.log("rowyRun"); setLoading(true); - const resp = await ImpersonatorAuth(email); + const resp = await rowyRun({ + route: RunRoutes.impersonateUser, + params: [email], + }); + console.log(resp); setLoading(false); - if (resp.data.success) { - enqueueSnackbar(resp.data.message, { variant: "success" }); - await auth.signInWithCustomToken(resp.data.jwt); + if (resp.success) { + enqueueSnackbar(resp.message, { variant: "success" }); + await auth.signInWithCustomToken(resp.token); window.location.href = "/"; } else { - enqueueSnackbar(resp.data.message, { variant: "error" }); + enqueueSnackbar(resp.error.message, { variant: "error" }); } }; From 72efdc5b7708a7d2f79fbe812ac6c617df82f1bf Mon Sep 17 00:00:00 2001 From: shamsmosowi Date: Thu, 9 Sep 2021 08:13:49 +1000 Subject: [PATCH 2/2] actionScript --- src/components/fields/Action/ActionFab.tsx | 55 +++++++++++++--------- src/constants/runRoutes.ts | 1 + src/contexts/ProjectContext.tsx | 4 +- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/components/fields/Action/ActionFab.tsx b/src/components/fields/Action/ActionFab.tsx index 616e392c..db9eb782 100644 --- a/src/components/fields/Action/ActionFab.tsx +++ b/src/components/fields/Action/ActionFab.tsx @@ -12,6 +12,7 @@ import { cloudFunction } from "firebase/callables"; import { formatPath } from "utils/fns"; import { useConfirmation } from "components/ConfirmationDialog"; import { useActionParams } from "./FormDialog/Context"; +import { RunRoutes } from "@src/constants/runRoutes"; const replacer = (data: any) => (m: string, key: string) => { const objKey = key.split(":")[0]; @@ -49,7 +50,7 @@ export default function ActionFab({ const { requestConfirmation } = useConfirmation(); const { enqueueSnackbar } = useSnackbar(); const { requestParams } = useActionParams(); - const { tableState } = useProjectContext(); + const { tableState, rowyRun } = useProjectContext(); const { ref } = row; const { config } = column as any; @@ -64,7 +65,8 @@ export default function ActionFab({ const callableName: string = (column as any).callableName ?? config.callableName ?? "actionScript"; - const handleRun = (actionParams = null) => { + const handleRun = async (actionParams = null) => { + if (!rowyRun) return; setIsRunning(true); const data = { @@ -74,27 +76,34 @@ export default function ActionFab({ schemaDocPath: formatPath(tableState?.tablePath ?? ""), actionParams, }; - cloudFunction( - callableName, - data, - async (response) => { - const { message, cellValue, success } = response.data; - setIsRunning(false); - enqueueSnackbar(JSON.stringify(message), { - variant: success ? "success" : "error", - }); - if (cellValue && cellValue.status) { - await ref.update({ - [column.key]: cellValue, - }); - } - }, - (error) => { - console.error("ERROR", callableName, error); - setIsRunning(false); - enqueueSnackbar(JSON.stringify(error), { variant: "error" }); - } - ); + + const resp = await rowyRun({ + route: RunRoutes.actionScript, + body: data, + params: [], + }); + const { message, success } = resp; + setIsRunning(false); + enqueueSnackbar(JSON.stringify(message), { + variant: success ? "success" : "error", + }); + + // cloudFunction( + // callableName, + // data, + // async (response) => { + // const { message, cellValue, success } = response.data; + // setIsRunning(false); + // enqueueSnackbar(JSON.stringify(message), { + // variant: success ? "success" : "error", + // }); + // }, + // (error) => { + // console.error("ERROR", callableName, error); + // setIsRunning(false); + // enqueueSnackbar(JSON.stringify(error), { variant: "error" }); + // } + // ); }; const hasRan = value && value.status; diff --git a/src/constants/runRoutes.ts b/src/constants/runRoutes.ts index 9b999e9b..3c6de759 100644 --- a/src/constants/runRoutes.ts +++ b/src/constants/runRoutes.ts @@ -6,4 +6,5 @@ export const RunRoutes: { [key: string]: RunRoute } = { impersonateUser: { path: "/impersonateUser", method: "GET" }, version: { path: "/version", method: "GET" }, listCollections: { path: "/listCollections", method: "GET" }, + actionScript: { path: "/actionScript", method: "POST" }, }; diff --git a/src/contexts/ProjectContext.tsx b/src/contexts/ProjectContext.tsx index b4f651d8..bfab887c 100644 --- a/src/contexts/ProjectContext.tsx +++ b/src/contexts/ProjectContext.tsx @@ -194,9 +194,8 @@ export const ProjectContextProvider: React.FC = ({ children }) => { const { method, path } = route; let url = //'http://localhost:8080' - settings.doc.rowyRunUrl + route.path; + settings.doc.rowyRunUrl + path; if (params && params.length > 0) url = url + "/" + params.join("/"); - console.log(url, settings); const response = await fetch(url, { method: method, // *GET, POST, PUT, DELETE, etc. mode: "cors", // no-cors, *cors, same-origin @@ -211,6 +210,7 @@ export const ProjectContextProvider: React.FC = ({ children }) => { referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url body: method !== "GET" ? JSON.stringify(body) : null, // body data type must match "Content-Type" header }); + console.log(response); return response.json(); // parses JSON response into native JavaScript objects }; // A ref to the data grid. Contains data grid functions