[bugfix]: Check for Navidrome authentication on startup

Resolves #403.
This PR introduces a startup check for Navidrome that tries a simple API request (/songs) before loading homepage.
If the check fails, Navidrome API will fallback to trying saved password (if available).

Notes:
- It might also be worthwhile to do a periodic poll?
This commit is contained in:
Kendall Garner 2024-02-16 13:37:49 -08:00
parent 20b161ee86
commit b2fce071a9
No known key found for this signature in database
GPG key ID: 18D2767419676C87
3 changed files with 69 additions and 2 deletions

View file

@ -0,0 +1,54 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { useCurrentServer } from '/@/renderer/store';
import { AuthState, ServerListItem, ServerType } from '/@/renderer/types';
import { api } from '/@/renderer/api';
import { SongListSort, SortOrder } from '/@/renderer/api/types';
import { debounce } from 'lodash';
export const useServerAuthenticated = () => {
const priorServerId = useRef<string>();
const server = useCurrentServer();
const [ready, setReady] = useState(
server?.type === ServerType.NAVIDROME ? AuthState.LOADING : 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,
},
});
setReady(AuthState.VALID);
} catch (error) {
setReady(AuthState.INVALID);
}
}, []);
const debouncedAuth = debounce((server: ServerListItem) => {
authenticateNavidrome(server).catch(console.error);
}, 300);
useEffect(() => {
if (priorServerId.current !== server?.id) {
priorServerId.current = server?.id || '';
if (server?.type === ServerType.NAVIDROME) {
setReady(AuthState.LOADING);
debouncedAuth(server);
} else {
setReady(AuthState.VALID);
}
}
}, [debouncedAuth, server]);
return ready;
};