diff --git a/src/renderer/api/jellyfin.api.ts b/src/renderer/api/jellyfin.api.ts index 9f8b2faf..8775738b 100644 --- a/src/renderer/api/jellyfin.api.ts +++ b/src/renderer/api/jellyfin.api.ts @@ -94,12 +94,16 @@ const authenticate = async ( password: string; username: string; }, + basicAuth?: { password: string; username: string }, ): Promise => { const cleanServerUrl = url.replace(/\/$/, ''); const data = await ky .post(`${cleanServerUrl}/users/authenticatebyname`, { headers: { + Authorization: basicAuth + ? `Basic ${window.btoa(`${basicAuth?.username}:${basicAuth?.password}`)}` + : undefined, 'X-Emby-Authorization': `MediaBrowser Client="Feishin", Device="PC", DeviceId="Feishin", Version="${packageJson.version}"`, }, json: { diff --git a/src/renderer/api/navidrome.api.ts b/src/renderer/api/navidrome.api.ts index bd19bbfe..2f128fcd 100644 --- a/src/renderer/api/navidrome.api.ts +++ b/src/renderer/api/navidrome.api.ts @@ -130,11 +130,19 @@ const api = ky.create({ const authenticate = async ( url: string, body: { password: string; username: string }, + basicAuth?: { password: string; username: string }, ): Promise => { const cleanServerUrl = url.replace(/\/$/, ''); + const headers = new Headers({ + Authorization: `Basic ${window.btoa(`${basicAuth?.username}:${basicAuth?.password}`)}`, + 'Content-Type': 'application/json', + }); + const data = await ky .post(`${cleanServerUrl}/auth/login`, { + credentials: 'include', + headers: basicAuth ? headers : undefined, json: { password: body.password, username: body.username, diff --git a/src/renderer/api/subsonic.api.ts b/src/renderer/api/subsonic.api.ts index 575e4b1f..9d5aba6f 100644 --- a/src/renderer/api/subsonic.api.ts +++ b/src/renderer/api/subsonic.api.ts @@ -127,10 +127,16 @@ const authenticate = async ( password: string; username: string; }, + basicAuth?: { password: string; username: string }, ): Promise => { let credential; const cleanServerUrl = url.replace(/\/$/, ''); + const headers = new Headers({ + Authorization: `Basic ${window.btoa(`${basicAuth?.username}:${basicAuth?.password}`)}`, + 'Content-Type': 'application/json', + }); + if (body.legacy) { credential = `u=${body.username}&p=${body.password}`; } else { @@ -139,7 +145,9 @@ const authenticate = async ( credential = `u=${body.username}&s=${salt}&t=${hash}`; } - await ky.get(`${cleanServerUrl}/rest/ping.view?v=1.13.0&c=Feishin&f=json&${credential}`); + await ky.get(`${cleanServerUrl}/rest/ping.view?v=1.13.0&c=Feishin&f=json&${credential}`, { + headers, + }); return { credential, diff --git a/src/renderer/features/servers/components/add-server-form.tsx b/src/renderer/features/servers/components/add-server-form.tsx index 0ed780ff..f625f139 100644 --- a/src/renderer/features/servers/components/add-server-form.tsx +++ b/src/renderer/features/servers/components/add-server-form.tsx @@ -1,6 +1,14 @@ import { useState } from 'react'; import { Stack, Group, Checkbox } from '@mantine/core'; -import { Button, PasswordInput, SegmentedControl, TextInput, toast } from '/@/renderer/components'; +import { + Button, + Paper, + PasswordInput, + SegmentedControl, + Switch, + TextInput, + toast, +} from '/@/renderer/components'; import { useForm } from '@mantine/form'; import { useFocusTrap } from '@mantine/hooks'; import { closeAllModals } from '@mantine/modals'; @@ -10,7 +18,7 @@ import { navidromeApi } from '/@/renderer/api/navidrome.api'; import { subsonicApi } from '/@/renderer/api/subsonic.api'; import { AuthenticationResponse } from '/@/renderer/api/types'; import { useAuthStore, useAuthStoreActions } from '/@/renderer/store'; -import { ServerType } from '/@/renderer/types'; +import { ServerListItem, ServerType } from '/@/renderer/types'; const SERVER_TYPES = [ { label: 'Jellyfin', value: ServerType.JELLYFIN }, @@ -36,6 +44,9 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => { const form = useForm({ initialValues: { + basicAuth: false, + basicPassword: '', + basicUsername: '', legacyAuth: false, name: '', password: '', @@ -57,13 +68,20 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => { try { setIsLoading(true); - const data: AuthenticationResponse = await authFunction(values.url, { - legacy: values.legacyAuth, - password: values.password, - username: values.username, - }); + const data: AuthenticationResponse = await authFunction( + values.url, + { + legacy: values.legacyAuth, + password: values.password, + username: values.username, + }, + { password: values.basicPassword, username: values.basicUsername }, + ); - const serverItem = { + const serverItem: ServerListItem = { + basicAuth: values.basicAuth, + basicPassword: values.basicPassword, + basicUsername: values.basicUsername, credential: data.credential, id: nanoid(), name: values.name, @@ -97,6 +115,7 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => { { {...form.getInputProps('legacyAuth', { type: 'checkbox' })} /> )} + + + + {form.values.basicAuth && ( + <> + + + + )} + +