From b791d75b30dc6478faed54b7f65939dc0ee85ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Fitzner?= Date: Wed, 3 Jun 2026 03:35:25 -0300 Subject: [PATCH] fix(microsoft): prevent OAuth admin consent loop (#13962) Fixes #9775 ## Description This fixes a repeated admin consent loop in the Microsoft OAuth flow when connecting a Microsoft email inbox. Chatwoot was always sending `prompt=consent` in the Microsoft authorization URL. In the current code path, this parameter is only used when building the authorization URL and is not required by the callback, token exchange, token persistence, or refresh flow. By removing the forced consent prompt, the OAuth flow can proceed normally without repeatedly sending users back through the admin consent screen. ## What changed - removed `prompt: 'consent'` from the Microsoft authorization URL - added a regression assertion to ensure `prompt` is not included in the generated URL ## Why this is safe - `redirect_uri`, `scope`, and `state` remain unchanged - callback and token exchange flow remain unchanged - refresh token flow remains unchanged - no other part of the current Microsoft inbox flow depends on forcing a consent screen ## Testing - updated controller spec to assert that the generated authorization URL does not include `prompt` --- .../api/v1/accounts/microsoft/authorizations_controller.rb | 3 +-- .../api/v1/accounts/microsoft/authorization_controller_spec.rb | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/accounts/microsoft/authorizations_controller.rb b/app/controllers/api/v1/accounts/microsoft/authorizations_controller.rb index a300b5f593e..c65a3031d63 100644 --- a/app/controllers/api/v1/accounts/microsoft/authorizations_controller.rb +++ b/app/controllers/api/v1/accounts/microsoft/authorizations_controller.rb @@ -6,8 +6,7 @@ class Api::V1::Accounts::Microsoft::AuthorizationsController < Api::V1::Accounts { redirect_uri: "#{base_url}/microsoft/callback", scope: scope, - state: state, - prompt: 'consent' + state: state } ) if redirect_url diff --git a/spec/controllers/api/v1/accounts/microsoft/authorization_controller_spec.rb b/spec/controllers/api/v1/accounts/microsoft/authorization_controller_spec.rb index 60b05b36c01..18a26a393c0 100644 --- a/spec/controllers/api/v1/accounts/microsoft/authorization_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/microsoft/authorization_controller_spec.rb @@ -43,6 +43,7 @@ RSpec.describe 'Microsoft Authorization API', type: :request do ] expect(params['scope']).to eq(expected_scope) expect(params['redirect_uri']).to eq(["#{ENV.fetch('FRONTEND_URL', 'http://localhost:3000')}/microsoft/callback"]) + expect(url).not_to match(/(?:\?|&)prompt=/) # Validate state parameter exists and can be decoded back to the account expect(params['state']).to be_present