fix(FN-1952): read legacy oauth auth
This commit is contained in:
@@ -42,6 +42,46 @@ describe("createFusionAuthStorage", () => {
|
||||
expect(existsSync(getFusionAuthPath(homeDir))).toBe(true);
|
||||
});
|
||||
|
||||
it("reads non-expired legacy Pi OAuth credentials as fallback", async () => {
|
||||
const legacyAgentDir = join(homeDir, ".pi", "agent");
|
||||
mkdirSync(legacyAgentDir, { recursive: true });
|
||||
writeFileSync(
|
||||
join(legacyAgentDir, "auth.json"),
|
||||
JSON.stringify({
|
||||
"openai-codex": {
|
||||
type: "oauth",
|
||||
access: "legacy-access-token",
|
||||
refresh: "legacy-refresh-token",
|
||||
expires: Date.now() + 60_000,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const authStorage = createFusionAuthStorage();
|
||||
|
||||
expect(await authStorage.getApiKey("openai-codex")).toBe("legacy-access-token");
|
||||
});
|
||||
|
||||
it("does not use expired legacy Pi OAuth credentials", async () => {
|
||||
const legacyAgentDir = join(homeDir, ".pi", "agent");
|
||||
mkdirSync(legacyAgentDir, { recursive: true });
|
||||
writeFileSync(
|
||||
join(legacyAgentDir, "auth.json"),
|
||||
JSON.stringify({
|
||||
"openai-codex": {
|
||||
type: "oauth",
|
||||
access: "expired-access-token",
|
||||
refresh: "legacy-refresh-token",
|
||||
expires: Date.now() - 60_000,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const authStorage = createFusionAuthStorage();
|
||||
|
||||
expect(await authStorage.getApiKey("openai-codex")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does not create missing legacy Pi auth files", async () => {
|
||||
const authStorage = createFusionAuthStorage();
|
||||
|
||||
|
||||
@@ -2,8 +2,17 @@ import { existsSync, readFileSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { AuthStorage } from "@mariozechner/pi-coding-agent";
|
||||
import { getOAuthProvider } from "@mariozechner/pi-ai/oauth";
|
||||
import type { OAuthCredentials } from "@mariozechner/pi-ai/oauth";
|
||||
|
||||
type StoredCredential = { type?: string; key?: string };
|
||||
type StoredCredential = {
|
||||
type?: string;
|
||||
key?: string;
|
||||
access?: string;
|
||||
refresh?: string;
|
||||
expires?: number;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
function getHomeDir(): string {
|
||||
return process.env.HOME || process.env.USERPROFILE || homedir();
|
||||
@@ -45,6 +54,30 @@ function resolveStoredApiKey(key: string | undefined): string | undefined {
|
||||
return process.env[key] ?? key;
|
||||
}
|
||||
|
||||
function resolveOAuthApiKey(providerId: string, credential: StoredCredential): string | undefined {
|
||||
if (
|
||||
credential.type !== "oauth" ||
|
||||
typeof credential.access !== "string" ||
|
||||
typeof credential.refresh !== "string" ||
|
||||
typeof credential.expires !== "number" ||
|
||||
Date.now() >= credential.expires
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getOAuthProvider(providerId)?.getApiKey(credential as OAuthCredentials);
|
||||
}
|
||||
|
||||
function resolveStoredCredentialApiKey(providerId: string, credential: StoredCredential | undefined): string | undefined {
|
||||
if (credential?.type === "api_key") {
|
||||
return resolveStoredApiKey(credential.key);
|
||||
}
|
||||
if (credential?.type === "oauth") {
|
||||
return resolveOAuthApiKey(providerId, credential);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function createFusionAuthStorage(): AuthStorage {
|
||||
const primary = AuthStorage.create(getFusionAuthPath());
|
||||
let legacyCredentials = readLegacyCredentials();
|
||||
@@ -83,8 +116,7 @@ export function createFusionAuthStorage(): AuthStorage {
|
||||
const primaryKey = await target.getApiKey(provider);
|
||||
if (primaryKey) return primaryKey;
|
||||
|
||||
const credential = legacyCredentials[provider];
|
||||
return credential?.type === "api_key" ? resolveStoredApiKey(credential.key) : undefined;
|
||||
return resolveStoredCredentialApiKey(provider, legacyCredentials[provider]);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user