Updated rubocop to latest version (0.59.2) and applied required changes.
This commit is contained in:
parent
3d4d5414f1
commit
9af50f2a4e
536 changed files with 1327 additions and 340 deletions
|
@ -1,5 +1,5 @@
|
||||||
# Default enabled cops
|
# Default enabled cops
|
||||||
# https://github.com/bbatsov/rubocop/blob/master/config/enabled.yml
|
# https://github.com/rubocop-hq/rubocop/blob/master/config/default.yml
|
||||||
|
|
||||||
inherit_from: .rubocop_todo.yml
|
inherit_from: .rubocop_todo.yml
|
||||||
|
|
||||||
|
@ -144,6 +144,10 @@ Style/BracesAroundHashParameters:
|
||||||
Description: 'Enforce braces style around hash parameters.'
|
Description: 'Enforce braces style around hash parameters.'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/BulkChangeTable:
|
||||||
|
Description: 'Check whether alter queries are combinable.'
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
Rails/FindEach:
|
Rails/FindEach:
|
||||||
Description: 'Prefer all.find_each over all.find.'
|
Description: 'Prefer all.find_each over all.find.'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
|
@ -40,6 +40,14 @@ Rails/ApplicationRecord:
|
||||||
Description: 'Check that models subclass ApplicationRecord.'
|
Description: 'Check that models subclass ApplicationRecord.'
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
# Browser-Tests inherit from TestCase < Test::Unit::TestCase
|
||||||
|
# which does not provide assert_not
|
||||||
|
Rails/AssertNot:
|
||||||
|
Description: 'Use `assert_not` instead of `assert !`.'
|
||||||
|
Enabled: true
|
||||||
|
Exclude:
|
||||||
|
- "test/browser/*"
|
||||||
|
|
||||||
Rails/CreateTableWithTimestamps:
|
Rails/CreateTableWithTimestamps:
|
||||||
Description: >-
|
Description: >-
|
||||||
Checks the migration for which timestamps are not included
|
Checks the migration for which timestamps are not included
|
||||||
|
|
14
Gemfile.lock
14
Gemfile.lock
|
@ -203,6 +203,7 @@ GEM
|
||||||
ice_cube (0.16.2)
|
ice_cube (0.16.2)
|
||||||
inflection (1.0.0)
|
inflection (1.0.0)
|
||||||
interception (0.5)
|
interception (0.5)
|
||||||
|
jaro_winkler (1.5.1)
|
||||||
json (2.1.0)
|
json (2.1.0)
|
||||||
jwt (1.5.6)
|
jwt (1.5.6)
|
||||||
kgio (2.11.0)
|
kgio (2.11.0)
|
||||||
|
@ -293,12 +294,12 @@ GEM
|
||||||
omniauth (~> 1.5)
|
omniauth (~> 1.5)
|
||||||
omniauth-oauth2 (>= 1.4.0)
|
omniauth-oauth2 (>= 1.4.0)
|
||||||
parallel (1.12.1)
|
parallel (1.12.1)
|
||||||
parser (2.5.0.5)
|
parser (2.5.1.2)
|
||||||
ast (~> 2.4.0)
|
ast (~> 2.4.0)
|
||||||
pg (0.21.0)
|
pg (0.21.0)
|
||||||
pluginator (1.5.0)
|
pluginator (1.5.0)
|
||||||
power_assert (1.1.1)
|
power_assert (1.1.1)
|
||||||
powerpack (0.1.1)
|
powerpack (0.1.2)
|
||||||
pre-commit (0.37.0)
|
pre-commit (0.37.0)
|
||||||
pluginator (~> 1.5)
|
pluginator (~> 1.5)
|
||||||
pry (0.11.3)
|
pry (0.11.3)
|
||||||
|
@ -377,14 +378,15 @@ GEM
|
||||||
rspec-mocks (~> 3.8.0)
|
rspec-mocks (~> 3.8.0)
|
||||||
rspec-support (~> 3.8.0)
|
rspec-support (~> 3.8.0)
|
||||||
rspec-support (3.8.0)
|
rspec-support (3.8.0)
|
||||||
rubocop (0.54.0)
|
rubocop (0.59.2)
|
||||||
|
jaro_winkler (~> 1.5.1)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
parser (>= 2.5)
|
parser (>= 2.5, != 2.5.1.1)
|
||||||
powerpack (~> 0.1)
|
powerpack (~> 0.1)
|
||||||
rainbow (>= 2.2.2, < 4.0)
|
rainbow (>= 2.2.2, < 4.0)
|
||||||
ruby-progressbar (~> 1.7)
|
ruby-progressbar (~> 1.7)
|
||||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||||
ruby-progressbar (1.9.0)
|
ruby-progressbar (1.10.0)
|
||||||
ruby_dep (1.5.0)
|
ruby_dep (1.5.0)
|
||||||
rubyzip (1.2.2)
|
rubyzip (1.2.2)
|
||||||
safe_yaml (1.0.4)
|
safe_yaml (1.0.4)
|
||||||
|
@ -463,7 +465,7 @@ GEM
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.7.5)
|
unf_ext (0.0.7.5)
|
||||||
unicode-display_width (1.3.0)
|
unicode-display_width (1.4.0)
|
||||||
unicorn (5.3.1)
|
unicorn (5.3.1)
|
||||||
kgio (~> 2.6)
|
kgio (~> 2.6)
|
||||||
raindrops (~> 0.7)
|
raindrops (~> 0.7)
|
||||||
|
|
|
@ -15,10 +15,12 @@ module ApplicationController::Authenticates
|
||||||
permission: key,
|
permission: key,
|
||||||
)
|
)
|
||||||
return false if user
|
return false if user
|
||||||
|
|
||||||
raise Exceptions::NotAuthorized, 'Not authorized (token)!'
|
raise Exceptions::NotAuthorized, 'Not authorized (token)!'
|
||||||
end
|
end
|
||||||
|
|
||||||
return false if current_user&.permissions?(key)
|
return false if current_user&.permissions?(key)
|
||||||
|
|
||||||
raise Exceptions::NotAuthorized, 'Not authorized (user)!'
|
raise Exceptions::NotAuthorized, 'Not authorized (user)!'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -68,6 +70,7 @@ module ApplicationController::Authenticates
|
||||||
if Setting.get('api_password_access') == false
|
if Setting.get('api_password_access') == false
|
||||||
raise Exceptions::NotAuthorized, 'API password access disabled!'
|
raise Exceptions::NotAuthorized, 'API password access disabled!'
|
||||||
end
|
end
|
||||||
|
|
||||||
user = User.authenticate(username, password)
|
user = User.authenticate(username, password)
|
||||||
return authentication_check_prerequesits(user, 'basic_auth', auth_param) if user
|
return authentication_check_prerequesits(user, 'basic_auth', auth_param) if user
|
||||||
end
|
end
|
||||||
|
@ -79,6 +82,7 @@ module ApplicationController::Authenticates
|
||||||
if Setting.get('api_token_access') == false
|
if Setting.get('api_token_access') == false
|
||||||
raise Exceptions::NotAuthorized, 'API token access disabled!'
|
raise Exceptions::NotAuthorized, 'API token access disabled!'
|
||||||
end
|
end
|
||||||
|
|
||||||
user = Token.check(
|
user = Token.check(
|
||||||
action: 'api',
|
action: 'api',
|
||||||
name: token_string,
|
name: token_string,
|
||||||
|
|
|
@ -5,6 +5,7 @@ module ApplicationController::ChecksMaintainance
|
||||||
|
|
||||||
def check_maintenance(user)
|
def check_maintenance(user)
|
||||||
return false if !check_maintenance_only(user)
|
return false if !check_maintenance_only(user)
|
||||||
|
|
||||||
raise Exceptions::NotAuthorized, 'Maintenance mode enabled!'
|
raise Exceptions::NotAuthorized, 'Maintenance mode enabled!'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -12,6 +13,7 @@ module ApplicationController::ChecksMaintainance
|
||||||
def check_maintenance_only(user)
|
def check_maintenance_only(user)
|
||||||
return false if Setting.get('maintenance_mode') != true
|
return false if Setting.get('maintenance_mode') != true
|
||||||
return false if user.permissions?('admin.maintenance')
|
return false if user.permissions?('admin.maintenance')
|
||||||
|
|
||||||
Rails.logger.info "Maintenance mode enabled, denied login for user #{user.login}, it's no admin user."
|
Rails.logger.info "Maintenance mode enabled, denied login for user #{user.login}, it's no admin user."
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,7 @@ module ApplicationController::HandlesDevices
|
||||||
|
|
||||||
def user_device_check
|
def user_device_check
|
||||||
return false if !user_device_log(current_user, 'session')
|
return false if !user_device_log(current_user, 'session')
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ module ApplicationController::HandlesDevices
|
||||||
# if ip has not changed and ttl in still valid
|
# if ip has not changed and ttl in still valid
|
||||||
remote_ip = ENV['TEST_REMOTE_IP'] || request.remote_ip
|
remote_ip = ENV['TEST_REMOTE_IP'] || request.remote_ip
|
||||||
return true if time_to_check == false && session[:user_device_remote_ip] == remote_ip
|
return true if time_to_check == false && session[:user_device_remote_ip] == remote_ip
|
||||||
|
|
||||||
session[:user_device_remote_ip] = remote_ip
|
session[:user_device_remote_ip] = remote_ip
|
||||||
|
|
||||||
# for sessions we need the fingperprint
|
# for sessions we need the fingperprint
|
||||||
|
@ -46,6 +48,7 @@ module ApplicationController::HandlesDevices
|
||||||
if !session[:user_device_updated_at] && !params[:fingerprint] && !session[:user_device_fingerprint]
|
if !session[:user_device_updated_at] && !params[:fingerprint] && !session[:user_device_fingerprint]
|
||||||
raise Exceptions::UnprocessableEntity, 'Need fingerprint param!'
|
raise Exceptions::UnprocessableEntity, 'Need fingerprint param!'
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:fingerprint]
|
if params[:fingerprint]
|
||||||
UserDevice.fingerprint_validation(params[:fingerprint])
|
UserDevice.fingerprint_validation(params[:fingerprint])
|
||||||
session[:user_device_fingerprint] = params[:fingerprint]
|
session[:user_device_fingerprint] = params[:fingerprint]
|
||||||
|
|
|
@ -17,6 +17,7 @@ module ApplicationController::HasResponseExtentions
|
||||||
return true if params[:full] == 'true'
|
return true if params[:full] == 'true'
|
||||||
return true if params[:full] == 1
|
return true if params[:full] == 1
|
||||||
return true if params[:full] == '1'
|
return true if params[:full] == '1'
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ module ApplicationController::HasResponseExtentions
|
||||||
return true if params[:all] == 'true'
|
return true if params[:all] == 'true'
|
||||||
return true if params[:all] == 1
|
return true if params[:all] == 1
|
||||||
return true if params[:all] == '1'
|
return true if params[:all] == '1'
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ module ApplicationController::HasUser
|
||||||
def current_user
|
def current_user
|
||||||
user_on_behalf = current_user_on_behalf
|
user_on_behalf = current_user_on_behalf
|
||||||
return user_on_behalf if user_on_behalf
|
return user_on_behalf if user_on_behalf
|
||||||
|
|
||||||
current_user_real
|
current_user_real
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ module ApplicationController::HasUser
|
||||||
def current_user_real
|
def current_user_real
|
||||||
return @_current_user if @_current_user
|
return @_current_user if @_current_user
|
||||||
return if !session[:user_id]
|
return if !session[:user_id]
|
||||||
|
|
||||||
@_current_user = User.lookup(id: session[:user_id])
|
@_current_user = User.lookup(id: session[:user_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -49,6 +51,7 @@ module ApplicationController::HasUser
|
||||||
search_attributes[field] = request.headers['X-On-Behalf-Of']
|
search_attributes[field] = request.headers['X-On-Behalf-Of']
|
||||||
@_user_on_behalf = User.find_by(search_attributes)
|
@_user_on_behalf = User.find_by(search_attributes)
|
||||||
next if !@_user_on_behalf
|
next if !@_user_on_behalf
|
||||||
|
|
||||||
return @_user_on_behalf
|
return @_user_on_behalf
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -89,11 +92,13 @@ module ApplicationController::HasUser
|
||||||
|
|
||||||
# fill user agent
|
# fill user agent
|
||||||
return if session[:user_agent]
|
return if session[:user_agent]
|
||||||
|
|
||||||
session[:user_agent] = request.env['HTTP_USER_AGENT']
|
session[:user_agent] = request.env['HTTP_USER_AGENT']
|
||||||
end
|
end
|
||||||
|
|
||||||
def valid_session_with_user
|
def valid_session_with_user
|
||||||
return true if current_user
|
return true if current_user
|
||||||
|
|
||||||
raise Exceptions::UnprocessableEntity, 'No session user!'
|
raise Exceptions::UnprocessableEntity, 'No session user!'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,6 +24,7 @@ module ApplicationController::LogsHttpAccess
|
||||||
}
|
}
|
||||||
request.headers.each do |key, value|
|
request.headers.each do |key, value|
|
||||||
next if key[0, 5] != 'HTTP_'
|
next if key[0, 5] != 'HTTP_'
|
||||||
|
|
||||||
request_data[:content] += if key == 'HTTP_COOKIE'
|
request_data[:content] += if key == 'HTTP_COOKIE'
|
||||||
"#{key}: xxxxx\n"
|
"#{key}: xxxxx\n"
|
||||||
else
|
else
|
||||||
|
|
|
@ -10,6 +10,7 @@ module ApplicationController::PreventsCsrf
|
||||||
|
|
||||||
def set_csrf_token_headers
|
def set_csrf_token_headers
|
||||||
return true if @_auth_type.present? && @_auth_type != 'session'
|
return true if @_auth_type.present? && @_auth_type != 'session'
|
||||||
|
|
||||||
headers['CSRF-TOKEN'] = form_authenticity_token
|
headers['CSRF-TOKEN'] = form_authenticity_token
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ module ApplicationController::PreventsCsrf
|
||||||
return true if request.head?
|
return true if request.head?
|
||||||
return true if %w[token_auth basic_auth].include?(@_auth_type)
|
return true if %w[token_auth basic_auth].include?(@_auth_type)
|
||||||
return true if valid_authenticity_token?(session, params[:authenticity_token] || request.headers['X-CSRF-Token'])
|
return true if valid_authenticity_token?(session, params[:authenticity_token] || request.headers['X-CSRF-Token'])
|
||||||
|
|
||||||
logger.info 'CSRF token verification failed'
|
logger.info 'CSRF token verification failed'
|
||||||
raise Exceptions::NotAuthorized, 'CSRF token verification failed!'
|
raise Exceptions::NotAuthorized, 'CSRF token verification failed!'
|
||||||
end
|
end
|
||||||
|
|
|
@ -156,6 +156,7 @@ module ApplicationController::RendersModels
|
||||||
generic_object = object.find(params[:id])
|
generic_object = object.find(params[:id])
|
||||||
result = Models.references(object, generic_object.id)
|
result = Models.references(object, generic_object.id)
|
||||||
return false if result.blank?
|
return false if result.blank?
|
||||||
|
|
||||||
raise Exceptions::UnprocessableEntity, 'Can\'t delete, object has references.'
|
raise Exceptions::UnprocessableEntity, 'Can\'t delete, object has references.'
|
||||||
rescue => e
|
rescue => e
|
||||||
raise Exceptions::UnprocessableEntity, e
|
raise Exceptions::UnprocessableEntity, e
|
||||||
|
|
|
@ -11,6 +11,7 @@ module ApplicationController::SetsHeaders
|
||||||
# For all responses in this controller, return the CORS access control headers.
|
# For all responses in this controller, return the CORS access control headers.
|
||||||
def set_access_control_headers
|
def set_access_control_headers
|
||||||
return if @_auth_type != 'token_auth' && @_auth_type != 'basic_auth'
|
return if @_auth_type != 'token_auth' && @_auth_type != 'basic_auth'
|
||||||
|
|
||||||
set_access_control_headers_execute
|
set_access_control_headers_execute
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,11 +27,13 @@ module ApplicationController::SetsHeaders
|
||||||
# text/plain.
|
# text/plain.
|
||||||
def cors_preflight_check
|
def cors_preflight_check
|
||||||
return true if @_auth_type != 'token_auth' && @_auth_type != 'basic_auth'
|
return true if @_auth_type != 'token_auth' && @_auth_type != 'basic_auth'
|
||||||
|
|
||||||
cors_preflight_check_execute
|
cors_preflight_check_execute
|
||||||
end
|
end
|
||||||
|
|
||||||
def cors_preflight_check_execute
|
def cors_preflight_check_execute
|
||||||
return true if request.method != 'OPTIONS'
|
return true if request.method != 'OPTIONS'
|
||||||
|
|
||||||
headers['Access-Control-Allow-Origin'] = '*'
|
headers['Access-Control-Allow-Origin'] = '*'
|
||||||
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, PATCH, OPTIONS'
|
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, PATCH, OPTIONS'
|
||||||
headers['Access-Control-Allow-Headers'] = 'Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Accept-Language'
|
headers['Access-Control-Allow-Headers'] = 'Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Accept-Language'
|
||||||
|
|
|
@ -29,6 +29,7 @@ class ChannelsEmailController < ApplicationController
|
||||||
end
|
end
|
||||||
EmailAddress.all.each do |email_address|
|
EmailAddress.all.each do |email_address|
|
||||||
next if system_online_service && email_address.preferences && email_address.preferences['online_service_disable']
|
next if system_online_service && email_address.preferences && email_address.preferences['online_service_disable']
|
||||||
|
|
||||||
email_address_ids.push email_address.id
|
email_address_ids.push email_address.id
|
||||||
assets = email_address.assets(assets)
|
assets = email_address.assets(assets)
|
||||||
if !email_address.channel_id || !email_address.active || !Channel.find_by(id: email_address.channel_id)
|
if !email_address.channel_id || !email_address.active || !Channel.find_by(id: email_address.channel_id)
|
||||||
|
@ -256,6 +257,7 @@ class ChannelsEmailController < ApplicationController
|
||||||
next if channel.options[:inbound][:options][:user] != result[:setting][:inbound][:options][:user]
|
next if channel.options[:inbound][:options][:user] != result[:setting][:inbound][:options][:user]
|
||||||
next if channel.options[:inbound][:options][:folder].to_s != result[:setting][:inbound][:options][:folder].to_s
|
next if channel.options[:inbound][:options][:folder].to_s != result[:setting][:inbound][:options][:folder].to_s
|
||||||
next if channel.id.to_s == channel_id.to_s
|
next if channel.id.to_s == channel_id.to_s
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
result: 'duplicate',
|
result: 'duplicate',
|
||||||
message: 'Account already exists!',
|
message: 'Account already exists!',
|
||||||
|
@ -267,6 +269,7 @@ class ChannelsEmailController < ApplicationController
|
||||||
|
|
||||||
def check_online_service
|
def check_online_service
|
||||||
return true if !Setting.get('system_online_service')
|
return true if !Setting.get('system_online_service')
|
||||||
|
|
||||||
raise Exceptions::NotAuthorized
|
raise Exceptions::NotAuthorized
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ module ChecksUserAttributesByCurrentUserPermission
|
||||||
return true if params[:id].present?
|
return true if params[:id].present?
|
||||||
return true if params[:role_ids]
|
return true if params[:role_ids]
|
||||||
return true if params[:roles]
|
return true if params[:roles]
|
||||||
|
|
||||||
params[:role_ids] = Role.signup_role_ids
|
params[:role_ids] = Role.signup_role_ids
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,8 +13,10 @@ module ClonesTicketArticleAttachments
|
||||||
attachments = []
|
attachments = []
|
||||||
article.attachments.each do |new_attachment|
|
article.attachments.each do |new_attachment|
|
||||||
next if new_attachment.preferences['content-alternative'] == true
|
next if new_attachment.preferences['content-alternative'] == true
|
||||||
|
|
||||||
if article.content_type.present? && article.content_type =~ %r{text/html}i
|
if article.content_type.present? && article.content_type =~ %r{text/html}i
|
||||||
next if new_attachment.preferences['content_disposition'].present? && new_attachment.preferences['content_disposition'] !~ /inline/
|
next if new_attachment.preferences['content_disposition'].present? && new_attachment.preferences['content_disposition'] !~ /inline/
|
||||||
|
|
||||||
if new_attachment.preferences['Content-ID'].present? && article.body.present?
|
if new_attachment.preferences['Content-ID'].present? && article.body.present?
|
||||||
next if article.body.match?(/#{Regexp.quote(new_attachment.preferences['Content-ID'])}/i)
|
next if article.body.match?(/#{Regexp.quote(new_attachment.preferences['Content-ID'])}/i)
|
||||||
end
|
end
|
||||||
|
@ -22,10 +24,12 @@ module ClonesTicketArticleAttachments
|
||||||
already_added = false
|
already_added = false
|
||||||
existing_attachments.each do |existing_attachment|
|
existing_attachments.each do |existing_attachment|
|
||||||
next if existing_attachment.filename != new_attachment.filename || existing_attachment.size != new_attachment.size
|
next if existing_attachment.filename != new_attachment.filename || existing_attachment.size != new_attachment.size
|
||||||
|
|
||||||
already_added = true
|
already_added = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
next if already_added == true
|
next if already_added == true
|
||||||
|
|
||||||
file = Store.add(
|
file = Store.add(
|
||||||
object: 'UploadCache',
|
object: 'UploadCache',
|
||||||
o_id: params[:form_id],
|
o_id: params[:form_id],
|
||||||
|
|
|
@ -84,12 +84,14 @@ module CreatesTicketArticles
|
||||||
# validation
|
# validation
|
||||||
['mime-type', 'filename', 'data'].each do |key|
|
['mime-type', 'filename', 'data'].each do |key|
|
||||||
next if attachment[key]
|
next if attachment[key]
|
||||||
|
|
||||||
raise Exceptions::UnprocessableEntity, "Attachment needs '#{key}' param for attachment with index '#{index}'"
|
raise Exceptions::UnprocessableEntity, "Attachment needs '#{key}' param for attachment with index '#{index}'"
|
||||||
end
|
end
|
||||||
|
|
||||||
preferences = {}
|
preferences = {}
|
||||||
['charset', 'mime-type'].each do |key|
|
['charset', 'mime-type'].each do |key|
|
||||||
next if !attachment[key]
|
next if !attachment[key]
|
||||||
|
|
||||||
store_key = key.tr('-', '_').camelize.gsub(/(.+)([A-Z])/, '\1_\2').tr('_', '-')
|
store_key = key.tr('-', '_').camelize.gsub(/(.+)([A-Z])/, '\1_\2').tr('_', '-')
|
||||||
preferences[store_key] = attachment[key]
|
preferences[store_key] = attachment[key]
|
||||||
end
|
end
|
||||||
|
|
|
@ -58,6 +58,7 @@ class ExternalCredentialsController < ApplicationController
|
||||||
if params[:id].present? && ExternalCredential.exists?(params[:id])
|
if params[:id].present? && ExternalCredential.exists?(params[:id])
|
||||||
external_credential = ExternalCredential.find(params[:id])
|
external_credential = ExternalCredential.find(params[:id])
|
||||||
raise 'No such ExternalCredential!' if !external_credential
|
raise 'No such ExternalCredential!' if !external_credential
|
||||||
|
|
||||||
authentication_check(permission: ["admin.channel_#{external_credential.name}"])
|
authentication_check(permission: ["admin.channel_#{external_credential.name}"])
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
|
@ -223,6 +223,7 @@ class FirstStepsController < ApplicationController
|
||||||
|
|
||||||
def access?
|
def access?
|
||||||
return true if current_user.permissions?(['admin', 'ticket.agent'])
|
return true if current_user.permissions?(['admin', 'ticket.agent'])
|
||||||
|
|
||||||
render json: []
|
render json: []
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
@ -243,10 +244,12 @@ class FirstStepsController < ApplicationController
|
||||||
test_ticket_active = false
|
test_ticket_active = false
|
||||||
end
|
end
|
||||||
return result if test_ticket_active
|
return result if test_ticket_active
|
||||||
|
|
||||||
result.each do |item|
|
result.each do |item|
|
||||||
items = []
|
items = []
|
||||||
item[:items].each do |local_item|
|
item[:items].each do |local_item|
|
||||||
next if local_item[:name] == 'Create a Test Ticket'
|
next if local_item[:name] == 'Create a Test Ticket'
|
||||||
|
|
||||||
items.push local_item
|
items.push local_item
|
||||||
end
|
end
|
||||||
item[:items] = items
|
item[:items] = items
|
||||||
|
|
|
@ -230,6 +230,7 @@ class FormController < ApplicationController
|
||||||
|
|
||||||
def fingerprint_exists?
|
def fingerprint_exists?
|
||||||
return true if params[:fingerprint].present? && params[:fingerprint].length > 30
|
return true if params[:fingerprint].present? && params[:fingerprint].length > 30
|
||||||
|
|
||||||
Rails.logger.info 'No fingerprint given!'
|
Rails.logger.info 'No fingerprint given!'
|
||||||
response_access_deny
|
response_access_deny
|
||||||
false
|
false
|
||||||
|
@ -238,6 +239,7 @@ class FormController < ApplicationController
|
||||||
def enabled?
|
def enabled?
|
||||||
return true if params[:test] && current_user && current_user.permissions?('admin.channel_formular')
|
return true if params[:test] && current_user && current_user.permissions?('admin.channel_formular')
|
||||||
return true if Setting.get('form_ticket_create')
|
return true if Setting.get('form_ticket_create')
|
||||||
|
|
||||||
response_access_deny
|
response_access_deny
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
|
@ -103,6 +103,7 @@ class ImportOtrsController < ApplicationController
|
||||||
|
|
||||||
def import_start
|
def import_start
|
||||||
return if setup_done_response
|
return if setup_done_response
|
||||||
|
|
||||||
Setting.set('import_mode', true)
|
Setting.set('import_mode', true)
|
||||||
welcome = Import::OTRS.connection_test
|
welcome = Import::OTRS.connection_test
|
||||||
if !welcome
|
if !welcome
|
||||||
|
@ -130,6 +131,7 @@ class ImportOtrsController < ApplicationController
|
||||||
dynamic_fields = Import::OTRS::Requester.load('DynamicField')
|
dynamic_fields = Import::OTRS::Requester.load('DynamicField')
|
||||||
dynamic_fields.each do |dynamic_field|
|
dynamic_fields.each do |dynamic_field|
|
||||||
next if dynamic_field['ValidID'].to_i != 1
|
next if dynamic_field['ValidID'].to_i != 1
|
||||||
|
|
||||||
dynamic_field_count += 1
|
dynamic_field_count += 1
|
||||||
end
|
end
|
||||||
if dynamic_field_count > 20
|
if dynamic_field_count > 20
|
||||||
|
@ -140,6 +142,7 @@ class ImportOtrsController < ApplicationController
|
||||||
sys_configs = Import::OTRS::Requester.load('SysConfig')
|
sys_configs = Import::OTRS::Requester.load('SysConfig')
|
||||||
sys_configs.each do |sys_config|
|
sys_configs.each do |sys_config|
|
||||||
next if sys_config['Key'] != 'Process'
|
next if sys_config['Key'] != 'Process'
|
||||||
|
|
||||||
issues.push 'otrsProcesses'
|
issues.push 'otrsProcesses'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -176,6 +179,7 @@ class ImportOtrsController < ApplicationController
|
||||||
if !setup_done
|
if !setup_done
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
setup_done: true,
|
setup_done: true,
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,7 @@ class ImportZendeskController < ApplicationController
|
||||||
|
|
||||||
def import_start
|
def import_start
|
||||||
return if setup_done_response
|
return if setup_done_response
|
||||||
|
|
||||||
Setting.set('import_mode', true)
|
Setting.set('import_mode', true)
|
||||||
Setting.set('import_backend', 'zendesk')
|
Setting.set('import_backend', 'zendesk')
|
||||||
|
|
||||||
|
@ -129,6 +130,7 @@ class ImportZendeskController < ApplicationController
|
||||||
if !setup_done
|
if !setup_done
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
setup_done: true,
|
setup_done: true,
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ UserAgent: #{request.env['HTTP_USER_AGENT']}
|
||||||
ticket_ids_found.each do |ticket_id|
|
ticket_ids_found.each do |ticket_id|
|
||||||
ticket = Ticket.find_by(id: ticket_id)
|
ticket = Ticket.find_by(id: ticket_id)
|
||||||
next if !ticket
|
next if !ticket
|
||||||
|
|
||||||
article = Ticket::Article.create!(
|
article = Ticket::Article.create!(
|
||||||
ticket_id: ticket_id,
|
ticket_id: ticket_id,
|
||||||
type_id: Ticket::Article::Type.find_by(name: 'web').id,
|
type_id: Ticket::Article::Type.find_by(name: 'web').id,
|
||||||
|
@ -84,6 +85,7 @@ UserAgent: #{request.env['HTTP_USER_AGENT']}
|
||||||
ticket_ids_found.each do |ticket_id|
|
ticket_ids_found.each do |ticket_id|
|
||||||
ticket = Ticket.find_by(id: ticket_id)
|
ticket = Ticket.find_by(id: ticket_id)
|
||||||
next if !ticket
|
next if !ticket
|
||||||
|
|
||||||
ticket.state_id = auto_close_state_id
|
ticket.state_id = auto_close_state_id
|
||||||
ticket.save!
|
ticket.save!
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,6 +48,7 @@ class Integration::CtiController < ApplicationController
|
||||||
routing_table.each do |row|
|
routing_table.each do |row|
|
||||||
dest = row[:dest].gsub(/\*/, '.+?')
|
dest = row[:dest].gsub(/\*/, '.+?')
|
||||||
next if to !~ /^#{dest}$/
|
next if to !~ /^#{dest}$/
|
||||||
|
|
||||||
from = row[:caller_id]
|
from = row[:caller_id]
|
||||||
data = {
|
data = {
|
||||||
action: 'dial',
|
action: 'dial',
|
||||||
|
|
|
@ -19,6 +19,7 @@ class Integration::LdapController < ApplicationController
|
||||||
rescue => e
|
rescue => e
|
||||||
# workaround for issue #1114
|
# workaround for issue #1114
|
||||||
raise if !e.message.end_with?(', 48, Inappropriate Authentication')
|
raise if !e.message.end_with?(', 48, Inappropriate Authentication')
|
||||||
|
|
||||||
# return empty result
|
# return empty result
|
||||||
{}
|
{}
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,6 +14,7 @@ class Integration::SipgateController < ApplicationController
|
||||||
# check if call need to be blocked
|
# check if call need to be blocked
|
||||||
block_caller_ids.each do |item|
|
block_caller_ids.each do |item|
|
||||||
next if item[:caller_id] != params['from']
|
next if item[:caller_id] != params['from']
|
||||||
|
|
||||||
xml = Builder::XmlMarkup.new(indent: 2)
|
xml = Builder::XmlMarkup.new(indent: 2)
|
||||||
xml.instruct!
|
xml.instruct!
|
||||||
content = xml.Response(onHangup: url, onAnswer: url) do
|
content = xml.Response(onHangup: url, onAnswer: url) do
|
||||||
|
@ -61,6 +62,7 @@ class Integration::SipgateController < ApplicationController
|
||||||
routing_table.each do |row|
|
routing_table.each do |row|
|
||||||
dest = row[:dest].gsub(/\*/, '.+?')
|
dest = row[:dest].gsub(/\*/, '.+?')
|
||||||
next if to !~ /^#{dest}$/
|
next if to !~ /^#{dest}$/
|
||||||
|
|
||||||
from = row[:caller_id]
|
from = row[:caller_id]
|
||||||
content = xml.Response(onHangup: url, onAnswer: url) do
|
content = xml.Response(onHangup: url, onAnswer: url) do
|
||||||
xml.Dial(callerId: from) { xml.Number(params[:to]) }
|
xml.Dial(callerId: from) { xml.Number(params[:to]) }
|
||||||
|
|
|
@ -103,8 +103,10 @@ class LongPollingController < ApplicationController
|
||||||
|
|
||||||
def client_id_verify
|
def client_id_verify
|
||||||
return if !params[:client_id]
|
return if !params[:client_id]
|
||||||
|
|
||||||
sessions = Sessions.sessions
|
sessions = Sessions.sessions
|
||||||
return if !sessions.include?(params[:client_id].to_s)
|
return if !sessions.include?(params[:client_id].to_s)
|
||||||
|
|
||||||
params[:client_id].to_s
|
params[:client_id].to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ curl http://localhost/api/v1/monitoring/health_check?token=XXX
|
||||||
message = "Channel: #{channel.area} in "
|
message = "Channel: #{channel.area} in "
|
||||||
%w[host user uid].each do |key|
|
%w[host user uid].each do |key|
|
||||||
next if channel.options[key].blank?
|
next if channel.options[key].blank?
|
||||||
|
|
||||||
message += "key:#{channel.options[key]};"
|
message += "key:#{channel.options[key]};"
|
||||||
end
|
end
|
||||||
issues.push "#{message} #{channel.last_log_in}"
|
issues.push "#{message} #{channel.last_log_in}"
|
||||||
|
@ -52,9 +53,11 @@ curl http://localhost/api/v1/monitoring/health_check?token=XXX
|
||||||
|
|
||||||
# outbound channel
|
# outbound channel
|
||||||
next if channel.status_out != 'error'
|
next if channel.status_out != 'error'
|
||||||
|
|
||||||
message = "Channel: #{channel.area} out "
|
message = "Channel: #{channel.area} out "
|
||||||
%w[host user uid].each do |key|
|
%w[host user uid].each do |key|
|
||||||
next if channel.options[key].blank?
|
next if channel.options[key].blank?
|
||||||
|
|
||||||
message += "key:#{channel.options[key]};"
|
message += "key:#{channel.options[key]};"
|
||||||
end
|
end
|
||||||
issues.push "#{message} #{channel.last_log_out}"
|
issues.push "#{message} #{channel.last_log_out}"
|
||||||
|
@ -76,6 +79,7 @@ curl http://localhost/api/v1/monitoring/health_check?token=XXX
|
||||||
Scheduler.where('active = ? AND period > 300', true).where.not(last_run: nil).order(last_run: :asc, period: :asc).each do |scheduler|
|
Scheduler.where('active = ? AND period > 300', true).where.not(last_run: nil).order(last_run: :asc, period: :asc).each do |scheduler|
|
||||||
diff = Time.zone.now - (scheduler.last_run + scheduler.period.seconds)
|
diff = Time.zone.now - (scheduler.last_run + scheduler.period.seconds)
|
||||||
next if diff < 8.minutes
|
next if diff < 8.minutes
|
||||||
|
|
||||||
issues.push "scheduler may not run (last execution of #{scheduler.method} #{helpers.time_ago_in_words(Time.zone.now - diff.seconds)} over) - please contact your system administrator"
|
issues.push "scheduler may not run (last execution of #{scheduler.method} #{helpers.time_ago_in_words(Time.zone.now - diff.seconds)} over) - please contact your system administrator"
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
@ -259,11 +263,13 @@ curl http://localhost/api/v1/monitoring/status?token=XXX
|
||||||
user = authentication_check_only(permission: 'admin.monitoring')
|
user = authentication_check_only(permission: 'admin.monitoring')
|
||||||
return if user
|
return if user
|
||||||
return if Setting.get('monitoring_token') == params[:token]
|
return if Setting.get('monitoring_token') == params[:token]
|
||||||
|
|
||||||
raise Exceptions::NotAuthorized
|
raise Exceptions::NotAuthorized
|
||||||
end
|
end
|
||||||
|
|
||||||
def access_check
|
def access_check
|
||||||
return if Permission.find_by(name: 'admin.monitoring', active: true)
|
return if Permission.find_by(name: 'admin.monitoring', active: true)
|
||||||
|
|
||||||
raise Exceptions::NotAuthorized
|
raise Exceptions::NotAuthorized
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ curl http://localhost/api/v1/online_notifications/#{id} -v -u #{login}:#{passwor
|
||||||
|
|
||||||
def show
|
def show
|
||||||
return if !access?
|
return if !access?
|
||||||
|
|
||||||
model_show_render(OnlineNotification, params)
|
model_show_render(OnlineNotification, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -131,6 +132,7 @@ curl http://localhost/api/v1/online_notifications -v -u #{login}:#{password} -H
|
||||||
|
|
||||||
def update
|
def update
|
||||||
return if !access?
|
return if !access?
|
||||||
|
|
||||||
model_update_render(OnlineNotification, params)
|
model_update_render(OnlineNotification, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -149,6 +151,7 @@ curl http://localhost/api/v1/online_notifications/{id}.json -v -u #{login}:#{pas
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
return if !access?
|
return if !access?
|
||||||
|
|
||||||
model_destroy_render(OnlineNotification, params)
|
model_destroy_render(OnlineNotification, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -190,6 +190,7 @@ curl http://localhost/api/v1/overviews_prio -v -u #{login}:#{password} -H "Conte
|
||||||
params[:prios].each do |overview_prio|
|
params[:prios].each do |overview_prio|
|
||||||
overview = Overview.find(overview_prio[0])
|
overview = Overview.find(overview_prio[0])
|
||||||
next if overview.prio == overview_prio[1]
|
next if overview.prio == overview_prio[1]
|
||||||
|
|
||||||
overview.prio = overview_prio[1]
|
overview.prio = overview_prio[1]
|
||||||
overview.save!
|
overview.save!
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,6 +30,7 @@ class ReportsController < ApplicationController
|
||||||
backend[:condition] = condition
|
backend[:condition] = condition
|
||||||
end
|
end
|
||||||
next if !backend[:adapter]
|
next if !backend[:adapter]
|
||||||
|
|
||||||
result[backend[:name]] = backend[:adapter].aggs(
|
result[backend[:name]] = backend[:adapter].aggs(
|
||||||
range_start: get_params[:start],
|
range_start: get_params[:start],
|
||||||
range_end: get_params[:stop],
|
range_end: get_params[:stop],
|
||||||
|
@ -75,6 +76,7 @@ class ReportsController < ApplicationController
|
||||||
result = {}
|
result = {}
|
||||||
get_params[:metric][:backend].each do |backend|
|
get_params[:metric][:backend].each do |backend|
|
||||||
next if params[:downloadBackendSelected] != backend[:name]
|
next if params[:downloadBackendSelected] != backend[:name]
|
||||||
|
|
||||||
condition = get_params[:profile].condition
|
condition = get_params[:profile].condition
|
||||||
if backend[:condition]
|
if backend[:condition]
|
||||||
backend[:condition].merge(condition)
|
backend[:condition].merge(condition)
|
||||||
|
@ -82,6 +84,7 @@ class ReportsController < ApplicationController
|
||||||
backend[:condition] = condition
|
backend[:condition] = condition
|
||||||
end
|
end
|
||||||
next if !backend[:adapter]
|
next if !backend[:adapter]
|
||||||
|
|
||||||
result = backend[:adapter].items(
|
result = backend[:adapter].items(
|
||||||
range_start: get_params[:start],
|
range_start: get_params[:start],
|
||||||
range_end: get_params[:stop],
|
range_end: get_params[:stop],
|
||||||
|
@ -95,6 +98,7 @@ class ReportsController < ApplicationController
|
||||||
|
|
||||||
# generate sheet
|
# generate sheet
|
||||||
next if !params[:sheet]
|
next if !params[:sheet]
|
||||||
|
|
||||||
content = sheet(get_params[:profile], backend[:display], result)
|
content = sheet(get_params[:profile], backend[:display], result)
|
||||||
send_data(
|
send_data(
|
||||||
content,
|
content,
|
||||||
|
@ -113,11 +117,13 @@ class ReportsController < ApplicationController
|
||||||
if !params[:profiles] && !params[:profile_id]
|
if !params[:profiles] && !params[:profile_id]
|
||||||
raise Exceptions::UnprocessableEntity, 'No such profiles param'
|
raise Exceptions::UnprocessableEntity, 'No such profiles param'
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:profile_id]
|
if params[:profile_id]
|
||||||
profile = Report::Profile.find(params[:profile_id])
|
profile = Report::Profile.find(params[:profile_id])
|
||||||
else
|
else
|
||||||
params[:profiles].each do |profile_id, active|
|
params[:profiles].each do |profile_id, active|
|
||||||
next if !active
|
next if !active
|
||||||
|
|
||||||
profile = Report::Profile.find(profile_id)
|
profile = Report::Profile.find(profile_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -129,6 +135,7 @@ class ReportsController < ApplicationController
|
||||||
if !local_config || !local_config[:metric] || !local_config[:metric][params[:metric].to_sym]
|
if !local_config || !local_config[:metric] || !local_config[:metric][params[:metric].to_sym]
|
||||||
raise Exceptions::UnprocessableEntity, "No such metric #{params[:metric]}"
|
raise Exceptions::UnprocessableEntity, "No such metric #{params[:metric]}"
|
||||||
end
|
end
|
||||||
|
|
||||||
metric = local_config[:metric][params[:metric].to_sym]
|
metric = local_config[:metric][params[:metric].to_sym]
|
||||||
|
|
||||||
#{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year", "report"=>{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year"}}
|
#{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year", "report"=>{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year"}}
|
||||||
|
|
|
@ -36,6 +36,7 @@ class SearchController < ApplicationController
|
||||||
local_class = object.constantize
|
local_class = object.constantize
|
||||||
preferences = local_class.search_preferences(current_user)
|
preferences = local_class.search_preferences(current_user)
|
||||||
next if !preferences
|
next if !preferences
|
||||||
|
|
||||||
objects_in_order_hash[preferences[:prio]] = local_class
|
objects_in_order_hash[preferences[:prio]] = local_class
|
||||||
end
|
end
|
||||||
objects_in_order_hash.keys.sort.reverse_each do |prio|
|
objects_in_order_hash.keys.sort.reverse_each do |prio|
|
||||||
|
@ -53,6 +54,7 @@ class SearchController < ApplicationController
|
||||||
objects.each do |object|
|
objects.each do |object|
|
||||||
preferences = object.constantize.search_preferences(current_user)
|
preferences = object.constantize.search_preferences(current_user)
|
||||||
next if !preferences
|
next if !preferences
|
||||||
|
|
||||||
if preferences[:direct_search_index]
|
if preferences[:direct_search_index]
|
||||||
objects_with_direct_search_index.push object
|
objects_with_direct_search_index.push object
|
||||||
else
|
else
|
||||||
|
@ -68,6 +70,7 @@ class SearchController < ApplicationController
|
||||||
local_class = Kernel.const_get(item[:type])
|
local_class = Kernel.const_get(item[:type])
|
||||||
record = local_class.lookup(id: item[:id])
|
record = local_class.lookup(id: item[:id])
|
||||||
next if !record
|
next if !record
|
||||||
|
|
||||||
assets = record.assets(assets)
|
assets = record.assets(assets)
|
||||||
item[:type] = local_class.to_app_model.to_s
|
item[:type] = local_class.to_app_model.to_s
|
||||||
result.push item
|
result.push item
|
||||||
|
@ -87,6 +90,7 @@ class SearchController < ApplicationController
|
||||||
objects_in_order.each do |object|
|
objects_in_order.each do |object|
|
||||||
result.each do |item|
|
result.each do |item|
|
||||||
next if item[:type] != object.to_app_model.to_s
|
next if item[:type] != object.to_app_model.to_s
|
||||||
|
|
||||||
item[:id] = item[:id].to_i
|
item[:id] = item[:id].to_i
|
||||||
result_in_order.push item
|
result_in_order.push item
|
||||||
end
|
end
|
||||||
|
|
|
@ -45,5 +45,5 @@ module ExtraCollection
|
||||||
|
|
||||||
[collections, assets]
|
[collections, assets]
|
||||||
end
|
end
|
||||||
module_function :session
|
module_function :session # rubocop:disable Style/AccessModifierDeclarations
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,9 +10,10 @@ module ExtraCollection
|
||||||
key: 'dashboard',
|
key: 'dashboard',
|
||||||
)
|
)
|
||||||
return [collections, assets] if !item
|
return [collections, assets] if !item
|
||||||
|
|
||||||
collections['StatsStore'] = [item]
|
collections['StatsStore'] = [item]
|
||||||
|
|
||||||
[collections, assets]
|
[collections, assets]
|
||||||
end
|
end
|
||||||
module_function :session
|
module_function :session # rubocop:disable Style/AccessModifierDeclarations
|
||||||
end
|
end
|
||||||
|
|
|
@ -44,5 +44,5 @@ module ExtraCollection
|
||||||
end
|
end
|
||||||
[collections, assets]
|
[collections, assets]
|
||||||
end
|
end
|
||||||
module_function :session
|
module_function :session # rubocop:disable Style/AccessModifierDeclarations
|
||||||
end
|
end
|
||||||
|
|
|
@ -288,10 +288,13 @@ class SessionsController < ApplicationController
|
||||||
sessions_clean = []
|
sessions_clean = []
|
||||||
SessionHelper.list.each do |session|
|
SessionHelper.list.each do |session|
|
||||||
next if session.data['user_id'].blank?
|
next if session.data['user_id'].blank?
|
||||||
|
|
||||||
sessions_clean.push session
|
sessions_clean.push session
|
||||||
next if session.data['user_id']
|
next if session.data['user_id']
|
||||||
|
|
||||||
user = User.lookup(id: session.data['user_id'])
|
user = User.lookup(id: session.data['user_id'])
|
||||||
next if !user
|
next if !user
|
||||||
|
|
||||||
assets = user.assets(assets)
|
assets = user.assets(assets)
|
||||||
end
|
end
|
||||||
render json: {
|
render json: {
|
||||||
|
@ -314,8 +317,10 @@ class SessionsController < ApplicationController
|
||||||
config = {}
|
config = {}
|
||||||
Setting.select('name, preferences').where(frontend: true).each do |setting|
|
Setting.select('name, preferences').where(frontend: true).each do |setting|
|
||||||
next if setting.preferences[:authentication] == true && !current_user
|
next if setting.preferences[:authentication] == true && !current_user
|
||||||
|
|
||||||
value = Setting.get(setting.name)
|
value = Setting.get(setting.name)
|
||||||
next if !current_user && (value == false || value.nil?)
|
next if !current_user && (value == false || value.nil?)
|
||||||
|
|
||||||
config[setting.name] = value
|
config[setting.name] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ class SettingsController < ApplicationController
|
||||||
list = []
|
list = []
|
||||||
Setting.all.each do |setting|
|
Setting.all.each do |setting|
|
||||||
next if setting.preferences[:permission] && !current_user.permissions?(setting.preferences[:permission])
|
next if setting.preferences[:permission] && !current_user.permissions?(setting.preferences[:permission])
|
||||||
|
|
||||||
list.push setting
|
list.push setting
|
||||||
end
|
end
|
||||||
render json: list, status: :ok
|
render json: list, status: :ok
|
||||||
|
|
|
@ -44,6 +44,7 @@ class TicketArticlesController < ApplicationController
|
||||||
|
|
||||||
# ignore internal article if customer is requesting
|
# ignore internal article if customer is requesting
|
||||||
next if article.internal == true && current_user.permissions?('ticket.customer')
|
next if article.internal == true && current_user.permissions?('ticket.customer')
|
||||||
|
|
||||||
result = article.attributes_with_association_names
|
result = article.attributes_with_association_names
|
||||||
articles.push result
|
articles.push result
|
||||||
end
|
end
|
||||||
|
@ -74,6 +75,7 @@ class TicketArticlesController < ApplicationController
|
||||||
|
|
||||||
# ignore internal article if customer is requesting
|
# ignore internal article if customer is requesting
|
||||||
next if article.internal == true && current_user.permissions?('ticket.customer')
|
next if article.internal == true && current_user.permissions?('ticket.customer')
|
||||||
|
|
||||||
articles.push article.attributes_with_association_names
|
articles.push article.attributes_with_association_names
|
||||||
end
|
end
|
||||||
render json: articles, status: :ok
|
render json: articles, status: :ok
|
||||||
|
@ -315,6 +317,7 @@ class TicketArticlesController < ApplicationController
|
||||||
if Setting.get('import_mode') != true
|
if Setting.get('import_mode') != true
|
||||||
raise 'Only can import tickets if system is in import mode.'
|
raise 'Only can import tickets if system is in import mode.'
|
||||||
end
|
end
|
||||||
|
|
||||||
result = Ticket::Article.csv_import(
|
result = Ticket::Article.csv_import(
|
||||||
string: params[:file].read.force_encoding('utf-8'),
|
string: params[:file].read.force_encoding('utf-8'),
|
||||||
parse_params: {
|
parse_params: {
|
||||||
|
@ -331,6 +334,7 @@ class TicketArticlesController < ApplicationController
|
||||||
disposition = params.fetch(:disposition, 'inline')
|
disposition = params.fetch(:disposition, 'inline')
|
||||||
valid_disposition = %w[inline attachment]
|
valid_disposition = %w[inline attachment]
|
||||||
return disposition if valid_disposition.include?(disposition)
|
return disposition if valid_disposition.include?(disposition)
|
||||||
|
|
||||||
raise Exceptions::NotAuthorized, "Invalid disposition #{disposition} requested. Only #{valid_disposition.join(', ')} are valid."
|
raise Exceptions::NotAuthorized, "Invalid disposition #{disposition} requested. Only #{valid_disposition.join(', ')} are valid."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,6 +31,7 @@ class TicketStatesController < ApplicationController
|
||||||
def destroy
|
def destroy
|
||||||
permission_check('admin.object')
|
permission_check('admin.object')
|
||||||
return if model_references_check(Ticket::State, params)
|
return if model_references_check(Ticket::State, params)
|
||||||
|
|
||||||
model_destroy_render(Ticket::State, params)
|
model_destroy_render(Ticket::State, params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -177,10 +177,13 @@ class TicketsController < ApplicationController
|
||||||
if params[:links].present?
|
if params[:links].present?
|
||||||
link = params[:links].permit!.to_h
|
link = params[:links].permit!.to_h
|
||||||
raise Exceptions::UnprocessableEntity, 'Invalid link structure' if !link.is_a? Hash
|
raise Exceptions::UnprocessableEntity, 'Invalid link structure' if !link.is_a? Hash
|
||||||
|
|
||||||
link.each do |target_object, link_types_with_object_ids|
|
link.each do |target_object, link_types_with_object_ids|
|
||||||
raise Exceptions::UnprocessableEntity, 'Invalid link structure (Object)' if !link_types_with_object_ids.is_a? Hash
|
raise Exceptions::UnprocessableEntity, 'Invalid link structure (Object)' if !link_types_with_object_ids.is_a? Hash
|
||||||
|
|
||||||
link_types_with_object_ids.each do |link_type, object_ids|
|
link_types_with_object_ids.each do |link_type, object_ids|
|
||||||
raise Exceptions::UnprocessableEntity, 'Invalid link structure (Object->LinkType)' if !object_ids.is_a? Array
|
raise Exceptions::UnprocessableEntity, 'Invalid link structure (Object->LinkType)' if !object_ids.is_a? Array
|
||||||
|
|
||||||
object_ids.each do |local_object_id|
|
object_ids.each do |local_object_id|
|
||||||
link = Link.add(
|
link = Link.add(
|
||||||
link_type: link_type,
|
link_type: link_type,
|
||||||
|
@ -342,6 +345,7 @@ class TicketsController < ApplicationController
|
||||||
recent_views.each do |recent_view|
|
recent_views.each do |recent_view|
|
||||||
next if recent_view.object.name != 'Ticket'
|
next if recent_view.object.name != 'Ticket'
|
||||||
next if recent_view.o_id == ticket.id
|
next if recent_view.o_id == ticket.id
|
||||||
|
|
||||||
ticket_ids_recent_viewed.push recent_view.o_id
|
ticket_ids_recent_viewed.push recent_view.o_id
|
||||||
recent_view_ticket = Ticket.find(recent_view.o_id)
|
recent_view_ticket = Ticket.find(recent_view.o_id)
|
||||||
assets = recent_view_ticket.assets(assets)
|
assets = recent_view_ticket.assets(assets)
|
||||||
|
@ -516,6 +520,7 @@ class TicketsController < ApplicationController
|
||||||
if !user
|
if !user
|
||||||
raise "No such user with id #{params[:user_id]}"
|
raise "No such user with id #{params[:user_id]}"
|
||||||
end
|
end
|
||||||
|
|
||||||
conditions = {
|
conditions = {
|
||||||
closed_ids: {
|
closed_ids: {
|
||||||
'ticket.state_id' => {
|
'ticket.state_id' => {
|
||||||
|
@ -557,6 +562,7 @@ class TicketsController < ApplicationController
|
||||||
if !organization
|
if !organization
|
||||||
raise "No such organization with id #{params[:organization_id]}"
|
raise "No such organization with id #{params[:organization_id]}"
|
||||||
end
|
end
|
||||||
|
|
||||||
conditions = {
|
conditions = {
|
||||||
closed_ids: {
|
closed_ids: {
|
||||||
'ticket.state_id' => {
|
'ticket.state_id' => {
|
||||||
|
@ -634,6 +640,7 @@ class TicketsController < ApplicationController
|
||||||
if Setting.get('import_mode') != true
|
if Setting.get('import_mode') != true
|
||||||
raise 'Only can import tickets if system is in import mode.'
|
raise 'Only can import tickets if system is in import mode.'
|
||||||
end
|
end
|
||||||
|
|
||||||
string = params[:data] || params[:file].read.force_encoding('utf-8')
|
string = params[:data] || params[:file].read.force_encoding('utf-8')
|
||||||
result = Ticket.csv_import(
|
result = Ticket.csv_import(
|
||||||
string: string,
|
string: string,
|
||||||
|
@ -652,6 +659,7 @@ class TicketsController < ApplicationController
|
||||||
|
|
||||||
return true if ticket.group.follow_up_possible != 'new_ticket' # check if the setting for follow_up_possible is disabled
|
return true if ticket.group.follow_up_possible != 'new_ticket' # check if the setting for follow_up_possible is disabled
|
||||||
return true if ticket.state.name != 'closed' # check if the ticket state is already closed
|
return true if ticket.state.name != 'closed' # check if the ticket state is already closed
|
||||||
|
|
||||||
raise Exceptions::UnprocessableEntity, 'Cannot follow up on a closed ticket. Please create a new ticket.'
|
raise Exceptions::UnprocessableEntity, 'Cannot follow up on a closed ticket. Please create a new ticket.'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ class TimeAccountingsController < ApplicationController
|
||||||
time_unit.each do |ticket_id, local_time_unit|
|
time_unit.each do |ticket_id, local_time_unit|
|
||||||
ticket = Ticket.lookup(id: ticket_id)
|
ticket = Ticket.lookup(id: ticket_id)
|
||||||
next if !ticket
|
next if !ticket
|
||||||
|
|
||||||
if !customers[ticket.customer_id]
|
if !customers[ticket.customer_id]
|
||||||
customers[ticket.customer_id] = '-'
|
customers[ticket.customer_id] = '-'
|
||||||
if ticket.customer_id
|
if ticket.customer_id
|
||||||
|
@ -264,6 +265,7 @@ class TimeAccountingsController < ApplicationController
|
||||||
time_unit.each do |ticket_id, local_time_unit|
|
time_unit.each do |ticket_id, local_time_unit|
|
||||||
ticket = Ticket.lookup(id: ticket_id)
|
ticket = Ticket.lookup(id: ticket_id)
|
||||||
next if !ticket
|
next if !ticket
|
||||||
|
|
||||||
if !customers[ticket.customer_id]
|
if !customers[ticket.customer_id]
|
||||||
organization = nil
|
organization = nil
|
||||||
if ticket.organization_id
|
if ticket.organization_id
|
||||||
|
@ -345,6 +347,7 @@ class TimeAccountingsController < ApplicationController
|
||||||
ticket = Ticket.lookup(id: ticket_id)
|
ticket = Ticket.lookup(id: ticket_id)
|
||||||
next if !ticket
|
next if !ticket
|
||||||
next if !ticket.organization_id
|
next if !ticket.organization_id
|
||||||
|
|
||||||
if !organizations[ticket.organization_id]
|
if !organizations[ticket.organization_id]
|
||||||
organizations[ticket.organization_id] = {
|
organizations[ticket.organization_id] = {
|
||||||
organization: Organization.lookup(id: ticket.organization_id).attributes,
|
organization: Organization.lookup(id: ticket.organization_id).attributes,
|
||||||
|
|
|
@ -41,6 +41,7 @@ curl http://localhost/api/v1/user_access_token -v -u #{login}:#{password}
|
||||||
keys = Object.const_get('Permission').with_parents(key)
|
keys = Object.const_get('Permission').with_parents(key)
|
||||||
keys.each do |local_key|
|
keys.each do |local_key|
|
||||||
next if local_permissions_new.key?([local_key])
|
next if local_permissions_new.key?([local_key])
|
||||||
|
|
||||||
if local_permissions[local_key] == true
|
if local_permissions[local_key] == true
|
||||||
local_permissions_new[local_key] = true
|
local_permissions_new[local_key] = true
|
||||||
next
|
next
|
||||||
|
@ -51,6 +52,7 @@ curl http://localhost/api/v1/user_access_token -v -u #{login}:#{password}
|
||||||
permissions = []
|
permissions = []
|
||||||
Permission.all.where(active: true).order(:name).each do |permission|
|
Permission.all.where(active: true).order(:name).each do |permission|
|
||||||
next if !local_permissions_new.key?(permission.name) && !current_user.permissions?(permission.name)
|
next if !local_permissions_new.key?(permission.name) && !current_user.permissions?(permission.name)
|
||||||
|
|
||||||
permission_attributes = permission.attributes
|
permission_attributes = permission.attributes
|
||||||
if local_permissions_new[permission.name] == false
|
if local_permissions_new[permission.name] == false
|
||||||
permission_attributes['preferences']['disabled'] = true
|
permission_attributes['preferences']['disabled'] = true
|
||||||
|
@ -93,6 +95,7 @@ curl http://localhost/api/v1/user_access_token -v -u #{login}:#{password} -H "Co
|
||||||
if params[:label].blank?
|
if params[:label].blank?
|
||||||
raise Exceptions::UnprocessableEntity, 'Need label!'
|
raise Exceptions::UnprocessableEntity, 'Need label!'
|
||||||
end
|
end
|
||||||
|
|
||||||
token = Token.create!(
|
token = Token.create!(
|
||||||
action: 'api',
|
action: 'api',
|
||||||
label: params[:label],
|
label: params[:label],
|
||||||
|
@ -124,6 +127,7 @@ curl http://localhost/api/v1/user_access_token/{id} -v -u #{login}:#{password} -
|
||||||
def destroy
|
def destroy
|
||||||
token = Token.find_by(action: 'api', user_id: current_user.id, id: params[:id])
|
token = Token.find_by(action: 'api', user_id: current_user.id, id: params[:id])
|
||||||
raise Exceptions::UnprocessableEntity, 'Unable to find api token!' if !token
|
raise Exceptions::UnprocessableEntity, 'Unable to find api token!' if !token
|
||||||
|
|
||||||
token.destroy!
|
token.destroy!
|
||||||
render json: {}, status: :ok
|
render json: {}, status: :ok
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,6 +36,7 @@ class UserDevicesController < ApplicationController
|
||||||
next if !session.data['user_id']
|
next if !session.data['user_id']
|
||||||
next if !session.data['user_device_id']
|
next if !session.data['user_device_id']
|
||||||
next if session.data['user_device_id'] != user_device.id
|
next if session.data['user_device_id'] != user_device.id
|
||||||
|
|
||||||
SessionHelper.destroy( session.id )
|
SessionHelper.destroy( session.id )
|
||||||
end
|
end
|
||||||
user_device.destroy
|
user_device.destroy
|
||||||
|
|
|
@ -411,6 +411,7 @@ class UsersController < ApplicationController
|
||||||
}
|
}
|
||||||
%i[role_ids permissions].each do |key|
|
%i[role_ids permissions].each do |key|
|
||||||
next if params[key].blank?
|
next if params[key].blank?
|
||||||
|
|
||||||
query_params[key] = params[key]
|
query_params[key] = params[key]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -827,6 +828,7 @@ curl http://localhost/api/v1/users/out_of_office -v -u #{login}:#{password} -H "
|
||||||
|
|
||||||
def out_of_office
|
def out_of_office
|
||||||
raise Exceptions::UnprocessableEntity, 'No current user!' if !current_user
|
raise Exceptions::UnprocessableEntity, 'No current user!' if !current_user
|
||||||
|
|
||||||
user = User.find(current_user.id)
|
user = User.find(current_user.id)
|
||||||
user.with_lock do
|
user.with_lock do
|
||||||
user.assign_attributes(
|
user.assign_attributes(
|
||||||
|
@ -1065,6 +1067,7 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
|
||||||
if Setting.get('password_min_2_lower_2_upper_characters').to_i == 1 && ( password !~ /[A-Z].*[A-Z]/ || password !~ /[a-z].*[a-z]/ )
|
if Setting.get('password_min_2_lower_2_upper_characters').to_i == 1 && ( password !~ /[A-Z].*[A-Z]/ || password !~ /[a-z].*[a-z]/ )
|
||||||
return ["Can't update password, it must contain at least 2 lowercase and 2 uppercase characters!"]
|
return ["Can't update password, it must contain at least 2 lowercase and 2 uppercase characters!"]
|
||||||
end
|
end
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -45,6 +45,7 @@ add a new activity entry for an object
|
||||||
if !permission
|
if !permission
|
||||||
raise "No such Permission #{data[:permission]}"
|
raise "No such Permission #{data[:permission]}"
|
||||||
end
|
end
|
||||||
|
|
||||||
permission_id = permission.id
|
permission_id = permission.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -43,12 +43,15 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
return data if !self['created_by_id']
|
return data if !self['created_by_id']
|
||||||
|
|
||||||
app_model_user = User.to_app_model
|
app_model_user = User.to_app_model
|
||||||
%w[created_by_id].each do |local_user_id|
|
%w[created_by_id].each do |local_user_id|
|
||||||
next if !self[ local_user_id ]
|
next if !self[ local_user_id ]
|
||||||
next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ]
|
next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ]
|
||||||
|
|
||||||
user = User.lookup(id: self[ local_user_id ])
|
user = User.lookup(id: self[ local_user_id ])
|
||||||
next if !user
|
next if !user
|
||||||
|
|
||||||
data = user.assets(data)
|
data = user.assets(data)
|
||||||
end
|
end
|
||||||
data
|
data
|
||||||
|
|
|
@ -32,12 +32,15 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
return data if !self['created_by_id'] && !self['updated_by_id']
|
return data if !self['created_by_id'] && !self['updated_by_id']
|
||||||
|
|
||||||
app_model_user = User.to_app_model
|
app_model_user = User.to_app_model
|
||||||
%w[created_by_id updated_by_id].each do |local_user_id|
|
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||||
next if !self[ local_user_id ]
|
next if !self[ local_user_id ]
|
||||||
next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ]
|
next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ]
|
||||||
|
|
||||||
user = User.lookup(id: self[ local_user_id ])
|
user = User.lookup(id: self[ local_user_id ])
|
||||||
next if !user
|
next if !user
|
||||||
|
|
||||||
data = user.assets(data)
|
data = user.assets(data)
|
||||||
end
|
end
|
||||||
data
|
data
|
||||||
|
@ -60,10 +63,12 @@ get assets and record_ids of selector
|
||||||
send(selector).each do |item, content|
|
send(selector).each do |item, content|
|
||||||
attribute = item.split(/\./)
|
attribute = item.split(/\./)
|
||||||
next if !attribute[1]
|
next if !attribute[1]
|
||||||
|
|
||||||
begin
|
begin
|
||||||
attribute_class = attribute[0].to_classname.constantize
|
attribute_class = attribute[0].to_classname.constantize
|
||||||
rescue => e
|
rescue => e
|
||||||
next if attribute[0] == 'article'
|
next if attribute[0] == 'article'
|
||||||
|
|
||||||
logger.error "Unable to get asset for '#{attribute[0]}': #{e.inspect}"
|
logger.error "Unable to get asset for '#{attribute[0]}': #{e.inspect}"
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
@ -73,12 +78,15 @@ get assets and record_ids of selector
|
||||||
next if !models[attribute_class][:reflections]
|
next if !models[attribute_class][:reflections]
|
||||||
next if !models[attribute_class][:reflections][reflection]
|
next if !models[attribute_class][:reflections][reflection]
|
||||||
next if !models[attribute_class][:reflections][reflection].klass
|
next if !models[attribute_class][:reflections][reflection].klass
|
||||||
|
|
||||||
attribute_ref_class = models[attribute_class][:reflections][reflection].klass
|
attribute_ref_class = models[attribute_class][:reflections][reflection].klass
|
||||||
if content['value'].instance_of?(Array)
|
if content['value'].instance_of?(Array)
|
||||||
content['value'].each do |item_id|
|
content['value'].each do |item_id|
|
||||||
next if item_id.blank?
|
next if item_id.blank?
|
||||||
|
|
||||||
attribute_object = attribute_ref_class.lookup(id: item_id)
|
attribute_object = attribute_ref_class.lookup(id: item_id)
|
||||||
next if !attribute_object
|
next if !attribute_object
|
||||||
|
|
||||||
assets = attribute_object.assets(assets)
|
assets = attribute_object.assets(assets)
|
||||||
end
|
end
|
||||||
elsif content['value'].present?
|
elsif content['value'].present?
|
||||||
|
|
|
@ -23,8 +23,10 @@ returns
|
||||||
group_ids: :group_ids_access_map=
|
group_ids: :group_ids_access_map=
|
||||||
}.each do |param, setter|
|
}.each do |param, setter|
|
||||||
next if !params.key?(param)
|
next if !params.key?(param)
|
||||||
|
|
||||||
map = params[param]
|
map = params[param]
|
||||||
next if !respond_to?(setter)
|
next if !respond_to?(setter)
|
||||||
|
|
||||||
send(setter, map)
|
send(setter, map)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -32,9 +34,11 @@ returns
|
||||||
self.class.reflect_on_all_associations.map do |assoc|
|
self.class.reflect_on_all_associations.map do |assoc|
|
||||||
assoc_name = assoc.name
|
assoc_name = assoc.name
|
||||||
next if association_attributes_ignored.include?(assoc_name)
|
next if association_attributes_ignored.include?(assoc_name)
|
||||||
|
|
||||||
real_ids = assoc_name[0, assoc_name.length - 1] + '_ids'
|
real_ids = assoc_name[0, assoc_name.length - 1] + '_ids'
|
||||||
real_ids = real_ids.to_sym
|
real_ids = real_ids.to_sym
|
||||||
next if !params.key?(real_ids)
|
next if !params.key?(real_ids)
|
||||||
|
|
||||||
list_of_items = params[real_ids]
|
list_of_items = params[real_ids]
|
||||||
if !params[real_ids].instance_of?(Array)
|
if !params[real_ids].instance_of?(Array)
|
||||||
list_of_items = [ params[real_ids] ]
|
list_of_items = [ params[real_ids] ]
|
||||||
|
@ -42,12 +46,14 @@ returns
|
||||||
list = []
|
list = []
|
||||||
list_of_items.each do |item_id|
|
list_of_items.each do |item_id|
|
||||||
next if !item_id
|
next if !item_id
|
||||||
|
|
||||||
lookup = assoc.klass.lookup(id: item_id)
|
lookup = assoc.klass.lookup(id: item_id)
|
||||||
|
|
||||||
# complain if we found no reference
|
# complain if we found no reference
|
||||||
if !lookup
|
if !lookup
|
||||||
raise ArgumentError, "No value found for '#{assoc_name}' with id #{item_id.inspect}"
|
raise ArgumentError, "No value found for '#{assoc_name}' with id #{item_id.inspect}"
|
||||||
end
|
end
|
||||||
|
|
||||||
list.push item_id
|
list.push item_id
|
||||||
end
|
end
|
||||||
send("#{real_ids}=", list)
|
send("#{real_ids}=", list)
|
||||||
|
@ -57,16 +63,20 @@ returns
|
||||||
self.class.reflect_on_all_associations.map do |assoc|
|
self.class.reflect_on_all_associations.map do |assoc|
|
||||||
assoc_name = assoc.name
|
assoc_name = assoc.name
|
||||||
next if association_attributes_ignored.include?(assoc_name)
|
next if association_attributes_ignored.include?(assoc_name)
|
||||||
|
|
||||||
real_ids = assoc_name[0, assoc_name.length - 1] + '_ids'
|
real_ids = assoc_name[0, assoc_name.length - 1] + '_ids'
|
||||||
next if !respond_to?(real_ids)
|
next if !respond_to?(real_ids)
|
||||||
|
|
||||||
real_values = assoc_name[0, assoc_name.length - 1] + 's'
|
real_values = assoc_name[0, assoc_name.length - 1] + 's'
|
||||||
real_values = real_values.to_sym
|
real_values = real_values.to_sym
|
||||||
next if !respond_to?(real_values)
|
next if !respond_to?(real_values)
|
||||||
next if !params[real_values]
|
next if !params[real_values]
|
||||||
|
|
||||||
if params[real_values].instance_of?(String) || params[real_values].instance_of?(Integer) || params[real_values].instance_of?(Float)
|
if params[real_values].instance_of?(String) || params[real_values].instance_of?(Integer) || params[real_values].instance_of?(Float)
|
||||||
params[real_values] = [params[real_values]]
|
params[real_values] = [params[real_values]]
|
||||||
end
|
end
|
||||||
next if !params[real_values].instance_of?(Array)
|
next if !params[real_values].instance_of?(Array)
|
||||||
|
|
||||||
list = []
|
list = []
|
||||||
class_object = assoc.klass
|
class_object = assoc.klass
|
||||||
params[real_values].each do |value|
|
params[real_values].each do |value|
|
||||||
|
@ -86,6 +96,7 @@ returns
|
||||||
if !lookup
|
if !lookup
|
||||||
raise ArgumentError, "No lookup value found for '#{assoc_name}': #{value.inspect}"
|
raise ArgumentError, "No lookup value found for '#{assoc_name}': #{value.inspect}"
|
||||||
end
|
end
|
||||||
|
|
||||||
list.push lookup.id
|
list.push lookup.id
|
||||||
end
|
end
|
||||||
send("#{real_ids}=", list)
|
send("#{real_ids}=", list)
|
||||||
|
@ -171,8 +182,10 @@ returns
|
||||||
self.class.reflect_on_all_associations.map do |assoc|
|
self.class.reflect_on_all_associations.map do |assoc|
|
||||||
next if !respond_to?(assoc.name)
|
next if !respond_to?(assoc.name)
|
||||||
next if association_attributes_ignored.include?(assoc.name)
|
next if association_attributes_ignored.include?(assoc.name)
|
||||||
|
|
||||||
ref = send(assoc.name)
|
ref = send(assoc.name)
|
||||||
next if !ref
|
next if !ref
|
||||||
|
|
||||||
if ref.respond_to?(:first)
|
if ref.respond_to?(:first)
|
||||||
attributes[assoc.name.to_s] = []
|
attributes[assoc.name.to_s] = []
|
||||||
ref.each do |item|
|
ref.each do |item|
|
||||||
|
@ -181,6 +194,7 @@ returns
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
next if !item[:name]
|
next if !item[:name]
|
||||||
|
|
||||||
attributes[assoc.name.to_s].push item[:name]
|
attributes[assoc.name.to_s].push item[:name]
|
||||||
end
|
end
|
||||||
if ref.count.positive? && attributes[assoc.name.to_s].blank?
|
if ref.count.positive? && attributes[assoc.name.to_s].blank?
|
||||||
|
@ -193,6 +207,7 @@ returns
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
next if !ref[:name]
|
next if !ref[:name]
|
||||||
|
|
||||||
attributes[assoc.name.to_s] = ref[:name]
|
attributes[assoc.name.to_s] = ref[:name]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -207,8 +222,10 @@ returns
|
||||||
'updated_by_id' => 'updated_by',
|
'updated_by_id' => 'updated_by',
|
||||||
}.each do |source, destination|
|
}.each do |source, destination|
|
||||||
next if !attributes[source]
|
next if !attributes[source]
|
||||||
|
|
||||||
user = User.lookup(id: attributes[source])
|
user = User.lookup(id: attributes[source])
|
||||||
next if !user
|
next if !user
|
||||||
|
|
||||||
attributes[destination] = user.login
|
attributes[destination] = user.login
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -245,14 +262,18 @@ returns
|
||||||
|
|
||||||
# check if id is assigned
|
# check if id is assigned
|
||||||
next if !key.end_with?('_id')
|
next if !key.end_with?('_id')
|
||||||
|
|
||||||
key_short = key.chomp('_id')
|
key_short = key.chomp('_id')
|
||||||
|
|
||||||
self.class.reflect_on_all_associations.map do |assoc|
|
self.class.reflect_on_all_associations.map do |assoc|
|
||||||
next if assoc.name.to_s != key_short
|
next if assoc.name.to_s != key_short
|
||||||
|
|
||||||
item = assoc.class_name.constantize
|
item = assoc.class_name.constantize
|
||||||
return false if !item.respond_to?(:find_by)
|
return false if !item.respond_to?(:find_by)
|
||||||
|
|
||||||
ref_object = item.find_by(id: value)
|
ref_object = item.find_by(id: value)
|
||||||
return false if !ref_object
|
return false if !ref_object
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -332,6 +353,7 @@ returns
|
||||||
assoc_name = assoc.name
|
assoc_name = assoc.name
|
||||||
value = data[assoc_name]
|
value = data[assoc_name]
|
||||||
next if !value # next if we do not have a value
|
next if !value # next if we do not have a value
|
||||||
|
|
||||||
ref_name = "#{assoc_name}_id"
|
ref_name = "#{assoc_name}_id"
|
||||||
|
|
||||||
# handle _id values
|
# handle _id values
|
||||||
|
@ -345,6 +367,7 @@ returns
|
||||||
if !value.instance_of?(String)
|
if !value.instance_of?(String)
|
||||||
raise ArgumentError, "String is needed as ref value #{value.inspect} for '#{assoc_name}'"
|
raise ArgumentError, "String is needed as ref value #{value.inspect} for '#{assoc_name}'"
|
||||||
end
|
end
|
||||||
|
|
||||||
if !lookup
|
if !lookup
|
||||||
lookup = class_object.lookup(login: value)
|
lookup = class_object.lookup(login: value)
|
||||||
end
|
end
|
||||||
|
@ -374,6 +397,7 @@ returns
|
||||||
|
|
||||||
# handle _ids values
|
# handle _ids values
|
||||||
next if !assoc_name.to_s.end_with?('s')
|
next if !assoc_name.to_s.end_with?('s')
|
||||||
|
|
||||||
ref_names = "#{assoc_name.to_s.chomp('s')}_ids"
|
ref_names = "#{assoc_name.to_s.chomp('s')}_ids"
|
||||||
generic_object_tmp = new
|
generic_object_tmp = new
|
||||||
next if !generic_object_tmp.respond_to?(ref_names) # if we do have an _ids attribute
|
next if !generic_object_tmp.respond_to?(ref_names) # if we do have an _ids attribute
|
||||||
|
@ -388,6 +412,7 @@ returns
|
||||||
if !item.instance_of?(String)
|
if !item.instance_of?(String)
|
||||||
raise ArgumentError, "String is needed in array ref as ref value #{value.inspect} for '#{assoc_name}'"
|
raise ArgumentError, "String is needed in array ref as ref value #{value.inspect} for '#{assoc_name}'"
|
||||||
end
|
end
|
||||||
|
|
||||||
if !lookup
|
if !lookup
|
||||||
lookup = class_object.lookup(login: item)
|
lookup = class_object.lookup(login: item)
|
||||||
end
|
end
|
||||||
|
@ -402,6 +427,7 @@ returns
|
||||||
if !lookup
|
if !lookup
|
||||||
raise ArgumentError, "No lookup value found for '#{assoc_name}': #{item.inspect}"
|
raise ArgumentError, "No lookup value found for '#{assoc_name}': #{item.inspect}"
|
||||||
end
|
end
|
||||||
|
|
||||||
lookup_ids.push lookup.id
|
lookup_ids.push lookup.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -50,10 +50,12 @@ returns
|
||||||
reflect_on_all_associations.map do |assoc|
|
reflect_on_all_associations.map do |assoc|
|
||||||
class_name = assoc.options[:class_name]
|
class_name = assoc.options[:class_name]
|
||||||
next if !class_name
|
next if !class_name
|
||||||
|
|
||||||
name = "#{assoc.name}_id"
|
name = "#{assoc.name}_id"
|
||||||
next if !data.key?(name)
|
next if !data.key?(name)
|
||||||
next if data[name].blank?
|
next if data[name].blank?
|
||||||
next if assoc.klass.lookup(id: data[name])
|
next if assoc.klass.lookup(id: data[name])
|
||||||
|
|
||||||
raise ArgumentError, "Invalid value for param '#{name}': #{data[name].inspect}"
|
raise ArgumentError, "Invalid value for param '#{name}': #{data[name].inspect}"
|
||||||
end
|
end
|
||||||
clean_params[attribute] = data[attribute]
|
clean_params[attribute] = data[attribute]
|
||||||
|
@ -105,6 +107,7 @@ merge preferences param
|
||||||
def param_preferences_merge(new_params)
|
def param_preferences_merge(new_params)
|
||||||
return new_params if new_params.blank?
|
return new_params if new_params.blank?
|
||||||
return new_params if preferences.blank?
|
return new_params if preferences.blank?
|
||||||
|
|
||||||
new_params[:preferences] = preferences.merge(new_params[:preferences] || {})
|
new_params[:preferences] = preferences.merge(new_params[:preferences] || {})
|
||||||
new_params
|
new_params
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,6 +27,7 @@ returns
|
||||||
updated_at = order(updated_at: :desc, id: :desc).limit(1).pluck(:updated_at).first
|
updated_at = order(updated_at: :desc, id: :desc).limit(1).pluck(:updated_at).first
|
||||||
|
|
||||||
return if !updated_at
|
return if !updated_at
|
||||||
|
|
||||||
latest_change_set(updated_at)
|
latest_change_set(updated_at)
|
||||||
updated_at
|
updated_at
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,6 +25,7 @@ returns
|
||||||
attribute_name_with_id = key.to_s
|
attribute_name_with_id = key.to_s
|
||||||
attribute_name = key.to_s
|
attribute_name = key.to_s
|
||||||
next if attribute_name[-3, 3] != '_id'
|
next if attribute_name[-3, 3] != '_id'
|
||||||
|
|
||||||
attribute_name = attribute_name[ 0, attribute_name.length - 3 ]
|
attribute_name = attribute_name[ 0, attribute_name.length - 3 ]
|
||||||
|
|
||||||
# check if attribute method exists
|
# check if attribute method exists
|
||||||
|
|
|
@ -21,6 +21,7 @@ touch references by params
|
||||||
object_class = Kernel.const_get(data[:object])
|
object_class = Kernel.const_get(data[:object])
|
||||||
object = object_class.lookup(id: data[:o_id])
|
object = object_class.lookup(id: data[:o_id])
|
||||||
return if !object
|
return if !object
|
||||||
|
|
||||||
object.touch # rubocop:disable Rails/SkipsModelValidations
|
object.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
rescue => e
|
rescue => e
|
||||||
logger.error e
|
logger.error e
|
||||||
|
|
|
@ -19,6 +19,7 @@ module ApplicationModel::ChecksAttributeValuesAndLength
|
||||||
columns = self.class.columns_hash
|
columns = self.class.columns_hash
|
||||||
attributes.each do |name, value|
|
attributes.each do |name, value|
|
||||||
next if !value.instance_of?(String)
|
next if !value.instance_of?(String)
|
||||||
|
|
||||||
column = columns[name]
|
column = columns[name]
|
||||||
next if !column
|
next if !column
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ module ApplicationModel::ChecksAttributeValuesAndLength
|
||||||
|
|
||||||
# strip 4 bytes utf8 chars if needed (mysql/mariadb will complain it)
|
# strip 4 bytes utf8 chars if needed (mysql/mariadb will complain it)
|
||||||
next if self[name].blank?
|
next if self[name].blank?
|
||||||
|
|
||||||
self[name] = self[name].utf8_to_3bytesutf8
|
self[name] = self[name].utf8_to_3bytesutf8
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
|
|
|
@ -14,6 +14,7 @@ module ApplicationModel::ChecksImport
|
||||||
return if !Setting.get('system_init_done')
|
return if !Setting.get('system_init_done')
|
||||||
return if Setting.get('import_mode') && import_class_list.include?(self.class.to_s)
|
return if Setting.get('import_mode') && import_class_list.include?(self.class.to_s)
|
||||||
return if !has_attribute?(:id)
|
return if !has_attribute?(:id)
|
||||||
|
|
||||||
self[:id] = nil
|
self[:id] = nil
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
|
@ -96,6 +96,7 @@ class Authorization < ApplicationModel
|
||||||
|
|
||||||
def delete_user_cache
|
def delete_user_cache
|
||||||
return if !user
|
return if !user
|
||||||
|
|
||||||
user.touch # rubocop:disable Rails/SkipsModelValidations
|
user.touch # rubocop:disable Rails/SkipsModelValidations
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,7 @@ add avatar by url
|
||||||
# fetch image
|
# fetch image
|
||||||
image = Service::Image.user(url)
|
image = Service::Image.user(url)
|
||||||
return if !image
|
return if !image
|
||||||
|
|
||||||
data[:resize] = image
|
data[:resize] = image
|
||||||
data[:full] = image
|
data[:full] = image
|
||||||
end
|
end
|
||||||
|
@ -358,6 +359,7 @@ returns:
|
||||||
store_hash: hash,
|
store_hash: hash,
|
||||||
)
|
)
|
||||||
return if !avatar
|
return if !avatar
|
||||||
|
|
||||||
Store.find(avatar.store_resize_id)
|
Store.find(avatar.store_resize_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -389,6 +391,7 @@ returns:
|
||||||
).order('created_at ASC, id DESC')
|
).order('created_at ASC, id DESC')
|
||||||
avatars.each do |avatar|
|
avatars.each do |avatar|
|
||||||
next if avatar.id == avatar_id
|
next if avatar.id == avatar_id
|
||||||
|
|
||||||
avatar.default = false
|
avatar.default = false
|
||||||
avatar.save!
|
avatar.save!
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,6 +33,7 @@ returns calendar object
|
||||||
# prevent multible setups for same ip
|
# prevent multible setups for same ip
|
||||||
cache = Cache.get('Calendar.init_setup.done')
|
cache = Cache.get('Calendar.init_setup.done')
|
||||||
return if cache && cache[:ip] == ip
|
return if cache && cache[:ip] == ip
|
||||||
|
|
||||||
Cache.write('Calendar.init_setup.done', { ip: ip }, { expires_in: 1.hour })
|
Cache.write('Calendar.init_setup.done', { ip: ip }, { expires_in: 1.hour })
|
||||||
|
|
||||||
# call for calendar suggestion
|
# call for calendar suggestion
|
||||||
|
@ -171,6 +172,7 @@ returns
|
||||||
public_holidays.each do |day, meta|
|
public_holidays.each do |day, meta|
|
||||||
next if !public_holidays[day]['feed']
|
next if !public_holidays[day]['feed']
|
||||||
next if meta['feed'] == Digest::MD5.hexdigest(ical_url)
|
next if meta['feed'] == Digest::MD5.hexdigest(ical_url)
|
||||||
|
|
||||||
public_holidays.delete(day)
|
public_holidays.delete(day)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -215,6 +217,7 @@ returns
|
||||||
if !result.success?
|
if !result.success?
|
||||||
raise result.error
|
raise result.error
|
||||||
end
|
end
|
||||||
|
|
||||||
cal_file = result.body
|
cal_file = result.body
|
||||||
else
|
else
|
||||||
cal_file = File.open(location)
|
cal_file = File.open(location)
|
||||||
|
@ -234,14 +237,17 @@ returns
|
||||||
occurrences.each do |occurrence|
|
occurrences.each do |occurrence|
|
||||||
result = Calendar.day_and_comment_by_event(event, occurrence.start_time)
|
result = Calendar.day_and_comment_by_event(event, occurrence.start_time)
|
||||||
next if !result
|
next if !result
|
||||||
|
|
||||||
events[result[0]] = result[1]
|
events[result[0]] = result[1]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
next if event.dtstart < Time.zone.now - 1.year
|
next if event.dtstart < Time.zone.now - 1.year
|
||||||
next if event.dtstart > Time.zone.now + 3.years
|
next if event.dtstart > Time.zone.now + 3.years
|
||||||
|
|
||||||
result = Calendar.day_and_comment_by_event(event, event.dtstart)
|
result = Calendar.day_and_comment_by_event(event, event.dtstart)
|
||||||
next if !result
|
next if !result
|
||||||
|
|
||||||
events[result[0]] = result[1]
|
events[result[0]] = result[1]
|
||||||
end
|
end
|
||||||
events.sort.to_h
|
events.sort.to_h
|
||||||
|
@ -255,6 +261,7 @@ returns
|
||||||
|
|
||||||
# ignore daylight saving time entries
|
# ignore daylight saving time entries
|
||||||
return if comment.match?(/(daylight saving|sommerzeit|summertime)/i)
|
return if comment.match?(/(daylight saving|sommerzeit|summertime)/i)
|
||||||
|
|
||||||
[day, comment]
|
[day, comment]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -263,9 +270,11 @@ returns
|
||||||
# if changed calendar is default, set all others default to false
|
# if changed calendar is default, set all others default to false
|
||||||
def sync_default
|
def sync_default
|
||||||
return true if !default
|
return true if !default
|
||||||
|
|
||||||
Calendar.find_each do |calendar|
|
Calendar.find_each do |calendar|
|
||||||
next if calendar.id == id
|
next if calendar.id == id
|
||||||
next if !calendar.default
|
next if !calendar.default
|
||||||
|
|
||||||
calendar.default = false
|
calendar.default = false
|
||||||
calendar.save
|
calendar.save
|
||||||
end
|
end
|
||||||
|
@ -277,6 +286,7 @@ returns
|
||||||
if !Calendar.find_by(default: true)
|
if !Calendar.find_by(default: true)
|
||||||
first = Calendar.order(:created_at, :id).limit(1).first
|
first = Calendar.order(:created_at, :id).limit(1).first
|
||||||
return true if !first
|
return true if !first
|
||||||
|
|
||||||
first.default = true
|
first.default = true
|
||||||
first.save
|
first.save
|
||||||
end
|
end
|
||||||
|
|
|
@ -58,6 +58,7 @@ fetch one account
|
||||||
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
||||||
driver_instance = driver_class.new
|
driver_instance = driver_class.new
|
||||||
return if !force && !driver_instance.fetchable?(self)
|
return if !force && !driver_instance.fetchable?(self)
|
||||||
|
|
||||||
result = driver_instance.fetch(adapter_options, self)
|
result = driver_instance.fetch(adapter_options, self)
|
||||||
self.status_in = result[:result]
|
self.status_in = result[:result]
|
||||||
self.last_log_in = result[:notice]
|
self.last_log_in = result[:notice]
|
||||||
|
@ -103,6 +104,7 @@ stream instance of account
|
||||||
|
|
||||||
# check is stream exists
|
# check is stream exists
|
||||||
return if !driver_instance.respond_to?(:stream_instance)
|
return if !driver_instance.respond_to?(:stream_instance)
|
||||||
|
|
||||||
driver_instance.stream_instance(self)
|
driver_instance.stream_instance(self)
|
||||||
|
|
||||||
# set scheduler job to active
|
# set scheduler job to active
|
||||||
|
@ -142,9 +144,11 @@ stream all accounts
|
||||||
channels.each do |channel|
|
channels.each do |channel|
|
||||||
adapter = channel.options[:adapter]
|
adapter = channel.options[:adapter]
|
||||||
next if adapter.blank?
|
next if adapter.blank?
|
||||||
|
|
||||||
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
driver_class = Object.const_get("Channel::Driver::#{adapter.to_classname}")
|
||||||
next if !driver_class.respond_to?(:streamable?)
|
next if !driver_class.respond_to?(:streamable?)
|
||||||
next if !driver_class.streamable?
|
next if !driver_class.streamable?
|
||||||
|
|
||||||
channel_id = channel.id.to_s
|
channel_id = channel.id.to_s
|
||||||
|
|
||||||
current_channels.push channel_id
|
current_channels.push channel_id
|
||||||
|
@ -225,6 +229,7 @@ stream all accounts
|
||||||
last_channels.each do |channel_id|
|
last_channels.each do |channel_id|
|
||||||
next if @@channel_stream[channel_id].blank?
|
next if @@channel_stream[channel_id].blank?
|
||||||
next if current_channels.include?(channel_id)
|
next if current_channels.include?(channel_id)
|
||||||
|
|
||||||
logger.info "channel (#{channel_id}) not longer active, stop stream thread"
|
logger.info "channel (#{channel_id}) not longer active, stop stream thread"
|
||||||
@@channel_stream[channel_id][:thread].exit
|
@@channel_stream[channel_id][:thread].exit
|
||||||
@@channel_stream[channel_id][:thread].join
|
@@channel_stream[channel_id][:thread].join
|
||||||
|
|
|
@ -52,11 +52,14 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
return data if !self['created_by_id'] && !self['updated_by_id']
|
return data if !self['created_by_id'] && !self['updated_by_id']
|
||||||
|
|
||||||
%w[created_by_id updated_by_id].each do |local_user_id|
|
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||||
next if !self[ local_user_id ]
|
next if !self[ local_user_id ]
|
||||||
next if data[ User.to_app_model ] && data[ User.to_app_model ][ self[ local_user_id ] ]
|
next if data[ User.to_app_model ] && data[ User.to_app_model ][ self[ local_user_id ] ]
|
||||||
|
|
||||||
user = User.lookup(id: self[ local_user_id ])
|
user = User.lookup(id: self[ local_user_id ])
|
||||||
next if !user
|
next if !user
|
||||||
|
|
||||||
data = user.assets(data)
|
data = user.assets(data)
|
||||||
end
|
end
|
||||||
data
|
data
|
||||||
|
|
|
@ -30,11 +30,13 @@ class Channel::Driver::Facebook
|
||||||
access_token = nil
|
access_token = nil
|
||||||
options['pages'].each do |page|
|
options['pages'].each do |page|
|
||||||
next if page['id'].to_s != fb_object_id.to_s
|
next if page['id'].to_s != fb_object_id.to_s
|
||||||
|
|
||||||
access_token = page['access_token']
|
access_token = page['access_token']
|
||||||
end
|
end
|
||||||
if !access_token
|
if !access_token
|
||||||
raise "No access_token found for fb_object_id: #{fb_object_id}"
|
raise "No access_token found for fb_object_id: #{fb_object_id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
client = ::Facebook.new(access_token)
|
client = ::Facebook.new(access_token)
|
||||||
client.from_article(article)
|
client.from_article(article)
|
||||||
end
|
end
|
||||||
|
@ -54,6 +56,7 @@ class Channel::Driver::Facebook
|
||||||
return true if !channel.preferences
|
return true if !channel.preferences
|
||||||
return true if !channel.preferences[:last_fetch]
|
return true if !channel.preferences[:last_fetch]
|
||||||
return false if channel.preferences[:last_fetch] > Time.zone.now - 5.minutes
|
return false if channel.preferences[:last_fetch] > Time.zone.now - 5.minutes
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -93,6 +96,7 @@ returns
|
||||||
page = get_page(page_to_sync_id)
|
page = get_page(page_to_sync_id)
|
||||||
next if !page
|
next if !page
|
||||||
next if page_to_sync_params['group_id'].blank?
|
next if page_to_sync_params['group_id'].blank?
|
||||||
|
|
||||||
page_client = ::Facebook.new(page['access_token'])
|
page_client = ::Facebook.new(page['access_token'])
|
||||||
|
|
||||||
posts = page_client.client.get_connection('me', 'feed', fields: 'id,from,to,message,created_time,permalink_url,comments{id,from,to,message,created_time}')
|
posts = page_client.client.get_connection('me', 'feed', fields: 'id,from,to,message,created_time,permalink_url,comments{id,from,to,message,created_time}')
|
||||||
|
|
|
@ -164,6 +164,7 @@ example
|
||||||
subject = message_meta['ENVELOPE'].subject
|
subject = message_meta['ENVELOPE'].subject
|
||||||
next if !subject
|
next if !subject
|
||||||
next if subject !~ /#{verify_string}/
|
next if subject !~ /#{verify_string}/
|
||||||
|
|
||||||
Rails.logger.info " - verify email #{verify_string} found"
|
Rails.logger.info " - verify email #{verify_string} found"
|
||||||
@imap.store(message_id, '+FLAGS', [:Deleted])
|
@imap.store(message_id, '+FLAGS', [:Deleted])
|
||||||
@imap.expunge()
|
@imap.expunge()
|
||||||
|
@ -206,6 +207,7 @@ example
|
||||||
# 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']
|
msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
|
||||||
next if !msg
|
next if !msg
|
||||||
|
|
||||||
process(channel, msg, false)
|
process(channel, msg, false)
|
||||||
if !keep_on_server
|
if !keep_on_server
|
||||||
@imap.store(message_id, '+FLAGS', [:Deleted])
|
@imap.store(message_id, '+FLAGS', [:Deleted])
|
||||||
|
@ -231,6 +233,7 @@ example
|
||||||
|
|
||||||
def disconnect
|
def disconnect
|
||||||
return if !@imap
|
return if !@imap
|
||||||
|
|
||||||
@imap.disconnect()
|
@imap.disconnect()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -256,8 +259,10 @@ returns
|
||||||
return false if !keep_on_server
|
return false if !keep_on_server
|
||||||
return false if !message_meta.attr
|
return false if !message_meta.attr
|
||||||
return false if !message_meta.attr['ENVELOPE']
|
return false if !message_meta.attr['ENVELOPE']
|
||||||
|
|
||||||
local_message_id = message_meta.attr['ENVELOPE'].message_id
|
local_message_id = message_meta.attr['ENVELOPE'].message_id
|
||||||
return false if local_message_id.blank?
|
return false if local_message_id.blank?
|
||||||
|
|
||||||
local_message_id_md5 = Digest::MD5.hexdigest(local_message_id)
|
local_message_id_md5 = Digest::MD5.hexdigest(local_message_id)
|
||||||
article = Ticket::Article.where(message_id_md5: local_message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
article = Ticket::Article.where(message_id_md5: local_message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
||||||
return false if !article
|
return false if !article
|
||||||
|
@ -275,6 +280,7 @@ returns
|
||||||
|
|
||||||
def deleted?(message_meta, count, count_all)
|
def deleted?(message_meta, count, count_all)
|
||||||
return false if !message_meta.attr['FLAGS'].include?(:Deleted)
|
return false if !message_meta.attr['FLAGS'].include?(:Deleted)
|
||||||
|
|
||||||
Rails.logger.info " - ignore message #{count}/#{count_all} - because message has already delete flag"
|
Rails.logger.info " - ignore message #{count}/#{count_all} - because message has already delete flag"
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
|
@ -118,6 +118,7 @@ returns
|
||||||
|
|
||||||
# check if verify message exists
|
# check if verify message exists
|
||||||
next if mail !~ /#{verify_string}/
|
next if mail !~ /#{verify_string}/
|
||||||
|
|
||||||
Rails.logger.info " - verify email #{verify_string} found"
|
Rails.logger.info " - verify email #{verify_string} found"
|
||||||
m.delete
|
m.delete
|
||||||
disconnect
|
disconnect
|
||||||
|
@ -196,6 +197,7 @@ returns
|
||||||
|
|
||||||
def disconnect
|
def disconnect
|
||||||
return if !@pop
|
return if !@pop
|
||||||
|
|
||||||
@pop.finish
|
@pop.finish
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ class Channel::Driver::Sendmail
|
||||||
|
|
||||||
def delivery_method
|
def delivery_method
|
||||||
return :test if Rails.env.test?
|
return :test if Rails.env.test?
|
||||||
|
|
||||||
:sendmail
|
:sendmail
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -50,6 +50,7 @@ returns
|
||||||
if options[:auth] && options[:auth][:external_credential_id]
|
if options[:auth] && options[:auth][:external_credential_id]
|
||||||
external_credential = ExternalCredential.find_by(id: options[:auth][:external_credential_id])
|
external_credential = ExternalCredential.find_by(id: options[:auth][:external_credential_id])
|
||||||
raise "No such ExternalCredential.find(#{options[:auth][:external_credential_id]})" if !external_credential
|
raise "No such ExternalCredential.find(#{options[:auth][:external_credential_id]})" if !external_credential
|
||||||
|
|
||||||
options[:auth][:api_key] = external_credential.credentials['api_key']
|
options[:auth][:api_key] = external_credential.credentials['api_key']
|
||||||
end
|
end
|
||||||
options
|
options
|
||||||
|
|
|
@ -83,6 +83,7 @@ returns
|
||||||
return true if !channel.preferences
|
return true if !channel.preferences
|
||||||
return true if !channel.preferences[:last_fetch]
|
return true if !channel.preferences[:last_fetch]
|
||||||
return false if channel.preferences[:last_fetch] > Time.zone.now - 20.minutes
|
return false if channel.preferences[:last_fetch] > Time.zone.now - 20.minutes
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -206,6 +207,7 @@ returns
|
||||||
if loop_count >= 2
|
if loop_count >= 2
|
||||||
raise "Unable to stream, try #{loop_count}, error #{e.inspect}"
|
raise "Unable to stream, try #{loop_count}, error #{e.inspect}"
|
||||||
end
|
end
|
||||||
|
|
||||||
Rails.logger.info "wait for #{sleep_on_unauthorized} sec. and try it again"
|
Rails.logger.info "wait for #{sleep_on_unauthorized} sec. and try it again"
|
||||||
sleep sleep_on_unauthorized
|
sleep sleep_on_unauthorized
|
||||||
end
|
end
|
||||||
|
@ -224,6 +226,7 @@ returns
|
||||||
next if item['term'].blank?
|
next if item['term'].blank?
|
||||||
next if item['term'] == '#'
|
next if item['term'] == '#'
|
||||||
next if item['group_id'].blank?
|
next if item['group_id'].blank?
|
||||||
|
|
||||||
hashtags.push item['term']
|
hashtags.push item['term']
|
||||||
end
|
end
|
||||||
filter[:track] = hashtags.join(',')
|
filter[:track] = hashtags.join(',')
|
||||||
|
@ -246,6 +249,7 @@ returns
|
||||||
if tweet.class == Twitter::DirectMessage
|
if tweet.class == Twitter::DirectMessage
|
||||||
if sync['direct_messages'] && sync['direct_messages']['group_id'] != ''
|
if sync['direct_messages'] && sync['direct_messages']['group_id'] != ''
|
||||||
next if @stream_client.direct_message_limit_reached(tweet, 2)
|
next if @stream_client.direct_message_limit_reached(tweet, 2)
|
||||||
|
|
||||||
@stream_client.to_group(tweet, sync['direct_messages']['group_id'], @channel)
|
@stream_client.to_group(tweet, sync['direct_messages']['group_id'], @channel)
|
||||||
end
|
end
|
||||||
next
|
next
|
||||||
|
@ -275,8 +279,10 @@ returns
|
||||||
next if item['term'].blank?
|
next if item['term'].blank?
|
||||||
next if item['term'] == '#'
|
next if item['term'] == '#'
|
||||||
next if item['group_id'].blank?
|
next if item['group_id'].blank?
|
||||||
|
|
||||||
tweet.hashtags.each do |hashtag|
|
tweet.hashtags.each do |hashtag|
|
||||||
next if item['term'] !~ /^#/
|
next if item['term'] !~ /^#/
|
||||||
|
|
||||||
if item['term'].sub(/^#/, '') == hashtag.text
|
if item['term'].sub(/^#/, '') == hashtag.text
|
||||||
hit = item
|
hit = item
|
||||||
end
|
end
|
||||||
|
@ -296,6 +302,7 @@ returns
|
||||||
next if item['term'].blank?
|
next if item['term'].blank?
|
||||||
next if item['term'] == '#'
|
next if item['term'] == '#'
|
||||||
next if item['group_id'].blank?
|
next if item['group_id'].blank?
|
||||||
|
|
||||||
if body.match?(/#{item['term']}/)
|
if body.match?(/#{item['term']}/)
|
||||||
hit = item
|
hit = item
|
||||||
end
|
end
|
||||||
|
@ -312,10 +319,12 @@ returns
|
||||||
|
|
||||||
def fetch_search
|
def fetch_search
|
||||||
return if @sync[:search].blank?
|
return if @sync[:search].blank?
|
||||||
|
|
||||||
@sync[:search].each do |search|
|
@sync[:search].each do |search|
|
||||||
next if search[:term].blank?
|
next if search[:term].blank?
|
||||||
next if search[:term] == '#'
|
next if search[:term] == '#'
|
||||||
next if search[:group_id].blank?
|
next if search[:group_id].blank?
|
||||||
|
|
||||||
result_type = search[:type] || 'mixed'
|
result_type = search[:type] || 'mixed'
|
||||||
Rails.logger.debug { " - searching for '#{search[:term]}'" }
|
Rails.logger.debug { " - searching for '#{search[:term]}'" }
|
||||||
older_import = 0
|
older_import = 0
|
||||||
|
@ -333,6 +342,7 @@ returns
|
||||||
next if @rest_client.locale_sender?(tweet) && own_tweet_already_imported?(tweet)
|
next if @rest_client.locale_sender?(tweet) && own_tweet_already_imported?(tweet)
|
||||||
next if Ticket::Article.find_by(message_id: tweet.id)
|
next if Ticket::Article.find_by(message_id: tweet.id)
|
||||||
break if @rest_client.tweet_limit_reached(tweet)
|
break if @rest_client.tweet_limit_reached(tweet)
|
||||||
|
|
||||||
@rest_client.to_group(tweet, search[:group_id], @channel)
|
@rest_client.to_group(tweet, search[:group_id], @channel)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -341,6 +351,7 @@ returns
|
||||||
def fetch_mentions
|
def fetch_mentions
|
||||||
return if @sync[:mentions].blank?
|
return if @sync[:mentions].blank?
|
||||||
return if @sync[:mentions][:group_id].blank?
|
return if @sync[:mentions][:group_id].blank?
|
||||||
|
|
||||||
Rails.logger.debug { ' - searching for mentions' }
|
Rails.logger.debug { ' - searching for mentions' }
|
||||||
older_import = 0
|
older_import = 0
|
||||||
older_import_max = 20
|
older_import_max = 20
|
||||||
|
@ -355,6 +366,7 @@ returns
|
||||||
end
|
end
|
||||||
next if Ticket::Article.find_by(message_id: tweet.id)
|
next if Ticket::Article.find_by(message_id: tweet.id)
|
||||||
break if @rest_client.tweet_limit_reached(tweet)
|
break if @rest_client.tweet_limit_reached(tweet)
|
||||||
|
|
||||||
@rest_client.to_group(tweet, @sync[:mentions][:group_id], @channel)
|
@rest_client.to_group(tweet, @sync[:mentions][:group_id], @channel)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -362,6 +374,7 @@ returns
|
||||||
def fetch_direct_messages
|
def fetch_direct_messages
|
||||||
return if @sync[:direct_messages].blank?
|
return if @sync[:direct_messages].blank?
|
||||||
return if @sync[:direct_messages][:group_id].blank?
|
return if @sync[:direct_messages][:group_id].blank?
|
||||||
|
|
||||||
Rails.logger.debug { ' - searching for direct_messages' }
|
Rails.logger.debug { ' - searching for direct_messages' }
|
||||||
older_import = 0
|
older_import = 0
|
||||||
older_import_max = 20
|
older_import_max = 20
|
||||||
|
@ -375,6 +388,7 @@ returns
|
||||||
end
|
end
|
||||||
next if Ticket::Article.find_by(message_id: tweet.id)
|
next if Ticket::Article.find_by(message_id: tweet.id)
|
||||||
break if @rest_client.direct_message_limit_reached(tweet)
|
break if @rest_client.direct_message_limit_reached(tweet)
|
||||||
|
|
||||||
@rest_client.to_group(tweet, @sync[:direct_messages][:group_id], @channel)
|
@rest_client.to_group(tweet, @sync[:direct_messages][:group_id], @channel)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -383,6 +397,7 @@ returns
|
||||||
if options[:auth] && options[:auth][:external_credential_id]
|
if options[:auth] && options[:auth][:external_credential_id]
|
||||||
external_credential = ExternalCredential.find_by(id: options[:auth][:external_credential_id])
|
external_credential = ExternalCredential.find_by(id: options[:auth][:external_credential_id])
|
||||||
raise "No such ExternalCredential.find(#{options[:auth][:external_credential_id]})" if !external_credential
|
raise "No such ExternalCredential.find(#{options[:auth][:external_credential_id]})" if !external_credential
|
||||||
|
|
||||||
options[:auth][:consumer_key] = external_credential.credentials['consumer_key']
|
options[:auth][:consumer_key] = external_credential.credentials['consumer_key']
|
||||||
options[:auth][:consumer_secret] = external_credential.credentials['consumer_secret']
|
options[:auth][:consumer_secret] = external_credential.credentials['consumer_secret']
|
||||||
end
|
end
|
||||||
|
@ -403,6 +418,7 @@ returns
|
||||||
end
|
end
|
||||||
count = Delayed::Job.where('created_at < ?', event_time).count
|
count = Delayed::Job.where('created_at < ?', event_time).count
|
||||||
break if count.zero?
|
break if count.zero?
|
||||||
|
|
||||||
sleep_time = 2 * count
|
sleep_time = 2 * count
|
||||||
sleep_time = 5 if sleep_time > 5
|
sleep_time = 5 if sleep_time > 5
|
||||||
Rails.logger.debug { "Delay importing own tweets - sleep #{sleep_time} (loop #{loop_count})" }
|
Rails.logger.debug { "Delay importing own tweets - sleep #{sleep_time} (loop #{loop_count})" }
|
||||||
|
|
|
@ -37,6 +37,7 @@ module Channel::EmailBuild
|
||||||
next if key.to_s == 'attachments'
|
next if key.to_s == 'attachments'
|
||||||
next if key.to_s == 'body'
|
next if key.to_s == 'body'
|
||||||
next if key.to_s == 'content_type'
|
next if key.to_s == 'content_type'
|
||||||
|
|
||||||
mail[key.to_s] = if value && value.class != Array
|
mail[key.to_s] = if value && value.class != Array
|
||||||
value.to_s
|
value.to_s
|
||||||
else
|
else
|
||||||
|
@ -84,6 +85,7 @@ module Channel::EmailBuild
|
||||||
attr[:attachments]&.each do |attachment|
|
attr[:attachments]&.each do |attachment|
|
||||||
next if attachment.class == Hash
|
next if attachment.class == Hash
|
||||||
next if attachment.preferences['Content-ID'].blank?
|
next if attachment.preferences['Content-ID'].blank?
|
||||||
|
|
||||||
attachment = Mail::Part.new do
|
attachment = Mail::Part.new do
|
||||||
content_type attachment.preferences['Content-Type']
|
content_type attachment.preferences['Content-Type']
|
||||||
content_id "<#{attachment.preferences['Content-ID']}>"
|
content_id "<#{attachment.preferences['Content-ID']}>"
|
||||||
|
@ -105,6 +107,7 @@ module Channel::EmailBuild
|
||||||
mail.attachments[attachment[:filename]] = attachment
|
mail.attachments[attachment[:filename]] = attachment
|
||||||
else
|
else
|
||||||
next if attachment.preferences['Content-ID'].present?
|
next if attachment.preferences['Content-ID'].present?
|
||||||
|
|
||||||
filename = attachment.filename
|
filename = attachment.filename
|
||||||
encoded_filename = Mail::Encodings.decode_encode filename, :encode
|
encoded_filename = Mail::Encodings.decode_encode filename, :encode
|
||||||
disposition = attachment.preferences['Content-Disposition'] || 'attachment'
|
disposition = attachment.preferences['Content-Disposition'] || 'attachment'
|
||||||
|
@ -131,6 +134,7 @@ returns
|
||||||
|
|
||||||
def self.recipient_line(realname, email)
|
def self.recipient_line(realname, email)
|
||||||
return "#{realname} <#{email}>" if realname.match?(/^[A-z]+$/i)
|
return "#{realname} <#{email}>" if realname.match?(/^[A-z]+$/i)
|
||||||
|
|
||||||
"\"#{realname.gsub('"', '\"')}\" <#{email}>"
|
"\"#{realname.gsub('"', '\"')}\" <#{email}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,7 @@ returns
|
||||||
file.write msg
|
file.write msg
|
||||||
end
|
end
|
||||||
return false if exception == false
|
return false if exception == false
|
||||||
|
|
||||||
raise e.inspect + "\n" + e.backtrace.join("\n")
|
raise e.inspect + "\n" + e.backtrace.join("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -169,6 +170,7 @@ returns
|
||||||
if !session_user_id
|
if !session_user_id
|
||||||
raise 'No x-zammad-session-user-id, no sender set!'
|
raise 'No x-zammad-session-user-id, no sender set!'
|
||||||
end
|
end
|
||||||
|
|
||||||
session_user = User.lookup(id: session_user_id)
|
session_user = User.lookup(id: session_user_id)
|
||||||
if !session_user
|
if !session_user
|
||||||
raise "No user found for x-zammad-session-user-id: #{session_user_id}!"
|
raise "No user found for x-zammad-session-user-id: #{session_user_id}!"
|
||||||
|
@ -320,23 +322,28 @@ returns
|
||||||
attribute = nil
|
attribute = nil
|
||||||
# skip check attributes if it is tags
|
# skip check attributes if it is tags
|
||||||
return true if header_name == 'x-zammad-ticket-tags'
|
return true if header_name == 'x-zammad-ticket-tags'
|
||||||
|
|
||||||
if header_name =~ /^x-zammad-(.+?)-(followup-|)(.*)$/i
|
if header_name =~ /^x-zammad-(.+?)-(followup-|)(.*)$/i
|
||||||
class_name = $1
|
class_name = $1
|
||||||
attribute = $3
|
attribute = $3
|
||||||
end
|
end
|
||||||
return true if !class_name
|
return true if !class_name
|
||||||
|
|
||||||
if class_name.downcase == 'article'
|
if class_name.downcase == 'article'
|
||||||
class_name = 'Ticket::Article'
|
class_name = 'Ticket::Article'
|
||||||
end
|
end
|
||||||
return true if !attribute
|
return true if !attribute
|
||||||
|
|
||||||
key_short = attribute[ attribute.length - 3, attribute.length ]
|
key_short = attribute[ attribute.length - 3, attribute.length ]
|
||||||
return true if key_short != '_id'
|
return true if key_short != '_id'
|
||||||
|
|
||||||
class_object = Object.const_get(class_name.to_classname)
|
class_object = Object.const_get(class_name.to_classname)
|
||||||
return if !class_object
|
return if !class_object
|
||||||
|
|
||||||
class_instance = class_object.new
|
class_instance = class_object.new
|
||||||
|
|
||||||
return false if !class_instance.association_id_validation(attribute, value)
|
return false if !class_instance.association_id_validation(attribute, value)
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -467,6 +474,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
||||||
Dir.glob("#{path}/*.eml") do |entry|
|
Dir.glob("#{path}/*.eml") do |entry|
|
||||||
ticket, article, user, mail = Channel::EmailParser.new.process(params, IO.binread(entry))
|
ticket, article, user, mail = Channel::EmailParser.new.process(params, IO.binread(entry))
|
||||||
next if ticket.blank?
|
next if ticket.blank?
|
||||||
|
|
||||||
files.push entry
|
files.push entry
|
||||||
File.delete(entry)
|
File.delete(entry)
|
||||||
end
|
end
|
||||||
|
@ -535,6 +543,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
||||||
body_text = Mail::Utilities.to_lf(body_text)
|
body_text = Mail::Utilities.to_lf(body_text)
|
||||||
|
|
||||||
return body_text.html2html_strict if options[:strict_html]
|
return body_text.html2html_strict if options[:strict_html]
|
||||||
|
|
||||||
body_text
|
body_text
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -567,6 +576,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
||||||
attachments.push(*new_attachments)
|
attachments.push(*new_attachments)
|
||||||
rescue => e # Protect process to work with spam emails (see test/fixtures/mail15.box)
|
rescue => e # Protect process to work with spam emails (see test/fixtures/mail15.box)
|
||||||
raise e if (fail_count ||= 0).positive?
|
raise e if (fail_count ||= 0).positive?
|
||||||
|
|
||||||
(fail_count += 1) && retry
|
(fail_count += 1) && retry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -694,6 +704,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
||||||
}
|
}
|
||||||
map.each do |type, ext|
|
map.each do |type, ext|
|
||||||
next if headers_store['Content-Type'] !~ /^#{Regexp.quote(type)}/i
|
next if headers_store['Content-Type'] !~ /^#{Regexp.quote(type)}/i
|
||||||
|
|
||||||
filename = if headers_store['Content-Description'].present?
|
filename = if headers_store['Content-Description'].present?
|
||||||
"#{headers_store['Content-Description']}.#{ext[0]}".to_s.force_encoding('utf-8')
|
"#{headers_store['Content-Description']}.#{ext[0]}".to_s.force_encoding('utf-8')
|
||||||
else
|
else
|
||||||
|
@ -723,6 +734,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
break if filename_exists == false
|
break if filename_exists == false
|
||||||
|
|
||||||
filename = if local_extention.present?
|
filename = if local_extention.present?
|
||||||
"#{local_filename}#{i}.#{local_extention}"
|
"#{local_filename}#{i}.#{local_extention}"
|
||||||
else
|
else
|
||||||
|
@ -769,6 +781,7 @@ module Mail
|
||||||
value = @raw_value.utf8_encode(fallback: :read_as_sanitized_binary)
|
value = @raw_value.utf8_encode(fallback: :read_as_sanitized_binary)
|
||||||
end
|
end
|
||||||
return value if value.blank?
|
return value if value.blank?
|
||||||
|
|
||||||
value.sub(/^.+?:(\s|)/, '')
|
value.sub(/^.+?:(\s|)/, '')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,6 +16,7 @@ module Channel::Filter::BounceDeliveryPermanentFailed
|
||||||
|
|
||||||
result = Channel::EmailParser.new.parse(attachment[:data])
|
result = Channel::EmailParser.new.parse(attachment[:data])
|
||||||
next if !result[:message_id]
|
next if !result[:message_id]
|
||||||
|
|
||||||
message_id_md5 = Digest::MD5.hexdigest(result[:message_id])
|
message_id_md5 = Digest::MD5.hexdigest(result[:message_id])
|
||||||
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
||||||
next if !article
|
next if !article
|
||||||
|
@ -30,11 +31,13 @@ module Channel::Filter::BounceDeliveryPermanentFailed
|
||||||
if article.sender.name == 'System' || article.sender.name == 'Agent'
|
if article.sender.name == 'System' || article.sender.name == 'Agent'
|
||||||
%w[to cc].each do |line|
|
%w[to cc].each do |line|
|
||||||
next if article[line].blank?
|
next if article[line].blank?
|
||||||
|
|
||||||
recipients = []
|
recipients = []
|
||||||
begin
|
begin
|
||||||
list = Mail::AddressList.new(article[line])
|
list = Mail::AddressList.new(article[line])
|
||||||
list.addresses.each do |address|
|
list.addresses.each do |address|
|
||||||
next if address.address.blank?
|
next if address.address.blank?
|
||||||
|
|
||||||
recipients.push address.address.downcase
|
recipients.push address.address.downcase
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
|
@ -60,6 +63,7 @@ module Channel::Filter::BounceDeliveryPermanentFailed
|
||||||
users = User.where(email: recipient)
|
users = User.where(email: recipient)
|
||||||
users.each do |user|
|
users.each do |user|
|
||||||
next if !user
|
next if !user
|
||||||
|
|
||||||
user.preferences[:mail_delivery_failed] = true
|
user.preferences[:mail_delivery_failed] = true
|
||||||
user.preferences[:mail_delivery_failed_data] = Time.zone.now
|
user.preferences[:mail_delivery_failed_data] = Time.zone.now
|
||||||
user.save!
|
user.save!
|
||||||
|
|
|
@ -16,6 +16,7 @@ module Channel::Filter::BounceFollowUpCheck
|
||||||
|
|
||||||
result = Channel::EmailParser.new.parse(attachment[:data])
|
result = Channel::EmailParser.new.parse(attachment[:data])
|
||||||
next if !result[:message_id]
|
next if !result[:message_id]
|
||||||
|
|
||||||
message_id_md5 = Digest::MD5.hexdigest(result[:message_id])
|
message_id_md5 = Digest::MD5.hexdigest(result[:message_id])
|
||||||
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
||||||
next if !article
|
next if !article
|
||||||
|
|
|
@ -14,6 +14,7 @@ module Channel::Filter::Database
|
||||||
filter[:match].each do |key, meta|
|
filter[:match].each do |key, meta|
|
||||||
begin
|
begin
|
||||||
next if meta.blank? || meta['value'].blank?
|
next if meta.blank? || meta['value'].blank?
|
||||||
|
|
||||||
value = mail[ key.downcase.to_sym ]
|
value = mail[ key.downcase.to_sym ]
|
||||||
match_rule = meta['value']
|
match_rule = meta['value']
|
||||||
min_one_rule_exists = true
|
min_one_rule_exists = true
|
||||||
|
@ -44,6 +45,7 @@ module Channel::Filter::Database
|
||||||
|
|
||||||
filter[:perform].each do |key, meta|
|
filter[:perform].each do |key, meta|
|
||||||
next if !Channel::EmailParser.check_attributes_by_x_headers(key, meta['value'])
|
next if !Channel::EmailParser.check_attributes_by_x_headers(key, meta['value'])
|
||||||
|
|
||||||
Rails.logger.info " perform '#{key.downcase}' = '#{meta.inspect}'"
|
Rails.logger.info " perform '#{key.downcase}' = '#{meta.inspect}'"
|
||||||
|
|
||||||
if key.downcase == 'x-zammad-ticket-tags' && meta['value'].present? && meta['operator'].present?
|
if key.downcase == 'x-zammad-ticket-tags' && meta['value'].present? && meta['operator'].present?
|
||||||
|
@ -54,13 +56,16 @@ module Channel::Filter::Database
|
||||||
when 'add'
|
when 'add'
|
||||||
tags.each do |tag|
|
tags.each do |tag|
|
||||||
next if tag.blank?
|
next if tag.blank?
|
||||||
|
|
||||||
tag.strip!
|
tag.strip!
|
||||||
next if mail[ 'x-zammad-ticket-tags'.downcase.to_sym ].include?(tag)
|
next if mail[ 'x-zammad-ticket-tags'.downcase.to_sym ].include?(tag)
|
||||||
|
|
||||||
mail[ 'x-zammad-ticket-tags'.downcase.to_sym ].push tag
|
mail[ 'x-zammad-ticket-tags'.downcase.to_sym ].push tag
|
||||||
end
|
end
|
||||||
when 'remove'
|
when 'remove'
|
||||||
tags.each do |tag|
|
tags.each do |tag|
|
||||||
next if tag.blank?
|
next if tag.blank?
|
||||||
|
|
||||||
tag.strip!
|
tag.strip!
|
||||||
mail[ 'x-zammad-ticket-tags'.downcase.to_sym ] -= [tag]
|
mail[ 'x-zammad-ticket-tags'.downcase.to_sym ] -= [tag]
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,8 +30,10 @@ module Channel::Filter::FollowUpCheck
|
||||||
if setting.include?('attachment') && mail[:attachments]
|
if setting.include?('attachment') && mail[:attachments]
|
||||||
mail[:attachments].each do |attachment|
|
mail[:attachments].each do |attachment|
|
||||||
next if !attachment[:data]
|
next if !attachment[:data]
|
||||||
|
|
||||||
ticket = Ticket::Number.check(attachment[:data].html2text)
|
ticket = Ticket::Number.check(attachment[:data].html2text)
|
||||||
next if !ticket
|
next if !ticket
|
||||||
|
|
||||||
Rails.logger.debug { "Follow up for '##{ticket.number}' in attachment." }
|
Rails.logger.debug { "Follow up for '##{ticket.number}' in attachment." }
|
||||||
mail['x-zammad-ticket-id'.to_sym] = ticket.id
|
mail['x-zammad-ticket-id'.to_sym] = ticket.id
|
||||||
return true
|
return true
|
||||||
|
@ -58,6 +60,7 @@ module Channel::Filter::FollowUpCheck
|
||||||
message_id_md5 = Digest::MD5.hexdigest(message_id)
|
message_id_md5 = Digest::MD5.hexdigest(message_id)
|
||||||
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
||||||
next if !article
|
next if !article
|
||||||
|
|
||||||
Rails.logger.debug { "Follow up for '##{article.ticket.number}' in references." }
|
Rails.logger.debug { "Follow up for '##{article.ticket.number}' in references." }
|
||||||
mail['x-zammad-ticket-id'.to_sym] = article.ticket_id
|
mail['x-zammad-ticket-id'.to_sym] = article.ticket_id
|
||||||
return true
|
return true
|
||||||
|
@ -85,8 +88,10 @@ module Channel::Filter::FollowUpCheck
|
||||||
message_id_md5 = Digest::MD5.hexdigest(message_id)
|
message_id_md5 = Digest::MD5.hexdigest(message_id)
|
||||||
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
|
||||||
next if !article
|
next if !article
|
||||||
|
|
||||||
ticket = article.ticket
|
ticket = article.ticket
|
||||||
next if !ticket
|
next if !ticket
|
||||||
|
|
||||||
article_first = ticket.articles.first
|
article_first = ticket.articles.first
|
||||||
next if !article_first
|
next if !article_first
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ module Channel::Filter::FollowUpPossibleCheck
|
||||||
def self.run(_channel, mail)
|
def self.run(_channel, mail)
|
||||||
ticket_id = mail['x-zammad-ticket-id'.to_sym]
|
ticket_id = mail['x-zammad-ticket-id'.to_sym]
|
||||||
return true if !ticket_id
|
return true if !ticket_id
|
||||||
|
|
||||||
ticket = Ticket.lookup(id: ticket_id)
|
ticket = Ticket.lookup(id: ticket_id)
|
||||||
return true if !ticket
|
return true if !ticket
|
||||||
return true if ticket.state.state_type.name !~ /^(closed|merged|removed)/i
|
return true if ticket.state.state_type.name !~ /^(closed|merged|removed)/i
|
||||||
|
|
|
@ -96,14 +96,17 @@ module Channel::Filter::IdentifySender
|
||||||
current_count = 0
|
current_count = 0
|
||||||
['raw-to', 'raw-cc'].each do |item|
|
['raw-to', 'raw-cc'].each do |item|
|
||||||
next if mail[item.to_sym].blank?
|
next if mail[item.to_sym].blank?
|
||||||
|
|
||||||
begin
|
begin
|
||||||
items = mail[item.to_sym].addrs
|
items = mail[item.to_sym].addrs
|
||||||
next if items.blank?
|
next if items.blank?
|
||||||
|
|
||||||
items.each do |address_data|
|
items.each do |address_data|
|
||||||
email_address = address_data.address
|
email_address = address_data.address
|
||||||
next if email_address.blank?
|
next if email_address.blank?
|
||||||
next if email_address !~ /@/
|
next if email_address !~ /@/
|
||||||
next if email_address.match?(/\s/)
|
next if email_address.match?(/\s/)
|
||||||
|
|
||||||
user_create(
|
user_create(
|
||||||
firstname: address_data.display_name,
|
firstname: address_data.display_name,
|
||||||
lastname: '',
|
lastname: '',
|
||||||
|
@ -131,6 +134,7 @@ module Channel::Filter::IdentifySender
|
||||||
next if address.blank?
|
next if address.blank?
|
||||||
next if address !~ /@/
|
next if address !~ /@/
|
||||||
next if address.match?(/\s/)
|
next if address.match?(/\s/)
|
||||||
|
|
||||||
user_create(
|
user_create(
|
||||||
firstname: display_name,
|
firstname: display_name,
|
||||||
lastname: '',
|
lastname: '',
|
||||||
|
|
|
@ -10,11 +10,13 @@ module Channel::Filter::Match::EmailRegex
|
||||||
if regexp == false
|
if regexp == false
|
||||||
match_rule_quoted = Regexp.quote(match_rule).gsub(/\\\*/, '.*')
|
match_rule_quoted = Regexp.quote(match_rule).gsub(/\\\*/, '.*')
|
||||||
return true if value.match?(/#{match_rule_quoted}/i)
|
return true if value.match?(/#{match_rule_quoted}/i)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
return true if value.match?(/#{match_rule}/i)
|
return true if value.match?(/#{match_rule}/i)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
rescue => e
|
rescue => e
|
||||||
message = "Can't use regex '#{match_rule}' on '#{value}': #{e.message}"
|
message = "Can't use regex '#{match_rule}' on '#{value}': #{e.message}"
|
||||||
|
|
|
@ -14,6 +14,7 @@ class Channel::Filter::MonitoringBase
|
||||||
def self.run(_channel, mail)
|
def self.run(_channel, mail)
|
||||||
integration = integration_name
|
integration = integration_name
|
||||||
return if !Setting.get("#{integration}_integration")
|
return if !Setting.get("#{integration}_integration")
|
||||||
|
|
||||||
sender = Setting.get("#{integration}_sender")
|
sender = Setting.get("#{integration}_sender")
|
||||||
auto_close = Setting.get("#{integration}_auto_close")
|
auto_close = Setting.get("#{integration}_auto_close")
|
||||||
auto_close_state_id = Setting.get("#{integration}_auto_close_state_id")
|
auto_close_state_id = Setting.get("#{integration}_auto_close_state_id")
|
||||||
|
@ -22,6 +23,7 @@ class Channel::Filter::MonitoringBase
|
||||||
|
|
||||||
return if mail[:from].blank?
|
return if mail[:from].blank?
|
||||||
return if mail[:body].blank?
|
return if mail[:body].blank?
|
||||||
|
|
||||||
session_user_id = mail[ 'x-zammad-session-user-id'.to_sym ]
|
session_user_id = mail[ 'x-zammad-session-user-id'.to_sym ]
|
||||||
return if !session_user_id
|
return if !session_user_id
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ module Channel::Filter::OwnNotificationLoopDetection
|
||||||
|
|
||||||
message_id = mail['message-id'.to_sym]
|
message_id = mail['message-id'.to_sym]
|
||||||
return if !message_id
|
return if !message_id
|
||||||
|
|
||||||
recedence = mail['precedence'.to_sym]
|
recedence = mail['precedence'.to_sym]
|
||||||
return if !recedence
|
return if !recedence
|
||||||
return if recedence !~ /bulk/i
|
return if recedence !~ /bulk/i
|
||||||
|
|
|
@ -16,9 +16,11 @@ module Channel::Filter::SenderIsSystemAddress
|
||||||
# in case, set sender
|
# in case, set sender
|
||||||
begin
|
begin
|
||||||
return if !mail[form].addrs
|
return if !mail[form].addrs
|
||||||
|
|
||||||
items = mail[form].addrs
|
items = mail[form].addrs
|
||||||
items.each do |item|
|
items.each do |item|
|
||||||
next if !EmailAddress.find_by(email: item.address.downcase)
|
next if !EmailAddress.find_by(email: item.address.downcase)
|
||||||
|
|
||||||
mail['x-zammad-ticket-create-article-sender'.to_sym] = 'Agent'
|
mail['x-zammad-ticket-create-article-sender'.to_sym] = 'Agent'
|
||||||
mail['x-zammad-article-sender'.to_sym] = 'Agent'
|
mail['x-zammad-article-sender'.to_sym] = 'Agent'
|
||||||
return true
|
return true
|
||||||
|
@ -29,10 +31,12 @@ module Channel::Filter::SenderIsSystemAddress
|
||||||
|
|
||||||
# check if sender is agent
|
# check if sender is agent
|
||||||
return if mail[:from_email].blank?
|
return if mail[:from_email].blank?
|
||||||
|
|
||||||
begin
|
begin
|
||||||
user = User.find_by(email: mail[:from_email].downcase)
|
user = User.find_by(email: mail[:from_email].downcase)
|
||||||
return if !user
|
return if !user
|
||||||
return if !user.permissions?('ticket.agent')
|
return if !user.permissions?('ticket.agent')
|
||||||
|
|
||||||
mail['x-zammad-ticket-create-article-sender'.to_sym] = 'Agent'
|
mail['x-zammad-ticket-create-article-sender'.to_sym] = 'Agent'
|
||||||
mail['x-zammad-article-sender'.to_sym] = 'Agent'
|
mail['x-zammad-article-sender'.to_sym] = 'Agent'
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -9,6 +9,7 @@ module Channel::Filter::Trusted
|
||||||
if !channel[:trusted]
|
if !channel[:trusted]
|
||||||
mail.each_key do |key|
|
mail.each_key do |key|
|
||||||
next if key !~ /^x-zammad/i
|
next if key !~ /^x-zammad/i
|
||||||
|
|
||||||
mail.delete(key)
|
mail.delete(key)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
|
@ -20,6 +21,7 @@ module Channel::Filter::Trusted
|
||||||
|
|
||||||
# no assoc exists, remove header
|
# no assoc exists, remove header
|
||||||
next if Channel::EmailParser.check_attributes_by_x_headers(key, value)
|
next if Channel::EmailParser.check_attributes_by_x_headers(key, value)
|
||||||
|
|
||||||
mail.delete(key.to_sym)
|
mail.delete(key.to_sym)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ class Chat < ApplicationModel
|
||||||
|
|
||||||
def self.agent_state(user_id)
|
def self.agent_state(user_id)
|
||||||
return { state: 'chat_disabled' } if !Setting.get('chat')
|
return { state: 'chat_disabled' } if !Setting.get('chat')
|
||||||
|
|
||||||
assets = {}
|
assets = {}
|
||||||
Chat.where(active: true).each do |chat|
|
Chat.where(active: true).each do |chat|
|
||||||
assets = chat.assets(assets)
|
assets = chat.assets(assets)
|
||||||
|
@ -76,8 +77,10 @@ class Chat < ApplicationModel
|
||||||
runningchat_session_list_local = running_chat_session_list
|
runningchat_session_list_local = running_chat_session_list
|
||||||
runningchat_session_list_local.each do |session|
|
runningchat_session_list_local.each do |session|
|
||||||
next if !session['user_id']
|
next if !session['user_id']
|
||||||
|
|
||||||
user = User.lookup(id: session['user_id'])
|
user = User.lookup(id: session['user_id'])
|
||||||
next if !user
|
next if !user
|
||||||
|
|
||||||
assets = user.assets(assets)
|
assets = user.assets(assets)
|
||||||
end
|
end
|
||||||
{
|
{
|
||||||
|
@ -96,6 +99,7 @@ class Chat < ApplicationModel
|
||||||
|
|
||||||
def self.agent_state_with_sessions(user_id)
|
def self.agent_state_with_sessions(user_id)
|
||||||
return { state: 'chat_disabled' } if !Setting.get('chat')
|
return { state: 'chat_disabled' } if !Setting.get('chat')
|
||||||
|
|
||||||
result = agent_state(user_id)
|
result = agent_state(user_id)
|
||||||
result[:active_sessions] = Chat::Session.active_chats_by_user_id(user_id)
|
result[:active_sessions] = Chat::Session.active_chats_by_user_id(user_id)
|
||||||
result
|
result
|
||||||
|
@ -146,6 +150,7 @@ class Chat < ApplicationModel
|
||||||
Chat::Agent.where(active: true).where('updated_at > ?', Time.zone.now - diff).each do |record|
|
Chat::Agent.where(active: true).where('updated_at > ?', Time.zone.now - diff).each do |record|
|
||||||
user = User.lookup(id: record.updated_by_id)
|
user = User.lookup(id: record.updated_by_id)
|
||||||
next if !user
|
next if !user
|
||||||
|
|
||||||
users.push user
|
users.push user
|
||||||
end
|
end
|
||||||
users
|
users
|
||||||
|
@ -180,6 +185,7 @@ optional you can ignore it for dedecated user
|
||||||
# send broadcast to agents
|
# send broadcast to agents
|
||||||
Chat::Agent.where('active = ? OR updated_at > ?', true, Time.zone.now - 8.hours).each do |item|
|
Chat::Agent.where('active = ? OR updated_at > ?', true, Time.zone.now - 8.hours).each do |item|
|
||||||
next if item.updated_by_id == ignore_user_id
|
next if item.updated_by_id == ignore_user_id
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
event: 'chat_status_agent',
|
event: 'chat_status_agent',
|
||||||
data: Chat.agent_state(item.updated_by_id),
|
data: Chat.agent_state(item.updated_by_id),
|
||||||
|
@ -250,6 +256,7 @@ optional you can put the max oldest chat sessions as argument
|
||||||
def self.cleanup_close(diff = 5.minutes)
|
def self.cleanup_close(diff = 5.minutes)
|
||||||
Chat::Session.where.not(state: 'closed').where('updated_at < ?', Time.zone.now - diff).each do |chat_session|
|
Chat::Session.where.not(state: 'closed').where('updated_at < ?', Time.zone.now - diff).each do |chat_session|
|
||||||
next if chat_session.recipients_active?
|
next if chat_session.recipients_active?
|
||||||
|
|
||||||
chat_session.state = 'closed'
|
chat_session.state = 'closed'
|
||||||
chat_session.save
|
chat_session.save
|
||||||
message = {
|
message = {
|
||||||
|
@ -276,6 +283,7 @@ check if ip address is blocked for chat
|
||||||
def blocked_ip?(ip)
|
def blocked_ip?(ip)
|
||||||
return false if ip.blank?
|
return false if ip.blank?
|
||||||
return false if block_ip.blank?
|
return false if block_ip.blank?
|
||||||
|
|
||||||
ips = block_ip.split(';')
|
ips = block_ip.split(';')
|
||||||
ips.each do |local_ip|
|
ips.each do |local_ip|
|
||||||
return true if ip == local_ip.strip
|
return true if ip == local_ip.strip
|
||||||
|
@ -296,9 +304,11 @@ check if country is blocked for chat
|
||||||
def blocked_country?(ip)
|
def blocked_country?(ip)
|
||||||
return false if ip.blank?
|
return false if ip.blank?
|
||||||
return false if block_country.blank?
|
return false if block_country.blank?
|
||||||
|
|
||||||
geo_ip = Service::GeoIp.location(ip)
|
geo_ip = Service::GeoIp.location(ip)
|
||||||
return false if geo_ip.blank?
|
return false if geo_ip.blank?
|
||||||
return false if geo_ip['country_code'].blank?
|
return false if geo_ip['country_code'].blank?
|
||||||
|
|
||||||
countries = block_country.split(';')
|
countries = block_country.split(';')
|
||||||
countries.each do |local_country|
|
countries.each do |local_country|
|
||||||
return true if geo_ip['country_code'] == local_country
|
return true if geo_ip['country_code'] == local_country
|
||||||
|
|
|
@ -14,6 +14,7 @@ class Chat::Agent < ApplicationModel
|
||||||
)
|
)
|
||||||
if state.nil?
|
if state.nil?
|
||||||
return false if !chat_agent
|
return false if !chat_agent
|
||||||
|
|
||||||
return chat_agent.active
|
return chat_agent.active
|
||||||
end
|
end
|
||||||
if chat_agent
|
if chat_agent
|
||||||
|
|
|
@ -23,6 +23,7 @@ class Chat::Session < ApplicationModel
|
||||||
preferences[:participants] = []
|
preferences[:participants] = []
|
||||||
end
|
end
|
||||||
return preferences[:participants] if preferences[:participants].include?(client_id)
|
return preferences[:participants] if preferences[:participants].include?(client_id)
|
||||||
|
|
||||||
preferences[:participants].push client_id
|
preferences[:participants].push client_id
|
||||||
if store
|
if store
|
||||||
save
|
save
|
||||||
|
@ -33,18 +34,22 @@ class Chat::Session < ApplicationModel
|
||||||
def recipients_active?
|
def recipients_active?
|
||||||
return true if !preferences
|
return true if !preferences
|
||||||
return true if !preferences[:participants]
|
return true if !preferences[:participants]
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
preferences[:participants].each do |client_id|
|
preferences[:participants].each do |client_id|
|
||||||
next if !Sessions.session_exists?(client_id)
|
next if !Sessions.session_exists?(client_id)
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
end
|
end
|
||||||
return true if count >= 2
|
return true if count >= 2
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_to_recipients(message, ignore_client_id = nil)
|
def send_to_recipients(message, ignore_client_id = nil)
|
||||||
preferences[:participants].each do |local_client_id|
|
preferences[:participants].each do |local_client_id|
|
||||||
next if local_client_id == ignore_client_id
|
next if local_client_id == ignore_client_id
|
||||||
|
|
||||||
Sessions.send(local_client_id, message)
|
Sessions.send(local_client_id, message)
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
|
@ -52,6 +57,7 @@ class Chat::Session < ApplicationModel
|
||||||
|
|
||||||
def position
|
def position
|
||||||
return if state != 'waiting'
|
return if state != 'waiting'
|
||||||
|
|
||||||
position = 0
|
position = 0
|
||||||
Chat::Session.where(state: 'waiting').order(created_at: :asc).each do |chat_session|
|
Chat::Session.where(state: 'waiting').order(created_at: :asc).each do |chat_session|
|
||||||
position += 1
|
position += 1
|
||||||
|
@ -63,6 +69,7 @@ class Chat::Session < ApplicationModel
|
||||||
def self.messages_by_session_id(session_id)
|
def self.messages_by_session_id(session_id)
|
||||||
chat_session = Chat::Session.find_by(session_id: session_id)
|
chat_session = Chat::Session.find_by(session_id: session_id)
|
||||||
return if !chat_session
|
return if !chat_session
|
||||||
|
|
||||||
session_attributes = []
|
session_attributes = []
|
||||||
Chat::Message.where(chat_session_id: chat_session.id).order(created_at: :asc).each do |message|
|
Chat::Message.where(chat_session_id: chat_session.id).order(created_at: :asc).each do |message|
|
||||||
session_attributes.push message.attributes
|
session_attributes.push message.attributes
|
||||||
|
|
|
@ -48,8 +48,10 @@ returns
|
||||||
%w[created_by_id updated_by_id].each do |local_user_id|
|
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||||
next if !self[ local_user_id ]
|
next if !self[ local_user_id ]
|
||||||
next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ]
|
next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ]
|
||||||
|
|
||||||
user = User.lookup(id: self[ local_user_id ])
|
user = User.lookup(id: self[ local_user_id ])
|
||||||
next if !user
|
next if !user
|
||||||
|
|
||||||
data = user.assets(data)
|
data = user.assets(data)
|
||||||
end
|
end
|
||||||
data
|
data
|
||||||
|
|
|
@ -27,6 +27,7 @@ returns if user has no permissions to search
|
||||||
|
|
||||||
def search_preferences(current_user)
|
def search_preferences(current_user)
|
||||||
return false if Setting.get('chat') != true || !current_user.permissions?('chat.agent')
|
return false if Setting.get('chat') != true || !current_user.permissions?('chat.agent')
|
||||||
|
|
||||||
{
|
{
|
||||||
prio: 900,
|
prio: 900,
|
||||||
direct_search_index: true,
|
direct_search_index: true,
|
||||||
|
@ -68,6 +69,7 @@ returns
|
||||||
items.each do |item|
|
items.each do |item|
|
||||||
chat_session = Chat::Session.lookup(id: item[:id])
|
chat_session = Chat::Session.lookup(id: item[:id])
|
||||||
next if !chat_session
|
next if !chat_session
|
||||||
|
|
||||||
chat_sessions.push chat_session
|
chat_sessions.push chat_session
|
||||||
end
|
end
|
||||||
return chat_sessions
|
return chat_sessions
|
||||||
|
|
|
@ -70,6 +70,7 @@ returns
|
||||||
|
|
||||||
if data[:file].present?
|
if data[:file].present?
|
||||||
raise Exceptions::UnprocessableEntity, "No such file '#{data[:file]}'" if !File.exist?(data[:file])
|
raise Exceptions::UnprocessableEntity, "No such file '#{data[:file]}'" if !File.exist?(data[:file])
|
||||||
|
|
||||||
begin
|
begin
|
||||||
file = File.open(data[:file], 'r:UTF-8')
|
file = File.open(data[:file], 'r:UTF-8')
|
||||||
data[:string] = file.read
|
data[:string] = file.read
|
||||||
|
@ -103,6 +104,7 @@ returns
|
||||||
item.strip!
|
item.strip!
|
||||||
end
|
end
|
||||||
next if !item.respond_to?(:downcase!)
|
next if !item.respond_to?(:downcase!)
|
||||||
|
|
||||||
item.downcase!
|
item.downcase!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -124,6 +126,7 @@ returns
|
||||||
row.each_with_index do |item, count|
|
row.each_with_index do |item, count|
|
||||||
next if item.blank?
|
next if item.blank?
|
||||||
next if header[count].nil?
|
next if header[count].nil?
|
||||||
|
|
||||||
if payload_last[header[count].to_sym].class != Array
|
if payload_last[header[count].to_sym].class != Array
|
||||||
payload_last[header[count].to_sym] = [payload_last[header[count].to_sym]]
|
payload_last[header[count].to_sym] = [payload_last[header[count].to_sym]]
|
||||||
end
|
end
|
||||||
|
@ -136,6 +139,7 @@ returns
|
||||||
next if !item
|
next if !item
|
||||||
next if header[count].blank?
|
next if header[count].blank?
|
||||||
next if @csv_attributes_ignored&.include?(header[count].to_sym)
|
next if @csv_attributes_ignored&.include?(header[count].to_sym)
|
||||||
|
|
||||||
attributes[header[count].to_sym] = if item.respond_to?(:strip)
|
attributes[header[count].to_sym] = if item.respond_to?(:strip)
|
||||||
item.strip
|
item.strip
|
||||||
else
|
else
|
||||||
|
@ -170,6 +174,7 @@ returns
|
||||||
record = nil
|
record = nil
|
||||||
%i[id number name login email].each do |lookup_by|
|
%i[id number name login email].each do |lookup_by|
|
||||||
next if !attributes[lookup_by]
|
next if !attributes[lookup_by]
|
||||||
|
|
||||||
params = {}
|
params = {}
|
||||||
params[lookup_by] = attributes[lookup_by]
|
params[lookup_by] = attributes[lookup_by]
|
||||||
record = lookup(params)
|
record = lookup(params)
|
||||||
|
@ -208,6 +213,7 @@ returns
|
||||||
end
|
end
|
||||||
record = new(clean_params)
|
record = new(clean_params)
|
||||||
next if try == true
|
next if try == true
|
||||||
|
|
||||||
record.associations_from_param(attributes)
|
record.associations_from_param(attributes)
|
||||||
record.save!
|
record.save!
|
||||||
rescue => e
|
rescue => e
|
||||||
|
@ -217,6 +223,7 @@ returns
|
||||||
else
|
else
|
||||||
stats[:updated] += 1
|
stats[:updated] += 1
|
||||||
next if try == true
|
next if try == true
|
||||||
|
|
||||||
begin
|
begin
|
||||||
csv_verify_attributes(clean_params)
|
csv_verify_attributes(clean_params)
|
||||||
clean_params = param_cleanup(clean_params)
|
clean_params = param_cleanup(clean_params)
|
||||||
|
@ -278,6 +285,7 @@ verify if attributes are valid, will raise an ArgumentError with "unknown attrib
|
||||||
end
|
end
|
||||||
clean_params.each_key do |key|
|
clean_params.each_key do |key|
|
||||||
next if all_clean_attributes.key?(key.to_sym)
|
next if all_clean_attributes.key?(key.to_sym)
|
||||||
|
|
||||||
raise ArgumentError, "unknown attribute '#{key}' for #{new.class}."
|
raise ArgumentError, "unknown attribute '#{key}' for #{new.class}."
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
|
@ -319,6 +327,7 @@ returns
|
||||||
next if key == 'created_at'
|
next if key == 'created_at'
|
||||||
next if key == 'updated_at'
|
next if key == 'updated_at'
|
||||||
next if header.include?(key)
|
next if header.include?(key)
|
||||||
|
|
||||||
header.push key
|
header.push key
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -339,6 +348,7 @@ returns
|
||||||
record[key].each do |entry|
|
record[key].each do |entry|
|
||||||
entry_count += 1
|
entry_count += 1
|
||||||
next if entry_count == -1
|
next if entry_count == -1
|
||||||
|
|
||||||
if !rows_to_add[entry_count]
|
if !rows_to_add[entry_count]
|
||||||
rows_to_add[entry_count] = Array.new(header.count + 1) { '' }
|
rows_to_add[entry_count] = Array.new(header.count + 1) { '' }
|
||||||
end
|
end
|
||||||
|
@ -350,6 +360,7 @@ returns
|
||||||
end
|
end
|
||||||
rows.push row
|
rows.push row
|
||||||
next if rows_to_add.count.zero?
|
next if rows_to_add.count.zero?
|
||||||
|
|
||||||
rows_to_add.each do |item|
|
rows_to_add.each do |item|
|
||||||
rows.push item
|
rows.push item
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,6 +21,7 @@ returns
|
||||||
|
|
||||||
def generate_uniq_name(name)
|
def generate_uniq_name(name)
|
||||||
return name if !exists?(name: name)
|
return name if !exists?(name: name)
|
||||||
|
|
||||||
(1..100).each do |counter|
|
(1..100).each do |counter|
|
||||||
name = "#{name}_#{counter}"
|
name = "#{name}_#{counter}"
|
||||||
break if !exists?(name: name)
|
break if !exists?(name: name)
|
||||||
|
|
|
@ -29,6 +29,7 @@ class OwnModel < ApplicationModel
|
||||||
|
|
||||||
# return if we run import mode
|
# return if we run import mode
|
||||||
return if Setting.get('import_mode')
|
return if Setting.get('import_mode')
|
||||||
|
|
||||||
logger.debug { "#{self.class.name}.find(#{id}) notify created #{created_at}" }
|
logger.debug { "#{self.class.name}.find(#{id}) notify created #{created_at}" }
|
||||||
class_name = self.class.name
|
class_name = self.class.name
|
||||||
class_name.gsub!(/::/, '')
|
class_name.gsub!(/::/, '')
|
||||||
|
@ -61,6 +62,7 @@ class OwnModel < ApplicationModel
|
||||||
|
|
||||||
# return if we run import mode
|
# return if we run import mode
|
||||||
return if Setting.get('import_mode')
|
return if Setting.get('import_mode')
|
||||||
|
|
||||||
logger.debug { "#{self.class.name}.find(#{id}) notify UPDATED #{updated_at}" }
|
logger.debug { "#{self.class.name}.find(#{id}) notify UPDATED #{updated_at}" }
|
||||||
class_name = self.class.name
|
class_name = self.class.name
|
||||||
class_name.gsub!(/::/, '')
|
class_name.gsub!(/::/, '')
|
||||||
|
@ -93,6 +95,7 @@ class OwnModel < ApplicationModel
|
||||||
|
|
||||||
# return if we run import mode
|
# return if we run import mode
|
||||||
return if Setting.get('import_mode')
|
return if Setting.get('import_mode')
|
||||||
|
|
||||||
logger.debug { "#{self.class.name}.find(#{id}) notify TOUCH #{updated_at}" }
|
logger.debug { "#{self.class.name}.find(#{id}) notify TOUCH #{updated_at}" }
|
||||||
class_name = self.class.name
|
class_name = self.class.name
|
||||||
class_name.gsub!(/::/, '')
|
class_name.gsub!(/::/, '')
|
||||||
|
@ -124,6 +127,7 @@ class OwnModel < ApplicationModel
|
||||||
|
|
||||||
# return if we run import mode
|
# return if we run import mode
|
||||||
return if Setting.get('import_mode')
|
return if Setting.get('import_mode')
|
||||||
|
|
||||||
logger.debug { "#{self.class.name}.find(#{id}) notify DESTOY #{updated_at}" }
|
logger.debug { "#{self.class.name}.find(#{id}) notify DESTOY #{updated_at}" }
|
||||||
class_name = self.class.name
|
class_name = self.class.name
|
||||||
class_name.gsub!(/::/, '')
|
class_name.gsub!(/::/, '')
|
||||||
|
|
|
@ -28,6 +28,7 @@ module ChecksConditionValidation
|
||||||
|
|
||||||
ticket_count, tickets = Ticket.selectors(validate_condition, 1, User.find(1))
|
ticket_count, tickets = Ticket.selectors(validate_condition, 1, User.find(1))
|
||||||
return true if ticket_count.present?
|
return true if ticket_count.present?
|
||||||
|
|
||||||
raise Exceptions::UnprocessableEntity, 'Invalid ticket selector conditions'
|
raise Exceptions::UnprocessableEntity, 'Invalid ticket selector conditions'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -40,9 +40,11 @@ log object update activity stream, if configured - will be executed automaticall
|
||||||
log = false
|
log = false
|
||||||
saved_changes.each_key do |key|
|
saved_changes.each_key do |key|
|
||||||
next if ignored_attributes.include?(key.to_sym)
|
next if ignored_attributes.include?(key.to_sym)
|
||||||
|
|
||||||
log = true
|
log = true
|
||||||
end
|
end
|
||||||
return true if !log
|
return true if !log
|
||||||
|
|
||||||
activity_stream_log('update', self['updated_by_id'])
|
activity_stream_log('update', self['updated_by_id'])
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,6 +47,7 @@ module HasGroupRelationDefinition
|
||||||
end
|
end
|
||||||
|
|
||||||
return if !query.exists?
|
return if !query.exists?
|
||||||
|
|
||||||
errors.add(:access, "#{group_relation_model_identifier.to_s.capitalize} can have full or granular access to group")
|
errors.add(:access, "#{group_relation_model_identifier.to_s.capitalize} can have full or granular access to group")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,7 @@ module HasGroups
|
||||||
|
|
||||||
# check indirect access through Roles if possible
|
# check indirect access through Roles if possible
|
||||||
return false if !respond_to?(:role_access?)
|
return false if !respond_to?(:role_access?)
|
||||||
|
|
||||||
role_access?(group_id, access)
|
role_access?(group_id, access)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -197,6 +198,7 @@ module HasGroups
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def groups_access_permission?
|
def groups_access_permission?
|
||||||
return true if !respond_to?(:permissions?)
|
return true if !respond_to?(:permissions?)
|
||||||
|
|
||||||
permissions?('ticket.agent')
|
permissions?('ticket.agent')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -244,6 +246,7 @@ module HasGroups
|
||||||
# if changes to the map were performed
|
# if changes to the map were performed
|
||||||
# otherwise it's just an update of other attributes
|
# otherwise it's just an update of other attributes
|
||||||
return if group_access_buffer.nil?
|
return if group_access_buffer.nil?
|
||||||
|
|
||||||
yield
|
yield
|
||||||
group_access_buffer = nil
|
group_access_buffer = nil
|
||||||
cache_delete
|
cache_delete
|
||||||
|
@ -356,6 +359,7 @@ module HasGroups
|
||||||
|
|
||||||
def ensure_group_id_parameter(group_or_id)
|
def ensure_group_id_parameter(group_or_id)
|
||||||
return group_or_id if group_or_id.is_a?(Integer)
|
return group_or_id if group_or_id.is_a?(Integer)
|
||||||
|
|
||||||
group_or_id.id
|
group_or_id.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@ module HasRoles
|
||||||
|
|
||||||
def ensure_group_id_parameter(group_or_id)
|
def ensure_group_id_parameter(group_or_id)
|
||||||
return group_or_id if group_or_id.is_a?(Integer)
|
return group_or_id if group_or_id.is_a?(Integer)
|
||||||
|
|
||||||
group_or_id.id
|
group_or_id.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ update search index, if configured - will be executed automatically
|
||||||
|
|
||||||
# start background job to transfer data to search index
|
# start background job to transfer data to search index
|
||||||
return true if !SearchIndexBackend.enabled?
|
return true if !SearchIndexBackend.enabled?
|
||||||
|
|
||||||
Delayed::Job.enqueue(BackgroundJobSearchIndex.new(self.class.to_s, id))
|
Delayed::Job.enqueue(BackgroundJobSearchIndex.new(self.class.to_s, id))
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
@ -38,6 +39,7 @@ delete search index object, will be executed automatically
|
||||||
|
|
||||||
def search_index_destroy
|
def search_index_destroy
|
||||||
return true if ignore_search_indexing?(:destroy)
|
return true if ignore_search_indexing?(:destroy)
|
||||||
|
|
||||||
SearchIndexBackend.remove(self.class.to_s, id)
|
SearchIndexBackend.remove(self.class.to_s, id)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
@ -87,9 +89,11 @@ returns
|
||||||
%w[name note].each do |key|
|
%w[name note].each do |key|
|
||||||
next if !self[key]
|
next if !self[key]
|
||||||
next if self[key].respond_to?('blank?') && self[key].blank?
|
next if self[key].respond_to?('blank?') && self[key].blank?
|
||||||
|
|
||||||
attributes[key] = self[key]
|
attributes[key] = self[key]
|
||||||
end
|
end
|
||||||
return true if attributes.blank?
|
return true if attributes.blank?
|
||||||
|
|
||||||
attributes
|
attributes
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -130,6 +134,7 @@ reload search index with full data
|
||||||
ids.each do |item_id|
|
ids.each do |item_id|
|
||||||
item = find(item_id)
|
item = find(item_id)
|
||||||
next if item.ignore_search_indexing?(:destroy)
|
next if item.ignore_search_indexing?(:destroy)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
item.search_index_update_backend
|
item.search_index_update_backend
|
||||||
rescue => e
|
rescue => e
|
||||||
|
|
|
@ -72,6 +72,7 @@ returns
|
||||||
# check order
|
# check order
|
||||||
params[:order_by].each do |value|
|
params[:order_by].each do |value|
|
||||||
raise "Found invalid order by value #{value}. Please use 'asc' or 'desc'." if value !~ /\A(asc|desc)\z/i
|
raise "Found invalid order by value #{value}. Please use 'asc' or 'desc'." if value !~ /\A(asc|desc)\z/i
|
||||||
|
|
||||||
order_by.push(value.downcase)
|
order_by.push(value.downcase)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ module Cti
|
||||||
)
|
)
|
||||||
|
|
||||||
return record if !record.new_record?
|
return record if !record.new_record?
|
||||||
|
|
||||||
record.comment = data[:comment]
|
record.comment = data[:comment]
|
||||||
record.save!
|
record.save!
|
||||||
end
|
end
|
||||||
|
@ -72,10 +73,12 @@ returns
|
||||||
model = nil
|
model = nil
|
||||||
map.each do |item|
|
map.each do |item|
|
||||||
next if item[:model] != record.class
|
next if item[:model] != record.class
|
||||||
|
|
||||||
level = item[:level]
|
level = item[:level]
|
||||||
model = item[:model]
|
model = item[:model]
|
||||||
end
|
end
|
||||||
return if !level || !model
|
return if !level || !model
|
||||||
|
|
||||||
build_item(record, model, level)
|
build_item(record, model, level)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -92,6 +95,7 @@ returns
|
||||||
article = record.articles.first
|
article = record.articles.first
|
||||||
return if !article
|
return if !article
|
||||||
return if article.sender.name != 'Customer'
|
return if article.sender.name != 'Customer'
|
||||||
|
|
||||||
record = article
|
record = article
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -112,8 +116,10 @@ returns
|
||||||
attributes.each_value do |value|
|
attributes.each_value do |value|
|
||||||
next if value.class != String
|
next if value.class != String
|
||||||
next if value.blank?
|
next if value.blank?
|
||||||
|
|
||||||
local_caller_ids = Cti::CallerId.extract_numbers(value)
|
local_caller_ids = Cti::CallerId.extract_numbers(value)
|
||||||
next if local_caller_ids.blank?
|
next if local_caller_ids.blank?
|
||||||
|
|
||||||
caller_ids = caller_ids.concat(local_caller_ids)
|
caller_ids = caller_ids.concat(local_caller_ids)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -217,6 +223,7 @@ returns
|
||||||
def self.extract_numbers(text)
|
def self.extract_numbers(text)
|
||||||
# see specs for example
|
# see specs for example
|
||||||
return [] if !text.is_a?(String)
|
return [] if !text.is_a?(String)
|
||||||
|
|
||||||
text.scan(/([\d|\s|\-|\(|\)]{6,26})/).map do |match|
|
text.scan(/([\d|\s|\-|\(|\)]{6,26})/).map do |match|
|
||||||
normalize_number(match[0])
|
normalize_number(match[0])
|
||||||
end
|
end
|
||||||
|
@ -273,17 +280,20 @@ returns
|
||||||
end
|
end
|
||||||
return [from_comment_known, preferences_known] if from_comment_known.present?
|
return [from_comment_known, preferences_known] if from_comment_known.present?
|
||||||
return ["maybe #{from_comment_maybe}", preferences_maybe] if from_comment_maybe.present?
|
return ["maybe #{from_comment_maybe}", preferences_maybe] if from_comment_maybe.present?
|
||||||
|
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_cti_logs
|
def update_cti_logs
|
||||||
return if object != 'User'
|
return if object != 'User'
|
||||||
|
|
||||||
UpdateCtiLogsByCallerJob.perform_later(caller_id)
|
UpdateCtiLogsByCallerJob.perform_later(caller_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_cti_logs_with_fg_optimization
|
def update_cti_logs_with_fg_optimization
|
||||||
return if object != 'User'
|
return if object != 'User'
|
||||||
return if level != 'known'
|
return if level != 'known'
|
||||||
|
|
||||||
UpdateCtiLogsByCallerJob.perform_now(caller_id, limit: 20)
|
UpdateCtiLogsByCallerJob.perform_now(caller_id, limit: 20)
|
||||||
UpdateCtiLogsByCallerJob.perform_later(caller_id, limit: 40, offset: 20)
|
UpdateCtiLogsByCallerJob.perform_later(caller_id, limit: 40, offset: 20)
|
||||||
end
|
end
|
||||||
|
|
|
@ -320,6 +320,7 @@ Cti::Log.process(
|
||||||
done = false
|
done = false
|
||||||
end
|
end
|
||||||
raise "call_id #{call_id} already exists!" if log
|
raise "call_id #{call_id} already exists!" if log
|
||||||
|
|
||||||
create(
|
create(
|
||||||
direction: params['direction'],
|
direction: params['direction'],
|
||||||
from: params['from'],
|
from: params['from'],
|
||||||
|
@ -336,6 +337,7 @@ Cti::Log.process(
|
||||||
when 'answer'
|
when 'answer'
|
||||||
raise "No such call_id #{call_id}" if !log
|
raise "No such call_id #{call_id}" if !log
|
||||||
return if log.state == 'hangup' # call is already hangup, ignore answer
|
return if log.state == 'hangup' # call is already hangup, ignore answer
|
||||||
|
|
||||||
log.with_lock do
|
log.with_lock do
|
||||||
log.state = 'answer'
|
log.state = 'answer'
|
||||||
log.start_at = Time.zone.now
|
log.start_at = Time.zone.now
|
||||||
|
@ -349,6 +351,7 @@ Cti::Log.process(
|
||||||
end
|
end
|
||||||
when 'hangup'
|
when 'hangup'
|
||||||
raise "No such call_id #{call_id}" if !log
|
raise "No such call_id #{call_id}" if !log
|
||||||
|
|
||||||
log.with_lock do
|
log.with_lock do
|
||||||
log.done = done
|
log.done = done
|
||||||
if params['direction'] == 'in'
|
if params['direction'] == 'in'
|
||||||
|
@ -395,6 +398,7 @@ Cti::Log.process(
|
||||||
def self.push_caller_list_update?(record)
|
def self.push_caller_list_update?(record)
|
||||||
list_ids = Cti::Log.log_records.pluck(:id)
|
list_ids = Cti::Log.log_records.pluck(:id)
|
||||||
return true if list_ids.include?(record.id)
|
return true if list_ids.include?(record.id)
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ check and if channel not exists reset configured channels for email addresses
|
||||||
|
|
||||||
# set in inactive if channel not longer exists
|
# set in inactive if channel not longer exists
|
||||||
next if !email_address.active
|
next if !email_address.active
|
||||||
|
|
||||||
email_address.save!
|
email_address.save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -45,9 +46,11 @@ check and if channel not exists reset configured channels for email addresses
|
||||||
def check_email
|
def check_email
|
||||||
return true if Setting.get('import_mode')
|
return true if Setting.get('import_mode')
|
||||||
return true if email.blank?
|
return true if email.blank?
|
||||||
|
|
||||||
self.email = email.downcase.strip
|
self.email = email.downcase.strip
|
||||||
raise Exceptions::UnprocessableEntity, 'Invalid email' if email !~ /@/
|
raise Exceptions::UnprocessableEntity, 'Invalid email' if email !~ /@/
|
||||||
raise Exceptions::UnprocessableEntity, 'Invalid email' if email.match?(/\s/)
|
raise Exceptions::UnprocessableEntity, 'Invalid email' if email.match?(/\s/)
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -79,6 +82,7 @@ check and if channel not exists reset configured channels for email addresses
|
||||||
total = Group.count
|
total = Group.count
|
||||||
return if not_configured.zero?
|
return if not_configured.zero?
|
||||||
return if total != 1
|
return if total != 1
|
||||||
|
|
||||||
group = Group.find_by(email_address_id: nil)
|
group = Group.find_by(email_address_id: nil)
|
||||||
group.email_address_id = id
|
group.email_address_id = id
|
||||||
group.updated_by_id = updated_by_id
|
group.updated_by_id = updated_by_id
|
||||||
|
|
|
@ -37,8 +37,10 @@ class ExternalSync < ApplicationModel
|
||||||
local_key_sym = local_key.to_sym
|
local_key_sym = local_key.to_sym
|
||||||
|
|
||||||
next if result[local_key_sym].present?
|
next if result[local_key_sym].present?
|
||||||
|
|
||||||
value = extract(remote_key, information_source)
|
value = extract(remote_key, information_source)
|
||||||
next if value.blank?
|
next if value.blank?
|
||||||
|
|
||||||
result[local_key_sym] = value
|
result[local_key_sym] = value
|
||||||
end
|
end
|
||||||
result
|
result
|
||||||
|
|
|
@ -5,11 +5,9 @@ class History < ApplicationModel
|
||||||
|
|
||||||
self.table_name = 'histories'
|
self.table_name = 'histories'
|
||||||
|
|
||||||
# rubocop:disable Rails/InverseOf
|
|
||||||
belongs_to :history_type, class_name: 'History::Type'
|
belongs_to :history_type, class_name: 'History::Type'
|
||||||
belongs_to :history_object, class_name: 'History::Object'
|
belongs_to :history_object, class_name: 'History::Object'
|
||||||
belongs_to :history_attribute, class_name: 'History::Attribute'
|
belongs_to :history_attribute, class_name: 'History::Attribute'
|
||||||
# rubocop:enable Rails/InverseOf
|
|
||||||
|
|
||||||
# the noop is needed since Layout/EmptyLines detects
|
# the noop is needed since Layout/EmptyLines detects
|
||||||
# the block commend below wrongly as the measurement of
|
# the block commend below wrongly as the measurement of
|
||||||
|
@ -101,6 +99,7 @@ remove whole history entries of an object
|
||||||
def self.remove(requested_object, requested_object_id)
|
def self.remove(requested_object, requested_object_id)
|
||||||
history_object = History::Object.find_by(name: requested_object)
|
history_object = History::Object.find_by(name: requested_object)
|
||||||
return if !history_object
|
return if !history_object
|
||||||
|
|
||||||
History.where(
|
History.where(
|
||||||
history_object_id: history_object.id,
|
history_object_id: history_object.id,
|
||||||
o_id: requested_object_id,
|
o_id: requested_object_id,
|
||||||
|
|
|
@ -51,8 +51,10 @@ class ImportJob < ApplicationModel
|
||||||
# return [Boolean] whether the ImportJob should get rescheduled (true) or destroyed (false)
|
# return [Boolean] whether the ImportJob should get rescheduled (true) or destroyed (false)
|
||||||
def reschedule?(delayed_job)
|
def reschedule?(delayed_job)
|
||||||
return false if finished_at.present?
|
return false if finished_at.present?
|
||||||
|
|
||||||
instance = name.constantize.new(self)
|
instance = name.constantize.new(self)
|
||||||
return false if !instance.respond_to?(:reschedule?)
|
return false if !instance.respond_to?(:reschedule?)
|
||||||
|
|
||||||
instance.reschedule?(delayed_job)
|
instance.reschedule?(delayed_job)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ Job.run
|
||||||
jobs = Job.where(active: true)
|
jobs = Job.where(active: true)
|
||||||
jobs.each do |job|
|
jobs.each do |job|
|
||||||
next if !job.executable?
|
next if !job.executable?
|
||||||
|
|
||||||
job.run(false, start_at)
|
job.run(false, start_at)
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
|
@ -199,10 +200,12 @@ job.run(true)
|
||||||
(0..5).each do |minute_counter|
|
(0..5).each do |minute_counter|
|
||||||
if minute_counter.nonzero?
|
if minute_counter.nonzero?
|
||||||
break if day_to_check.min.zero?
|
break if day_to_check.min.zero?
|
||||||
|
|
||||||
day_to_check = day_to_check + 10.minutes
|
day_to_check = day_to_check + 10.minutes
|
||||||
end
|
end
|
||||||
next if !timeplan['hours'][day_to_check.hour] && !timeplan['hours'][day_to_check.hour.to_s]
|
next if !timeplan['hours'][day_to_check.hour] && !timeplan['hours'][day_to_check.hour.to_s]
|
||||||
next if !timeplan['minutes'][match_minutes(day_to_check.min)] && !timeplan['minutes'][match_minutes(day_to_check.min).to_s]
|
next if !timeplan['minutes'][match_minutes(day_to_check.min)] && !timeplan['minutes'][match_minutes(day_to_check.min).to_s]
|
||||||
|
|
||||||
return day_to_check
|
return day_to_check
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -227,10 +230,12 @@ job.run(true)
|
||||||
(0..5).each do |minute_counter|
|
(0..5).each do |minute_counter|
|
||||||
minute_to_check = hour_to_check + minute_counter.minutes * 10
|
minute_to_check = hour_to_check + minute_counter.minutes * 10
|
||||||
next if !timeplan['minutes'][match_minutes(minute_to_check.min)] && !timeplan['minutes'][match_minutes(minute_to_check.min).to_s]
|
next if !timeplan['minutes'][match_minutes(minute_to_check.min)] && !timeplan['minutes'][match_minutes(minute_to_check.min).to_s]
|
||||||
|
|
||||||
time_to_check = minute_to_check
|
time_to_check = minute_to_check
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
next if !minute_to_check
|
next if !minute_to_check
|
||||||
|
|
||||||
return time_to_check
|
return time_to_check
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -252,6 +257,7 @@ job.run(true)
|
||||||
|
|
||||||
def match_minutes(minutes)
|
def match_minutes(minutes)
|
||||||
return 0 if minutes < 10
|
return 0 if minutes < 10
|
||||||
|
|
||||||
"#{minutes.to_s.gsub(/(\d)\d/, '\\1')}0".to_i
|
"#{minutes.to_s.gsub(/(\d)\d/, '\\1')}0".to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,10 @@ returns
|
||||||
%w[created_by_id updated_by_id].each do |local_user_id|
|
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||||
next if !self[ local_user_id ]
|
next if !self[ local_user_id ]
|
||||||
next if data[ User.to_app_model ][ self[ local_user_id ] ]
|
next if data[ User.to_app_model ][ self[ local_user_id ] ]
|
||||||
|
|
||||||
user = User.lookup(id: self[ local_user_id ])
|
user = User.lookup(id: self[ local_user_id ])
|
||||||
next if !user
|
next if !user
|
||||||
|
|
||||||
data = user.assets(data)
|
data = user.assets(data)
|
||||||
end
|
end
|
||||||
data
|
data
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue