Skip to content

Commit

Permalink
fix: resolve plex user mismatch due to caching issues (#1242)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
fallenbagel authored Jan 12, 2025
1 parent 7d08f58 commit 131a5a2
Showing 1 changed file with 21 additions and 25 deletions.
46 changes: 21 additions & 25 deletions server/api/externalapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,13 @@ class ExternalAPI {
ttl?: number,
config?: RequestInit
): Promise<T> {
const headers = { ...this.defaultHeaders, ...config?.headers };
const cacheKey = this.serializeCacheKey(endpoint, {
...this.params,
...params,
headers,
});

const cachedItem = this.cache?.get<T>(cacheKey);
if (cachedItem) {
return cachedItem;
Expand All @@ -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();
Expand All @@ -111,10 +111,13 @@ class ExternalAPI {
ttl?: number,
config?: RequestInit
): Promise<T> {
const headers = { ...this.defaultHeaders, ...config?.headers };
const cacheKey = this.serializeCacheKey(endpoint, {
config: { ...this.params, ...params },
headers,
data,
});

const cachedItem = this.cache?.get<T>(cacheKey);
if (cachedItem) {
return cachedItem;
Expand All @@ -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) {
Expand Down Expand Up @@ -155,10 +155,13 @@ class ExternalAPI {
ttl?: number,
config?: RequestInit
): Promise<T> {
const headers = { ...this.defaultHeaders, ...config?.headers };
const cacheKey = this.serializeCacheKey(endpoint, {
config: { ...this.params, ...params },
data,
headers,
});

const cachedItem = this.cache?.get<T>(cacheKey);
if (cachedItem) {
return cachedItem;
Expand All @@ -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) {
Expand Down Expand Up @@ -227,9 +227,11 @@ class ExternalAPI {
config?: RequestInit,
overwriteBaseUrl?: string
): Promise<T> {
const headers = { ...this.defaultHeaders, ...config?.headers };
const cacheKey = this.serializeCacheKey(endpoint, {
...this.params,
...params,
headers,
});
const cachedItem = this.cache?.get<T>(cacheKey);

Expand All @@ -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();
Expand All @@ -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();
Expand All @@ -293,10 +289,10 @@ class ExternalAPI {
return data;
}

protected removeCache(endpoint: string, params?: Record<string, string>) {
protected removeCache(endpoint: string, options?: Record<string, string>) {
const cacheKey = this.serializeCacheKey(endpoint, {
...this.params,
...params,
...options,
});
this.cache?.del(cacheKey);
}
Expand Down Expand Up @@ -325,13 +321,13 @@ class ExternalAPI {

private serializeCacheKey(
endpoint: string,
params?: Record<string, unknown>
options?: Record<string, unknown>
) {
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) {
Expand Down

0 comments on commit 131a5a2

Please sign in to comment.