@dataroadinc/setup-auth
Version:
CLI tool and programmatic API for automated OAuth setup across cloud platforms
85 lines (84 loc) • 4.77 kB
JavaScript
import { GcpCloudCliClient } from "../../../providers/gcp/cloud-cli-client.js";
import { GcpIdentityFactory } from "../../../providers/gcp/creds/identity.js";
import { GcpProjectOAuthSetup } from "../../../providers/gcp/oauth/index.js";
import { enforceUserDomainOrFail, GCP_OAUTH_BRAND_RESOURCE_NAME, getAdcEmailOrNull, printGcloudAndAdcAccounts, } from "../../../utils/env-handler.js";
import { SetupAuthError } from "../../../utils/error.js";
import { checkOptions } from "./options.js";
export async function gcpSetupOAuth(options) {
console.log("Setting up GCP OAuth...");
await printGcloudAndAdcAccounts();
const expectedDomain = process.env.EKG_ORG_PRIMARY_DOMAIN;
if (!expectedDomain) {
throw new SetupAuthError("Missing required environment variable: EKG_ORG_PRIMARY_DOMAIN. This tool enforces a fail-fast approach and requires this variable to be set in your .env.local (e.g., EKG_ORG_PRIMARY_DOMAIN=your-domain.com).");
}
let adcEmail = await getAdcEmailOrNull();
if (!adcEmail) {
console.log("ADC not configured. Attempting automatic authentication...");
const cli = new GcpCloudCliClient();
try {
await cli.autoApplicationDefaultAuthenticate();
adcEmail = await getAdcEmailOrNull();
}
catch (error) {
throw new SetupAuthError("Failed to automatically configure Application Default Credentials.\n" +
"This may be because:\n" +
"1. You're running in a non-interactive environment (CI/CD)\n" +
"2. gcloud is not installed or not in PATH\n" +
"3. You need to manually run: gcloud auth application-default login\n", { cause: error });
}
}
if (!adcEmail) {
throw new SetupAuthError("Could not determine Application Default Credentials (ADC) email after authentication attempt.");
}
const adcDomain = adcEmail.split("@")[1] || "";
if (adcDomain.toLowerCase() !== expectedDomain.toLowerCase()) {
throw new SetupAuthError(`Application Default Credentials (ADC) are for '${adcEmail}', which does not match the required organization domain (${expectedDomain}).\n` +
`Please run 'gcloud auth application-default login' and select your <user>@${expectedDomain} account.`);
}
try {
await checkOptions(options);
const platform = options.platform;
const projectId = options.gcpOauthProjectId;
const organizationId = options.gcpOauthOrganizationId;
const vercelProjectName = options.vercelProjectName;
const identity = GcpIdentityFactory.createAdcIdentity();
const userEmail = await identity.getCurrentUserEmail();
enforceUserDomainOrFail(userEmail);
const brandResourceName = process.env[GCP_OAUTH_BRAND_RESOURCE_NAME];
if (!brandResourceName) {
throw new SetupAuthError(`OAuth Brand resource name not found in environment variable ${GCP_OAUTH_BRAND_RESOURCE_NAME}. ` +
`Please run 'gcp-setup-service-account' first.`);
}
console.log(`Using OAuth Brand Resource Name: ${brandResourceName}`);
console.log(`Platform: ${platform}`);
console.log(`Using explicitly provided GCP project ID: ${projectId}`);
console.log(`Using explicitly provided GCP organization ID: ${organizationId}`);
if (vercelProjectName)
console.log(`Using specified Vercel project name: ${vercelProjectName}`);
const setup = new GcpProjectOAuthSetup(identity, organizationId, projectId, projectId, brandResourceName, platform, undefined, vercelProjectName);
await setup.setupForProject();
console.log("✅ GCP OAuth setup completed successfully.");
}
catch (error) {
if (error instanceof SetupAuthError) {
console.error("\n❌ FATAL: " + error.message);
if (error.isReauthenticationError && error.isReauthenticationError()) {
console.error("Hint: Your credentials are expired or invalid. Run `gcloud auth login` or `gcloud auth application-default login` to re-authenticate.");
console.error("See: https://support.google.com/a/answer/9368756");
}
else {
let hint = "Check your GCP permissions and environment variables.";
if (error.originalError &&
typeof error.originalError === "object" &&
"message" in error.originalError) {
hint = error.originalError.message || hint;
}
console.error("Hint: " + hint);
}
}
else {
console.error("\n❌ Unknown fatal error:", error);
}
process.exit(1);
}
}