Converted variables to be runtime.

This commit is contained in:
Mike Cao 2025-07-24 22:41:23 -07:00
parent b6862de2be
commit 5b6292dd11
11 changed files with 46 additions and 36 deletions

View file

@ -12,11 +12,8 @@ const cloudMode = process.env.CLOUD_MODE;
const cloudUrl = process.env.CLOUD_URL; const cloudUrl = process.env.CLOUD_URL;
const corsMaxAge = process.env.CORS_MAX_AGE; const corsMaxAge = process.env.CORS_MAX_AGE;
const defaultLocale = process.env.DEFAULT_LOCALE; const defaultLocale = process.env.DEFAULT_LOCALE;
const disableLogin = process.env.DISABLE_LOGIN;
const disableUI = process.env.DISABLE_UI;
const forceSSL = process.env.FORCE_SSL; const forceSSL = process.env.FORCE_SSL;
const frameAncestors = process.env.ALLOWED_FRAME_URLS ?? ''; const frameAncestors = process.env.ALLOWED_FRAME_URLS ?? '';
const privateMode = process.env.PRIVATE_MODE;
const trackerScriptName = process.env.TRACKER_SCRIPT_NAME; const trackerScriptName = process.env.TRACKER_SCRIPT_NAME;
const trackerScriptURL = process.env.TRACKER_SCRIPT_URL; const trackerScriptURL = process.env.TRACKER_SCRIPT_URL;
@ -172,13 +169,11 @@ if (cloudMode && cloudUrl) {
permanent: false, permanent: false,
}); });
if (disableLogin) { redirects.push({
redirects.push({ source: '/login',
source: '/login', destination: cloudUrl,
destination: cloudUrl, permanent: false,
permanent: false, });
});
}
} }
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
@ -190,9 +185,6 @@ export default {
cloudUrl, cloudUrl,
currentVersion: pkg.version, currentVersion: pkg.version,
defaultLocale, defaultLocale,
disableLogin,
disableUI,
privateMode,
}, },
basePath, basePath,
output: 'standalone', output: 'standalone',

View file

