From 2c2a1259d3d2271d3b0a99321bcfe3305a6a5087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Leszczyk?= Date: Thu, 7 Apr 2022 13:52:50 +0200 Subject: [PATCH] refactor(dashboard-v2): move access guards outside of SWRConfig --- packages/dashboard-v2/gatsby-browser.js | 12 ++-- packages/dashboard-v2/gatsby-ssr.js | 12 ++-- .../src/components/NavBar/NavBar.js | 2 +- .../portal-settings/PortalSettingsProvider.js | 2 +- .../src/contexts/user/UserProvider.js | 36 +++++++++-- .../dashboard-v2/src/layouts/AuthLayout.js | 45 +++++++------- .../src/layouts/DashboardLayout.js | 31 ++++------ .../src/layouts/UserSettingsLayout.js | 61 ++++--------------- packages/dashboard-v2/src/lib/swrConfig.js | 45 +++++--------- 9 files changed, 107 insertions(+), 139 deletions(-) diff --git a/packages/dashboard-v2/gatsby-browser.js b/packages/dashboard-v2/gatsby-browser.js index 79b58e24..030fcadd 100644 --- a/packages/dashboard-v2/gatsby-browser.js +++ b/packages/dashboard-v2/gatsby-browser.js @@ -1,4 +1,5 @@ import * as React from "react"; +import { SWRConfig } from "swr"; import "@fontsource/sora/300.css"; // light import "@fontsource/sora/400.css"; // normal import "@fontsource/sora/500.css"; // medium @@ -6,6 +7,7 @@ import "@fontsource/sora/600.css"; // semibold import "@fontsource/source-sans-pro/400.css"; // normal import "@fontsource/source-sans-pro/600.css"; // semibold import "./src/styles/global.css"; +import swrConfig from "./src/lib/swrConfig"; import { MODAL_ROOT_ID } from "./src/components/Modal"; import { PortalSettingsProvider } from "./src/contexts/portal-settings"; @@ -13,10 +15,12 @@ export function wrapPageElement({ element, props }) { const Layout = element.type.Layout ?? React.Fragment; return ( - - {element} -
- + + + {element} +
+ + ); } diff --git a/packages/dashboard-v2/gatsby-ssr.js b/packages/dashboard-v2/gatsby-ssr.js index 79b58e24..030fcadd 100644 --- a/packages/dashboard-v2/gatsby-ssr.js +++ b/packages/dashboard-v2/gatsby-ssr.js @@ -1,4 +1,5 @@ import * as React from "react"; +import { SWRConfig } from "swr"; import "@fontsource/sora/300.css"; // light import "@fontsource/sora/400.css"; // normal import "@fontsource/sora/500.css"; // medium @@ -6,6 +7,7 @@ import "@fontsource/sora/600.css"; // semibold import "@fontsource/source-sans-pro/400.css"; // normal import "@fontsource/source-sans-pro/600.css"; // semibold import "./src/styles/global.css"; +import swrConfig from "./src/lib/swrConfig"; import { MODAL_ROOT_ID } from "./src/components/Modal"; import { PortalSettingsProvider } from "./src/contexts/portal-settings"; @@ -13,10 +15,12 @@ export function wrapPageElement({ element, props }) { const Layout = element.type.Layout ?? React.Fragment; return ( - - {element} -
- + + + {element} +
+ + ); } diff --git a/packages/dashboard-v2/src/components/NavBar/NavBar.js b/packages/dashboard-v2/src/components/NavBar/NavBar.js index 6d2cb9eb..9ad8e91c 100644 --- a/packages/dashboard-v2/src/components/NavBar/NavBar.js +++ b/packages/dashboard-v2/src/components/NavBar/NavBar.js @@ -97,7 +97,7 @@ export const NavBar = () => { as="button" onClick={onLogout} activeClassName="text-primary" - className="cursor-pointer" + className="cursor-pointer w-full" icon={LockClosedIcon} label="Log out" /> diff --git a/packages/dashboard-v2/src/contexts/portal-settings/PortalSettingsProvider.js b/packages/dashboard-v2/src/contexts/portal-settings/PortalSettingsProvider.js index a5a033c8..5d8de1ab 100644 --- a/packages/dashboard-v2/src/contexts/portal-settings/PortalSettingsProvider.js +++ b/packages/dashboard-v2/src/contexts/portal-settings/PortalSettingsProvider.js @@ -16,7 +16,7 @@ const fetcher = async (path) => { }; export const PortalSettingsProvider = ({ children }) => { - const { data, error } = useSWRImmutable("/__internal/do/not/use/accounts", fetcher); + const { data, error } = useSWRImmutable("__internal/do/not/use/accounts", fetcher); const [loading, setLoading] = useState(true); const [settings, setSettings] = useState(defaultSettings); diff --git a/packages/dashboard-v2/src/contexts/user/UserProvider.js b/packages/dashboard-v2/src/contexts/user/UserProvider.js index bb10ffe4..014d5b7f 100644 --- a/packages/dashboard-v2/src/contexts/user/UserProvider.js +++ b/packages/dashboard-v2/src/contexts/user/UserProvider.js @@ -1,17 +1,41 @@ +import { navigate } from "gatsby"; import { useEffect, useState } from "react"; import useSWRImmutable from "swr/immutable"; +import { UnauthorizedError } from "../../lib/swrConfig"; +import { FullScreenLoadingIndicator } from "../../components/LoadingIndicator"; import { UserContext } from "./UserContext"; -export const UserProvider = ({ children }) => { +export const UserProvider = ({ children, allowGuests = false, allowAuthenticated = true }) => { const { data: user, error, mutate } = useSWRImmutable("user"); const [loading, setLoading] = useState(true); useEffect(() => { - if (user || error) { - setLoading(false); - } - }, [user, error]); + const guard = async () => { + if (user) { + if (!allowAuthenticated) { + navigate("/"); + } else { + setLoading(false); + } + } else if (error) { + if (error instanceof UnauthorizedError && !allowGuests) { + await navigate(`/auth/login?return_to=${encodeURIComponent(window.location.href)}`); + } else { + setLoading(false); + } + } else if (user === null) { + setLoading(false); + } + }; - return {children}; + guard(); + }, [user, error, allowGuests, allowAuthenticated]); + + return ( + + {loading && } + {!loading && children} + + ); }; diff --git a/packages/dashboard-v2/src/layouts/AuthLayout.js b/packages/dashboard-v2/src/layouts/AuthLayout.js index 85604321..847562e5 100644 --- a/packages/dashboard-v2/src/layouts/AuthLayout.js +++ b/packages/dashboard-v2/src/layouts/AuthLayout.js @@ -1,9 +1,7 @@ import * as React from "react"; import styled from "styled-components"; -import { SWRConfig } from "swr"; import { UserProvider } from "../contexts/user"; -import { guestsOnly, allUsers } from "../lib/swrConfig"; const Layout = styled.div.attrs({ className: "min-h-screen w-screen bg-black flex", @@ -22,29 +20,32 @@ const Content = styled.div.attrs({ })``; const AuthLayout = - (swrConfig) => - ({ children }) => { - return ( + (userProviderProps) => + ({ children }) => + ( <> - - - - -
-

- The decentralized revolution starts with decentralized storage -

-
-
- {children} -
-
-
+ + + +
+

+ The decentralized revolution starts with decentralized storage +

+
+
+ {children} +
+
); - }; // Some pages (e.g. email confirmation) need to be accessible to both logged-in and guest users. -export const AllUsersAuthLayout = AuthLayout(allUsers); +export const AllUsersAuthLayout = AuthLayout({ + allowGuests: true, + allowAuthenticated: true, +}); -export default AuthLayout(guestsOnly); +export default AuthLayout({ + allowGuests: true, + allowAuthenticated: false, +}); diff --git a/packages/dashboard-v2/src/layouts/DashboardLayout.js b/packages/dashboard-v2/src/layouts/DashboardLayout.js index fe4c5385..633057eb 100644 --- a/packages/dashboard-v2/src/layouts/DashboardLayout.js +++ b/packages/dashboard-v2/src/layouts/DashboardLayout.js @@ -1,8 +1,5 @@ import * as React from "react"; import styled from "styled-components"; -import { SWRConfig } from "swr"; - -import { authenticatedOnly } from "../lib/swrConfig"; import { PageContainer } from "../components/PageContainer"; import { NavBar } from "../components/NavBar"; @@ -30,22 +27,16 @@ const Layout = ({ children }) => { ); }; -const DashboardLayout = ({ children }) => { - return ( - <> - - - - - -
{children}
-
-