This commit is contained in:
Sidney Alcantara
2021-09-09 18:58:59 +10:00
7 changed files with 108 additions and 40 deletions

View File

@@ -66,11 +66,6 @@ export default function App() {
path={routes.auth}
render={() => <AuthView />}
/>
<Route
exact
path={routes.impersonatorAuth}
render={() => <ImpersonatorAuthPage />}
/>
<Route
exact
path={routes.authSetup}
@@ -104,10 +99,16 @@ export default function App() {
routes.projectSettings,
routes.userSettings,
routes.userManagement,
routes.impersonatorAuth,
]}
render={() => (
<ProjectContextProvider>
<Switch>
<Route
exact
path={routes.impersonatorAuth}
render={() => <ImpersonatorAuthPage />}
/>
<PrivateRoute
exact
path={routes.home}

View File

@@ -66,7 +66,7 @@ export default function CloudRun({
<TextField
label="Cloud Run Instance URL"
id="cloudRunUrl"
defaultValue={settings.cloudRunUrl}
defaultValue={settings.rowyRunUrl}
onChange={(e) => updateSettings({ cloudRunUrl: e.target.value })}
fullWidth
placeholder="https://<id>.run.app"

View File

@@ -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;

View File

@@ -0,0 +1,10 @@
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" },
actionScript: { path: "/actionScript", method: "POST" },
};

View File

@@ -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<ColumnMenuRef | undefined>;
// A ref ot the import wizard. Prevents unnecessary re-renders
importWizardRef: React.MutableRefObject<ImportWizardRef | undefined>;
rowyRun: (args: {
route: RunRoute;
body?: any;
params: string[];
}) => Promise<any>;
}
const ProjectContext = React.createContext<Partial<ProjectContextProps>>({});
@@ -96,6 +103,7 @@ export const ProjectContextProvider: React.FC = ({ children }) => {
const [userClaims, setUserClaims] = useState<any>();
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 + path;
if (params && params.length > 0) url = url + "/" + params.join("/");
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
});
console.log(response);
return response.json(); // parses JSON response into native JavaScript objects
};
// A ref to the data grid. Contains data grid functions
const dataGridRef = useRef<DataGridHandle>(null);
const sideDrawerRef = useRef<SideDrawerRef>();
@@ -193,6 +234,7 @@ export const ProjectContextProvider: React.FC = ({ children }) => {
sideDrawerRef,
columnMenuRef,
importWizardRef,
rowyRun,
}}
>
{children}

View File

@@ -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 });

View File

@@ -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" });
}
};