@ -13,13 +13,14 @@ export function UpdateNotice({ user, config }) {
const { latest, checked, hasUpdate, releaseUrl } = useStore(); const { latest, checked, hasUpdate, releaseUrl } = useStore();
const pathname = usePathname(); const pathname = usePathname();
const [dismissed, setDismissed] = useState(checked); const [dismissed, setDismissed] = useState(checked);
const allowUpdate = const allowUpdate =
process.env.NODE_ENV === 'production' && process.env.NODE_ENV === 'production' &&
user?.isAdmin && user?.isAdmin &&
!config?.updatesDisabled && !config?.updatesDisabled &&
!config?.privateMode &&
!pathname.includes('/share/') && !pathname.includes('/share/') &&
!process.env.cloudMode && !process.env.cloudMode &&
!process.env.privateMode &&
!dismissed; !dismissed;
const updateCheck = useCallback(() => { const updateCheck = useCallback(() => {

View file

@ -9,6 +9,7 @@ export function LanguageSetting() {
const [search, setSearch] = useState(''); const [search, setSearch] = useState('');
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const { locale, saveLocale } = useLocale(); const { locale, saveLocale } = useLocale();
const options = search const options = search
? Object.keys(languages).filter(n => { ? Object.keys(languages).filter(n => {
return ( return (

View file

@ -1,11 +1,23 @@
'use server'; 'use server';
export async function getConfig() { export type Config = {
faviconUrl: string | undefined;
loginDisabled: boolean;
privateMode: boolean;
telemetryDisabled: boolean;
trackerScriptName: string | undefined;
uiDisabled: boolean;
updatesDisabled: boolean;
};
export async function getConfig(): Promise<Config> {
return { return {
faviconUrl: process.env.FAVICON_URL,
loginDisabled: !!process.env.DISABLE_LOGIN,
privateMode: !!process.env.PRIVATE_MODE,
telemetryDisabled: !!process.env.DISABLE_TELEMETRY, telemetryDisabled: !!process.env.DISABLE_TELEMETRY,
trackerScriptName: process.env.TRACKER_SCRIPT_NAME, trackerScriptName: process.env.TRACKER_SCRIPT_NAME,
uiDisabled: !!process.env.DISABLE_UI, uiDisabled: !!process.env.DISABLE_UI,
updatesDisabled: !!process.env.DISABLE_UPDATES, updatesDisabled: !!process.env.DISABLE_UPDATES,
faviconUrl: process.env.FAVICON_URL,
}; };
} }

View file

@ -2,25 +2,25 @@ import { CURRENT_VERSION, TELEMETRY_PIXEL } from '@/lib/constants';
export async function GET() { export async function GET() {
if ( if (
process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'production' ||
process.env.DISABLE_TELEMETRY && process.env.DISABLE_TELEMETRY ||
process.env.PRIVATE_MODE process.env.PRIVATE_MODE
) { ) {
const script = ` return new Response('/* telemetry disabled */', {
(()=>{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: { headers: {
'content-type': 'text/javascript', '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: { headers: {
'content-type': 'text/javascript', 'content-type': 'text/javascript',
}, },

View file

@ -1,9 +1,12 @@
'use client'; 'use client';
import { useConfig } from '@/components/hooks';
import LoginForm from './LoginForm'; import LoginForm from './LoginForm';
import styles from './LoginPage.module.css'; import styles from './LoginPage.module.css';
export function LoginPage() { export function LoginPage() {
if (process.env.disableLogin) { const config = useConfig();
if (config?.loginDisabled) {
return null; return null;
} }

View file

@ -1,14 +1,15 @@
'use client'; 'use client';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useApi } from '@/components/hooks'; import { useApi, useConfig } from '@/components/hooks';
import { setUser } from '@/store/app'; import { setUser } from '@/store/app';
import { removeClientAuthToken } from '@/lib/client'; import { removeClientAuthToken } from '@/lib/client';
export function LogoutPage() { export function LogoutPage() {
const disabled = !!(process.env.disableLogin || process.env.cloudMode); const config = useConfig();
const router = useRouter(); const router = useRouter();
const { post } = useApi(); const { post } = useApi();
const disabled = !!(config?.loginDisabled || process.env.cloudMode);
useEffect(() => { useEffect(() => {
async function logout() { async function logout() {

View file

@ -9,11 +9,11 @@ function getHostName(url: string) {
export function Favicon({ domain, ...props }) { export function Favicon({ domain, ...props }) {
const config = useConfig(); const config = useConfig();
if (process.env.privateMode) { if (config?.privateMode) {
return null; return null;
} }
const url = config?.faviconURL || FAVICON_URL; const url = config?.faviconUrl || FAVICON_URL;
const hostName = domain ? getHostName(domain) : null; const hostName = domain ? getHostName(domain) : null;
const domainName = GROUPED_DOMAINS[hostName]?.domain || hostName; const domainName = GROUPED_DOMAINS[hostName]?.domain || hostName;
const src = hostName ? url.replace(/\{\{\s*domain\s*}}/, domainName) : null; const src = hostName ? url.replace(/\{\{\s*domain\s*}}/, domainName) : null;

View file

@ -1,8 +1,8 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import useStore, { setConfig } from '@/store/app'; 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(); const { config } = useStore();
async function loadConfig() { async function loadConfig() {

View file

@ -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 TELEMETRY_PIXEL = 'https://i.umami.is/a.png';
export const FAVICON_URL = 'https://icons.duckduckgo.com/ip3/{{domain}}.ico'; 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_THEME = 'light';
export const DEFAULT_ANIMATION_DURATION = 300; export const DEFAULT_ANIMATION_DURATION = 300;
export const DEFAULT_DATE_RANGE = '24hour'; export const DEFAULT_DATE_RANGE = '24hour';

View file

@ -20,7 +20,7 @@ function getDefaultTheme() {
} }
const initialState = { const initialState = {
locale: getItem(LOCALE_CONFIG) || DEFAULT_LOCALE, locale: getItem(LOCALE_CONFIG) || process.env.defaultLocale || DEFAULT_LOCALE,
theme: getItem(THEME_CONFIG) || getDefaultTheme() || DEFAULT_THEME, theme: getItem(THEME_CONFIG) || getDefaultTheme() || DEFAULT_THEME,
timezone: getItem(TIMEZONE_CONFIG) || getTimezone(), timezone: getItem(TIMEZONE_CONFIG) || getTimezone(),
dateRange: getItem(DATE_RANGE_CONFIG) || DEFAULT_DATE_RANGE, dateRange: getItem(DATE_RANGE_CONFIG) || DEFAULT_DATE_RANGE,