diff --git a/frappe/change_log/v13/v13_3_0.md b/frappe/change_log/v13/v13_3_0.md new file mode 100644 index 0000000000..6ab181ef09 --- /dev/null +++ b/frappe/change_log/v13/v13_3_0.md @@ -0,0 +1,49 @@ +# Version 13.3.0 Release Notes + +### Features & Enhancements + +- Deletion Steps in Data Deletion Tool ([#13124](https://github.com/frappe/frappe/pull/13124)) +- Format Option for list-apps in bench CLI ([#13125](https://github.com/frappe/frappe/pull/13125)) +- Add password fieldtype option for Web Form ([#13093](https://github.com/frappe/frappe/pull/13093)) +- Add simple __repr__ for DocTypes ([#13151](https://github.com/frappe/frappe/pull/13151)) +- Switch theme with left/right keys ([#13077](https://github.com/frappe/frappe/pull/13077)) +- sourceURL for injected javascript ([#13022](https://github.com/frappe/frappe/pull/13022)) + +### Fixes + +- Decode uri before importing file via weblink ([#13026](https://github.com/frappe/frappe/pull/13026)) +- Respond to /api requests as JSON by default ([#13053](https://github.com/frappe/frappe/pull/13053)) +- Disabled checkbox should be disabled ([#13021](https://github.com/frappe/frappe/pull/13021)) +- Moving Site folder across different FileSystems failed ([#13038](https://github.com/frappe/frappe/pull/13038)) +- Freeze screen till the background request is complete ([#13078](https://github.com/frappe/frappe/pull/13078)) +- Added conditional rendering for content field in split section w… ([#13075](https://github.com/frappe/frappe/pull/13075)) +- Show delete button on portal if user has permission to delete document ([#13149](https://github.com/frappe/frappe/pull/13149)) +- Dont disable dialog scroll on focusing a Link/Autocomplete field ([#13119](https://github.com/frappe/frappe/pull/13119)) +- Typo in RecorderDetail.vue ([#13086](https://github.com/frappe/frappe/pull/13086)) +- Error for bench drop-site. Added missing import. ([#13064](https://github.com/frappe/frappe/pull/13064)) +- Report column context ([#13090](https://github.com/frappe/frappe/pull/13090)) +- Different service name for push and pull request events ([#13094](https://github.com/frappe/frappe/pull/13094)) +- Moving Site folder across different FileSystems failed ([#13033](https://github.com/frappe/frappe/pull/13033)) +- Consistent checkboxes on all browsers ([#13042](https://github.com/frappe/frappe/pull/13042)) +- Changed shorcut widgets color picker to dropdown ([#13073](https://github.com/frappe/frappe/pull/13073)) +- Error while exporting reports with duration field ([#13118](https://github.com/frappe/frappe/pull/13118)) +- Add margin to download backup card ([#13079](https://github.com/frappe/frappe/pull/13079)) +- Move mention list generation logic to server-side ([#13074](https://github.com/frappe/frappe/pull/13074)) +- Make strings translatable ([#13046](https://github.com/frappe/frappe/pull/13046)) +- Don't evaluate dynamic properties to check if conflicts exist ([#13186](https://github.com/frappe/frappe/pull/13186)) +- Add __ function in vue global for translation in recorder ([#13089](https://github.com/frappe/frappe/pull/13089)) +- Make strings translatable ([#13076](https://github.com/frappe/frappe/pull/13076)) +- Show config in bench CLI ([#13128](https://github.com/frappe/frappe/pull/13128)) +- Add breadcrumbs for list view ([#13091](https://github.com/frappe/frappe/pull/13091)) +- Do not skip data in save while using shortcut ([#13182](https://github.com/frappe/frappe/pull/13182)) +- Use docfields from options if no docfields are returned from meta ([#13188](https://github.com/frappe/frappe/pull/13188)) +- Disable reloading files in `__pycache__` directory ([#13109](https://github.com/frappe/frappe/pull/13109)) +- RTL stylesheet route to load RTL style on demand. ([#13007](https://github.com/frappe/frappe/pull/13007)) +- Do not show messsage when exception is handled ([#13111](https://github.com/frappe/frappe/pull/13111)) +- Replace parseFloat by Number ([#13082](https://github.com/frappe/frappe/pull/13082)) +- Add margin to download backup card ([#13050](https://github.com/frappe/frappe/pull/13050)) +- Translate report column labels ([#13083](https://github.com/frappe/frappe/pull/13083)) +- Grid row color picker field not working ([#13040](https://github.com/frappe/frappe/pull/13040)) +- Improve oauthlib implementation ([#13045](https://github.com/frappe/frappe/pull/13045)) +- Replace filter_by like with full text filter ([#13126](https://github.com/frappe/frappe/pull/13126)) +- Focus jumps to first field ([#13067](https://github.com/frappe/frappe/pull/13067)) \ No newline at end of file diff --git a/frappe/integrations/oauth2.py b/frappe/integrations/oauth2.py index 2ce99d8aa3..2b227f503d 100644 --- a/frappe/integrations/oauth2.py +++ b/frappe/integrations/oauth2.py @@ -1,6 +1,5 @@ import json from urllib.parse import quote, urlencode - from oauthlib.oauth2 import FatalClientError, OAuth2Error from oauthlib.openid.connect.core.endpoints.pre_configured import ( Server as WebApplicationServer, diff --git a/frappe/oauth.py b/frappe/oauth.py index 35f047a2b6..a4c66bf3f2 100644 --- a/frappe/oauth.py +++ b/frappe/oauth.py @@ -4,11 +4,9 @@ import hashlib import re from http import cookies from urllib.parse import unquote, urlparse - import jwt import pytz from oauthlib.openid import RequestValidator - import frappe from frappe.auth import LoginManager diff --git a/frappe/public/js/frappe/web_form/web_form.js b/frappe/public/js/frappe/web_form/web_form.js index c490c5c66c..70353de170 100644 --- a/frappe/public/js/frappe/web_form/web_form.js +++ b/frappe/public/js/frappe/web_form/web_form.js @@ -87,11 +87,13 @@ export default class WebForm extends frappe.ui.FieldGroup { } setup_delete_button() { - this.add_button_to_header( - frappe.utils.icon('delete'), - "danger", - () => this.delete() - ); + frappe.has_permission(this.doc_type, "", "delete", () => { + this.add_button_to_header( + frappe.utils.icon('delete'), + "danger", + () => this.delete() + ); + }); } setup_print_button() { diff --git a/frappe/public/js/frappe/web_form/web_form_list.js b/frappe/public/js/frappe/web_form/web_form_list.js index 21eed52e5e..de45b3ac11 100644 --- a/frappe/public/js/frappe/web_form/web_form_list.js +++ b/frappe/public/js/frappe/web_form/web_form_list.js @@ -190,9 +190,11 @@ export default class WebFormList { make_actions() { const actions = document.querySelector(".list-view-actions"); - this.addButton(actions, "delete-rows", "danger", true, "Delete", () => - this.delete_rows() - ); + frappe.has_permission(this.doctype, "", "delete", () => { + this.addButton(actions, "delete-rows", "danger", true, "Delete", () => + this.delete_rows() + ); + }); this.addButton( actions, diff --git a/frappe/utils/__init__.py b/frappe/utils/__init__.py index 43a7b82c16..d74186aa02 100644 --- a/frappe/utils/__init__.py +++ b/frappe/utils/__init__.py @@ -66,7 +66,7 @@ def get_formatted_email(user, mail=None): def extract_email_id(email): """fetch only the email part of the Email Address""" email_id = parse_addr(email)[1] - if email_id and isinstance(email_id, bytes): + if email_id and isinstance(email_id, str) and not isinstance(email_id, str): email_id = email_id.decode("utf-8", "ignore") return email_id @@ -394,18 +394,15 @@ def get_site_url(site): def encode_dict(d, encoding="utf-8"): for key in d: - if isinstance(d[key], str): + if isinstance(d[key], str) and isinstance(d[key], str): d[key] = d[key].encode(encoding) return d def decode_dict(d, encoding="utf-8"): for key in d: - if isinstance(d[key], bytes): - d[key] = d[key].decode(encoding, "ignore") - + if isinstance(d[key], str) and not isinstance(d[key], str): return d - @functools.lru_cache() def get_site_name(hostname): return hostname.split(':')[0] @@ -847,3 +844,11 @@ def groupby_metric(iterable: typing.Dict[str, list], key: str): for item in items: records.setdefault(item[key], {}).setdefault(category, []).append(item) return records + +def validate_url(url_string): + try: + result = urlparse(url_string) + return result.scheme and result.scheme in ["http", "https", "ftp", "ftps"] + except Exception: + return False +