Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56d9cc7e0b | ||
|
|
092f9ef500 |
@@ -6,8 +6,7 @@ class Api::V1::Accounts::Microsoft::AuthorizationsController < Api::V1::Accounts
|
|||||||
{
|
{
|
||||||
redirect_uri: "#{base_url}/microsoft/callback",
|
redirect_uri: "#{base_url}/microsoft/callback",
|
||||||
scope: scope,
|
scope: scope,
|
||||||
state: state,
|
state: state
|
||||||
prompt: 'consent'
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if redirect_url
|
if redirect_url
|
||||||
|
|||||||
@@ -14,4 +14,11 @@ class Microsoft::CallbacksController < OauthCallbackController
|
|||||||
def imap_address
|
def imap_address
|
||||||
'outlook.office365.com'
|
'outlook.office365.com'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Exchange Online's SMTP AUTH (XOAUTH2) rejects proxy addresses in the SASL `user=` field;
|
||||||
|
# it must match the token's UPN. `preferred_username` is the documented v2.0 claim;
|
||||||
|
# `upn` is the v1.0 fallback.
|
||||||
|
def imap_login_identity
|
||||||
|
users_data['preferred_username'] || users_data['upn'] || super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class OauthCallbackController < ApplicationController
|
|||||||
|
|
||||||
def update_channel(channel_email)
|
def update_channel(channel_email)
|
||||||
channel_email.update!({
|
channel_email.update!({
|
||||||
imap_login: users_data['email'], imap_address: imap_address,
|
imap_login: imap_login_identity, imap_address: imap_address,
|
||||||
imap_port: '993', imap_enabled: true,
|
imap_port: '993', imap_enabled: true,
|
||||||
provider: provider_name,
|
provider: provider_name,
|
||||||
provider_config: {
|
provider_config: {
|
||||||
@@ -55,6 +55,13 @@ class OauthCallbackController < ApplicationController
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Identity used as the IMAP/SMTP login (SASL XOAUTH2 `user=` field). Defaults to the
|
||||||
|
# id_token's email claim; providers override when their server requires a different
|
||||||
|
# claim (e.g. Microsoft SMTP requires UPN).
|
||||||
|
def imap_login_identity
|
||||||
|
users_data['email']
|
||||||
|
end
|
||||||
|
|
||||||
def provider_name
|
def provider_name
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ RSpec.describe 'Microsoft Authorization API', type: :request do
|
|||||||
]
|
]
|
||||||
expect(params['scope']).to eq(expected_scope)
|
expect(params['scope']).to eq(expected_scope)
|
||||||
expect(params['redirect_uri']).to eq(["#{ENV.fetch('FRONTEND_URL', 'http://localhost:3000')}/microsoft/callback"])
|
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
|
# Validate state parameter exists and can be decoded back to the account
|
||||||
expect(params['state']).to be_present
|
expect(params['state']).to be_present
|
||||||
|
|||||||
@@ -34,6 +34,25 @@ RSpec.describe 'Microsoft::CallbacksController', type: :request do
|
|||||||
expect(inbox.channel.imap_address).to eq 'outlook.office365.com'
|
expect(inbox.channel.imap_address).to eq 'outlook.office365.com'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'sets imap_login from preferred_username when the id_token carries a UPN that differs from email' do
|
||||||
|
upn = 'livetestaccount@capeunionmart.co.za'
|
||||||
|
mailbox = 'LiveTestAccount@cumi.co.za'
|
||||||
|
response_body = {
|
||||||
|
id_token: JWT.encode({ email: mailbox, preferred_username: upn, name: 'test' }, false),
|
||||||
|
access_token: SecureRandom.hex(10), token_type: 'Bearer', refresh_token: SecureRandom.hex(10)
|
||||||
|
}
|
||||||
|
stub_request(:post, 'https://login.microsoftonline.com/common/oauth2/v2.0/token')
|
||||||
|
.with(body: { 'code' => code, 'grant_type' => 'authorization_code',
|
||||||
|
'redirect_uri' => "#{ENV.fetch('FRONTEND_URL', 'http://localhost:3000')}/microsoft/callback" })
|
||||||
|
.to_return(status: 200, body: response_body.to_json, headers: { 'Content-Type' => 'application/json' })
|
||||||
|
|
||||||
|
get microsoft_callback_url, params: { code: code, state: state }
|
||||||
|
|
||||||
|
channel = account.inboxes.last.channel
|
||||||
|
expect(channel.imap_login).to eq upn
|
||||||
|
expect(channel.email).to eq mailbox
|
||||||
|
end
|
||||||
|
|
||||||
it 'creates updates inbox channel config if inbox exists and authentication is successful' do
|
it 'creates updates inbox channel config if inbox exists and authentication is successful' do
|
||||||
inbox = create(:channel_email, account: account, email: email)&.inbox
|
inbox = create(:channel_email, account: account, email: email)&.inbox
|
||||||
expect(inbox.channel.provider_config).to eq({})
|
expect(inbox.channel.provider_config).to eq({})
|
||||||
|
|||||||
Reference in New Issue
Block a user