From c3c5e91e8182fcb0cd831b75b8ec839ba690756c Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Tue, 18 Nov 2014 12:51:35 +0100 Subject: [PATCH] Improved mailbox setup/auto detection. --- .../app/controllers/getting_started.js.coffee | 112 ++++++++++-------- .../app/views/getting_started/email.jst.eco | 1 + app/controllers/getting_started_controller.rb | 98 ++++++++------- app/models/channel/imap.rb | 31 +++-- app/models/channel/pop3.rb | 2 +- 5 files changed, 142 insertions(+), 102 deletions(-) diff --git a/app/assets/javascripts/app/controllers/getting_started.js.coffee b/app/assets/javascripts/app/controllers/getting_started.js.coffee index bd6749ffb..54ebafca1 100644 --- a/app/assets/javascripts/app/controllers/getting_started.js.coffee +++ b/app/assets/javascripts/app/controllers/getting_started.js.coffee @@ -348,10 +348,10 @@ App.Config.set( 'getting_started/channel', Channel, 'Routes' ) class ChannelEmail extends App.ControllerContent className: 'getstarted fit' events: - 'submit .js-intro': 'emailProbe' - 'submit .js-inbound': 'storeInbound' - 'change .js-outbound [name=adapter]': 'toggleAdapter' - 'submit .js-outbound': 'storeOutbound' + 'submit .js-intro': 'probeBasedOnIntro' + 'submit .js-inbound': 'probeInbound' + 'change .js-outbound [name=adapter]': 'toggleOutboundAdapter' + 'submit .js-outbound': 'probleOutbound' constructor: -> super @@ -410,7 +410,7 @@ class ChannelEmail extends App.ControllerContent el: @$('.base-outbound-type'), model: { configure_attributes: configureAttributesOutbound, className: '' }, ) - @toggleAdapter() + @toggleOutboundAdapter() # inbound configureAttributesInbound = [ @@ -425,7 +425,15 @@ class ChannelEmail extends App.ControllerContent model: { configure_attributes: configureAttributesInbound, className: '' }, ) - toggleAdapter: (channel_used = {}) => + toggleOutboundAdapter: => + + # fill user / password based on intro info + channel_used = { options: {} } + if @account['meta'] + channel_used['options']['user'] = @account['meta']['email'] + channel_used['options']['password'] = @account['meta']['password'] + + # show used backend adapter = @$('.js-outbound [name=adapter]').val() if adapter is 'smtp' configureAttributesOutbound = [ @@ -442,7 +450,7 @@ class ChannelEmail extends App.ControllerContent else @el.find('.base-outbound-settings').html('') - emailProbe: (e) => + probeBasedOnIntro: (e) => e.preventDefault() params = @formParam(e.target) @@ -467,17 +475,47 @@ class ChannelEmail extends App.ControllerContent @verify(@account) else @showSlide('js-inbound') + @showAlert('js-inbound', 'Unable to detect your server settings. Manual configuration needed.' ) + @$('.js-inbound [name="options::user"]').val( @account['meta']['email'] ) + @$('.js-inbound [name="options::password"]').val( @account['meta']['password'] ) + @enable(e) fail: => @enable(e) @showSlide('js-intro') ) - showSlide: (name) => - @$('.setup.wizard').addClass('hide') - @$(".setup.wizard.#{name}").removeClass('hide') + probeInbound: (e) => + e.preventDefault() - storeOutbound: (e) => + # get params + params = @formParam(e.target) + @disable(e) + + @ajax( + id: 'email_inbound' + type: 'POST' + url: @apiPath + '/getting_started/email_inbound' + data: JSON.stringify( params ) + processData: true + success: (data, status, xhr) => + if data.result is 'ok' + + # remember account settings + @account.inbound = params + + @showSlide('js-outbound') + @$('.js-outbound [name="options::user"]').val( @account['meta']['email'] ) + @$('.js-outbound [name="options::password"]').val( @account['meta']['password'] ) + + else + @showAlert('js-inbound', data.message_human || data.message ) + @enable(e) + fail: => + @enable(e) + ) + + probleOutbound: (e) => e.preventDefault() # get params @@ -485,8 +523,6 @@ class ChannelEmail extends App.ControllerContent params['email'] = @account['meta']['email'] @disable(e) - @hideAlert('js-outbound') - @ajax( id: 'email_outbound' type: 'POST' @@ -507,39 +543,9 @@ class ChannelEmail extends App.ControllerContent @enable(e) ) - storeInbound: (e) => - e.preventDefault() - - # get params - params = @formParam(e.target) - @disable(e) - - @hideAlert('js-inbound') - - @ajax( - id: 'email_inbound' - type: 'POST' - url: @apiPath + '/getting_started/email_inbound' - data: JSON.stringify( params ) - processData: true - success: (data, status, xhr) => - if data.result is 'ok' - @showSlide('js-outbound') - - # remember account settings - @account.inbound = params - else - @showAlert('js-inbound', data.message_human || data.message ) - @enable(e) - fail: => - @enable(e) - ) - verify: (account, count = 0) => @showSlide('js-verify') - @hideAlert('js-verify') - @ajax( id: 'email_verify' type: 'POST' @@ -550,19 +556,31 @@ class ChannelEmail extends App.ControllerContent if data.result is 'ok' @navigate 'getting_started/agents' else - if count is 1 + if count is 2 @showAlert('js-verify', data.message_human || data.message ) @delay( - => @showSlide('js-inbound') + => + @showSlide('js-intro') + @showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.' ) + 2300 ) else + console.log('r', data, @account) + if data.subject && @account + @account.subject = data.subject @verify( @account, count + 1 ) - @enable(e) + #@enable(e) fail: => - @enable(e) + #@enable(e) ) + + showSlide: (name) => + @hideAlert(name) + @$('.setup.wizard').addClass('hide') + @$(".setup.wizard.#{name}").removeClass('hide') + showAlert: (screen, message) => @$(".#{screen}").find('.alert').removeClass('hide').text( App.i18n.translateInline( message ) ) diff --git a/app/assets/javascripts/app/views/getting_started/email.jst.eco b/app/assets/javascripts/app/views/getting_started/email.jst.eco index 9a6edb1af..bc57dabd4 100644 --- a/app/assets/javascripts/app/views/getting_started/email.jst.eco +++ b/app/assets/javascripts/app/views/getting_started/email.jst.eco @@ -5,6 +5,7 @@

