From 99c975c329b9be958bf5a09d6890324680028dae Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Thu, 27 Oct 2022 12:14:34 -0700 Subject: [PATCH 001/452] add DISABLE_UI, DISABLE_ADMIN --- components/layout/Header.js | 2 +- components/settings/UserButton.js | 2 +- next.config.js | 2 +- pages/404.js | 14 +++++++++++++- pages/console/[[...id]].js | 9 ++++++--- pages/dashboard/[[...id]].js | 12 ++++++++++-- pages/login.js | 9 ++++++--- pages/realtime.js | 12 ++++++++++-- pages/settings/accounts.js | 8 ++++++++ pages/settings/index.js | 12 ++++++++++-- pages/settings/profile.js | 8 ++++++++ pages/share/[...id].js | 12 ++++++++++-- pages/websites/[...id].js | 12 ++++++++++-- 13 files changed, 94 insertions(+), 20 deletions(-) diff --git a/components/layout/Header.js b/components/layout/Header.js index a81e016c..81c4e710 100644 --- a/components/layout/Header.js +++ b/components/layout/Header.js @@ -38,7 +38,7 @@ export default function Header() { - {!process.env.isCloudMode && ( + {!process.env.isAdminDisabled && ( diff --git a/components/settings/UserButton.js b/components/settings/UserButton.js index 0d67bbd3..d1a8b4ca 100644 --- a/components/settings/UserButton.js +++ b/components/settings/UserButton.js @@ -28,7 +28,7 @@ export default function UserButton() { { label: , value: 'profile', - hidden: process.env.isCloudMode, + hidden: process.env.isAdminDisabled, }, { label: , value: 'logout' }, ]; diff --git a/next.config.js b/next.config.js index e26d882e..3e649d2f 100644 --- a/next.config.js +++ b/next.config.js @@ -36,7 +36,7 @@ module.exports = { env: { currentVersion: pkg.version, isProduction: process.env.NODE_ENV === 'production', - isCloudMode: process.env.CLOUD_MODE, + isAdminDisabled: process.env.DISABLE_ADMIN, }, basePath: process.env.BASE_PATH, output: 'standalone', diff --git a/pages/404.js b/pages/404.js index 4c85b10a..6a65c3b9 100644 --- a/pages/404.js +++ b/pages/404.js @@ -2,7 +2,11 @@ import React from 'react'; import Layout from 'components/layout/Layout'; import { FormattedMessage } from 'react-intl'; -export default function Custom404() { +export default function Custom404({ pageDisabled }) { + if (pageDisabled) { + return null; + } + return (
@@ -13,3 +17,11 @@ export default function Custom404() { ); } + +export async function getServerSideProps() { + return { + props: { + pageDisabled: !!process.env.DISABLE_UI, + }, + }; +} diff --git a/pages/console/[[...id]].js b/pages/console/[[...id]].js index a13537f8..0fd816b1 100644 --- a/pages/console/[[...id]].js +++ b/pages/console/[[...id]].js @@ -4,11 +4,11 @@ import TestConsole from 'components/pages/TestConsole'; import useRequireLogin from 'hooks/useRequireLogin'; import useUser from 'hooks/useUser'; -export default function ConsolePage({ enabled }) { +export default function ConsolePage({ enabled, pageDisabled }) { const { loading } = useRequireLogin(); const { user } = useUser(); - if (loading || !enabled || !user?.isAdmin) { + if (pageDisabled || loading || !enabled || !user?.isAdmin) { return null; } @@ -21,6 +21,9 @@ export default function ConsolePage({ enabled }) { export async function getServerSideProps() { return { - props: { enabled: !!process.env.ENABLE_TEST_CONSOLE }, + props: { + pageDisabled: !!process.env.DISABLE_UI, + enabled: !!process.env.ENABLE_TEST_CONSOLE, + }, }; } diff --git a/pages/dashboard/[[...id]].js b/pages/dashboard/[[...id]].js index 7c762097..0959fd0e 100644 --- a/pages/dashboard/[[...id]].js +++ b/pages/dashboard/[[...id]].js @@ -5,7 +5,7 @@ import useRequireLogin from 'hooks/useRequireLogin'; import { useRouter } from 'next/router'; import useUser from 'hooks/useUser'; -export default function DashboardPage() { +export default function DashboardPage({ pageDisabled }) { const { query: { id }, isReady, @@ -14,7 +14,7 @@ export default function DashboardPage() { const { loading } = useRequireLogin(); const user = useUser(); - if (!user || !isReady || loading) { + if (pageDisabled || !user || !isReady || loading) { return null; } @@ -26,3 +26,11 @@ export default function DashboardPage() { ); } + +export async function getServerSideProps() { + return { + props: { + pageDisabled: !!process.env.DISABLE_UI, + }, + }; +} diff --git a/pages/login.js b/pages/login.js index 12f70ac9..29e9624f 100644 --- a/pages/login.js +++ b/pages/login.js @@ -2,8 +2,8 @@ import React from 'react'; import Layout from 'components/layout/Layout'; import LoginForm from 'components/forms/LoginForm'; -export default function LoginPage({ loginDisabled }) { - if (loginDisabled) { +export default function LoginPage({ pageDisabled }) { + if (pageDisabled) { return null; } @@ -16,6 +16,9 @@ export default function LoginPage({ loginDisabled }) { export async function getServerSideProps() { return { - props: { loginDisabled: !!process.env.DISABLE_LOGIN || !!process.env.isCloudMode }, + props: { + pageDisabled: + !!process.env.DISABLE_LOGIN || !!process.env.DISABLE_UI || !!process.env.isAdminDisabled, + }, }; } diff --git a/pages/realtime.js b/pages/realtime.js index 9f1ebffa..30dc1467 100644 --- a/pages/realtime.js +++ b/pages/realtime.js @@ -3,10 +3,10 @@ import Layout from 'components/layout/Layout'; import RealtimeDashboard from 'components/pages/RealtimeDashboard'; import useRequireLogin from 'hooks/useRequireLogin'; -export default function RealtimePage() { +export default function RealtimePage({ pageDisabled }) { const { loading } = useRequireLogin(); - if (loading) { + if (pageDisabled || loading) { return null; } @@ -16,3 +16,11 @@ export default function RealtimePage() { ); } + +export async function getServerSideProps() { + return { + props: { + pageDisabled: !!process.env.DISABLE_UI, + }, + }; +} diff --git a/pages/settings/accounts.js b/pages/settings/accounts.js index 3426f4b8..c46f179a 100644 --- a/pages/settings/accounts.js +++ b/pages/settings/accounts.js @@ -1,3 +1,11 @@ import Index from './index'; export default Index; + +export async function getServerSideProps() { + return { + props: { + pageDisabled: !!process.env.DISABLE_UI, + }, + }; +} diff --git a/pages/settings/index.js b/pages/settings/index.js index 18f33109..9bb1b0fa 100644 --- a/pages/settings/index.js +++ b/pages/settings/index.js @@ -3,10 +3,10 @@ import Layout from 'components/layout/Layout'; import Settings from 'components/pages/Settings'; import useRequireLogin from 'hooks/useRequireLogin'; -export default function SettingsPage() { +export default function SettingsPage({ pageDisabled }) { const { loading } = useRequireLogin(); - if (process.env.isCloudMode || loading) { + if (pageDisabled || loading) { return null; } @@ -16,3 +16,11 @@ export default function SettingsPage() { ); } + +export async function getServerSideProps() { + return { + props: { + pageDisabled: !!process.env.DISABLE_UI || !!process.env.isAdminDisabled, + }, + }; +} diff --git a/pages/settings/profile.js b/pages/settings/profile.js index 3426f4b8..c46f179a 100644 --- a/pages/settings/profile.js +++ b/pages/settings/profile.js @@ -1,3 +1,11 @@ import Index from './index'; export default Index; + +export async function getServerSideProps() { + return { + props: { + pageDisabled: !!process.env.DISABLE_UI, + }, + }; +} diff --git a/pages/share/[...id].js b/pages/share/[...id].js index d449afa5..6c81a67a 100644 --- a/pages/share/[...id].js +++ b/pages/share/[...id].js @@ -4,13 +4,13 @@ import Layout from 'components/layout/Layout'; import WebsiteDetails from 'components/pages/WebsiteDetails'; import useShareToken from 'hooks/useShareToken'; -export default function SharePage() { +export default function SharePage({ pageDisabled }) { const router = useRouter(); const { id } = router.query; const shareId = id?.[0]; const shareToken = useShareToken(shareId); - if (!shareToken) { + if (pageDisabled || !shareToken) { return null; } @@ -20,3 +20,11 @@ export default function SharePage() { ); } + +export async function getServerSideProps() { + return { + props: { + pageDisabled: !!process.env.DISABLE_UI, + }, + }; +} diff --git a/pages/websites/[...id].js b/pages/websites/[...id].js index 90f4f492..7d068d3d 100644 --- a/pages/websites/[...id].js +++ b/pages/websites/[...id].js @@ -4,12 +4,12 @@ import Layout from 'components/layout/Layout'; import WebsiteDetails from 'components/pages/WebsiteDetails'; import useRequireLogin from 'hooks/useRequireLogin'; -export default function DetailsPage() { +export default function DetailsPage({ pageDisabled }) { const { loading } = useRequireLogin(); const router = useRouter(); const { id } = router.query; - if (!id || loading) { + if (pageDisabled || !id || loading) { return null; } @@ -21,3 +21,11 @@ export default function DetailsPage() { ); } + +export async function getServerSideProps() { + return { + props: { + pageDisabled: !!process.env.DISABLE_UI, + }, + }; +} From 08ec801fdc465f932f895aa8104661b279d9cf19 Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Thu, 27 Oct 2022 14:48:21 -0700 Subject: [PATCH 002/452] remove GSS from 404 --- pages/404.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/pages/404.js b/pages/404.js index 6a65c3b9..4c85b10a 100644 --- a/pages/404.js +++ b/pages/404.js @@ -2,11 +2,7 @@ import React from 'react'; import Layout from 'components/layout/Layout'; import { FormattedMessage } from 'react-intl'; -export default function Custom404({ pageDisabled }) { - if (pageDisabled) { - return null; - } - +export default function Custom404() { return (
@@ -17,11 +13,3 @@ export default function Custom404({ pageDisabled }) { ); } - -export async function getServerSideProps() { - return { - props: { - pageDisabled: !!process.env.DISABLE_UI, - }, - }; -} From fc9584eb4491b940d90b2e0b642a3de245e1ce0d Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Thu, 27 Oct 2022 16:42:57 -0700 Subject: [PATCH 003/452] Refactor env check. --- components/layout/Header.js | 4 ++-- components/settings/UserButton.js | 4 +++- next.config.js | 1 - pages/_app.js | 6 ++++++ pages/api/config.js | 3 +++ pages/console/[[...id]].js | 7 +++---- pages/dashboard/[[...id]].js | 12 ++---------- pages/login.js | 3 +-- pages/realtime.js | 12 ++---------- pages/settings/accounts.js | 8 -------- pages/settings/index.js | 14 ++++---------- pages/settings/profile.js | 8 -------- pages/share/[...id].js | 12 ++---------- pages/websites/[...id].js | 12 ++---------- 14 files changed, 30 insertions(+), 76 deletions(-) diff --git a/components/layout/Header.js b/components/layout/Header.js index 81c4e710..02a2e081 100644 --- a/components/layout/Header.js +++ b/components/layout/Header.js @@ -17,7 +17,7 @@ import styles from './Header.module.css'; export default function Header() { const { user } = useUser(); const { pathname } = useRouter(); - const { updatesDisabled } = useConfig(); + const { updatesDisabled, adminDisabled } = useConfig(); const isSharePage = pathname.includes('/share/'); const allowUpdate = user?.isAdmin && !updatesDisabled && !isSharePage; @@ -38,7 +38,7 @@ export default function Header() { - {!process.env.isAdminDisabled && ( + {!adminDisabled && ( diff --git a/components/settings/UserButton.js b/components/settings/UserButton.js index d1a8b4ca..1d002c4b 100644 --- a/components/settings/UserButton.js +++ b/components/settings/UserButton.js @@ -8,10 +8,12 @@ import User from 'assets/user.svg'; import styles from './UserButton.module.css'; import { AUTH_TOKEN } from 'lib/constants'; import useUser from 'hooks/useUser'; +import useConfig from 'hooks/useConfig'; export default function UserButton() { const { user } = useUser(); const router = useRouter(); + const { adminDisabled } = useConfig(); const menuOptions = [ { @@ -28,7 +30,7 @@ export default function UserButton() { { label: , value: 'profile', - hidden: process.env.isAdminDisabled, + hidden: adminDisabled, }, { label: , value: 'logout' }, ]; diff --git a/next.config.js b/next.config.js index 3e649d2f..0401516c 100644 --- a/next.config.js +++ b/next.config.js @@ -36,7 +36,6 @@ module.exports = { env: { currentVersion: pkg.version, isProduction: process.env.NODE_ENV === 'production', - isAdminDisabled: process.env.DISABLE_ADMIN, }, basePath: process.env.BASE_PATH, output: 'standalone', diff --git a/pages/_app.js b/pages/_app.js index b8653113..655f9fad 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -2,6 +2,7 @@ import Head from 'next/head'; import { useRouter } from 'next/router'; import { IntlProvider } from 'react-intl'; import useLocale from 'hooks/useLocale'; +import useConfig from 'hooks/useConfig'; import 'styles/variables.css'; import 'styles/bootstrap-grid.css'; import 'styles/index.css'; @@ -23,6 +24,11 @@ const Intl = ({ children }) => { export default function App({ Component, pageProps }) { const { basePath } = useRouter(); const { dir } = useLocale(); + const { uiDisabled } = useConfig(); + + if (uiDisabled) { + return null; + } return ( diff --git a/pages/api/config.js b/pages/api/config.js index 27a04eaa..1facd45d 100644 --- a/pages/api/config.js +++ b/pages/api/config.js @@ -7,6 +7,9 @@ export default async (req, res) => { trackerScriptName: process.env.TRACKER_SCRIPT_NAME, updatesDisabled: !!process.env.DISABLE_UPDATES, telemetryDisabled: !!process.env.DISABLE_TELEMETRY, + loginDisabled: !!process.env.DISABLE_LOGIN, + adminDisabled: !!process.env.DISABLE_ADMIN, + uiDisabled: !!process.env.DISABLE_UI, }); } diff --git a/pages/console/[[...id]].js b/pages/console/[[...id]].js index 0fd816b1..270a81df 100644 --- a/pages/console/[[...id]].js +++ b/pages/console/[[...id]].js @@ -4,11 +4,11 @@ import TestConsole from 'components/pages/TestConsole'; import useRequireLogin from 'hooks/useRequireLogin'; import useUser from 'hooks/useUser'; -export default function ConsolePage({ enabled, pageDisabled }) { +export default function ConsolePage({ pageDisabled }) { const { loading } = useRequireLogin(); const { user } = useUser(); - if (pageDisabled || loading || !enabled || !user?.isAdmin) { + if (pageDisabled || loading || !user?.isAdmin) { return null; } @@ -22,8 +22,7 @@ export default function ConsolePage({ enabled, pageDisabled }) { export async function getServerSideProps() { return { props: { - pageDisabled: !!process.env.DISABLE_UI, - enabled: !!process.env.ENABLE_TEST_CONSOLE, + pageDisabled: !process.env.ENABLE_TEST_CONSOLE, }, }; } diff --git a/pages/dashboard/[[...id]].js b/pages/dashboard/[[...id]].js index 0959fd0e..7c762097 100644 --- a/pages/dashboard/[[...id]].js +++ b/pages/dashboard/[[...id]].js @@ -5,7 +5,7 @@ import useRequireLogin from 'hooks/useRequireLogin'; import { useRouter } from 'next/router'; import useUser from 'hooks/useUser'; -export default function DashboardPage({ pageDisabled }) { +export default function DashboardPage() { const { query: { id }, isReady, @@ -14,7 +14,7 @@ export default function DashboardPage({ pageDisabled }) { const { loading } = useRequireLogin(); const user = useUser(); - if (pageDisabled || !user || !isReady || loading) { + if (!user || !isReady || loading) { return null; } @@ -26,11 +26,3 @@ export default function DashboardPage({ pageDisabled }) { ); } - -export async function getServerSideProps() { - return { - props: { - pageDisabled: !!process.env.DISABLE_UI, - }, - }; -} diff --git a/pages/login.js b/pages/login.js index 29e9624f..55b10427 100644 --- a/pages/login.js +++ b/pages/login.js @@ -17,8 +17,7 @@ export default function LoginPage({ pageDisabled }) { export async function getServerSideProps() { return { props: { - pageDisabled: - !!process.env.DISABLE_LOGIN || !!process.env.DISABLE_UI || !!process.env.isAdminDisabled, + pageDisabled: !!(process.env.DISABLE_LOGIN || process.env.DISABLE_ADMIN), }, }; } diff --git a/pages/realtime.js b/pages/realtime.js index 30dc1467..9f1ebffa 100644 --- a/pages/realtime.js +++ b/pages/realtime.js @@ -3,10 +3,10 @@ import Layout from 'components/layout/Layout'; import RealtimeDashboard from 'components/pages/RealtimeDashboard'; import useRequireLogin from 'hooks/useRequireLogin'; -export default function RealtimePage({ pageDisabled }) { +export default function RealtimePage() { const { loading } = useRequireLogin(); - if (pageDisabled || loading) { + if (loading) { return null; } @@ -16,11 +16,3 @@ export default function RealtimePage({ pageDisabled }) { ); } - -export async function getServerSideProps() { - return { - props: { - pageDisabled: !!process.env.DISABLE_UI, - }, - }; -} diff --git a/pages/settings/accounts.js b/pages/settings/accounts.js index c46f179a..3426f4b8 100644 --- a/pages/settings/accounts.js +++ b/pages/settings/accounts.js @@ -1,11 +1,3 @@ import Index from './index'; export default Index; - -export async function getServerSideProps() { - return { - props: { - pageDisabled: !!process.env.DISABLE_UI, - }, - }; -} diff --git a/pages/settings/index.js b/pages/settings/index.js index 9bb1b0fa..02e89cea 100644 --- a/pages/settings/index.js +++ b/pages/settings/index.js @@ -2,11 +2,13 @@ import React from 'react'; import Layout from 'components/layout/Layout'; import Settings from 'components/pages/Settings'; import useRequireLogin from 'hooks/useRequireLogin'; +import useConfig from 'hooks/useConfig'; -export default function SettingsPage({ pageDisabled }) { +export default function SettingsPage() { const { loading } = useRequireLogin(); + const { adminDisabled } = useConfig(); - if (pageDisabled || loading) { + if (adminDisabled || loading) { return null; } @@ -16,11 +18,3 @@ export default function SettingsPage({ pageDisabled }) { ); } - -export async function getServerSideProps() { - return { - props: { - pageDisabled: !!process.env.DISABLE_UI || !!process.env.isAdminDisabled, - }, - }; -} diff --git a/pages/settings/profile.js b/pages/settings/profile.js index c46f179a..3426f4b8 100644 --- a/pages/settings/profile.js +++ b/pages/settings/profile.js @@ -1,11 +1,3 @@ import Index from './index'; export default Index; - -export async function getServerSideProps() { - return { - props: { - pageDisabled: !!process.env.DISABLE_UI, - }, - }; -} diff --git a/pages/share/[...id].js b/pages/share/[...id].js index 6c81a67a..d449afa5 100644 --- a/pages/share/[...id].js +++ b/pages/share/[...id].js @@ -4,13 +4,13 @@ import Layout from 'components/layout/Layout'; import WebsiteDetails from 'components/pages/WebsiteDetails'; import useShareToken from 'hooks/useShareToken'; -export default function SharePage({ pageDisabled }) { +export default function SharePage() { const router = useRouter(); const { id } = router.query; const shareId = id?.[0]; const shareToken = useShareToken(shareId); - if (pageDisabled || !shareToken) { + if (!shareToken) { return null; } @@ -20,11 +20,3 @@ export default function SharePage({ pageDisabled }) { ); } - -export async function getServerSideProps() { - return { - props: { - pageDisabled: !!process.env.DISABLE_UI, - }, - }; -} diff --git a/pages/websites/[...id].js b/pages/websites/[...id].js index 7d068d3d..90f4f492 100644 --- a/pages/websites/[...id].js +++ b/pages/websites/[...id].js @@ -4,12 +4,12 @@ import Layout from 'components/layout/Layout'; import WebsiteDetails from 'components/pages/WebsiteDetails'; import useRequireLogin from 'hooks/useRequireLogin'; -export default function DetailsPage({ pageDisabled }) { +export default function DetailsPage() { const { loading } = useRequireLogin(); const router = useRouter(); const { id } = router.query; - if (pageDisabled || !id || loading) { + if (!id || loading) { return null; } @@ -21,11 +21,3 @@ export default function DetailsPage({ pageDisabled }) { ); } - -export async function getServerSideProps() { - return { - props: { - pageDisabled: !!process.env.DISABLE_UI, - }, - }; -} From 98835bbc785e0e9f4c6d0ddee78f704fff8ffb44 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Thu, 27 Oct 2022 17:02:54 -0700 Subject: [PATCH 004/452] Define uiDisabled at build time. --- next.config.js | 1 + pages/_app.js | 4 +--- pages/api/config.js | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/next.config.js b/next.config.js index 0401516c..b95c39d4 100644 --- a/next.config.js +++ b/next.config.js @@ -36,6 +36,7 @@ module.exports = { env: { currentVersion: pkg.version, isProduction: process.env.NODE_ENV === 'production', + uiDisabled: !!process.env.DISABLE_UI, }, basePath: process.env.BASE_PATH, output: 'standalone', diff --git a/pages/_app.js b/pages/_app.js index 655f9fad..db4bb6e5 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -2,7 +2,6 @@ import Head from 'next/head'; import { useRouter } from 'next/router'; import { IntlProvider } from 'react-intl'; import useLocale from 'hooks/useLocale'; -import useConfig from 'hooks/useConfig'; import 'styles/variables.css'; import 'styles/bootstrap-grid.css'; import 'styles/index.css'; @@ -24,9 +23,8 @@ const Intl = ({ children }) => { export default function App({ Component, pageProps }) { const { basePath } = useRouter(); const { dir } = useLocale(); - const { uiDisabled } = useConfig(); - if (uiDisabled) { + if (!process.env.uiDisabled) { return null; } diff --git a/pages/api/config.js b/pages/api/config.js index 1facd45d..faf94c0b 100644 --- a/pages/api/config.js +++ b/pages/api/config.js @@ -7,9 +7,7 @@ export default async (req, res) => { trackerScriptName: process.env.TRACKER_SCRIPT_NAME, updatesDisabled: !!process.env.DISABLE_UPDATES, telemetryDisabled: !!process.env.DISABLE_TELEMETRY, - loginDisabled: !!process.env.DISABLE_LOGIN, adminDisabled: !!process.env.DISABLE_ADMIN, - uiDisabled: !!process.env.DISABLE_UI, }); } From 246e4e5f4ffcde63c81e0e1937797c24d50a3f02 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Fri, 28 Oct 2022 10:34:50 -0700 Subject: [PATCH 005/452] Fix disable checks. --- components/layout/Header.js | 10 ++++------ pages/_app.js | 2 +- pages/dashboard/[[...id]].js | 6 ++++-- pages/login.js | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/layout/Header.js b/components/layout/Header.js index 02a2e081..3fa71147 100644 --- a/components/layout/Header.js +++ b/components/layout/Header.js @@ -30,7 +30,7 @@ export default function Header() { umami
- {user && ( + {user && !adminDisabled && (
@@ -38,11 +38,9 @@ export default function Header() { - {!adminDisabled && ( - - - - )} + + +
)}
diff --git a/pages/_app.js b/pages/_app.js index db4bb6e5..0d942f9d 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -24,7 +24,7 @@ export default function App({ Component, pageProps }) { const { basePath } = useRouter(); const { dir } = useLocale(); - if (!process.env.uiDisabled) { + if (process.env.uiDisabled) { return null; } diff --git a/pages/dashboard/[[...id]].js b/pages/dashboard/[[...id]].js index 7c762097..c9ef6231 100644 --- a/pages/dashboard/[[...id]].js +++ b/pages/dashboard/[[...id]].js @@ -1,9 +1,10 @@ import React from 'react'; +import { useRouter } from 'next/router'; import Layout from 'components/layout/Layout'; import Dashboard from 'components/pages/Dashboard'; import useRequireLogin from 'hooks/useRequireLogin'; -import { useRouter } from 'next/router'; import useUser from 'hooks/useUser'; +import useConfig from 'hooks/useConfig'; export default function DashboardPage() { const { @@ -13,8 +14,9 @@ export default function DashboardPage() { } = useRouter(); const { loading } = useRequireLogin(); const user = useUser(); + const { adminDisabled } = useConfig(); - if (!user || !isReady || loading) { + if (adminDisabled || !user || !isReady || loading) { return null; } diff --git a/pages/login.js b/pages/login.js index 55b10427..fb2fcb21 100644 --- a/pages/login.js +++ b/pages/login.js @@ -17,7 +17,7 @@ export default function LoginPage({ pageDisabled }) { export async function getServerSideProps() { return { props: { - pageDisabled: !!(process.env.DISABLE_LOGIN || process.env.DISABLE_ADMIN), + pageDisabled: !!process.env.DISABLE_LOGIN, }, }; } From c58e037a7e9706ec6cf04ef9a80876b11a2f75f4 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Mon, 31 Oct 2022 11:02:37 -0700 Subject: [PATCH 006/452] Updated useConfig. Added SSO page. --- hooks/useConfig.js | 7 ++++--- lib/auth.js | 15 ++++++++++----- lib/crypto.js | 4 ++-- lib/middleware.js | 6 +++--- package.json | 2 +- pages/_app.js | 21 +++++++-------------- pages/sso.js | 38 ++++++++++++++++++++++++++++++++++++++ yarn.lock | 8 ++++---- 8 files changed, 69 insertions(+), 32 deletions(-) create mode 100644 pages/sso.js diff --git a/hooks/useConfig.js b/hooks/useConfig.js index 8adedcaf..678b6d1c 100644 --- a/hooks/useConfig.js +++ b/hooks/useConfig.js @@ -2,7 +2,7 @@ import { useEffect } from 'react'; import useStore, { setConfig } from 'store/app'; import useApi from 'hooks/useApi'; -let fetched = false; +let loading = false; export default function useConfig() { const { config } = useStore(); @@ -10,12 +10,13 @@ export default function useConfig() { async function loadConfig() { const { data } = await get('/config'); + loading = false; setConfig(data); } useEffect(() => { - if (!config && !fetched) { - fetched = true; + if (!config && !loading) { + loading = true; loadConfig(); } }, []); diff --git a/lib/auth.js b/lib/auth.js index 93027544..25985168 100644 --- a/lib/auth.js +++ b/lib/auth.js @@ -1,22 +1,26 @@ import { parseSecureToken, parseToken } from 'next-basics'; import { getAccount, getWebsite } from 'queries'; +import debug from 'debug'; import { SHARE_TOKEN_HEADER, TYPE_ACCOUNT, TYPE_WEBSITE } from 'lib/constants'; import { secret } from 'lib/crypto'; -export function getAuthToken(req) { +const log = debug('umami:auth'); + +export function parseAuthToken(req) { try { const token = req.headers.authorization; - return parseSecureToken(token.split(' ')[1], secret()); - } catch { + } catch (e) { + log(e); return null; } } -export function getShareToken(req) { +export function parseShareToken(req) { try { return parseToken(req.headers[SHARE_TOKEN_HEADER], secret()); - } catch { + } catch (e) { + log(e); return null; } } @@ -29,6 +33,7 @@ export function isValidToken(token, validation) { return validation(token); } } catch (e) { + log(e); return false; } diff --git a/lib/crypto.js b/lib/crypto.js index 74470549..ceb8aa99 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -9,11 +9,11 @@ export function secret() { export function salt() { const ROTATING_SALT = hash(startOfMonth(new Date()).toUTCString()); - return hash([secret(), ROTATING_SALT]); + return hash(secret(), ROTATING_SALT); } export function uuid(...args) { if (!args.length) return v4(); - return v5(hash([...args, salt()]), v5.DNS); + return v5(hash(...args, salt()), v5.DNS); } diff --git a/lib/middleware.js b/lib/middleware.js index 8189ea66..d42823fa 100644 --- a/lib/middleware.js +++ b/lib/middleware.js @@ -1,7 +1,7 @@ import { createMiddleware, unauthorized, badRequest, serverError } from 'next-basics'; import cors from 'cors'; import { getSession } from './session'; -import { getAuthToken, getShareToken } from './auth'; +import { parseAuthToken, parseShareToken } from './auth'; export const useCors = createMiddleware(cors()); @@ -26,8 +26,8 @@ export const useSession = createMiddleware(async (req, res, next) => { }); export const useAuth = createMiddleware(async (req, res, next) => { - const token = await getAuthToken(req); - const shareToken = await getShareToken(req); + const token = await parseAuthToken(req); + const shareToken = await parseShareToken(req); if (!token && !shareToken) { return unauthorized(res); diff --git a/package.json b/package.json index aad3b913..e27b1f61 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "maxmind": "^4.3.6", "moment-timezone": "^0.5.35", "next": "^12.3.1", - "next-basics": "^0.18.0", + "next-basics": "^0.20.0", "node-fetch": "^3.2.8", "npm-run-all": "^4.1.5", "prop-types": "^15.7.2", diff --git a/pages/_app.js b/pages/_app.js index 0d942f9d..c3617a08 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -2,34 +2,27 @@ import Head from 'next/head'; import { useRouter } from 'next/router'; import { IntlProvider } from 'react-intl'; import useLocale from 'hooks/useLocale'; +import useConfig from 'hooks/useConfig'; import 'styles/variables.css'; import 'styles/bootstrap-grid.css'; import 'styles/index.css'; import '@fontsource/inter/400.css'; import '@fontsource/inter/600.css'; -const Intl = ({ children }) => { - const { locale, messages } = useLocale(); - - const Wrapper = ({ children }) => {children}; - - return ( - - {children} - - ); -}; - export default function App({ Component, pageProps }) { + const { locale, messages } = useLocale(); const { basePath } = useRouter(); const { dir } = useLocale(); + useConfig(); + + const Wrapper = ({ children }) => {children}; if (process.env.uiDisabled) { return null; } return ( - + @@ -45,6 +38,6 @@ export default function App({ Component, pageProps }) {
-
+ ); } diff --git a/pages/sso.js b/pages/sso.js new file mode 100644 index 00000000..c2c337ab --- /dev/null +++ b/pages/sso.js @@ -0,0 +1,38 @@ +import { useEffect } from 'react'; +import debug from 'debug'; +import { useRouter } from 'next/router'; +import { setItem } from 'next-basics'; +import { AUTH_TOKEN } from 'lib/constants'; +import useApi from 'hooks/useApi'; +import { setUser } from 'store/app'; + +const log = debug('umami:sso'); + +export default function SingleSignOnPage() { + const router = useRouter(); + const { get } = useApi(); + const { token, url } = router.query; + + useEffect(() => { + async function verify() { + setItem(AUTH_TOKEN, token); + + const { ok, data } = await get('/auth/verify'); + + if (ok) { + log(data); + setUser(data); + + if (url) { + await router.push(url); + } + } + } + + if (token) { + verify(); + } + }, [token]); + + return null; +} diff --git a/yarn.lock b/yarn.lock index ef95aaec..5aa6d841 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5244,10 +5244,10 @@ natural-compare@^1.4.0: resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -next-basics@^0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/next-basics/-/next-basics-0.18.0.tgz#7683ec67d562fb57a6f3fb346c989802157450d1" - integrity sha512-KJZjAHahQ++YYaSPuJVAY0wH9QYXVq85ZUGW5mBMq+qDfL8ZVG4nTWc8GhuI8EYLLR+oZp/eInvoqYgiW/dbhg== +next-basics@^0.20.0: + version "0.20.0" + resolved "https://registry.yarnpkg.com/next-basics/-/next-basics-0.20.0.tgz#f88791dcc538438b5044695e37d58b4fdccc6dd8" + integrity sha512-KPqVVSzkKUvu9shvZt5Bp7Xv1nZ2xJRRqwqQ+a6a5JjsdE10Q3p07VLrT2ykl+v/CvR4sz98c0n+MaWpgO3Ckw== dependencies: base-x "^4.0.0" bcryptjs "^2.4.3" From d5fd3336335ad729f832a90cf92c99d9156692bb Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Mon, 31 Oct 2022 20:33:06 -0700 Subject: [PATCH 007/452] Bump version v2.0.0-beta.1. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f1dee3c8..0cb823c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "umami", - "version": "1.39.4", + "version": "2.0.0-beta.1", "description": "A simple, fast, privacy-focused alternative to Google Analytics.", "author": "Mike Cao ", "license": "MIT", From 17041efaaed7101405ed1bc4e513677cccd55891 Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Mon, 31 Oct 2022 23:42:37 -0700 Subject: [PATCH 008/452] use uuid --- README.md | 5 +- components/forms/ChangePasswordForm.js | 2 +- components/forms/TrackingCodeForm.js | 2 +- .../{AccountEditForm.js => UserEditForm.js} | 4 +- components/forms/WebsiteEditForm.js | 14 +- components/metrics/RealtimeHeader.js | 4 +- components/pages/DashboardEdit.js | 12 +- components/pages/RealtimeDashboard.js | 16 +- components/pages/Settings.js | 8 +- components/pages/TestConsole.js | 12 +- components/pages/WebsiteList.js | 8 +- .../{AccountSettings.js => UserSettings.js} | 54 ++--- ...ngs.module.css => UserSettings.module.css} | 0 components/settings/WebsiteSettings.js | 30 +-- .../migrations/01_init/migration.sql | 132 ---------- .../02_add_event_data/migration.sql | 66 ----- .../03_remove_casade_delete/migration.sql | 35 --- .../migrations/04_add_uuid/migration.sql | 38 --- db/postgresql/migrations/migration_lock.toml | 3 - db/postgresql/schema.prisma | 226 +++++++++++++----- interface/auth.d.ts | 5 + interface/base.d.ts | 22 ++ interface/index.d.ts | 22 ++ lib/auth.js | 8 +- lib/constants.js | 2 +- lib/redis.js | 31 +-- lib/session.js | 44 ++-- next-env.d.ts | 5 + pages/api/auth/login.js | 11 +- pages/api/collect.js | 12 +- pages/api/realtime/init.js | 2 +- pages/api/share/[id].js | 8 +- pages/api/{accounts => users}/[id]/index.js | 20 +- .../api/{accounts => users}/[id]/password.js | 10 +- pages/api/{accounts => users}/index.js | 18 +- pages/api/websites/[id]/index.js | 26 +- pages/api/websites/[id]/metrics.js | 2 +- pages/api/websites/index.js | 21 +- pages/settings/{accounts.js => users.js} | 0 queries/admin/account/createAccount.js | 7 - queries/admin/account/getAccount.js | 7 - queries/admin/account/updateAccount.js | 8 - queries/admin/user/createUser.js | 7 + .../deleteAccount.js => user/deleteUser.js} | 13 +- queries/admin/user/getUser.js | 7 + .../getAccounts.js => user/getUsers.js} | 6 +- queries/admin/user/updateUser.js | 8 + queries/admin/website/createWebsite.js | 4 +- queries/admin/website/deleteWebsite.js | 14 +- queries/admin/website/getAllWebsites.js | 4 +- queries/admin/website/getWebsite.js | 2 +- queries/admin/website/resetWebsite.js | 10 +- queries/analytics/event/getEventData.js | 2 +- queries/analytics/event/getEventMetrics.js | 2 +- queries/analytics/event/getEvents.js | 2 +- queries/analytics/event/saveEvent.js | 9 +- .../analytics/pageview/getPageviewMetrics.js | 2 +- .../analytics/pageview/getPageviewParams.js | 2 +- .../analytics/pageview/getPageviewStats.js | 2 +- queries/analytics/pageview/getPageviews.js | 2 +- queries/analytics/pageview/savePageView.js | 12 +- queries/analytics/session/createSession.js | 9 +- .../{getSessionByUuid.js => getSession.js} | 10 +- .../analytics/session/getSessionMetrics.js | 2 +- queries/analytics/session/getSessions.js | 2 +- queries/analytics/stats/getActiveVisitors.js | 2 +- queries/analytics/stats/getWebsiteStats.js | 2 +- queries/index.js | 12 +- scripts/change-password.js | 10 +- scripts/check-db.js | 2 +- sql/schema.mysql.sql | 102 -------- sql/schema.postgresql.sql | 132 ---------- tracker/index.js | 8 +- 73 files changed, 491 insertions(+), 874 deletions(-) rename components/forms/{AccountEditForm.js => UserEditForm.js} (93%) rename components/settings/{AccountSettings.js => UserSettings.js} (68%) rename components/settings/{AccountSettings.module.css => UserSettings.module.css} (100%) delete mode 100644 db/postgresql/migrations/01_init/migration.sql delete mode 100644 db/postgresql/migrations/02_add_event_data/migration.sql delete mode 100644 db/postgresql/migrations/03_remove_casade_delete/migration.sql delete mode 100644 db/postgresql/migrations/04_add_uuid/migration.sql delete mode 100644 db/postgresql/migrations/migration_lock.toml create mode 100644 interface/auth.d.ts create mode 100644 interface/base.d.ts create mode 100644 interface/index.d.ts create mode 100644 next-env.d.ts rename pages/api/{accounts => users}/[id]/index.js (65%) rename pages/api/{accounts => users}/[id]/password.js (70%) rename pages/api/{accounts => users}/index.js (56%) rename pages/settings/{accounts.js => users.js} (100%) delete mode 100644 queries/admin/account/createAccount.js delete mode 100644 queries/admin/account/getAccount.js delete mode 100644 queries/admin/account/updateAccount.js create mode 100644 queries/admin/user/createUser.js rename queries/admin/{account/deleteAccount.js => user/deleteUser.js} (73%) create mode 100644 queries/admin/user/getUser.js rename queries/admin/{account/getAccounts.js => user/getUsers.js} (64%) create mode 100644 queries/admin/user/updateUser.js rename queries/analytics/session/{getSessionByUuid.js => getSession.js} (83%) delete mode 100644 sql/schema.mysql.sql delete mode 100644 sql/schema.postgresql.sql diff --git a/README.md b/README.md index 5fe9dd96..70576b8c 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ DATABASE_URL=connection-url ``` The connection url is in the following format: + ``` postgresql://username:mypassword@localhost:5432/mydb @@ -48,7 +49,7 @@ mysql://username:mypassword@localhost:3306/mydb yarn build ``` -The build step will also create tables in your database if you ae installing for the first time. It will also create a login account with username **admin** and password **umami**. +The build step will also create tables in your database if you ae installing for the first time. It will also create a login user with username **admin** and password **umami**. ### Start the application @@ -69,11 +70,13 @@ docker compose up ``` Alternatively, to pull just the Umami Docker image with PostgreSQL support: + ```bash docker pull docker.umami.is/umami-software/umami:postgresql-latest ``` Or with MySQL support: + ```bash docker pull docker.umami.is/umami-software/umami:mysql-latest ``` diff --git a/components/forms/ChangePasswordForm.js b/components/forms/ChangePasswordForm.js index dcad6f17..8942ecf6 100644 --- a/components/forms/ChangePasswordForm.js +++ b/components/forms/ChangePasswordForm.js @@ -43,7 +43,7 @@ export default function ChangePasswordForm({ values, onSave, onClose }) { const { user } = useUser(); const handleSubmit = async values => { - const { ok, error } = await post(`/accounts/${user.accountUuid}/password`, values); + const { ok, error } = await post(`/users/${user.id}/password`, values); if (ok) { onSave(); diff --git a/components/forms/TrackingCodeForm.js b/components/forms/TrackingCodeForm.js index 52df3bde..5a098b8d 100644 --- a/components/forms/TrackingCodeForm.js +++ b/components/forms/TrackingCodeForm.js @@ -26,7 +26,7 @@ export default function TrackingCodeForm({ values, onClose }) { rows={3} cols={60} spellCheck={false} - defaultValue={``} readOnly diff --git a/components/forms/AccountEditForm.js b/components/forms/UserEditForm.js similarity index 93% rename from components/forms/AccountEditForm.js rename to components/forms/UserEditForm.js index 70125656..0d7e392f 100644 --- a/components/forms/AccountEditForm.js +++ b/components/forms/UserEditForm.js @@ -28,13 +28,13 @@ const validate = ({ id, username, password }) => { return errors; }; -export default function AccountEditForm({ values, onSave, onClose }) { +export default function UserEditForm({ values, onSave, onClose }) { const { post } = useApi(); const [message, setMessage] = useState(); const handleSubmit = async values => { const { id } = values; - const { ok, data } = await post(id ? `/accounts/${id}` : '/accounts', values); + const { ok, data } = await post(id ? `/users/${id}` : '/users', values); if (ok) { onSave(); diff --git a/components/forms/WebsiteEditForm.js b/components/forms/WebsiteEditForm.js index f13d0aa0..491a8bfe 100644 --- a/components/forms/WebsiteEditForm.js +++ b/components/forms/WebsiteEditForm.js @@ -37,7 +37,7 @@ const validate = ({ name, domain }) => { return errors; }; -const OwnerDropDown = ({ user, accounts }) => { +const OwnerDropDown = ({ user, users }) => { const { setFieldValue, values } = useFormikContext(); useEffect(() => { @@ -46,7 +46,7 @@ const OwnerDropDown = ({ user, accounts }) => { } else if (user?.id && values.owner === '') { setFieldValue('owner', user.id.toString()); } - }, [accounts, setFieldValue, user, values]); + }, [users, setFieldValue, user, values]); if (user?.isAdmin) { return ( @@ -56,7 +56,7 @@ const OwnerDropDown = ({ user, accounts }) => {
- {accounts?.map(acc => ( + {users?.map(acc => ( @@ -73,14 +73,14 @@ const OwnerDropDown = ({ user, accounts }) => { export default function WebsiteEditForm({ values, onSave, onClose }) { const { post } = useApi(); - const { data: accounts } = useFetch(`/accounts`); + const { data: users } = useFetch(`/users`); const { user } = useUser(); const [message, setMessage] = useState(); const handleSubmit = async values => { - const { websiteUuid: websiteId } = values; + const { id } = values; - const { ok, data } = await post(websiteId ? `/websites/${websiteId}` : '/websites', values); + const { ok, data } = await post(id ? `/websites/${id}` : '/websites', values); if (ok) { onSave(); @@ -125,7 +125,7 @@ export default function WebsiteEditForm({ values, onSave, onClose }) {
- +