From 7a561fca4540764b6a2c9b75b202bf5675ec6e3d Mon Sep 17 00:00:00 2001 From: sudacode Date: Sat, 21 Feb 2026 23:27:22 -0800 Subject: [PATCH] fix(jellyfin): align session-store config contract --- docs/configuration.md | 5 ++- docs/subagents/INDEX.md | 3 ++ ...x-jellyfin-ts-fix-20260222T071530Z-5e50.md | 36 +++++++++++++++++++ docs/subagents/collaboration.md | 7 ++++ .../definitions/defaults-integrations.ts | 2 -- src/config/resolve/integrations.ts | 2 -- src/config/resolve/jellyfin.test.ts | 11 ++++++ src/main.ts | 11 +++--- 8 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 docs/subagents/agents/codex-jellyfin-ts-fix-20260222T071530Z-5e50.md diff --git a/docs/configuration.md b/docs/configuration.md index d532798..c677df8 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -498,8 +498,6 @@ Jellyfin integration is optional and disabled by default. When enabled, SubMiner | `enabled` | `true`, `false` | Enable Jellyfin integration and CLI commands (default: `false`) | | `serverUrl` | string (URL) | Jellyfin server base URL | | `username` | string | Default username used by `--jellyfin-login` | -| `accessToken` | string | Optional explicit Jellyfin access token override; leave empty to use stored local token | -| `userId` | string | Jellyfin user id bound to token/session | | `deviceId` | string | Client device id sent in auth headers (default: `subminer`) | | `clientName` | string | Client name sent in auth headers (default: `SubMiner`) | | `clientVersion` | string | Client version sent in auth headers (default: `0.1.0`) | @@ -514,7 +512,8 @@ Jellyfin integration is optional and disabled by default. When enabled, SubMiner | `directPlayContainers` | string[] | Container allowlist for direct play decisions | | `transcodeVideoCodec` | string | Preferred transcode video codec fallback (default: `h264`) | -When `jellyfin.accessToken` is empty, SubMiner uses the locally stored encrypted token saved from Jellyfin login/setup. +Jellyfin auth session (`accessToken` + `userId`) is stored in local encrypted storage after login/setup. +Optional environment overrides: `SUBMINER_JELLYFIN_ACCESS_TOKEN`, `SUBMINER_JELLYFIN_USER_ID`. Jellyfin direct app CLI commands (`SubMiner.AppImage ...`): diff --git a/docs/subagents/INDEX.md b/docs/subagents/INDEX.md index 132aa8e..9f9c012 100644 --- a/docs/subagents/INDEX.md +++ b/docs/subagents/INDEX.md @@ -65,3 +65,6 @@ Read first. Keep concise. | `codex-fix-ci-20260222T025848Z-0xdl` | `codex-fix-ci` | `Inspect failing GitHub Actions PR checks and implement approved fix` | `done` | `docs/subagents/agents/codex-fix-ci-20260222T025848Z-0xdl.md` | `2026-02-22T03:25:40Z` | | `opencode-task100-dead-code-prune-20260222T033155Z-qenz` | `opencode-task100-dead-code-prune` | `Execute TASK-100 dead-code prune and cleanup via writing-plans + executing-plans (no commit)` | `done` | `docs/subagents/agents/opencode-task100-dead-code-prune-20260222T033155Z-qenz.md` | `2026-02-22T04:00:41Z` | | `codex-gh-fix-ci-20260222T054631Z-m4t8` | `codex-gh-fix-ci` | `Inspect failing GitHub Actions checks; propose fix plan before implementation` | `done` | `docs/subagents/agents/codex-gh-fix-ci-20260222T054631Z-m4t8.md` | `2026-02-22T06:11:15Z` | +| `codex-fix-rebase-errors-20260222T062235Z-73h4` | `codex-fix-rebase-errors` | `Resolve current git rebase conflicts in ipc/main runtime files and land clean rebase state` | `done` | `docs/subagents/agents/codex-fix-rebase-errors-20260222T062235Z-73h4.md` | `2026-02-22T06:30:48Z` | +| `codex-review-cleanup-20260222T065718Z-9p4m` | `codex-review-cleanup` | `Review post-refactor codebase quality and create cleanup tickets with concrete scope and completion criteria` | `done` | `docs/subagents/agents/codex-review-cleanup-20260222T065718Z-9p4m.md` | `2026-02-22T07:04:48Z` | +| `codex-jellyfin-ts-fix-20260222T071530Z-5e50` | `codex-jellyfin-ts-fix` | `Fix Jellyfin token/session type drift causing TS compile failures in config+main.` | `done` | `docs/subagents/agents/codex-jellyfin-ts-fix-20260222T071530Z-5e50.md` | `2026-02-22T07:23:47Z` | diff --git a/docs/subagents/agents/codex-jellyfin-ts-fix-20260222T071530Z-5e50.md b/docs/subagents/agents/codex-jellyfin-ts-fix-20260222T071530Z-5e50.md new file mode 100644 index 0000000..e530726 --- /dev/null +++ b/docs/subagents/agents/codex-jellyfin-ts-fix-20260222T071530Z-5e50.md @@ -0,0 +1,36 @@ +# codex-jellyfin-ts-fix-20260222T071530Z-5e50 + +- alias: `codex-jellyfin-ts-fix` +- mission: `Fix Jellyfin token/session type drift causing current TS build break in config + main runtime wiring` +- status: `done` +- branch: `main` +- started_at: `2026-02-22T07:15:30Z` +- heartbeat_minutes: `5` + +## Current Work (newest first) +- [2026-02-22T07:23:47Z] progress: updated stale Jellyfin docs entry in `docs/configuration.md` to remove config `accessToken/userId` guidance and document stored session + env override keys. +- [2026-02-22T07:18:07Z] test: green - `bun run tsc --noEmit`. +- [2026-02-22T07:18:07Z] test: green - `bun test src/config/resolve/jellyfin.test.ts src/main/runtime/jellyfin-client-info-main-deps.test.ts src/main/runtime/jellyfin-cli-main-deps.test.ts src/main/runtime/jellyfin-setup-window-main-deps.test.ts`. +- [2026-02-22T07:17:00Z] progress: aligned `src/main.ts` to Jellyfin session-store API names and removed legacy config auth fields. +- [2026-02-22T07:16:58Z] test: red - added regression `jellyfin legacy auth keys are ignored by resolver` and confirmed failure before fix. +- [2026-02-22T07:15:30Z] intent: scoped to existing backlog ticket `backlog/tasks/task-93 - Remove-Jellyfin-token-userId-from-config-use-env-and-stored-session.md`. + +## Files Touched +- `src/config/definitions/defaults-integrations.ts` +- `src/config/resolve/integrations.ts` +- `src/config/resolve/jellyfin.test.ts` +- `src/main.ts` +- `docs/configuration.md` +- `docs/subagents/agents/codex-jellyfin-ts-fix-20260222T071530Z-5e50.md` +- `docs/subagents/INDEX.md` +- `docs/subagents/collaboration.md` + +## Assumptions +- compile break came from partial migration from token-in-config to stored-session model. +- existing backlog task coverage is sufficient; no new task required for this narrow fix. + +## Open Questions / Blockers +- none + +## Next Step +- handoff complete. diff --git a/docs/subagents/collaboration.md b/docs/subagents/collaboration.md index ccdd781..e349fad 100644 --- a/docs/subagents/collaboration.md +++ b/docs/subagents/collaboration.md @@ -91,3 +91,10 @@ Shared notes. Append-only. - [2026-02-22T04:00:41Z] [opencode-task100-dead-code-prune-20260222T033155Z-qenz|opencode-task100-dead-code-prune] completed TASK-100 execution pass: removed confirmed dead imports/helpers/exports across Anki/core/renderer/provider modules, added dead-code report at `docs/reports/2026-02-22-task-100-dead-code-report.md`, verified build + core/config src tests + file-budget checks, and prepared Backlog finalization updates. - [2026-02-22T05:46:31Z] [codex-gh-fix-ci-20260222T054631Z-m4t8|codex-gh-fix-ci] starting CI triage via gh-fix-ci skill; no branch PR found for `main`, falling back to latest failed GitHub Actions runs on `main` for root-cause summary + fix plan. - [2026-02-22T06:11:15Z] [codex-gh-fix-ci-20260222T054631Z-m4t8|codex-gh-fix-ci] completed requested change: removed file-budget guardrail script + package scripts + CI invocation; retained main-fanin/runtime-cycle strict checks and updated active docs commands. +- [2026-02-22T06:22:35Z] [codex-fix-rebase-errors-20260222T062235Z-73h4|codex-fix-rebase-errors] conflict note: resolving in-flight rebase conflicts in `src/core/services/ipc.ts` and `src/main.ts` (files recently touched by multiple agents); keeping scope to conflict resolution only. +- [2026-02-22T06:30:48Z] [codex-fix-rebase-errors-20260222T062235Z-73h4|codex-fix-rebase-errors] completed rebase recovery: resolved two rebase stops (`main/ipc` + `config/docs`), preserved modular config architecture while porting `subtitleStyle.hoverTokenColor`, and finished interactive rebase cleanly on `main`. +- [2026-02-22T06:57:52Z] [codex-review-cleanup-20260222T065718Z-9p4m|codex-review-cleanup] starting post-refactor code review pass + backlog ticket creation for remaining simplification/cleanup actions; scope whole repo with maintainability focus. +- [2026-02-22T07:04:48Z] [codex-review-cleanup-20260222T065718Z-9p4m|codex-review-cleanup] completed review + ticketing pass: flagged Jellyfin session migration compile break and opened TASK-102..TASK-106; refreshed TASK-57 with current context/action steps/DoD. +- [2026-02-22T07:15:30Z] [codex-jellyfin-ts-fix-20260222T071530Z-5e50|codex-jellyfin-ts-fix] overlap note: fixing Jellyfin config/runtime type drift touching `src/main.ts`, `src/config/definitions/*`, `src/config/resolve/*`; preserving recent refactor structure and limiting scope to TS errors only. +- [2026-02-22T07:18:07Z] [codex-jellyfin-ts-fix-20260222T071530Z-5e50|codex-jellyfin-ts-fix] completed TS fix: removed legacy `jellyfin.accessToken/userId` from defaults/resolver, aligned `src/main.ts` to `loadSession/saveSession/clearSession`, added resolver regression test for legacy keys, and verified `bun run tsc --noEmit` + focused jellyfin tests green. +- [2026-02-22T07:23:47Z] [codex-jellyfin-ts-fix-20260222T071530Z-5e50|codex-jellyfin-ts-fix] docs follow-up: fixed stale `docs/configuration.md` Jellyfin table/text to remove `accessToken/userId` config guidance; now states stored encrypted session + env override keys. diff --git a/src/config/definitions/defaults-integrations.ts b/src/config/definitions/defaults-integrations.ts index abc6a20..8199c03 100644 --- a/src/config/definitions/defaults-integrations.ts +++ b/src/config/definitions/defaults-integrations.ts @@ -85,8 +85,6 @@ export const INTEGRATIONS_DEFAULT_CONFIG: Pick< enabled: false, serverUrl: '', username: '', - accessToken: '', - userId: '', deviceId: 'subminer', clientName: 'SubMiner', clientVersion: '0.1.0', diff --git a/src/config/resolve/integrations.ts b/src/config/resolve/integrations.ts index b6051f9..3c2b1f3 100644 --- a/src/config/resolve/integrations.ts +++ b/src/config/resolve/integrations.ts @@ -41,8 +41,6 @@ export function applyIntegrationConfig(context: ResolveContext): void { const stringKeys = [ 'serverUrl', 'username', - 'accessToken', - 'userId', 'deviceId', 'clientName', 'clientVersion', diff --git a/src/config/resolve/jellyfin.test.ts b/src/config/resolve/jellyfin.test.ts index 0c8eb79..ad905d2 100644 --- a/src/config/resolve/jellyfin.test.ts +++ b/src/config/resolve/jellyfin.test.ts @@ -14,3 +14,14 @@ test('jellyfin directPlayContainers are normalized', () => { assert.deepEqual(context.resolved.jellyfin.directPlayContainers, ['mkv', 'mp4', 'webm']); }); + +test('jellyfin legacy auth keys are ignored by resolver', () => { + const { context } = createResolveContext({ + jellyfin: ({ accessToken: 'legacy-token', userId: 'legacy-user' } as unknown) as never, + }); + + applyIntegrationConfig(context); + + assert.equal('accessToken' in (context.resolved.jellyfin as Record), false); + assert.equal('userId' in (context.resolved.jellyfin as Record), false); +}); diff --git a/src/main.ts b/src/main.ts index d747859..658095d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1145,7 +1145,8 @@ function getResolvedConfig() { const buildGetResolvedJellyfinConfigMainDepsHandler = createBuildGetResolvedJellyfinConfigMainDepsHandler({ getResolvedConfig: () => getResolvedConfig(), - loadStoredToken: () => jellyfinTokenStore.loadToken(), + loadStoredSession: () => jellyfinTokenStore.loadSession(), + getEnv: (name) => process.env[name], }); const getResolvedJellyfinConfigMainDeps = buildGetResolvedJellyfinConfigMainDepsHandler(); const getResolvedJellyfinConfigHandler = createGetResolvedJellyfinConfigHandler( @@ -1295,8 +1296,8 @@ const buildHandleJellyfinAuthCommandsMainDepsHandler = }, authenticateWithPassword: (serverUrl, username, password, clientInfo) => authenticateWithPasswordRuntime(serverUrl, username, password, clientInfo), - saveStoredToken: (token) => jellyfinTokenStore.saveToken(token), - clearStoredToken: () => jellyfinTokenStore.clearToken(), + saveStoredSession: (session) => jellyfinTokenStore.saveSession(session), + clearStoredSession: () => jellyfinTokenStore.clearSession(), logInfo: (message) => logger.info(message), }); const handleJellyfinAuthCommandsMainDeps = buildHandleJellyfinAuthCommandsMainDepsHandler(); @@ -1536,15 +1537,13 @@ const buildOpenJellyfinSetupWindowMainDepsHandler = authenticateWithPassword: (server, username, password, clientInfo) => authenticateWithPasswordRuntime(server, username, password, clientInfo), getJellyfinClientInfo: () => getJellyfinClientInfo(), - saveStoredToken: (token) => jellyfinTokenStore.saveToken(token), + saveStoredSession: (session) => jellyfinTokenStore.saveSession(session), patchJellyfinConfig: (session) => { configService.patchRawConfig({ jellyfin: { enabled: true, serverUrl: session.serverUrl, username: session.username, - accessToken: '', - userId: session.userId, }, }); },