From fb584b35a90ab0b3b7a3bc7de25f0b9f9932a630 Mon Sep 17 00:00:00 2001 From: Kendall Garner <17521368+kgarner7@users.noreply.github.com> Date: Thu, 26 Jun 2025 21:14:20 -0700 Subject: [PATCH] handle Navidrome login loop error --- .../routes/action-required-route.tsx | 3 +- .../hooks/use-server-authenticated.ts | 61 ++++++++++++------- src/renderer/router/app-outlet.tsx | 3 + 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/renderer/features/action-required/routes/action-required-route.tsx b/src/renderer/features/action-required/routes/action-required-route.tsx index ab9daf5e..436e8c8a 100644 --- a/src/renderer/features/action-required/routes/action-required-route.tsx +++ b/src/renderer/features/action-required/routes/action-required-route.tsx @@ -62,7 +62,8 @@ const ActionRequiredRoute = () => { {canReturnHome && } - {!displayedCheck && ( + {/* This should be displayed if a credential is required */} + {isCredentialRequired && ( { const priorServerId = useRef(undefined); const server = useCurrentServer(); const [ready, setReady] = useState( - server?.type === ServerType.NAVIDROME ? AuthState.LOADING : AuthState.VALID, + server?.type === ServerType.NAVIDROME ? AuthState.VALID : AuthState.VALID, ); - const authenticateNavidrome = useCallback(async (server: ServerListItem) => { - // This trick works because navidrome-api.ts will internally check for authentication - // failures and try to log in again (where available). So, all that's necessary is - // making one request first - try { - await api.controller.getSongList({ - apiClientProps: { server }, - query: { - limit: 1, - sortBy: SongListSort.NAME, - sortOrder: SortOrder.ASC, - startIndex: 0, - }, - }); + const { updateServer } = useAuthStoreActions(); - setReady(AuthState.VALID); - } catch (error) { - toast.error({ message: (error as Error).message }); - setReady(AuthState.INVALID); - } - }, []); + const authenticateNavidrome = useCallback( + async (server: ServerListItem) => { + // This trick works because navidrome-api.ts will internally check for authentication + // failures and try to log in again (where available). So, all that's necessary is + // making one request first + try { + await api.controller.getSongList({ + apiClientProps: { server }, + query: { + limit: 1, + sortBy: SongListSort.NAME, + sortOrder: SortOrder.ASC, + startIndex: 0, + }, + }); + + setReady(AuthState.VALID); + } catch (error) { + // Clear server credentials (and saved password). + if (server.savePassword && localSettings) { + localSettings.passwordRemove(server.id); + } + + server.credential = ''; + updateServer(server.id, server); + + toast.error({ message: (error as Error).message }); + + setReady(AuthState.INVALID); + } + }, + [updateServer], + ); const debouncedAuth = debounce((server: ServerListItem) => { authenticateNavidrome(server).catch(console.error); diff --git a/src/renderer/router/app-outlet.tsx b/src/renderer/router/app-outlet.tsx index be1e31a9..68ce3c8b 100644 --- a/src/renderer/router/app-outlet.tsx +++ b/src/renderer/router/app-outlet.tsx @@ -19,6 +19,8 @@ export const AppOutlet = () => { const setFallback = useSetPlayerFallback(); const authState = useServerAuthenticated(); + console.log(authState); + const isActionsRequired = useMemo(() => { const isServerRequired = !currentServer; @@ -55,6 +57,7 @@ export const AppOutlet = () => { } if (isActionsRequired || authState === AuthState.INVALID) { + console.log('required', isActionsRequired); return (