* Handle the callback from Roo Code Cloud * * This method is called when the user is redirected back to the extension * after authenticating with Roo Code Cloud. * * @param code The authorization code from the callback * @param state The state parameter from the callback * @param organ
( code: string | null, state: string | null, organizationId?: string | null, providerModel?: string | null, )
| 300 | * @param providerModel The model ID selected during signup (optional) |
| 301 | */ |
| 302 | public async handleCallback( |
| 303 | code: string | null, |
| 304 | state: string | null, |
| 305 | organizationId?: string | null, |
| 306 | providerModel?: string | null, |
| 307 | ): Promise<void> { |
| 308 | if (!code || !state) { |
| 309 | const vscode = await importVscode() |
| 310 | |
| 311 | if (vscode) { |
| 312 | vscode.window.showInformationMessage("Invalid Roo Code Cloud sign in url") |
| 313 | } |
| 314 | |
| 315 | return |
| 316 | } |
| 317 | |
| 318 | try { |
| 319 | // Validate state parameter to prevent CSRF attacks. |
| 320 | const storedState = this.context.globalState.get(AUTH_STATE_KEY) |
| 321 | |
| 322 | if (state !== storedState) { |
| 323 | this.log("[auth] State mismatch in callback") |
| 324 | throw new Error("Invalid state parameter. Authentication request may have been tampered with.") |
| 325 | } |
| 326 | |
| 327 | const credentials = await this.clerkSignIn(code) |
| 328 | |
| 329 | // Set organizationId (null for personal accounts) |
| 330 | credentials.organizationId = organizationId || null |
| 331 | |
| 332 | await this.storeCredentials(credentials) |
| 333 | |
| 334 | // Store the provider model if provided, or flag that no model was selected |
| 335 | if (providerModel) { |
| 336 | await this.context.globalState.update("roo-provider-model", providerModel) |
| 337 | await this.context.globalState.update("roo-auth-skip-model", undefined) |
| 338 | this.log(`[auth] Stored provider model: ${providerModel}`) |
| 339 | } else { |
| 340 | // No model was selected during signup - flag this for the webview |
| 341 | await this.context.globalState.update("roo-auth-skip-model", true) |
| 342 | this.log(`[auth] No provider model selected during signup`) |
| 343 | } |
| 344 | |
| 345 | const vscode = await importVscode() |
| 346 | |
| 347 | if (vscode) { |
| 348 | vscode.window.showInformationMessage("Successfully authenticated with Roo Code Cloud") |
| 349 | } |
| 350 | |
| 351 | this.log("[auth] Successfully authenticated with Roo Code Cloud") |
| 352 | } catch (error) { |
| 353 | this.log(`[auth] Error handling Roo Code Cloud callback: ${error}`) |
| 354 | this.changeState("logged-out") |
| 355 | throw new Error(`Failed to handle Roo Code Cloud callback: ${error}`) |
| 356 | } |
| 357 | } |
| 358 | |
| 359 | /** |
nothing calls this directly
no test coverage detected