diff --git a/next.config.ts b/next.config.ts index f2c07aff..77a0c1c6 100644 --- a/next.config.ts +++ b/next.config.ts @@ -13,12 +13,8 @@ const cloudMode = process.env.CLOUD_MODE; const cloudUrl = process.env.CLOUD_URL; const corsMaxAge = process.env.CORS_MAX_AGE; const defaultLocale = process.env.DEFAULT_LOCALE; -const disableLogin = process.env.DISABLE_LOGIN; -const disableUI = process.env.DISABLE_UI; -const faviconURL = process.env.FAVICON_URL; const forceSSL = process.env.FORCE_SSL; const frameAncestors = process.env.ALLOWED_FRAME_URLS ?? ''; -const privateMode = process.env.PRIVATE_MODE; const trackerScriptName = process.env.TRACKER_SCRIPT_NAME; const trackerScriptURL = process.env.TRACKER_SCRIPT_URL; @@ -168,13 +164,11 @@ if (cloudMode && cloudUrl) { permanent: false, }); - if (disableLogin) { - redirects.push({ - source: '/login', - destination: cloudUrl, - permanent: false, - }); - } + redirects.push({ + source: '/login', + destination: cloudUrl, + permanent: false, + }); } /** @type {import('next').NextConfig} */ @@ -186,10 +180,6 @@ export default { cloudUrl, currentVersion: pkg.version, defaultLocale, - disableLogin, - disableUI, - faviconURL, - privateMode, }, basePath, output: 'standalone', diff --git a/src/app/(main)/App.tsx b/src/app/(main)/App.tsx index 53d305fe..e3602d5a 100644 --- a/src/app/(main)/App.tsx +++ b/src/app/(main)/App.tsx @@ -25,10 +25,6 @@ export function App({ children }) { return null; } - if (config.uiDisabled) { - return null; - } - return ( diff --git a/src/app/(main)/UpdateNotice.tsx b/src/app/(main)/UpdateNotice.tsx index ed163d52..35728791 100644 --- a/src/app/(main)/UpdateNotice.tsx +++ b/src/app/(main)/UpdateNotice.tsx @@ -11,13 +11,14 @@ export function UpdateNotice({ user, config }) { const { latest, checked, hasUpdate, releaseUrl } = useVersion(); const pathname = usePathname(); const [dismissed, setDismissed] = useState(checked); + const allowUpdate = process.env.NODE_ENV === 'production' && user?.isAdmin && !config?.updatesDisabled && + !config?.privateMode && !pathname.includes('/share/') && !process.env.cloudMode && - !process.env.privateMode && !dismissed; const updateCheck = useCallback(() => { diff --git a/src/app/actions/getConfig.ts b/src/app/actions/getConfig.ts index 7a16a3a4..cc99dd9f 100644 --- a/src/app/actions/getConfig.ts +++ b/src/app/actions/getConfig.ts @@ -1,10 +1,19 @@ 'use server'; -export async function getConfig() { +export type Config = { + faviconUrl: string | undefined; + privateMode: boolean; + telemetryDisabled: boolean; + trackerScriptName: string | undefined; + updatesDisabled: boolean; +}; + +export async function getConfig(): Promise { return { + faviconUrl: process.env.FAVICON_URL, + privateMode: !!process.env.PRIVATE_MODE, telemetryDisabled: !!process.env.DISABLE_TELEMETRY, trackerScriptName: process.env.TRACKER_SCRIPT_NAME, - uiDisabled: !!process.env.DISABLE_UI, updatesDisabled: !!process.env.DISABLE_UPDATES, loginDisabled: !!process.env.DISABLE_LOGIN, }; diff --git a/src/app/api/scripts/telemetry/route.ts b/src/app/api/scripts/telemetry/route.ts index 54cee565..b19e99f1 100644 --- a/src/app/api/scripts/telemetry/route.ts +++ b/src/app/api/scripts/telemetry/route.ts @@ -2,25 +2,25 @@ import { CURRENT_VERSION, TELEMETRY_PIXEL } from '@/lib/constants'; export async function GET() { if ( - process.env.NODE_ENV !== 'production' && - process.env.DISABLE_TELEMETRY && + process.env.NODE_ENV !== 'production' || + process.env.DISABLE_TELEMETRY || process.env.PRIVATE_MODE ) { - const script = ` - (()=>{const i=document.createElement('img'); - i.setAttribute('src','${TELEMETRY_PIXEL}?v=${CURRENT_VERSION}'); - i.setAttribute('style','width:0;height:0;position:absolute;pointer-events:none;'); - document.body.appendChild(i);})(); - `; - - return new Response(script.replace(/\s\s+/g, ''), { + return new Response('/* telemetry disabled */', { headers: { 'content-type': 'text/javascript', }, }); } - return new Response('/* telemetry disabled */', { + const script = ` + (()=>{const i=document.createElement('img'); + i.setAttribute('src','${TELEMETRY_PIXEL}?v=${CURRENT_VERSION}'); + i.setAttribute('style','width:0;height:0;position:absolute;pointer-events:none;'); + document.body.appendChild(i);})(); + `; + + return new Response(script.replace(/\s\s+/g, ''), { headers: { 'content-type': 'text/javascript', }, diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 448915eb..b2430cc2 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -9,6 +9,14 @@ import '@/styles/global.css'; import '@/styles/variables.css'; export default function ({ children }) { + if (process.env.DISABLE_UI) { + return ( + + + + ); + } + return ( diff --git a/src/app/login/LoginPage.tsx b/src/app/login/LoginPage.tsx index a4fc9b55..83d17bd4 100644 --- a/src/app/login/LoginPage.tsx +++ b/src/app/login/LoginPage.tsx @@ -3,10 +3,6 @@ import { Column } from '@umami/react-zen'; import { LoginForm } from './LoginForm'; export function LoginPage() { - if (process.env.disableLogin) { - return null; - } - return ( diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 364561f1..4c8d8044 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -2,6 +2,10 @@ import { Metadata } from 'next'; import { LoginPage } from './LoginPage'; export default async function () { + if (process.env.DISABLE_LOGIN) { + return null; + } + return ; } diff --git a/src/app/logout/LogoutPage.tsx b/src/app/logout/LogoutPage.tsx index 082e0c6d..46988671 100644 --- a/src/app/logout/LogoutPage.tsx +++ b/src/app/logout/LogoutPage.tsx @@ -6,9 +6,9 @@ import { setUser } from '@/store/app'; import { removeClientAuthToken } from '@/lib/client'; export function LogoutPage() { - const disabled = !!(process.env.disableLogin || process.env.cloudMode); const router = useRouter(); const { post } = useApi(); + const disabled = process.env.cloudMode; useEffect(() => { async function logout() { diff --git a/src/app/logout/page.tsx b/src/app/logout/page.tsx index f9280d0d..7b56ea67 100644 --- a/src/app/logout/page.tsx +++ b/src/app/logout/page.tsx @@ -2,6 +2,10 @@ import { LogoutPage } from './LogoutPage'; import { Metadata } from 'next'; export default function () { + if (process.env.DISABLE_LOGIN) { + return null; + } + return ; } diff --git a/src/components/common/Favicon.tsx b/src/components/common/Favicon.tsx index c6d3db0d..a6b5e522 100644 --- a/src/components/common/Favicon.tsx +++ b/src/components/common/Favicon.tsx @@ -1,3 +1,4 @@ +import { useConfig } from '@/components/hooks'; import { FAVICON_URL, GROUPED_DOMAINS } from '@/lib/constants'; function getHostName(url: string) { @@ -6,11 +7,13 @@ function getHostName(url: string) { } export function Favicon({ domain, ...props }) { - if (process.env.privateMode) { + const config = useConfig(); + + if (config?.privateMode) { return null; } - const url = process.env.faviconURL || FAVICON_URL; + const url = config?.faviconUrl || FAVICON_URL; const hostName = domain ? getHostName(domain) : null; const domainName = GROUPED_DOMAINS[hostName]?.domain || hostName; const src = hostName ? url.replace(/\{\{\s*domain\s*}}/, domainName) : null; diff --git a/src/components/hooks/useConfig.ts b/src/components/hooks/useConfig.ts index b0fe287e..46c815d6 100644 --- a/src/components/hooks/useConfig.ts +++ b/src/components/hooks/useConfig.ts @@ -1,8 +1,8 @@ import { useEffect } from 'react'; import { useApp, setConfig } from '@/store/app'; -import { getConfig } from '@/app/actions/getConfig'; +import { getConfig, Config } from '@/app/actions/getConfig'; -export function useConfig() { +export function useConfig(): Config { const { config } = useApp(); async function loadConfig() { diff --git a/src/lib/constants.ts b/src/lib/constants.ts index b5350872..1564458d 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -13,7 +13,7 @@ export const UPDATES_URL = 'https://api.umami.is/v1/updates'; export const TELEMETRY_PIXEL = 'https://i.umami.is/a.png'; export const FAVICON_URL = 'https://icons.duckduckgo.com/ip3/{{domain}}.ico'; -export const DEFAULT_LOCALE = process.env.defaultLocale || 'en-US'; +export const DEFAULT_LOCALE = 'en-US'; export const DEFAULT_THEME = 'light'; export const DEFAULT_ANIMATION_DURATION = 300; export const DEFAULT_DATE_RANGE_VALUE = '24hour'; diff --git a/src/store/app.ts b/src/store/app.ts index 56bd589e..3f22756d 100644 --- a/src/store/app.ts +++ b/src/store/app.ts @@ -20,7 +20,7 @@ function getDefaultTheme() { } const initialState = { - locale: getItem(LOCALE_CONFIG) || DEFAULT_LOCALE, + locale: getItem(LOCALE_CONFIG) || process.env.defaultLocale || DEFAULT_LOCALE, theme: getItem(THEME_CONFIG) || getDefaultTheme() || DEFAULT_THEME, timezone: getItem(TIMEZONE_CONFIG) || getTimezone(), dateRangeValue: getItem(DATE_RANGE_CONFIG) || DEFAULT_DATE_RANGE_VALUE,