mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-10-29 07:26:28 +08:00
Merge pull request #385 from okriuchykhin/ok_SCI_102
Fix XSS on activites and throghout the rest of app [SCI-102]
This commit is contained in:
commit
02bfd19d1c
71 changed files with 268 additions and 189 deletions
|
|
@ -1,4 +1,6 @@
|
|||
class CustomFieldsController < ApplicationController
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :load_vars, only: [:update, :destroy, :destroy_html]
|
||||
before_action :load_vars_nested, only: [:create, :destroy_html]
|
||||
before_action :check_create_permissions, only: :create
|
||||
|
|
@ -15,7 +17,7 @@ class CustomFieldsController < ApplicationController
|
|||
format.json do
|
||||
render json: {
|
||||
id: @custom_field.id,
|
||||
name: @custom_field.name,
|
||||
name: escape_input(@custom_field.name),
|
||||
edit_url:
|
||||
organization_custom_field_path(@organization, @custom_field),
|
||||
destroy_html_url:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ class ExperimentsController < ApplicationController
|
|||
include SampleActions
|
||||
include PermissionHelper
|
||||
include OrganizationsHelper
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :set_experiment,
|
||||
except: [:new, :create]
|
||||
|
|
@ -252,7 +253,8 @@ class ExperimentsController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.json do
|
||||
render json: { message: t('experiments.move.error_flash',
|
||||
experiment: @experiment.name) },
|
||||
experiment:
|
||||
escape_input(@experiment.name)) },
|
||||
status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
class MyModuleCommentsController < ApplicationController
|
||||
include ActionView::Helpers::TextHelper
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :load_vars
|
||||
before_action :check_view_permissions, only: :index
|
||||
|
|
@ -115,7 +116,7 @@ class MyModuleCommentsController < ApplicationController
|
|||
)
|
||||
)
|
||||
render json: {
|
||||
comment: auto_link(
|
||||
comment: custom_auto_link(
|
||||
simple_format(@comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
class MyModulesController < ApplicationController
|
||||
include SampleActions
|
||||
include OrganizationsHelper
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :load_vars, only: [
|
||||
:show, :update, :destroy,
|
||||
|
|
@ -53,7 +54,8 @@ class MyModulesController < ApplicationController
|
|||
html: render_to_string({
|
||||
partial: "description.html.erb"
|
||||
}),
|
||||
title: t("my_modules.description.title", module: @my_module.name)
|
||||
title: t('my_modules.description.title',
|
||||
module: escape_input(@my_module.name))
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
@ -124,7 +126,8 @@ class MyModulesController < ApplicationController
|
|||
html: render_to_string({
|
||||
partial: "due_date.html.erb"
|
||||
}),
|
||||
title: t("my_modules.due_date.title", module: @my_module.name)
|
||||
title: t('my_modules.due_date.title',
|
||||
module: escape_input(@my_module.name))
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
class ProjectCommentsController < ApplicationController
|
||||
include ActionView::Helpers::TextHelper
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :load_vars
|
||||
before_action :check_view_permissions, only: :index
|
||||
|
|
@ -112,7 +113,7 @@ class ProjectCommentsController < ApplicationController
|
|||
)
|
||||
)
|
||||
render json: {
|
||||
comment: auto_link(
|
||||
comment: custom_auto_link(
|
||||
simple_format(@comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ class ProjectsController < ApplicationController
|
|||
include SampleActions
|
||||
include RenamingUtil
|
||||
include OrganizationsHelper
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :load_vars, only: [:show, :edit, :update,
|
||||
:notifications, :reports,
|
||||
|
|
@ -104,7 +105,8 @@ class ProjectsController < ApplicationController
|
|||
partial: "edit.html.erb",
|
||||
locals: { project: @project }
|
||||
}),
|
||||
title: t("projects.index.modal_edit_project.modal_title", project: @project.name)
|
||||
title: t('projects.index.modal_edit_project.modal_title',
|
||||
project: escape_input(@project.name))
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ class ProtocolsController < ApplicationController
|
|||
include RenamingUtil
|
||||
include ProtocolsImporter
|
||||
include ProtocolsExporter
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :check_create_permissions, only: [
|
||||
:create_new_modal,
|
||||
|
|
@ -86,7 +87,7 @@ class ProtocolsController < ApplicationController
|
|||
format.json do
|
||||
render json: {
|
||||
title: I18n.t('protocols.index.preview.title',
|
||||
protocol: @protocol.name),
|
||||
protocol: escape_input(@protocol.name)),
|
||||
html: render_to_string(
|
||||
partial: 'protocols/index/protocol_preview_modal_body.html.erb',
|
||||
locals: { protocol: @protocol }
|
||||
|
|
@ -104,7 +105,8 @@ class ProtocolsController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.json {
|
||||
render json: {
|
||||
title: I18n.t("protocols.index.linked_children.title", protocol: @protocol.name),
|
||||
title: I18n.t('protocols.index.linked_children.title',
|
||||
protocol: escape_input(@protocol.name)),
|
||||
html: render_to_string({
|
||||
partial: "protocols/index/linked_children_modal_body.html.erb",
|
||||
locals: { protocol: @protocol }
|
||||
|
|
@ -181,7 +183,7 @@ class ProtocolsController < ApplicationController
|
|||
respond_to do |format|
|
||||
# sanitize user input
|
||||
params[:keywords].collect! do |keyword|
|
||||
ActionController::Base.helpers.sanitize(keyword)
|
||||
escape_input(keyword)
|
||||
end
|
||||
if @protocol.update_keywords(params[:keywords])
|
||||
format.json {
|
||||
|
|
@ -536,10 +538,12 @@ class ProtocolsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
p_name = (
|
||||
@protocol_json["name"].present? &&
|
||||
!@protocol_json["name"].empty?
|
||||
) ? @protocol_json["name"] : t("protocols.index.no_protocol_name")
|
||||
p_name =
|
||||
if @protocol_json['name'].present? && !@protocol_json['name'].empty?
|
||||
escape_input(@protocol_json['name'])
|
||||
else
|
||||
t('protocols.index.no_protocol_name')
|
||||
end
|
||||
if transaction_error
|
||||
format.json {
|
||||
render json: { name: p_name, status: :bad_request }, status: :bad_request
|
||||
|
|
@ -700,7 +704,8 @@ class ProtocolsController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.json {
|
||||
render json: {
|
||||
title: I18n.t("protocols.header.edit_name_modal.title", protocol: @protocol.name),
|
||||
title: I18n.t('protocols.header.edit_name_modal.title',
|
||||
protocol: escape_input(@protocol.name)),
|
||||
html: render_to_string({
|
||||
partial: "protocols/header/edit_name_modal_body.html.erb"
|
||||
})
|
||||
|
|
@ -713,7 +718,8 @@ class ProtocolsController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.json {
|
||||
render json: {
|
||||
title: I18n.t("protocols.header.edit_keywords_modal.title", protocol: @protocol.name),
|
||||
title: I18n.t('protocols.header.edit_keywords_modal.title',
|
||||
protocol: escape_input(@protocol.name)),
|
||||
html: render_to_string({
|
||||
partial: "protocols/header/edit_keywords_modal_body.html.erb"
|
||||
}),
|
||||
|
|
@ -727,7 +733,8 @@ class ProtocolsController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.json {
|
||||
render json: {
|
||||
title: I18n.t("protocols.header.edit_authors_modal.title", protocol: @protocol.name),
|
||||
title: I18n.t('protocols.header.edit_authors_modal.title',
|
||||
protocol: escape_input(@protocol.name)),
|
||||
html: render_to_string({
|
||||
partial: "protocols/header/edit_authors_modal_body.html.erb"
|
||||
})
|
||||
|
|
@ -740,7 +747,8 @@ class ProtocolsController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.json {
|
||||
render json: {
|
||||
title: I18n.t("protocols.header.edit_description_modal.title", protocol: @protocol.name),
|
||||
title: I18n.t('protocols.header.edit_description_modal.title',
|
||||
protocol: escape_input(@protocol.name)),
|
||||
html: render_to_string({
|
||||
partial: "protocols/header/edit_description_modal_body.html.erb"
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
class ResultCommentsController < ApplicationController
|
||||
include ActionView::Helpers::TextHelper
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :load_vars
|
||||
|
||||
|
|
@ -113,7 +114,7 @@ class ResultCommentsController < ApplicationController
|
|||
)
|
||||
)
|
||||
render json: {
|
||||
comment: auto_link(
|
||||
comment: custom_auto_link(
|
||||
simple_format(@comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
class SamplesController < ApplicationController
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :load_vars, only: [:edit, :update, :destroy, :show]
|
||||
before_action :load_vars_nested, only: [:new, :create]
|
||||
|
||||
|
|
@ -85,8 +87,8 @@ class SamplesController < ApplicationController
|
|||
id: sample.id,
|
||||
flash: t(
|
||||
'samples.create.success_flash',
|
||||
sample: sample.name,
|
||||
organization: @organization.name
|
||||
sample: escape_input(sample.name),
|
||||
organization: escape_input(@organization.name)
|
||||
)
|
||||
},
|
||||
status: :ok
|
||||
|
|
@ -115,7 +117,7 @@ class SamplesController < ApplicationController
|
|||
def edit
|
||||
json = {
|
||||
sample: {
|
||||
name: @sample.name,
|
||||
name: escape_input(@sample.name),
|
||||
sample_type: @sample.sample_type.nil? ? "" : @sample.sample_type.id,
|
||||
sample_group: @sample.sample_group.nil? ? "" : @sample.sample_group.id,
|
||||
custom_fields: {}
|
||||
|
|
@ -128,7 +130,7 @@ class SamplesController < ApplicationController
|
|||
@sample.sample_custom_fields.each do |scf|
|
||||
json[:sample][:custom_fields][scf.custom_field_id] = {
|
||||
sample_custom_field_id: scf.id,
|
||||
value: scf.value
|
||||
value: escape_input(scf.value)
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -254,8 +256,8 @@ class SamplesController < ApplicationController
|
|||
id: sample.id,
|
||||
flash: t(
|
||||
'samples.update.success_flash',
|
||||
sample: sample.name,
|
||||
organization: @organization.name
|
||||
sample: escape_input(sample.name),
|
||||
organization: escape_input(@organization.name)
|
||||
)
|
||||
},
|
||||
status: :ok
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
class StepCommentsController < ApplicationController
|
||||
include ActionView::Helpers::TextHelper
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :load_vars
|
||||
|
||||
|
|
@ -118,7 +119,7 @@ class StepCommentsController < ApplicationController
|
|||
)
|
||||
end
|
||||
render json: {
|
||||
comment: auto_link(
|
||||
comment: custom_auto_link(
|
||||
simple_format(@comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
class Users::SettingsController < ApplicationController
|
||||
include UsersGenerator
|
||||
include NotificationsHelper
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :load_user, only: [
|
||||
:preferences,
|
||||
|
|
@ -184,7 +185,7 @@ class Users::SettingsController < ApplicationController
|
|||
}),
|
||||
heading: I18n.t(
|
||||
"users.settings.organizations.index.leave_uo_heading",
|
||||
org: @user_org.organization.name
|
||||
org: escape_input(@user_org.organization.name)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -201,8 +202,8 @@ class Users::SettingsController < ApplicationController
|
|||
}),
|
||||
heading: I18n.t(
|
||||
"users.settings.organizations.edit.destroy_uo_heading",
|
||||
user: @user_org.user.full_name,
|
||||
org: @user_org.organization.name
|
||||
user: escape_input(@user_org.user.full_name),
|
||||
org: escape_input(@user_org.organization.name)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
class LoadFromRepositoryProtocolsDatatable < AjaxDatatablesRails::Base
|
||||
# Needed for sanitize_sql_like method
|
||||
include ActiveRecord::Sanitization::ClassMethods
|
||||
include InputSanitizeHelper
|
||||
|
||||
def initialize(view, organization, type, user)
|
||||
super(view)
|
||||
|
|
@ -69,13 +70,13 @@ class LoadFromRepositoryProtocolsDatatable < AjaxDatatablesRails::Base
|
|||
def data
|
||||
records.map do |record|
|
||||
{
|
||||
"DT_RowId": record.id,
|
||||
"1": record.name,
|
||||
"2": keywords_html(record),
|
||||
"3": record.nr_of_linked_children,
|
||||
"4": record.full_username_str,
|
||||
"5": timestamp_column_html(record),
|
||||
"6": I18n.l(record.updated_at, format: :full)
|
||||
'DT_RowId': record.id,
|
||||
'1': escape_input(record.name),
|
||||
'2': keywords_html(record),
|
||||
'3': record.nr_of_linked_children,
|
||||
'4': escape_input(record.full_username_str),
|
||||
'5': timestamp_column_html(record),
|
||||
'6': I18n.l(record.updated_at, format: :full)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -140,7 +141,7 @@ class LoadFromRepositoryProtocolsDatatable < AjaxDatatablesRails::Base
|
|||
kws.sort_by{ |word| word.downcase }.each do |kw|
|
||||
res << "<a href='#' data-action='filter' data-param='#{kw}'>#{kw}</a>"
|
||||
end
|
||||
res.join(", ")
|
||||
sanitize_input(res.join(', '))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
class OrganizationUsersDatatable < AjaxDatatablesRails::Base
|
||||
include InputSanitizeHelper
|
||||
|
||||
def_delegator :@view, :link_to
|
||||
def_delegator :@view, :update_user_organization_path
|
||||
def_delegator :@view, :destroy_user_organization_html_path
|
||||
|
|
@ -49,13 +51,13 @@ class OrganizationUsersDatatable < AjaxDatatablesRails::Base
|
|||
def data
|
||||
records.map do |record|
|
||||
{
|
||||
"DT_RowId": record.id,
|
||||
"0": record.user.full_name,
|
||||
"1": record.user.email,
|
||||
"2": I18n.l(record.created_at, format: :full),
|
||||
"3": record.user.active_status_str,
|
||||
"4": record.role_str,
|
||||
"5": ApplicationController.new.render_to_string(
|
||||
'DT_RowId': record.id,
|
||||
'0': escape_input(record.user.full_name),
|
||||
'1': escape_input(record.user.email),
|
||||
'2': I18n.l(record.created_at, format: :full),
|
||||
'3': record.user.active_status_str,
|
||||
'4': record.role_str,
|
||||
'5': ApplicationController.new.render_to_string(
|
||||
partial: "users/settings/organizations/user_dropdown.html.erb",
|
||||
locals: {
|
||||
user_organization: record,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
class ProtocolsDatatable < AjaxDatatablesRails::Base
|
||||
# Needed for sanitize_sql_like method
|
||||
include ActiveRecord::Sanitization::ClassMethods
|
||||
include InputSanitizeHelper
|
||||
|
||||
def_delegator :@view, :can_edit_protocol
|
||||
def_delegator :@view, :edit_protocol_path
|
||||
|
|
@ -83,24 +84,34 @@ class ProtocolsDatatable < AjaxDatatablesRails::Base
|
|||
records.each do |record|
|
||||
protocol = Protocol.find(record.id)
|
||||
result_data << {
|
||||
"DT_RowId": record.id,
|
||||
"DT_CanEdit": can_edit_protocol(protocol),
|
||||
"DT_EditUrl": can_edit_protocol(protocol) ?
|
||||
edit_protocol_path(protocol, organization: @organization, type: @type) : nil,
|
||||
"DT_CanClone": can_clone_protocol(protocol),
|
||||
"DT_CloneUrl": can_clone_protocol(protocol) ?
|
||||
clone_protocol_path(protocol, organization: @organization, type: @type) : nil,
|
||||
"DT_CanMakePrivate": can_make_protocol_private(protocol),
|
||||
"DT_CanPublish": can_publish_protocol(protocol),
|
||||
"DT_CanArchive": can_archive_protocol(protocol),
|
||||
"DT_CanRestore": can_restore_protocol(protocol),
|
||||
"DT_CanExport": can_export_protocol(protocol),
|
||||
"1": protocol.in_repository_archived? ? record.name : name_html(record),
|
||||
"2": keywords_html(record),
|
||||
"3": modules_html(record),
|
||||
"4": record.full_username_str,
|
||||
"5": timestamp_column_html(record),
|
||||
"6": I18n.l(record.updated_at, format: :full)
|
||||
'DT_RowId': record.id,
|
||||
'DT_CanEdit': can_edit_protocol(protocol),
|
||||
'DT_EditUrl': if can_edit_protocol(protocol)
|
||||
edit_protocol_path(protocol,
|
||||
organization: @organization,
|
||||
type: @type)
|
||||
end,
|
||||
'DT_CanClone': can_clone_protocol(protocol),
|
||||
'DT_CloneUrl': if can_clone_protocol(protocol)
|
||||
clone_protocol_path(protocol,
|
||||
organization: @organization,
|
||||
type: @type)
|
||||
end,
|
||||
'DT_CanMakePrivate': can_make_protocol_private(protocol),
|
||||
'DT_CanPublish': can_publish_protocol(protocol),
|
||||
'DT_CanArchive': can_archive_protocol(protocol),
|
||||
'DT_CanRestore': can_restore_protocol(protocol),
|
||||
'DT_CanExport': can_export_protocol(protocol),
|
||||
'1': if protocol.in_repository_archived?
|
||||
escape_input(record.name)
|
||||
else
|
||||
name_html(record)
|
||||
end,
|
||||
'2': keywords_html(record),
|
||||
'3': modules_html(record),
|
||||
'4': escape_input(record.full_username_str),
|
||||
'5': timestamp_column_html(record),
|
||||
'6': I18n.l(record.updated_at, format: :full)
|
||||
}
|
||||
end
|
||||
result_data
|
||||
|
|
@ -168,7 +179,7 @@ class ProtocolsDatatable < AjaxDatatablesRails::Base
|
|||
def name_html(record)
|
||||
"<a href='#' data-action='protocol-preview'" \
|
||||
"data-url='#{preview_protocol_path(record)}'>" \
|
||||
"#{record.name}" \
|
||||
"#{escape_input(record.name)}" \
|
||||
"</a>"
|
||||
end
|
||||
|
||||
|
|
@ -181,7 +192,7 @@ class ProtocolsDatatable < AjaxDatatablesRails::Base
|
|||
kws.sort_by{ |word| word.downcase }.each do |kw|
|
||||
res << "<a href='#' data-action='filter' data-param='#{kw}'>#{kw}</a>"
|
||||
end
|
||||
res.join(", ")
|
||||
sanitize_input(res.join(', '))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ require 'active_record'
|
|||
class SampleDatatable < AjaxDatatablesRails::Base
|
||||
include ActionView::Helpers::TextHelper
|
||||
include SamplesHelper
|
||||
include InputSanitizeHelper
|
||||
|
||||
ASSIGNED_SORT_COL = 'assigned'
|
||||
|
||||
|
|
@ -106,24 +107,32 @@ class SampleDatatable < AjaxDatatablesRails::Base
|
|||
sample = {
|
||||
'DT_RowId': record.id,
|
||||
'1': assigned_cell(record),
|
||||
'2': record.name,
|
||||
'3': record.sample_type.nil? ? I18n.t('samples.table.no_type') : record.sample_type.name,
|
||||
'4': record.sample_group.nil? ?
|
||||
"<span class='glyphicon glyphicon-asterisk'></span> " + I18n.t("samples.table.no_group") :
|
||||
"<span class='glyphicon glyphicon-asterisk' style='color: #{record.sample_group.color}'></span> " + record.sample_group.name,
|
||||
"5": I18n.l(record.created_at, format: :full),
|
||||
"6": record.user.full_name,
|
||||
"sampleInfoUrl": Rails.application.routes.url_helpers.edit_sample_path(record.id),
|
||||
"sampleUpdateUrl": Rails.application.routes.url_helpers.sample_path(record.id)
|
||||
'2': escape_input(record.name),
|
||||
'3': if record.sample_type.nil?
|
||||
I18n.t('samples.table.no_type')
|
||||
else
|
||||
escape_input(record.sample_type.name)
|
||||
end,
|
||||
'4': if record.sample_group.nil?
|
||||
"<span class='glyphicon glyphicon-asterisk'></span> " +
|
||||
I18n.t('samples.table.no_group')
|
||||
else
|
||||
"<span class='glyphicon glyphicon-asterisk' "\
|
||||
"style='color: #{escape_input(record.sample_group.color)}'>"\
|
||||
"</span> " + escape_input(record.sample_group.name)
|
||||
end,
|
||||
'5': I18n.l(record.created_at, format: :full),
|
||||
'6': escape_input(record.user.full_name),
|
||||
'sampleInfoUrl':
|
||||
Rails.application.routes.url_helpers.edit_sample_path(record.id),
|
||||
'sampleUpdateUrl':
|
||||
Rails.application.routes.url_helpers.sample_path(record.id)
|
||||
}
|
||||
|
||||
# Add custom attributes
|
||||
record.sample_custom_fields.each do |scf|
|
||||
sample[@cf_mappings[scf.custom_field_id]] = auto_link(scf.value,
|
||||
link: :urls,
|
||||
html: {
|
||||
target: '_blank'
|
||||
})
|
||||
sample[@cf_mappings[scf.custom_field_id]] =
|
||||
custom_auto_link(scf.value, link: :urls, html: { target: '_blank' })
|
||||
end
|
||||
sample
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ module ActivityHelper
|
|||
title = truncate(activity_title, length: len)
|
||||
end
|
||||
message = message.gsub(/#{activity_title}/, title )
|
||||
message.html_safe if message
|
||||
sanitize_input(message) if message
|
||||
end
|
||||
|
||||
def days_since_1970(dt)
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@ module ApplicationHelper
|
|||
|
||||
def display_tooltip(message, len = Constants::NAME_TRUNCATION_LENGTH)
|
||||
if message.strip.length > Constants::NAME_TRUNCATION_LENGTH
|
||||
"<div class='modal-tooltip'>#{truncate(message.strip, length: len)} \
|
||||
<span class='modal-tooltiptext'>#{message.strip}</span></div>".html_safe
|
||||
sanitize_input("<div class='modal-tooltip'> \
|
||||
#{truncate(message.strip, length: len)} \
|
||||
<span class='modal-tooltiptext'> \
|
||||
#{message.strip}</span></div>")
|
||||
else
|
||||
truncate(message.strip, length: len)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@ module AssetsHelper
|
|||
res = <<-eos
|
||||
<span
|
||||
data-status='asset-loading'
|
||||
data-filename='#{asset.file_file_name}'
|
||||
data-filename='#{escape_input(asset.file_file_name)}'
|
||||
data-type='#{asset.is_image? ? "image" : "asset"}'
|
||||
data-present-url='#{file_present_asset_path(asset, format: :json)}'
|
||||
#{asset.is_image? ? "data-preview-url='" + preview_asset_path(asset) + "'" : ""}'
|
||||
data-download-url='#{download_asset_path(asset)}'
|
||||
>
|
||||
<span class='asset-loading-spinner' id='asset-loading-spinner-#{asset.id}'></span>
|
||||
#{t('general.file.uploading', fileName: asset.file_file_name)}
|
||||
#{t('general.file.uploading', fileName: escape_input(asset.file_file_name))}
|
||||
</span>
|
||||
<script type='text/javascript'>
|
||||
$('#asset-loading-spinner-#{asset.id}').spin(
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ module FormTagHelper
|
|||
res << '</span>'
|
||||
end
|
||||
res << '</div>'
|
||||
res.html_safe
|
||||
sanitize_input(res)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
18
app/helpers/input_sanitize_helper.rb
Normal file
18
app/helpers/input_sanitize_helper.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
module InputSanitizeHelper
|
||||
def sanitize_input(text)
|
||||
ActionController::Base.helpers.sanitize(
|
||||
text,
|
||||
tags: Constants::WHITELISTED_TAGS,
|
||||
attributes: Constants::WHITELISTED_ATTRIBUTES
|
||||
)
|
||||
end
|
||||
|
||||
def escape_input(text)
|
||||
ERB::Util.html_escape(text)
|
||||
end
|
||||
|
||||
def custom_auto_link(text, args)
|
||||
args[:sanitize] = false
|
||||
sanitize_input(auto_link(text, args))
|
||||
end
|
||||
end
|
||||
|
|
@ -9,8 +9,9 @@ module OrganizationsHelper
|
|||
|
||||
def truncate_organization_name(name, len = Constants::NAME_TRUNCATION_LENGTH)
|
||||
if name.length > len
|
||||
"<div class='modal-tooltip'>#{truncate(name, length: len)}
|
||||
<span class='modal-tooltiptext'>#{name}</span></div>".html_safe
|
||||
sanitize_input("<div class='modal-tooltip'>#{truncate(name, length: len)}
|
||||
<span class='modal-tooltiptext'>#{name}</span>
|
||||
</div>")
|
||||
else
|
||||
name
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ module ProtocolStatusHelper
|
|||
|
||||
def protocol_status_href(protocol)
|
||||
parent = protocol.parent
|
||||
res = ""
|
||||
res << "<a href=\"#\" data-toggle=\"popover\" data-html=\"true\" "
|
||||
res << "data-trigger=\"focus\" data-placement=\"bottom\" title=\""
|
||||
res << protocol_status_popover_title(parent) + "\" data-content=\"" + protocol_status_popover_content(parent) + "\">" + protocol_name(parent) + "</a>"
|
||||
res = ''
|
||||
res << '<a href="#" data-toggle="popover" data-html="true" '
|
||||
res << 'data-trigger="focus" data-placement="bottom" title="'
|
||||
res << protocol_status_popover_title(parent) +
|
||||
'" data-content="' + protocol_status_popover_content(parent) +
|
||||
'">' + protocol_name(parent) + '</a>'
|
||||
res.html_safe
|
||||
end
|
||||
|
||||
|
|
@ -16,7 +18,11 @@ module ProtocolStatusHelper
|
|||
end
|
||||
|
||||
def protocol_name(protocol)
|
||||
protocol_private_for_current_user?(protocol) ? I18n.t("my_modules.protocols.protocol_status_bar.private_parent") : protocol.name
|
||||
if protocol_private_for_current_user?(protocol)
|
||||
I18n.t('my_modules.protocols.protocol_status_bar.private_parent')
|
||||
else
|
||||
escape_input(protocol.name)
|
||||
end
|
||||
end
|
||||
|
||||
def protocol_status_popover_title(protocol)
|
||||
|
|
@ -34,7 +40,11 @@ module ProtocolStatusHelper
|
|||
end
|
||||
res << " - "
|
||||
res << "<span style='font-style: italic;'>" + I18n.t("my_modules.protocols.protocol_status_bar.added_by") + " "
|
||||
res << "<a href='#' data-toggle='tooltip' data-placement='right' title='" + I18n.t("my_modules.protocols.protocol_status_bar.added_by_tooltip", ts: I18n.l(protocol.created_at, format: :full)) + "'>" + protocol.added_by.full_name + "</a></span>"
|
||||
res << "<a href='#' data-toggle='tooltip' data-placement='right' title='" +
|
||||
I18n.t('my_modules.protocols.protocol_status_bar.added_by_tooltip',
|
||||
ts: I18n.l(protocol.created_at, format: :full)) + "'>" +
|
||||
escape_input(protocol.added_by.full_name) + '</a></span>'
|
||||
res
|
||||
end
|
||||
|
||||
def protocol_status_popover_content(protocol)
|
||||
|
|
@ -59,6 +69,6 @@ module ProtocolStatusHelper
|
|||
end
|
||||
res << "</p>"
|
||||
end
|
||||
res
|
||||
sanitize_input(res)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ def render_new_element(hide)
|
|||
end
|
||||
|
||||
def render_report_element(element, provided_locals = nil)
|
||||
children_html = "".html_safe
|
||||
children_html = ''
|
||||
|
||||
# First, recursively render element's children
|
||||
if element.comments? or element.project_header?
|
||||
if element.comments? || element.project_header?
|
||||
# Render no children
|
||||
elsif element.result?
|
||||
# Special handling for result comments
|
||||
|
|
|
|||
|
|
@ -53,5 +53,4 @@ class Checklist < ActiveRecord::Base
|
|||
.offset((page - 1) * Constants::SEARCH_LIMIT)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -100,5 +100,4 @@ class Comment < ActiveRecord::Base
|
|||
errors.add(:base, "Comment can only belong to 1 'parent' object.")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ class Result < ActiveRecord::Base
|
|||
end
|
||||
|
||||
private
|
||||
|
||||
def text_or_asset_or_table
|
||||
num_of_assigns = 0
|
||||
num_of_assigns += result_text.blank? ? 0 : 1
|
||||
|
|
|
|||
|
|
@ -69,5 +69,4 @@ class Sample < ActiveRecord::Base
|
|||
.offset((page - 1) * Constants::SEARCH_LIMIT)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("experiments.canvas.head_title", project: @project.name))) %>
|
||||
<% provide(:head_title, t("experiments.canvas.head_title", project: h(@project.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("experiments.module_archive.head_title", experiment: @experiment.name))) %>
|
||||
<% provide(:head_title, t("experiments.module_archive.head_title", experiment: h(@experiment.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("projects.samples.head_title", project: @experiment.name))) %>
|
||||
<% provide(:head_title, t("projects.samples.head_title", project: h(@experiment.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
<div class="container">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<span class="glyphicon glyphicon-ok-sign"></span>
|
||||
<span><%= flash[:success].html_safe %></span>
|
||||
<span><%= sanitize_input(flash[:success]) %></span>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
<div class="container">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<span class="glyphicon glyphicon-exclamation-sign"></span>
|
||||
<span><%= alert || flash[:error].html_safe %></span>
|
||||
<span><%= alert || sanitize_input(flash[:error]) %></span>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@
|
|||
</div>
|
||||
<strong><%= comment.user.full_name %>:</strong>
|
||||
<div data-role="comment-message-container">
|
||||
<div data-role="comment-message"><%= auto_link(simple_format(comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %></div>
|
||||
<div data-role="comment-message">
|
||||
<%= custom_auto_link(simple_format(comment.message),
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<% if @my_module.description.blank? %>
|
||||
<em><%=t "experiments.canvas.popups.no_description" %></em>
|
||||
<% else %>
|
||||
<%= auto_link(simple_format(@my_module.description),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %>
|
||||
<%= custom_auto_link(simple_format(@my_module.description),
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
<a class="result-panel-collapse-link" href="#result-panel-<%= result.id %>" data-toggle="collapse" data-remote="true">
|
||||
<span class="glyphicon glyphicon-collapse-down collapse-result-icon"></span>
|
||||
<strong><%= result.name %></strong> |
|
||||
<span><%= raw t'my_modules.results.published_on', timestamp: l(result.created_at, format: :full), user: result.user.full_name %></span>
|
||||
<span><%= t('my_modules.results.published_on', timestamp: l(result.created_at, format: :full), user: h(result.user.full_name)).html_safe %></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="panel-collapse collapse" id="result-panel-<%= result.id %>" role="tabpanel">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("my_modules.activities.head_title", project: @my_module.experiment.project.name, module: @my_module.name))) %>
|
||||
<% provide(:head_title, t("my_modules.activities.head_title", project: h(@my_module.experiment.project.name), module: h(@my_module.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
|
|
@ -23,4 +23,3 @@
|
|||
</div>
|
||||
|
||||
<%= javascript_include_tag("my_modules/activities") %>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
<span class="activity-item-date">
|
||||
<%= l activity.created_at, format: :full %>
|
||||
</span>
|
||||
<span class="activity-item-text"><%= activity.message.html_safe %>
|
||||
<span class="activity-item-text"><%= sanitize_input(activity.message) %>
|
||||
</span>
|
||||
</li>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("my_modules.module_archive.head_title", project: @my_module.experiment.project.name, module: @my_module.name))) %>
|
||||
<% provide(:head_title, t("my_modules.module_archive.head_title", project: h(@my_module.experiment.project.name), module: h(@my_module.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("my_modules.protocols.head_title", project: @project.name, module: @my_module.name))) %>
|
||||
<% provide(:head_title, t("my_modules.protocols.head_title", project: h(@project.name), module: h(@my_module.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("my_modules.results.head_title", project: @project.name, module: @my_module.name))) %>
|
||||
<% provide(:head_title, t("my_modules.results.head_title", project: h(@project.name), module: h(@my_module.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
<% provide(:head_title, raw(t("my_modules.samples.head_title", project: @project.name, module: @my_module.name))) %>
|
||||
<% provide(:head_title, t("my_modules.samples.head_title", project: h(@project.name), module: h(@my_module.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
<div id="content">
|
||||
<%= render partial: "shared/samples" %>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@
|
|||
</div>
|
||||
<strong><%= comment.user.full_name %>:</strong>
|
||||
<div data-role="comment-message-container">
|
||||
<div data-role="comment-message"><%= auto_link(simple_format(comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %></div>
|
||||
<div data-role="comment-message">
|
||||
<%= custom_auto_link(simple_format(comment.message),
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("projects.experiment_archive.head_title", project: @project.name))) %>
|
||||
<% provide(:head_title, t("projects.experiment_archive.head_title", project: h(@project.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
<% provide(:head_title, raw(t("projects.samples.head_title", project: @project.name))) %>
|
||||
<% provide(:head_title, t("projects.samples.head_title", project: h(@project.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
<div id="content">
|
||||
<%= render partial: "shared/samples" %>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("projects.show.head_title", project: @project.name))) %>
|
||||
<% provide(:head_title, t("projects.show.head_title", project: h(@project.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
|
|
|
|||
|
|
@ -49,9 +49,8 @@
|
|||
</span>
|
||||
<% if experiment.description? %>
|
||||
<div class='experiment-description'>
|
||||
<%= auto_link(simple_format(experiment.description),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %>
|
||||
<%= custom_auto_link(simple_format(experiment.description),
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
</div>
|
||||
<% else %>
|
||||
<span class='experiment-no-description'>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<% if @protocol.protocol_keywords.count > 0 %>
|
||||
<%= @protocol.protocol_keywords.collect{ |kw| "<strong>#{sanitize(kw.name)}</strong>" }.join(", ").html_safe %>
|
||||
<%= @protocol.protocol_keywords.collect{ |kw| "<strong>#{h(kw.name)}</strong>" }.join(", ").html_safe %>
|
||||
<% else %>
|
||||
<em><%= t("protocols.no_keywords") %></em>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong><%= step.name %></strong> |
|
||||
<span><%= raw t("protocols.steps.published_on", timestamp: l(step.created_at, format: :full), user: step.user.full_name) %></span>
|
||||
<span><%= t("protocols.steps.published_on", timestamp: l(step.created_at, format: :full), user: h(step.user.full_name)).html_safe %></span>
|
||||
</div>
|
||||
<div class="panel-collapse collapse in" id="step-panel-<%= step.id %>" role="tabpanel" aria-expanded="true">
|
||||
<div class="panel-body">
|
||||
|
|
@ -85,7 +85,7 @@
|
|||
<em><%= t("protocols.steps.no_description") %></em>
|
||||
<% else %>
|
||||
<div class="ql-editor">
|
||||
<%= step.description.html_safe %>
|
||||
<%= sanitize_input(step.description) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
<li>
|
||||
<span class="label label-success"><%= t("protocols.index.#{en_action}.row_success") %></span>
|
||||
<% if en_action == "restore_results" %>
|
||||
<%= t("protocols.index.restore_results.row_#{r[:type]}", protocol: r[:name]).html_safe %>
|
||||
<%= t("protocols.index.restore_results.row_#{r[:type]}", protocol: h(r[:name])).html_safe %>
|
||||
<% else %>
|
||||
<%= r[:name] %>
|
||||
<% end %>
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
<% renamed.each do |r| %>
|
||||
<li>
|
||||
<span class="label label-warning"><%= t("protocols.index.#{en_action}.row_renamed") %></span>
|
||||
<% protocol_str = t("protocols.index.row_renamed_html", old_name: r[:name], new_name: r[:new_name]) %>
|
||||
<% protocol_str = t("protocols.index.row_renamed_html", old_name: h(r[:name]), new_name: h(r[:new_name])) %>
|
||||
<% if en_action == "restore_results" %>
|
||||
<%= t("protocols.index.restore_results.row_#{r[:type]}", protocol: protocol_str).html_safe %>
|
||||
<% else %>
|
||||
|
|
@ -52,4 +52,4 @@
|
|||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -27,9 +27,8 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<% if experiment.description.present? %>
|
||||
<%= auto_link(simple_format(experiment.description),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %>
|
||||
<%= custom_auto_link(simple_format(experiment.description),
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
<% else %>
|
||||
<em><%=t "projects.reports.elements.experiment.no_description" %></em>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
</span>
|
||||
<span class="activity-message">
|
||||
|
||||
<%= activity.message.html_safe %>
|
||||
<%= sanitize_input(activity.message) %>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -30,9 +30,8 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<% if my_module.description.present? %>
|
||||
<%= auto_link(simple_format(my_module.description),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %>
|
||||
<%= custom_auto_link(simple_format(my_module.description),
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
<% else %>
|
||||
<em><%=t "projects.reports.elements.module.no_description" %></em>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@
|
|||
</span>
|
||||
<span class="comment-message">
|
||||
|
||||
<%= auto_link(simple_format(comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %>
|
||||
<%= custom_auto_link(simple_format(comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -23,9 +23,8 @@
|
|||
<div class="report-element-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 text-container ql-editor">
|
||||
<%= auto_link(result_text.text,
|
||||
link: :urls,
|
||||
html: { target: '_blank' }).html_safe %>
|
||||
<%= custom_auto_link(result_text.text,
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -24,10 +24,9 @@
|
|||
<li>
|
||||
<input type="checkbox" disabled="disabled" <%= "checked='checked'" if item.checked %>/>
|
||||
<span class="<%= 'checked' if item.checked %>">
|
||||
<%= auto_link(simple_format(item.text),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %></span>
|
||||
|
||||
<%= custom_auto_link(simple_format(item.text),
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@
|
|||
</span>
|
||||
<span class="comment-message">
|
||||
|
||||
<%= auto_link(simple_format(comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %>
|
||||
<%= custom_auto_link(simple_format(comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -27,9 +27,8 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12 ql-editor">
|
||||
<% if strip_tags(step.description).present? %>
|
||||
<%= auto_link(step.description,
|
||||
link: :urls,
|
||||
html: { target: '_blank' }).html_safe %>
|
||||
<%= custom_auto_link(step.description,
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
<% else %>
|
||||
<em><%=t "projects.reports.elements.step.no_description" %></em>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("projects.reports.index.head_title", project: @project.name))) %>
|
||||
<% provide(:head_title, t("projects.reports.index.head_title", project: h(@project.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar" %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("projects.reports.new.head_title", project: @project.name))) %>
|
||||
<% provide(:head_title, t("projects.reports.new.head_title", project: h(@project.name)).html_safe) %>
|
||||
<% provide(:body_class, "report-body") %>
|
||||
<% provide(:sidebar_wrapper_class, "report-sidebar-wrapper") %>
|
||||
<% provide(:container_class, "report-container") %>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</head>
|
||||
<body class="print-report-body">
|
||||
<div class="print-report">
|
||||
<%= @html.html_safe %>
|
||||
<%= sanitize_input(@html) %>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@
|
|||
<% end %>
|
||||
</div>
|
||||
<div data-role="comment-message-container">
|
||||
<div data-role="comment-message"><%= auto_link(simple_format(comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %></div>
|
||||
<div data-role="comment-message">
|
||||
<%= custom_auto_link(simple_format(comment.message),
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<div class="ql-editor">
|
||||
<%= auto_link(result.result_text.text,
|
||||
link: :urls,
|
||||
html: { target: '_blank' }).html_safe %>
|
||||
<%= custom_auto_link(result.result_text.text,
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<!-- Display asset contents if it exists -->
|
||||
<% if asset.headline.present? && !asset.headline.empty? && asset.headline.include?("<mark>") %>
|
||||
<blockquote class="blockquote-search">
|
||||
<p><%= raw asset.headline %></p>
|
||||
<p><%= sanitize_input(asset.headline) %></p>
|
||||
</blockquote>
|
||||
<% end %>
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<% if result.is_text && result.result_text.text.present? && !result.result_text.text.empty? %>
|
||||
<blockquote class="search-asset-text-data">
|
||||
<p>
|
||||
<%= highlight(result.result_text.text.html_safe, search_query.strip.split(/\s+/)) %>
|
||||
<%= highlight(sanitize_input(result.result_text.text), search_query.strip.split(/\s+/)) %>
|
||||
</p>
|
||||
</blockquote>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@
|
|||
<% end %>
|
||||
</div>
|
||||
<div data-role="comment-message-container">
|
||||
<div data-role="comment-message"><%= auto_link(simple_format(comment.message),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %></div>
|
||||
<div data-role="comment-message">
|
||||
<%= custom_auto_link(simple_format(comment.message),
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
<a class="step-panel-collapse-link" href="#step-panel-<%= step.id %>" data-toggle="collapse" data-remote="true">
|
||||
<span class="glyphicon glyphicon-collapse-down collapse-step-icon"></span>
|
||||
<strong><%= step.name %></strong> |
|
||||
<span><%= raw t("protocols.steps.published_on", timestamp: l(step.created_at, format: :full), user: step.user.full_name) %></span>
|
||||
<span><%= sanitize_input t("protocols.steps.published_on", timestamp: l(step.created_at, format: :full), user: h(step.user.full_name)) %></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="panel-collapse collapse" id="step-panel-<%= step.id %>" role="tabpanel">
|
||||
|
|
@ -37,9 +37,8 @@
|
|||
<em><%= t("protocols.steps.no_description") %></em>
|
||||
<% else %>
|
||||
<div class="ql-editor">
|
||||
<%= auto_link(step.description,
|
||||
link: :urls,
|
||||
html: { target: '_blank' }).html_safe %>
|
||||
<%= custom_auto_link(step.description,
|
||||
link: :urls, html: { target: '_blank' }) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
@ -89,9 +88,11 @@
|
|||
<% unless step.checklists.blank? then %>
|
||||
<div class="col-xs-12">
|
||||
<% step.checklists.each do |checklist| %>
|
||||
<strong><%= auto_link(simple_format(checklist.name),
|
||||
<strong>
|
||||
<%= custom_auto_link(simple_format(checklist.name),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %></strong>
|
||||
html: { target: '_blank' }) %>
|
||||
</strong>
|
||||
<% if checklist.checklist_items.empty? %>
|
||||
</br>
|
||||
<%= t("protocols.steps.empty_checklist") %>
|
||||
|
|
@ -105,9 +106,9 @@
|
|||
<% else %>
|
||||
<input type="checkbox" value="" disabled="disabled" />
|
||||
<% end %>
|
||||
<%= auto_link(simple_format(checklist_item.text),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %>
|
||||
<%= custom_auto_link(simple_format(checklist_item.text),
|
||||
link: :urls,
|
||||
html: { target: '_blank' }) %>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
<% end %>
|
||||
</div>
|
||||
<div class="col-xs-9 col-md-11">
|
||||
<strong><%= notification.title.html_safe %></strong> <br>
|
||||
<%= l(notification.created_at, format: :full) %> | <%= notification.message.html_safe %>
|
||||
<strong><%= sanitize_input(notification.title) %></strong> <br>
|
||||
<%= l(notification.created_at, format: :full) %> | <%= sanitize_input(notification.message) %>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@
|
|||
</div>
|
||||
|
||||
<div class="col-xs-10">
|
||||
<strong><%= notification.title.html_safe %></strong> <br>
|
||||
<%= l(notification.created_at, format: :full) %> | <%= notification.message.html_safe %>
|
||||
<strong><%= sanitize_input(notification.title) %></strong> <br>
|
||||
<%= l(notification.created_at, format: :full) %> | <%= sanitize_input(notification.message) %>
|
||||
</div>
|
||||
</div>
|
||||
<li>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% provide(:head_title, raw(t("notifications.title"))) %>
|
||||
<% provide(:head_title, sanitize_input(t("notifications.title"))) %>
|
||||
<div class="notifications-container">
|
||||
<div class="notifications-header">
|
||||
<span><%= t('notifications.title') %></span><span class="pull-right"><%= link_to t('nav.user.settings'), preferences_path %></span>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@
|
|||
|
||||
<p>Type: <%= I18n.t("notifications.types.#{@notification.type_of}") %></p>
|
||||
|
||||
<p><%= prepend_server_url_to_links(@notification.title.html_safe).html_safe %></p>
|
||||
<p><%= sanitize_input(prepend_server_url_to_links(@notification.title)) %></p>
|
||||
|
||||
<p><%= prepend_server_url_to_links(@notification.message).html_safe %></p>
|
||||
<p><%= sanitize_input(prepend_server_url_to_links(@notification.message)) %></p>
|
||||
|
|
|
|||
|
|
@ -11,4 +11,4 @@
|
|||
<li><%= t("users.settings.organizations.index.leave_uo_alert_line_3")%></li>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -207,6 +207,15 @@ class Constants
|
|||
'gif', 'jpeg', 'pjpeg', 'png', 'x-png', 'svg+xml', 'bmp'
|
||||
].freeze
|
||||
|
||||
WHITELISTED_TAGS = %w(
|
||||
a b strong i em li ul ol h1 del ins h2 h3 h4 h5 h6 br sub sup p code hr div
|
||||
span u s blockquote pre
|
||||
).freeze
|
||||
|
||||
WHITELISTED_ATTRIBUTES = %w(
|
||||
href src width height alt cite datetime title class name xml:lang abbr style
|
||||
).freeze
|
||||
|
||||
# Very basic regex to check for validity of emails
|
||||
BASIC_EMAIL_REGEX = URI::MailTo::EMAIL_REGEXP
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue