fix: persist token after refresh (#1006)
After a token refresh/exchange, persist the new refresh and id token
This commit is contained in:
@@ -333,15 +333,20 @@ if (cli.flags.login) {
|
|||||||
// Ensure the API key is available as an environment variable for legacy code
|
// Ensure the API key is available as an environment variable for legacy code
|
||||||
process.env["OPENAI_API_KEY"] = apiKey;
|
process.env["OPENAI_API_KEY"] = apiKey;
|
||||||
|
|
||||||
if (cli.flags.free && savedTokens?.refresh_token) {
|
if (cli.flags.free) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(`${chalk.bold("codex --free")} attempting to redeem credits...`);
|
console.log(`${chalk.bold("codex --free")} attempting to redeem credits...`);
|
||||||
await maybeRedeemCredits(
|
if (!savedTokens?.refresh_token) {
|
||||||
client.issuer,
|
apiKey = await fetchApiKey(client.issuer, client.client_id, true);
|
||||||
client.client_id,
|
// fetchApiKey includes credit redemption as the end of the flow
|
||||||
savedTokens.refresh_token,
|
} else {
|
||||||
savedTokens.id_token,
|
await maybeRedeemCredits(
|
||||||
);
|
client.issuer,
|
||||||
|
client.client_id,
|
||||||
|
savedTokens.refresh_token,
|
||||||
|
savedTokens.id_token,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set of providers that don't require API keys
|
// Set of providers that don't require API keys
|
||||||
|
|||||||
@@ -132,13 +132,37 @@ async function maybeRedeemCredits(
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const refreshData = (await refreshRes.json()) as { id_token: string };
|
const refreshData = (await refreshRes.json()) as {
|
||||||
|
id_token: string;
|
||||||
|
refresh_token?: string;
|
||||||
|
};
|
||||||
currentIdToken = refreshData.id_token;
|
currentIdToken = refreshData.id_token;
|
||||||
idClaims = JSON.parse(
|
idClaims = JSON.parse(
|
||||||
Buffer.from(currentIdToken.split(".")[1]!, "base64url").toString(
|
Buffer.from(currentIdToken.split(".")[1]!, "base64url").toString(
|
||||||
"utf8",
|
"utf8",
|
||||||
),
|
),
|
||||||
) as IDTokenClaims;
|
) as IDTokenClaims;
|
||||||
|
if (refreshData.refresh_token) {
|
||||||
|
try {
|
||||||
|
const home = os.homedir();
|
||||||
|
const authDir = path.join(home, ".codex");
|
||||||
|
const authFile = path.join(authDir, "auth.json");
|
||||||
|
const existingJson = JSON.parse(
|
||||||
|
await fs.readFile(authFile, "utf-8"),
|
||||||
|
);
|
||||||
|
existingJson.tokens.id_token = currentIdToken;
|
||||||
|
existingJson.tokens.refresh_token = refreshData.refresh_token;
|
||||||
|
existingJson.last_refresh = new Date().toISOString();
|
||||||
|
await fs.writeFile(
|
||||||
|
authFile,
|
||||||
|
JSON.stringify(existingJson, null, 2),
|
||||||
|
{ mode: 0o600 },
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn("Unable to update refresh token in auth file:", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn("Unable to refresh ID token via token-exchange:", err);
|
console.warn("Unable to refresh ID token via token-exchange:", err);
|
||||||
@@ -200,7 +224,7 @@ async function maybeRedeemCredits(
|
|||||||
const redeemRes = await fetch(`${apiHost}/v1/billing/redeem_credits`, {
|
const redeemRes = await fetch(`${apiHost}/v1/billing/redeem_credits`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ id_token: idToken }),
|
body: JSON.stringify({ id_token: currentIdToken }),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!redeemRes.ok) {
|
if (!redeemRes.ok) {
|
||||||
@@ -713,8 +737,9 @@ async function signInFlow(issuer: string, clientId: string): Promise<string> {
|
|||||||
export async function getApiKey(
|
export async function getApiKey(
|
||||||
issuer: string,
|
issuer: string,
|
||||||
clientId: string,
|
clientId: string,
|
||||||
|
forceLogin: boolean = false,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
if (process.env["OPENAI_API_KEY"]) {
|
if (!forceLogin && process.env["OPENAI_API_KEY"]) {
|
||||||
return process.env["OPENAI_API_KEY"]!;
|
return process.env["OPENAI_API_KEY"]!;
|
||||||
}
|
}
|
||||||
const choice = await promptUserForChoice();
|
const choice = await promptUserForChoice();
|
||||||
|
|||||||
Reference in New Issue
Block a user