From 0ff8d556f842c2e8973e99ed11bb61afa40a0303 Mon Sep 17 00:00:00 2001 From: Lachlan Wisdom <34927628+its-wizza@users.noreply.github.com> Date: Mon, 26 Jan 2026 23:49:42 +1100 Subject: [PATCH 1/7] Add Jellyfin GUID normalization and comparison functions --- server/utils/jellyfin.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 server/utils/jellyfin.ts diff --git a/server/utils/jellyfin.ts b/server/utils/jellyfin.ts new file mode 100644 index 0000000000..7815437e6c --- /dev/null +++ b/server/utils/jellyfin.ts @@ -0,0 +1,25 @@ +export function normalizeJellyfinGuid( + value: string | null | undefined +): string | null { + if (!value || typeof value !== 'string') { + return null; + } + + const normalized = value.replace(/-/g, '').toLowerCase(); + + if (!/^[0-9a-f]{32}$/.test(normalized)) { + return null; + } + + return normalized; +} + +export function jellyfinGuidsEqual( + a?: string | null, + b?: string | null +): boolean { + const na = normalizeJellyfinGuid(a); + const nb = normalizeJellyfinGuid(b); + + return !!na && na === nb; +} From 98a805e8aa2d23090a7f323d90272462364fbc38 Mon Sep 17 00:00:00 2001 From: Lachlan Wisdom <34927628+its-wizza@users.noreply.github.com> Date: Tue, 27 Jan 2026 00:02:04 +1100 Subject: [PATCH 2/7] Remove jellyfinGuidsEqual function Removed the jellyfinGuidsEqual function and its export. --- server/utils/jellyfin.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/server/utils/jellyfin.ts b/server/utils/jellyfin.ts index 7815437e6c..20cc325183 100644 --- a/server/utils/jellyfin.ts +++ b/server/utils/jellyfin.ts @@ -13,13 +13,3 @@ export function normalizeJellyfinGuid( return normalized; } - -export function jellyfinGuidsEqual( - a?: string | null, - b?: string | null -): boolean { - const na = normalizeJellyfinGuid(a); - const nb = normalizeJellyfinGuid(b); - - return !!na && na === nb; -} From 72d8a34fd639eff03c1ef61ab53d0fe58fd6397c Mon Sep 17 00:00:00 2001 From: Lachlan Wisdom <34927628+its-wizza@users.noreply.github.com> Date: Tue, 27 Jan 2026 00:13:08 +1100 Subject: [PATCH 3/7] Allow multiple Jellyfin Guid formats for user import --- server/routes/user/index.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/server/routes/user/index.ts b/server/routes/user/index.ts index 107327bc13..8255d25f9d 100644 --- a/server/routes/user/index.ts +++ b/server/routes/user/index.ts @@ -28,6 +28,7 @@ import { findIndex, sortBy } from 'lodash'; import type { EntityManager } from 'typeorm'; import { In, Not } from 'typeorm'; import userSettingsRoutes from './usersettings'; +import { normalizeJellyfinGuid } from '@server/utils/jellyfin'; const router = Router(); @@ -675,10 +676,16 @@ router.post( jellyfinClient.setUserId(admin.jellyfinUserId ?? ''); const jellyfinUsers = await jellyfinClient.getUsers(); - for (const jellyfinUserId of body.jellyfinUserIds) { - const jellyfinUser = jellyfinUsers.users.find( - (user) => user.Id === jellyfinUserId - ); + const jellyfinUsersById = new Map( + jellyfinUsers.users.map((user) => [ + normalizeJellyfinGuid(user.Id), + user, + ]) + ); + + for (const rawJellyfinUserId of body.jellyfinUserIds) { + const jellyfinUserId = normalizeJellyfinGuid(rawJellyfinUserId); + const jellyfinUser = jellyfinUsersById.get(jellyfinUserId); const user = await userRepository.findOne({ select: ['id', 'jellyfinUserId'], From d9d1aa004b7069d0cfebaf49e7622d4b7a3a638b Mon Sep 17 00:00:00 2001 From: Lachlan Wisdom <34927628+its-wizza@users.noreply.github.com> Date: Tue, 27 Jan 2026 00:19:04 +1100 Subject: [PATCH 4/7] Refactor normalizeJellyfinGuid to simplify value check Simplified the condition for checking the value type. --- server/utils/jellyfin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/utils/jellyfin.ts b/server/utils/jellyfin.ts index 20cc325183..68d3c3c96a 100644 --- a/server/utils/jellyfin.ts +++ b/server/utils/jellyfin.ts @@ -1,7 +1,7 @@ export function normalizeJellyfinGuid( value: string | null | undefined ): string | null { - if (!value || typeof value !== 'string') { + if (!value) { return null; } From f2caaf2f830156d47d0438231b4d068f88d4dcfa Mon Sep 17 00:00:00 2001 From: its-wizza <34927628+its-wizza@users.noreply.github.com> Date: Tue, 27 Jan 2026 01:32:06 +1100 Subject: [PATCH 5/7] fix: handle null from normalize function --- server/routes/user/index.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/routes/user/index.ts b/server/routes/user/index.ts index 8255d25f9d..bd455078b2 100644 --- a/server/routes/user/index.ts +++ b/server/routes/user/index.ts @@ -22,13 +22,13 @@ import { getSettings } from '@server/lib/settings'; import logger from '@server/logger'; import { isAuthenticated } from '@server/middleware/auth'; import { getHostname } from '@server/utils/getHostname'; +import { normalizeJellyfinGuid } from '@server/utils/jellyfin'; import { Router } from 'express'; import gravatarUrl from 'gravatar-url'; import { findIndex, sortBy } from 'lodash'; import type { EntityManager } from 'typeorm'; import { In, Not } from 'typeorm'; import userSettingsRoutes from './usersettings'; -import { normalizeJellyfinGuid } from '@server/utils/jellyfin'; const router = Router(); @@ -685,6 +685,10 @@ router.post( for (const rawJellyfinUserId of body.jellyfinUserIds) { const jellyfinUserId = normalizeJellyfinGuid(rawJellyfinUserId); + if (!jellyfinUserId) { + continue; + } + const jellyfinUser = jellyfinUsersById.get(jellyfinUserId); const user = await userRepository.findOne({ From a107148c5df61fc0464fa4a1b507b0503052740c Mon Sep 17 00:00:00 2001 From: its-wizza <34927628+its-wizza@users.noreply.github.com> Date: Tue, 27 Jan 2026 01:34:09 +1100 Subject: [PATCH 6/7] style: i18n --- src/i18n/locale/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json index b2ddcc2fbb..81ab4ba0fd 100644 --- a/src/i18n/locale/en.json +++ b/src/i18n/locale/en.json @@ -105,7 +105,6 @@ "components.Discover.StudioSlider.studios": "Studios", "components.Discover.TvGenreList.seriesgenres": "Series Genres", "components.Discover.TvGenreSlider.tvgenres": "Series Genres", - "components.DiscoverTvUpcoming.upcomingtv": "Upcoming Series", "components.Discover.createnewslider": "Create New Slider", "components.Discover.customizediscover": "Customize Discover", "components.Discover.discover": "Discover", @@ -139,6 +138,7 @@ "components.Discover.upcomingtv": "Upcoming Series", "components.Discover.updatefailed": "Something went wrong updating the discover customization settings.", "components.Discover.updatesuccess": "Updated discover customization settings.", + "components.DiscoverTvUpcoming.upcomingtv": "Upcoming Series", "components.DownloadBlock.estimatedtime": "Estimated {time}", "components.DownloadBlock.formattedTitle": "{title}: Season {seasonNumber} Episode {episodeNumber}", "components.IssueDetails.IssueComment.areyousuredelete": "Are you sure you want to delete this comment?", @@ -1258,7 +1258,7 @@ "components.Setup.librarieserror": "Validation failed. Please toggle the libraries again to continue.", "components.Setup.servertype": "Choose Server Type", "components.Setup.setup": "Setup", - "components.Setup.signin": "Sign In", + "components.Setup.signin": "Sign in to your account", "components.Setup.signinMessage": "Get started by signing in", "components.Setup.signinWithEmby": "Enter your Emby details", "components.Setup.signinWithJellyfin": "Enter your Jellyfin details", From 66f8a278385ea13849aeb4e6e47bbd6f45f745c4 Mon Sep 17 00:00:00 2001 From: its-wizza <34927628+its-wizza@users.noreply.github.com> Date: Tue, 27 Jan 2026 01:36:28 +1100 Subject: [PATCH 7/7] refactor: remove i18n change, irrelevant --- src/i18n/locale/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json index 81ab4ba0fd..b2ddcc2fbb 100644 --- a/src/i18n/locale/en.json +++ b/src/i18n/locale/en.json @@ -105,6 +105,7 @@ "components.Discover.StudioSlider.studios": "Studios", "components.Discover.TvGenreList.seriesgenres": "Series Genres", "components.Discover.TvGenreSlider.tvgenres": "Series Genres", + "components.DiscoverTvUpcoming.upcomingtv": "Upcoming Series", "components.Discover.createnewslider": "Create New Slider", "components.Discover.customizediscover": "Customize Discover", "components.Discover.discover": "Discover", @@ -138,7 +139,6 @@ "components.Discover.upcomingtv": "Upcoming Series", "components.Discover.updatefailed": "Something went wrong updating the discover customization settings.", "components.Discover.updatesuccess": "Updated discover customization settings.", - "components.DiscoverTvUpcoming.upcomingtv": "Upcoming Series", "components.DownloadBlock.estimatedtime": "Estimated {time}", "components.DownloadBlock.formattedTitle": "{title}: Season {seasonNumber} Episode {episodeNumber}", "components.IssueDetails.IssueComment.areyousuredelete": "Are you sure you want to delete this comment?", @@ -1258,7 +1258,7 @@ "components.Setup.librarieserror": "Validation failed. Please toggle the libraries again to continue.", "components.Setup.servertype": "Choose Server Type", "components.Setup.setup": "Setup", - "components.Setup.signin": "Sign in to your account", + "components.Setup.signin": "Sign In", "components.Setup.signinMessage": "Get started by signing in", "components.Setup.signinWithEmby": "Enter your Emby details", "components.Setup.signinWithJellyfin": "Enter your Jellyfin details",