Some small improvements to email channel management.
This commit is contained in:
parent
64da02366c
commit
71c774cb99
13 changed files with 259 additions and 116 deletions
|
@ -204,8 +204,15 @@ class App.ControllerGenericDestroyConfirm extends App.ControllerModal
|
||||||
|
|
||||||
onSubmit: (e) ->
|
onSubmit: (e) ->
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@hide()
|
@item.destroy(
|
||||||
@item.destroy()
|
done: =>
|
||||||
|
if @callback
|
||||||
|
@callback()
|
||||||
|
@hide()
|
||||||
|
fail: =>
|
||||||
|
@log 'errors'
|
||||||
|
@hide()
|
||||||
|
)
|
||||||
|
|
||||||
class App.ControllerDrox extends App.Controller
|
class App.ControllerDrox extends App.Controller
|
||||||
constructor: (params) ->
|
constructor: (params) ->
|
||||||
|
|
|
@ -411,7 +411,7 @@ class App.ChannelEmailAccountWizard extends App.Controller
|
||||||
configure_attributes: configureAttributesOutbound
|
configure_attributes: configureAttributesOutbound
|
||||||
className: ''
|
className: ''
|
||||||
params:
|
params:
|
||||||
adapter: @account.outbound.adapter || 'sendmail'
|
adapter: @account.outbound.adapter || 'smtp'
|
||||||
)
|
)
|
||||||
@toggleOutboundAdapter()
|
@toggleOutboundAdapter()
|
||||||
|
|
||||||
|
@ -419,8 +419,8 @@ class App.ChannelEmailAccountWizard extends App.Controller
|
||||||
configureAttributesInbound = [
|
configureAttributesInbound = [
|
||||||
{ name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: { imap: 'imap', pop3: 'pop3' } },
|
{ name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: { imap: 'imap', pop3: 'pop3' } },
|
||||||
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
|
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
|
||||||
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
|
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autocomplete: 'off', },
|
||||||
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, single: true },
|
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||||
]
|
]
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
el: @$('.base-inbound-settings'),
|
el: @$('.base-inbound-settings'),
|
||||||
|
@ -439,13 +439,13 @@ class App.ChannelEmailAccountWizard extends App.Controller
|
||||||
channel_used['options']['password'] = @account['meta']['password']
|
channel_used['options']['password'] = @account['meta']['password']
|
||||||
|
|
||||||
# show used backend
|
# show used backend
|
||||||
@el.find('.base-outbound-settings').html('')
|
@$('.base-outbound-settings').html('')
|
||||||
adapter = @$('.js-outbound [name=adapter]').val()
|
adapter = @$('.js-outbound [name=adapter]').val()
|
||||||
if adapter is 'smtp'
|
if adapter is 'smtp'
|
||||||
configureAttributesOutbound = [
|
configureAttributesOutbound = [
|
||||||
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true },
|
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true },
|
||||||
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false },
|
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'off', },
|
||||||
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, single: true },
|
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||||
]
|
]
|
||||||
@form = new App.ControllerForm(
|
@form = new App.ControllerForm(
|
||||||
el: @$('.base-outbound-settings')
|
el: @$('.base-outbound-settings')
|
||||||
|
@ -504,7 +504,8 @@ class App.ChannelEmailAccountWizard extends App.Controller
|
||||||
params = @formParam(e.target)
|
params = @formParam(e.target)
|
||||||
|
|
||||||
# let backend know about the channel
|
# let backend know about the channel
|
||||||
params.channel_id = @channel.id
|
if @channel
|
||||||
|
params.channel_id = @channel.id
|
||||||
|
|
||||||
@disable(e)
|
@disable(e)
|
||||||
|
|
||||||
|
@ -523,17 +524,26 @@ class App.ChannelEmailAccountWizard extends App.Controller
|
||||||
@account.inbound = params
|
@account.inbound = params
|
||||||
|
|
||||||
@showSlide('js-outbound')
|
@showSlide('js-outbound')
|
||||||
|
|
||||||
|
# fill user / password based on inbound settings
|
||||||
if !@channel
|
if !@channel
|
||||||
@$('.js-outbound [name="options::user"]').val( @account['meta']['email'] )
|
if @account['inbound']['options']
|
||||||
@$('.js-outbound [name="options::password"]').val( @account['meta']['password'] )
|
@$('.js-outbound [name="options::host"]').val( @account['inbound']['options']['host'] )
|
||||||
|
@$('.js-outbound [name="options::user"]').val( @account['inbound']['options']['user'] )
|
||||||
|
@$('.js-outbound [name="options::password"]').val( @account['inbound']['options']['password'] )
|
||||||
|
else
|
||||||
|
@$('.js-outbound [name="options::user"]').val( @account['meta']['email'] )
|
||||||
|
@$('.js-outbound [name="options::password"]').val( @account['meta']['password'] )
|
||||||
|
|
||||||
else
|
else
|
||||||
@showSlide('js-inbound')
|
@showSlide('js-inbound')
|
||||||
@showAlert('js-inbound', data.message_human || data.message )
|
@showAlert('js-inbound', data.message_human || data.message )
|
||||||
|
@showInvalidField('js-inbound', data.invalid_field)
|
||||||
@enable(e)
|
@enable(e)
|
||||||
fail: =>
|
fail: =>
|
||||||
@showSlide('js-inbound')
|
@showSlide('js-inbound')
|
||||||
@showAlert('js-inbound', data.message_human || data.message )
|
@showAlert('js-inbound', data.message_human || data.message )
|
||||||
|
@showInvalidField('js-inbound', data.invalid_field)
|
||||||
@enable(e)
|
@enable(e)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -550,7 +560,8 @@ class App.ChannelEmailAccountWizard extends App.Controller
|
||||||
params['email'] = email_addresses[0].email
|
params['email'] = email_addresses[0].email
|
||||||
|
|
||||||
# let backend know about the channel
|
# let backend know about the channel
|
||||||
params.channel_id = @channel.id
|
if @channel
|
||||||
|
params.channel_id = @channel.id
|
||||||
|
|
||||||
@disable(e)
|
@disable(e)
|
||||||
|
|
||||||
|
@ -572,10 +583,12 @@ class App.ChannelEmailAccountWizard extends App.Controller
|
||||||
else
|
else
|
||||||
@showSlide('js-outbound')
|
@showSlide('js-outbound')
|
||||||
@showAlert('js-outbound', data.message_human || data.message )
|
@showAlert('js-outbound', data.message_human || data.message )
|
||||||
|
@showInvalidField('js-outbound', data.invalid_field)
|
||||||
@enable(e)
|
@enable(e)
|
||||||
fail: =>
|
fail: =>
|
||||||
@showSlide('js-outbound')
|
@showSlide('js-outbound')
|
||||||
@showAlert('js-outbound', data.message_human || data.message )
|
@showAlert('js-outbound', data.message_human || data.message )
|
||||||
|
@showInvalidField('js-outbound', data.invalid_field)
|
||||||
@enable(e)
|
@enable(e)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -599,24 +612,29 @@ class App.ChannelEmailAccountWizard extends App.Controller
|
||||||
processData: true
|
processData: true
|
||||||
success: (data, status, xhr) =>
|
success: (data, status, xhr) =>
|
||||||
if data.result is 'ok'
|
if data.result is 'ok'
|
||||||
@el.remove()
|
@el.modal('hide')
|
||||||
else
|
else
|
||||||
if count is 2
|
if data.source is 'inbound' || data.source is 'outbound'
|
||||||
@showAlert('js-verify', data.message_human || data.message )
|
@showSlide("js-#{data.source}")
|
||||||
@delay(
|
@showAlert("js-#{data.source}", data.message_human || data.message )
|
||||||
=>
|
@showInvalidField("js-#{data.source}", data.invalid_field)
|
||||||
@showSlide('js-intro')
|
|
||||||
@showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.' )
|
|
||||||
|
|
||||||
2300
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
if data.subject && @account
|
if count is 2
|
||||||
@account.subject = data.subject
|
@showAlert('js-verify', data.message_human || data.message )
|
||||||
@verify( @account, count + 1 )
|
@delay(
|
||||||
|
=>
|
||||||
|
@showSlide('js-intro')
|
||||||
|
@showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.')
|
||||||
|
|
||||||
|
2300
|
||||||
|
)
|
||||||
|
else
|
||||||
|
if data.subject && @account
|
||||||
|
@account.subject = data.subject
|
||||||
|
@verify( @account, count + 1 )
|
||||||
fail: =>
|
fail: =>
|
||||||
@showSlide('js-intro')
|
@showSlide('js-intro')
|
||||||
@showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.' )
|
@showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.')
|
||||||
)
|
)
|
||||||
|
|
||||||
goToSlide: (e) =>
|
goToSlide: (e) =>
|
||||||
|
@ -644,6 +662,13 @@ class App.ChannelEmailAccountWizard extends App.Controller
|
||||||
@formEnable(e)
|
@formEnable(e)
|
||||||
@$('.wizard-controls .btn').attr('disabled', false)
|
@$('.wizard-controls .btn').attr('disabled', false)
|
||||||
|
|
||||||
|
showInvalidField: (screen, fields) =>
|
||||||
|
@$(".#{screen}").find('.form-group').removeClass('has-error')
|
||||||
|
return if !fields
|
||||||
|
for field, type of fields
|
||||||
|
if type
|
||||||
|
@$(".#{screen}").find("[name=\"options::#{field}\"]").closest('.form-group').addClass('has-error')
|
||||||
|
|
||||||
hide: (e) =>
|
hide: (e) =>
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@el.modal('hide')
|
@el.modal('hide')
|
||||||
|
@ -727,8 +752,8 @@ class App.ChannelEmailNotificationWizard extends App.Controller
|
||||||
if adapter is 'smtp'
|
if adapter is 'smtp'
|
||||||
configureAttributesOutbound = [
|
configureAttributesOutbound = [
|
||||||
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true },
|
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true },
|
||||||
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false },
|
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'off' },
|
||||||
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, single: true },
|
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||||
]
|
]
|
||||||
@form = new App.ControllerForm(
|
@form = new App.ControllerForm(
|
||||||
el: @$('.base-outbound-settings')
|
el: @$('.base-outbound-settings')
|
||||||
|
|
|
@ -466,8 +466,8 @@ class EmailNotification extends App.ControllerContent
|
||||||
if adapter is 'smtp'
|
if adapter is 'smtp'
|
||||||
configureAttributesOutbound = [
|
configureAttributesOutbound = [
|
||||||
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true, default: (channel_used['options']&&channel_used['options']['host']) },
|
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true, default: (channel_used['options']&&channel_used['options']['host']) },
|
||||||
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, default: (channel_used['options']&&channel_used['options']['user']) },
|
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'off', default: (channel_used['options']&&channel_used['options']['user']) },
|
||||||
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, single: true, default: (channel_used['options']&&channel_used['options']['password']) },
|
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password', single: true, default: (channel_used['options']&&channel_used['options']['password']) },
|
||||||
]
|
]
|
||||||
@form = new App.ControllerForm(
|
@form = new App.ControllerForm(
|
||||||
el: @$('.base-outbound-settings')
|
el: @$('.base-outbound-settings')
|
||||||
|
@ -696,7 +696,7 @@ class ChannelEmail extends App.ControllerContent
|
||||||
adapters =
|
adapters =
|
||||||
sendmail: 'Local MTA (Sendmail/Postfix/Exim/...) - use server setup'
|
sendmail: 'Local MTA (Sendmail/Postfix/Exim/...) - use server setup'
|
||||||
smtp: 'SMTP - configure your own outgoing SMTP settings'
|
smtp: 'SMTP - configure your own outgoing SMTP settings'
|
||||||
adapter_used = 'sendmail'
|
adapter_used = 'smtp'
|
||||||
configureAttributesOutbound = [
|
configureAttributesOutbound = [
|
||||||
{ name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: adapters , default: adapter_used },
|
{ name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: adapters , default: adapter_used },
|
||||||
]
|
]
|
||||||
|
@ -710,8 +710,8 @@ class ChannelEmail extends App.ControllerContent
|
||||||
configureAttributesInbound = [
|
configureAttributesInbound = [
|
||||||
{ name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: { imap: 'IMAP', pop3: 'POP3' } },
|
{ name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: { imap: 'IMAP', pop3: 'POP3' } },
|
||||||
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
|
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
|
||||||
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
|
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autocomplete: 'off', },
|
||||||
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, single: true },
|
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||||
]
|
]
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
el: @$('.base-inbound-settings'),
|
el: @$('.base-inbound-settings'),
|
||||||
|
@ -727,12 +727,13 @@ class ChannelEmail extends App.ControllerContent
|
||||||
channel_used['options']['password'] = @account['meta']['password']
|
channel_used['options']['password'] = @account['meta']['password']
|
||||||
|
|
||||||
# show used backend
|
# show used backend
|
||||||
|
@$('.base-outbound-settings').html('')
|
||||||
adapter = @$('.js-outbound [name=adapter]').val()
|
adapter = @$('.js-outbound [name=adapter]').val()
|
||||||
if adapter is 'smtp'
|
if adapter is 'smtp'
|
||||||
configureAttributesOutbound = [
|
configureAttributesOutbound = [
|
||||||
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true, default: (channel_used['options']&&channel_used['options']['host']) },
|
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true, default: (channel_used['options']&&channel_used['options']['host']) },
|
||||||
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, default: (channel_used['options']&&channel_used['options']['user']) },
|
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'off', default: (channel_used['options']&&channel_used['options']['user']) },
|
||||||
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, single: true, default: (channel_used['options']&&channel_used['options']['password']) },
|
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password', single: true, default: (channel_used['options']&&channel_used['options']['password']) },
|
||||||
]
|
]
|
||||||
@form = new App.ControllerForm(
|
@form = new App.ControllerForm(
|
||||||
el: @$('.base-outbound-settings')
|
el: @$('.base-outbound-settings')
|
||||||
|
@ -764,6 +765,9 @@ class ChannelEmail extends App.ControllerContent
|
||||||
for key, value of data.setting
|
for key, value of data.setting
|
||||||
@account[key] = value
|
@account[key] = value
|
||||||
@verify(@account)
|
@verify(@account)
|
||||||
|
else if data.result is 'duplicate'
|
||||||
|
@showSlide('js-intro')
|
||||||
|
@showAlert('js-intro', 'Account already exists!' )
|
||||||
else
|
else
|
||||||
@showSlide('js-inbound')
|
@showSlide('js-inbound')
|
||||||
@showAlert('js-inbound', 'Unable to detect your server settings. Manual configuration needed.' )
|
@showAlert('js-inbound', 'Unable to detect your server settings. Manual configuration needed.' )
|
||||||
|
@ -798,16 +802,26 @@ class ChannelEmail extends App.ControllerContent
|
||||||
@account.inbound = params
|
@account.inbound = params
|
||||||
|
|
||||||
@showSlide('js-outbound')
|
@showSlide('js-outbound')
|
||||||
@$('.js-outbound [name="options::user"]').val( @account['meta']['email'] )
|
|
||||||
@$('.js-outbound [name="options::password"]').val( @account['meta']['password'] )
|
# fill user / password based on inbound settings
|
||||||
|
if !@channel
|
||||||
|
if @account['inbound']['options']
|
||||||
|
@$('.js-outbound [name="options::host"]').val( @account['inbound']['options']['host'] )
|
||||||
|
@$('.js-outbound [name="options::user"]').val( @account['inbound']['options']['user'] )
|
||||||
|
@$('.js-outbound [name="options::password"]').val( @account['inbound']['options']['password'] )
|
||||||
|
else
|
||||||
|
@$('.js-outbound [name="options::user"]').val( @account['meta']['email'] )
|
||||||
|
@$('.js-outbound [name="options::password"]').val( @account['meta']['password'] )
|
||||||
|
|
||||||
else
|
else
|
||||||
@showSlide('js-inbound')
|
@showSlide('js-inbound')
|
||||||
@showAlert('js-inbound', data.message_human || data.message )
|
@showAlert('js-inbound', data.message_human || data.message )
|
||||||
|
@showInvalidField('js-inbound', data.invalid_field)
|
||||||
@enable(e)
|
@enable(e)
|
||||||
fail: =>
|
fail: =>
|
||||||
@showSlide('js-inbound')
|
@showSlide('js-inbound')
|
||||||
@showAlert('js-inbound', data.message_human || data.message )
|
@showAlert('js-inbound', data.message_human || data.message )
|
||||||
|
@showInvalidField('js-inbound', data.invalid_field)
|
||||||
@enable(e)
|
@enable(e)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -837,10 +851,12 @@ class ChannelEmail extends App.ControllerContent
|
||||||
else
|
else
|
||||||
@showSlide('js-outbound')
|
@showSlide('js-outbound')
|
||||||
@showAlert('js-outbound', data.message_human || data.message )
|
@showAlert('js-outbound', data.message_human || data.message )
|
||||||
|
@showInvalidField('js-outbound', data.invalid_field)
|
||||||
@enable(e)
|
@enable(e)
|
||||||
fail: =>
|
fail: =>
|
||||||
@showSlide('js-outbound')
|
@showSlide('js-outbound')
|
||||||
@showAlert('js-outbound', data.message_human || data.message )
|
@showAlert('js-outbound', data.message_human || data.message )
|
||||||
|
@showInvalidField('js-outbound', data.invalid_field)
|
||||||
@enable(e)
|
@enable(e)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -857,19 +873,24 @@ 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 2
|
if data.source is 'inbound' || data.source is 'outbound'
|
||||||
@showAlert('js-verify', data.message_human || data.message )
|
@showSlide("js-#{data.source}")
|
||||||
@delay(
|
@showAlert("js-#{data.source}", data.message_human || data.message )
|
||||||
=>
|
@showInvalidField("js-#{data.source}", data.invalid_field)
|
||||||
@showSlide('js-intro')
|
|
||||||
@showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.' )
|
|
||||||
|
|
||||||
2300
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
if data.subject && @account
|
if count is 2
|
||||||
@account.subject = data.subject
|
@showAlert('js-verify', data.message_human || data.message )
|
||||||
@verify( @account, count + 1 )
|
@delay(
|
||||||
|
=>
|
||||||
|
@showSlide('js-intro')
|
||||||
|
@showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.' )
|
||||||
|
|
||||||
|
2300
|
||||||
|
)
|
||||||
|
else
|
||||||
|
if data.subject && @account
|
||||||
|
@account.subject = data.subject
|
||||||
|
@verify( @account, count + 1 )
|
||||||
fail: =>
|
fail: =>
|
||||||
@showSlide('js-intro')
|
@showSlide('js-intro')
|
||||||
@showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.' )
|
@showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.' )
|
||||||
|
@ -900,6 +921,13 @@ class ChannelEmail extends App.ControllerContent
|
||||||
@formEnable(e)
|
@formEnable(e)
|
||||||
@$('.wizard-controls .btn').attr('disabled', false)
|
@$('.wizard-controls .btn').attr('disabled', false)
|
||||||
|
|
||||||
|
showInvalidField: (screen, fields) =>
|
||||||
|
@$(".#{screen}").find('.form-group').removeClass('has-error')
|
||||||
|
return if !fields
|
||||||
|
for field, type of fields
|
||||||
|
if type
|
||||||
|
@$(".#{screen}").find("[name=\"options::#{field}\"]").closest('.form-group').addClass('has-error')
|
||||||
|
|
||||||
App.Config.set( 'getting_started/channel/email', ChannelEmail, 'Routes' )
|
App.Config.set( 'getting_started/channel/email', ChannelEmail, 'Routes' )
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><%- @T('Email') %></label>
|
<label><%- @T('Email') %></label>
|
||||||
<input type="email" class="form-control" value="" name="email" placeholder="<%- @Ti('support@example.com') %>" required>
|
<input type="email" class="form-control" value="" name="email" placeholder="<%- @Ti('support@example.com') %>" required autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><%- @T('Password') %></label>
|
<label><%- @T('Password') %></label>
|
||||||
<input type="password" class="form-control" name="password" value="" required>
|
<input type="password" class="form-control" name="password" value="" required autocomplete="new-password">
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<svg class="wizard-logo icon-full-logo"><use xlink:href="#icon-full-logo" /></svg>
|
<svg class="wizard-logo icon-full-logo"><use xlink:href="#icon-full-logo" /></svg>
|
||||||
|
|
||||||
<form class="setup wizard js-intro">
|
<form class="setup wizard js-intro">
|
||||||
|
<input type="password" style="display:none"/><!-- dummy to prevent chrome to ask for password save -->
|
||||||
<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">
|
||||||
|
@ -13,11 +14,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><%- @T('Email') %></label>
|
<label><%- @T('Email') %></label>
|
||||||
<input type="email" class="form-control" value="" name="email" placeholder="<%- @Ti('support@example.com') %>" required>
|
<input type="email" class="form-control" value="" name="email" placeholder="<%- @Ti('support@example.com') %>" required autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><%- @T('Password') %></label>
|
<label><%- @T('Password') %></label>
|
||||||
<input type="password" class="form-control" name="password" value="" required>
|
<input type="password" class="form-control" name="password" value="" required autocomplete="new-password">
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
@ -63,6 +64,7 @@
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form class="setup wizard hide js-inbound">
|
<form class="setup wizard hide js-inbound">
|
||||||
|
<input type="password" style="display:none"/><!-- dummy to prevent chrome to ask for password save -->
|
||||||
<div class="wizard-slide">
|
<div class="wizard-slide">
|
||||||
<h2><%- @T('Email Inbound') %></h2>
|
<h2><%- @T('Email Inbound') %></h2>
|
||||||
<div class="wizard-body vertical justified">
|
<div class="wizard-body vertical justified">
|
||||||
|
@ -77,6 +79,7 @@
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form class="setup wizard hide js-outbound">
|
<form class="setup wizard hide js-outbound">
|
||||||
|
<input type="password" style="display:none"/><!-- dummy to prevent chrome to ask for password save -->
|
||||||
<div class="wizard-slide">
|
<div class="wizard-slide">
|
||||||
<h2><%- @T('Email Outbound') %></h2>
|
<h2><%- @T('Email Outbound') %></h2>
|
||||||
<div class="wizard-body vertical justified">
|
<div class="wizard-body vertical justified">
|
||||||
|
|
|
@ -5,10 +5,11 @@ class ChannelsController < ApplicationController
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
Format:
|
Resource:
|
||||||
JSON
|
GET /api/v1/channels/#{id}.json
|
||||||
|
|
||||||
|
Response example 1:
|
||||||
|
|
||||||
Example:
|
|
||||||
{
|
{
|
||||||
"id":1,
|
"id":1,
|
||||||
"area":"Email::Account",
|
"area":"Email::Account",
|
||||||
|
@ -38,6 +39,8 @@ Example:
|
||||||
"created_by_id":2,
|
"created_by_id":2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Response example 2:
|
||||||
|
|
||||||
{
|
{
|
||||||
"id":1,
|
"id":1,
|
||||||
"area":"Twitter::Account",
|
"area":"Twitter::Account",
|
||||||
|
@ -84,49 +87,6 @@ Example:
|
||||||
"created_by_id":2,
|
"created_by_id":2,
|
||||||
}
|
}
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
Resource:
|
|
||||||
GET /api/v1/channels.json
|
|
||||||
|
|
||||||
Response:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"area":"Email::Account",
|
|
||||||
...
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 2,
|
|
||||||
"area":"Email::Account",
|
|
||||||
...
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
Test:
|
|
||||||
curl http://localhost/api/v1/channels.json -v -u #{login}:#{password}
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def index
|
|
||||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
|
||||||
model_index_render(Channel, params)
|
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
Resource:
|
|
||||||
GET /api/v1/channels/#{id}.json
|
|
||||||
|
|
||||||
Response:
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"area":"Email::Account",
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
curl http://localhost/api/v1/channels/#{id}.json -v -u #{login}:#{password}
|
curl http://localhost/api/v1/channels/#{id}.json -v -u #{login}:#{password}
|
||||||
|
|
||||||
|
@ -134,6 +94,7 @@ curl http://localhost/api/v1/channels/#{id}.json -v -u #{login}:#{password}
|
||||||
|
|
||||||
def show
|
def show
|
||||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||||
|
return if !check_access
|
||||||
model_show_render(Channel, params)
|
model_show_render(Channel, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -230,6 +191,7 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
|
||||||
|
|
||||||
def update
|
def update
|
||||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||||
|
return if !check_access
|
||||||
model_update_render(Channel, params)
|
model_update_render(Channel, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -248,6 +210,7 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||||
|
return if !check_access
|
||||||
model_destory_render(Channel, params)
|
model_destory_render(Channel, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -256,9 +219,11 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
|
||||||
|
|
||||||
assets = {}
|
assets = {}
|
||||||
Channel.all.each {|channel|
|
Channel.all.each {|channel|
|
||||||
|
next if channel.preferences && channel.preferences[:online_service_disable]
|
||||||
assets = channel.assets(assets)
|
assets = channel.assets(assets)
|
||||||
}
|
}
|
||||||
EmailAddress.all.each {|email_address|
|
EmailAddress.all.each {|email_address|
|
||||||
|
next if email_address.preferences && email_address.preferences[:online_service_disable]
|
||||||
assets = email_address.assets(assets)
|
assets = email_address.assets(assets)
|
||||||
}
|
}
|
||||||
render json: {
|
render json: {
|
||||||
|
@ -290,6 +255,9 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
|
||||||
# check admin permissions
|
# check admin permissions
|
||||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||||
|
|
||||||
|
# verify access
|
||||||
|
return if !check_access(params[:channel_id]) if params[:channel_id]
|
||||||
|
|
||||||
# connection test
|
# connection test
|
||||||
render json: EmailHelper::Probe.outbound(params, params[:email])
|
render json: EmailHelper::Probe.outbound(params, params[:email])
|
||||||
end
|
end
|
||||||
|
@ -299,6 +267,9 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
|
||||||
# check admin permissions
|
# check admin permissions
|
||||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||||
|
|
||||||
|
# verify access
|
||||||
|
return if !check_access(params[:channel_id]) if params[:channel_id]
|
||||||
|
|
||||||
# connection test
|
# connection test
|
||||||
result = EmailHelper::Probe.inbound(params)
|
result = EmailHelper::Probe.inbound(params)
|
||||||
|
|
||||||
|
@ -317,6 +288,9 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
|
||||||
email = email.downcase
|
email = email.downcase
|
||||||
channel_id = params[:channel_id]
|
channel_id = params[:channel_id]
|
||||||
|
|
||||||
|
# verify access
|
||||||
|
return if !check_access(channel_id) if channel_id
|
||||||
|
|
||||||
# check account duplicate
|
# check account duplicate
|
||||||
return if email_account_duplicate?({ setting: { inbound: params[:inbound] } }, channel_id)
|
return if email_account_duplicate?({ setting: { inbound: params[:inbound] } }, channel_id)
|
||||||
|
|
||||||
|
@ -359,6 +333,10 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
|
||||||
inbound: params[:inbound],
|
inbound: params[:inbound],
|
||||||
outbound: params[:outbound],
|
outbound: params[:outbound],
|
||||||
},
|
},
|
||||||
|
last_log_in: nil,
|
||||||
|
last_log_out: nil,
|
||||||
|
status_in: 'ok',
|
||||||
|
status_out: 'ok',
|
||||||
active: true,
|
active: true,
|
||||||
group_id: Group.first.id,
|
group_id: Group.first.id,
|
||||||
)
|
)
|
||||||
|
@ -394,6 +372,8 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
|
||||||
|
|
||||||
def email_notification
|
def email_notification
|
||||||
|
|
||||||
|
return if !check_online_service
|
||||||
|
|
||||||
# check admin permissions
|
# check admin permissions
|
||||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||||
|
|
||||||
|
@ -455,4 +435,23 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_online_service
|
||||||
|
return true if !Setting.get('system_online_service')
|
||||||
|
response_access_deny
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_access(id = nil)
|
||||||
|
if !id
|
||||||
|
id = params[:id]
|
||||||
|
end
|
||||||
|
return true if !Setting.get('system_online_service')
|
||||||
|
|
||||||
|
channel = Channel.find(id)
|
||||||
|
return true if channel.preferences && !channel.preferences[:online_service_disable]
|
||||||
|
|
||||||
|
response_access_deny
|
||||||
|
false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -91,6 +91,7 @@ class SettingsController < ApplicationController
|
||||||
# DELETE /settings/1
|
# DELETE /settings/1
|
||||||
def destroy
|
def destroy
|
||||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||||
|
return if !check_access
|
||||||
model_destory_render(Setting, params)
|
model_destory_render(Setting, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
class Channel < ApplicationModel
|
class Channel < ApplicationModel
|
||||||
store :options
|
store :options
|
||||||
|
store :preferences
|
||||||
|
|
||||||
after_create :email_address_check
|
after_create :email_address_check
|
||||||
after_update :email_address_check
|
after_update :email_address_check
|
||||||
|
|
|
@ -10,7 +10,6 @@ Zammad::Application.routes.draw do
|
||||||
match api_path + '/channels/email_notification', to: 'channels#email_notification', via: :post
|
match api_path + '/channels/email_notification', to: 'channels#email_notification', via: :post
|
||||||
|
|
||||||
# channels
|
# channels
|
||||||
match api_path + '/channels', to: 'channels#index', via: :get
|
|
||||||
match api_path + '/channels/:id', to: 'channels#show', via: :get
|
match api_path + '/channels/:id', to: 'channels#show', via: :get
|
||||||
match api_path + '/channels', to: 'channels#create', via: :post
|
match api_path + '/channels', to: 'channels#create', via: :post
|
||||||
match api_path + '/channels/:id', to: 'channels#update', via: :put
|
match api_path + '/channels/:id', to: 'channels#update', via: :put
|
||||||
|
|
53
db/migrate/20150828000001_add_setting_online_service2.rb
Normal file
53
db/migrate/20150828000001_add_setting_online_service2.rb
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
class AddSettingOnlineService2 < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
|
||||||
|
# add preferences
|
||||||
|
add_column :channels, :preferences, :string, limit: 2000, null: true
|
||||||
|
Channel.reset_column_information
|
||||||
|
Channel.where(area: 'Email::Notification').each {|channel|
|
||||||
|
channel.preferences[:online_service_disable] = true
|
||||||
|
channel.save
|
||||||
|
}
|
||||||
|
Channel.where(area: 'Email::Account').each {|channel|
|
||||||
|
next if !channel.options
|
||||||
|
next if !channel.options[:options]
|
||||||
|
next if !channel.options[:options][:host]
|
||||||
|
next if channel.options[:options][:host] !~ /zammad/i
|
||||||
|
channel.preferences[:online_service_disable] = true
|
||||||
|
channel.save
|
||||||
|
}
|
||||||
|
|
||||||
|
add_column :email_addresses, :preferences, :string, limit: 2000, null: true
|
||||||
|
EmailAddress.reset_column_information
|
||||||
|
EmailAddress.all.each {|email_address|
|
||||||
|
next if email_address.email !~ /zammad/i
|
||||||
|
email_address.preferences[:online_service_disable] = true
|
||||||
|
email_address.save
|
||||||
|
}
|
||||||
|
|
||||||
|
# return if it's a new setup
|
||||||
|
return if !Setting.find_by(name: 'system_init_done')
|
||||||
|
|
||||||
|
Setting.create_or_update(
|
||||||
|
title: 'Block Notifications',
|
||||||
|
name: 'send_no_auto_response_reg_exp',
|
||||||
|
area: 'Email::Base',
|
||||||
|
description: 'If this regex matches, no notification will be send by the sender.',
|
||||||
|
options: {
|
||||||
|
form: [
|
||||||
|
{
|
||||||
|
display: '',
|
||||||
|
null: false,
|
||||||
|
name: 'send_no_auto_response_reg_exp',
|
||||||
|
tag: 'input',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
state: '(MAILER-DAEMON|postmaster|abuse)@.+?\..+?',
|
||||||
|
preferences: { online_service_disable: true },
|
||||||
|
frontend: false
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -1160,6 +1160,7 @@ Setting.create_if_not_exists(
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
state: '(MAILER-DAEMON|postmaster|abuse)@.+?\..+?',
|
state: '(MAILER-DAEMON|postmaster|abuse)@.+?\..+?',
|
||||||
|
preferences: { online_service_disable: true },
|
||||||
frontend: false
|
frontend: false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -203,17 +203,12 @@ returns on fail
|
||||||
driver_instance.fetch(params[:options], nil, 'check')
|
driver_instance.fetch(params[:options], nil, 'check')
|
||||||
|
|
||||||
rescue => e
|
rescue => e
|
||||||
message_human = ''
|
|
||||||
translations.each {|key, message|
|
|
||||||
if e.message =~ /#{Regexp.escape(key)}/i
|
|
||||||
message_human = message
|
|
||||||
end
|
|
||||||
}
|
|
||||||
result = {
|
result = {
|
||||||
result: 'invalid',
|
result: 'invalid',
|
||||||
settings: params,
|
settings: params,
|
||||||
message: e.message,
|
message: e.message,
|
||||||
message_human: message_human,
|
message_human: translation(e.message),
|
||||||
|
invalid_field: invalid_field(e.message),
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
@ -335,17 +330,12 @@ returns on fail
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
message_human = ''
|
|
||||||
translations.each {|key, message|
|
|
||||||
if e.message =~ /#{Regexp.escape(key)}/i
|
|
||||||
message_human = message
|
|
||||||
end
|
|
||||||
}
|
|
||||||
result = {
|
result = {
|
||||||
result: 'invalid',
|
result: 'invalid',
|
||||||
settings: params,
|
settings: params,
|
||||||
message: e.message,
|
message: e.message,
|
||||||
message_human: message_human,
|
message_human: translation(e.message),
|
||||||
|
invalid_field: invalid_field(e.message),
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
@ -355,6 +345,35 @@ returns on fail
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.invalid_field(message_backend)
|
||||||
|
invalid_fields.each {|key, fields|
|
||||||
|
return fields if message_backend =~ /#{Regexp.escape(key)}/i
|
||||||
|
}
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.invalid_fields
|
||||||
|
{
|
||||||
|
'authentication failed' => { user: true, password: true},
|
||||||
|
'Username and Password not accepted' => { user: true, password: true},
|
||||||
|
'Incorrect username' => { user: true, password: true},
|
||||||
|
'Lookup failed' => { user: true },
|
||||||
|
'Invalid credentials' => { user: true, password: true},
|
||||||
|
'getaddrinfo: nodename nor servname provided, or not known' => { host: true },
|
||||||
|
'getaddrinfo: Name or service not known' => { host: true },
|
||||||
|
'No route to host' => { host: true },
|
||||||
|
'execution expired' => { host: true },
|
||||||
|
'Connection refused' => { host: true },
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.translation(message_backend)
|
||||||
|
translations.each {|key, message_human|
|
||||||
|
return message_human if message_backend =~ /#{Regexp.escape(key)}/i
|
||||||
|
}
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
def self.translations
|
def self.translations
|
||||||
{
|
{
|
||||||
'authentication failed' => 'Authentication failed!',
|
'authentication failed' => 'Authentication failed!',
|
||||||
|
|
|
@ -62,10 +62,14 @@ or
|
||||||
subject = params[:subject]
|
subject = params[:subject]
|
||||||
end
|
end
|
||||||
result = EmailHelper::Probe.outbound(params[:outbound], params[:sender], subject)
|
result = EmailHelper::Probe.outbound(params[:outbound], params[:sender], subject)
|
||||||
|
if result[:result] != 'ok'
|
||||||
|
result[:source] = 'outbound'
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
# looking for verify email
|
# looking for verify email
|
||||||
(1..5).each {
|
(1..10).each {
|
||||||
sleep 10
|
sleep 5
|
||||||
|
|
||||||
# fetch mailbox
|
# fetch mailbox
|
||||||
found = nil
|
found = nil
|
||||||
|
@ -79,7 +83,10 @@ or
|
||||||
rescue => e
|
rescue => e
|
||||||
result = {
|
result = {
|
||||||
result: 'invalid',
|
result: 'invalid',
|
||||||
|
source: 'inbound',
|
||||||
message: e.to_s,
|
message: e.to_s,
|
||||||
|
message_human: EmailHelper::Probe.translation(e.message),
|
||||||
|
invalid_field: EmailHelper::Probe.invalid_field(e.message),
|
||||||
subject: subject,
|
subject: subject,
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|
Loading…
Reference in a new issue