diff --git a/server/api/jellyfin.ts b/server/api/jellyfin.ts index f23e9aceb..81b505f11 100644 --- a/server/api/jellyfin.ts +++ b/server/api/jellyfin.ts @@ -126,25 +126,31 @@ class JellyfinAPI extends ExternalAPI { Password?: string, ClientIP?: string ): Promise { - try { - const headers = ClientIP - ? { - 'X-Forwarded-For': ClientIP, - } - : {}; + const authenticate = async (useHeaders: boolean) => { + const headers = + useHeaders && ClientIP ? { 'X-Forwarded-For': ClientIP } : {}; - const authResponse = await this.post( + return this.post( '/Users/AuthenticateByName', { - Username: Username, + Username, Pw: Password, }, - { - headers: headers, - } + { headers } ); + }; - return authResponse; + try { + return await authenticate(true); + } catch (e) { + logger.debug(`Failed to authenticate with headers: ${e.message}`, { + label: 'Jellyfin API', + ip: ClientIP, + }); + } + + try { + return await authenticate(false); } catch (e) { const status = e.response?.status; diff --git a/server/index.ts b/server/index.ts index b62080778..a9a746562 100644 --- a/server/index.ts +++ b/server/index.ts @@ -27,6 +27,7 @@ import type CacheableLookupType from 'cacheable-lookup'; import { TypeormStore } from 'connect-typeorm/out'; import cookieParser from 'cookie-parser'; import csurf from 'csurf'; +import { lookup } from 'dns'; import type { NextFunction, Request, Response } from 'express'; import express from 'express'; import * as OpenApiValidator from 'express-openapi-validator'; @@ -54,6 +55,19 @@ app const CacheableLookup = (await _importDynamic('cacheable-lookup')) .default as typeof CacheableLookupType; const cacheable = new CacheableLookup(); + + const originalLookup = cacheable.lookup; + + // if hostname is localhost use dns.lookup instead of cacheable-lookup + cacheable.lookup = (...args: any) => { + const [hostname] = args; + if (hostname === 'localhost') { + lookup(...(args as Parameters)); + } else { + originalLookup(...(args as Parameters)); + } + }; + cacheable.install(http.globalAgent); cacheable.install(https.globalAgent); diff --git a/server/routes/auth.ts b/server/routes/auth.ts index 82c34b153..52c63ff29 100644 --- a/server/routes/auth.ts +++ b/server/routes/auth.ts @@ -14,6 +14,7 @@ import { ApiError } from '@server/types/error'; import * as EmailValidator from 'email-validator'; import { Router } from 'express'; import gravatarUrl from 'gravatar-url'; +import net from 'net'; const authRoutes = Router(); @@ -271,11 +272,21 @@ authRoutes.post('/jellyfin', async (req, res, next) => { ? jellyfinHost.slice(0, -1) : jellyfinHost; - const ip = req.ip ? req.ip.split(':').reverse()[0] : undefined; + const ip = req.ip; + let clientIp; + + if (ip) { + if (net.isIPv4(ip)) { + clientIp = ip; + } else if (net.isIPv6(ip)) { + clientIp = ip.startsWith('::ffff:') ? ip.substring(7) : ip; + } + } + const account = await jellyfinserver.login( body.username, body.password, - ip + clientIp ); // Next let's see if the user already exists