Improved mailbox setup/auto detection.

This commit is contained in:
Martin Edenhofer 2014-11-18 12:51:35 +01:00
parent 965d4538ab
commit c3c5e91e81
5 changed files with 142 additions and 102 deletions

View file

@ -348,10 +348,10 @@ App.Config.set( 'getting_started/channel', Channel, 'Routes' )
class ChannelEmail extends App.ControllerContent class ChannelEmail extends App.ControllerContent
className: 'getstarted fit' className: 'getstarted fit'
events: events:
'submit .js-intro': 'emailProbe' 'submit .js-intro': 'probeBasedOnIntro'
'submit .js-inbound': 'storeInbound' 'submit .js-inbound': 'probeInbound'
'change .js-outbound [name=adapter]': 'toggleAdapter' 'change .js-outbound [name=adapter]': 'toggleOutboundAdapter'
'submit .js-outbound': 'storeOutbound' 'submit .js-outbound': 'probleOutbound'
constructor: -> constructor: ->
super super
@ -410,7 +410,7 @@ class ChannelEmail extends App.ControllerContent
el: @$('.base-outbound-type'), el: @$('.base-outbound-type'),
model: { configure_attributes: configureAttributesOutbound, className: '' }, model: { configure_attributes: configureAttributesOutbound, className: '' },
) )
@toggleAdapter() @toggleOutboundAdapter()
# inbound # inbound
configureAttributesInbound = [ configureAttributesInbound = [
@ -425,7 +425,15 @@ class ChannelEmail extends App.ControllerContent
model: { configure_attributes: configureAttributesInbound, className: '' }, 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() adapter = @$('.js-outbound [name=adapter]').val()
if adapter is 'smtp' if adapter is 'smtp'
configureAttributesOutbound = [ configureAttributesOutbound = [
@ -442,7 +450,7 @@ class ChannelEmail extends App.ControllerContent
else else
@el.find('.base-outbound-settings').html('') @el.find('.base-outbound-settings').html('')
emailProbe: (e) => probeBasedOnIntro: (e) =>
e.preventDefault() e.preventDefault()
params = @formParam(e.target) params = @formParam(e.target)
@ -467,17 +475,47 @@ class ChannelEmail extends App.ControllerContent
@verify(@account) @verify(@account)
else else
@showSlide('js-inbound') @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) @enable(e)
fail: => fail: =>
@enable(e) @enable(e)
@showSlide('js-intro') @showSlide('js-intro')
) )
showSlide: (name) => probeInbound: (e) =>
@$('.setup.wizard').addClass('hide') e.preventDefault()
@$(".setup.wizard.#{name}").removeClass('hide')
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() e.preventDefault()
# get params # get params
@ -485,8 +523,6 @@ class ChannelEmail extends App.ControllerContent
params['email'] = @account['meta']['email'] params['email'] = @account['meta']['email']
@disable(e) @disable(e)
@hideAlert('js-outbound')
@ajax( @ajax(
id: 'email_outbound' id: 'email_outbound'
type: 'POST' type: 'POST'
@ -507,39 +543,9 @@ class ChannelEmail extends App.ControllerContent
@enable(e) @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) => verify: (account, count = 0) =>
@showSlide('js-verify') @showSlide('js-verify')
@hideAlert('js-verify')
@ajax( @ajax(
id: 'email_verify' id: 'email_verify'
type: 'POST' type: 'POST'
@ -550,19 +556,31 @@ class ChannelEmail extends App.ControllerContent
if data.result is 'ok' if data.result is 'ok'
@navigate 'getting_started/agents' @navigate 'getting_started/agents'
else else
if count is 1 if count is 2
@showAlert('js-verify', data.message_human || data.message ) @showAlert('js-verify', data.message_human || data.message )
@delay( @delay(
=> @showSlide('js-inbound') =>
@showSlide('js-intro')
@showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.' )
2300 2300
) )
else else
console.log('r', data, @account)
if data.subject && @account
@account.subject = data.subject
@verify( @account, count + 1 ) @verify( @account, count + 1 )
@enable(e) #@enable(e)
fail: => fail: =>
@enable(e) #@enable(e)
) )
showSlide: (name) =>
@hideAlert(name)
@$('.setup.wizard').addClass('hide')
@$(".setup.wizard.#{name}").removeClass('hide')
showAlert: (screen, message) => showAlert: (screen, message) =>
@$(".#{screen}").find('.alert').removeClass('hide').text( App.i18n.translateInline( message ) ) @$(".#{screen}").find('.alert').removeClass('hide').text( App.i18n.translateInline( message ) )

View file

@ -5,6 +5,7 @@
<div class="wizard-slide"> <div class="wizard-slide">
<h2><%- @T('Email Account') %></h2> <h2><%- @T('Email Account') %></h2>
<div class="wizard-body vertical justified"> <div class="wizard-body vertical justified">
<div class="alert alert--danger hide" role="alert"></div>
<fieldset> <fieldset>
<div class="form-group"> <div class="form-group">
<label><%- @T('Full Name') %></label> <label><%- @T('Full Name') %></label>

View file

@ -174,7 +174,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
:adapter => 'smtp', :adapter => 'smtp',
:options => { :options => {
:host => 'smtp.gmail.com', :host => 'smtp.gmail.com',
:port => '465', :port => '25',
:ssl => true, :ssl => true,
:user => params[:email], :user => params[:email],
:password => params[:password], :password => params[:password],
@ -212,7 +212,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
render :json => { render :json => {
:result => 'ok', :result => 'ok',
:account => settings, :setting => settings,
} }
return return
end end
@ -540,9 +540,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
# connection test # connection test
result = email_probe_outbound( params, params[:email] ) result = email_probe_outbound( params, params[:email] )
render :json => { render :json => result
:result => result
}
end end
def email_inbound 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') return if deny_if_not_role('Admin')
# send verify email to inbox # send verify email to inbox
if !params[:subject]
subject = '#' + rand(99999999999).to_s subject = '#' + rand(99999999999).to_s
Channel::EmailSend.new.send( else
{ subject = params[:subject]
:from => params[:meta][:email], end
:to => params[:meta][:email], result = email_probe_outbound( params[:outbound], params[:meta][:email], subject )
:subject => "Zammad Getting started Test Email #{subject}",
:body => '.', (1..7).each {|loop|
'x-zammad-ignore' => 'true', sleep 7
}
)
(1..5).each {|loop|
sleep 10
# fetch mailbox # fetch mailbox
found = nil found = nil
@ -655,22 +650,40 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
render :json => { render :json => {
:result => 'invalid', :result => 'invalid',
:message => 'Verification Email not found in mailbox.', :message => 'Verification Email not found in mailbox.',
:subject => subject,
} }
end end
private private
def email_probe_outbound(params, email) def email_probe_outbound(params, email, subject = nil)
# validate params # validate params
if !params[:adapter] if !params[:adapter]
result = { result = {
:result => 'invalid', :result => 'invalid',
:message => 'Invalid!', :message => 'Invalid, need adapter!',
} }
return result return result
end 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 # test connection
translationMap = { translationMap = {
'authentication failed' => 'Authentication failed!', '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!', 'No route to host' => 'No route to host!',
'Connection refused' => 'Connection refused!', 'Connection refused' => 'Connection refused!',
} }
if params[:adapter] == 'smtp' if params[:adapter] =~ /^smtp$/i
begin begin
Channel::SMTP.new.send( Channel::SMTP.new.send(
{ mail,
:from => email,
:to => 'emailtrytest@znuny.com',
:subject => 'test',
:body => 'test',
},
{ {
:options => params[:options] :options => params[:options]
} }
@ -694,6 +702,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
rescue Exception => e rescue Exception => e
# check if sending email was ok, but mailserver rejected # check if sending email was ok, but mailserver rejected
if !subject
whiteMap = { whiteMap = {
'Recipient address rejected' => true, 'Recipient address rejected' => true,
} }
@ -701,11 +710,13 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
if e.message =~ /#{Regexp.escape(key)}/i if e.message =~ /#{Regexp.escape(key)}/i
result = { result = {
:result => 'ok', :result => 'ok',
:settings => params,
:notice => e.message, :notice => e.message,
} }
return result return result
end end
} }
end
message_human = '' message_human = ''
translationMap.each {|key, message| translationMap.each {|key, message|
if e.message =~ /#{Regexp.escape(key)}/i if e.message =~ /#{Regexp.escape(key)}/i
@ -714,6 +725,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
} }
result = { result = {
:result => 'invalid', :result => 'invalid',
:settings => params,
:message => e.message, :message => e.message,
:message_human => message_human, :message_human => message_human,
} }
@ -727,12 +739,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
begin begin
Channel::Sendmail.new.send( Channel::Sendmail.new.send(
{ mail,
:from => email,
:to => 'emailtrytest@znuny.com',
:subject => 'test',
:body => 'test',
},
nil nil
) )
rescue Exception => e rescue Exception => e
@ -744,6 +751,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
} }
result = { result = {
:result => 'invalid', :result => 'invalid',
:settings => params,
:message => e.message, :message => e.message,
:message_human => message_human, :message_human => message_human,
} }
@ -781,6 +789,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
} }
result = { result = {
:result => 'invalid', :result => 'invalid',
:settings => params,
:message => e.message, :message => e.message,
:message_human => message_human, :message_human => message_human,
} }
@ -803,6 +812,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
} }
result = { result = {
:result => 'invalid', :result => 'invalid',
:settings => params,
:message => e.message, :message => e.message,
:message_human => message_human, :message_human => message_human,
} }

