({ email, password, loginProxy, autoAdd })
| 207 | } |
| 208 | |
| 209 | async function processWindsurfLogin({ email, password, loginProxy, autoAdd }) { |
| 210 | if (!email || !password) { |
| 211 | const err = new Error('ERR_EMAIL_PASSWORD_REQUIRED'); |
| 212 | err.statusCode = 400; |
| 213 | err.code = 'ERR_EMAIL_PASSWORD_REQUIRED'; |
| 214 | throw err; |
| 215 | } |
| 216 | |
| 217 | // Use provided proxy, or global proxy |
| 218 | const proxy = loginProxy?.host ? loginProxy : getProxyConfig().global; |
| 219 | const result = await windsurfLogin(email, password, proxy); |
| 220 | |
| 221 | // Auto-add to account pool if requested |
| 222 | let account = null; |
| 223 | if (autoAdd !== false) { |
| 224 | account = addAccountByKey(result.apiKey, result.name || email); |
| 225 | // Persist refresh token via the setter so it survives restart and |
| 226 | // the background Firebase-renewal loop can find it. |
| 227 | if (result.refreshToken) { |
| 228 | setAccountTokens(account.id, { refreshToken: result.refreshToken, idToken: result.idToken }); |
| 229 | } |
| 230 | // Persist the per-account proxy we used for login so chat requests |
| 231 | // also egress through the same IP, then warm up a matching LS. |
| 232 | if (loginProxy?.host) setAccountProxy(account.id, loginProxy); |
| 233 | scheduleAccountWarmup(account.id); |
| 234 | } |
| 235 | |
| 236 | return { |
| 237 | success: true, |
| 238 | // When autoAdd:false, the caller is doing a one-time login to retrieve the |
| 239 | // upstream key without storing it (e.g. external tooling that wants the |
| 240 | // raw key) — they need the full apiKey. When autoAdd is true, the key is |
| 241 | // already persisted in the pool and the response only echoes a masked |
| 242 | // form (the dashboard never needs the raw key in the listing path; the |
| 243 | // explicit reveal-key endpoint covers the rare per-account export case). |
| 244 | ...(autoAdd === false |
| 245 | ? { apiKey: result.apiKey } |
| 246 | : { apiKey_masked: maskApiKey(result.apiKey) }), |
| 247 | name: result.name, |
| 248 | email: result.email, |
| 249 | apiServerUrl: result.apiServerUrl, |
| 250 | account: account ? { id: account.id, email: account.email, status: account.status } : null, |
| 251 | }; |
| 252 | } |
| 253 | |
| 254 | /** |
| 255 | * Handle all /dashboard/api/* requests. |
no test coverage detected