mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-22 03:44:34 +02:00
more potential fixes for server lock duplication
This commit is contained in:
@@ -0,0 +1,34 @@
|
|||||||
|
import { ServerListItemWithCredential } from '/@/shared/types/domain-types';
|
||||||
|
import { ServerType } from '/@/shared/types/types';
|
||||||
|
|
||||||
|
export const normalizeServerUrl = (url: string) => url.replace(/\/$/, '');
|
||||||
|
|
||||||
|
export const findExistingServerLockServer = (
|
||||||
|
serverList: Record<string, ServerListItemWithCredential>,
|
||||||
|
configuredUrl: string,
|
||||||
|
serverType?: null | ServerType,
|
||||||
|
): ServerListItemWithCredential | undefined => {
|
||||||
|
const servers = Object.values(serverList);
|
||||||
|
|
||||||
|
if (servers.length === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedUrl = normalizeServerUrl(configuredUrl);
|
||||||
|
const byUrl = servers.find((server) => normalizeServerUrl(server.url) === normalizedUrl);
|
||||||
|
|
||||||
|
if (byUrl) {
|
||||||
|
return byUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server lock allows only one server — reuse the existing entry even if the URL changed.
|
||||||
|
if (servers.length === 1) {
|
||||||
|
return servers[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serverType) {
|
||||||
|
return servers.find((server) => server.type === serverType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
@@ -6,6 +6,10 @@ import { Navigate } from 'react-router';
|
|||||||
|
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { PageHeader } from '/@/renderer/components/page-header/page-header';
|
import { PageHeader } from '/@/renderer/components/page-header/page-header';
|
||||||
|
import {
|
||||||
|
findExistingServerLockServer,
|
||||||
|
normalizeServerUrl,
|
||||||
|
} from '/@/renderer/features/action-required/utils/server-lock';
|
||||||
import {
|
import {
|
||||||
isLegacyAuth,
|
isLegacyAuth,
|
||||||
isServerLock,
|
isServerLock,
|
||||||
@@ -19,6 +23,7 @@ import { PageErrorBoundary } from '/@/renderer/features/shared/components/page-e
|
|||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import {
|
import {
|
||||||
getServerById,
|
getServerById,
|
||||||
|
useAuthStore,
|
||||||
useAuthStoreActions,
|
useAuthStoreActions,
|
||||||
useCurrentServer,
|
useCurrentServer,
|
||||||
useServerList,
|
useServerList,
|
||||||
@@ -51,12 +56,10 @@ const SERVER_NAMES: Record<ServerType, string> = {
|
|||||||
[ServerType.SUBSONIC]: 'OpenSubsonic',
|
[ServerType.SUBSONIC]: 'OpenSubsonic',
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizeUrl = (url: string) => url.replace(/\/$/, '');
|
|
||||||
|
|
||||||
const LoginRoute = () => {
|
const LoginRoute = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const { addServer, setCurrentServer, updateServer } = useAuthStoreActions();
|
const { addServer, deleteServer, setCurrentServer, updateServer } = useAuthStoreActions();
|
||||||
const currentServer = useCurrentServer();
|
const currentServer = useCurrentServer();
|
||||||
const serverList = useServerList();
|
const serverList = useServerList();
|
||||||
|
|
||||||
@@ -151,15 +154,16 @@ const LoginRoute = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const normalizedUrl = normalizeUrl(serverUrl);
|
const normalizedUrl = normalizeServerUrl(serverUrl);
|
||||||
const normalizedRemoteURL = normalizeUrl(remoteUrl);
|
const normalizedRemoteURL = normalizeServerUrl(remoteUrl);
|
||||||
const existingServer =
|
const existingServer = serverLock
|
||||||
serverLock &&
|
? findExistingServerLockServer(serverList, normalizedUrl, serverType)
|
||||||
Object.values(serverList).find((s) => normalizeUrl(s.url) === normalizedUrl);
|
: undefined;
|
||||||
|
|
||||||
|
const serverId = existingServer?.id ?? nanoid();
|
||||||
const serverItem: ServerListItemWithCredential = {
|
const serverItem: ServerListItemWithCredential = {
|
||||||
credential: data.credential,
|
credential: data.credential,
|
||||||
id: nanoid(),
|
id: serverId,
|
||||||
isAdmin: data.isAdmin,
|
isAdmin: data.isAdmin,
|
||||||
name: serverName,
|
name: serverName,
|
||||||
remoteUrl: normalizedRemoteURL,
|
remoteUrl: normalizedRemoteURL,
|
||||||
@@ -173,6 +177,9 @@ const LoginRoute = () => {
|
|||||||
const updates: Partial<ServerListItemWithCredential> = {
|
const updates: Partial<ServerListItemWithCredential> = {
|
||||||
credential: data.credential,
|
credential: data.credential,
|
||||||
isAdmin: data.isAdmin,
|
isAdmin: data.isAdmin,
|
||||||
|
name: serverName,
|
||||||
|
remoteUrl: normalizedRemoteURL,
|
||||||
|
url: normalizedUrl,
|
||||||
userId: data.userId,
|
userId: data.userId,
|
||||||
username: data.username,
|
username: data.username,
|
||||||
};
|
};
|
||||||
@@ -190,12 +197,20 @@ const LoginRoute = () => {
|
|||||||
setCurrentServer(serverItem);
|
setCurrentServer(serverItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (serverLock) {
|
||||||
|
Object.values(useAuthStore.getState().serverList).forEach((server) => {
|
||||||
|
if (server.id !== serverId) {
|
||||||
|
deleteServer(server.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
toast.success({
|
toast.success({
|
||||||
message: t('form.addServer.success'),
|
message: t('form.addServer.success'),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (localSettings && values.password) {
|
if (localSettings && values.password) {
|
||||||
const saved = await localSettings.passwordSet(values.password, serverItem.id);
|
const saved = await localSettings.passwordSet(values.password, serverId);
|
||||||
if (!saved) {
|
if (!saved) {
|
||||||
toast.error({
|
toast.error({
|
||||||
message: t('form.addServer.error', {
|
message: t('form.addServer.error', {
|
||||||
|
|||||||
@@ -2,12 +2,11 @@ import { useEffect, useMemo } from 'react';
|
|||||||
import { Navigate, Outlet } from 'react-router';
|
import { Navigate, Outlet } from 'react-router';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
|
|
||||||
|
import { normalizeServerUrl } from '/@/renderer/features/action-required/utils/server-lock';
|
||||||
import { isServerLock } from '/@/renderer/features/action-required/utils/window-properties';
|
import { isServerLock } from '/@/renderer/features/action-required/utils/window-properties';
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { useAuthStore, useAuthStoreActions } from '/@/renderer/store';
|
import { useAuthStore, useAuthStoreActions } from '/@/renderer/store';
|
||||||
|
|
||||||
const normalizeUrl = (url: string) => url.replace(/\/$/, '');
|
|
||||||
|
|
||||||
export const AppOutlet = () => {
|
export const AppOutlet = () => {
|
||||||
const currentServer = useAuthStore(
|
const currentServer = useAuthStore(
|
||||||
(state) =>
|
(state) =>
|
||||||
@@ -19,25 +18,27 @@ export const AppOutlet = () => {
|
|||||||
: null,
|
: null,
|
||||||
shallow,
|
shallow,
|
||||||
);
|
);
|
||||||
const { deleteServer, setCurrentServer } = useAuthStoreActions();
|
const { setCurrentServer, updateServer } = useAuthStoreActions();
|
||||||
|
|
||||||
const hasServerLockMismatch = useMemo(() => {
|
const hasServerLockMismatch = useMemo(() => {
|
||||||
if (!isServerLock() || !currentServer || !window.SERVER_URL) {
|
if (!isServerLock() || !currentServer || !window.SERVER_URL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const configuredUrl = normalizeUrl(window.SERVER_URL);
|
const configuredUrl = normalizeServerUrl(window.SERVER_URL);
|
||||||
const persistedUrl = normalizeUrl(currentServer.url);
|
const persistedUrl = normalizeServerUrl(currentServer.url);
|
||||||
|
|
||||||
return configuredUrl !== persistedUrl;
|
return configuredUrl !== persistedUrl;
|
||||||
}, [currentServer]);
|
}, [currentServer]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hasServerLockMismatch && currentServer) {
|
if (hasServerLockMismatch && currentServer && window.SERVER_URL) {
|
||||||
deleteServer(currentServer.id);
|
updateServer(currentServer.id, {
|
||||||
|
url: normalizeServerUrl(window.SERVER_URL),
|
||||||
|
});
|
||||||
setCurrentServer(null);
|
setCurrentServer(null);
|
||||||
}
|
}
|
||||||
}, [currentServer, deleteServer, hasServerLockMismatch, setCurrentServer]);
|
}, [currentServer, hasServerLockMismatch, setCurrentServer, updateServer]);
|
||||||
|
|
||||||
const isActionsRequired = !currentServer || hasServerLockMismatch;
|
const isActionsRequired = !currentServer || hasServerLockMismatch;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user