fix(jellyfin): align session-store config contract

This commit is contained in:
2026-02-21 23:27:22 -08:00
parent 4682938d17
commit 7a561fca45
8 changed files with 64 additions and 13 deletions

View File

@@ -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 ...`):

View File

@@ -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` |

View File

@@ -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.

View File

@@ -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.

View File

@@ -85,8 +85,6 @@ export const INTEGRATIONS_DEFAULT_CONFIG: Pick<
enabled: false,
serverUrl: '',
username: '',
accessToken: '',
userId: '',
deviceId: 'subminer',
clientName: 'SubMiner',
clientVersion: '0.1.0',

View File

@@ -41,8 +41,6 @@ export function applyIntegrationConfig(context: ResolveContext): void {
const stringKeys = [
'serverUrl',
'username',
'accessToken',
'userId',
'deviceId',
'clientName',
'clientVersion',

View File

@@ -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<string, unknown>), false);
assert.equal('userId' in (context.resolved.jellyfin as Record<string, unknown>), false);
});

View File

@@ -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,
},
});
},