UNPKG

@dataroadinc/setup-auth

Version:

CLI tool and programmatic API for automated OAuth setup across cloud platforms

158 lines (157 loc) 6.35 kB
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; }