mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
move authToken, userClaims, userRoles to AppContext
This commit is contained in:
@@ -37,8 +37,8 @@ export default function NavDrawer({
|
||||
currentSection,
|
||||
...props
|
||||
}: INavDrawerProps) {
|
||||
const { userDoc } = useAppContext();
|
||||
const { userClaims, tables } = useProjectContext();
|
||||
const { userDoc, userClaims } = useAppContext();
|
||||
const { tables } = useProjectContext();
|
||||
|
||||
const favorites = Array.isArray(userDoc.state.doc?.favoriteTables)
|
||||
? userDoc.state.doc.favoriteTables
|
||||
|
||||
@@ -19,6 +19,7 @@ import LockIcon from "@mui/icons-material/LockOutlined";
|
||||
|
||||
import { FieldType } from "constants/fields";
|
||||
import { getFieldProp } from "components/fields";
|
||||
import { useAppContext } from "contexts/AppContext";
|
||||
import { useProjectContext } from "contexts/ProjectContext";
|
||||
import { TableOrder } from "@src/hooks/useTable";
|
||||
|
||||
@@ -115,7 +116,8 @@ export default function DraggableHeaderRenderer<R>({
|
||||
}) {
|
||||
const classes = useStyles();
|
||||
|
||||
const { tableState, tableActions, userClaims, columnMenuRef } =
|
||||
const {userClaims}=useAppContext()
|
||||
const { tableState, tableActions, columnMenuRef } =
|
||||
useProjectContext();
|
||||
const [{ isDragging }, drag] = useDrag({
|
||||
item: { key: column.key, type: "COLUMN_DRAG" },
|
||||
|
||||
@@ -21,8 +21,8 @@ import { FieldType } from "constants/fields";
|
||||
export const TABLE_HEADER_HEIGHT = 44;
|
||||
|
||||
export default function TableHeader() {
|
||||
const { currentUser } = useAppContext();
|
||||
const { tableActions, tableState, userClaims } = useProjectContext();
|
||||
const { currentUser, userClaims } = useAppContext();
|
||||
const { tableActions, tableState, } = useProjectContext();
|
||||
|
||||
const hasDerivatives =
|
||||
tableState &&
|
||||
|
||||
@@ -43,4 +43,5 @@ export const RunRoutes: { [key: string]: RunRoute } = {
|
||||
actionScript: { path: "/actionScript", method: "POST" },
|
||||
buildFunction: { path: "/buildFunction", method: "POST" },
|
||||
projectOwner: { path: "/projectOwner", method: "GET" },
|
||||
setOwnerRoles: { path: "/setOwnerRoles", method: "GET" },
|
||||
};
|
||||
|
||||
@@ -20,9 +20,12 @@ const useThemeOverriddenState = createPersistedState(
|
||||
"__ROWY__THEME_OVERRIDDEN"
|
||||
);
|
||||
|
||||
interface AppContextInterface {
|
||||
interface IAppContext {
|
||||
projectId: string;
|
||||
currentUser: firebase.User | null | undefined;
|
||||
userClaims: Record<string, any> | undefined;
|
||||
userRoles: null | string[];
|
||||
authToken: string;
|
||||
userDoc: any;
|
||||
theme: keyof typeof themes;
|
||||
themeOverridden: boolean;
|
||||
@@ -30,9 +33,12 @@ interface AppContextInterface {
|
||||
setThemeOverridden: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
export const AppContext = React.createContext<AppContextInterface>({
|
||||
export const AppContext = React.createContext<IAppContext>({
|
||||
projectId: "",
|
||||
currentUser: undefined,
|
||||
userClaims: undefined,
|
||||
userRoles: [],
|
||||
authToken: "",
|
||||
userDoc: undefined,
|
||||
theme: "light",
|
||||
themeOverridden: false,
|
||||
@@ -47,9 +53,23 @@ export const AppProvider: React.FC = ({ children }) => {
|
||||
const [currentUser, setCurrentUser] = useState<
|
||||
firebase.User | null | undefined
|
||||
>();
|
||||
// Store user auth data
|
||||
const [userClaims, setUserClaims] =
|
||||
useState<IAppContext["userClaims"]>(undefined);
|
||||
const [userRoles, setUserRoles] = useState<IAppContext["userRoles"]>([]);
|
||||
const [authToken, setAuthToken] = useState<IAppContext["authToken"]>("");
|
||||
|
||||
// Get user data from Firebase Auth event
|
||||
useEffect(() => {
|
||||
auth.onAuthStateChanged((auth) => {
|
||||
setCurrentUser(auth);
|
||||
|
||||
if (auth)
|
||||
auth.getIdTokenResult(true).then((results) => {
|
||||
setAuthToken(results.token);
|
||||
setUserRoles(results.claims.roles || []);
|
||||
setUserClaims(results.claims);
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
|
||||
@@ -128,8 +148,11 @@ export const AppProvider: React.FC = ({ children }) => {
|
||||
<AppContext.Provider
|
||||
value={{
|
||||
projectId,
|
||||
userDoc: { state: userDoc, dispatch: dispatchUserDoc },
|
||||
currentUser,
|
||||
userClaims,
|
||||
userRoles,
|
||||
authToken,
|
||||
userDoc: { state: userDoc, dispatch: dispatchUserDoc },
|
||||
theme,
|
||||
themeOverridden,
|
||||
setTheme,
|
||||
|
||||
@@ -10,7 +10,8 @@ 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";
|
||||
|
||||
import { rowyRun, IRowyRunRequestProps } from "utils/rowyRun";
|
||||
|
||||
export type Table = {
|
||||
id: string;
|
||||
@@ -23,7 +24,7 @@ export type Table = {
|
||||
tableType: string;
|
||||
};
|
||||
|
||||
interface ProjectContextProps {
|
||||
interface IProjectContext {
|
||||
tables: Table[];
|
||||
roles: string[];
|
||||
tableState: TableState;
|
||||
@@ -58,8 +59,6 @@ interface ProjectContextProps {
|
||||
deleteTable: (id: string) => void;
|
||||
};
|
||||
|
||||
userClaims: any;
|
||||
|
||||
// A ref to the data grid. Contains data grid functions
|
||||
dataGridRef: React.RefObject<DataGridHandle>;
|
||||
// A ref to the side drawer state. Prevents unnecessary re-renders
|
||||
@@ -69,15 +68,12 @@ interface ProjectContextProps {
|
||||
// A ref ot the import wizard. Prevents unnecessary re-renders
|
||||
importWizardRef: React.MutableRefObject<ImportWizardRef | undefined>;
|
||||
|
||||
rowyRun: (args: {
|
||||
route: RunRoute;
|
||||
body?: any;
|
||||
params?: string[];
|
||||
localhost?: boolean;
|
||||
}) => Promise<any>;
|
||||
rowyRun: (
|
||||
args: Omit<IRowyRunRequestProps, "rowyRunUrl" | "authToken">
|
||||
) => Promise<any>;
|
||||
}
|
||||
|
||||
const ProjectContext = React.createContext<Partial<ProjectContextProps>>({});
|
||||
const ProjectContext = React.createContext<Partial<IProjectContext>>({});
|
||||
export default ProjectContext;
|
||||
|
||||
export const rowyUser = (currentUser) => {
|
||||
@@ -96,15 +92,13 @@ export const rowyUser = (currentUser) => {
|
||||
export const useProjectContext = () => useContext(ProjectContext);
|
||||
|
||||
export const ProjectContextProvider: React.FC = ({ children }) => {
|
||||
const { currentUser, userRoles, authToken } = useAppContext();
|
||||
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
const { tableState, tableActions } = useTable();
|
||||
const [tables, setTables] = useState<ProjectContextProps["tables"]>();
|
||||
const [tables, setTables] = useState<IProjectContext["tables"]>();
|
||||
const [settings, settingsActions] = useSettings();
|
||||
const [userRoles, setUserRoles] = useState<null | string[]>();
|
||||
const [userClaims, setUserClaims] = useState<any>();
|
||||
|
||||
const { currentUser } = useAppContext();
|
||||
const [authToken, setAuthToken] = useState("");
|
||||
useEffect(() => {
|
||||
const { tables } = settings;
|
||||
if (tables && userRoles) {
|
||||
@@ -138,17 +132,7 @@ export const ProjectContextProvider: React.FC = ({ children }) => {
|
||||
[tables]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentUser && !userClaims) {
|
||||
currentUser.getIdTokenResult(true).then((results) => {
|
||||
setAuthToken(results.token);
|
||||
setUserRoles(results.claims.roles || []);
|
||||
setUserClaims(results.claims);
|
||||
});
|
||||
}
|
||||
}, [currentUser]);
|
||||
|
||||
const updateCell: ProjectContextProps["updateCell"] = (
|
||||
const updateCell: IProjectContext["updateCell"] = (
|
||||
ref,
|
||||
fieldName,
|
||||
value,
|
||||
@@ -182,40 +166,11 @@ export const ProjectContextProvider: React.FC = ({ children }) => {
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// rowyRun access
|
||||
const rowyRun = async ({
|
||||
route,
|
||||
body,
|
||||
params,
|
||||
localhost = false,
|
||||
}: {
|
||||
route: RunRoute;
|
||||
body?: any;
|
||||
params?: string[];
|
||||
localhost?: boolean;
|
||||
}) => {
|
||||
const { method, path } = route;
|
||||
let url = `${
|
||||
localhost ? "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: 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
|
||||
};
|
||||
const _rowyRun: IProjectContext["rowyRun"] = async (args) =>
|
||||
rowyRun({ rowyRunUrl: settings.doc.rowyRunUrl, authToken, ...args });
|
||||
|
||||
// A ref to the data grid. Contains data grid functions
|
||||
const dataGridRef = useRef<DataGridHandle>(null);
|
||||
const sideDrawerRef = useRef<SideDrawerRef>();
|
||||
@@ -231,12 +186,11 @@ export const ProjectContextProvider: React.FC = ({ children }) => {
|
||||
settingsActions,
|
||||
roles,
|
||||
tables,
|
||||
userClaims,
|
||||
dataGridRef,
|
||||
sideDrawerRef,
|
||||
columnMenuRef,
|
||||
importWizardRef,
|
||||
rowyRun,
|
||||
rowyRun: _rowyRun,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -48,8 +48,8 @@ import { APP_BAR_HEIGHT } from "components/Navigation";
|
||||
const useHomeViewState = createPersistedState("__ROWY__HOME_VIEW");
|
||||
|
||||
export default function HomePage() {
|
||||
const { userDoc } = useAppContext();
|
||||
const { tables, userClaims } = useProjectContext();
|
||||
const { userDoc, userClaims } = useAppContext();
|
||||
const { tables } = useProjectContext();
|
||||
|
||||
const [results, query, handleQuery] = useBasicSearch(
|
||||
tables ?? [],
|
||||
@@ -131,7 +131,7 @@ export default function HomePage() {
|
||||
);
|
||||
|
||||
if (tables.length === 0) {
|
||||
if (userClaims.roles.includes("ADMIN"))
|
||||
if (userClaims?.roles.includes("ADMIN"))
|
||||
return (
|
||||
<>
|
||||
<HomeWelcomePrompt />
|
||||
@@ -167,7 +167,7 @@ export default function HomePage() {
|
||||
|
||||
const getActions = (table: Table) => (
|
||||
<>
|
||||
{userClaims.roles.includes("ADMIN") && (
|
||||
{userClaims?.roles.includes("ADMIN") && (
|
||||
<IconButton
|
||||
aria-label="Edit table"
|
||||
onClick={() =>
|
||||
@@ -258,7 +258,7 @@ export default function HomePage() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{userClaims.roles.includes("ADMIN") && (
|
||||
{userClaims?.roles.includes("ADMIN") && (
|
||||
<>
|
||||
{createTableFab}
|
||||
<TableSettingsDialog
|
||||
|
||||
42
src/utils/rowyRun.ts
Normal file
42
src/utils/rowyRun.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { RunRoute } from "constants/runRoutes";
|
||||
|
||||
export interface IRowyRunRequestProps {
|
||||
rowyRunUrl: string;
|
||||
authToken?: string;
|
||||
route: RunRoute;
|
||||
body?: any;
|
||||
params?: string[];
|
||||
localhost?: boolean;
|
||||
json?: boolean;
|
||||
}
|
||||
|
||||
export const rowyRun = async ({
|
||||
rowyRunUrl,
|
||||
authToken,
|
||||
route,
|
||||
body,
|
||||
params,
|
||||
localhost = false,
|
||||
json = true,
|
||||
}: IRowyRunRequestProps) => {
|
||||
const { method, path } = route;
|
||||
let url = (localhost ? "http://localhost:8080" : rowyRunUrl) + path;
|
||||
if (params && params.length > 0) url = url + "/" + params.join("/");
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: method,
|
||||
mode: "cors",
|
||||
cache: "no-cache",
|
||||
credentials: "same-origin",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: "Bearer " + authToken,
|
||||
},
|
||||
redirect: "follow",
|
||||
referrerPolicy: "no-referrer",
|
||||
body: body && method !== "GET" ? JSON.stringify(body) : null, // body data type must match "Content-Type" header
|
||||
});
|
||||
|
||||
if (json) return await response.json();
|
||||
return response;
|
||||
};
|
||||
Reference in New Issue
Block a user