mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
fix(jellyfin): align session-store config contract
This commit is contained in:
@@ -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`) |
|
| `enabled` | `true`, `false` | Enable Jellyfin integration and CLI commands (default: `false`) |
|
||||||
| `serverUrl` | string (URL) | Jellyfin server base URL |
|
| `serverUrl` | string (URL) | Jellyfin server base URL |
|
||||||
| `username` | string | Default username used by `--jellyfin-login` |
|
| `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`) |
|
| `deviceId` | string | Client device id sent in auth headers (default: `subminer`) |
|
||||||
| `clientName` | string | Client name 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`) |
|
| `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 |
|
| `directPlayContainers` | string[] | Container allowlist for direct play decisions |
|
||||||
| `transcodeVideoCodec` | string | Preferred transcode video codec fallback (default: `h264`) |
|
| `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 ...`):
|
Jellyfin direct app CLI commands (`SubMiner.AppImage ...`):
|
||||||
|
|
||||||
|
|||||||
@@ -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` |
|
| `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` |
|
| `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-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` |
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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-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-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: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.
|
||||||
|
|||||||
@@ -85,8 +85,6 @@ export const INTEGRATIONS_DEFAULT_CONFIG: Pick<
|
|||||||
enabled: false,
|
enabled: false,
|
||||||
serverUrl: '',
|
serverUrl: '',
|
||||||
username: '',
|
username: '',
|
||||||
accessToken: '',
|
|
||||||
userId: '',
|
|
||||||
deviceId: 'subminer',
|
deviceId: 'subminer',
|
||||||
clientName: 'SubMiner',
|
clientName: 'SubMiner',
|
||||||
clientVersion: '0.1.0',
|
clientVersion: '0.1.0',
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ export function applyIntegrationConfig(context: ResolveContext): void {
|
|||||||
const stringKeys = [
|
const stringKeys = [
|
||||||
'serverUrl',
|
'serverUrl',
|
||||||
'username',
|
'username',
|
||||||
'accessToken',
|
|
||||||
'userId',
|
|
||||||
'deviceId',
|
'deviceId',
|
||||||
'clientName',
|
'clientName',
|
||||||
'clientVersion',
|
'clientVersion',
|
||||||
|
|||||||
@@ -14,3 +14,14 @@ test('jellyfin directPlayContainers are normalized', () => {
|
|||||||
|
|
||||||
assert.deepEqual(context.resolved.jellyfin.directPlayContainers, ['mkv', 'mp4', 'webm']);
|
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);
|
||||||
|
});
|
||||||
|
|||||||
11
src/main.ts
11
src/main.ts
@@ -1145,7 +1145,8 @@ function getResolvedConfig() {
|
|||||||
const buildGetResolvedJellyfinConfigMainDepsHandler =
|
const buildGetResolvedJellyfinConfigMainDepsHandler =
|
||||||
createBuildGetResolvedJellyfinConfigMainDepsHandler({
|
createBuildGetResolvedJellyfinConfigMainDepsHandler({
|
||||||
getResolvedConfig: () => getResolvedConfig(),
|
getResolvedConfig: () => getResolvedConfig(),
|
||||||
loadStoredToken: () => jellyfinTokenStore.loadToken(),
|
loadStoredSession: () => jellyfinTokenStore.loadSession(),
|
||||||
|
getEnv: (name) => process.env[name],
|
||||||
});
|
});
|
||||||
const getResolvedJellyfinConfigMainDeps = buildGetResolvedJellyfinConfigMainDepsHandler();
|
const getResolvedJellyfinConfigMainDeps = buildGetResolvedJellyfinConfigMainDepsHandler();
|
||||||
const getResolvedJellyfinConfigHandler = createGetResolvedJellyfinConfigHandler(
|
const getResolvedJellyfinConfigHandler = createGetResolvedJellyfinConfigHandler(
|
||||||
@@ -1295,8 +1296,8 @@ const buildHandleJellyfinAuthCommandsMainDepsHandler =
|
|||||||
},
|
},
|
||||||
authenticateWithPassword: (serverUrl, username, password, clientInfo) =>
|
authenticateWithPassword: (serverUrl, username, password, clientInfo) =>
|
||||||
authenticateWithPasswordRuntime(serverUrl, username, password, clientInfo),
|
authenticateWithPasswordRuntime(serverUrl, username, password, clientInfo),
|
||||||
saveStoredToken: (token) => jellyfinTokenStore.saveToken(token),
|
saveStoredSession: (session) => jellyfinTokenStore.saveSession(session),
|
||||||
clearStoredToken: () => jellyfinTokenStore.clearToken(),
|
clearStoredSession: () => jellyfinTokenStore.clearSession(),
|
||||||
logInfo: (message) => logger.info(message),
|
logInfo: (message) => logger.info(message),
|
||||||
});
|
});
|
||||||
const handleJellyfinAuthCommandsMainDeps = buildHandleJellyfinAuthCommandsMainDepsHandler();
|
const handleJellyfinAuthCommandsMainDeps = buildHandleJellyfinAuthCommandsMainDepsHandler();
|
||||||
@@ -1536,15 +1537,13 @@ const buildOpenJellyfinSetupWindowMainDepsHandler =
|
|||||||
authenticateWithPassword: (server, username, password, clientInfo) =>
|
authenticateWithPassword: (server, username, password, clientInfo) =>
|
||||||
authenticateWithPasswordRuntime(server, username, password, clientInfo),
|
authenticateWithPasswordRuntime(server, username, password, clientInfo),
|
||||||
getJellyfinClientInfo: () => getJellyfinClientInfo(),
|
getJellyfinClientInfo: () => getJellyfinClientInfo(),
|
||||||
saveStoredToken: (token) => jellyfinTokenStore.saveToken(token),
|
saveStoredSession: (session) => jellyfinTokenStore.saveSession(session),
|
||||||
patchJellyfinConfig: (session) => {
|
patchJellyfinConfig: (session) => {
|
||||||
configService.patchRawConfig({
|
configService.patchRawConfig({
|
||||||
jellyfin: {
|
jellyfin: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
serverUrl: session.serverUrl,
|
serverUrl: session.serverUrl,
|
||||||
username: session.username,
|
username: session.username,
|
||||||
accessToken: '',
|
|
||||||
userId: session.userId,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user