diff --git a/next.config.mjs b/next.config.mjs index 69ce52be..7f402008 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -12,12 +12,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; @@ -173,13 +169,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} */ @@ -191,10 +185,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 4cbb1c80..b4cbdfde 100644 --- a/src/app/(main)/App.tsx +++ b/src/app/(main)/App.tsx @@ -22,10 +22,6 @@ export function App({ children }) { return null; } - if (config.uiDisabled) { - return null; - } - return ( <> {children} diff --git a/src/app/(main)/UpdateNotice.tsx b/src/app/(main)/UpdateNotice.tsx index 17c2bce7..ea102faa 100644 --- a/src/app/(main)/UpdateNotice.tsx +++ b/src/app/(main)/UpdateNotice.tsx @@ -13,13 +13,14 @@ export function UpdateNotice({ user, config }) { const { latest, checked, hasUpdate, releaseUrl } = useStore(); 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/(main)/profile/LanguageSetting.tsx b/src/app/(main)/profile/LanguageSetting.tsx index a47394b3..fd8699fd 100644 --- a/src/app/(main)/profile/LanguageSetting.tsx +++ b/src/app/(main)/profile/LanguageSetting.tsx @@ -9,6 +9,7 @@ export function LanguageSetting() { const [search, setSearch] = useState(''); const { formatMessage, labels } = useMessages(); const { locale, saveLocale } = useLocale(); + const options = search ? Object.keys(languages).filter(n => { return ( diff --git a/src/app/actions/getConfig.ts b/src/app/actions/getConfig.ts index bb892f01..32b8a7d0 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, }; } 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 ebe313e6..e939f8c4 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -9,6 +9,14 @@ import '@/styles/index.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 8ea0b4e2..2eca070f 100644 --- a/src/app/login/LoginPage.tsx +++ b/src/app/login/LoginPage.tsx @@ -3,10 +3,6 @@ import LoginForm from './LoginForm'; import styles from './LoginPage.module.css'; 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 6f34d987..cca230c2 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 d3dc481a..2914c4eb 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 a253049a..80a61f52 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 c02fe74f..ce2d0d57 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/queries/useConfig.ts b/src/components/hooks/queries/useConfig.ts index 223f4550..9533d616 100644 --- a/src/components/hooks/queries/useConfig.ts +++ b/src/components/hooks/queries/useConfig.ts @@ -1,8 +1,8 @@ import { useEffect } from 'react'; import useStore, { 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 } = useStore(); async function loadConfig() { diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 7fd1a85d..7ac1d2ab 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 = '24hour'; diff --git a/src/store/app.ts b/src/store/app.ts index 0890b7e9..1908023f 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(), dateRange: getItem(DATE_RANGE_CONFIG) || DEFAULT_DATE_RANGE,