(token: string)
| 161 | } |
| 162 | |
| 163 | export async function handleAuthCallback(token: string): Promise<boolean> { |
| 164 | if (!token || !token.startsWith("zoo_ext_")) { |
| 165 | vscode.window.showErrorMessage(t("common:zooAuth.errors.invalid_token_received")) |
| 166 | return false |
| 167 | } |
| 168 | |
| 169 | // Verify token with backend before storing |
| 170 | const baseUrl = getZooCodeBaseUrl() |
| 171 | try { |
| 172 | const response = await fetch(`${baseUrl}/api/extension/auth/verify`, { |
| 173 | headers: { Authorization: `Bearer ${token}` }, |
| 174 | signal: AbortSignal.timeout(10_000), |
| 175 | }) |
| 176 | if (!response.ok) { |
| 177 | // Treat 5xx as a transient backend issue (e.g. DB unreachable) so the |
| 178 | // user can retry sign-in instead of being told the token is bad. |
| 179 | if (response.status >= 500) { |
| 180 | vscode.window.showErrorMessage(t("common:zooAuth.errors.could_not_verify_token")) |
| 181 | } else { |
| 182 | vscode.window.showErrorMessage(t("common:zooAuth.errors.token_verification_failed")) |
| 183 | } |
| 184 | return false |
| 185 | } |
| 186 | const data = (await response.json()) as { valid?: boolean } |
| 187 | if (!data.valid) { |
| 188 | vscode.window.showErrorMessage(t("common:zooAuth.errors.invalid_token")) |
| 189 | return false |
| 190 | } |
| 191 | } catch { |
| 192 | vscode.window.showErrorMessage(t("common:zooAuth.errors.could_not_verify_token")) |
| 193 | return false |
| 194 | } |
| 195 | |
| 196 | await setZooCodeToken(token) |
| 197 | |
| 198 | vscode.window.showInformationMessage(t("common:zooAuth.info.connected")) |
| 199 | return true |
| 200 | } |
| 201 | |
| 202 | /** |
| 203 | * Verify the stored token against the backend. |
no test coverage detected