From dd1289441c62e402d1495665dac46adf69fdc9e0 Mon Sep 17 00:00:00 2001 From: Violet Caulfield Date: Thu, 17 Oct 2024 14:39:38 -0500 Subject: [PATCH] lots of stuff lets see if I can authenticate and get pushed to the library selection --- api/mutators/auth.ts | 16 ------ api/mutators/storage.ts | 20 ------- components/Login/component.tsx | 23 ++++---- components/Login/helpers/server-address.tsx | 2 +- .../Login/helpers/server-authentication.tsx | 40 ++++++++++++-- components/Login/helpers/sign-in.tsx | 8 --- components/jellify.tsx | 22 +++++--- components/jellyfin-api-provider.tsx | 54 +++++++++++++++++-- package-lock.json | 45 ++++++++++++++-- package.json | 4 +- 10 files changed, 156 insertions(+), 78 deletions(-) delete mode 100644 api/mutators/auth.ts delete mode 100644 api/mutators/storage.ts delete mode 100644 components/Login/helpers/sign-in.tsx diff --git a/api/mutators/auth.ts b/api/mutators/auth.ts deleted file mode 100644 index 0f0ca1db..00000000 --- a/api/mutators/auth.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { useMutation } from "@tanstack/react-query"; -import { JellyfinCredentials } from "../types/jellyfin-credentials"; -import { MutationKeys } from "../../enums/mutation-keys"; -import { createPublicApi } from "../queries/functions/api"; -import { fetchServer } from "../queries/functions/storage"; - -export const authenticateWithCredentials = useMutation({ - mutationKey: [MutationKeys.AuthenticationWithCredentials], - mutationFn: async (credentials: JellyfinCredentials) => { - createPublicApi((await fetchServer()).url) - .authenticateUserByName(credentials.username, credentials.password!); - }, - onSuccess(data, credentials, context) { - - }, -}) \ No newline at end of file diff --git a/api/mutators/storage.ts b/api/mutators/storage.ts deleted file mode 100644 index d35d7560..00000000 --- a/api/mutators/storage.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { useMutation } from "@tanstack/react-query"; -import { MutationKeys } from "../../enums/mutation-keys"; - -import { JellyfinCredentials } from "../types/jellyfin-credentials"; -import { mutateServer, mutateServerCredentials } from "./functions/storage"; -import { JellifyServer } from "../../types/JellifyServer"; - -export const jellifyServerMutation = useMutation({ - mutationKey: [MutationKeys.ServerUrl], - mutationFn: async (server: JellifyServer | undefined) => { - return mutateServer(server) - } -}); - -export const credentials = useMutation({ - mutationKey: [MutationKeys.Credentials], - mutationFn: async (credentials: JellyfinCredentials) => { - return mutateServerCredentials(credentials) - }, -}); \ No newline at end of file diff --git a/components/Login/component.tsx b/components/Login/component.tsx index 9f1e2d58..28534175 100644 --- a/components/Login/component.tsx +++ b/components/Login/component.tsx @@ -5,16 +5,17 @@ import { createStackNavigator } from "@react-navigation/stack"; import { useApiClientContext } from "../jellyfin-api-provider"; import { useColorScheme } from "react-native"; import { Colors } from "react-native-ui-lib"; +import ServerLibrary from "./helpers/server-library"; export default function Login(): React.JSX.Element { - const { server } = useApiClientContext(); + const { server, username } = useApiClientContext(); const Stack = createStackNavigator(); return ( - { + { (_.isUndefined(server) || _.isEmpty(server.url)) ? ( ) : ( - + + (_.isUndefined(username)) ? ( + + ) : ( + + ) ) } diff --git a/components/Login/helpers/server-address.tsx b/components/Login/helpers/server-address.tsx index a7bdf62f..343ea267 100644 --- a/components/Login/helpers/server-address.tsx +++ b/components/Login/helpers/server-address.tsx @@ -24,7 +24,7 @@ export default function ServerAddress(): React.JSX.Element { const useServerMutation = useMutation({ mutationFn: serverMutation, - onSuccess: async (publicSystemInfoResponse, serverUrl, context) => { + onSuccess: async (publicSystemInfoResponse, serverUrl) => { if (!!!publicSystemInfoResponse.data.Version) throw new Error("Jellyfin instance did not respond"); diff --git a/components/Login/helpers/server-authentication.tsx b/components/Login/helpers/server-authentication.tsx index 3bd888fe..f5b03caa 100644 --- a/components/Login/helpers/server-authentication.tsx +++ b/components/Login/helpers/server-authentication.tsx @@ -1,11 +1,16 @@ -import React, { useEffect } from "react"; +import React from "react"; import { useColorScheme } from "react-native"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { useMutation } from "@tanstack/react-query"; import { AsyncStorageKeys } from "../../../enums/async-storage-keys"; import { useApiClientContext } from "../../jellyfin-api-provider"; -import { RadioGroup, RadioButton, TextField, View, Button, Card, Colors } from 'react-native-ui-lib'; +import { TextField, View, Button, Colors } from 'react-native-ui-lib'; import { jellifyStyles } from "../../styles"; +import { credentials } from "../../../api/mutators/storage"; +import { JellyfinCredentials } from "../../../api/types/jellyfin-credentials"; +import * as Keychain from "react-native-keychain" +import _ from "lodash"; +import { client } from "../../../api/queries"; export default function ServerAuthentication(): React.JSX.Element { const [username, setUsername] = React.useState(''); @@ -13,7 +18,34 @@ export default function ServerAuthentication(): React.JSX.Element { const isDarkMode = useColorScheme() === 'dark'; - const { setServer, setChangeServer } = useApiClientContext(); + const { apiClient, setApiClient, server, setServer, setChangeServer } = useApiClientContext(); + + const useApiMutation = useMutation({ + mutationFn: async (credentials: JellyfinCredentials) => { + return apiClient!.authenticateUserByName(credentials.username, credentials.password!); + }, + onSuccess: async (authResult, credentials) => { + + console.log(`Received auth response from ${server!.name}`) + if (_.isUndefined(authResult)) + return Promise.reject(new Error("Authentication result was empty")) + + if (authResult.status >= 400 || _.isEmpty(authResult.data.AccessToken)) + return Promise.reject(new Error("Invalid credentials")) + + if (_.isUndefined(authResult.data.User)) + return Promise.reject(new Error("Unable to login")); + + setApiClient(client.createApi(server!.url, (authResult.data.AccessToken as string))) + setUsername(authResult.data.User.Name!); + return await Keychain.setInternetCredentials(server!.url, credentials.username, (authResult.data.AccessToken as string)); + + }, + onError: async (error: Error) => { + console.error("An error occurred connecting to the Jellyfin instance", error); + return await AsyncStorage.setItem(AsyncStorageKeys.ServerUrl, ""); + } + }); const clearServer = useMutation({ mutationFn: async () => { @@ -49,7 +81,7 @@ export default function ServerAuthentication(): React.JSX.Element {