@dataroadinc/setup-auth
Version:
CLI tool and programmatic API for automated OAuth setup across cloud platforms
158 lines (157 loc) • 6.35 kB
JavaScript
import * as fs from "fs";
import * as path from "path";
import { GCP_OAUTH_ALLOWED_DOMAINS, GCP_OAUTH_CLIENT_ID, GCP_OAUTH_CLIENT_SECRET, } from "../env-handler.js";
import { SetupAuthError } from "../error.js";
import { fileExists } from "../file.js";
import { VercelApiClientImpl } from "./api/index.js";
export async function getVercelJsonPath() {
const rootPath = path.resolve(process.cwd(), "../../");
const vercelJsonPath = path.join(rootPath, "vercel.json");
if (fs.existsSync(vercelJsonPath)) {
return vercelJsonPath;
}
return null;
}
export async function getVercelJson() {
const vercelJsonPath = await getVercelJsonPath();
if (vercelJsonPath && fs.existsSync(vercelJsonPath)) {
try {
const vercelJson = JSON.parse(fs.readFileSync(vercelJsonPath, "utf8"));
if (vercelJson.token) {
return vercelJson.token;
}
}
catch (error) {
console.warn("Error reading vercel.json:", error);
}
}
return null;
}
export async function updateVercelWithOAuthCredentials(vercelClient, clientId, clientSecret, allowedDomains) {
const projectName = await vercelClient.getProjectName();
if (!projectName) {
throw new SetupAuthError("Could not determine Vercel project name.");
}
const projectInfo = await vercelClient.getProject(projectName);
const projectId = projectInfo?.id;
if (!projectId) {
throw new SetupAuthError(`Could not retrieve Vercel project info/ID for project name: ${projectName}.`);
}
console.log(`Updating Vercel environment variables for project ${projectName} (ID: ${projectId})...`);
const targets = ["production", "preview", "development"];
const envVarsToSet = [
{ key: GCP_OAUTH_CLIENT_ID, value: clientId, targets },
...(clientSecret
? [{ key: GCP_OAUTH_CLIENT_SECRET, value: clientSecret, targets }]
: []),
...(allowedDomains
? [{ key: GCP_OAUTH_ALLOWED_DOMAINS, value: allowedDomains, targets }]
: []),
];
try {
const existingVars = await vercelClient.getEnvVariables();
const existingVarsMap = new Map(existingVars.map(v => [v.key, v]));
for (const envVar of envVarsToSet) {
const existingVar = existingVarsMap.get(envVar.key);
if (existingVar) {
if (existingVar.value !== envVar.value) {
console.log(`Updating Vercel environment variable ${envVar.key}...`);
try {
await vercelClient.updateEnvVariable(existingVar.id, envVar);
console.log(`Updated Vercel environment variable ${envVar.key}.`);
}
catch (updateError) {
console.warn(`Failed to update env var ${envVar.key}:`, updateError);
}
}
else {
console.log(`Vercel environment variable ${envVar.key} already up-to-date.`);
}
}
else {
console.log(`Creating Vercel environment variable ${envVar.key}...`);
await vercelClient.createEnvVariable(envVar);
}
}
}
catch (error) {
console.error("Failed to update Vercel environment variables:", error);
throw new SetupAuthError("Failed to update Vercel environment variables. Please check your Vercel configuration.", { cause: error });
}
}
export async function getVercelClient() {
const client = new VercelApiClientImpl(process.env.VERCEL_ACCESS_TOKEN || "");
try {
await client.getTeamId();
}
catch (error) {
throw new SetupAuthError("Failed to validate Vercel authentication. Please check your VERCEL_ACCESS_TOKEN and VERCEL_TEAM_ID.", { cause: error });
}
return client;
}
export async function updateVercelEnvVarWithRetry(client, key, value, scope = undefined, maxRetries = 3) {
let attempts = 0;
while (attempts < maxRetries) {
try {
attempts++;
console.log(`Setting ${key} in Vercel (attempt ${attempts})...`);
const envVars = await client.getEnvVariables();
const existingVar = envVars.find((env) => env.key === key);
if (existingVar) {
if (existingVar.value === value) {
console.log(`✅ ${key} already has the correct value in Vercel`);
return true;
}
console.log(`Updating ${key} in Vercel...`);
await client.updateEnvVariable(existingVar.id, {
key,
value,
targets: undefined,
scope: scope,
});
console.log(`✅ Updated ${key} in Vercel`);
}
else {
await client.createEnvVariable({
key,
value,
targets: undefined,
scope: scope,
});
console.log(`✅ Added ${key} to Vercel`);
}
return true;
}
catch (error) {
console.error(`❌ Error setting ${key} in Vercel (attempt ${attempts}):`, error);
if (attempts >= maxRetries) {
return false;
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
return false;
}
export async function _getVercelTokenFromEnvironment() {
if (process.env.VERCEL_ACCESS_TOKEN) {
return process.env.VERCEL_ACCESS_TOKEN;
}
try {
const homeDir = process.env.HOME || process.env.USERPROFILE;
if (homeDir) {
const vercelAuthPath = path.join(homeDir, ".vercel", "auth.json");
if (await fileExists(vercelAuthPath)) {
const authJson = JSON.parse(fs.readFileSync(vercelAuthPath, "utf8"));
if (authJson.token) {
return authJson.token;
}
}
}
}
catch (error) {
console.warn("Error reading Vercel auth file:", error);
return null;
}
console.warn("No Vercel token found, please set VERCEL_ACCESS_TOKEN environment variable");
return null;
}