diff --git a/apps/router/src/api/ServiceCheckApi.ts b/apps/router/src/api/ServiceCheckApi.ts index f11101064..633f8be44 100644 --- a/apps/router/src/api/ServiceCheckApi.ts +++ b/apps/router/src/api/ServiceCheckApi.ts @@ -13,7 +13,7 @@ export class ServiceCheckApi { public async check( baseUrl: string, - password?: string + password: string | null ): Promise { const isWebsocket = baseUrl.startsWith('ws://') || baseUrl.startsWith('wss://'); @@ -24,7 +24,7 @@ export class ServiceCheckApi { private async checkGuardian( baseUrl: string, - password?: string + password: string | null ): Promise { const websocket = new JsonRpcWebsocket( baseUrl, @@ -40,21 +40,15 @@ export class ServiceCheckApi { return { serviceType: 'guardian', serviceName: 'Guardian', - status: password - ? result.server - : result.server !== 'awaiting_password' - ? 'Setup' - : result.server, - requiresPassword: password - ? true - : result.server !== 'awaiting_password', + status: result.server, + requiresPassword: result.server === 'awaiting_password', }; } catch (error) { if (error instanceof JsonRpcError && error.code === -32600) { return { serviceType: 'guardian', serviceName: 'Guardian', - status: password ? 'Invalid Password' : 'Setup', + status: 'Invalid Password', requiresPassword: true, }; } @@ -66,17 +60,22 @@ export class ServiceCheckApi { private async getGuardianStatus( websocket: JsonRpcWebsocket, - password?: string + password: string | null ) { - if (password) { - await websocket.call('auth', [{ auth: password, params: null }]); + try { + return await websocket.call('status', [{ auth: password, params: null }]); + } catch (error) { + if (error instanceof JsonRpcError && error.code === -32600 && password) { + // If authentication fails with a password, try without it + return await websocket.call('status', [{ auth: null, params: null }]); + } + throw error; } - return websocket.call('status', [{ auth: password, params: null }]); } private async checkGateway( baseUrl: string, - password?: string + password: string | null ): Promise { const headers: Record = { 'Content-Type': 'application/json', diff --git a/apps/router/src/home/modals/connectServiceModal/useConnectServiceForm.tsx b/apps/router/src/home/modals/connectServiceModal/useConnectServiceForm.tsx index 164f65a1b..7efa4fac3 100644 --- a/apps/router/src/home/modals/connectServiceModal/useConnectServiceForm.tsx +++ b/apps/router/src/home/modals/connectServiceModal/useConnectServiceForm.tsx @@ -40,7 +40,7 @@ export const useConnectServiceForm = (onClose: () => void) => { } let info: ServiceCheckResponse; if (!requiresPassword || password === null) { - info = await api.check(configUrl); + info = await api.check(configUrl, null); if (info.requiresPassword) { setRequiresPassword(true); setServiceInfo(null); diff --git a/apps/router/src/home/services/ViewServiceButton.tsx b/apps/router/src/home/services/ViewServiceButton.tsx index e0aed1eab..e9d38dbb1 100644 --- a/apps/router/src/home/services/ViewServiceButton.tsx +++ b/apps/router/src/home/services/ViewServiceButton.tsx @@ -41,13 +41,21 @@ export const ViewServiceButton: React.FC = ({ const api = new ServiceCheckApi(); try { - if (!decryptedServicePassword) { + const checkResult = await api.check(baseUrl, decryptedServicePassword); + + if ( + checkResult.status === 'awaiting_password' || + checkResult.status === 'Setup' + ) { + // Allow navigation if the service is awaiting password or in setup + navigate(`/${type}/${id}`); + } else if (checkResult.requiresPassword && !decryptedServicePassword) { throw new Error('Service password not found'); + } else { + navigate(`/${type}/${id}`); } - - await api.check(baseUrl, decryptedServicePassword); - navigate(`/${type}/${id}`); } catch (error) { + console.error('Service check error:', error); onOpen(); } finally { setIsLoading(false); diff --git a/apps/router/src/hooks/useUnlockedService.tsx b/apps/router/src/hooks/useUnlockedService.tsx index 7d9aa06a2..1e18059f2 100644 --- a/apps/router/src/hooks/useUnlockedService.tsx +++ b/apps/router/src/hooks/useUnlockedService.tsx @@ -18,7 +18,6 @@ export const useUnlockedService = ( useEffect(() => { const decryptPassword = async () => { if (!masterPassword || !serviceId || !serviceType) { - console.error('Missing required data for decryption'); setError('Missing required data for decryption'); return; } @@ -27,11 +26,11 @@ export const useUnlockedService = ( serviceType === 'guardian' ? guardianEncryptedPasswords : gatewayEncryptedPasswords; - const serviceEncryptedPassword = services[serviceId]; + if (!serviceEncryptedPassword) { - console.error(`No encrypted password found for service ${serviceId}`); - setError(`No encrypted password found for service ${serviceId}`); + setDecryptedServicePassword(null); + setError(null); return; } @@ -43,13 +42,9 @@ export const useUnlockedService = ( setDecryptedServicePassword(decrypted); setError(null); } catch (err) { - if (err instanceof Error) { - console.error('Decryption error:', err); - setError(`Failed to decrypt password: ${err.message}`); - } else { - console.error('Unknown decryption error:', err); - setError('Failed to decrypt password: Unknown error'); - } + const errorMessage = + err instanceof Error ? err.message : 'Unknown error'; + setError(`Failed to decrypt password: ${errorMessage}`); setDecryptedServicePassword(null); } }; @@ -63,8 +58,5 @@ export const useUnlockedService = ( gatewayEncryptedPasswords, ]); - return { - decryptedServicePassword, - error, - }; + return { decryptedServicePassword, error }; };