<%- @T('Email Account') %>

+
diff --git a/app/controllers/getting_started_controller.rb b/app/controllers/getting_started_controller.rb index 4c475d8a6..b23b7691b 100644 --- a/app/controllers/getting_started_controller.rb +++ b/app/controllers/getting_started_controller.rb @@ -174,7 +174,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} :adapter => 'smtp', :options => { :host => 'smtp.gmail.com', - :port => '465', + :port => '25', :ssl => true, :user => params[:email], :password => params[:password], @@ -212,7 +212,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} render :json => { :result => 'ok', - :account => settings, + :setting => settings, } return end @@ -540,9 +540,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} # connection test result = email_probe_outbound( params, params[:email] ) - render :json => { - :result => result - } + render :json => result end def email_inbound @@ -571,18 +569,15 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} return if deny_if_not_role('Admin') # send verify email to inbox - subject = '#' + rand(99999999999).to_s - Channel::EmailSend.new.send( - { - :from => params[:meta][:email], - :to => params[:meta][:email], - :subject => "Zammad Getting started Test Email #{subject}", - :body => '.', - 'x-zammad-ignore' => 'true', - } - ) - (1..5).each {|loop| - sleep 10 + if !params[:subject] + subject = '#' + rand(99999999999).to_s + else + subject = params[:subject] + end + result = email_probe_outbound( params[:outbound], params[:meta][:email], subject ) + + (1..7).each {|loop| + sleep 7 # fetch mailbox found = nil @@ -655,22 +650,40 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} render :json => { :result => 'invalid', :message => 'Verification Email not found in mailbox.', + :subject => subject, } end private - def email_probe_outbound(params, email) + def email_probe_outbound(params, email, subject = nil) # validate params if !params[:adapter] result = { :result => 'invalid', - :message => 'Invalid!', + :message => 'Invalid, need adapter!', } return result end + if subject + mail = { + :from => email, + :to => email, + :subject => "Zammad Getting started Test Email #{subject}", + :body => '.', + 'x-zammad-ignore' => 'true', + } + else + mail = { + :from => email, + :to => 'emailtrytest@znuny.com', + :subject => 'test', + :body => 'test', + } + end + # test connection translationMap = { 'authentication failed' => 'Authentication failed!', @@ -678,15 +691,10 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} 'No route to host' => 'No route to host!', 'Connection refused' => 'Connection refused!', } - if params[:adapter] == 'smtp' + if params[:adapter] =~ /^smtp$/i begin Channel::SMTP.new.send( - { - :from => email, - :to => 'emailtrytest@znuny.com', - :subject => 'test', - :body => 'test', - }, + mail, { :options => params[:options] } @@ -694,18 +702,21 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} rescue Exception => e # check if sending email was ok, but mailserver rejected - whiteMap = { - 'Recipient address rejected' => true, - } - whiteMap.each {|key, message| - if e.message =~ /#{Regexp.escape(key)}/i - result = { - :result => 'ok', - :notice => e.message, - } - return result - end - } + if !subject + whiteMap = { + 'Recipient address rejected' => true, + } + whiteMap.each {|key, message| + if e.message =~ /#{Regexp.escape(key)}/i + result = { + :result => 'ok', + :settings => params, + :notice => e.message, + } + return result + end + } + end message_human = '' translationMap.each {|key, message| if e.message =~ /#{Regexp.escape(key)}/i @@ -714,6 +725,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} } result = { :result => 'invalid', + :settings => params, :message => e.message, :message_human => message_human, } @@ -727,12 +739,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} begin Channel::Sendmail.new.send( - { - :from => email, - :to => 'emailtrytest@znuny.com', - :subject => 'test', - :body => 'test', - }, + mail, nil ) rescue Exception => e @@ -744,6 +751,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} } result = { :result => 'invalid', + :settings => params, :message => e.message, :message_human => message_human, } @@ -781,6 +789,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} } result = { :result => 'invalid', + :settings => params, :message => e.message, :message_human => message_human, } @@ -803,6 +812,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} } result = { :result => 'invalid', + :settings => params, :message => e.message, :message_human => message_human, } diff --git a/app/models/channel/imap.rb b/app/models/channel/imap.rb index 5eb460697..f39bbc31e 100644 --- a/app/models/channel/imap.rb +++ b/app/models/channel/imap.rb @@ -14,17 +14,28 @@ class Channel::IMAP < Channel::EmailParser puts "fetching imap (#{channel[:options][:host]}/#{channel[:options][:user]} port=#{port},ssl=#{ssl})" - @imap = Net::IMAP.new( channel[:options][:host], port, ssl, nil, false ) - - # try LOGIN, if not - try plain - begin - @imap.authenticate( 'LOGIN', channel[:options][:user], channel[:options][:password] ) - rescue Exception => e - if e.to_s !~ /unsupported\sauthentication\smechanism/i - raise e - end - @imap.login( channel[:options][:user], channel[:options][:password] ) + # on check, reduce open_timeout to have faster probing + timeout = 12 + if check_type == 'check' + timeout = 4 end + + Timeout.timeout(timeout) do + + @imap = Net::IMAP.new( channel[:options][:host], port, ssl, nil, false ) + + end + + # try LOGIN, if not - try plain + begin + @imap.authenticate( 'LOGIN', channel[:options][:user], channel[:options][:password] ) + rescue Exception => e + if e.to_s !~ /unsupported\s(authenticate|authentication)\smechanism/i + raise e + end + @imap.login( channel[:options][:user], channel[:options][:password] ) + end + if !channel[:options][:folder] || channel[:options][:folder].empty? @imap.select('INBOX') else diff --git a/app/models/channel/pop3.rb b/app/models/channel/pop3.rb index 7c2e92a33..8324410a2 100644 --- a/app/models/channel/pop3.rb +++ b/app/models/channel/pop3.rb @@ -18,7 +18,7 @@ class Channel::POP3 < Channel::EmailParser # on check, reduce open_timeout to have faster probing if check_type == 'check' - @pop.open_timeout = 5 + @pop.open_timeout = 4 @pop.read_timeout = 6 end