feat(jellyfinapi): switch to API tokens instead of auth tokens (#868)

* feat(jellyfinapi): create Jellyfin API key from admin user

* fix(jellyfinapi): add migration script for Jellyfin API key

* feat(jellyfinapi): use Jellyfin API key instead of admin auth token

* fix(jellyfinapi): fix api key migration

* feat(jellyfinapi): add API key field to Jellyfin settings

* fix: move the API key field in the Jellyfin settings
This commit is contained in:
Gauthier
2024-08-13 16:01:45 +02:00
committed by GitHub
parent 12f908de7f
commit bd4da6d5fc
13 changed files with 309 additions and 235 deletions

View File

@@ -85,7 +85,7 @@ class ExternalAPI {
protected async post<T>(
endpoint: string,
data: Record<string, unknown>,
data?: Record<string, unknown>,
params?: Record<string, string>,
ttl?: number,
config?: RequestInit
@@ -107,7 +107,7 @@ class ExternalAPI {
...this.defaultHeaders,
...config?.headers,
},
body: JSON.stringify(data),
body: data ? JSON.stringify(data) : undefined,
});
if (!response.ok) {
const text = await response.text();
@@ -286,7 +286,12 @@ class ExternalAPI {
...this.params,
...params,
});
return `${href}?${searchParams.toString()}`;
return (
href +
(searchParams.toString().length
? '?' + searchParams.toString()
: searchParams.toString())
);
}
private serializeCacheKey(

View File

@@ -93,9 +93,7 @@ export interface JellyfinLibraryItemExtended extends JellyfinLibraryItem {
}
class JellyfinAPI extends ExternalAPI {
private authToken?: string;
private userId?: string;
private jellyfinHost: string;
constructor(jellyfinHost: string, authToken?: string, deviceId?: string) {
let authHeaderVal: string;
@@ -114,9 +112,6 @@ class JellyfinAPI extends ExternalAPI {
},
}
);
this.jellyfinHost = jellyfinHost;
this.authToken = authToken;
}
public async login(
@@ -405,6 +400,23 @@ class JellyfinAPI extends ExternalAPI {
throw new ApiError(e.cause?.status, ApiErrorCode.InvalidAuthToken);
}
}
public async createApiToken(appName: string): Promise<string> {
try {
await this.post(`/Auth/Keys?App=${appName}`);
const apiKeys = await this.get<any>(`/Auth/Keys`);
return apiKeys.Items.reverse().find(
(item: any) => item.AppName === appName
).AccessToken;
} catch (e) {
logger.error(
`Something went wrong while creating an API key the Jellyfin server: ${e.message}`,
{ label: 'Jellyfin API' }
);
throw new ApiError(e.response?.status, ApiErrorCode.InvalidAuthToken);
}
}
}
export default JellyfinAPI;