From 52f3a5ecc4fea63609ba105f6b504eebf5e52377 Mon Sep 17 00:00:00 2001 From: Ward Marissen Date: Tue, 6 Feb 2018 13:25:04 +0100 Subject: [PATCH 1/3] [CLA] signature for Ward Marissen Closes #22841 --- doc/cla/individual/wardm95.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 doc/cla/individual/wardm95.md diff --git a/doc/cla/individual/wardm95.md b/doc/cla/individual/wardm95.md new file mode 100644 index 00000000000..46396fd4e05 --- /dev/null +++ b/doc/cla/individual/wardm95.md @@ -0,0 +1,11 @@ +Belgium, 06/02/2018 + +I hereby agree to the terms of the Odoo Individual Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Ward Marissen ward.marissen@gmail.com https://github.com/wardm95 From bcc088c348abb15d8daae18d6431e5367869fb47 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Thu, 8 Feb 2018 15:48:50 +0100 Subject: [PATCH 2/3] [FIX] web, web_editor: Better email validation with regex (JS) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit improves link creation in web editor. Before this commit, anything with a @​ would be considered as valid email which is obviously not the case. It would then be prefixed by 'mailto:'. This was causing 2 issues: - URL with @​ symbol in it would have 'mailto:' added as prefix, like google maps coordinates. eg: mailto:http://www.google.com/maps/whatever/@​312211.22,321321 - Incorrect emails would go through (eg: @​@​@​, ko@​k@​k@​, mail@​mail) Now, we will try to detect and identify valid emails from invalid emails from URLs. It will also handle 'mailto:' directly typed in the input. This commit comes with it's counterpart in enterprise https://github.com/odoo/enterprise/pull/1859 This closes #11984, closes #22936 Note that there is a WIP in master to use this new is_email function everywhere we try to validate emails. It will aim to uniformize email validation in odoo's javascript that are often performed with different mean here and there, some more permissive than others, some only checking for @​. --- addons/web/static/src/js/framework/utils.js | 11 +++++++++++ addons/web_editor/static/src/js/widgets.js | 13 ++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/framework/utils.js b/addons/web/static/src/js/framework/utils.js index 3e9bd87f8de..cfb9d16af22 100644 --- a/addons/web/static/src/js/framework/utils.js +++ b/addons/web/static/src/js/framework/utils.js @@ -418,6 +418,16 @@ function swap(array, elem1, elem2) { array[i1] = elem2; } +function is_email(value, allow_mailto) { + // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript + var re; + if (allow_mailto) { + re = /^(mailto:)?(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; + } else { + re = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; + } + return re.test(value); +} return { divmod: divmod, @@ -445,6 +455,7 @@ return { xor: xor, DropMisordered: DropMisordered, swap: swap, + is_email: is_email, }; }); diff --git a/addons/web_editor/static/src/js/widgets.js b/addons/web_editor/static/src/js/widgets.js index bf72f25bc74..f23e196997a 100644 --- a/addons/web_editor/static/src/js/widgets.js +++ b/addons/web_editor/static/src/js/widgets.js @@ -4,6 +4,7 @@ odoo.define('web_editor.widget', function (require) { var core = require('web.core'); var ajax = require('web.ajax'); var Widget = require('web.Widget'); +var utils = require('web.utils'); var base = require('web_editor.base'); var rte = require('web_editor.rte'); @@ -1050,6 +1051,7 @@ var LinkDialog = Dialog.extend({ if (!$e.length) { $e = this.$('input.url-source:first'); } + $e.closest('.form-group').removeClass('has-error'); var val = $e.val(); var label = this.$('#link-text').val() || val; @@ -1070,8 +1072,7 @@ var LinkDialog = Dialog.extend({ var size = this.$("input[name='link-style-size']:checked").val() || ''; var classes = (this.data.className || "") + (style && style.length ? " btn " : "") + style + " " + size; var isNewWindow = this.$('input.window-new').prop('checked'); - - if ($e.hasClass('email-address') && $e.val().indexOf("@") !== -1) { + if ($e.hasClass('email-address') && (_.str.startsWith(val, 'mailto:') || (val.indexOf("@") !== -1 && !_.str.startsWith(val, 'http') && !_.str.startsWith(val, 'www')))) { self.get_data_buy_mail(def, $e, isNewWindow, label, classes, test); } else { self.get_data_buy_url(def, $e, isNewWindow, label, classes, test); @@ -1080,7 +1081,13 @@ var LinkDialog = Dialog.extend({ }, get_data_buy_mail: function (def, $e, isNewWindow, label, classes, test) { var val = $e.val(); - def.resolve(val.indexOf("mailto:") === 0 ? val : 'mailto:' + val, isNewWindow, label, classes); + if (utils.is_email(val, true)) { + def.resolve(val.indexOf("mailto:") === 0 ? val : 'mailto:' + val, isNewWindow, label, classes); + } else { + $e.closest('.form-group').addClass('has-error'); + $e.focus(); + def.reject(); + } }, get_data_buy_url: function (def, $e, isNewWindow, label, classes, test) { def.resolve($e.val(), isNewWindow, label, classes); From e544ec8df7028e6a9ffb2c9b2a3ec64035c33bf9 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 20 Feb 2018 15:23:40 +0100 Subject: [PATCH 3/3] [FIX] stock_account: method expect a record, not an id Backport of 6cedc90f69d8c4fb82da19a6ed8a1ed3460101bc opw-817262 --- addons/stock_account/stock_account.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/stock_account/stock_account.py b/addons/stock_account/stock_account.py index 88c1c1edaf2..18c07c0fbed 100644 --- a/addons/stock_account/stock_account.py +++ b/addons/stock_account/stock_account.py @@ -136,13 +136,13 @@ class account_invoice(osv.osv): company_currency = inv.company_id.currency_id price_unit = i_line._get_anglo_saxon_price_unit() if inv.currency_id != company_currency: - currency_id = inv.currency_id.id + currency = inv.currency_id amount_currency = i_line._get_price(inv, company_currency.id, i_line, price_unit) else: - currency_id = False + currency = False amount_currency = False - return self.env['product.product']._anglo_saxon_sale_move_lines(i_line.name, i_line.product_id, i_line.uom_id, i_line.quantity, price_unit, currency=currency_id, amount_currency=amount_currency, fiscal_position=inv.fiscal_position_id, account_analytic=i_line.account_analytic_id) + return self.env['product.product']._anglo_saxon_sale_move_lines(i_line.name, i_line.product_id, i_line.uom_id, i_line.quantity, price_unit, currency=currency, amount_currency=amount_currency, fiscal_position=inv.fiscal_position_id, account_analytic=i_line.account_analytic_id) #----------------------------------------------------------