UNPKG

vanta-auditor-tui

Version:

Beautiful terminal UI for exporting Vanta audit evidence with ZIP support and progress tracking

138 lines 7.89 kB
import React, { useEffect, useRef, useState } from "react"; import { Box, Text } from "ink"; import { SelectInput } from "../lib/inkModules.js"; import { theme } from "../theme.js"; import { BorderedInput } from "./ui/BorderedInput.js"; import { FormSection } from "./ui/FormSection.js"; import { StepIndicator } from "./ui/StepIndicator.js"; export function CredentialsForm({ onSubmit }) { const [mode, setMode] = useState("oauth"); const [token, setToken] = useState(""); const [clientId, setClientId] = useState(""); const [clientSecret, setClientSecret] = useState(""); const [scope, setScope] = useState("auditor-api.audit:read auditor-api.auditor:read"); const [region, setRegion] = useState("us"); const [serverURL, setServerURL] = useState(""); const [debug, setDebug] = useState(process.argv.includes("--verbose")); const [stage, setStage] = useState("mode"); useEffect(() => { // focus order managed by stage }, [stage]); // Submit once stage transitions to done. This must be declared before any early returns // so that hook order remains stable across renders. const submittedRef = useRef(false); useEffect(() => { if (stage === "done" && !submittedRef.current) { submittedRef.current = true; onSubmit({ token: mode === "token" ? token : undefined, clientId: mode === "oauth" ? clientId : undefined, clientSecret: mode === "oauth" ? clientSecret : undefined, scope: mode === "oauth" ? scope : undefined, region, serverURL: serverURL || undefined, debug }); } }, [stage, mode, token, clientId, clientSecret, scope, region, serverURL, debug]); // Auto-advance if env vars present for faster debugging useEffect(() => { if (stage !== "mode") return; if (token) { setMode("token"); setStage("region"); } else if (clientId && clientSecret) { setMode("oauth"); setStage("region"); } }, [stage]); if (stage === "mode") { const items = [ { label: "OAuth client credentials", value: "oauth" }, { label: "Bearer token", value: "token" } ]; return (React.createElement(FormSection, { title: "\uD83E\uDD99 Welcome to Vanta Auditor TUI!", subtitle: "Let's get your audit evidence exported", borderStyle: "double" }, React.createElement(StepIndicator, { steps: [ { label: "Auth Method", status: "active" }, { label: "Credentials", status: "pending" }, { label: "Region", status: "pending" } ] }), React.createElement(Box, { flexDirection: "column", marginTop: 1 }, React.createElement(Text, { color: theme.colors.primaryLight }, "Choose authentication method:"), React.createElement(Box, { borderStyle: "single", borderColor: theme.colors.primary, paddingX: 1, paddingY: 1, marginTop: 1 }, React.createElement(SelectInput, { items: items, onSelect: (i) => { setMode(i.value); setStage(i.value === "oauth" ? "oauthClientId" : "token"); } }))))); } if (stage === "token") { return (React.createElement(FormSection, { title: "\uD83D\uDD10 Bearer Token Authentication", subtitle: "Enter your Vanta API bearer token" }, React.createElement(StepIndicator, { steps: [ { label: "Auth Method", status: "completed" }, { label: "API Token", status: "active" }, { label: "Region", status: "pending" } ] }), React.createElement(BorderedInput, { label: "API Token:", value: token, onChange: setToken, mask: "*", placeholder: "vat_...", onSubmit: () => setStage("region"), width: 50 }))); } if (stage === "oauthClientId") { return (React.createElement(FormSection, { title: "\uD83D\uDD10 OAuth Client Credentials", subtitle: "Step 1 of 3: Enter your Client ID" }, React.createElement(StepIndicator, { steps: [ { label: "Auth Method", status: "completed" }, { label: "Client ID", status: "active" }, { label: "Client Secret", status: "pending" }, { label: "Scopes", status: "pending" }, { label: "Region", status: "pending" } ] }), React.createElement(BorderedInput, { label: "Client ID:", value: clientId, onChange: setClientId, onSubmit: () => setStage("oauthClientSecret"), placeholder: "Enter your OAuth client ID", width: 50 }))); } if (stage === "oauthClientSecret") { return (React.createElement(FormSection, { title: "\uD83D\uDD10 OAuth Client Credentials", subtitle: "Step 2 of 3: Enter your Client Secret" }, React.createElement(StepIndicator, { steps: [ { label: "Auth Method", status: "completed" }, { label: "Client ID", status: "completed" }, { label: "Client Secret", status: "active" }, { label: "Scopes", status: "pending" }, { label: "Region", status: "pending" } ] }), React.createElement(BorderedInput, { label: "Client Secret:", value: clientSecret, onChange: setClientSecret, mask: "*", onSubmit: () => setStage("oauthScope"), placeholder: "Enter your OAuth client secret", width: 50 }))); } if (stage === "oauthScope") { return (React.createElement(FormSection, { title: "\uD83D\uDD10 OAuth Client Credentials", subtitle: "Step 3 of 3: Specify API scopes" }, React.createElement(StepIndicator, { steps: [ { label: "Auth Method", status: "completed" }, { label: "Client ID", status: "completed" }, { label: "Client Secret", status: "completed" }, { label: "Scopes", status: "active" }, { label: "Region", status: "pending" } ] }), React.createElement(BorderedInput, { label: "Scopes (space-separated):", value: scope, onChange: setScope, onSubmit: () => setStage("region"), placeholder: "auditor-api.audit:read auditor-api.auditor:read", width: 60 }))); } if (stage === "region") { const items = [ { label: "US", value: "us" }, { label: "EU", value: "eu" }, { label: "AUS", value: "aus" }, { label: "Custom URL", value: "custom" } ]; return (React.createElement(FormSection, { title: "\uD83C\uDF0E Select Your Vanta Region", subtitle: "Choose the region where your Vanta instance is hosted" }, React.createElement(Box, { borderStyle: "single", borderColor: theme.colors.primary, paddingX: 1, paddingY: 1 }, React.createElement(SelectInput, { items: items, onSelect: (i) => { setRegion(i.value); if (i.value === "custom") setStage("custom"); else setStage("done"); } })))); } if (stage === "custom") { return (React.createElement(FormSection, { title: "\uD83C\uDF10 Custom Server URL", subtitle: "Enter the full URL for your Vanta API endpoint" }, React.createElement(BorderedInput, { label: "Server URL:", value: serverURL, onChange: setServerURL, placeholder: "https://api.aus.vanta.com/v1", onSubmit: () => setStage("done"), width: 60 }))); } if (stage === "done") return null; return null; } export default CredentialsForm; //# sourceMappingURL=CredentialsForm.js.map