View file

@ -14,17 +14,28 @@ class Channel::IMAP < Channel::EmailParser
puts "fetching imap (#{channel[:options][:host]}/#{channel[:options][:user]} port=#{port},ssl=#{ssl})" puts "fetching imap (#{channel[:options][:host]}/#{channel[:options][:user]} port=#{port},ssl=#{ssl})"
# 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 ) @imap = Net::IMAP.new( channel[:options][:host], port, ssl, nil, false )
end
# try LOGIN, if not - try plain # try LOGIN, if not - try plain
begin begin
@imap.authenticate( 'LOGIN', channel[:options][:user], channel[:options][:password] ) @imap.authenticate( 'LOGIN', channel[:options][:user], channel[:options][:password] )
rescue Exception => e rescue Exception => e
if e.to_s !~ /unsupported\sauthentication\smechanism/i if e.to_s !~ /unsupported\s(authenticate|authentication)\smechanism/i
raise e raise e
end end
@imap.login( channel[:options][:user], channel[:options][:password] ) @imap.login( channel[:options][:user], channel[:options][:password] )
end end
if !channel[:options][:folder] || channel[:options][:folder].empty? if !channel[:options][:folder] || channel[:options][:folder].empty?
@imap.select('INBOX') @imap.select('INBOX')
else else

View file

@ -18,7 +18,7 @@ class Channel::POP3 < Channel::EmailParser
# on check, reduce open_timeout to have faster probing # on check, reduce open_timeout to have faster probing
if check_type == 'check' if check_type == 'check'
@pop.open_timeout = 5 @pop.open_timeout = 4
@pop.read_timeout = 6 @pop.read_timeout = 6
end end