Improved email channel wizard, show info if there are already emails in the mailbox.
This commit is contained in:
parent
5ece50c39a
commit
eb0aac89ba
20 changed files with 527 additions and 160 deletions
|
@ -602,6 +602,7 @@ class App.Wizard extends App.Controller
|
||||||
goToSlide: (e) =>
|
goToSlide: (e) =>
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
slide = $(e.target).data('slide')
|
slide = $(e.target).data('slide')
|
||||||
|
return if !slide
|
||||||
@showSlide(slide)
|
@showSlide(slide)
|
||||||
|
|
||||||
showSlide: (name) =>
|
showSlide: (name) =>
|
||||||
|
|
|
@ -14,3 +14,29 @@ class App.ChannelChat extends App.ControllerTabs
|
||||||
]
|
]
|
||||||
|
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
|
# enable/disable
|
||||||
|
|
||||||
|
# show also if nobody is online / leave a message
|
||||||
|
|
||||||
|
# channels
|
||||||
|
# sales - en / authentication needed
|
||||||
|
# sales - de / authentication needed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# agent
|
||||||
|
# channes I'm work for
|
||||||
|
|
||||||
|
# x sales - de / greeting
|
||||||
|
# o sales - en / greeting
|
||||||
|
|
||||||
|
# concurent chats
|
||||||
|
|
||||||
|
# active chats
|
||||||
|
# name, email, location/ip, age
|
||||||
|
|
||||||
|
|
||||||
|
# chat history
|
||||||
|
|
||||||
|
App.Config.set( 'Chat', { prio: 4000, name: 'Chat', parent: '#channels', target: '#channels/chat', controller: App.ChannelChat, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
|
|
|
@ -363,7 +363,7 @@ class App.ChannelEmailAccountWizard extends App.Wizard
|
||||||
'submit .js-inbound': 'probeInbound'
|
'submit .js-inbound': 'probeInbound'
|
||||||
'change .js-outbound [name=adapter]': 'toggleOutboundAdapter'
|
'change .js-outbound [name=adapter]': 'toggleOutboundAdapter'
|
||||||
'submit .js-outbound': 'probleOutbound'
|
'submit .js-outbound': 'probleOutbound'
|
||||||
'click .js-back': 'goToSlide'
|
'click .js-goToSlide': 'goToSlide'
|
||||||
'click .js-close': 'hide'
|
'click .js-close': 'hide'
|
||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
|
@ -488,7 +488,20 @@ class App.ChannelEmailAccountWizard extends App.Wizard
|
||||||
if data.setting
|
if data.setting
|
||||||
for key, value of data.setting
|
for key, value of data.setting
|
||||||
@account[key] = value
|
@account[key] = value
|
||||||
@verify(@account)
|
|
||||||
|
if !@channel && data.content_messages && data.content_messages > 0
|
||||||
|
message = App.i18n.translateContent('We have already found %s emails in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages)
|
||||||
|
@$('.js-inbound-acknowledge .js-message').html(message)
|
||||||
|
@$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-intro')
|
||||||
|
@$('.js-inbound-acknowledge .js-next').attr('data-slide', '')
|
||||||
|
@$('.js-inbound-acknowledge .js-next').unbind('click.verify').bind('click.verify', (e) =>
|
||||||
|
e.preventDefault()
|
||||||
|
@verify(@account)
|
||||||
|
)
|
||||||
|
@showSlide('js-inbound-acknowledge')
|
||||||
|
else
|
||||||
|
@verify(@account)
|
||||||
|
|
||||||
else if data.result is 'duplicate'
|
else if data.result is 'duplicate'
|
||||||
@showSlide('js-intro')
|
@showSlide('js-intro')
|
||||||
@showAlert('js-intro', 'Account already exists!' )
|
@showAlert('js-intro', 'Account already exists!' )
|
||||||
|
@ -530,7 +543,14 @@ class App.ChannelEmailAccountWizard extends App.Wizard
|
||||||
# remember account settings
|
# remember account settings
|
||||||
@account.inbound = params
|
@account.inbound = params
|
||||||
|
|
||||||
@showSlide('js-outbound')
|
if !@channel && data.content_messages && data.content_messages > 0
|
||||||
|
message = App.i18n.translateContent('We have already found %s emails in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages)
|
||||||
|
@$('.js-inbound-acknowledge .js-message').html(message)
|
||||||
|
@$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-inbound')
|
||||||
|
@$('.js-inbound-acknowledge .js-next').unbind('click.verify')
|
||||||
|
@showSlide('js-inbound-acknowledge')
|
||||||
|
else
|
||||||
|
@showSlide('js-outbound')
|
||||||
|
|
||||||
# fill user / password based on inbound settings
|
# fill user / password based on inbound settings
|
||||||
if !@channel
|
if !@channel
|
||||||
|
@ -768,3 +788,5 @@ class App.ChannelEmailNotificationWizard extends App.Wizard
|
||||||
@showInvalidField('js-outbound', data.invalid_field)
|
@showInvalidField('js-outbound', data.invalid_field)
|
||||||
@enable(e)
|
@enable(e)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
App.Config.set( 'Email', { prio: 3000, name: 'Email', parent: '#channels', target: '#channels/email', controller: App.ChannelEmail, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
|
|
|
@ -12,3 +12,5 @@ class App.ChannelFacebook extends App.Controller
|
||||||
@html App.view('channel/facebook')(
|
@html App.view('channel/facebook')(
|
||||||
head: 'some header'
|
head: 'some header'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
App.Config.set( 'Facebook', { prio: 6000, name: 'Facebook', parent: '#channels', target: '#channels/facebook', controller: App.ChannelFacebook, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
|
|
|
@ -31,3 +31,5 @@ class App.ChannelForm extends App.Controller
|
||||||
else
|
else
|
||||||
paramString += " #{key}: '#{quote(value)}'"
|
paramString += " #{key}: '#{quote(value)}'"
|
||||||
@$('.js-modal-params').html(paramString)
|
@$('.js-modal-params').html(paramString)
|
||||||
|
|
||||||
|
App.Config.set( 'Form', { prio: 2000, name: 'Form', parent: '#channels', target: '#channels/form', controller: App.ChannelForm, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
|
|
|
@ -11,3 +11,5 @@ class App.ChannelTwitter extends App.Controller
|
||||||
@html App.view('channel/twitter')(
|
@html App.view('channel/twitter')(
|
||||||
head: 'some header'
|
head: 'some header'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
App.Config.set( 'Twitter', { prio: 5000, name: 'Twitter', parent: '#channels', target: '#channels/twitter', controller: App.ChannelTwitter, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
|
|
|
@ -14,3 +14,5 @@ class App.ChannelWeb extends App.ControllerTabs
|
||||||
]
|
]
|
||||||
|
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
|
App.Config.set( 'Web', { prio: 1000, name: 'Web', parent: '#channels', target: '#channels/web', controller: App.ChannelWeb, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
#App.Config.set( 'channels/:target', Index, 'Routes' )
|
|
||||||
#App.Config.set( 'channels', Index, 'Routes' )
|
|
||||||
|
|
||||||
#App.Config.set( 'Channels', { prio: 2500, name: 'Channels', target: '#channels', role: ['Admin'] }, 'NavBarLevel4' )
|
|
||||||
|
|
||||||
#App.Config.set( 'Channels', { prio: 2500, parent: '#admin', name: 'Channels', target: '#channels', role: ['Admin'] }, 'NavBar' )
|
|
||||||
|
|
||||||
App.Config.set( 'Web', { prio: 1000, name: 'Web', parent: '#channels', target: '#channels/web', controller: App.ChannelWeb, role: ['Admin'] }, 'NavBarAdmin' )
|
|
||||||
App.Config.set( 'Form', { prio: 2000, name: 'Form', parent: '#channels', target: '#channels/form', controller: App.ChannelForm, role: ['Admin'] }, 'NavBarAdmin' )
|
|
||||||
App.Config.set( 'Email', { prio: 3000, name: 'Email', parent: '#channels', target: '#channels/email', controller: App.ChannelEmail, role: ['Admin'] }, 'NavBarAdmin' )
|
|
||||||
App.Config.set( 'Chat', { prio: 4000, name: 'Chat', parent: '#channels', target: '#channels/chat', controller: App.ChannelChat, role: ['Admin'] }, 'NavBarAdmin' )
|
|
||||||
App.Config.set( 'Twitter', { prio: 5000, name: 'Twitter', parent: '#channels', target: '#channels/twitter', controller: App.ChannelTwitter, role: ['Admin'] }, 'NavBarAdmin' )
|
|
||||||
App.Config.set( 'Facebook', { prio: 6000, name: 'Facebook', parent: '#channels', target: '#channels/facebook', controller: App.ChannelFacebook, role: ['Admin'] }, 'NavBarAdmin' )
|
|
||||||
|
|
|
@ -613,7 +613,7 @@ class ChannelEmail extends App.Wizard
|
||||||
'submit .js-inbound': 'probeInbound'
|
'submit .js-inbound': 'probeInbound'
|
||||||
'change .js-outbound [name=adapter]': 'toggleOutboundAdapter'
|
'change .js-outbound [name=adapter]': 'toggleOutboundAdapter'
|
||||||
'submit .js-outbound': 'probleOutbound'
|
'submit .js-outbound': 'probleOutbound'
|
||||||
'click .js-back': 'goToSlide'
|
'click .js-goToSlide': 'goToSlide'
|
||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super
|
super
|
||||||
|
@ -744,7 +744,20 @@ class ChannelEmail extends App.Wizard
|
||||||
if data.setting
|
if data.setting
|
||||||
for key, value of data.setting
|
for key, value of data.setting
|
||||||
@account[key] = value
|
@account[key] = value
|
||||||
@verify(@account)
|
|
||||||
|
if data.content_messages && data.content_messages > 0
|
||||||
|
message = App.i18n.translateContent('We have already found %s emails in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages)
|
||||||
|
@$('.js-inbound-acknowledge .js-message').html(message)
|
||||||
|
@$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-intro')
|
||||||
|
@$('.js-inbound-acknowledge .js-next').attr('data-slide', '')
|
||||||
|
@$('.js-inbound-acknowledge .js-next').unbind('click.verify').bind('click.verify', (e) =>
|
||||||
|
e.preventDefault()
|
||||||
|
@verify(@account)
|
||||||
|
)
|
||||||
|
@showSlide('js-inbound-acknowledge')
|
||||||
|
else
|
||||||
|
@verify(@account)
|
||||||
|
|
||||||
else if data.result is 'duplicate'
|
else if data.result is 'duplicate'
|
||||||
@showSlide('js-intro')
|
@showSlide('js-intro')
|
||||||
@showAlert('js-intro', 'Account already exists!' )
|
@showAlert('js-intro', 'Account already exists!' )
|
||||||
|
@ -781,7 +794,14 @@ class ChannelEmail extends App.Wizard
|
||||||
# remember account settings
|
# remember account settings
|
||||||
@account.inbound = params
|
@account.inbound = params
|
||||||
|
|
||||||
@showSlide('js-outbound')
|
if data.content_messages && data.content_messages > 0
|
||||||
|
message = App.i18n.translateContent('We have already found %s emails in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages)
|
||||||
|
@$('.js-inbound-acknowledge .js-message').html(message)
|
||||||
|
@$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-inbound')
|
||||||
|
@$('.js-inbound-acknowledge .js-next').unbind('click.verify')
|
||||||
|
@showSlide('js-inbound-acknowledge')
|
||||||
|
else
|
||||||
|
@showSlide('js-outbound')
|
||||||
|
|
||||||
# fill user / password based on inbound settings
|
# fill user / password based on inbound settings
|
||||||
if !@channel
|
if !@channel
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<div class="modal-rightFooter">
|
<div class="modal-rightFooter">
|
||||||
<a class="btn btn--text btn--secondary js-back align-left" data-slide="js-intro"><%- @T('Go Back') %></a>
|
<a class="btn btn--text btn--secondary js-goToSlide align-left" data-slide="js-intro"><%- @T('Go Back') %></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-rightFooter">
|
<div class="modal-rightFooter">
|
||||||
<button class="btn btn--primary align-right"><%- @T('Continue') %></button>
|
<button class="btn btn--primary align-right"><%- @T('Continue') %></button>
|
||||||
|
@ -116,6 +116,29 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<form class="modal-content setup wizard hide js-inbound-acknowledge">
|
||||||
|
<div class="modal-header">
|
||||||
|
<div class="modal-close js-close">
|
||||||
|
<%- @Icon('diagonal-cross') %>
|
||||||
|
</div>
|
||||||
|
<h1 class="modal-title"><%- @T('Email Inbound') %></h1>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="wizard-body vertical justified">
|
||||||
|
<div class="alert alert--danger hide" role="alert"></div>
|
||||||
|
<p class="js-message"><%- @T('We have already found %s email(s) in your mailbox. Zammad will move it all from your mailbox into Zammad.', 'x') %></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<div class="modal-rightFooter">
|
||||||
|
<a class="btn btn--text btn--secondary js-goToSlide js-back align-left" data-slide="js-inbound"><%- @T('Go Back') %></a>
|
||||||
|
</div>
|
||||||
|
<div class="modal-rightFooter">
|
||||||
|
<button class="btn btn--primary js-goToSlide js-next align-right" data-slide="js-outbound"><%- @T('Continue') %></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
<form class="modal-content setup wizard hide js-outbound">
|
<form class="modal-content setup wizard hide js-outbound">
|
||||||
<!-- dummy to prevent chrome to ask for password save -->
|
<!-- dummy to prevent chrome to ask for password save -->
|
||||||
<input style="display:none">
|
<input style="display:none">
|
||||||
|
@ -136,7 +159,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<div class="modal-rightFooter">
|
<div class="modal-rightFooter">
|
||||||
<a class="btn btn--text btn--secondary js-back align-left" data-slide="js-inbound"><%- @T('Go Back') %></a>
|
<a class="btn btn--text btn--secondary js-goToSlide align-left" data-slide="js-inbound"><%- @T('Go Back') %></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-rightFooter">
|
<div class="modal-rightFooter">
|
||||||
<button class="btn btn--primary align-right"><%- @T('Continue') %></button>
|
<button class="btn btn--primary align-right"><%- @T('Continue') %></button>
|
||||||
|
|
|
@ -78,12 +78,26 @@
|
||||||
<div class="base-inbound-settings"></div>
|
<div class="base-inbound-settings"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="wizard-controls center">
|
<div class="wizard-controls center">
|
||||||
<a class="btn btn--text btn--secondary js-back" data-slide="js-intro"><%- @T('Go Back') %></a>
|
<a class="btn btn--text btn--secondary js-goToSlide" data-slide="js-intro"><%- @T('Go Back') %></a>
|
||||||
<button class="btn btn--primary align-right"><%- @T( 'Continue' ) %></button>
|
<button class="btn btn--primary align-right"><%- @T( 'Continue' ) %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<form class="setup wizard hide js-inbound-acknowledge">
|
||||||
|
<div class="wizard-slide">
|
||||||
|
<h2><%- @T('Email Inbound') %></h2>
|
||||||
|
<div class="wizard-body vertical justified">
|
||||||
|
<div class="alert alert--danger hide" role="alert"></div>
|
||||||
|
<p class="js-message"><%- @T('We have already found %s email(s) in your mailbox. Zammad will move it all from your mailbox into Zammad.', 'x') %></p>
|
||||||
|
</div>
|
||||||
|
<div class="wizard-controls center">
|
||||||
|
<a class="btn btn--text btn--secondary js-goToSlide js-back" data-slide="js-intro"><%- @T('Go Back') %></a>
|
||||||
|
<button class="btn btn--primary js-goToSlide js-next align-right" data-slide="js-outbound"><%- @T('Continue') %></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
<form class="setup wizard hide js-outbound">
|
<form class="setup wizard hide js-outbound">
|
||||||
<!-- dummy to prevent chrome to ask for password save -->
|
<!-- dummy to prevent chrome to ask for password save -->
|
||||||
<input style="display:none">
|
<input style="display:none">
|
||||||
|
@ -97,7 +111,7 @@
|
||||||
<div class="base-outbound-settings"></div>
|
<div class="base-outbound-settings"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="wizard-controls center">
|
<div class="wizard-controls center">
|
||||||
<a class="btn btn--text btn--secondary js-back" data-slide="js-inbound"><%- @T('Go Back') %></a>
|
<a class="btn btn--text btn--secondary js-goToSlide" data-slide="js-inbound"><%- @T('Go Back') %></a>
|
||||||
<button class="btn btn--primary align-right"><%- @T( 'Continue' ) %></button>
|
<button class="btn btn--primary align-right"><%- @T( 'Continue' ) %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -157,9 +157,7 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
|
||||||
status_in: 'ok',
|
status_in: 'ok',
|
||||||
status_out: 'ok',
|
status_out: 'ok',
|
||||||
)
|
)
|
||||||
render json: {
|
render json: result
|
||||||
result: 'ok',
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -202,9 +200,7 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: {
|
render json: result
|
||||||
result: 'ok',
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def email_notification
|
def email_notification
|
||||||
|
|
|
@ -52,9 +52,9 @@ fetch one account
|
||||||
|
|
||||||
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
||||||
driver_instance = driver_class.new
|
driver_instance = driver_class.new
|
||||||
driver_instance.fetch(adapter_options, self)
|
result = driver_instance.fetch(adapter_options, self)
|
||||||
self.status_in = 'ok'
|
self.status_in = result[:result]
|
||||||
self.last_log_in = ''
|
self.last_log_in = result[:notice]
|
||||||
save
|
save
|
||||||
rescue => e
|
rescue => e
|
||||||
error = "Can't use Channel::Driver::#{adapter.to_classname}: #{e.inspect}"
|
error = "Can't use Channel::Driver::#{adapter.to_classname}: #{e.inspect}"
|
||||||
|
|
|
@ -29,12 +29,21 @@ returns
|
||||||
if !data[ self.class.to_app_model ][ id ]
|
if !data[ self.class.to_app_model ][ id ]
|
||||||
attributes = attributes_with_associations
|
attributes = attributes_with_associations
|
||||||
|
|
||||||
# remove passwords
|
# remove passwords if use is no admin
|
||||||
%w(inbound outbound).each {|key|
|
access = false
|
||||||
if attributes['options'] && attributes['options'][key] && attributes['options'][key]['options']
|
if UserInfo.current_user_id
|
||||||
attributes['options'][key]['options'].delete('password')
|
user = User.lookup(id: UserInfo.current_user_id)
|
||||||
|
if user.role?('Admin')
|
||||||
|
access = true
|
||||||
end
|
end
|
||||||
}
|
end
|
||||||
|
if !access
|
||||||
|
%w(inbound outbound).each {|key|
|
||||||
|
if attributes['options'] && attributes['options'][key] && attributes['options'][key]['options']
|
||||||
|
attributes['options'][key]['options'].delete('password')
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
data[ self.class.to_app_model ][ id ] = attributes
|
data[ self.class.to_app_model ][ id ] = attributes
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,46 @@ require 'net/imap'
|
||||||
|
|
||||||
class Channel::Driver::Imap < Channel::EmailParser
|
class Channel::Driver::Imap < Channel::EmailParser
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
fetch emails from IMAP account
|
||||||
|
|
||||||
|
instance = Channel::Driver::Imap.new
|
||||||
|
result = instance.fetch(params[:inbound][:options], channel, 'verify', subject_looking_for)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
result: 'ok',
|
||||||
|
fetched: 123,
|
||||||
|
notice: 'e. g. message about to big emails in mailbox',
|
||||||
|
}
|
||||||
|
|
||||||
|
check if connect to IMAP account is possible, return count of mails in mailbox
|
||||||
|
|
||||||
|
instance = Channel::Driver::Imap.new
|
||||||
|
result = instance.fetch(params[:inbound][:options], channel, 'check')
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
result: 'ok',
|
||||||
|
content_messages: 123,
|
||||||
|
}
|
||||||
|
|
||||||
|
verify IMAP account, check if search email is in there
|
||||||
|
|
||||||
|
instance = Channel::Driver::Imap.new
|
||||||
|
result = instance.fetch(params[:inbound][:options], channel, 'verify', subject_looking_for)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
result: 'ok', # 'verify not ok'
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
def fetch (options, channel, check_type = '', verify_string = '')
|
def fetch (options, channel, check_type = '', verify_string = '')
|
||||||
ssl = true
|
ssl = true
|
||||||
port = 993
|
port = 993
|
||||||
|
@ -21,65 +61,118 @@ class Channel::Driver::Imap < Channel::EmailParser
|
||||||
end
|
end
|
||||||
|
|
||||||
Timeout.timeout(timeout) do
|
Timeout.timeout(timeout) do
|
||||||
|
|
||||||
@imap = Net::IMAP.new( options[:host], port, ssl, nil, false )
|
@imap = Net::IMAP.new( options[:host], port, ssl, nil, false )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# try LOGIN, if not - try plain
|
# try LOGIN, if not - try plain
|
||||||
begin
|
begin
|
||||||
@imap.authenticate( 'LOGIN', options[:user], options[:password] )
|
@imap.authenticate('LOGIN', options[:user], options[:password])
|
||||||
rescue => e
|
rescue => e
|
||||||
if e.to_s !~ /(unsupported\s(authenticate|authentication)\smechanism|not\ssupported)/i
|
if e.to_s !~ /(unsupported\s(authenticate|authentication)\smechanism|not\ssupported)/i
|
||||||
raise e
|
raise e
|
||||||
end
|
end
|
||||||
@imap.login( options[:user], options[:password] )
|
@imap.login(options[:user], options[:password])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# select folder
|
||||||
if !options[:folder] || options[:folder].empty?
|
if !options[:folder] || options[:folder].empty?
|
||||||
@imap.select('INBOX')
|
@imap.select('INBOX')
|
||||||
else
|
else
|
||||||
@imap.select( options[:folder] )
|
@imap.select(options[:folder])
|
||||||
end
|
|
||||||
if check_type == 'check'
|
|
||||||
Rails.logger.info 'check only mode, fetch no emails'
|
|
||||||
disconnect
|
|
||||||
return
|
|
||||||
elsif check_type == 'verify'
|
|
||||||
Rails.logger.info "verify mode, fetch no emails #{verify_string}"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
message_ids = @imap.search(['ALL'])
|
message_ids = @imap.search(['ALL'])
|
||||||
count_all = message_ids.count
|
|
||||||
count = 0
|
# check mode only
|
||||||
|
if check_type == 'check'
|
||||||
|
Rails.logger.info 'check only mode, fetch no emails'
|
||||||
|
content_max_check = 5
|
||||||
|
content_messages = 0
|
||||||
|
|
||||||
|
# check messages
|
||||||
|
message_ids.each do |message_id|
|
||||||
|
|
||||||
|
message_meta = @imap.fetch(message_id, ['RFC822.HEADER'])[0].attr
|
||||||
|
|
||||||
|
# check how many content messages we have, for notice used
|
||||||
|
header = message_meta['RFC822.HEADER']
|
||||||
|
if header && header !~ /x-zammad-ignore/i
|
||||||
|
content_messages += 1
|
||||||
|
break if content_max_check < content_messages
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if content_messages >= content_messages
|
||||||
|
content_messages = message_ids.count
|
||||||
|
end
|
||||||
|
disconnect
|
||||||
|
return {
|
||||||
|
result: 'ok',
|
||||||
|
content_messages: content_messages,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
# reverse message order to increase performance
|
# reverse message order to increase performance
|
||||||
if check_type == 'verify'
|
if check_type == 'verify'
|
||||||
|
Rails.logger.info "verify mode, fetch no emails #{verify_string}"
|
||||||
message_ids.reverse!
|
message_ids.reverse!
|
||||||
end
|
|
||||||
|
|
||||||
message_ids.each do |message_id|
|
|
||||||
count += 1
|
|
||||||
Rails.logger.info " - message #{count}/#{count_all}"
|
|
||||||
#Rails.logger.info msg.to_s
|
|
||||||
|
|
||||||
# check for verify message
|
# check for verify message
|
||||||
if check_type == 'verify'
|
message_ids.each do |message_id|
|
||||||
subject = @imap.fetch(message_id, 'ENVELOPE')[0].attr['ENVELOPE'].subject
|
|
||||||
|
message_meta = @imap.fetch(message_id, ['ENVELOPE'])[0].attr
|
||||||
|
|
||||||
|
# check if verify message exists
|
||||||
|
subject = message_meta['ENVELOPE'].subject
|
||||||
if subject && subject =~ /#{verify_string}/
|
if subject && subject =~ /#{verify_string}/
|
||||||
Rails.logger.info " - verify email #{verify_string} found"
|
Rails.logger.info " - verify email #{verify_string} found"
|
||||||
@imap.store(message_id, '+FLAGS', [:Deleted])
|
@imap.store(message_id, '+FLAGS', [:Deleted])
|
||||||
@imap.expunge()
|
@imap.expunge()
|
||||||
disconnect
|
disconnect
|
||||||
return 'verify ok'
|
return {
|
||||||
|
result: 'ok',
|
||||||
|
}
|
||||||
end
|
end
|
||||||
else
|
end
|
||||||
|
|
||||||
# delete email from server after article was created
|
disconnect
|
||||||
msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
|
return {
|
||||||
if process(channel, msg)
|
result: 'verify not ok',
|
||||||
@imap.store(message_id, '+FLAGS', [:Deleted])
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# fetch regular messages
|
||||||
|
count_all = message_ids.count
|
||||||
|
count = 0
|
||||||
|
count_fetched = 0
|
||||||
|
notice = ''
|
||||||
|
message_ids.each do |message_id|
|
||||||
|
count += 1
|
||||||
|
Rails.logger.info " - message #{count}/#{count_all}"
|
||||||
|
#Rails.logger.info msg.to_s
|
||||||
|
|
||||||
|
message_meta = @imap.fetch(message_id, ['RFC822.SIZE', 'FLAGS', 'INTERNALDATE'])[0]
|
||||||
|
|
||||||
|
# ignore to big messages
|
||||||
|
max_message_size = Setting.get('postmaster_max_size')
|
||||||
|
real_message_size = message_meta.attr['RFC822.SIZE'].to_f / 1024 / 1024
|
||||||
|
if real_message_size > max_message_size
|
||||||
|
info = " - ignore message #{count}/#{count_all} - because message is to big (is:#{real_message_size}/max:#{max_message_size} in MB)"
|
||||||
|
Rails.logger.info info
|
||||||
|
notice += "#{info}\n"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
# ignore deleted messages
|
||||||
|
if message_meta.attr['FLAGS'].include?(:Deleted)
|
||||||
|
Rails.logger.info " - ignore message #{count}/#{count_all} - because message has already delete flag"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
# delete email from server after article was created
|
||||||
|
msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
|
||||||
|
if process(channel, msg)
|
||||||
|
@imap.store(message_id, '+FLAGS', [:Deleted])
|
||||||
|
count_fetched += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@imap.expunge()
|
@imap.expunge()
|
||||||
|
@ -88,6 +181,11 @@ class Channel::Driver::Imap < Channel::EmailParser
|
||||||
Rails.logger.info ' - no message'
|
Rails.logger.info ' - no message'
|
||||||
end
|
end
|
||||||
Rails.logger.info 'done'
|
Rails.logger.info 'done'
|
||||||
|
{
|
||||||
|
result: 'ok',
|
||||||
|
fetched: count_fetched,
|
||||||
|
notice: notice,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def disconnect
|
def disconnect
|
||||||
|
|
|
@ -4,6 +4,46 @@ require 'net/pop'
|
||||||
|
|
||||||
class Channel::Driver::Pop3 < Channel::EmailParser
|
class Channel::Driver::Pop3 < Channel::EmailParser
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
fetch emails from Pop3 account
|
||||||
|
|
||||||
|
instance = Channel::Driver::Imap.new
|
||||||
|
result = instance.fetch(params[:inbound][:options], channel, 'verify', subject_looking_for)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
result: 'ok',
|
||||||
|
fetched: 123,
|
||||||
|
notice: 'e. g. message about to big emails in mailbox',
|
||||||
|
}
|
||||||
|
|
||||||
|
check if connect to Pop3 account is possible, return count of mails in mailbox
|
||||||
|
|
||||||
|
instance = Channel::Driver::Imap.new
|
||||||
|
result = instance.fetch(params[:inbound][:options], channel, 'check')
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
result: 'ok',
|
||||||
|
content_messages: 123,
|
||||||
|
}
|
||||||
|
|
||||||
|
verify Pop3 account, check if search email is in there
|
||||||
|
|
||||||
|
instance = Channel::Driver::Imap.new
|
||||||
|
result = instance.fetch(params[:inbound][:options], channel, 'verify', subject_looking_for)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
result: 'ok', # 'verify not ok'
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
def fetch (options, channel, check_type = '', verify_string = '')
|
def fetch (options, channel, check_type = '', verify_string = '')
|
||||||
ssl = true
|
ssl = true
|
||||||
port = 995
|
port = 995
|
||||||
|
@ -15,8 +55,11 @@ class Channel::Driver::Pop3 < Channel::EmailParser
|
||||||
Rails.logger.info "fetching pop3 (#{options[:host]}/#{options[:user]} port=#{port},ssl=#{ssl})"
|
Rails.logger.info "fetching pop3 (#{options[:host]}/#{options[:user]} port=#{port},ssl=#{ssl})"
|
||||||
|
|
||||||
@pop = Net::POP3.new( options[:host], port )
|
@pop = Net::POP3.new( options[:host], port )
|
||||||
|
#@pop.set_debug_output $stderr
|
||||||
|
|
||||||
# on check, reduce open_timeout to have faster probing
|
# on check, reduce open_timeout to have faster probing
|
||||||
|
@pop.open_timeout = 8
|
||||||
|
@pop.read_timeout = 12
|
||||||
if check_type == 'check'
|
if check_type == 'check'
|
||||||
@pop.open_timeout = 4
|
@pop.open_timeout = 4
|
||||||
@pop.read_timeout = 6
|
@pop.read_timeout = 6
|
||||||
|
@ -25,43 +68,87 @@ class Channel::Driver::Pop3 < Channel::EmailParser
|
||||||
if ssl
|
if ssl
|
||||||
@pop.enable_ssl(OpenSSL::SSL::VERIFY_NONE)
|
@pop.enable_ssl(OpenSSL::SSL::VERIFY_NONE)
|
||||||
end
|
end
|
||||||
@pop.start( options[:user], options[:password] )
|
@pop.start(options[:user], options[:password])
|
||||||
|
|
||||||
|
mails = @pop.mails
|
||||||
|
|
||||||
if check_type == 'check'
|
if check_type == 'check'
|
||||||
Rails.logger.info 'check only mode, fetch no emails'
|
Rails.logger.info 'check only mode, fetch no emails'
|
||||||
disconnect
|
content_max_check = 2
|
||||||
return
|
content_messages = 0
|
||||||
elsif check_type == 'verify'
|
|
||||||
Rails.logger.info 'verify mode, fetch no emails'
|
|
||||||
end
|
|
||||||
|
|
||||||
mails = @pop.mails
|
# check messages
|
||||||
count = 0
|
mails.each do |m|
|
||||||
count_all = mails.size
|
mail = m.pop
|
||||||
|
next if !mail
|
||||||
|
|
||||||
|
# check how many content messages we have, for notice used
|
||||||
|
if mail !~ /x-zammad-ignore/i
|
||||||
|
content_messages += 1
|
||||||
|
break if content_max_check < content_messages
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if content_messages >= content_messages
|
||||||
|
content_messages = mails.count
|
||||||
|
end
|
||||||
|
disconnect
|
||||||
|
return {
|
||||||
|
result: 'ok',
|
||||||
|
content_messages: content_messages,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
# reverse message order to increase performance
|
# reverse message order to increase performance
|
||||||
if check_type == 'verify'
|
if check_type == 'verify'
|
||||||
|
Rails.logger.info 'verify mode, fetch no emails'
|
||||||
mails.reverse!
|
mails.reverse!
|
||||||
|
|
||||||
|
# check for verify message
|
||||||
|
mails.each do |m|
|
||||||
|
mail = m.pop
|
||||||
|
next if !mail
|
||||||
|
|
||||||
|
# check if verify message exists
|
||||||
|
if mail =~ /#{verify_string}/
|
||||||
|
Rails.logger.info " - verify email #{verify_string} found"
|
||||||
|
m.delete
|
||||||
|
disconnect
|
||||||
|
return {
|
||||||
|
result: 'ok',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
result: 'verify not ok',
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# fetch regular messages
|
||||||
|
count_all = mails.size
|
||||||
|
count = 0
|
||||||
|
count_fetched = 0
|
||||||
|
notice = ''
|
||||||
mails.each do |m|
|
mails.each do |m|
|
||||||
count += 1
|
count += 1
|
||||||
Rails.logger.info " - message #{count}/#{count_all}"
|
Rails.logger.info " - message #{count}/#{count_all}"
|
||||||
|
|
||||||
# check for verify message
|
mail = m.pop
|
||||||
if check_type == 'verify'
|
|
||||||
mail = m.pop
|
|
||||||
if mail && mail =~ /#{verify_string}/
|
|
||||||
Rails.logger.info " - verify email #{verify_string} found"
|
|
||||||
m.delete
|
|
||||||
disconnect
|
|
||||||
return 'verify ok'
|
|
||||||
end
|
|
||||||
else
|
|
||||||
|
|
||||||
# delete email from server after article was created
|
# ignore to big messages
|
||||||
if process(channel, m.pop)
|
max_message_size = Setting.get('postmaster_max_size')
|
||||||
m.delete
|
real_message_size = mail.size.to_f / 1024 / 1024
|
||||||
end
|
if real_message_size > max_message_size
|
||||||
|
info = " - ignore message #{count}/#{count_all} - because message is to big (is:#{real_message_size}/max:#{max_message_size} in MB)"
|
||||||
|
Rails.logger.info info
|
||||||
|
notice += "#{info}\n"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
# delete email from server after article was created
|
||||||
|
if process(channel, m.pop)
|
||||||
|
m.delete
|
||||||
|
count_fetched += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
disconnect
|
disconnect
|
||||||
|
@ -69,6 +156,11 @@ class Channel::Driver::Pop3 < Channel::EmailParser
|
||||||
Rails.logger.info ' - no message'
|
Rails.logger.info ' - no message'
|
||||||
end
|
end
|
||||||
Rails.logger.info 'done'
|
Rails.logger.info 'done'
|
||||||
|
{
|
||||||
|
result: 'ok',
|
||||||
|
fetched: count_fetched,
|
||||||
|
notice: notice,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def disconnect
|
def disconnect
|
||||||
|
|
|
@ -107,8 +107,8 @@ returns
|
||||||
def self.provider(email, password)
|
def self.provider(email, password)
|
||||||
# check domain based attributes
|
# check domain based attributes
|
||||||
provider_map = {
|
provider_map = {
|
||||||
google: {
|
google_imap: {
|
||||||
domain: 'gmail.com|googlemail.com|gmail.de',
|
domain: 'gmail|googlemail|google',
|
||||||
inbound: {
|
inbound: {
|
||||||
adapter: 'imap',
|
adapter: 'imap',
|
||||||
options: {
|
options: {
|
||||||
|
@ -153,6 +153,29 @@ returns
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
google_pop3: {
|
||||||
|
domain: 'gmail|googlemail|google',
|
||||||
|
inbound: {
|
||||||
|
adapter: 'pop3',
|
||||||
|
options: {
|
||||||
|
host: 'pop.gmail.com',
|
||||||
|
port: 995,
|
||||||
|
ssl: true,
|
||||||
|
user: email,
|
||||||
|
password: password,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
outbound: {
|
||||||
|
adapter: 'smtp',
|
||||||
|
options: {
|
||||||
|
host: 'smtp.gmail.com',
|
||||||
|
port: 25,
|
||||||
|
start_tls: true,
|
||||||
|
user: email,
|
||||||
|
password: password,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
provider_map
|
provider_map
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,13 +51,12 @@ returns on fail
|
||||||
user, domain = EmailHelper.parse_email(params[:email])
|
user, domain = EmailHelper.parse_email(params[:email])
|
||||||
|
|
||||||
if !user || !domain
|
if !user || !domain
|
||||||
result = {
|
return {
|
||||||
result: 'invalid',
|
result: 'invalid',
|
||||||
messages: {
|
messages: {
|
||||||
email: 'Invalid email.'
|
email: 'Invalid email.'
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# probe provider based settings
|
# probe provider based settings
|
||||||
|
@ -73,18 +72,22 @@ returns on fail
|
||||||
next if domain_to_check !~ /#{settings[:domain]}/i
|
next if domain_to_check !~ /#{settings[:domain]}/i
|
||||||
|
|
||||||
# probe inbound
|
# probe inbound
|
||||||
result = EmailHelper::Probe.inbound(settings[:inbound])
|
Rails.logger.info "INBOUND PROBE PROVIDER: #{settings[:inbound].inspect}"
|
||||||
return result if result[:result] != 'ok'
|
result_inbound = EmailHelper::Probe.inbound(settings[:inbound])
|
||||||
|
Rails.logger.info "INBOUND RESULT PROVIDER: #{result_inbound.inspect}"
|
||||||
|
next if result_inbound[:result] != 'ok'
|
||||||
|
|
||||||
# probe outbound
|
# probe outbound
|
||||||
result = EmailHelper::Probe.outbound(settings[:outbound], params[:email])
|
Rails.logger.info "OUTBOUND PROBE PROVIDER: #{settings[:outbound].inspect}"
|
||||||
return result if result[:result] != 'ok'
|
result_outbound = EmailHelper::Probe.outbound(settings[:outbound], params[:email])
|
||||||
|
Rails.logger.info "OUTBOUND RESULT PROVIDER: #{result_outbound.inspect}"
|
||||||
|
next if result_outbound[:result] != 'ok'
|
||||||
|
|
||||||
result = {
|
return {
|
||||||
result: 'ok',
|
result: 'ok',
|
||||||
|
content_messages: result_inbound[:content_messages],
|
||||||
setting: settings,
|
setting: settings,
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,25 +97,31 @@ returns on fail
|
||||||
inbound_mx = EmailHelper.provider_inbound_mx(user, params[:email], params[:password], mx_records)
|
inbound_mx = EmailHelper.provider_inbound_mx(user, params[:email], params[:password], mx_records)
|
||||||
inbound_guess = EmailHelper.provider_inbound_guess(user, params[:email], params[:password], domain)
|
inbound_guess = EmailHelper.provider_inbound_guess(user, params[:email], params[:password], domain)
|
||||||
inbound_map = inbound_mx + inbound_guess
|
inbound_map = inbound_mx + inbound_guess
|
||||||
settings = {}
|
result = {
|
||||||
|
result: 'ok',
|
||||||
|
setting: {}
|
||||||
|
}
|
||||||
success = false
|
success = false
|
||||||
inbound_map.each {|config|
|
inbound_map.each {|config|
|
||||||
Rails.logger.info "INBOUND PROBE: #{config.inspect}"
|
Rails.logger.info "INBOUND PROBE GUESS: #{config.inspect}"
|
||||||
result = EmailHelper::Probe.inbound( config )
|
result_inbound = EmailHelper::Probe.inbound(config)
|
||||||
Rails.logger.info "INBOUND RESULT: #{result.inspect}"
|
Rails.logger.info "INBOUND RESULT GUESS: #{result_inbound.inspect}"
|
||||||
|
|
||||||
next if result[:result] != 'ok'
|
next if result_inbound[:result] != 'ok'
|
||||||
|
|
||||||
|
success = true
|
||||||
|
result[:setting][:inbound] = config
|
||||||
|
result[:content_messages] = result_inbound[:content_messages]
|
||||||
|
|
||||||
success = true
|
|
||||||
settings[:inbound] = config
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# give up, no possible inbound found
|
||||||
if !success
|
if !success
|
||||||
result = {
|
return {
|
||||||
result: 'failed',
|
result: 'failed',
|
||||||
|
reason: 'inbound failed',
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# probe outbound
|
# probe outbound
|
||||||
|
@ -122,28 +131,26 @@ returns on fail
|
||||||
|
|
||||||
success = false
|
success = false
|
||||||
outbound_map.each {|config|
|
outbound_map.each {|config|
|
||||||
Rails.logger.info "OUTBOUND PROBE: #{config.inspect}"
|
Rails.logger.info "OUTBOUND PROBE GUESS: #{config.inspect}"
|
||||||
result = EmailHelper::Probe.outbound( config, params[:email] )
|
result_outbound = EmailHelper::Probe.outbound(config, params[:email])
|
||||||
Rails.logger.info "OUTBOUND RESULT: #{result.inspect}"
|
Rails.logger.info "OUTBOUND RESULT GUESS: #{result_outbound.inspect}"
|
||||||
|
|
||||||
next if result[:result] != 'ok'
|
next if result_outbound[:result] != 'ok'
|
||||||
|
|
||||||
success = true
|
success = true
|
||||||
settings[:outbound] = config
|
result[:setting][:outbound] = config
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# give up, no possible outbound found
|
||||||
if !success
|
if !success
|
||||||
result = {
|
return {
|
||||||
result: 'failed',
|
result: 'failed',
|
||||||
|
reason: 'outbound failed',
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
{
|
result
|
||||||
result: 'ok',
|
|
||||||
setting: settings,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -197,28 +204,25 @@ returns on fail
|
||||||
end
|
end
|
||||||
|
|
||||||
# connection test
|
# connection test
|
||||||
|
result_inbound = {}
|
||||||
begin
|
begin
|
||||||
|
|
||||||
require "channel/driver/#{adapter.to_filename}"
|
require "channel/driver/#{adapter.to_filename}"
|
||||||
|
|
||||||
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
||||||
driver_instance = driver_class.new
|
driver_instance = driver_class.new
|
||||||
driver_instance.fetch(params[:options], nil, 'check')
|
result_inbound = driver_instance.fetch(params[:options], nil, 'check')
|
||||||
|
|
||||||
rescue => e
|
rescue => e
|
||||||
result = {
|
return {
|
||||||
result: 'invalid',
|
result: 'invalid',
|
||||||
settings: params,
|
settings: params,
|
||||||
message: e.message,
|
message: e.message,
|
||||||
message_human: translation(e.message),
|
message_human: translation(e.message),
|
||||||
invalid_field: invalid_field(e.message),
|
invalid_field: invalid_field(e.message),
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
result = {
|
result_inbound
|
||||||
result: 'ok',
|
|
||||||
}
|
|
||||||
result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -291,10 +295,13 @@ returns on fail
|
||||||
body: "This is a Test Email of Zammad to verify if Zammad can send emails to an external address.\n\nIf you see this email, you can ignore and delete it.",
|
body: "This is a Test Email of Zammad to verify if Zammad can send emails to an external address.\n\nIf you see this email, you can ignore and delete it.",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
mail['X-Zammad-Ignore'] = 'true'
|
if subject
|
||||||
mail['X-Loop'] = 'yes'
|
mail['X-Zammad-Test-Message'] = subject
|
||||||
mail['Precedence'] = 'bulk'
|
end
|
||||||
mail['Auto-Submitted'] = 'auto-generated'
|
mail['X-Zammad-Ignore'] = 'true'
|
||||||
|
mail['X-Loop'] = 'yes'
|
||||||
|
mail['Precedence'] = 'bulk'
|
||||||
|
mail['Auto-Submitted'] = 'auto-generated'
|
||||||
|
|
||||||
# test connection
|
# test connection
|
||||||
begin
|
begin
|
||||||
|
@ -318,27 +325,24 @@ returns on fail
|
||||||
|
|
||||||
next if e.message !~ /#{Regexp.escape(key)}/i
|
next if e.message !~ /#{Regexp.escape(key)}/i
|
||||||
|
|
||||||
result = {
|
return {
|
||||||
result: 'ok',
|
result: 'ok',
|
||||||
settings: params,
|
settings: params,
|
||||||
notice: e.message,
|
notice: e.message,
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
result = {
|
return {
|
||||||
result: 'invalid',
|
result: 'invalid',
|
||||||
settings: params,
|
settings: params,
|
||||||
message: e.message,
|
message: e.message,
|
||||||
message_human: translation(e.message),
|
message_human: translation(e.message),
|
||||||
invalid_field: invalid_field(e.message),
|
invalid_field: invalid_field(e.message),
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
result = {
|
{
|
||||||
result: 'ok',
|
result: 'ok',
|
||||||
}
|
}
|
||||||
result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.invalid_field(message_backend)
|
def self.invalid_field(message_backend)
|
||||||
|
|
|
@ -81,14 +81,14 @@ or
|
||||||
sleep 5
|
sleep 5
|
||||||
|
|
||||||
# fetch mailbox
|
# fetch mailbox
|
||||||
found = nil
|
fetch_result = nil
|
||||||
|
|
||||||
begin
|
begin
|
||||||
require "channel/driver/#{adapter.to_filename}"
|
require "channel/driver/#{adapter.to_filename}"
|
||||||
|
|
||||||
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
||||||
driver_instance = driver_class.new
|
driver_instance = driver_class.new
|
||||||
found = driver_instance.fetch(params[:inbound][:options], self, 'verify', subject)
|
fetch_result = driver_instance.fetch(params[:inbound][:options], self, 'verify', subject)
|
||||||
rescue => e
|
rescue => e
|
||||||
result = {
|
result = {
|
||||||
result: 'invalid',
|
result: 'invalid',
|
||||||
|
@ -101,13 +101,10 @@ or
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
next if !found
|
next if !fetch_result
|
||||||
next if found != 'verify ok'
|
next if fetch_result[:result] != 'ok'
|
||||||
|
|
||||||
return {
|
|
||||||
result: 'ok',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return fetch_result
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,18 +32,18 @@ class EmailHelperTest < ActiveSupport::TestCase
|
||||||
password = 'some_pw'
|
password = 'some_pw'
|
||||||
map = EmailHelper.provider(email, password)
|
map = EmailHelper.provider(email, password)
|
||||||
|
|
||||||
assert_equal('imap', map[:google][:inbound][:adapter])
|
assert_equal('imap', map[:google_imap][:inbound][:adapter])
|
||||||
assert_equal('imap.gmail.com', map[:google][:inbound][:options][:host])
|
assert_equal('imap.gmail.com', map[:google_imap][:inbound][:options][:host])
|
||||||
assert_equal(993, map[:google][:inbound][:options][:port])
|
assert_equal(993, map[:google_imap][:inbound][:options][:port])
|
||||||
assert_equal(email, map[:google][:inbound][:options][:user])
|
assert_equal(email, map[:google_imap][:inbound][:options][:user])
|
||||||
assert_equal(password, map[:google][:inbound][:options][:password])
|
assert_equal(password, map[:google_imap][:inbound][:options][:password])
|
||||||
|
|
||||||
assert_equal('smtp', map[:google][:outbound][:adapter])
|
assert_equal('smtp', map[:google_imap][:outbound][:adapter])
|
||||||
assert_equal('smtp.gmail.com', map[:google][:outbound][:options][:host])
|
assert_equal('smtp.gmail.com', map[:google_imap][:outbound][:options][:host])
|
||||||
assert_equal(25, map[:google][:outbound][:options][:port])
|
assert_equal(25, map[:google_imap][:outbound][:options][:port])
|
||||||
assert_equal(true, map[:google][:outbound][:options][:start_tls])
|
assert_equal(true, map[:google_imap][:outbound][:options][:start_tls])
|
||||||
assert_equal(email, map[:google][:outbound][:options][:user])
|
assert_equal(email, map[:google_imap][:outbound][:options][:user])
|
||||||
assert_equal(password, map[:google][:outbound][:options][:password])
|
assert_equal(password, map[:google_imap][:outbound][:options][:password])
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -431,7 +431,7 @@ class EmailHelperTest < ActiveSupport::TestCase
|
||||||
assert_equal('invalid', result[:result])
|
assert_equal('invalid', result[:result])
|
||||||
assert_not(result[:setting])
|
assert_not(result[:setting])
|
||||||
|
|
||||||
# realtest - test I
|
# realtest - test I, with imap
|
||||||
if !ENV['EMAILHELPER_MAILBOX_1']
|
if !ENV['EMAILHELPER_MAILBOX_1']
|
||||||
fail "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@znuny.com:somepass'"
|
fail "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@znuny.com:somepass'"
|
||||||
end
|
end
|
||||||
|
@ -446,11 +446,26 @@ class EmailHelperTest < ActiveSupport::TestCase
|
||||||
assert_equal('arber.znuny.com', result[:setting][:inbound][:options][:host])
|
assert_equal('arber.znuny.com', result[:setting][:inbound][:options][:host])
|
||||||
assert_equal('arber.znuny.com', result[:setting][:outbound][:options][:host])
|
assert_equal('arber.znuny.com', result[:setting][:outbound][:options][:host])
|
||||||
|
|
||||||
|
# realtest - test II, gmail with only pop3
|
||||||
|
if !ENV['EMAILHELPER_MAILBOX_2']
|
||||||
|
fail "Need EMAILHELPER_MAILBOX_2 as ENV variable like export EMAILHELPER_MAILBOX_2='hansb36621@gmail.com:somepass'"
|
||||||
|
end
|
||||||
|
mailbox_user = ENV['EMAILHELPER_MAILBOX_2'].split(':')[0]
|
||||||
|
mailbox_password = ENV['EMAILHELPER_MAILBOX_2'].split(':')[1]
|
||||||
|
|
||||||
|
result = EmailHelper::Probe.full(
|
||||||
|
email: mailbox_user,
|
||||||
|
password: mailbox_password,
|
||||||
|
)
|
||||||
|
assert_equal('ok', result[:result])
|
||||||
|
assert_equal('pop.gmail.com', result[:setting][:inbound][:options][:host])
|
||||||
|
assert_equal('smtp.gmail.com', result[:setting][:outbound][:options][:host])
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'zz verify' do
|
test 'zz verify' do
|
||||||
|
|
||||||
# realtest - test I
|
# realtest - test I, with imap
|
||||||
if !ENV['EMAILHELPER_MAILBOX_1']
|
if !ENV['EMAILHELPER_MAILBOX_1']
|
||||||
fail "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@znuny.com:somepass'"
|
fail "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@znuny.com:somepass'"
|
||||||
end
|
end
|
||||||
|
@ -481,6 +496,39 @@ class EmailHelperTest < ActiveSupport::TestCase
|
||||||
sender: mailbox_user,
|
sender: mailbox_user,
|
||||||
)
|
)
|
||||||
assert_equal('ok', result[:result])
|
assert_equal('ok', result[:result])
|
||||||
|
|
||||||
|
# realtest - test II, gmail with pop3
|
||||||
|
if !ENV['EMAILHELPER_MAILBOX_2']
|
||||||
|
fail "Need EMAILHELPER_MAILBOX_2 as ENV variable like export EMAILHELPER_MAILBOX_2='hansb36621@gmail.com:somepass'"
|
||||||
|
end
|
||||||
|
mailbox_user = ENV['EMAILHELPER_MAILBOX_2'].split(':')[0]
|
||||||
|
mailbox_password = ENV['EMAILHELPER_MAILBOX_2'].split(':')[1]
|
||||||
|
user, domain = EmailHelper.parse_email(mailbox_user)
|
||||||
|
result = EmailHelper::Verify.email(
|
||||||
|
inbound: {
|
||||||
|
adapter: 'pop3',
|
||||||
|
options: {
|
||||||
|
host: 'pop.gmail.com',
|
||||||
|
port: 995,
|
||||||
|
ssl: true,
|
||||||
|
user: mailbox_user,
|
||||||
|
password: mailbox_password,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
outbound: {
|
||||||
|
adapter: 'smtp',
|
||||||
|
options: {
|
||||||
|
host: 'smtp.gmail.com',
|
||||||
|
port: 25,
|
||||||
|
start_tls: true,
|
||||||
|
user: mailbox_user,
|
||||||
|
password: mailbox_password,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sender: mailbox_user,
|
||||||
|
)
|
||||||
|
assert_equal('ok', result[:result])
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue