mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-01 19:48:08 +00:00
When moving form using Gmail Legacy auth to using OAuth, we need the email address that will be used to connect. This is because we need to store this email address in the cache and reuse when we get the callback to find the associated inbox. However there are cases where the imap login might be `support@company.com` and the email used to communicate will be `contact@company.com` (Probably an alias) In that case, we need to send the correct email address to Chatwoot when re-authenticating At the moment, we used the inbox email. This PR adds a check that defaults to to `imap_login` if that is available and imap is enabled This PR also fixes an unrelated problem where the email inbox creation flow was not working --- Tested it, it is working correctly 
89 lines
4.4 KiB
Ruby
89 lines
4.4 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe 'Google::CallbacksController', type: :request do
|
|
let(:account) { create(:account) }
|
|
let(:code) { SecureRandom.hex(10) }
|
|
let(:email) { Faker::Internet.email }
|
|
let(:cache_key) { "google::#{email.downcase}" }
|
|
|
|
before do
|
|
Redis::Alfred.set(cache_key, account.id)
|
|
end
|
|
|
|
describe 'GET /google/callback' do
|
|
let(:response_body_success) do
|
|
{ id_token: JWT.encode({ email: email, name: 'test' }, false), access_token: SecureRandom.hex(10), token_type: 'Bearer',
|
|
refresh_token: SecureRandom.hex(10) }
|
|
end
|
|
|
|
let(:response_body_success_without_name) do
|
|
{ id_token: JWT.encode({ email: email }, false), access_token: SecureRandom.hex(10), token_type: 'Bearer',
|
|
refresh_token: SecureRandom.hex(10) }
|
|
end
|
|
|
|
it 'creates inboxes if authentication is successful' do
|
|
stub_request(:post, 'https://accounts.google.com/o/oauth2/token')
|
|
.with(body: { 'code' => code, 'grant_type' => 'authorization_code',
|
|
'redirect_uri' => "#{ENV.fetch('FRONTEND_URL', 'http://localhost:3000')}/google/callback" })
|
|
.to_return(status: 200, body: response_body_success.to_json, headers: { 'Content-Type' => 'application/json' })
|
|
|
|
get google_callback_url, params: { code: code }
|
|
|
|
expect(response).to redirect_to app_email_inbox_agents_url(account_id: account.id, inbox_id: account.inboxes.last.id)
|
|
expect(account.inboxes.count).to be 1
|
|
inbox = account.inboxes.last
|
|
expect(inbox.name).to eq 'test'
|
|
expect(inbox.channel.reload.provider_config.keys).to include('access_token', 'refresh_token', 'expires_on')
|
|
expect(inbox.channel.reload.provider_config['access_token']).to eq response_body_success[:access_token]
|
|
expect(inbox.channel.imap_address).to eq 'imap.gmail.com'
|
|
expect(Redis::Alfred.get(cache_key)).to be_nil
|
|
end
|
|
|
|
it 'updates inbox channel config if inbox exists with imap_login and authentication is successful' do
|
|
channel_email = create(:channel_email, account: account, imap_login: email)
|
|
inbox = channel_email.inbox
|
|
expect(inbox.channel.provider_config).to eq({})
|
|
|
|
stub_request(:post, 'https://accounts.google.com/o/oauth2/token')
|
|
.with(body: { 'code' => code, 'grant_type' => 'authorization_code',
|
|
'redirect_uri' => "#{ENV.fetch('FRONTEND_URL', 'http://localhost:3000')}/google/callback" })
|
|
.to_return(status: 200, body: response_body_success.to_json, headers: { 'Content-Type' => 'application/json' })
|
|
|
|
get google_callback_url, params: { code: code }
|
|
|
|
expect(response).to redirect_to app_email_inbox_settings_url(account_id: account.id, inbox_id: inbox.id)
|
|
expect(account.inboxes.count).to be 1
|
|
expect(inbox.channel.reload.provider_config.keys).to include('access_token', 'refresh_token', 'expires_on')
|
|
expect(inbox.channel.reload.provider_config['access_token']).to eq response_body_success[:access_token]
|
|
expect(inbox.channel.imap_address).to eq 'imap.gmail.com'
|
|
expect(Redis::Alfred.get(cache_key)).to be_nil
|
|
end
|
|
|
|
it 'creates inboxes with fallback_name when account name is not present in id_token' do
|
|
stub_request(:post, 'https://accounts.google.com/o/oauth2/token')
|
|
.with(body: { 'code' => code, 'grant_type' => 'authorization_code',
|
|
'redirect_uri' => "#{ENV.fetch('FRONTEND_URL', 'http://localhost:3000')}/google/callback" })
|
|
.to_return(status: 200, body: response_body_success_without_name.to_json, headers: { 'Content-Type' => 'application/json' })
|
|
|
|
get google_callback_url, params: { code: code }
|
|
|
|
expect(response).to redirect_to app_email_inbox_agents_url(account_id: account.id, inbox_id: account.inboxes.last.id)
|
|
expect(account.inboxes.count).to be 1
|
|
inbox = account.inboxes.last
|
|
expect(inbox.name).to eq email.split('@').first.parameterize.titleize
|
|
end
|
|
|
|
it 'redirects to google app in case of error' do
|
|
stub_request(:post, 'https://accounts.google.com/o/oauth2/token')
|
|
.with(body: { 'code' => code, 'grant_type' => 'authorization_code',
|
|
'redirect_uri' => "#{ENV.fetch('FRONTEND_URL', 'http://localhost:3000')}/google/callback" })
|
|
.to_return(status: 401)
|
|
|
|
get google_callback_url, params: { code: code }
|
|
|
|
expect(response).to redirect_to '/'
|
|
expect(Redis::Alfred.get(cache_key).to_i).to eq account.id
|
|
end
|
|
end
|
|
end
|