Init version of new installer.
This commit is contained in:
parent
500b11c86b
commit
0de3fc7c6b
20 changed files with 1096 additions and 198 deletions
|
@ -183,7 +183,7 @@ class App.Controller extends Spine.Controller
|
||||||
callback: data.callback
|
callback: data.callback
|
||||||
)
|
)
|
||||||
|
|
||||||
authenticate: ->
|
authenticate: (checkOnly = false) ->
|
||||||
|
|
||||||
# return true if session exists
|
# return true if session exists
|
||||||
return true if @Session.get()
|
return true if @Session.get()
|
||||||
|
@ -191,6 +191,8 @@ class App.Controller extends Spine.Controller
|
||||||
# remember requested url
|
# remember requested url
|
||||||
@Config.set( 'requested_url', window.location.hash )
|
@Config.set( 'requested_url', window.location.hash )
|
||||||
|
|
||||||
|
return false if checkOnly
|
||||||
|
|
||||||
# redirect to login
|
# redirect to login
|
||||||
@navigate '#login'
|
@navigate '#login'
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -1,18 +1,486 @@
|
||||||
class Index extends App.ControllerContent
|
class Index extends App.ControllerContent
|
||||||
className: 'getstarted fit'
|
className: 'getstarted fit'
|
||||||
|
|
||||||
|
constructor: ->
|
||||||
|
super
|
||||||
|
|
||||||
|
if @authenticate(true)
|
||||||
|
@navigate '#'
|
||||||
|
|
||||||
|
# set title
|
||||||
|
@title 'Get Started'
|
||||||
|
|
||||||
|
@fetch()
|
||||||
|
|
||||||
|
release: =>
|
||||||
|
@el.removeClass('fit').removeClass('getstarted')
|
||||||
|
|
||||||
|
fetch: ->
|
||||||
|
|
||||||
|
# get data
|
||||||
|
@ajax(
|
||||||
|
id: 'getting_started',
|
||||||
|
type: 'GET',
|
||||||
|
url: @apiPath + '/getting_started',
|
||||||
|
processData: true,
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
# redirect to login if master user already exists
|
||||||
|
if data.setup_done
|
||||||
|
@navigate '#login'
|
||||||
|
return
|
||||||
|
|
||||||
|
# render page
|
||||||
|
@render()
|
||||||
|
)
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
|
||||||
|
@html App.view('getting_started/index')()
|
||||||
|
|
||||||
|
App.Config.set( 'getting_started', Index, 'Routes' )
|
||||||
|
|
||||||
|
|
||||||
|
class Base extends App.ControllerContent
|
||||||
|
className: 'getstarted fit'
|
||||||
events:
|
events:
|
||||||
'submit form': 'submit',
|
'change [name=adapter]': 'toggleAdapter'
|
||||||
'click .submit': 'submit',
|
'submit .base': 'storeFqdn'
|
||||||
|
'submit .base-outbound': 'storeOutbound'
|
||||||
|
'submit .base-inbound': 'storeInbound'
|
||||||
|
'click .js-next': 'submit'
|
||||||
|
|
||||||
|
constructor: ->
|
||||||
|
super
|
||||||
|
|
||||||
|
if @authenticate(true)
|
||||||
|
@navigate '#'
|
||||||
|
|
||||||
|
# set title
|
||||||
|
@title 'Configure Base'
|
||||||
|
|
||||||
|
@fetch()
|
||||||
|
|
||||||
|
release: =>
|
||||||
|
@el.removeClass('fit').removeClass('getstarted')
|
||||||
|
|
||||||
|
fetch: ->
|
||||||
|
|
||||||
|
# get data
|
||||||
|
@ajax(
|
||||||
|
id: 'getting_started',
|
||||||
|
type: 'GET',
|
||||||
|
url: @apiPath + '/getting_started',
|
||||||
|
processData: true,
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
# redirect to login if master user already exists
|
||||||
|
if data.setup_done
|
||||||
|
@navigate '#login'
|
||||||
|
return
|
||||||
|
|
||||||
|
# render page
|
||||||
|
@render()
|
||||||
|
)
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
|
||||||
|
@html App.view('getting_started/base')()
|
||||||
|
|
||||||
|
# fqdn
|
||||||
|
configureAttributesBase = [
|
||||||
|
{ name: 'fqdn', display: 'System URL (where the system can be reached)', tag: 'input', null: false, placeholder: 'http://yourhost' },
|
||||||
|
]
|
||||||
|
new App.ControllerForm(
|
||||||
|
el: @$('.base-fqdn'),
|
||||||
|
model: { configure_attributes: configureAttributesBase, className: '' },
|
||||||
|
)
|
||||||
|
|
||||||
|
# outbound
|
||||||
|
adapters =
|
||||||
|
sendmail: 'Local MTA (Sendmail/Postfix/Exim/...)'
|
||||||
|
smtp: 'SMTP'
|
||||||
|
adapter_used = 'sendmail'
|
||||||
|
configureAttributesOutbound = [
|
||||||
|
{ name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: adapters , default: adapter_used },
|
||||||
|
]
|
||||||
|
new App.ControllerForm(
|
||||||
|
el: @$('.base-outbound-type'),
|
||||||
|
model: { configure_attributes: configureAttributesOutbound, className: '' },
|
||||||
|
)
|
||||||
|
|
||||||
|
@toggleAdapter()
|
||||||
|
|
||||||
|
# inbound
|
||||||
|
configureAttributesInbound = [
|
||||||
|
{ name: 'email', display: 'Email', tag: 'input', type: 'text', limit: 200, null: false, autocapitalize: false, default: '' },
|
||||||
|
{ 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::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
|
||||||
|
{ name: 'options::password', display: 'Password', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
|
||||||
|
{ name: 'options::ssl', display: 'SSL', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' }, translate: true, default: true},
|
||||||
|
]
|
||||||
|
new App.ControllerForm(
|
||||||
|
el: @$('.base-inbound-settings'),
|
||||||
|
model: { configure_attributes: configureAttributesInbound, className: '' },
|
||||||
|
)
|
||||||
|
|
||||||
|
toggleAdapter: (channel_used = {}) =>
|
||||||
|
adapter = @$('[name=adapter]').val()
|
||||||
|
if adapter is 'smtp'
|
||||||
|
configureAttributesOutbound = [
|
||||||
|
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, 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::password', display: 'Password', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, default: (channel_used['options']&&channel_used['options']['password']) },
|
||||||
|
{ name: 'options::ssl', display: 'SSL', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' } , translate: true, default: (channel_used['options']&&channel_used['options']['ssl']||true) },
|
||||||
|
{ name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 5, null: false, class: 'span1', autocapitalize: false, default: ((channel_used['options']&&channel_used['options']['port']) || 25) },
|
||||||
|
]
|
||||||
|
@form = new App.ControllerForm(
|
||||||
|
el: @$('.base-outbound-settings')
|
||||||
|
model: { configure_attributes: configureAttributesOutbound, className: '' }
|
||||||
|
autofocus: true
|
||||||
|
)
|
||||||
|
else
|
||||||
|
@el.find('.base-outbound-settings').html('')
|
||||||
|
|
||||||
|
submit: (e) =>
|
||||||
|
e.preventDefault()
|
||||||
|
form = $(e.target).attr('data-form')
|
||||||
|
console.log('submit', form)
|
||||||
|
@$(".#{form}").trigger('submit')
|
||||||
|
|
||||||
|
showOutbound: =>
|
||||||
|
@$('.base').addClass('hide')
|
||||||
|
@$('.base-outbound').removeClass('hide')
|
||||||
|
@$('.base-inbound').addClass('hide')
|
||||||
|
@$('.wizard-controls .btn').text('Check').attr('data-form', 'base-outbound').addClass('btn--primary').removeClass('btn--danger').removeClass('btn--success')
|
||||||
|
@enable( @$('.btn') )
|
||||||
|
|
||||||
|
showInbound: =>
|
||||||
|
@$('.base').addClass('hide')
|
||||||
|
@$('.base-outbound').addClass('hide')
|
||||||
|
@$('.base-inbound').removeClass('hide')
|
||||||
|
@$('.wizard-controls .btn').text('Check').attr('data-form', 'base-inbound').addClass('btn--primary').removeClass('btn--danger').removeClass('btn--success')
|
||||||
|
@enable( @$('.btn') )
|
||||||
|
|
||||||
|
storeFqdn: (e) =>
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
# get params
|
||||||
|
params = @formParam(e.target)
|
||||||
|
console.log('submit', params, e)
|
||||||
|
@disable(e)
|
||||||
|
|
||||||
|
@ajax(
|
||||||
|
id: 'base_fqdn'
|
||||||
|
type: 'POST'
|
||||||
|
url: @apiPath + '/getting_started/base_fqdn'
|
||||||
|
data: JSON.stringify( {fqdn:params.fqdn} )
|
||||||
|
processData: true
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
if data.result is 'ok'
|
||||||
|
@$('.wizard-controls .btn').text('Done').removeClass('btn--primary').removeClass('btn--danger').addClass('btn--success')
|
||||||
|
@delay( @showOutbound, 1500 )
|
||||||
|
else
|
||||||
|
@$('.wizard-controls .btn').text( data.message_human || data.message ).addClass('btn--danger').removeClass('btn--primary').removeClass('btn--success')
|
||||||
|
@enable(e)
|
||||||
|
fail: =>
|
||||||
|
@enable(e)
|
||||||
|
)
|
||||||
|
|
||||||
|
storeOutbound: (e) =>
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
# get params
|
||||||
|
params = @formParam(e.target)
|
||||||
|
@disable(e)
|
||||||
|
|
||||||
|
@ajax(
|
||||||
|
id: 'base_outbound'
|
||||||
|
type: 'POST'
|
||||||
|
url: @apiPath + '/getting_started/base_outbound'
|
||||||
|
data: JSON.stringify( params )
|
||||||
|
processData: true
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
if data.result is 'ok'
|
||||||
|
@$('.wizard-controls .btn').text('Done').removeClass('btn--primary').removeClass('btn--danger').addClass('btn--success')
|
||||||
|
@delay( @showInbound, 1500 )
|
||||||
|
else
|
||||||
|
@$('.wizard-controls .btn').text( data.message_human || data.message ).addClass('btn--danger').removeClass('btn--primary').removeClass('btn--success')
|
||||||
|
@enable(e)
|
||||||
|
fail: =>
|
||||||
|
@enable(e)
|
||||||
|
)
|
||||||
|
|
||||||
|
storeInbound: (e) =>
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
# get params
|
||||||
|
params = @formParam(e.target)
|
||||||
|
@disable(e)
|
||||||
|
|
||||||
|
console.log('PA', params)
|
||||||
|
|
||||||
|
@ajax(
|
||||||
|
id: 'base_inbound'
|
||||||
|
type: 'POST'
|
||||||
|
url: @apiPath + '/getting_started/base_inbound'
|
||||||
|
data: JSON.stringify( params )
|
||||||
|
processData: true
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
if data.result is 'ok'
|
||||||
|
@$('.wizard-controls .btn').text('Done').removeClass('btn--primary').removeClass('btn--danger').addClass('btn--success')
|
||||||
|
@delay( @goToAdmin, 1500 )
|
||||||
|
else
|
||||||
|
@$('.wizard-controls .btn').text( data.message_human || data.message ).addClass('btn--danger').removeClass('btn--primary').removeClass('btn--success')
|
||||||
|
@enable(e)
|
||||||
|
fail: =>
|
||||||
|
@enable(e)
|
||||||
|
)
|
||||||
|
|
||||||
|
disable: (e) =>
|
||||||
|
@formDisable(e)
|
||||||
|
@$('.wizard-controls .btn').attr('disabled', true)
|
||||||
|
|
||||||
|
enable: (e) =>
|
||||||
|
@formEnable(e)
|
||||||
|
@$('.wizard-controls .btn').attr('disabled', false)
|
||||||
|
|
||||||
|
goToAdmin: =>
|
||||||
|
@navigate 'getting_started/admin'
|
||||||
|
|
||||||
|
App.Config.set( 'getting_started/base', Base, 'Routes' )
|
||||||
|
|
||||||
|
|
||||||
|
class Admin extends App.ControllerContent
|
||||||
|
className: 'getstarted fit'
|
||||||
|
events:
|
||||||
|
'submit .js-admin': 'submit'
|
||||||
|
|
||||||
|
constructor: ->
|
||||||
|
super
|
||||||
|
|
||||||
|
if @authenticate(true)
|
||||||
|
@navigate '#'
|
||||||
|
|
||||||
|
# set title
|
||||||
|
@title 'Create Admin'
|
||||||
|
|
||||||
|
@fetch()
|
||||||
|
|
||||||
|
release: =>
|
||||||
|
@el.removeClass('fit').removeClass('getstarted')
|
||||||
|
|
||||||
|
fetch: ->
|
||||||
|
|
||||||
|
# get data
|
||||||
|
@ajax(
|
||||||
|
id: 'getting_started',
|
||||||
|
type: 'GET',
|
||||||
|
url: @apiPath + '/getting_started',
|
||||||
|
data: {
|
||||||
|
# view: @view,
|
||||||
|
}
|
||||||
|
processData: true,
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
# redirect to login if master user already exists
|
||||||
|
if data.setup_done
|
||||||
|
@navigate '#login'
|
||||||
|
return
|
||||||
|
|
||||||
|
# load group collection
|
||||||
|
App.Collection.load( type: 'Group', data: data.groups )
|
||||||
|
|
||||||
|
# render page
|
||||||
|
@render()
|
||||||
|
)
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
|
||||||
|
@html App.view('getting_started/admin')()
|
||||||
|
|
||||||
|
new App.ControllerForm(
|
||||||
|
el: @$('.js-admin')
|
||||||
|
model: App.User
|
||||||
|
screen: 'signup'
|
||||||
|
autofocus: true
|
||||||
|
)
|
||||||
|
|
||||||
|
submit: (e) =>
|
||||||
|
e.preventDefault()
|
||||||
|
@formDisable(e)
|
||||||
|
@params = @formParam(e.target)
|
||||||
|
@params.role_ids = [0]
|
||||||
|
|
||||||
|
user = new App.User
|
||||||
|
user.load(@params)
|
||||||
|
|
||||||
|
errors = user.validate(
|
||||||
|
screen: 'signup'
|
||||||
|
)
|
||||||
|
if errors
|
||||||
|
@log 'error new', errors
|
||||||
|
@formValidate( form: e.target, errors: errors )
|
||||||
|
@formEnable(e)
|
||||||
|
return false
|
||||||
|
|
||||||
|
# save user
|
||||||
|
user.save(
|
||||||
|
done: (r) =>
|
||||||
|
App.Auth.login(
|
||||||
|
data:
|
||||||
|
username: @params.email
|
||||||
|
password: @params.password
|
||||||
|
success: @relogin
|
||||||
|
error: =>
|
||||||
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'error'
|
||||||
|
msg: App.i18n.translateContent( 'Signin failed! Please contact the support team!' )
|
||||||
|
timeout: 2500
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@Config.set('system_init_done', true)
|
||||||
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'success'
|
||||||
|
msg: App.i18n.translateContent( 'Welcome to %s!', @Config.get('product_name') )
|
||||||
|
timeout: 2500
|
||||||
|
}
|
||||||
|
|
||||||
|
fail: (data) =>
|
||||||
|
@formEnable(e)
|
||||||
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'error'
|
||||||
|
msg: App.i18n.translateContent( 'Can\'t create user!' )
|
||||||
|
timeout: 2500
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
relogin: (data, status, xhr) =>
|
||||||
|
@log 'notice', 'relogin:success', data
|
||||||
|
|
||||||
|
# add notify
|
||||||
|
App.Event.trigger 'notify:removeall'
|
||||||
|
|
||||||
|
@navigate 'getting_started/agents'
|
||||||
|
|
||||||
|
App.Config.set( 'getting_started/admin', Admin, 'Routes' )
|
||||||
|
|
||||||
|
class Agent extends App.ControllerContent
|
||||||
|
className: 'getstarted'
|
||||||
|
events:
|
||||||
|
'submit .js-agent': 'submit'
|
||||||
|
|
||||||
|
constructor: ->
|
||||||
|
super
|
||||||
|
|
||||||
|
return if !@authenticate()
|
||||||
|
|
||||||
|
# set title
|
||||||
|
@title 'Invite Agents'
|
||||||
|
|
||||||
|
@fetch()
|
||||||
|
|
||||||
|
|
||||||
|
release: =>
|
||||||
|
@el.removeClass('fit').removeClass('getstarted')
|
||||||
|
|
||||||
|
fetch: ->
|
||||||
|
|
||||||
|
# get data
|
||||||
|
@ajax(
|
||||||
|
id: 'getting_started',
|
||||||
|
type: 'GET',
|
||||||
|
url: @apiPath + '/getting_started',
|
||||||
|
data: {
|
||||||
|
# view: @view,
|
||||||
|
}
|
||||||
|
processData: true,
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
# redirect to login if master user already exists
|
||||||
|
if !data.setup_done
|
||||||
|
@navigate '#getting_started/admin'
|
||||||
|
return
|
||||||
|
|
||||||
|
# load group collection
|
||||||
|
App.Collection.load( type: 'Group', data: data.groups )
|
||||||
|
|
||||||
|
# render page
|
||||||
|
@render()
|
||||||
|
)
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
|
||||||
|
@html App.view('getting_started/agent')()
|
||||||
|
|
||||||
|
new App.ControllerForm(
|
||||||
|
el: @$('.js-agent')
|
||||||
|
model: App.User
|
||||||
|
screen: 'invite_agent'
|
||||||
|
autofocus: true
|
||||||
|
)
|
||||||
|
|
||||||
|
submit: (e) =>
|
||||||
|
e.preventDefault()
|
||||||
|
@formDisable(e)
|
||||||
|
@params = @formParam(e.target)
|
||||||
|
@params.role_ids = [0]
|
||||||
|
|
||||||
|
# set invite flag
|
||||||
|
@params.invite = true
|
||||||
|
|
||||||
|
# find agent role
|
||||||
|
role = App.Role.findByAttribute( 'name', 'Agent' )
|
||||||
|
if role
|
||||||
|
@params.role_ids = role.id
|
||||||
|
|
||||||
|
user = new App.User
|
||||||
|
user.load(@params)
|
||||||
|
|
||||||
|
errors = user.validate(
|
||||||
|
screen: 'invite_agent'
|
||||||
|
)
|
||||||
|
if errors
|
||||||
|
@log 'error new', errors
|
||||||
|
@formValidate( form: e.target, errors: errors )
|
||||||
|
@formEnable(e)
|
||||||
|
return false
|
||||||
|
|
||||||
|
# save user
|
||||||
|
user.save(
|
||||||
|
done: (r) =>
|
||||||
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'success'
|
||||||
|
msg: App.i18n.translateContent( 'Invitation sent!' )
|
||||||
|
timeout: 3500
|
||||||
|
}
|
||||||
|
|
||||||
|
# rerender page
|
||||||
|
@render()
|
||||||
|
|
||||||
|
fail: (data) =>
|
||||||
|
@formEnable(e)
|
||||||
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'error'
|
||||||
|
msg: App.i18n.translateContent( 'Can\'t create user!' )
|
||||||
|
timeout: 2500
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
App.Config.set( 'getting_started/agents', Agent, 'Routes' )
|
||||||
|
|
||||||
|
class Import extends App.ControllerContent
|
||||||
|
className: 'getstarted fit'
|
||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super
|
super
|
||||||
|
|
||||||
# set title
|
# set title
|
||||||
@title 'Get Started'
|
@title 'Import'
|
||||||
@navupdate '#get_started'
|
|
||||||
|
|
||||||
@master_user = 0
|
|
||||||
@fetch()
|
@fetch()
|
||||||
|
|
||||||
fetch: ->
|
fetch: ->
|
||||||
|
@ -28,11 +496,10 @@ class Index extends App.ControllerContent
|
||||||
processData: true,
|
processData: true,
|
||||||
success: (data, status, xhr) =>
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
# get meta data
|
# redirect to login if master user already exists
|
||||||
@master_user = data.master_user
|
if data.setup_done
|
||||||
|
@navigate '#login'
|
||||||
# load group collection
|
return
|
||||||
App.Collection.load( type: 'Group', data: data.groups )
|
|
||||||
|
|
||||||
# render page
|
# render page
|
||||||
@render()
|
@render()
|
||||||
|
@ -40,113 +507,6 @@ class Index extends App.ControllerContent
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
|
|
||||||
# check authentication, redirect to login if master user already exists
|
@html App.view('getting_started/import')()
|
||||||
if !@master_user && !@authenticate()
|
|
||||||
@navigate '#login'
|
|
||||||
|
|
||||||
@html App.view('getting_started')(
|
App.Config.set( 'getting_started/import', Import, 'Routes' )
|
||||||
master_user: @master_user
|
|
||||||
)
|
|
||||||
|
|
||||||
new App.ControllerForm(
|
|
||||||
el: @el.find('#form-master')
|
|
||||||
model: App.User
|
|
||||||
screen: 'signup'
|
|
||||||
autofocus: true
|
|
||||||
)
|
|
||||||
new App.ControllerForm(
|
|
||||||
el: @el.find('#form-agent')
|
|
||||||
model: App.User
|
|
||||||
screen: 'invite_agent'
|
|
||||||
autofocus: true
|
|
||||||
)
|
|
||||||
|
|
||||||
if !@master_user
|
|
||||||
@el.find('.agent_user').removeClass('hide')
|
|
||||||
|
|
||||||
submit: (e) ->
|
|
||||||
e.preventDefault()
|
|
||||||
@params = @formParam(e.target)
|
|
||||||
|
|
||||||
# if no login is given, use emails as fallback
|
|
||||||
if !@params.login && @params.email
|
|
||||||
@params.login = @params.email
|
|
||||||
|
|
||||||
# set invite flag
|
|
||||||
@params.invite = true
|
|
||||||
|
|
||||||
# find agent role
|
|
||||||
role = App.Role.findByAttribute( 'name', 'Agent' )
|
|
||||||
if role
|
|
||||||
@params.role_ids = role.id
|
|
||||||
else
|
|
||||||
@params.role_ids = [0]
|
|
||||||
|
|
||||||
@log 'notice', 'updateAttributes', @params
|
|
||||||
user = new App.User
|
|
||||||
user.load(@params)
|
|
||||||
|
|
||||||
errors = user.validate()
|
|
||||||
if errors
|
|
||||||
@log 'error', errors
|
|
||||||
@formValidate( form: e.target, errors: errors )
|
|
||||||
return false
|
|
||||||
|
|
||||||
# save user
|
|
||||||
user.save(
|
|
||||||
done: =>
|
|
||||||
if @master_user
|
|
||||||
@master_user = false
|
|
||||||
App.Auth.login(
|
|
||||||
data: {
|
|
||||||
username: @params.login
|
|
||||||
password: @params.password
|
|
||||||
},
|
|
||||||
success: @relogin
|
|
||||||
# error: @error,
|
|
||||||
)
|
|
||||||
@Config.set('system_init_done', true)
|
|
||||||
App.Event.trigger 'notify', {
|
|
||||||
type: 'success'
|
|
||||||
msg: App.i18n.translateContent( 'Welcome to %s!', @Config.get('product_name') )
|
|
||||||
timeout: 2500
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
App.Event.trigger 'notify', {
|
|
||||||
type: 'success'
|
|
||||||
msg: App.i18n.translateContent( 'Invitation sent!' )
|
|
||||||
timeout: 3500
|
|
||||||
}
|
|
||||||
|
|
||||||
# rerender page
|
|
||||||
@render()
|
|
||||||
|
|
||||||
fail: (data) ->
|
|
||||||
App.Event.trigger 'notify', {
|
|
||||||
type: 'error'
|
|
||||||
msg: App.i18n.translateContent( 'Can\'t create user!' )
|
|
||||||
timeout: 2500
|
|
||||||
}
|
|
||||||
# @modalHide()
|
|
||||||
)
|
|
||||||
|
|
||||||
relogin: (data, status, xhr) =>
|
|
||||||
@log 'notice', 'relogin:success', data
|
|
||||||
|
|
||||||
# add notify
|
|
||||||
App.Event.trigger 'notify:removeall'
|
|
||||||
# @notify
|
|
||||||
# type: 'success',
|
|
||||||
# msg: 'Thanks for joining. Email sent to "' + @params.email + '". Please verify your email address.'
|
|
||||||
|
|
||||||
@el.find('.master_user').addClass('hide')
|
|
||||||
@el.find('.agent_user').removeClass('hide')
|
|
||||||
@el.find('.tabs .tab.active').removeClass('active')
|
|
||||||
@el.find('.tabs .invite_agents').addClass('active')
|
|
||||||
# @el.find('.master_user').fadeOut('slow', =>
|
|
||||||
# @el.find('.agent_user').fadeIn()
|
|
||||||
# )
|
|
||||||
|
|
||||||
App.Config.set( 'getting_started', Index, 'Routes' )
|
|
||||||
|
|
152
app/assets/javascripts/app/controllers/import.js.coffee
Normal file
152
app/assets/javascripts/app/controllers/import.js.coffee
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
class Index extends App.ControllerContent
|
||||||
|
className: 'getstarted fit'
|
||||||
|
|
||||||
|
events:
|
||||||
|
'submit form': 'submit',
|
||||||
|
'click .submit': 'submit',
|
||||||
|
|
||||||
|
constructor: ->
|
||||||
|
super
|
||||||
|
|
||||||
|
# set title
|
||||||
|
@title 'Get Started'
|
||||||
|
@navupdate '#get_started'
|
||||||
|
|
||||||
|
@master_user = 0
|
||||||
|
@fetch()
|
||||||
|
|
||||||
|
fetch: ->
|
||||||
|
|
||||||
|
# get data
|
||||||
|
@ajax(
|
||||||
|
id: 'getting_started',
|
||||||
|
type: 'GET',
|
||||||
|
url: @apiPath + '/getting_started',
|
||||||
|
data: {
|
||||||
|
# view: @view,
|
||||||
|
}
|
||||||
|
processData: true,
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
# get meta data
|
||||||
|
@master_user = data.master_user
|
||||||
|
|
||||||
|
# load group collection
|
||||||
|
App.Collection.load( type: 'Group', data: data.groups )
|
||||||
|
|
||||||
|
# render page
|
||||||
|
@render()
|
||||||
|
)
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
|
||||||
|
# check authentication, redirect to login if master user already exists
|
||||||
|
#if !@master_user && !@authenticate()
|
||||||
|
# @navigate '#login'
|
||||||
|
|
||||||
|
@html App.view('getting_started')(
|
||||||
|
master_user: @master_user
|
||||||
|
)
|
||||||
|
|
||||||
|
new App.ControllerForm(
|
||||||
|
el: @el.find('#form-master')
|
||||||
|
model: App.User
|
||||||
|
screen: 'signup'
|
||||||
|
autofocus: true
|
||||||
|
)
|
||||||
|
new App.ControllerForm(
|
||||||
|
el: @el.find('#form-agent')
|
||||||
|
model: App.User
|
||||||
|
screen: 'invite_agent'
|
||||||
|
autofocus: true
|
||||||
|
)
|
||||||
|
|
||||||
|
if !@master_user
|
||||||
|
@el.find('.agent_user').removeClass('hide')
|
||||||
|
|
||||||
|
submit: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
@params = @formParam(e.target)
|
||||||
|
|
||||||
|
# if no login is given, use emails as fallback
|
||||||
|
if !@params.login && @params.email
|
||||||
|
@params.login = @params.email
|
||||||
|
|
||||||
|
# set invite flag
|
||||||
|
@params.invite = true
|
||||||
|
|
||||||
|
# find agent role
|
||||||
|
role = App.Role.findByAttribute( 'name', 'Agent' )
|
||||||
|
if role
|
||||||
|
@params.role_ids = role.id
|
||||||
|
else
|
||||||
|
@params.role_ids = [0]
|
||||||
|
|
||||||
|
@log 'notice', 'updateAttributes', @params
|
||||||
|
user = new App.User
|
||||||
|
user.load(@params)
|
||||||
|
|
||||||
|
errors = user.validate()
|
||||||
|
if errors
|
||||||
|
@log 'error', errors
|
||||||
|
@formValidate( form: e.target, errors: errors )
|
||||||
|
return false
|
||||||
|
|
||||||
|
# save user
|
||||||
|
user.save(
|
||||||
|
done: =>
|
||||||
|
if @master_user
|
||||||
|
@master_user = false
|
||||||
|
App.Auth.login(
|
||||||
|
data: {
|
||||||
|
username: @params.login
|
||||||
|
password: @params.password
|
||||||
|
},
|
||||||
|
success: @relogin
|
||||||
|
# error: @error,
|
||||||
|
)
|
||||||
|
@Config.set('system_init_done', true)
|
||||||
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'success'
|
||||||
|
msg: App.i18n.translateContent( 'Welcome to %s!', @Config.get('product_name') )
|
||||||
|
timeout: 2500
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'success'
|
||||||
|
msg: App.i18n.translateContent( 'Invitation sent!' )
|
||||||
|
timeout: 3500
|
||||||
|
}
|
||||||
|
|
||||||
|
# rerender page
|
||||||
|
@render()
|
||||||
|
|
||||||
|
fail: (data) ->
|
||||||
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'error'
|
||||||
|
msg: App.i18n.translateContent( 'Can\'t create user!' )
|
||||||
|
timeout: 2500
|
||||||
|
}
|
||||||
|
# @modalHide()
|
||||||
|
)
|
||||||
|
|
||||||
|
relogin: (data, status, xhr) =>
|
||||||
|
@log 'notice', 'relogin:success', data
|
||||||
|
|
||||||
|
# add notify
|
||||||
|
App.Event.trigger 'notify:removeall'
|
||||||
|
# @notify
|
||||||
|
# type: 'success',
|
||||||
|
# msg: 'Thanks for joining. Email sent to "' + @params.email + '". Please verify your email address.'
|
||||||
|
|
||||||
|
@el.find('.master_user').addClass('hide')
|
||||||
|
@el.find('.agent_user').removeClass('hide')
|
||||||
|
@el.find('.tabs .tab.active').removeClass('active')
|
||||||
|
@el.find('.tabs .invite_agents').addClass('active')
|
||||||
|
# @el.find('.master_user').fadeOut('slow', =>
|
||||||
|
# @el.find('.agent_user').fadeIn()
|
||||||
|
# )
|
||||||
|
|
||||||
|
App.Config.set( 'import', Index, 'Routes' )
|
|
@ -22,11 +22,6 @@ class Index extends App.ControllerContent
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
|
|
||||||
# set password as required
|
|
||||||
for item in App.User.configure_attributes
|
|
||||||
if item.name is 'password'
|
|
||||||
item.null = false
|
|
||||||
|
|
||||||
@html App.view('signup')()
|
@html App.view('signup')()
|
||||||
|
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
|
@ -53,7 +48,9 @@ class Index extends App.ControllerContent
|
||||||
user = new App.User
|
user = new App.User
|
||||||
user.load(@params)
|
user.load(@params)
|
||||||
|
|
||||||
errors = user.validate()
|
errors = user.validate(
|
||||||
|
screen: 'signup'
|
||||||
|
)
|
||||||
if errors
|
if errors
|
||||||
@log 'error new', errors
|
@log 'error new', errors
|
||||||
@formValidate( form: e.target, errors: errors )
|
@formValidate( form: e.target, errors: errors )
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
<div class="fullHeight vertical center justified">
|
|
||||||
<div class="hero-unit">
|
|
||||||
<ol class="horizontal tabs progress-tabs tabs-condensed">
|
|
||||||
<li class="create_admin tab u-textTruncate active"><%- @T( 'Create Admin' ) %></li>
|
|
||||||
<li class="invite_agents tab u-textTruncate"><%- @T( 'Invite Agents' ) %></li>
|
|
||||||
<li class="configure_channels tab u-textTruncate"><%- @T( 'Configure Channels' ) %></li>
|
|
||||||
</ol>
|
|
||||||
<% if @master_user: %>
|
|
||||||
<div class="master_user hero-left">
|
|
||||||
<form class="form-stacked" id="form-master">
|
|
||||||
<button type="submit" class="btn btn--primary submit pull-right"><%- @T( 'Next Step' ) %></button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<div class="agent_user hero-left hide">
|
|
||||||
<form class="form-stacked" id="form-agent">
|
|
||||||
<div class="form-controls">
|
|
||||||
<button type="submit" class="btn btn--primary submit pull-right"><%- @T( 'Send Invitation' ) %></button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<div class="fullHeight flex vertical center justified getstarted fit">
|
||||||
|
<div class="hero-unit">
|
||||||
|
<ol class="horizontal tabs progress-tabs tabs-condensed">
|
||||||
|
<li class="configure_channels tab u-textTruncate"><%- @T( 'Configure Base' ) %></li>
|
||||||
|
<li class="create_admin tab u-textTruncate active"><%- @T( 'Create Admin' ) %></li>
|
||||||
|
<li class="invite_agents tab u-textTruncate"><%- @T( 'Invite Agents' ) %></li>
|
||||||
|
</ol>
|
||||||
|
<div class="master-user hero-left">
|
||||||
|
<form class="form-stacked js-admin">
|
||||||
|
<button type="submit" class="btn btn--primary submit pull-right"><%- @T( 'Create Admin' ) %></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<div class="fullHeight flex vertical center justified getstarted">
|
||||||
|
<div class="hero-unit">
|
||||||
|
<ol class="horizontal tabs progress-tabs tabs-condensed">
|
||||||
|
<li class="configure_channels tab u-textTruncate"><%- @T( 'Configure Base' ) %></li>
|
||||||
|
<li class="create_admin tab u-textTruncate"><%- @T( 'Create Admin' ) %></li>
|
||||||
|
<li class="invite_agents tab u-textTruncate active"><%- @T( 'Invite Agents' ) %></li>
|
||||||
|
</ol>
|
||||||
|
<div class="master-user hero-left">
|
||||||
|
<form class="form-stacked js-agent">
|
||||||
|
<div class="form-controls">
|
||||||
|
<button type="submit" class="btn btn--primary submit pull-right"><%- @T( 'Send Invitation' ) %></button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<div class="fullHeight flex vertical center justified">
|
||||||
|
<div class="hero-unit">
|
||||||
|
<ol class="horizontal tabs progress-tabs tabs-condensed">
|
||||||
|
<li class="configure_channels tab u-textTruncate active"><%- @T( 'Configure Base' ) %></li>
|
||||||
|
<li class="create_admin tab u-textTruncate"><%- @T( 'Create Admin' ) %></li>
|
||||||
|
<li class="invite_agents tab u-textTruncate"><%- @T( 'Invite Agents' ) %></li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<form class="base">
|
||||||
|
<div class="base-fqdn"></div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
<form class="base-outbound hide">
|
||||||
|
<%- @T('E-Mail Outbound') %>
|
||||||
|
<div class="base-outbound-type"></div>
|
||||||
|
<div class="base-outbound-settings"></div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form class="base-inbound hide">
|
||||||
|
<%- @T('E-Mail Inbound') %>
|
||||||
|
<div class="base-inbound-settings"></div>
|
||||||
|
<div class="base-inbound-state"></div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="wizard-controls horizontal center">
|
||||||
|
<a class="subtle-link" href="#getting_started"><%- @T('Go Back') %></a>
|
||||||
|
<div class="btn btn--primary js-next align-right" data-form="base"><%- @T('Update') %></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<div class="main flex centered darkBackground">
|
||||||
|
<div class="import wizard hero-unit">
|
||||||
|
<div class="wizard-slide vertical" data-slide="home">
|
||||||
|
<h2><%- @T('Import from') %></h2>
|
||||||
|
<div class="wizard-body flex vertical justified">
|
||||||
|
<div class="import-source centered" data-source="otrs" data-target="otrs-prepare-plugin">
|
||||||
|
<img class="logo" src="<%= @C('otrs-logo.png') %>" alt="OTRS" height="37">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wizard-slide vertical hide" data-slide="otrs-prepare-plugin" data-hide="2330">
|
||||||
|
<h2>Create OTRS Migration Plugin</h2>
|
||||||
|
<div class="wizard-body flex vertical justified">
|
||||||
|
<p class="wizard-loadingText">
|
||||||
|
<span class="loading icon"></span> Personalise Migration Plugin ..
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="wizard-controls horizontal center">
|
||||||
|
<a class="subtle-link" data-target="home">Go Back</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<div class="main flex centered darkBackground">
|
||||||
|
<div class="import wizard hero-unit">
|
||||||
|
<div class="wizard-slide vertical" data-slide="home">
|
||||||
|
<h2><%- @T('Welcome to %s', @C('product_name') ) %></h2>
|
||||||
|
<div class="wizard-body flex vertical justified">
|
||||||
|
<div class="centered">
|
||||||
|
<a href="#getting_started/import"><%- @T('Import from other System') %></a>
|
||||||
|
|
|
||||||
|
<a href="#getting_started/base"><%- @T('Setup new System') %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -30,14 +30,10 @@ curl http://localhost/api/v1/getting_started.json -v -u #{login}:#{password}
|
||||||
def index
|
def index
|
||||||
|
|
||||||
# check if first user already exists
|
# check if first user already exists
|
||||||
master_user = 0
|
return if setup_done_response
|
||||||
count = User.all.count()
|
|
||||||
if count <= 2
|
|
||||||
master_user = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
# if master user already exists, we need to be authenticated
|
# if master user already exists, we need to be authenticated
|
||||||
if master_user == 0
|
if setup_done
|
||||||
return if !authentication_check
|
return if !authentication_check
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -46,8 +42,287 @@ curl http://localhost/api/v1/getting_started.json -v -u #{login}:#{password}
|
||||||
|
|
||||||
# return result
|
# return result
|
||||||
render :json => {
|
render :json => {
|
||||||
:master_user => master_user,
|
:setup_done => setup_done,
|
||||||
:groups => groups,
|
:groups => groups,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def base_fqdn
|
||||||
|
return if setup_done_response
|
||||||
|
|
||||||
|
# validate
|
||||||
|
if !params[:fqdn] ||params[:fqdn] !~ /^(http|https):\/\/.+?$/
|
||||||
|
render :json => {
|
||||||
|
:result => 'invalid',
|
||||||
|
:message => 'Invalid!',
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
Setting.set('fqdn', params[:fqdn])
|
||||||
|
|
||||||
|
# return result
|
||||||
|
render :json => {
|
||||||
|
:result => 'ok',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def base_outbound
|
||||||
|
return if setup_done_response
|
||||||
|
|
||||||
|
# validate params
|
||||||
|
if !params[:adapter]
|
||||||
|
render :json => {
|
||||||
|
:result => 'invalid',
|
||||||
|
:message => 'Invalid!',
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# test connection
|
||||||
|
translationMap = {
|
||||||
|
'authentication failed' => 'Authentication failed!',
|
||||||
|
'getaddrinfo: nodename nor servname provided, or not known' => 'Hostname not found!',
|
||||||
|
'No route to host' => 'No route to host!',
|
||||||
|
'Connection refused' => 'Connection refused!',
|
||||||
|
}
|
||||||
|
if params[:adapter] == 'smtp'
|
||||||
|
begin
|
||||||
|
Channel::SMTP.new.send(
|
||||||
|
{
|
||||||
|
:from => 'me@example.com',
|
||||||
|
:to => 'emailtrytest@znuny.com',
|
||||||
|
:subject => 'test',
|
||||||
|
:body => 'test',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:options => params[:options]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
rescue Exception => e
|
||||||
|
|
||||||
|
# check if sending email was ok, but mailserver rejected
|
||||||
|
whiteMap = {
|
||||||
|
'Recipient address rejected' => true,
|
||||||
|
}
|
||||||
|
whiteMap.each {|key, message|
|
||||||
|
if e.message =~ /#{Regexp.escape(key)}/i
|
||||||
|
render :json => {
|
||||||
|
:result => 'ok',
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
}
|
||||||
|
message_human = ''
|
||||||
|
translationMap.each {|key, message|
|
||||||
|
if e.message =~ /#{Regexp.escape(key)}/i
|
||||||
|
message_human = message
|
||||||
|
end
|
||||||
|
}
|
||||||
|
render :json => {
|
||||||
|
:result => 'invalid',
|
||||||
|
:message => e.message,
|
||||||
|
:message_human => message_human,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Channel::Sendmail.new.send(
|
||||||
|
{
|
||||||
|
:from => 'me@example.com',
|
||||||
|
:to => 'emailtrytest@znuny.com',
|
||||||
|
:subject => 'test',
|
||||||
|
:body => 'test',
|
||||||
|
},
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
rescue Exception => e
|
||||||
|
message_human = ''
|
||||||
|
translationMap.each {|key, message|
|
||||||
|
if e.message =~ /#{Regexp.escape(key)}/i
|
||||||
|
message_human = message
|
||||||
|
end
|
||||||
|
}
|
||||||
|
render :json => {
|
||||||
|
:result => 'invalid',
|
||||||
|
:message => e.message,
|
||||||
|
:message_human => message_human,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# save settings
|
||||||
|
if params[:adapter] == 'smtp'
|
||||||
|
smtp = Channel.where( :adapter => 'SMTP', :area => 'Email::Outbound' ).first
|
||||||
|
smtp.options = params[:options]
|
||||||
|
smtp.active = true
|
||||||
|
smtp.save!
|
||||||
|
sendmail = Channel.where(:adapter => 'Sendmail').first
|
||||||
|
sendmail.active = false
|
||||||
|
sendmail.save!
|
||||||
|
else
|
||||||
|
sendmail = Channel.where( :adapter => 'Sendmail', :area => 'Email::Outbound' ).first
|
||||||
|
sendmail.options = {}
|
||||||
|
sendmail.active = true
|
||||||
|
sendmail.save!
|
||||||
|
smtp = Channel.where(:adapter => 'SMTP').first
|
||||||
|
smtp.active = false
|
||||||
|
smtp.save
|
||||||
|
end
|
||||||
|
|
||||||
|
# return result
|
||||||
|
render :json => {
|
||||||
|
:result => 'ok',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def base_inbound
|
||||||
|
return if setup_done_response
|
||||||
|
|
||||||
|
# validate params
|
||||||
|
if !params[:adapter]
|
||||||
|
render :json => {
|
||||||
|
:result => 'invalid',
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# connection test
|
||||||
|
translationMap = {
|
||||||
|
'authentication failed' => 'Authentication failed!',
|
||||||
|
'getaddrinfo: nodename nor servname provided, or not known' => 'Hostname not found!',
|
||||||
|
'No route to host' => 'No route to host!',
|
||||||
|
'Connection refused' => 'Connection refused!',
|
||||||
|
}
|
||||||
|
if params[:adapter] == 'IMAP'
|
||||||
|
begin
|
||||||
|
Channel::IMAP.new.fetch( { :options => params[:options] }, 'check' )
|
||||||
|
rescue Exception => e
|
||||||
|
message_human = ''
|
||||||
|
translationMap.each {|key, message|
|
||||||
|
if e.message =~ /#{Regexp.escape(key)}/i
|
||||||
|
message_human = message
|
||||||
|
end
|
||||||
|
}
|
||||||
|
render :json => {
|
||||||
|
:result => 'invalid',
|
||||||
|
:message => e.message,
|
||||||
|
:message_human => message_human,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Channel::POP3.new.fetch( { :options => params[:options] }, 'check' )
|
||||||
|
rescue Exception => e
|
||||||
|
message_human = ''
|
||||||
|
translationMap.each {|key, message|
|
||||||
|
if e.message =~ /#{Regexp.escape(key)}/i
|
||||||
|
message_human = message
|
||||||
|
end
|
||||||
|
}
|
||||||
|
render :json => {
|
||||||
|
:result => 'invalid',
|
||||||
|
:message => e.message,
|
||||||
|
:message_human => message_human,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# send verify email to inbox
|
||||||
|
subject = '#' + rand(99999999999).to_s
|
||||||
|
Channel::EmailSend.new.send(
|
||||||
|
{
|
||||||
|
:from => params[:email],
|
||||||
|
:to => params[:email],
|
||||||
|
:subject => "Zammad Getting started Test Email #{subject}",
|
||||||
|
:body => '.',
|
||||||
|
'x-zammad-ignore' => 'true',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(1..10).each {|loop|
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# fetch mailbox
|
||||||
|
found = nil
|
||||||
|
if params[:adapter] == 'IMAP'
|
||||||
|
found = Channel::IMAP.new.fetch( { :options => params[:options] }, 'verify', subject )
|
||||||
|
else
|
||||||
|
found = Channel::POP3.new.fetch( { :options => params[:options] }, 'verify', subject )
|
||||||
|
end
|
||||||
|
|
||||||
|
if found && found == 'verify ok'
|
||||||
|
|
||||||
|
# remember address
|
||||||
|
address = EmailAddress.all.first
|
||||||
|
if address
|
||||||
|
address.update_attributes(
|
||||||
|
:realname => 'Zammad',
|
||||||
|
:email => params[:email],
|
||||||
|
:active => 1,
|
||||||
|
:updated_by_id => 1,
|
||||||
|
:created_by_id => 1,
|
||||||
|
)
|
||||||
|
else
|
||||||
|
EmailAddress.create(
|
||||||
|
:realname => 'Zammad',
|
||||||
|
:email => params[:email],
|
||||||
|
:active => 1,
|
||||||
|
:updated_by_id => 1,
|
||||||
|
:created_by_id => 1,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# store mailbox
|
||||||
|
Channel.create(
|
||||||
|
:area => 'Email::Inbound',
|
||||||
|
:adapter => params[:adapter],
|
||||||
|
:options => params[:options],
|
||||||
|
:group_id => 1,
|
||||||
|
:active => 1,
|
||||||
|
:updated_by_id => 1,
|
||||||
|
:created_by_id => 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
render :json => {
|
||||||
|
:result => 'ok',
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
# check dilivery for 30 sek.
|
||||||
|
render :json => {
|
||||||
|
:result => 'invalid',
|
||||||
|
:message => 'Verification Email not found in mailbox.',
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def setup_done
|
||||||
|
#return false
|
||||||
|
count = User.all.count()
|
||||||
|
done = true
|
||||||
|
if count <= 2
|
||||||
|
done = false
|
||||||
|
end
|
||||||
|
done
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_done_response
|
||||||
|
if !setup_done
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
render :json => {
|
||||||
|
:setup_done => true,
|
||||||
|
}
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
|
@ -218,7 +218,7 @@ curl http://localhost/api/v1/users.json -v -u #{login}:#{password} -H "Content-T
|
||||||
data[:subject] = 'Invitation to #{config.product_name} at #{config.fqdn}'
|
data[:subject] = 'Invitation to #{config.product_name} at #{config.fqdn}'
|
||||||
data[:body] = 'Hi #{user.firstname},
|
data[:body] = 'Hi #{user.firstname},
|
||||||
|
|
||||||
I (#{current_user.firstname} #{current_user.lastname}) invite you to #{config.product_name} - a customer support / ticket system platform.
|
I (#{current_user.firstname} #{current_user.lastname}) invite you to #{config.product_name} - the customer support / ticket system platform.
|
||||||
|
|
||||||
Click on the following link and set your password:
|
Click on the following link and set your password:
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,6 @@ class Channel::EmailBuild
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return mail
|
mail
|
||||||
end
|
end
|
||||||
end
|
end
|
16
app/models/channel/email_send.rb
Normal file
16
app/models/channel/email_send.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
require 'net/imap'
|
||||||
|
|
||||||
|
class Channel::EmailSend
|
||||||
|
def send(attr, notification = false)
|
||||||
|
channel = Channel.where( :area => 'Email::Outbound', :active => true ).first
|
||||||
|
begin
|
||||||
|
c = eval 'Channel::' + channel[:adapter] + '.new'
|
||||||
|
c.send(attr, channel, notification)
|
||||||
|
rescue Exception => e
|
||||||
|
puts "can't use " + 'Channel::' + channel[:adapter]
|
||||||
|
puts e.inspect
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -4,7 +4,7 @@ require 'net/imap'
|
||||||
|
|
||||||
class Channel::IMAP < Channel::EmailParser
|
class Channel::IMAP < Channel::EmailParser
|
||||||
|
|
||||||
def fetch (channel)
|
def fetch (channel, check_type = '', verify_string = '')
|
||||||
ssl = false
|
ssl = false
|
||||||
port = 143
|
port = 143
|
||||||
if channel[:options][:ssl].to_s == 'true'
|
if channel[:options][:ssl].to_s == 'true'
|
||||||
|
@ -30,19 +30,39 @@ class Channel::IMAP < Channel::EmailParser
|
||||||
else
|
else
|
||||||
@imap.select( channel[:options][:folder] )
|
@imap.select( channel[:options][:folder] )
|
||||||
end
|
end
|
||||||
|
if check_type == 'check'
|
||||||
|
puts "check only mode, fetch no emails"
|
||||||
|
disconnect
|
||||||
|
return
|
||||||
|
elsif check_type == 'verify'
|
||||||
|
puts "verify mode, fetch no emails #{verify_string}"
|
||||||
|
end
|
||||||
count = 0
|
count = 0
|
||||||
count_all = @imap.search(['ALL']).count
|
count_all = @imap.search(['ALL']).count
|
||||||
@imap.search(['ALL']).each do |message_id|
|
@imap.search(['ALL']).each do |message_id|
|
||||||
count += 1
|
count += 1
|
||||||
puts " - message #{count.to_s}/#{count_all.to_s}"
|
puts " - message #{count.to_s}/#{count_all.to_s}"
|
||||||
msg = @imap.fetch(message_id,'RFC822')[0].attr['RFC822']
|
|
||||||
# puts msg.to_s
|
# puts msg.to_s
|
||||||
|
|
||||||
|
# check for verify message
|
||||||
|
if check_type == 'verify'
|
||||||
|
subject = @imap.fetch(message_id,'ENVELOPE')[0].attr['ENVELOPE'].subject
|
||||||
|
if subject && subject =~ /#{verify_string}/
|
||||||
|
puts " - verify email #{verify_string} found"
|
||||||
|
@imap.store(message_id, "+FLAGS", [:Deleted])
|
||||||
|
@imap.expunge()
|
||||||
|
disconnect
|
||||||
|
return 'verify ok'
|
||||||
|
end
|
||||||
|
else
|
||||||
|
|
||||||
# delete email from server after article was created
|
# delete email from server after article was created
|
||||||
|
msg = @imap.fetch(message_id,'RFC822')[0].attr['RFC822']
|
||||||
if process(channel, msg)
|
if process(channel, msg)
|
||||||
@imap.store(message_id, "+FLAGS", [:Deleted])
|
@imap.store(message_id, "+FLAGS", [:Deleted])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
@imap.expunge()
|
@imap.expunge()
|
||||||
disconnect
|
disconnect
|
||||||
if count == 0
|
if count == 0
|
||||||
|
@ -56,15 +76,4 @@ class Channel::IMAP < Channel::EmailParser
|
||||||
@imap.disconnect()
|
@imap.disconnect()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def send(attr, notification = false)
|
|
||||||
channel = Channel.where( :area => 'Email::Outbound', :active => true ).first
|
|
||||||
begin
|
|
||||||
c = eval 'Channel::' + channel[:adapter] + '.new'
|
|
||||||
c.send(attr, channel, notification)
|
|
||||||
rescue Exception => e
|
|
||||||
puts "can't use " + 'Channel::' + channel[:adapter]
|
|
||||||
puts e.inspect
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
|
@ -4,7 +4,7 @@ require 'net/pop'
|
||||||
|
|
||||||
class Channel::POP3 < Channel::EmailParser
|
class Channel::POP3 < Channel::EmailParser
|
||||||
|
|
||||||
def fetch (channel)
|
def fetch (channel, check_type = '')
|
||||||
ssl = false
|
ssl = false
|
||||||
port = 110
|
port = 110
|
||||||
if channel[:options][:ssl].to_s == 'true'
|
if channel[:options][:ssl].to_s == 'true'
|
||||||
|
@ -19,17 +19,36 @@ class Channel::POP3 < Channel::EmailParser
|
||||||
@pop.enable_ssl
|
@pop.enable_ssl
|
||||||
end
|
end
|
||||||
@pop.start( channel[:options][:user], channel[:options][:password] )
|
@pop.start( channel[:options][:user], channel[:options][:password] )
|
||||||
|
if check_type == 'check'
|
||||||
|
puts "check only mode, fetch no emails"
|
||||||
|
disconnect
|
||||||
|
return
|
||||||
|
elsif check_type == 'verify'
|
||||||
|
puts "verify mode, fetch no emails"
|
||||||
|
end
|
||||||
count = 0
|
count = 0
|
||||||
count_all = @pop.mails.size
|
count_all = @pop.mails.size
|
||||||
@pop.each_mail do |m|
|
@pop.each_mail do |m|
|
||||||
count += 1
|
count += 1
|
||||||
puts " - message #{count.to_s}/#{count_all.to_s}"
|
puts " - message #{count.to_s}/#{count_all.to_s}"
|
||||||
|
|
||||||
|
# check for verify message
|
||||||
|
if check_type == 'verify'
|
||||||
|
mail = m.pop
|
||||||
|
if mail && mail =~ /#{verify_string}/
|
||||||
|
puts " - verify email #{verify_string} found"
|
||||||
|
m.delete
|
||||||
|
disconnect
|
||||||
|
return 'verify ok'
|
||||||
|
end
|
||||||
|
else
|
||||||
|
|
||||||
# delete email from server after article was created
|
# delete email from server after article was created
|
||||||
if process(channel, m.pop)
|
if process(channel, m.pop)
|
||||||
m.delete
|
m.delete
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
disconnect
|
disconnect
|
||||||
if count == 0
|
if count == 0
|
||||||
puts " - no message"
|
puts " - no message"
|
||||||
|
@ -43,14 +62,4 @@ class Channel::POP3 < Channel::EmailParser
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def send(attr, notification = false)
|
|
||||||
channel = Channel.where( :area => 'Email::Outbound', :active => true ).first
|
|
||||||
begin
|
|
||||||
c = eval 'Channel::' + channel[:adapter] + '.new'
|
|
||||||
c.send(attr, channel, notification)
|
|
||||||
rescue Exception => e
|
|
||||||
puts "can't use " + 'Channel::' + channel[:adapter]
|
|
||||||
puts e.inspect
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
|
@ -10,7 +10,7 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
|
||||||
subject = ticket.subject_build( record.subject )
|
subject = ticket.subject_build( record.subject )
|
||||||
|
|
||||||
# send email
|
# send email
|
||||||
a = Channel::IMAP.new
|
a = Channel::EmailSend.new
|
||||||
message = a.send(
|
message = a.send(
|
||||||
{
|
{
|
||||||
:message_id => record.message_id,
|
:message_id => record.message_id,
|
||||||
|
|
|
@ -3,5 +3,8 @@ Zammad::Application.routes.draw do
|
||||||
|
|
||||||
# getting_started
|
# getting_started
|
||||||
match api_path + '/getting_started', :to => 'getting_started#index', :via => :get
|
match api_path + '/getting_started', :to => 'getting_started#index', :via => :get
|
||||||
|
match api_path + '/getting_started/base_fqdn', :to => 'getting_started#base_fqdn', :via => :post
|
||||||
|
match api_path + '/getting_started/base_outbound', :to => 'getting_started#base_outbound', :via => :post
|
||||||
|
match api_path + '/getting_started/base_inbound', :to => 'getting_started#base_inbound', :via => :post
|
||||||
|
|
||||||
end
|
end
|
|
@ -402,7 +402,7 @@ class UpdateObjectManager5 < ActiveRecord::Migration
|
||||||
:screens => {
|
:screens => {
|
||||||
:signup => {
|
:signup => {
|
||||||
'-all-' => {
|
'-all-' => {
|
||||||
:null => true,
|
:null => false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
:invite_agent => {},
|
:invite_agent => {},
|
||||||
|
|
|
@ -49,9 +49,8 @@ module NotificationFactory
|
||||||
|
|
||||||
def self.send(data)
|
def self.send(data)
|
||||||
sender = Setting.get('notification_sender')
|
sender = Setting.get('notification_sender')
|
||||||
a = Channel::IMAP.new
|
|
||||||
Rails.logger.info "NOTICE: SEND NOTIFICATION TO: #{data[:recipient][:email]}"
|
Rails.logger.info "NOTICE: SEND NOTIFICATION TO: #{data[:recipient][:email]}"
|
||||||
message = a.send(
|
Channel::EmailSend.new.send(
|
||||||
{
|
{
|
||||||
# :in_reply_to => self.in_reply_to,
|
# :in_reply_to => self.in_reply_to,
|
||||||
:from => sender,
|
:from => sender,
|
||||||
|
|
Loading…
Reference in a new issue