From 60f3f05f67907973f8ff4c993e52c215670a1ac2 Mon Sep 17 00:00:00 2001 From: FoxxMD Date: Mon, 30 Jun 2025 12:57:14 +0000 Subject: [PATCH 1/4] fix(Plex): Bump plexjs version to fix response validation #314 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 12ad0f87..5f6fbba0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "@gr2m/net-interceptor": "^1.0.0", "@jellyfin/sdk": "^0.11.0", "@kenyip/backoff-strategies": "^1.0.4", - "@lukehagar/plexjs": "^0.32.1", + "@lukehagar/plexjs": "^0.39.0", "@react-nano/use-event-source": "^0.13.0", "@reduxjs/toolkit": "^1.9.5", "@supercharge/promise-pool": "^3.0.0", @@ -1543,9 +1543,9 @@ "integrity": "sha512-vduQZw2ctS3kIuSnCSSRiE4J90Y8WShR9xVG+e1lvFWksU2aTxjdkArcQqJ+XLm22JS380OZmrIPY1U06TAsng==" }, "node_modules/@lukehagar/plexjs": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/@lukehagar/plexjs/-/plexjs-0.32.1.tgz", - "integrity": "sha512-cEIpepR1/BJYQey2lbzPhy342ZR/JmkChXKS+bOQkGLg1F17n45Zf650W67sBKMvF63effNVT0iUF3Fi3D7yPQ==", + "version": "0.39.0", + "resolved": "https://registry.npmjs.org/@lukehagar/plexjs/-/plexjs-0.39.0.tgz", + "integrity": "sha512-BXNHTh1Z9K0bb5qFKgYZv7gOC9+wYzOsatp/+DRGShGhp40bH0lTShzD6acKjqlIvqi2Pm7UJnF8+yBipE9Qmg==", "peerDependencies": { "zod": ">= 3" } diff --git a/package.json b/package.json index 67934700..c4252b0f 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@gr2m/net-interceptor": "^1.0.0", "@jellyfin/sdk": "^0.11.0", "@kenyip/backoff-strategies": "^1.0.4", - "@lukehagar/plexjs": "^0.32.1", + "@lukehagar/plexjs": "^0.39.0", "@react-nano/use-event-source": "^0.13.0", "@reduxjs/toolkit": "^1.9.5", "@supercharge/promise-pool": "^3.0.0", -- 2.54.0 From 63cebf378487d16369778f74cdd2d60dfae9f29a Mon Sep 17 00:00:00 2001 From: FoxxMD Date: Mon, 30 Jun 2025 13:43:18 +0000 Subject: [PATCH 2/4] fix(plex): Ignore library response validation As temporary fix for #314 --- patches/@lukehagar+plexjs+0.39.0.patch | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 patches/@lukehagar+plexjs+0.39.0.patch diff --git a/patches/@lukehagar+plexjs+0.39.0.patch b/patches/@lukehagar+plexjs+0.39.0.patch new file mode 100644 index 00000000..0d8852d4 --- /dev/null +++ b/patches/@lukehagar+plexjs+0.39.0.patch @@ -0,0 +1,18 @@ +diff --git a/node_modules/@lukehagar/plexjs/funcs/libraryGetAllLibraries.js b/node_modules/@lukehagar/plexjs/funcs/libraryGetAllLibraries.js +index f586c1f..221851d 100644 +--- a/node_modules/@lukehagar/plexjs/funcs/libraryGetAllLibraries.js ++++ b/node_modules/@lukehagar/plexjs/funcs/libraryGetAllLibraries.js +@@ -102,9 +102,9 @@ async function $do(client, options) { + const [result] = await M.match(M.json(200, operations.GetAllLibrariesResponse$inboundSchema, { + key: "object", + }), M.jsonErr(400, errors.GetAllLibrariesBadRequest$inboundSchema), M.jsonErr(401, errors.GetAllLibrariesUnauthorized$inboundSchema), M.fail("4XX"), M.fail("5XX"))(response, req, { extraFields: responseFields }); +- if (!result.ok) { +- return [result, { status: "complete", request: req, response }]; +- } ++ // if (!result.ok) { ++ // return [result, { status: "complete", request: req, response }]; ++ // } + return [result, { status: "complete", request: req, response }]; + } + //# sourceMappingURL=libraryGetAllLibraries.js.map +\ No newline at end of file -- 2.54.0 From 72341ff1de22dbdc73bb506b6e15e6d3589b9942 Mon Sep 17 00:00:00 2001 From: FoxxMD Date: Tue, 15 Jul 2025 17:47:29 +0000 Subject: [PATCH 3/4] fix(plex): Temporary fix for library response validation #314 Catches and ignores outdated validation from @lukehagar/plexjs if we can verify raw value contains the required objects https://github.com/LukeHagar/plexjs/issues/35 --- src/backend/sources/PlexApiSource.ts | 34 +++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/backend/sources/PlexApiSource.ts b/src/backend/sources/PlexApiSource.ts index 17348b41..bad51fbe 100644 --- a/src/backend/sources/PlexApiSource.ts +++ b/src/backend/sources/PlexApiSource.ts @@ -15,9 +15,6 @@ import { genGroupIdStr, getFirstNonEmptyString, getPlatformIdFromData, isDebugMo import { buildStatePlayerPlayIdententifyingInfo, parseArrayFromMaybeString } from "../utils/StringUtils.js"; import { GetSessionsMetadata } from "@lukehagar/plexjs/sdk/models/operations/getsessions.js"; import { PlexAPI } from "@lukehagar/plexjs"; -import { - SDKValidationError, - } from "@lukehagar/plexjs/sdk/models/errors"; import { PlexApiSourceConfig } from "../common/infrastructure/config/source/plex.js"; import { isPortReachable, joinedUrl } from '../utils/NetworkUtils.js'; import normalizeUrl from 'normalize-url'; @@ -29,6 +26,7 @@ import { AbstractPlayerState, PlayerStateOptions } from './PlayerState/AbstractP import { Logger } from '@foxxmd/logging'; import { MemoryPositionalSource } from './MemoryPositionalSource.js'; import { FixedSizeList } from 'fixed-size-list'; +import { SDKValidationError } from '@lukehagar/plexjs/sdk/models/errors/sdkvalidationerror.js'; const shortDeviceId = truncateStringToLength(10, ''); @@ -187,6 +185,17 @@ export default class PlexApiSource extends MemoryPositionalSource { this.libraries = libraries.object.mediaContainer.directory.map(x => ({name: x.title, collectionType: x.type, uuid: x.uuid})); } catch (e) { + if(e instanceof SDKValidationError) { + if((e.rawValue as any).object?.MediaContainer?.Directory !== undefined) { + // ensure directory has required values + const ok = (e.rawValue as any).object?.MediaContainer?.Directory.every(x => x.title !== undefined && x.type !== undefined && x.uuid !== undefined); + if(ok) { + this.libraries = (e.rawValue as any).object.MediaContainer.Directory.map(x => ({name: x.title, collectionType: x.type, uuid: x.uuid})); + return; + } + } + this.logger.debug({ rawValue: e.rawValue }, 'Plex Response'); + } throw new Error('Unable to get server libraries', {cause: e}); } @@ -452,3 +461,22 @@ ${JSON.stringify(obj)}`); getNewPlayer = (logger: Logger, id: PlayPlatformId, opts: PlayerStateOptions) => new PlexPlayerState(logger, id, opts); } + +async function streamToString(stream: any) { + const reader = stream.getReader(); + const textDecoder = new TextDecoder(); + let result = ''; + + async function read() { + const { done, value } = await reader.read(); + + if (done) { + return result; + } + + result += textDecoder.decode(value, { stream: true }); + return read(); + } + + return read(); +} \ No newline at end of file -- 2.54.0 From 87394fbce7e9119048689381291d5880c3feebdb Mon Sep 17 00:00:00 2001 From: FoxxMD Date: Tue, 15 Jul 2025 17:49:12 +0000 Subject: [PATCH 4/4] Remove patch Didn't work anyways --- patches/@lukehagar+plexjs+0.39.0.patch | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 patches/@lukehagar+plexjs+0.39.0.patch diff --git a/patches/@lukehagar+plexjs+0.39.0.patch b/patches/@lukehagar+plexjs+0.39.0.patch deleted file mode 100644 index 0d8852d4..00000000 --- a/patches/@lukehagar+plexjs+0.39.0.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/node_modules/@lukehagar/plexjs/funcs/libraryGetAllLibraries.js b/node_modules/@lukehagar/plexjs/funcs/libraryGetAllLibraries.js -index f586c1f..221851d 100644 ---- a/node_modules/@lukehagar/plexjs/funcs/libraryGetAllLibraries.js -+++ b/node_modules/@lukehagar/plexjs/funcs/libraryGetAllLibraries.js -@@ -102,9 +102,9 @@ async function $do(client, options) { - const [result] = await M.match(M.json(200, operations.GetAllLibrariesResponse$inboundSchema, { - key: "object", - }), M.jsonErr(400, errors.GetAllLibrariesBadRequest$inboundSchema), M.jsonErr(401, errors.GetAllLibrariesUnauthorized$inboundSchema), M.fail("4XX"), M.fail("5XX"))(response, req, { extraFields: responseFields }); -- if (!result.ok) { -- return [result, { status: "complete", request: req, response }]; -- } -+ // if (!result.ok) { -+ // return [result, { status: "complete", request: req, response }]; -+ // } - return [result, { status: "complete", request: req, response }]; - } - //# sourceMappingURL=libraryGetAllLibraries.js.map -\ No newline at end of file -- 2.54.0