From 131a5a2b0b1a235599940affc183b93c36f12ade Mon Sep 17 00:00:00 2001 From: Fallenbagel <98979876+Fallenbagel@users.noreply.github.com> Date: Sun, 12 Jan 2025 09:51:41 +0800 Subject: [PATCH] fix: resolve plex user mismatch due to caching issues (#1242) * fix: resolve plex user mismatch due to caching issues This commit addresses an issue where cached responses for PlexTV API requests could return incorrect user data when multiple users were logged in. This was caused by a shared cache key that did not account for differences in auth tokens, i.e `X-Plex-Token`. The `serializeCacheKey` method should now include headers in the cache key generation to ensure unique cache keys. This should fix the plex user mismatch that occurred due to the same cache key being used without accounting for the difference in auth token. fix #1227 * fix: adds the default params and optional params, add the headers in all methods * refactor: apply review commits and rename params to options in cachekey --- server/api/externalapi.ts | 46 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/server/api/externalapi.ts b/server/api/externalapi.ts index 9d6ef8d4a..d17ebf99e 100644 --- a/server/api/externalapi.ts +++ b/server/api/externalapi.ts @@ -69,10 +69,13 @@ class ExternalAPI { ttl?: number, config?: RequestInit ): Promise { + const headers = { ...this.defaultHeaders, ...config?.headers }; const cacheKey = this.serializeCacheKey(endpoint, { ...this.params, ...params, + headers, }); + const cachedItem = this.cache?.get(cacheKey); if (cachedItem) { return cachedItem; @@ -81,10 +84,7 @@ class ExternalAPI { const url = this.formatUrl(endpoint, params); const response = await this.fetch(url, { ...config, - headers: { - ...this.defaultHeaders, - ...config?.headers, - }, + headers, }); if (!response.ok) { const text = await response.text(); @@ -111,10 +111,13 @@ class ExternalAPI { ttl?: number, config?: RequestInit ): Promise { + const headers = { ...this.defaultHeaders, ...config?.headers }; const cacheKey = this.serializeCacheKey(endpoint, { config: { ...this.params, ...params }, + headers, data, }); + const cachedItem = this.cache?.get(cacheKey); if (cachedItem) { return cachedItem; @@ -124,10 +127,7 @@ class ExternalAPI { const response = await this.fetch(url, { method: 'POST', ...config, - headers: { - ...this.defaultHeaders, - ...config?.headers, - }, + headers, body: data ? JSON.stringify(data) : undefined, }); if (!response.ok) { @@ -155,10 +155,13 @@ class ExternalAPI { ttl?: number, config?: RequestInit ): Promise { + const headers = { ...this.defaultHeaders, ...config?.headers }; const cacheKey = this.serializeCacheKey(endpoint, { config: { ...this.params, ...params }, data, + headers, }); + const cachedItem = this.cache?.get(cacheKey); if (cachedItem) { return cachedItem; @@ -168,10 +171,7 @@ class ExternalAPI { const response = await this.fetch(url, { method: 'PUT', ...config, - headers: { - ...this.defaultHeaders, - ...config?.headers, - }, + headers, body: JSON.stringify(data), }); if (!response.ok) { @@ -227,9 +227,11 @@ class ExternalAPI { config?: RequestInit, overwriteBaseUrl?: string ): Promise { + const headers = { ...this.defaultHeaders, ...config?.headers }; const cacheKey = this.serializeCacheKey(endpoint, { ...this.params, ...params, + headers, }); const cachedItem = this.cache?.get(cacheKey); @@ -244,10 +246,7 @@ class ExternalAPI { const url = this.formatUrl(endpoint, params, overwriteBaseUrl); this.fetch(url, { ...config, - headers: { - ...this.defaultHeaders, - ...config?.headers, - }, + headers, }).then(async (response) => { if (!response.ok) { const text = await response.text(); @@ -270,10 +269,7 @@ class ExternalAPI { const url = this.formatUrl(endpoint, params, overwriteBaseUrl); const response = await this.fetch(url, { ...config, - headers: { - ...this.defaultHeaders, - ...config?.headers, - }, + headers, }); if (!response.ok) { const text = await response.text(); @@ -293,10 +289,10 @@ class ExternalAPI { return data; } - protected removeCache(endpoint: string, params?: Record) { + protected removeCache(endpoint: string, options?: Record) { const cacheKey = this.serializeCacheKey(endpoint, { ...this.params, - ...params, + ...options, }); this.cache?.del(cacheKey); } @@ -325,13 +321,13 @@ class ExternalAPI { private serializeCacheKey( endpoint: string, - params?: Record + options?: Record ) { - if (!params) { + if (!options) { return `${this.baseUrl}${endpoint}`; } - return `${this.baseUrl}${endpoint}${JSON.stringify(params)}`; + return `${this.baseUrl}${endpoint}${JSON.stringify(options)}`; } private async getDataFromResponse(response: Response) {