import { Input, Secret } from "jsr:@cliffy/prompt@1.0.0-rc.7"; import * as colors from "jsr:@std/fmt@0.225.2/colors"; import { generateDockerCompose, generateSpireDockerCompose, } from "../compose.ts"; import { AuthSetupConfig, COMPOSE_PATH, ENV_PATH, generateEnv, generateSpireEnv, SPIRE_COMPOSE_PATH, SPIRE_ENV_PATH, } from "../env.ts"; export async function promptAuthConfig( currentConfig: AuthSetupConfig, ): Promise> { console.log( colors.gray( "Please provide the following Auth Yes configuration details.\n", ), ); const reg = await Input.prompt({ message: "Enter the Primary Container Registry URL:", default: currentConfig.reg, }); const ghcrReg = await Input.prompt({ message: "Enter the GHCR Mirror Registry URL (for SPIRE):", default: currentConfig.ghcrReg || "ghcr.atyg.org", }); const domainName = await Input.prompt({ message: "Enter the Auth Domain Name:", hint: "E.g., auth.system.local", default: currentConfig.domainName, }); const appSecret = await Secret.prompt({ message: "Enter the App Secret for the IDP:", default: currentConfig.appSecret, minLength: 16, }); const pwdMessage = currentConfig.dbPassword ? "Enter the PostgreSQL database password: (Leave blank to keep existing password)" : "Enter the PostgreSQL database password:"; const pwdInput = await Secret.prompt({ message: pwdMessage, minLength: currentConfig.dbPassword ? 0 : 1, }); const dbPassword = pwdInput === "" && currentConfig.dbPassword !== "" ? currentConfig.dbPassword : pwdInput; return { reg, ghcrReg, domainName, appSecret, dbPassword }; } export async function promptSpireConfig( currentConfig: AuthSetupConfig, ): Promise> { const dbDataPath = await Input.prompt({ message: "Enter the Database Path on the Host:", default: currentConfig.dbDataPath, }); const spireDataPath = await Input.prompt({ message: "Enter the SPIRE Path on the Host:", default: currentConfig.spireDataPath, }); return { dbDataPath, spireDataPath }; } export async function promptConfirmation(): Promise { // Empty implementation as there was no explicit confirmation in cli.ts before // But we add it to cleanly delineate the flow as requested. } export async function generateAuthSetupFiles( config: AuthSetupConfig, ): Promise { const envContent = generateEnv(config); await Deno.writeTextFile(ENV_PATH, envContent); const spireEnvContent = generateSpireEnv(config); await Deno.writeTextFile(SPIRE_ENV_PATH, spireEnvContent); const composeContent = generateDockerCompose(); await Deno.writeTextFile(COMPOSE_PATH, composeContent); const spireComposeContent = generateSpireDockerCompose(); await Deno.writeTextFile(SPIRE_COMPOSE_PATH, spireComposeContent); console.log( colors.green( `\n✓ Successfully generated ${ENV_PATH}, ${SPIRE_ENV_PATH}, ${COMPOSE_PATH}, and ${SPIRE_COMPOSE_PATH}!`, ), ); console.log( colors.green("Setup complete. You may deploy your stacks by running:\n"), ); console.log( colors.cyan( "1. Deploy SPIRE Stack:\n" + " podman-compose --project-name spire --env-file infra/.env.spire -f infra/compose.spire.yml up -d\n\n" + "2. Deploy Auth-Yes Stack:\n" + " podman-compose --project-name auth-yes --env-file infra/stack.env -f infra/compose.yml up -d\n", ), ); } export async function handleAuthSetup( currentConfig: AuthSetupConfig, ): Promise { const authConfig = await promptAuthConfig(currentConfig); const spireConfig = await promptSpireConfig(currentConfig); const newConfig: AuthSetupConfig = { ...currentConfig, ...authConfig, ...spireConfig, }; await promptConfirmation(); await generateAuthSetupFiles(newConfig); return newConfig; }