api9nin / src /lib /oauth /providerHelpers.js
github-actions[bot]
deploy from github actions 2026-06-18
c8ae75d
Raw
History Blame Contribute Delete
3.11 kB
const BASE64_BLOCK_SIZE = 4;
function validateXaiOAuthEndpoint(rawUrl, field) {
const value = String(rawUrl || "").trim();
if (!value) throw new Error(`xai discovery ${field} is empty`);
let parsed;
try { parsed = new URL(value); } catch (err) {
throw new Error(`xai discovery ${field} is invalid: ${err.message}`);
}
if (parsed.protocol !== "https:") throw new Error(`xai discovery ${field} must use https: ${value}`);
const host = parsed.hostname.toLowerCase().trim();
if (host !== "x.ai" && !host.endsWith(".x.ai")) {
throw new Error(`xai discovery ${field} host ${host} is not on x.ai`);
}
return value;
}
function decodeXaiIdTokenEmail(idToken) {
if (!idToken || typeof idToken !== "string") return undefined;
const parts = idToken.split(".");
if (parts.length !== 3) return undefined;
try {
const base64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
const padding = (BASE64_BLOCK_SIZE - (base64.length % BASE64_BLOCK_SIZE)) % BASE64_BLOCK_SIZE;
const json = Buffer.from(base64 + "=".repeat(padding), "base64").toString("utf8");
const payload = JSON.parse(json);
return payload.email || payload.preferred_username || payload.sub || undefined;
} catch {
return undefined;
}
}
function decodeJwtPayload(jwt) {
try {
if (!jwt || typeof jwt !== "string") return null;
const parts = jwt.split(".");
if (parts.length !== 3) return null;
const base64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
const missingPadding = (BASE64_BLOCK_SIZE - (base64.length % BASE64_BLOCK_SIZE)) % BASE64_BLOCK_SIZE;
const padded = base64 + "=".repeat(missingPadding);
return JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
} catch {
return null;
}
}
function extractEmailFromAccessToken(accessToken) {
const payload = decodeJwtPayload(accessToken);
if (!payload) return undefined;
return payload.email || payload.preferred_username || payload.sub || undefined;
}
export async function fetchKiroProfileArn(accessToken) {
if (!accessToken) return null;
try {
const response = await fetch("https://codewhisperer.us-east-1.amazonaws.com/ListAvailableProfiles", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({ maxResults: 10 }),
});
if (!response.ok) return null;
const data = await response.json();
return data.profiles?.find((p) => p.arn?.trim())?.arn?.trim() || null;
} catch {
return null;
}
}
export function extractCodexAccountInfo(idToken) {
const payload = decodeJwtPayload(idToken);
if (!payload) return {};
const chatgpt = payload["https://api.openai.com/auth"] || {};
return {
email: payload.email,
chatgptAccountId: chatgpt.chatgpt_account_id || payload.account_id,
chatgptPlanType: chatgpt.chatgpt_plan_type || payload.plan_type,
};
}
export {
BASE64_BLOCK_SIZE,
validateXaiOAuthEndpoint,
decodeXaiIdTokenEmail,
decodeJwtPayload,
extractEmailFromAccessToken,
};