Reject malformed pi auth primitives (Sam & Codex)

Treat boolean and numeric auth.json provider entries as unusable credentials while preserving non-empty string, array, and object entries. Extend pi-config tests for empty arrays and primitive malformed entries.

---

Build: pass

Tests: pass — 2210 passed (166 files)

---
Build: pass | Tests: pass — 2210 passed (654 files)
This commit is contained in:
Operator & Codex 2026-05-07 20:11:27 +02:00
parent 1d66edc01e
commit 10f83c46d2
2 changed files with 38 additions and 2 deletions

View file

@ -76,13 +76,16 @@ describe('resolvePiProviderCredentials', () => {
});
});
it('ignores empty auth.json provider entries', () => {
it('ignores unusable auth.json provider entries', () => {
fs.writeFileSync(
authFile,
JSON.stringify({
'openai-codex': {},
openrouter: null,
zai: '',
anthropic: [],
openai: true,
gemini: 42,
}),
'utf-8',
);
@ -105,6 +108,24 @@ describe('resolvePiProviderCredentials', () => {
processEnv: { ZAI_API_KEY: 'zai-test' },
authFile,
});
const anthropic = resolvePiProviderCredentials({
provider: 'anthropic',
envContent: '',
processEnv: {},
authFile,
});
const openai = resolvePiProviderCredentials({
provider: 'openai',
envContent: '',
processEnv: {},
authFile,
});
const gemini = resolvePiProviderCredentials({
provider: 'gemini',
envContent: '',
processEnv: {},
authFile,
});
expect(codex).toEqual({
hasCredential: false,
@ -121,6 +142,21 @@ describe('resolvePiProviderCredentials', () => {
source: 'env',
keyVar: 'ZAI_API_KEY',
});
expect(anthropic).toEqual({
hasCredential: false,
source: 'none',
keyVar: 'ANTHROPIC_API_KEY',
});
expect(openai).toEqual({
hasCredential: false,
source: 'none',
keyVar: 'OPENAI_API_KEY',
});
expect(gemini).toEqual({
hasCredential: false,
source: 'none',
keyVar: 'GEMINI_API_KEY',
});
});
it('checks OLLAMA_HOST for ollama providers', () => {

View file

@ -102,7 +102,7 @@ function readPiAuthFile(authFile: string): Record<string, unknown> {
function hasUsablePiAuthEntry(entry: unknown): boolean {
if (entry === null || entry === undefined) return false;
if (typeof entry === 'string') return entry.trim().length > 0;
if (typeof entry !== 'object') return true;
if (typeof entry !== 'object') return false;
if (Array.isArray(entry)) return entry.length > 0;
return Object.keys(entry).length > 0;
}