From 1135c085d2816bc2169ed15159204fcd2dbf86e6 Mon Sep 17 00:00:00 2001 From: Fran Rimoldi Date: Thu, 5 Jan 2023 08:56:00 -0300 Subject: [PATCH 01/22] feat: add admin routes --- src/App.tsx | 10 +++++----- src/{AppInternal.tsx => AppAdmin.tsx} | 6 +++--- src/hooks/api/admin/useAdminProfile.ts | 15 +++++++++++++++ src/hooks/api/admin/useAdminSignIn.ts | 1 + src/hooks/api/urls.ts | 5 +++++ src/utils/routes.ts | 6 +++--- 6 files changed, 32 insertions(+), 11 deletions(-) rename src/{AppInternal.tsx => AppAdmin.tsx} (79%) create mode 100644 src/hooks/api/admin/useAdminProfile.ts create mode 100644 src/hooks/api/admin/useAdminSignIn.ts diff --git a/src/App.tsx b/src/App.tsx index 02a4203c..2699bad6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,11 +11,11 @@ import { ProtocolPage } from "./pages/Protocol" import { ClaimsPage } from "./pages/Claim" import AppStakers from "./AppStakers" import AppProtocols from "./AppProtocols" -import AppInternal from "./AppInternal" +import AppAdmin from "./AppAdmin" import { AppContests } from "./AppContests" import AppProtocolDashboard from "./AppProtocolDashboard" -import { routes, protocolsRoutes, contestsRoutes, internalRoutes, protocolDashboardRoutes } from "./utils/routes" +import { routes, protocolsRoutes, contestsRoutes, protocolDashboardRoutes, adminRoutes } from "./utils/routes" import MobileBlock from "./components/MobileBlock/MobileBlock" import { InternalOverviewPage } from "./pages/InternalOverview/InternalOverview" import { ContestsPage } from "./pages/Contests" @@ -97,10 +97,10 @@ function App() { {/** Internal section routes */} - }> - } /> + }> + } /> - } /> + } /> } /> diff --git a/src/AppInternal.tsx b/src/AppAdmin.tsx similarity index 79% rename from src/AppInternal.tsx rename to src/AppAdmin.tsx index 1afaea97..afb9f03c 100644 --- a/src/AppInternal.tsx +++ b/src/AppAdmin.tsx @@ -4,20 +4,20 @@ import { Footer } from "./components/Footer" import { Header, NavigationLink } from "./components/Header" import styles from "./App.module.scss" -import { internalRoutes } from "./utils/routes" +import { adminRoutes } from "./utils/routes" const AppInternal = () => { const navigationLinks: NavigationLink[] = [ { title: "OVERVIEW", - route: internalRoutes.InternalOverview, + route: adminRoutes.InternalOverview, }, ] return (
-
+
diff --git a/src/hooks/api/admin/useAdminProfile.ts b/src/hooks/api/admin/useAdminProfile.ts new file mode 100644 index 00000000..092aa0b0 --- /dev/null +++ b/src/hooks/api/admin/useAdminProfile.ts @@ -0,0 +1,15 @@ +import { useQuery } from "react-query" +import { Address } from "wagmi" +import { contests as contestsAPI } from "../axios" +import { getAdminProfile } from "../urls" + +type GetAdminProfileResponse = { + admin: Address +} + +export const useAdminProfile = () => + useQuery("isAdmin", async () => { + const { data } = await contestsAPI.get(getAdminProfile()) + + return data.admin + }) diff --git a/src/hooks/api/admin/useAdminSignIn.ts b/src/hooks/api/admin/useAdminSignIn.ts new file mode 100644 index 00000000..3046e8aa --- /dev/null +++ b/src/hooks/api/admin/useAdminSignIn.ts @@ -0,0 +1 @@ +import {} from "react-query" diff --git a/src/hooks/api/urls.ts b/src/hooks/api/urls.ts index 801514fb..8591d06d 100644 --- a/src/hooks/api/urls.ts +++ b/src/hooks/api/urls.ts @@ -35,3 +35,8 @@ export const getProtocolGithubHandles = (dashboardID: string) => `dashboard/${da export const addProtocolGithubHandle = (dashboardID: string) => `dashboard/${dashboardID}/github_handles` export const getProtocolDiscordHandles = (dashboardID: string) => `dashboard/${dashboardID}/discord_handles` export const addProtocolDiscordHandle = (dashboardID: string) => `dashboard/${dashboardID}/discord_handles` + +export const getAdminProfile = () => `/admin/profile` +export const adminSignIn = () => `/admin/signin` +export const adminSignOut = () => `/admin/signout` +export const getAdminNonce = () => `/admin/nonce` diff --git a/src/utils/routes.ts b/src/utils/routes.ts index 1576284a..34ceee2e 100644 --- a/src/utils/routes.ts +++ b/src/utils/routes.ts @@ -6,7 +6,7 @@ export const routes = { Protocols: "protocols", AuditContests: "audits", ProtocolDashboard: "dashboard/:dashboardID", - Internal: "internal", + Admin: "admin", Overview: "overview", USForbidden: "us", } as const @@ -23,7 +23,7 @@ export const contestsRoutes = { Profile: "profile", } as const -export const internalRoutes = { +export const adminRoutes = { InternalOverview: "overview", } as const @@ -35,7 +35,7 @@ export const protocolDashboardRoutes = { type R = typeof routes & typeof protocolsRoutes & typeof contestsRoutes & - typeof internalRoutes & + typeof adminRoutes & typeof protocolDashboardRoutes type ValueOf = T[keyof T] From 66fd283610d9c3b5bfd96b8f079c496a6245f03f Mon Sep 17 00:00:00 2001 From: Fran Rimoldi Date: Wed, 11 Jan 2023 10:21:38 +0100 Subject: [PATCH 02/22] feat: protect admin panel with signature --- src/AppAdmin.tsx | 42 ++++++++--- src/hooks/api/admin/useAdminProfile.ts | 3 +- src/hooks/api/admin/useAdminSignIn.ts | 98 +++++++++++++++++++++++++- 3 files changed, 133 insertions(+), 10 deletions(-) diff --git a/src/AppAdmin.tsx b/src/AppAdmin.tsx index afb9f03c..ec6adaf6 100644 --- a/src/AppAdmin.tsx +++ b/src/AppAdmin.tsx @@ -1,18 +1,37 @@ -import React from "react" +import React, { useCallback } from "react" import { Outlet } from "react-router-dom" import { Footer } from "./components/Footer" import { Header, NavigationLink } from "./components/Header" import styles from "./App.module.scss" import { adminRoutes } from "./utils/routes" +import { useAdminProfile } from "./hooks/api/admin/useAdminProfile" +import { Text } from "./components/Text" +import { Button } from "./components/Button" +import { Box } from "./components/Box" +import { useAdminSignIn } from "./hooks/api/admin/useAdminSignIn" +import { ErrorModal } from "./pages/ContestDetails/ErrorModal" const AppInternal = () => { - const navigationLinks: NavigationLink[] = [ - { - title: "OVERVIEW", - route: adminRoutes.InternalOverview, - }, - ] + const { data: adminAddress } = useAdminProfile() + const { signIn, error, reset } = useAdminSignIn() + + const handleSignInAsAdmin = useCallback(() => { + signIn() + }, [signIn]) + + const handleErrorModalClose = useCallback(() => { + reset() + }, [reset]) + + const navigationLinks: NavigationLink[] = adminAddress + ? [ + { + title: "OVERVIEW", + route: adminRoutes.InternalOverview, + }, + ] + : [] return (
@@ -20,7 +39,14 @@ const AppInternal = () => {
- + {adminAddress ? ( + + ) : ( + + + + )} + {error && }