refactor: resolving PR commets

This refactor includes a change that adds a conditional arg to the ExternalApi get() method to
override the base url. This method was pre-existing and already used in the calls and method.

#943
This commit is contained in:
Hermanus Engelbrecht
2024-08-27 15:27:53 +02:00
parent f5b3b06dfe
commit 0e588bf315
3 changed files with 40 additions and 48 deletions

View File

@@ -60,9 +60,9 @@ class EmbyConnectAPI extends ExternalAPI {
} }
public async authenticateConnectUser(Email?: string, Password?: string) { public async authenticateConnectUser(Email?: string, Password?: string) {
logger.debug( logger.debug(`Attempting to authenticate via EmbyConnect with email:`, {
`Attempting to authenticate via EmbyConnect with email: ${Email}` Email,
); });
const connectAuthResponse = await this.getConnectUserAccessToken( const connectAuthResponse = await this.getConnectUserAccessToken(
Email, Email,
@@ -76,8 +76,7 @@ class EmbyConnectAPI extends ExternalAPI {
const matchingServer = this.findMatchingServer(linkedServers); const matchingServer = this.findMatchingServer(linkedServers);
const embyServerApi = new EmbyServerApi(getHostname(), this.ClientIP); const localUserExchangeResponse = await this.localAuthExchange(
const localUserExchangeResponse = await embyServerApi.localAuthExchange(
matchingServer.AccessKey, matchingServer.AccessKey,
connectAuthResponse.User.Id, connectAuthResponse.User.Id,
this.DeviceId this.DeviceId
@@ -170,36 +169,31 @@ class EmbyConnectAPI extends ExternalAPI {
return matchingServer; return matchingServer;
} }
}
class EmbyServerApi extends ExternalAPI { private async localAuthExchange(
private ClientIP?: string;
constructor(embyHost: string, ClientIP?: string) {
super(embyHost, {}, {});
this.ClientIP = ClientIP;
}
async localAuthExchange(
accessKey: string, accessKey: string,
userId: string, userId: string,
deviceId?: string deviceId?: string
): Promise<LocalUserAuthExchangeResponse> { ): Promise<LocalUserAuthExchangeResponse> {
try { try {
return await this.get('/emby/Connect/Exchange', { return this.get(
format: 'json', '/emby/Connect/Exchange',
ConnectUserId: userId, {
'X-Emby-Client': 'Jellyseerr', format: 'json',
'X-Emby-Device-Id': deviceId ?? uniqueId(), ConnectUserId: userId,
'X-Emby-Client-Version': getAppVersion(), 'X-Emby-Client': 'Jellyseerr',
'X-Emby-Device-Name': 'Jellyseerr', 'X-Emby-Device-Id': deviceId ?? uniqueId(),
'X-Emby-Token': accessKey, 'X-Emby-Client-Version': getAppVersion(),
}); 'X-Emby-Device-Name': 'Jellyseerr',
'X-Emby-Token': accessKey,
},
undefined,
{},
getHostname()
);
} catch (e) { } catch (e) {
logger.error(`Failed to do local user auth exchange: ${e.message}`, { logger.debug('Failed local user auth exchange');
label: 'EmbyConnect.EmbyServer API', throw new ApiError(e.cause?.status, ApiErrorCode.InvalidCredentials);
ip: this.ClientIP,
});
throw new ApiError(e.cause?.status, ApiErrorCode.InvalidAuthToken);
} }
} }
} }

View File

@@ -47,7 +47,8 @@ class ExternalAPI {
endpoint: string, endpoint: string,
params?: Record<string, string>, params?: Record<string, string>,
ttl?: number, ttl?: number,
config?: RequestInit config?: RequestInit,
overwriteBaseUrl?: string
): Promise<T> { ): Promise<T> {
const cacheKey = this.serializeCacheKey(endpoint, { const cacheKey = this.serializeCacheKey(endpoint, {
...this.params, ...this.params,
@@ -58,7 +59,7 @@ class ExternalAPI {
return cachedItem; return cachedItem;
} }
const url = this.formatUrl(endpoint, params); const url = this.formatUrl(endpoint, params, overwriteBaseUrl);
const response = await this.fetch(url, { const response = await this.fetch(url, {
...config, ...config,
headers: { headers: {

View File

@@ -2,7 +2,9 @@
import EmbyConnectAPI from '@server/api/embyconnect'; import EmbyConnectAPI from '@server/api/embyconnect';
import ExternalAPI from '@server/api/externalapi'; import ExternalAPI from '@server/api/externalapi';
import { ApiErrorCode } from '@server/constants/error'; import { ApiErrorCode } from '@server/constants/error';
import { MediaServerType } from '@server/constants/server';
import availabilitySync from '@server/lib/availabilitySync'; import availabilitySync from '@server/lib/availabilitySync';
import { getSettings } from '@server/lib/settings';
import logger from '@server/logger'; import logger from '@server/logger';
import { ApiError } from '@server/types/error'; import { ApiError } from '@server/types/error';
import { getAppVersion } from '@server/utils/appVersion'; import { getAppVersion } from '@server/utils/appVersion';
@@ -175,13 +177,20 @@ class JellyfinAPI extends ExternalAPI {
} }
} }
if (Username && EmailValidator.validate(Username)) { const settings = getSettings();
if (
settings.main.mediaServerType === MediaServerType.EMBY &&
Username &&
EmailValidator.validate(Username)
) {
try { try {
return await this.authenticateWithEmbyConnect( const connectApi = new EmbyConnectAPI({
ClientIP, ClientIP: ClientIP,
Username, DeviceId: this.deviceId,
Password });
);
return await connectApi.authenticateConnectUser(Username, Password);
} catch (e) { } catch (e) {
logger.debug(`Emby Connect authentication failed: ${e}`); logger.debug(`Emby Connect authentication failed: ${e}`);
throw new ApiError(e.cause?.status, ApiErrorCode.InvalidCredentials); throw new ApiError(e.cause?.status, ApiErrorCode.InvalidCredentials);
@@ -191,18 +200,6 @@ class JellyfinAPI extends ExternalAPI {
} }
} }
private async authenticateWithEmbyConnect(
ClientIP: string | undefined,
Username: string | undefined,
Password: string | undefined
): Promise<JellyfinLoginResponse> {
const connectApi = new EmbyConnectAPI({
ClientIP: ClientIP,
DeviceId: this.deviceId,
});
return await connectApi.authenticateConnectUser(Username, Password);
}
public setUserId(userId: string): void { public setUserId(userId: string): void {
this.userId = userId; this.userId = userId;
return; return;