diff --git a/src/components/__tests__/jellyfinApi.test.ts b/src/components/__tests__/jellyfinApi.test.ts index 9c144f0d..d4ef9d12 100644 --- a/src/components/__tests__/jellyfinApi.test.ts +++ b/src/components/__tests__/jellyfinApi.test.ts @@ -213,11 +213,10 @@ describe('getting security headers', () => { // @ts-expect-error Since the method is private. const result = JellyfinApi.getSecurityHeaders(); - const correctAuth = `Jellyfin Client="Chromecast", Device="thisIsReceiverName", DeviceId="${btoa( + const correctAuth = `MediaBrowser Client="Chromecast", Token="thisIsAccessToken", Version="thisIsVersionNumber", DeviceId="${btoa( 'thisIsReceiverName' - )}", Version="thisIsVersionNumber", UserId="thisIsUserId"`; + )}", Device="thisIsReceiverName"`; - expect(result).toHaveProperty('X-MediaBrowser-Token'); expect(result).toHaveProperty('Authorization'); expect(result.Authorization).toMatch(correctAuth); }); @@ -232,7 +231,8 @@ describe('getting security headers', () => { // @ts-expect-error Since the method is private. const result = JellyfinApi.getSecurityHeaders(); const correct = { - Authorization: `Jellyfin Client="Chromecast", Device="Google Cast", DeviceId="thisIsSenderId", Version="thisIsVersionNumber"` + Authorization: + 'MediaBrowser Client="Chromecast", Token="thisIsAccessToken", Version="thisIsVersionNumber", DeviceId="thisIsSenderId", Device="Google%20Cast"' }; expect(result).toMatchObject(correct); diff --git a/src/components/jellyfinApi.ts b/src/components/jellyfinApi.ts index 5d47b344..43e47da7 100644 --- a/src/components/jellyfinApi.ts +++ b/src/components/jellyfinApi.ts @@ -1,5 +1,4 @@ import { ajax } from './fetchhelper'; -import { Dictionary } from '~/types/global'; export abstract class JellyfinApi { // userId that we are connecting as currently @@ -34,9 +33,6 @@ export abstract class JellyfinApi { this.accessToken = accessToken; this.serverAddress = serverAddress; - // remove special characters from the receiver name - receiverName = receiverName.replace(/[^\w\s]/gi, ''); - if (receiverName) { this.deviceName = receiverName; // deviceId just needs to be unique-ish @@ -54,26 +50,39 @@ export abstract class JellyfinApi { } // create the necessary headers for authentication - private static getSecurityHeaders(): Dictionary { - // TODO throw error if this fails + private static getSecurityHeaders(): { Authorization?: string } { + const parameters: Record = { + Client: 'Chromecast' + }; - let auth = - `Jellyfin Client="Chromecast", Device="${this.deviceName}", ` + - `DeviceId="${this.deviceId}", Version="${this.versionNumber}"`; + if (this.accessToken) { + parameters['Token'] = this.accessToken; + } - if (this.userId) { - auth += `, UserId="${this.userId}"`; + if (this.versionNumber) { + parameters['Version'] = this.versionNumber; } - const headers: Dictionary = { - Authorization: auth - }; + if (this.deviceId) { + parameters['DeviceId'] = this.deviceId; + } - if (this.accessToken != undefined) { - headers['X-MediaBrowser-Token'] = this.accessToken; + if (this.deviceName) { + parameters['Device'] = this.deviceName; } - return headers; + let header = 'MediaBrowser'; + + for (const [key, value] of Object.entries(parameters)) { + header += ` ${key}="${encodeURIComponent(value)}", `; + } + + // Remove last comma + header = header.substring(0, header.length - 2); + + return { + Authorization: header + }; } // Create a basic url.