()
| 100 | } |
| 101 | |
| 102 | async function authenticateAndGenerateKey(): Promise<string | null> { |
| 103 | const accessToken = (await getValidAccessToken()) ?? (await performLogin()); |
| 104 | |
| 105 | if (!accessToken) return null; |
| 106 | |
| 107 | const spinner = ora("Configuring authentication...").start(); |
| 108 | |
| 109 | try { |
| 110 | const response = await fetch(`${getBaseUrl()}/api/dashboard/api-keys`, { |
| 111 | method: "POST", |
| 112 | headers: { |
| 113 | Authorization: `Bearer ${accessToken}`, |
| 114 | "Content-Type": "application/json", |
| 115 | }, |
| 116 | body: JSON.stringify({ name: `ctx7-cli-${randomBytes(3).toString("hex")}` }), |
| 117 | }); |
| 118 | |
| 119 | if (!response.ok) { |
| 120 | const err = (await response.json().catch(() => ({}))) as { message?: string; error?: string }; |
| 121 | spinner.fail("Authentication failed"); |
| 122 | log.error(err.message || err.error || `HTTP ${response.status}`); |
| 123 | return null; |
| 124 | } |
| 125 | |
| 126 | const result = (await response.json()) as { data: { apiKey: string } }; |
| 127 | spinner.succeed("Authenticated"); |
| 128 | return result.data.apiKey; |
| 129 | } catch (err) { |
| 130 | spinner.fail("Authentication failed"); |
| 131 | log.error(err instanceof Error ? err.message : String(err)); |
| 132 | return null; |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | async function resolveAuth(options: SetupOptions): Promise<AuthOptions | null> { |
| 137 | if (options.apiKey) return { mode: "api-key", apiKey: options.apiKey }; |
no test coverage detected