render login page on SERVER_LOCK (#1172)

This commit is contained in:
jeffvli
2025-12-09 19:58:24 -08:00
parent 8a681a7e95
commit 389dfd08f7
9 changed files with 27 additions and 56 deletions
@@ -1,7 +1,6 @@
import { ReactNode } from 'react'; import { ReactNode } from 'react';
import { Group } from '/@/shared/components/group/group'; import { Group } from '/@/shared/components/group/group';
import { Icon } from '/@/shared/components/icon/icon';
import { Stack } from '/@/shared/components/stack/stack'; import { Stack } from '/@/shared/components/stack/stack';
import { Text } from '/@/shared/components/text/text'; import { Text } from '/@/shared/components/text/text';
@@ -13,7 +12,6 @@ interface ActionRequiredContainerProps {
export const ActionRequiredContainer = ({ children, title }: ActionRequiredContainerProps) => ( export const ActionRequiredContainer = ({ children, title }: ActionRequiredContainerProps) => (
<Stack style={{ cursor: 'default', maxWidth: '700px' }}> <Stack style={{ cursor: 'default', maxWidth: '700px' }}>
<Group> <Group>
<Icon fill="warn" icon="warn" size="lg" />
<Text size="xl" style={{ textTransform: 'uppercase' }}> <Text size="xl" style={{ textTransform: 'uppercase' }}>
{title} {title}
</Text> </Text>
@@ -28,20 +28,14 @@ const localSettings = isElectron() ? window.api.localSettings : null;
export const ServerRequired = () => { export const ServerRequired = () => {
const serverList = useServerList(); const serverList = useServerList();
const serverLock = const isServerLock = Boolean(window.SERVER_LOCK) || false;
(localSettings
? !!localSettings.env.SERVER_LOCK
: !!window.SERVER_LOCK &&
window.SERVER_TYPE &&
window.SERVER_NAME &&
window.SERVER_URL) || false;
if (Object.keys(serverList).length > 0) { if (Object.keys(serverList).length > 1) {
return ( return (
<ScrollArea> <ScrollArea>
<Stack miw="300px"> <Stack miw="300px">
<ServerSelector /> <ServerSelector />
{!serverLock && ( {!isServerLock && (
<> <>
<Divider my="lg" /> <Divider my="lg" />
<AddServerForm onCancel={null} /> <AddServerForm onCancel={null} />
@@ -1,5 +1,4 @@
import { openModal } from '@mantine/modals'; import { openModal } from '@mantine/modals';
import isElectron from 'is-electron';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Navigate } from 'react-router'; import { Navigate } from 'react-router';
@@ -7,6 +6,7 @@ import { PageHeader } from '/@/renderer/components/page-header/page-header';
import { ActionRequiredContainer } from '/@/renderer/features/action-required/components/action-required-container'; import { ActionRequiredContainer } from '/@/renderer/features/action-required/components/action-required-container';
import { ServerCredentialRequired } from '/@/renderer/features/action-required/components/server-credential-required'; import { ServerCredentialRequired } from '/@/renderer/features/action-required/components/server-credential-required';
import { ServerRequired } from '/@/renderer/features/action-required/components/server-required'; import { ServerRequired } from '/@/renderer/features/action-required/components/server-required';
import LoginRoute from '/@/renderer/features/login/routes/login-route';
import { ServerList } from '/@/renderer/features/servers/components/server-list'; import { ServerList } from '/@/renderer/features/servers/components/server-list';
import { AnimatedPage } from '/@/renderer/features/shared/components/animated-page'; import { AnimatedPage } from '/@/renderer/features/shared/components/animated-page';
import { PageErrorBoundary } from '/@/renderer/features/shared/components/page-error-boundary'; import { PageErrorBoundary } from '/@/renderer/features/shared/components/page-error-boundary';
@@ -18,14 +18,15 @@ import { Group } from '/@/shared/components/group/group';
import { Icon } from '/@/shared/components/icon/icon'; import { Icon } from '/@/shared/components/icon/icon';
import { Stack } from '/@/shared/components/stack/stack'; import { Stack } from '/@/shared/components/stack/stack';
const localSettings = isElectron() ? window.api.localSettings : null;
const ActionRequiredRoute = () => { const ActionRequiredRoute = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const currentServer = useCurrentServerWithCredential(); const currentServer = useCurrentServerWithCredential();
const isServerRequired = !currentServer; const isServerRequired = !currentServer;
const isCredentialRequired = currentServer && !currentServer.credential; const isCredentialRequired = currentServer && !currentServer.credential;
const isServerLock = Boolean(window.SERVER_LOCK) || false;
const isLoginRequired = isServerLock && !currentServer;
const checks = [ const checks = [
{ {
component: <ServerCredentialRequired />, component: <ServerCredentialRequired />,
@@ -49,6 +50,10 @@ const ActionRequiredRoute = () => {
}); });
}; };
if (isLoginRequired) {
return <LoginRoute />;
}
return ( return (
<AnimatedPage> <AnimatedPage>
<PageHeader /> <PageHeader />
@@ -64,7 +69,7 @@ const ActionRequiredRoute = () => {
<Stack mt="2rem"> <Stack mt="2rem">
{canReturnHome && <Navigate to={AppRoute.HOME} />} {canReturnHome && <Navigate to={AppRoute.HOME} />}
{/* This should be displayed if a credential is required */} {/* This should be displayed if a credential is required */}
{isCredentialRequired && !localSettings?.env.SERVER_LOCK && ( {isCredentialRequired && !isServerLock && (
<Group justify="center" wrap="nowrap"> <Group justify="center" wrap="nowrap">
<Button <Button
fullWidth fullWidth
@@ -48,18 +48,16 @@ const LoginRoute = () => {
const currentServer = useCurrentServer(); const currentServer = useCurrentServer();
// Check if server lock is configured // Check if server lock is configured
const serverLock = localSettings?.env.SERVER_LOCK || false; const isServerLock = Boolean(window.SERVER_LOCK) || false;
const serverType = localSettings?.env.SERVER_TYPE const serverType = window.SERVER_TYPE ? toServerType(window.SERVER_TYPE) : null;
? toServerType(localSettings.env.SERVER_TYPE) const serverName = window.SERVER_NAME || '';
: null; const serverUrl = window.SERVER_URL || '';
const serverName = localSettings?.env.SERVER_NAME || '';
const serverUrl = localSettings?.env.SERVER_URL || '';
const config = [ const config = [
{ {
isValid: true, isValid: true,
key: 'SERVER_LOCK', key: 'SERVER_LOCK',
value: serverLock, value: isServerLock,
}, },
{ {
isValid: serverType !== null, isValid: serverType !== null,
@@ -1,5 +1,4 @@
import { openModal } from '@mantine/modals'; import { openModal } from '@mantine/modals';
import isElectron from 'is-electron';
import { Dispatch, useCallback } from 'react'; import { Dispatch, useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router'; import { useNavigate } from 'react-router';
@@ -10,8 +9,6 @@ import { AppRoute } from '/@/renderer/router/routes';
import { useAuthStoreActions, useServerList } from '/@/renderer/store'; import { useAuthStoreActions, useServerList } from '/@/renderer/store';
import { ServerListItemWithCredential } from '/@/shared/types/domain-types'; import { ServerListItemWithCredential } from '/@/shared/types/domain-types';
const localSettings = isElectron() ? window.api.localSettings : null;
interface ServerCommandsProps { interface ServerCommandsProps {
handleClose: () => void; handleClose: () => void;
setPages: (pages: CommandPalettePages[]) => void; setPages: (pages: CommandPalettePages[]) => void;
@@ -45,7 +42,7 @@ export const ServerCommands = ({ handleClose, setPages, setQuery }: ServerComman
[handleClose, navigate, setCurrentServer, setPages, setQuery], [handleClose, navigate, setCurrentServer, setPages, setQuery],
); );
const serverLock = localSettings?.env.SERVER_LOCK || false; const isServerLock = Boolean(window.SERVER_LOCK) || false;
return ( return (
<> <>
@@ -59,7 +56,7 @@ export const ServerCommands = ({ handleClose, setPages, setQuery }: ServerComman
>{`${serverList[key].name}...`}</Command.Item> >{`${serverList[key].name}...`}</Command.Item>
))} ))}
</Command.Group> </Command.Group>
{!serverLock && ( {!isServerLock && (
<Command.Group heading={t('common.manage', { postProcess: 'sentenceCase' })}> <Command.Group heading={t('common.manage', { postProcess: 'sentenceCase' })}>
<Command.Item onSelect={handleManageServersModal}> <Command.Item onSelect={handleManageServersModal}>
{t('page.appMenu.manageServers', { postProcess: 'sentenceCase' })}... {t('page.appMenu.manageServers', { postProcess: 'sentenceCase' })}...
@@ -112,13 +112,7 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => {
}); });
// server lock for web is only true if lock is true *and* all other properties are set // server lock for web is only true if lock is true *and* all other properties are set
const serverLock = const isServerLock = Boolean(window.SERVER_LOCK) || false;
(localSettings
? !!localSettings.env.SERVER_LOCK
: !!window.SERVER_LOCK &&
window.SERVER_TYPE &&
window.SERVER_NAME &&
window.SERVER_URL) || false;
const isSubmitDisabled = !form.values.name || !form.values.url || !form.values.username; const isSubmitDisabled = !form.values.name || !form.values.url || !form.values.username;
@@ -227,7 +221,7 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => {
<Stack m={5} ref={focusTrapRef}> <Stack m={5} ref={focusTrapRef}>
<SegmentedControl <SegmentedControl
data={ALL_SERVERS} data={ALL_SERVERS}
disabled={Boolean(serverLock)} disabled={isServerLock}
p="md" p="md"
withItemsBorders={false} withItemsBorders={false}
{...form.getInputProps('type')} {...form.getInputProps('type')}
@@ -235,7 +229,7 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => {
<Group grow> <Group grow>
<TextInput <TextInput
data-autofocus data-autofocus
disabled={Boolean(serverLock)} disabled={isServerLock}
label={t('form.addServer.input', { label={t('form.addServer.input', {
context: 'name', context: 'name',
postProcess: 'titleCase', postProcess: 'titleCase',
@@ -244,7 +238,7 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => {
{...form.getInputProps('name')} {...form.getInputProps('name')}
/> />
<TextInput <TextInput
disabled={Boolean(serverLock)} disabled={isServerLock}
label={t('form.addServer.input', { label={t('form.addServer.input', {
context: 'url', context: 'url',
postProcess: 'titleCase', postProcess: 'titleCase',
@@ -1,6 +1,5 @@
import { openModal } from '@mantine/modals'; import { openModal } from '@mantine/modals';
import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useQuery, useQueryClient } from '@tanstack/react-query';
import isElectron from 'is-electron';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router'; import { useNavigate } from 'react-router';
@@ -17,8 +16,6 @@ import { Icon } from '/@/shared/components/icon/icon';
import { ServerListItemWithCredential, ServerType } from '/@/shared/types/domain-types'; import { ServerListItemWithCredential, ServerType } from '/@/shared/types/domain-types';
import { ServerFeature } from '/@/shared/types/features-types'; import { ServerFeature } from '/@/shared/types/features-types';
const localSettings = isElectron() ? window.api.localSettings : null;
export const ServerSelectorItems = () => { export const ServerSelectorItems = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const navigate = useNavigate(); const navigate = useNavigate();
@@ -91,7 +88,7 @@ export const ServerSelectorItems = () => {
}); });
}; };
const serverLock = localSettings?.env.SERVER_LOCK || false; const isServerLock = Boolean(window.SERVER_LOCK) || false;
return ( return (
<> <>
@@ -126,7 +123,7 @@ export const ServerSelectorItems = () => {
</DropdownMenu.Item> </DropdownMenu.Item>
); );
})} })}
{!serverLock && ( {!isServerLock && (
<DropdownMenu.Item <DropdownMenu.Item
leftSection={<Icon icon="edit" />} leftSection={<Icon icon="edit" />}
onClick={handleManageServersModal} onClick={handleManageServersModal}
@@ -13,8 +13,6 @@ import { DropdownMenu, MenuItemProps } from '/@/shared/components/dropdown-menu/
import { Icon } from '/@/shared/components/icon/icon'; import { Icon } from '/@/shared/components/icon/icon';
import { toast } from '/@/shared/components/toast/toast'; import { toast } from '/@/shared/components/toast/toast';
const localSettings = isElectron() ? window.api.localSettings : null;
const browser = isElectron() ? window.api.browser : null; const browser = isElectron() ? window.api.browser : null;
interface BaseMenuItem { interface BaseMenuItem {
@@ -177,7 +175,7 @@ export const AppMenu = () => {
type: 'divider', type: 'divider',
}, },
{ {
condition: !localSettings?.env.SERVER_LOCK, condition: !window.SERVER_LOCK,
id: 'manage-servers', id: 'manage-servers',
item: { item: {
label: t('page.appMenu.manageServers', { postProcess: 'sentenceCase' }), label: t('page.appMenu.manageServers', { postProcess: 'sentenceCase' }),
+1 -11
View File
@@ -1,4 +1,3 @@
import isElectron from 'is-electron';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { Navigate, Outlet } from 'react-router'; import { Navigate, Outlet } from 'react-router';
@@ -9,14 +8,10 @@ import { Center } from '/@/shared/components/center/center';
import { Spinner } from '/@/shared/components/spinner/spinner'; import { Spinner } from '/@/shared/components/spinner/spinner';
import { AuthState } from '/@/shared/types/types'; import { AuthState } from '/@/shared/types/types';
const localSettings = isElectron() ? window.api.localSettings : null;
export const AppOutlet = () => { export const AppOutlet = () => {
const currentServer = useCurrentServer(); const currentServer = useCurrentServer();
const authState = useServerAuthenticated(); const authState = useServerAuthenticated();
const serverLock = localSettings?.env.SERVER_LOCK || false;
const isActionsRequired = useMemo(() => { const isActionsRequired = useMemo(() => {
const isServerRequired = !currentServer; const isServerRequired = !currentServer;
@@ -34,12 +29,7 @@ export const AppOutlet = () => {
); );
} }
// When server lock is enabled always redirect to login if (isActionsRequired || authState === AuthState.INVALID) {
if (serverLock && !currentServer) {
return <Navigate replace to={AppRoute.LOGIN} />;
}
if (!serverLock && (isActionsRequired || authState === AuthState.INVALID)) {
return <Navigate replace to={AppRoute.ACTION_REQUIRED} />; return <Navigate replace to={AppRoute.ACTION_REQUIRED} />;
} }