From 0790da2e0dbcf525be9a498e47601c88ad4c83c5 Mon Sep 17 00:00:00 2001 From: Matt Foxx Date: Tue, 21 Oct 2025 09:10:38 -0400 Subject: [PATCH] feat(plex): Enable accepting self-signed certs #372 (#373) * feat(plex): Enable accepting self-signed certs #372 * docs(plex): Add invalidcert param to plex example config --- config/plex.json.example | 3 +- .../infrastructure/config/source/plex.ts | 10 ++++++ src/backend/sources/PlexApiSource.ts | 34 +++++++++++++++++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/config/plex.json.example b/config/plex.json.example index 79ff1359..679c86cb 100644 --- a/config/plex.json.example +++ b/config/plex.json.example @@ -15,7 +15,8 @@ }, "options": { "logPayload": true, - "logFilterFailure": "debug" + "logFilterFailure": "debug", + "ignoreInvalidCert": "false" } } ] diff --git a/src/backend/common/infrastructure/config/source/plex.ts b/src/backend/common/infrastructure/config/source/plex.ts index c021db70..dda2d20e 100644 --- a/src/backend/common/infrastructure/config/source/plex.ts +++ b/src/backend/common/infrastructure/config/source/plex.ts @@ -74,6 +74,16 @@ export interface PlexApiData extends CommonSourceData, PollingOptions { } export interface PlexApiOptions extends CommonSourceOptions { + /** + * Ignore invalid cert errors when connecting to Plex + * + * Useful for Plex servers using "Required" Secure Connections with self-signed certificates + * + * Do not enable unless you know you need this. + * + * @default false + */ + ignoreInvalidCert?: boolean } export interface PlexApiSourceConfig extends CommonSourceConfig { diff --git a/src/backend/sources/PlexApiSource.ts b/src/backend/sources/PlexApiSource.ts index db90a8eb..de95c590 100644 --- a/src/backend/sources/PlexApiSource.ts +++ b/src/backend/sources/PlexApiSource.ts @@ -13,7 +13,8 @@ import { import { genGroupIdStr, getFirstNonEmptyString, getPlatformIdFromData, isDebugMode, parseBool, } from "../utils.js"; import { buildStatePlayerPlayIdententifyingInfo, hashObject, parseArrayFromMaybeString } from "../utils/StringUtils.js"; import { GetSessionsMetadata } from "@lukehagar/plexjs/sdk/models/operations/getsessions.js"; -import { PlexAPI } from "@lukehagar/plexjs"; +import { PlexAPI, HTTPClient, Fetcher } from "@lukehagar/plexjs"; +import { Agent } from 'undici'; import { PlexApiSourceConfig } from "../common/infrastructure/config/source/plex.js"; import { isPortReachable, joinedUrl } from '../utils/NetworkUtils.js'; import normalizeUrl from 'normalize-url'; @@ -80,10 +81,11 @@ export default class PlexApiSource extends MemoryPositionalSource { devicesAllow = [], devicesBlock = [], librariesAllow = [], - librariesBlock = [], + librariesBlock = [] } = {}, options: { logFilterFailure = (isDebugMode() ? 'debug' : 'warn'), + ignoreInvalidCert = false } = {} } = this.config; @@ -123,9 +125,35 @@ export default class PlexApiSource extends MemoryPositionalSource { this.address = new URL(normal); this.logger.debug(`Config URL: ${this.config.data.url} | Normalized: ${this.address.toString()}`); + let httpClient: HTTPClient | undefined; + + if(ignoreInvalidCert) { + this.logger.debug('Using http client that ignores self-signed certs'); + + // https://github.com/nodejs/undici/issues/1489#issuecomment-1543856261 + const bypassAgent = new Agent({ + connect: { + rejectUnauthorized: false, + }, + }); + + const bypassFetcher: Fetcher = (input, init) => { + + if (init == null) { + // @ts-ignore + return fetch(input, {dispatcher: bypassAgent}); + } else { + // @ts-ignore + return fetch(input, {...init, dispatcher: bypassAgent}); + } + }; + httpClient = new HTTPClient({ fetcher: bypassFetcher }); + } + this.plexApi = new PlexAPI({ serverURL: this.address.toString(), - accessToken: this.config.data.token + accessToken: this.config.data.token, + httpClient }); return true; -- 2.51.2