Add authenticate function to controller

This commit is contained in:
jeffvli 2023-05-09 05:48:11 -07:00
parent 975c31635a
commit 63be8c8fb8
3 changed files with 50 additions and 33 deletions

View file

@ -43,8 +43,9 @@ import type {
TopSongListResponse, TopSongListResponse,
UpdatePlaylistResponse, UpdatePlaylistResponse,
UserListResponse, UserListResponse,
AuthenticationResponse,
} from '/@/renderer/api/types'; } from '/@/renderer/api/types';
import { ServerListItem } from '/@/renderer/types'; import { ServerType } from '/@/renderer/types';
import { DeletePlaylistResponse } from './types'; import { DeletePlaylistResponse } from './types';
import { ndController } from '/@/renderer/api/navidrome/navidrome-controller'; import { ndController } from '/@/renderer/api/navidrome/navidrome-controller';
import { ssController } from '/@/renderer/api/subsonic/subsonic-controller'; import { ssController } from '/@/renderer/api/subsonic/subsonic-controller';
@ -52,6 +53,10 @@ import { jfController } from '/@/renderer/api/jellyfin/jellyfin-controller';
export type ControllerEndpoint = Partial<{ export type ControllerEndpoint = Partial<{
addToPlaylist: (args: AddToPlaylistArgs) => Promise<AddToPlaylistResponse>; addToPlaylist: (args: AddToPlaylistArgs) => Promise<AddToPlaylistResponse>;
authenticate: (
url: string,
body: { password: string; username: string },
) => Promise<AuthenticationResponse>;
clearPlaylist: () => void; clearPlaylist: () => void;
createFavorite: (args: FavoriteArgs) => Promise<FavoriteResponse>; createFavorite: (args: FavoriteArgs) => Promise<FavoriteResponse>;
createPlaylist: (args: CreatePlaylistArgs) => Promise<CreatePlaylistResponse>; createPlaylist: (args: CreatePlaylistArgs) => Promise<CreatePlaylistResponse>;
@ -92,6 +97,7 @@ type ApiController = {
const endpoints: ApiController = { const endpoints: ApiController = {
jellyfin: { jellyfin: {
addToPlaylist: jfController.addToPlaylist, addToPlaylist: jfController.addToPlaylist,
authenticate: jfController.authenticate,
clearPlaylist: undefined, clearPlaylist: undefined,
createFavorite: jfController.createFavorite, createFavorite: jfController.createFavorite,
createPlaylist: jfController.createPlaylist, createPlaylist: jfController.createPlaylist,
@ -124,6 +130,7 @@ const endpoints: ApiController = {
}, },
navidrome: { navidrome: {
addToPlaylist: ndController.addToPlaylist, addToPlaylist: ndController.addToPlaylist,
authenticate: ndController.authenticate,
clearPlaylist: undefined, clearPlaylist: undefined,
createFavorite: ssController.createFavorite, createFavorite: ssController.createFavorite,
createPlaylist: ndController.createPlaylist, createPlaylist: ndController.createPlaylist,
@ -155,6 +162,7 @@ const endpoints: ApiController = {
updatePlaylist: ndController.updatePlaylist, updatePlaylist: ndController.updatePlaylist,
}, },
subsonic: { subsonic: {
authenticate: ssController.authenticate,
clearPlaylist: undefined, clearPlaylist: undefined,
createFavorite: ssController.createFavorite, createFavorite: ssController.createFavorite,
createPlaylist: undefined, createPlaylist: undefined,
@ -185,8 +193,8 @@ const endpoints: ApiController = {
}, },
}; };
const apiController = (endpoint: keyof ControllerEndpoint, server?: ServerListItem | null) => { const apiController = (endpoint: keyof ControllerEndpoint, type?: ServerType) => {
const serverType = server?.type || useAuthStore.getState().currentServer?.type; const serverType = type || useAuthStore.getState().currentServer?.type;
if (!serverType) { if (!serverType) {
toast.error({ message: 'No server selected', title: 'Unable to route request' }); toast.error({ message: 'No server selected', title: 'Unable to route request' });
@ -206,6 +214,14 @@ const apiController = (endpoint: keyof ControllerEndpoint, server?: ServerListIt
return endpoints[serverType][endpoint]; return endpoints[serverType][endpoint];
}; };
const authenticate = async (
url: string,
body: { legacy?: boolean; password: string; username: string },
type: ServerType,
) => {
return (apiController('authenticate', type) as ControllerEndpoint['authenticate'])?.(url, body);
};
const getAlbumList = async (args: AlbumListArgs) => { const getAlbumList = async (args: AlbumListArgs) => {
return (apiController('getAlbumList') as ControllerEndpoint['getAlbumList'])?.(args); return (apiController('getAlbumList') as ControllerEndpoint['getAlbumList'])?.(args);
}; };
@ -300,6 +316,7 @@ const scrobble = async (args: ScrobbleArgs) => {
export const controller = { export const controller = {
addToPlaylist, addToPlaylist,
authenticate,
createFavorite, createFavorite,
createPlaylist, createPlaylist,
deleteFavorite, deleteFavorite,

View file

@ -5,12 +5,10 @@ import { useForm } from '@mantine/form';
import { useFocusTrap } from '@mantine/hooks'; import { useFocusTrap } from '@mantine/hooks';
import { closeAllModals } from '@mantine/modals'; import { closeAllModals } from '@mantine/modals';
import { nanoid } from 'nanoid/non-secure'; import { nanoid } from 'nanoid/non-secure';
import { jellyfinApi } from '/@/renderer/api/jellyfin.api';
import { navidromeApi } from '/@/renderer/api/navidrome.api';
import { subsonicApi } from '/@/renderer/api/subsonic.api';
import { AuthenticationResponse } from '/@/renderer/api/types'; import { AuthenticationResponse } from '/@/renderer/api/types';
import { useAuthStore, useAuthStoreActions } from '/@/renderer/store'; import { useAuthStore, useAuthStoreActions } from '/@/renderer/store';
import { ServerType } from '/@/renderer/types'; import { ServerType } from '/@/renderer/types';
import { api } from '/@/renderer/api';
const SERVER_TYPES = [ const SERVER_TYPES = [
{ label: 'Jellyfin', value: ServerType.JELLYFIN }, { label: 'Jellyfin', value: ServerType.JELLYFIN },
@ -18,12 +16,6 @@ const SERVER_TYPES = [
// { label: 'Subsonic', value: ServerType.SUBSONIC }, // { label: 'Subsonic', value: ServerType.SUBSONIC },
]; ];
const AUTH_FUNCTIONS = {
[ServerType.JELLYFIN]: jellyfinApi.authenticate,
[ServerType.NAVIDROME]: navidromeApi.authenticate,
[ServerType.SUBSONIC]: subsonicApi.authenticate,
};
interface AddServerFormProps { interface AddServerFormProps {
onCancel: () => void; onCancel: () => void;
} }
@ -48,7 +40,7 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => {
const isSubmitDisabled = !form.values.name || !form.values.url || !form.values.username; const isSubmitDisabled = !form.values.name || !form.values.url || !form.values.username;
const handleSubmit = form.onSubmit(async (values) => { const handleSubmit = form.onSubmit(async (values) => {
const authFunction = AUTH_FUNCTIONS[values.type]; const authFunction = api.controller.authenticate;
if (!authFunction) { if (!authFunction) {
return toast.error({ message: 'Selected server type is invalid' }); return toast.error({ message: 'Selected server type is invalid' });
@ -56,11 +48,19 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => {
try { try {
setIsLoading(true); setIsLoading(true);
const data: AuthenticationResponse = await authFunction(values.url, { const data: AuthenticationResponse | undefined = await authFunction(
values.url,
{
legacy: values.legacyAuth, legacy: values.legacyAuth,
password: values.password, password: values.password,
username: values.username, username: values.username,
}); },
values.type,
);
if (!data) {
return toast.error({ message: 'Authentication failed' });
}
const serverItem = { const serverItem = {
credential: data.credential, credential: data.credential,

View file

@ -5,12 +5,10 @@ import { useForm } from '@mantine/form';
import { useFocusTrap } from '@mantine/hooks'; import { useFocusTrap } from '@mantine/hooks';
import { closeAllModals } from '@mantine/modals'; import { closeAllModals } from '@mantine/modals';
import { RiInformationLine } from 'react-icons/ri'; import { RiInformationLine } from 'react-icons/ri';
import { jellyfinApi } from '/@/renderer/api/jellyfin.api';
import { navidromeApi } from '/@/renderer/api/navidrome.api';
import { subsonicApi } from '/@/renderer/api/subsonic.api';
import { AuthenticationResponse } from '/@/renderer/api/types'; import { AuthenticationResponse } from '/@/renderer/api/types';
import { useAuthStoreActions } from '/@/renderer/store'; import { useAuthStoreActions } from '/@/renderer/store';
import { ServerListItem, ServerType } from '/@/renderer/types'; import { ServerListItem, ServerType } from '/@/renderer/types';
import { api } from '/@/renderer/api';
interface EditServerFormProps { interface EditServerFormProps {
isUpdate?: boolean; isUpdate?: boolean;
@ -18,12 +16,6 @@ interface EditServerFormProps {
server: ServerListItem; server: ServerListItem;
} }
const AUTH_FUNCTIONS = {
[ServerType.JELLYFIN]: jellyfinApi.authenticate,
[ServerType.NAVIDROME]: navidromeApi.authenticate,
[ServerType.SUBSONIC]: subsonicApi.authenticate,
};
const ModifiedFieldIndicator = () => { const ModifiedFieldIndicator = () => {
return ( return (
<Tooltip label="Field has been modified"> <Tooltip label="Field has been modified">
@ -53,7 +45,7 @@ export const EditServerForm = ({ isUpdate, server, onCancel }: EditServerFormPro
const isSubsonic = form.values.type === ServerType.SUBSONIC; const isSubsonic = form.values.type === ServerType.SUBSONIC;
const handleSubmit = form.onSubmit(async (values) => { const handleSubmit = form.onSubmit(async (values) => {
const authFunction = AUTH_FUNCTIONS[values.type]; const authFunction = api.controller.authenticate;
if (!authFunction) { if (!authFunction) {
return toast.error({ message: 'Selected server type is invalid' }); return toast.error({ message: 'Selected server type is invalid' });
@ -61,11 +53,19 @@ export const EditServerForm = ({ isUpdate, server, onCancel }: EditServerFormPro
try { try {
setIsLoading(true); setIsLoading(true);
const data: AuthenticationResponse = await authFunction(values.url, { const data: AuthenticationResponse | undefined = await authFunction(
values.url,
{
legacy: values.legacyAuth, legacy: values.legacyAuth,
password: values.password, password: values.password,
username: values.username, username: values.username,
}); },
values.type,
);
if (!data) {
return toast.error({ message: 'Authentication failed' });
}
const serverItem = { const serverItem = {
credential: data.credential, credential: data.credential,