From 96f88cf46bc373d5a91999619d916df8e962faee Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 31 Oct 2018 16:49:03 +0530 Subject: [PATCH 01/64] fix(filters): dont validate email in filters --- frappe/public/js/frappe/form/controls/data.js | 3 +++ frappe/public/js/frappe/ui/filters/filter.js | 4 +++- frappe/templates/includes/list/filters.js | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/data.js b/frappe/public/js/frappe/form/controls/data.js index aa78f2df8e..2e83e3b612 100644 --- a/frappe/public/js/frappe/form/controls/data.js +++ b/frappe/public/js/frappe/form/controls/data.js @@ -85,6 +85,9 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({ return val==null ? "" : val; }, validate: function(v) { + if(this.df.is_filter) { + return v; + } if(this.df.options == 'Phone') { if(v+''=='') { return ''; diff --git a/frappe/public/js/frappe/ui/filters/filter.js b/frappe/public/js/frappe/ui/filters/filter.js index 21fc8de216..1cbbc5fc2d 100644 --- a/frappe/public/js/frappe/ui/filters/filter.js +++ b/frappe/public/js/frappe/ui/filters/filter.js @@ -162,7 +162,9 @@ frappe.ui.Filter = class { let df = copy_dict(original_docfield); // filter field shouldn't be read only or hidden - df.read_only = 0; df.hidden = 0; + df.read_only = 0; + df.hidden = 0; + df.is_filter = true; let c = condition ? condition : this.utils.get_default_condition(df); this.set_condition(c); diff --git a/frappe/templates/includes/list/filters.js b/frappe/templates/includes/list/filters.js index c5a1109ab1..755077dd32 100644 --- a/frappe/templates/includes/list/filters.js +++ b/frappe/templates/includes/list/filters.js @@ -20,6 +20,7 @@ function setup_list_filters() { fieldtype: df.fieldtype, label: df.label, options: df.options, + is_filter: true, change: (e) => { const query_params = Object.assign(frappe.utils.get_query_params(), { [df.fieldname]: f.get_value() From e0cf3f367b9334951f32744698768d5c51a5dcd0 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Thu, 1 Nov 2018 19:06:30 +0530 Subject: [PATCH 02/64] fix(Quill): Add data-row attr to whitelist - data-row attribute is added by Quill for retaining table structure --- frappe/utils/html_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/utils/html_utils.py b/frappe/utils/html_utils.py index f788004be4..fe06ec7c43 100644 --- a/frappe/utils/html_utils.py +++ b/frappe/utils/html_utils.py @@ -158,7 +158,7 @@ acceptable_attributes = [ 'step', 'style', 'summary', 'suppress', 'tabindex', 'target', 'template', 'title', 'toppadding', 'type', 'unselectable', 'usemap', 'urn', 'valign', 'value', 'variable', 'volume', 'vspace', 'vrml', - 'width', 'wrap', 'xml:lang' + 'width', 'wrap', 'xml:lang', 'data-row' ] mathml_attributes = [ From 10c2e8f262eafb8caa260f70d783910a9bf46f25 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Thu, 1 Nov 2018 19:38:07 +0530 Subject: [PATCH 03/64] fix: Only allow images in Attach Image --- .../web_form/edit_profile/edit_profile.json | 41 ++++++++++++++----- .../js/frappe/form/controls/attach_image.js | 4 ++ frappe/public/js/frappe/upload.js | 5 +++ .../web_form_field/web_form_field.json | 8 ++-- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/frappe/core/web_form/edit_profile/edit_profile.json b/frappe/core/web_form/edit_profile/edit_profile.json index 02b0e0363f..1752284845 100644 --- a/frappe/core/web_form/edit_profile/edit_profile.json +++ b/frappe/core/web_form/edit_profile/edit_profile.json @@ -18,13 +18,14 @@ "is_standard": 1, "login_required": 1, "max_attachment_size": 0, - "modified": "2018-06-12 22:24:21.913166", + "modified": "2018-11-01 19:35:43.552429", "modified_by": "Administrator", "module": "Core", "name": "edit-profile", "owner": "Administrator", "published": 1, "route": "update-profile", + "show_in_grid": 0, "show_sidebar": 1, "sidebar_items": [], "success_message": "Profile updated successfully.", @@ -32,6 +33,7 @@ "title": "Update Profile", "web_form_fields": [ { + "allow_read_on_all_link_options": 0, "fieldname": "first_name", "fieldtype": "Data", "hidden": 0, @@ -39,9 +41,11 @@ "max_length": 0, "max_value": 0, "read_only": 0, - "reqd": 1 + "reqd": 1, + "show_in_filter": 0 }, { + "allow_read_on_all_link_options": 0, "fieldname": "middle_name", "fieldtype": "Data", "hidden": 0, @@ -49,9 +53,11 @@ "max_length": 0, "max_value": 0, "read_only": 0, - "reqd": 0 + "reqd": 0, + "show_in_filter": 0 }, { + "allow_read_on_all_link_options": 0, "fieldname": "last_name", "fieldtype": "Data", "hidden": 0, @@ -59,29 +65,35 @@ "max_length": 0, "max_value": 0, "read_only": 0, - "reqd": 0 + "reqd": 0, + "show_in_filter": 0 }, { + "allow_read_on_all_link_options": 0, "description": "", "fieldname": "user_image", - "fieldtype": "Attach", + "fieldtype": "Attach Image", "hidden": 0, "label": "User Image", "max_length": 0, "max_value": 0, "read_only": 0, - "reqd": 0 + "reqd": 0, + "show_in_filter": 0 }, { + "allow_read_on_all_link_options": 0, "fieldtype": "Section Break", "hidden": 0, "label": "More Information", "max_length": 0, "max_value": 0, "read_only": 0, - "reqd": 0 + "reqd": 0, + "show_in_filter": 0 }, { + "allow_read_on_all_link_options": 0, "fieldname": "phone", "fieldtype": "Data", "hidden": 0, @@ -89,9 +101,11 @@ "max_length": 0, "max_value": 0, "read_only": 0, - "reqd": 0 + "reqd": 0, + "show_in_filter": 0 }, { + "allow_read_on_all_link_options": 0, "fieldname": "mobile_no", "fieldtype": "Data", "hidden": 0, @@ -99,9 +113,11 @@ "max_length": 0, "max_value": 0, "read_only": 0, - "reqd": 0 + "reqd": 0, + "show_in_filter": 0 }, { + "allow_read_on_all_link_options": 0, "description": "", "fieldname": "language", "fieldtype": "Link", @@ -111,9 +127,11 @@ "max_value": 0, "options": "Language", "read_only": 0, - "reqd": 0 + "reqd": 0, + "show_in_filter": 0 }, { + "allow_read_on_all_link_options": 0, "fieldname": "roles", "fieldtype": "Table", "hidden": 0, @@ -122,7 +140,8 @@ "max_value": 0, "options": "Has Role", "read_only": 0, - "reqd": 0 + "reqd": 0, + "show_in_filter": 0 } ] } \ No newline at end of file diff --git a/frappe/public/js/frappe/form/controls/attach_image.js b/frappe/public/js/frappe/form/controls/attach_image.js index cf332d3d2a..4691064d8f 100644 --- a/frappe/public/js/frappe/form/controls/attach_image.js +++ b/frappe/public/js/frappe/form/controls/attach_image.js @@ -62,5 +62,9 @@ frappe.ui.form.ControlAttachImage = frappe.ui.form.ControlAttach.extend({ this.img_container.toggle(false); this.remove_image_link.toggle(false); } + }, + set_upload_options() { + this._super(); + this.upload_options.restrict_to_images = true; } }); diff --git a/frappe/public/js/frappe/upload.js b/frappe/public/js/frappe/upload.js index bdc8b41316..ec4394c718 100644 --- a/frappe/public/js/frappe/upload.js +++ b/frappe/public/js/frappe/upload.js @@ -41,6 +41,11 @@ frappe.upload = { $upload.find(".btn-browse").on("click", function() { $file_input.click(); }); + // restrict to images + if (opts.restrict_to_images) { + $file_input.prop('accept', 'image/*'); + } + // dropzone upload const $dropzone = $('
'); new frappe.ui.DropZone($dropzone, { diff --git a/frappe/website/doctype/web_form_field/web_form_field.json b/frappe/website/doctype/web_form_field/web_form_field.json index 00a0afda33..6f4dd2f03c 100644 --- a/frappe/website/doctype/web_form_field/web_form_field.json +++ b/frappe/website/doctype/web_form_field/web_form_field.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, @@ -61,7 +62,7 @@ "label": "Fieldtype", "length": 0, "no_copy": 0, - "options": "Attach\nCheck\nData\nDate\nDatetime\nFloat\nHTML\nInt\nLink\nSelect\nSmall Text\nText\nText Editor\nTable\nSection Break\nColumn Break\nPage Break", + "options": "Attach\nAttach Image\nCheck\nData\nDate\nDatetime\nFloat\nHTML\nInt\nLink\nSelect\nSmall Text\nText\nText Editor\nTable\nSection Break\nColumn Break\nPage Break", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, @@ -554,7 +555,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-09-20 10:01:13.346598", + "modified": "2018-11-01 19:35:17.742547", "modified_by": "Administrator", "module": "Website", "name": "Web Form Field", @@ -568,5 +569,6 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 0, - "track_seen": 0 + "track_seen": 0, + "track_views": 0 } \ No newline at end of file From 0aee7afb876d2d79ed04154536ff1da58e6cf5fc Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 2 Nov 2018 12:19:25 +0530 Subject: [PATCH 04/64] Fix permission error while import (#6385) Custom permission should apply while import or else import of doctype with custom roles fails --- frappe/model/meta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/model/meta.py b/frappe/model/meta.py index 6b9654c1f4..b502c5665f 100644 --- a/frappe/model/meta.py +++ b/frappe/model/meta.py @@ -320,7 +320,7 @@ class Meta(Document): def set_custom_permissions(self): '''Reset `permissions` with Custom DocPerm if exists''' - if frappe.flags.in_patch or frappe.flags.in_import or frappe.flags.in_install: + if frappe.flags.in_patch or frappe.flags.in_install: return if not self.istable and self.name not in ('DocType', 'DocField', 'DocPerm', From 731d12238eec11209c2d82f8497ecd9631c366f9 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 2 Nov 2018 15:18:47 +0530 Subject: [PATCH 05/64] Bredcrumb issue in the file --- frappe/core/doctype/file/file.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index d5e76fca01..86530e166d 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -38,9 +38,10 @@ class File(NestedSet): self.set_folder_name() def get_name_based_on_parent_folder(self): - path = get_breadcrumbs(self.folder) - folder_name = frappe.get_value("File", self.folder, "file_name") - return "/".join([d.file_name for d in path] + [folder_name, self.file_name]) + if self.folder: + path = get_breadcrumbs(self.folder) + folder_name = frappe.get_value("File", self.folder, "file_name") + return "/".join([d.file_name for d in path] + [folder_name, self.file_name]) def autoname(self): """Set name for folder""" From 6bbb84f9c3fa7f6bb3c8de1cbf2242e82e637e8c Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sat, 3 Nov 2018 11:52:09 +0530 Subject: [PATCH 06/64] XSS fixes (#6386) * fix(XSS): Sanitise page name before routing * fix(XSS): Sanitise tag value before saving it --- frappe/public/js/frappe/router.js | 3 ++- frappe/public/js/frappe/ui/tags.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index dbf48ee2e3..4f6b47fb32 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -48,7 +48,8 @@ frappe.route = function() { frappe.view_factory[route[0]].show(); } else { // show page - frappe.views.pageview.show(route[0]); + const route_name = frappe.utils.xss_sanitise(route[0]); + frappe.views.pageview.show(route_name); } diff --git a/frappe/public/js/frappe/ui/tags.js b/frappe/public/js/frappe/ui/tags.js index b3ae539809..c68f33a869 100644 --- a/frappe/public/js/frappe/ui/tags.js +++ b/frappe/public/js/frappe/ui/tags.js @@ -36,7 +36,8 @@ frappe.ui.Tags = class { bind() { this.$input.keypress((e) => { if(e.which == 13 || e.keyCode == 13) { - this.addTag(this.$input.val()); + const tagValue = frappe.utils.xss_sanitise(this.$input.val()); + this.addTag(tagValue); this.$input.val(''); } }); From 15d3f4660ebf91e54aff15cbf7611ab0e603ebc0 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 5 Nov 2018 10:07:16 +0530 Subject: [PATCH 07/64] fix(security): pop ignore_permissions arg from whitelisted method --- frappe/model/db_query.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index 1d241db443..f2da6e0b31 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -619,6 +619,7 @@ def get_order_by(doctype, meta): def get_list(doctype, *args, **kwargs): '''wrapper for DatabaseQuery''' kwargs.pop('cmd', None) + kwargs.pop('ignore_permissions', None) return DatabaseQuery(doctype).execute(None, *args, **kwargs) def is_parent_only_filter(doctype, filters): From 2ead22209004bb1882bd0cd3f67993dcea7192ca Mon Sep 17 00:00:00 2001 From: Ameya Shenoy Date: Mon, 5 Nov 2018 10:49:18 +0530 Subject: [PATCH 08/64] fix(email): Email status changes to Read (#6396) The email recieved template was in unsubscribe email. Hence it didn't used to function in case the emails were sent from DocTypes like Issue, wherein the unsubscribe email template is not used. Moved it to email_footer template. Signed-off-by: Ameya Shenoy --- frappe/email/queue.py | 5 +---- frappe/public/js/frappe/form/footer/timeline_item.html | 2 +- frappe/templates/emails/email_footer.html | 6 +++++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/frappe/email/queue.py b/frappe/email/queue.py index 9fbf01eb60..c06a7fb79b 100755 --- a/frappe/email/queue.py +++ b/frappe/email/queue.py @@ -276,10 +276,7 @@ def get_unsubscribe_message(unsubscribe_message, expose_recipients): target="_blank">{0}'''.format(_('Unsubscribe')) unsubscribe_html = _("{0} to stop receiving emails of this type").format(unsubscribe_link) - html = """ -