From 63a7be35a4cf0f11610c2097afc32d2ced0ef9e1 Mon Sep 17 00:00:00 2001 From: Manuel <30572287+manuel-rw@users.noreply.github.com> Date: Wed, 18 Dec 2024 14:10:58 +0100 Subject: [PATCH] fix: jellyfin integration does not allow username password auth (#1714) --- packages/integrations/src/base/integration.ts | 4 ++++ .../src/jellyfin/jellyfin-integration.ts | 24 +++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/packages/integrations/src/base/integration.ts b/packages/integrations/src/base/integration.ts index c9c953443..413ec6096 100644 --- a/packages/integrations/src/base/integration.ts +++ b/packages/integrations/src/base/integration.ts @@ -29,6 +29,10 @@ export abstract class Integration { return secret.value; } + protected hasSecretValue(kind: IntegrationSecretKind) { + return this.integration.decryptedSecrets.some((secret) => secret.kind === kind); + } + protected url(path: `/${string}`, queryParams?: Record) { const baseUrl = removeTrailingSlash(this.integration.url); const url = new URL(`${baseUrl}${path}`); diff --git a/packages/integrations/src/jellyfin/jellyfin-integration.ts b/packages/integrations/src/jellyfin/jellyfin-integration.ts index 4a603d6c2..2383473cd 100644 --- a/packages/integrations/src/jellyfin/jellyfin-integration.ts +++ b/packages/integrations/src/jellyfin/jellyfin-integration.ts @@ -18,13 +18,13 @@ export class JellyfinIntegration extends Integration { }); public async testConnectionAsync(): Promise { - const api = this.getApi(); + const api = await this.getApiAsync(); const systemApi = getSystemApi(api); await systemApi.getPingSystem(); } public async getCurrentSessionsAsync(): Promise { - const api = this.getApi(); + const api = await this.getApiAsync(); const sessionApi = getSessionApi(api); const sessions = await sessionApi.getSessions(); @@ -59,8 +59,22 @@ export class JellyfinIntegration extends Integration { }); } - private getApi() { - const apiKey = this.getSecretValue("apiKey"); - return this.jellyfin.createApi(this.url("/").toString(), apiKey); + /** + * Constructs an ApiClient synchronously with an ApiKey or asynchronously + * with a username and password. + * @returns An instance of Api that has been authenticated + */ + private async getApiAsync() { + if (this.hasSecretValue("apiKey")) { + const apiKey = this.getSecretValue("apiKey"); + return this.jellyfin.createApi(this.url("/").toString(), apiKey); + } + + const apiClient = this.jellyfin.createApi(this.url("/").toString()); + // Authentication state is stored internally in the Api class, so now + // requests that require authentication can be made normally. + // see https://typescript-sdk.jellyfin.org/#usage + await apiClient.authenticateUserByName(this.getSecretValue("username"), this.getSecretValue("password")); + return apiClient; } }