fix(auth): scan real session credential paths for fan-out/stale detection
listSessionCredentialPaths scanned <sessions>/<folder>/.claude/.credentials.json, but real session creds live at <sessions>/<folder>/services/<serviceId>/.claude/.credentials.json (and under tasks/<taskId>/...). The mismatch meant writeCredentials' fan-out and loadFreshestCredentials' stale-copy scan silently missed every real session file — so old refresh-token copies (family-revocation landmines) were never overwritten and the session→canonical write-back could not converge dormant sessions. Rewrite it via the pure, tested collectSessionCredentialPaths that walks the actual services/<id>/.claude and services/<id>/tasks/<id>/.claude layout. Verified on live data: now matches all 24 real session credential files (was 0). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest';
|
||||
|
||||
import {
|
||||
applyUpdatedTokensToEnvContent,
|
||||
collectSessionCredentialPaths,
|
||||
pickFreshestOAuth,
|
||||
shouldAdoptSessionOAuth,
|
||||
shouldStartTokenRefreshLoop,
|
||||
@@ -134,3 +135,31 @@ describe('shouldAdoptSessionOAuth (session→canonical write-back)', () => {
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('collectSessionCredentialPaths (real session layout)', () => {
|
||||
it('builds service group + task credential paths, not <group>/.claude', () => {
|
||||
const tree: Record<string, string[]> = {
|
||||
'/s': ['iger', 'javis_bot'],
|
||||
'/s/iger/services': ['claude'],
|
||||
'/s/iger/services/claude/tasks': ['task-1'],
|
||||
'/s/javis_bot/services': ['claude'],
|
||||
'/s/javis_bot/services/claude/tasks': [],
|
||||
};
|
||||
const paths = collectSessionCredentialPaths('/s', (dir) => tree[dir] ?? []);
|
||||
expect(paths).toContain(
|
||||
'/s/iger/services/claude/.claude/.credentials.json',
|
||||
);
|
||||
expect(paths).toContain(
|
||||
'/s/iger/services/claude/tasks/task-1/.claude/.credentials.json',
|
||||
);
|
||||
expect(paths).toContain(
|
||||
'/s/javis_bot/services/claude/.claude/.credentials.json',
|
||||
);
|
||||
// Must NOT use the old broken <group>/.claude path that matched nothing.
|
||||
expect(paths).not.toContain('/s/iger/.claude/.credentials.json');
|
||||
});
|
||||
|
||||
it('returns nothing when there are no session folders', () => {
|
||||
expect(collectSessionCredentialPaths('/s', () => [])).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user