feat: route deprecated sync clipboard read through permission checks (#45471)
* feat: route deprecated clipboard commands through permission checks Co-authored-by: deepak1556 <hop2deep@gmail.com> * docs: address review feedback Co-authored-by: deepak1556 <hop2deep@gmail.com> * fix: enable checks for child windows Co-authored-by: deepak1556 <hop2deep@gmail.com> --------- Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: deepak1556 <hop2deep@gmail.com>
This commit is contained in:
		
					parent
					
						
							
								51170c3652
							
						
					
				
			
			
				commit
				
					
						46c9ed61da
					
				
			
		
					 30 changed files with 441 additions and 35 deletions
				
			
		
							
								
								
									
										1
									
								
								BUILD.gn
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								BUILD.gn
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -430,6 +430,7 @@ source_set("electron_lib") {
 | 
			
		|||
    "chromium_src:chrome_spellchecker",
 | 
			
		||||
    "shell/common:mojo",
 | 
			
		||||
    "shell/common:plugin",
 | 
			
		||||
    "shell/common:web_contents_utility",
 | 
			
		||||
    "shell/services/node/public/mojom",
 | 
			
		||||
    "//base:base_static",
 | 
			
		||||
    "//base/allocator:buildflags",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -933,6 +933,7 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
 | 
			
		|||
    * `storage-access` - Allows content loaded in a third-party context to request access to third-party cookies using the [Storage Access API](https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API).
 | 
			
		||||
    * `top-level-storage-access` -  Allow top-level sites to request third-party cookie access on behalf of embedded content originating from another site in the same related website set using the [Storage Access API](https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API).
 | 
			
		||||
    * `usb` - Expose non-standard Universal Serial Bus (USB) compatible devices services to the web with the [WebUSB API](https://developer.mozilla.org/en-US/docs/Web/API/WebUSB_API).
 | 
			
		||||
    * `deprecated-sync-clipboard-read` _Deprecated_ - Request access to run `document.execCommand("paste")`
 | 
			
		||||
  * `requestingOrigin` string - The origin URL of the permission check
 | 
			
		||||
  * `details` Object - Some properties are only available on certain permission types.
 | 
			
		||||
    * `embeddingOrigin` string (optional) - The origin of the frame embedding the frame that made the permission check.  Only set for cross-origin sub frames making permission checks.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -148,6 +148,7 @@
 | 
			
		|||
  this will cause the `preferred-size-changed` event to be emitted on the
 | 
			
		||||
  `WebContents` when the preferred size changes. Default is `false`.
 | 
			
		||||
* `transparent` boolean (optional) - Whether to enable background transparency for the guest page. Default is `true`. **Note:** The guest page's text and background colors are derived from the [color scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme) of its root element. When transparency is enabled, the text color will still change accordingly but the background will remain transparent.
 | 
			
		||||
* `enableDeprecatedPaste` boolean (optional) _Deprecated_ - Whether to enable the `paste` [execCommand](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand). Default is `false`.
 | 
			
		||||
 | 
			
		||||
[chrome-content-scripts]: https://developer.chrome.com/extensions/content_scripts#execution-environment
 | 
			
		||||
[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,6 +73,15 @@ This brings the behavior to parity with Linux. Prior behavior: Menu bar is still
 | 
			
		|||
 | 
			
		||||
## Planned Breaking API Changes (33.0)
 | 
			
		||||
 | 
			
		||||
### Deprecated: `document.execCommand("paste")`
 | 
			
		||||
 | 
			
		||||
The synchronous clipboard read API [document.execCommand("paste")](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard) has been
 | 
			
		||||
deprecated in favor of [async clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API). This is to align with the browser defaults.
 | 
			
		||||
 | 
			
		||||
The `enableDeprecatedPaste` option on `WebPreferences` that triggers the permission
 | 
			
		||||
checks for this API and the associated permission type `deprecated-sync-clipboard-read`
 | 
			
		||||
are also deprecated.
 | 
			
		||||
 | 
			
		||||
### Behavior Changed: frame properties may retrieve detached WebFrameMain instances or none at all
 | 
			
		||||
 | 
			
		||||
APIs which provide access to a `WebFrameMain` instance may return an instance
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,7 +128,7 @@ fix_font_face_resolution_when_renderer_is_blocked.patch
 | 
			
		|||
feat_enable_passing_exit_code_on_service_process_crash.patch
 | 
			
		||||
chore_remove_reference_to_chrome_browser_themes.patch
 | 
			
		||||
feat_enable_customizing_symbol_color_in_framecaptionbutton.patch
 | 
			
		||||
build_expose_webplugininfo_interface_to_electron.patch
 | 
			
		||||
build_allow_electron_mojom_interfaces_to_depend_on_blink.patch
 | 
			
		||||
osr_shared_texture_remove_keyed_mutex_on_win_dxgi.patch
 | 
			
		||||
feat_allow_usage_of_sccontentsharingpicker_on_supported_platforms.patch
 | 
			
		||||
chore_partial_revert_of.patch
 | 
			
		||||
| 
						 | 
				
			
			@ -140,3 +140,4 @@ build_add_public_config_simdutf_config.patch
 | 
			
		|||
revert_code_health_clean_up_stale_macwebcontentsocclusion.patch
 | 
			
		||||
feat_add_signals_when_embedder_cleanup_callbacks_run_for.patch
 | 
			
		||||
build_remove_vr_directx_helpers_dependency.patch
 | 
			
		||||
feat_separate_content_settings_callback_for_sync_and_async_clipboard.patch
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,20 +1,24 @@
 | 
			
		|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: deepak1556 <hop2deep@gmail.com>
 | 
			
		||||
Date: Fri, 9 Aug 2024 22:39:47 +0900
 | 
			
		||||
Subject: build: expose webplugininfo interface to electron
 | 
			
		||||
Subject: build: allow electron mojom interfaces to depend on blink
 | 
			
		||||
 mojom_platform
 | 
			
		||||
 | 
			
		||||
Allows implementing electron::mojom::ElectronPluginInfoHost interface
 | 
			
		||||
which provides plugin details between browser<->renderer.
 | 
			
		||||
Needed for:
 | 
			
		||||
 | 
			
		||||
1) //electron/shell/common:plugin
 | 
			
		||||
2) //electron/shell/common:web_contents_utility
 | 
			
		||||
 | 
			
		||||
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
 | 
			
		||||
index 659f500a47eb0f2d1f753dee2b234bb7bf1027d4..46e4714e14a5992b30ea8bfa99c126e5f1d2c3eb 100644
 | 
			
		||||
index 659f500a47eb0f2d1f753dee2b234bb7bf1027d4..8f6e733b1ae1081f19a090cbdf2372b164e514a8 100644
 | 
			
		||||
--- a/content/public/common/BUILD.gn
 | 
			
		||||
+++ b/content/public/common/BUILD.gn
 | 
			
		||||
@@ -379,6 +379,7 @@ mojom("interfaces") {
 | 
			
		||||
@@ -379,6 +379,8 @@ mojom("interfaces") {
 | 
			
		||||
     "//content/common/*",
 | 
			
		||||
     "//extensions/common:mojom",
 | 
			
		||||
     "//extensions/common:mojom_blink",
 | 
			
		||||
+    "//electron/shell/common:plugin",
 | 
			
		||||
+    "//electron/shell/common:web_contents_utility",
 | 
			
		||||
   ]
 | 
			
		||||
 
 | 
			
		||||
   sources = [
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,114 @@
 | 
			
		|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: deepak1556 <hop2deep@gmail.com>
 | 
			
		||||
Date: Thu, 30 Jan 2025 20:28:38 +0900
 | 
			
		||||
Subject: feat: separate content settings callback for sync and async clipboard
 | 
			
		||||
 | 
			
		||||
`AllowReadFromClipboard` is called from both the types without a way to differentiate.
 | 
			
		||||
 | 
			
		||||
[sync path] - third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
 | 
			
		||||
[async path] - third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
 | 
			
		||||
 | 
			
		||||
This patch adds a new callback to separate these two paths so that we
 | 
			
		||||
can have sync permission checks for the sync path.
 | 
			
		||||
 | 
			
		||||
Additionally, `blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ`
 | 
			
		||||
has been added to support type conversion in permission policy checks. We have extended
 | 
			
		||||
`blink::PermissionType` in `electron::WebContentsPermissionHelper::PermissionType`
 | 
			
		||||
but it is hard to import the latter into the content permission layer checks.
 | 
			
		||||
 | 
			
		||||
This patch will be removed when the deprecated sync api support is
 | 
			
		||||
removed.
 | 
			
		||||
 | 
			
		||||
diff --git a/components/permissions/permission_util.cc b/components/permissions/permission_util.cc
 | 
			
		||||
index 0265815ae3b300c1c0637686e212d3a1c55fdd1b..eb7ea287de24a2563604e639de3bb783d80d98eb 100644
 | 
			
		||||
--- a/components/permissions/permission_util.cc
 | 
			
		||||
+++ b/components/permissions/permission_util.cc
 | 
			
		||||
@@ -384,6 +384,7 @@ ContentSettingsType PermissionUtil::PermissionTypeToContentSettingsTypeSafe(
 | 
			
		||||
       return ContentSettingsType::AUTOMATIC_FULLSCREEN;
 | 
			
		||||
     case PermissionType::WEB_APP_INSTALLATION:
 | 
			
		||||
       return ContentSettingsType::WEB_APP_INSTALLATION;
 | 
			
		||||
+    case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
 | 
			
		||||
     case PermissionType::NUM:
 | 
			
		||||
       break;
 | 
			
		||||
   }
 | 
			
		||||
diff --git a/content/browser/permissions/permission_controller_impl.cc b/content/browser/permissions/permission_controller_impl.cc
 | 
			
		||||
index e991887c103618b35688cf72307ca05fdb202e6e..54894f3412d42264eae80d767be5215e52f08184 100644
 | 
			
		||||
--- a/content/browser/permissions/permission_controller_impl.cc
 | 
			
		||||
+++ b/content/browser/permissions/permission_controller_impl.cc
 | 
			
		||||
@@ -86,6 +86,7 @@ PermissionToSchedulingFeature(PermissionType permission_name) {
 | 
			
		||||
     case PermissionType::POINTER_LOCK:
 | 
			
		||||
     case PermissionType::AUTOMATIC_FULLSCREEN:
 | 
			
		||||
     case PermissionType::WEB_APP_INSTALLATION:
 | 
			
		||||
+    case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
 | 
			
		||||
       return std::nullopt;
 | 
			
		||||
   }
 | 
			
		||||
 }
 | 
			
		||||
diff --git a/third_party/blink/common/permissions/permission_utils.cc b/third_party/blink/common/permissions/permission_utils.cc
 | 
			
		||||
index dfcd99a4336db5c5b8b722c6612b8abbf419a08f..9f074285203e6ee408abf8275f3070221b0d25c0 100644
 | 
			
		||||
--- a/third_party/blink/common/permissions/permission_utils.cc
 | 
			
		||||
+++ b/third_party/blink/common/permissions/permission_utils.cc
 | 
			
		||||
@@ -99,6 +99,8 @@ std::string GetPermissionString(PermissionType permission) {
 | 
			
		||||
       return "AutomaticFullscreen";
 | 
			
		||||
     case PermissionType::WEB_APP_INSTALLATION:
 | 
			
		||||
       return "WebAppInstallation";
 | 
			
		||||
+    case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
 | 
			
		||||
+      return "DeprecatedSyncClipboardRead";
 | 
			
		||||
     case PermissionType::NUM:
 | 
			
		||||
       NOTREACHED();
 | 
			
		||||
   }
 | 
			
		||||
@@ -171,6 +173,7 @@ PermissionTypeToPermissionsPolicyFeature(PermissionType permission) {
 | 
			
		||||
     case PermissionType::NOTIFICATIONS:
 | 
			
		||||
     case PermissionType::KEYBOARD_LOCK:
 | 
			
		||||
     case PermissionType::POINTER_LOCK:
 | 
			
		||||
+    case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
 | 
			
		||||
       return std::nullopt;
 | 
			
		||||
 
 | 
			
		||||
     case PermissionType::NUM:
 | 
			
		||||
diff --git a/third_party/blink/public/common/permissions/permission_utils.h b/third_party/blink/public/common/permissions/permission_utils.h
 | 
			
		||||
index ae03b7f099d30c157cfda7d1beb7c535d3615471..ca287e7a5271ee83c393de6c1fe347973f4292ba 100644
 | 
			
		||||
--- a/third_party/blink/public/common/permissions/permission_utils.h
 | 
			
		||||
+++ b/third_party/blink/public/common/permissions/permission_utils.h
 | 
			
		||||
@@ -64,6 +64,7 @@ enum class PermissionType {
 | 
			
		||||
   AUTOMATIC_FULLSCREEN = 40,
 | 
			
		||||
   HAND_TRACKING = 41,
 | 
			
		||||
   WEB_APP_INSTALLATION = 42,
 | 
			
		||||
+  DEPRECATED_SYNC_CLIPBOARD_READ = 43,
 | 
			
		||||
 
 | 
			
		||||
   // Always keep this at the end.
 | 
			
		||||
   NUM,
 | 
			
		||||
diff --git a/third_party/blink/public/platform/web_content_settings_client.h b/third_party/blink/public/platform/web_content_settings_client.h
 | 
			
		||||
index 28f616f21f998c7cd1c794e58efaccf9e6c11e6e..c64896642209124e500db2ed6fe2357e426cd10b 100644
 | 
			
		||||
--- a/third_party/blink/public/platform/web_content_settings_client.h
 | 
			
		||||
+++ b/third_party/blink/public/platform/web_content_settings_client.h
 | 
			
		||||
@@ -55,6 +55,9 @@ class WebContentSettingsClient {
 | 
			
		||||
   // Controls whether access to write the clipboard is allowed for this frame.
 | 
			
		||||
   virtual bool AllowWriteToClipboard() { return false; }
 | 
			
		||||
 
 | 
			
		||||
+  // Controls whether synchronous access to read the clipboard is allowed for this frame.
 | 
			
		||||
+  virtual bool AllowReadFromClipboardSync() { return false; }
 | 
			
		||||
+
 | 
			
		||||
   // Controls whether to enable MutationEvents for this frame.
 | 
			
		||||
   // The common use case of this method is actually to selectively disable
 | 
			
		||||
   // MutationEvents, but it's been named for consistency with the rest of the
 | 
			
		||||
diff --git a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
 | 
			
		||||
index 271ca7ba88fc92b8f6bad5ee4cffedf7f1b05aee..d8d01062de4af45a59eb10a1c0fa046a4adf1894 100644
 | 
			
		||||
--- a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
 | 
			
		||||
+++ b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
 | 
			
		||||
@@ -121,7 +121,7 @@ bool ClipboardCommands::CanReadClipboard(LocalFrame& frame,
 | 
			
		||||
     return true;
 | 
			
		||||
   }
 | 
			
		||||
   return frame.GetContentSettingsClient() &&
 | 
			
		||||
-         frame.GetContentSettingsClient()->AllowReadFromClipboard();
 | 
			
		||||
+         frame.GetContentSettingsClient()->AllowReadFromClipboardSync();
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 bool ClipboardCommands::CanWriteClipboard(LocalFrame& frame,
 | 
			
		||||
@@ -310,7 +310,7 @@ bool ClipboardCommands::PasteSupported(LocalFrame* frame) {
 | 
			
		||||
     return true;
 | 
			
		||||
   }
 | 
			
		||||
   return frame->GetContentSettingsClient() &&
 | 
			
		||||
-         frame->GetContentSettingsClient()->AllowReadFromClipboard();
 | 
			
		||||
+         frame->GetContentSettingsClient()->AllowReadFromClipboardSync();
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 bool ClipboardCommands::ExecuteCopy(LocalFrame& frame,
 | 
			
		||||
| 
						 | 
				
			
			@ -13,13 +13,13 @@
 | 
			
		|||
#include "base/no_destructor.h"
 | 
			
		||||
#include "content/browser/service_worker/service_worker_context_wrapper.h"  // nogncheck
 | 
			
		||||
#include "content/browser/service_worker/service_worker_version.h"  // nogncheck
 | 
			
		||||
#include "electron/shell/common/api/api.mojom.h"
 | 
			
		||||
#include "gin/handle.h"
 | 
			
		||||
#include "gin/object_template_builder.h"
 | 
			
		||||
#include "services/service_manager/public/cpp/interface_provider.h"
 | 
			
		||||
#include "shell/browser/api/message_port.h"
 | 
			
		||||
#include "shell/browser/browser.h"
 | 
			
		||||
#include "shell/browser/javascript_environment.h"
 | 
			
		||||
#include "shell/common/api/api.mojom.h"
 | 
			
		||||
#include "shell/common/gin_converters/blink_converter.h"
 | 
			
		||||
#include "shell/common/gin_converters/gurl_converter.h"
 | 
			
		||||
#include "shell/common/gin_converters/value_converter.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,7 +70,6 @@
 | 
			
		|||
#include "content/public/common/webplugininfo.h"
 | 
			
		||||
#include "electron/buildflags/buildflags.h"
 | 
			
		||||
#include "electron/mas.h"
 | 
			
		||||
#include "electron/shell/common/api/api.mojom.h"
 | 
			
		||||
#include "gin/arguments.h"
 | 
			
		||||
#include "gin/data_object_builder.h"
 | 
			
		||||
#include "gin/handle.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +109,7 @@
 | 
			
		|||
#include "shell/browser/web_contents_zoom_controller.h"
 | 
			
		||||
#include "shell/browser/web_view_guest_delegate.h"
 | 
			
		||||
#include "shell/browser/web_view_manager.h"
 | 
			
		||||
#include "shell/common/api/api.mojom.h"
 | 
			
		||||
#include "shell/common/api/electron_api_native_image.h"
 | 
			
		||||
#include "shell/common/api/electron_bindings.h"
 | 
			
		||||
#include "shell/common/color_util.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,7 +31,6 @@
 | 
			
		|||
#include "content/public/browser/web_contents_delegate.h"
 | 
			
		||||
#include "content/public/browser/web_contents_observer.h"
 | 
			
		||||
#include "electron/buildflags/buildflags.h"
 | 
			
		||||
#include "electron/shell/common/api/api.mojom.h"
 | 
			
		||||
#include "gin/handle.h"
 | 
			
		||||
#include "gin/wrappable.h"
 | 
			
		||||
#include "printing/buildflags/buildflags.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -43,9 +42,11 @@
 | 
			
		|||
#include "shell/browser/preload_script.h"
 | 
			
		||||
#include "shell/browser/ui/inspectable_web_contents_delegate.h"
 | 
			
		||||
#include "shell/browser/ui/inspectable_web_contents_view_delegate.h"
 | 
			
		||||
#include "shell/common/api/api.mojom.h"
 | 
			
		||||
#include "shell/common/gin_helper/cleaned_up_at_exit.h"
 | 
			
		||||
#include "shell/common/gin_helper/constructible.h"
 | 
			
		||||
#include "shell/common/gin_helper/pinnable.h"
 | 
			
		||||
#include "shell/common/web_contents_utility.mojom.h"
 | 
			
		||||
#include "ui/base/models/image_model.h"
 | 
			
		||||
 | 
			
		||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,13 +17,13 @@
 | 
			
		|||
#include "content/public/browser/frame_tree_node_id.h"
 | 
			
		||||
#include "content/public/browser/render_frame_host.h"
 | 
			
		||||
#include "content/public/common/isolated_world_ids.h"
 | 
			
		||||
#include "electron/shell/common/api/api.mojom.h"
 | 
			
		||||
#include "gin/handle.h"
 | 
			
		||||
#include "gin/object_template_builder.h"
 | 
			
		||||
#include "services/service_manager/public/cpp/interface_provider.h"
 | 
			
		||||
#include "shell/browser/api/message_port.h"
 | 
			
		||||
#include "shell/browser/browser.h"
 | 
			
		||||
#include "shell/browser/javascript_environment.h"
 | 
			
		||||
#include "shell/common/api/api.mojom.h"
 | 
			
		||||
#include "shell/common/gin_converters/blink_converter.h"
 | 
			
		||||
#include "shell/common/gin_converters/frame_converter.h"
 | 
			
		||||
#include "shell/common/gin_converters/gurl_converter.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,9 +10,9 @@
 | 
			
		|||
#include "base/memory/weak_ptr.h"
 | 
			
		||||
#include "content/public/browser/global_routing_id.h"
 | 
			
		||||
#include "content/public/browser/web_contents_observer.h"
 | 
			
		||||
#include "electron/shell/common/api/api.mojom.h"
 | 
			
		||||
#include "mojo/public/cpp/bindings/associated_receiver.h"
 | 
			
		||||
#include "shell/browser/api/electron_api_web_contents.h"
 | 
			
		||||
#include "shell/common/api/api.mojom.h"
 | 
			
		||||
 | 
			
		||||
namespace content {
 | 
			
		||||
class RenderFrameHost;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,7 +53,6 @@
 | 
			
		|||
#include "crypto/crypto_buildflags.h"
 | 
			
		||||
#include "electron/buildflags/buildflags.h"
 | 
			
		||||
#include "electron/fuses.h"
 | 
			
		||||
#include "electron/shell/common/api/api.mojom.h"
 | 
			
		||||
#include "extensions/browser/extension_navigation_ui_data.h"
 | 
			
		||||
#include "extensions/common/extension_id.h"
 | 
			
		||||
#include "mojo/public/cpp/bindings/binder_map.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +116,7 @@
 | 
			
		|||
#include "shell/common/platform_util.h"
 | 
			
		||||
#include "shell/common/plugin.mojom.h"
 | 
			
		||||
#include "shell/common/thread_restrictions.h"
 | 
			
		||||
#include "shell/common/web_contents_utility.mojom.h"
 | 
			
		||||
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
 | 
			
		||||
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
 | 
			
		||||
#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -298,8 +298,13 @@ bool ElectronPermissionManager::CheckPermissionWithDetails(
 | 
			
		|||
    content::RenderFrameHost* render_frame_host,
 | 
			
		||||
    const GURL& requesting_origin,
 | 
			
		||||
    base::Value::Dict details) const {
 | 
			
		||||
  if (check_handler_.is_null())
 | 
			
		||||
  if (check_handler_.is_null()) {
 | 
			
		||||
    if (permission == blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ) {
 | 
			
		||||
      return false;
 | 
			
		||||
    } else {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  auto* web_contents =
 | 
			
		||||
      render_frame_host
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,15 +6,19 @@
 | 
			
		|||
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
#include "content/public/browser/browser_context.h"
 | 
			
		||||
#include "content/public/browser/permission_controller.h"
 | 
			
		||||
#include "content/public/browser/render_frame_host.h"
 | 
			
		||||
#include "content/public/browser/render_process_host.h"
 | 
			
		||||
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
 | 
			
		||||
#include "shell/browser/web_contents_permission_helper.h"
 | 
			
		||||
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
 | 
			
		||||
 | 
			
		||||
namespace electron {
 | 
			
		||||
ElectronWebContentsUtilityHandlerImpl::ElectronWebContentsUtilityHandlerImpl(
 | 
			
		||||
    content::RenderFrameHost* frame_host,
 | 
			
		||||
    mojo::PendingAssociatedReceiver<mojom::ElectronWebContentsUtility> receiver)
 | 
			
		||||
    : render_frame_host_id_(frame_host->GetGlobalId()) {
 | 
			
		||||
    : render_frame_host_token_(frame_host->GetGlobalFrameToken()) {
 | 
			
		||||
  content::WebContents* web_contents =
 | 
			
		||||
      content::WebContents::FromRenderFrameHost(frame_host);
 | 
			
		||||
  DCHECK(web_contents);
 | 
			
		||||
| 
						 | 
				
			
			@ -28,9 +32,12 @@ ElectronWebContentsUtilityHandlerImpl::ElectronWebContentsUtilityHandlerImpl(
 | 
			
		|||
ElectronWebContentsUtilityHandlerImpl::
 | 
			
		||||
    ~ElectronWebContentsUtilityHandlerImpl() = default;
 | 
			
		||||
 | 
			
		||||
void ElectronWebContentsUtilityHandlerImpl::WebContentsDestroyed() {
 | 
			
		||||
void ElectronWebContentsUtilityHandlerImpl::RenderFrameDeleted(
 | 
			
		||||
    content::RenderFrameHost* render_frame_host) {
 | 
			
		||||
  if (render_frame_host->GetGlobalFrameToken() == render_frame_host_token_) {
 | 
			
		||||
    delete this;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ElectronWebContentsUtilityHandlerImpl::OnConnectionError() {
 | 
			
		||||
  delete this;
 | 
			
		||||
| 
						 | 
				
			
			@ -59,9 +66,42 @@ void ElectronWebContentsUtilityHandlerImpl::DoGetZoomLevel(
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ElectronWebContentsUtilityHandlerImpl::CanAccessClipboardDeprecated(
 | 
			
		||||
    mojom::PermissionName name,
 | 
			
		||||
    const blink::LocalFrameToken& frame_token,
 | 
			
		||||
    CanAccessClipboardDeprecatedCallback callback) {
 | 
			
		||||
  if (render_frame_host_token_.frame_token == frame_token) {
 | 
			
		||||
    // Paste requires either (1) user activation, ...
 | 
			
		||||
    if (web_contents()->HasRecentInteraction()) {
 | 
			
		||||
      std::move(callback).Run(blink::mojom::PermissionStatus::GRANTED);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // (2) granted permission, ...
 | 
			
		||||
    content::RenderFrameHost* render_frame_host = GetRenderFrameHost();
 | 
			
		||||
    content::BrowserContext* browser_context =
 | 
			
		||||
        render_frame_host->GetBrowserContext();
 | 
			
		||||
    content::PermissionController* permission_controller =
 | 
			
		||||
        browser_context->GetPermissionController();
 | 
			
		||||
    blink::PermissionType permission;
 | 
			
		||||
    if (name == mojom::PermissionName::DEPRECATED_SYNC_CLIPBOARD_READ) {
 | 
			
		||||
      permission = blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ;
 | 
			
		||||
    } else {
 | 
			
		||||
      std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    blink::mojom::PermissionStatus status =
 | 
			
		||||
        permission_controller->GetPermissionStatusForCurrentDocument(
 | 
			
		||||
            permission, render_frame_host);
 | 
			
		||||
    std::move(callback).Run(status);
 | 
			
		||||
  } else {
 | 
			
		||||
    std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
content::RenderFrameHost*
 | 
			
		||||
ElectronWebContentsUtilityHandlerImpl::GetRenderFrameHost() {
 | 
			
		||||
  return content::RenderFrameHost::FromID(render_frame_host_id_);
 | 
			
		||||
  return content::RenderFrameHost::FromFrameToken(render_frame_host_token_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// static
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@
 | 
			
		|||
#include "base/memory/weak_ptr.h"
 | 
			
		||||
#include "content/public/browser/global_routing_id.h"
 | 
			
		||||
#include "content/public/browser/web_contents_observer.h"
 | 
			
		||||
#include "electron/shell/common/api/api.mojom.h"
 | 
			
		||||
#include "electron/shell/common/web_contents_utility.mojom.h"
 | 
			
		||||
#include "mojo/public/cpp/bindings/associated_receiver.h"
 | 
			
		||||
#include "shell/browser/api/electron_api_web_contents.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +43,10 @@ class ElectronWebContentsUtilityHandlerImpl
 | 
			
		|||
  void OnFirstNonEmptyLayout() override;
 | 
			
		||||
  void SetTemporaryZoomLevel(double level) override;
 | 
			
		||||
  void DoGetZoomLevel(DoGetZoomLevelCallback callback) override;
 | 
			
		||||
  void CanAccessClipboardDeprecated(
 | 
			
		||||
      mojom::PermissionName name,
 | 
			
		||||
      const blink::LocalFrameToken& frame_token,
 | 
			
		||||
      CanAccessClipboardDeprecatedCallback callback) override;
 | 
			
		||||
 | 
			
		||||
  base::WeakPtr<ElectronWebContentsUtilityHandlerImpl> GetWeakPtr() {
 | 
			
		||||
    return weak_factory_.GetWeakPtr();
 | 
			
		||||
| 
						 | 
				
			
			@ -52,13 +56,13 @@ class ElectronWebContentsUtilityHandlerImpl
 | 
			
		|||
  ~ElectronWebContentsUtilityHandlerImpl() override;
 | 
			
		||||
 | 
			
		||||
  // content::WebContentsObserver:
 | 
			
		||||
  void WebContentsDestroyed() override;
 | 
			
		||||
  void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
 | 
			
		||||
 | 
			
		||||
  void OnConnectionError();
 | 
			
		||||
 | 
			
		||||
  content::RenderFrameHost* GetRenderFrameHost();
 | 
			
		||||
 | 
			
		||||
  content::GlobalRenderFrameHostId render_frame_host_id_;
 | 
			
		||||
  content::GlobalRenderFrameHostToken render_frame_host_token_;
 | 
			
		||||
 | 
			
		||||
  mojo::AssociatedReceiver<mojom::ElectronWebContentsUtility> receiver_{this};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ class WebContentsPermissionHelper
 | 
			
		|||
    HID,
 | 
			
		||||
    USB,
 | 
			
		||||
    KEYBOARD_LOCK,
 | 
			
		||||
    FILE_SYSTEM
 | 
			
		||||
    FILE_SYSTEM,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Asynchronous Requests
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -148,6 +148,7 @@ void WebContentsPreferences::Clear() {
 | 
			
		|||
      blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAllowed;
 | 
			
		||||
  preload_path_ = std::nullopt;
 | 
			
		||||
  v8_cache_options_ = blink::mojom::V8CacheOptions::kDefault;
 | 
			
		||||
  deprecated_paste_enabled_ = false;
 | 
			
		||||
 | 
			
		||||
#if BUILDFLAG(IS_MAC)
 | 
			
		||||
  scroll_bounce_ = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -245,6 +246,9 @@ void WebContentsPreferences::SetFromDictionary(
 | 
			
		|||
 | 
			
		||||
  web_preferences.Get("v8CacheOptions", &v8_cache_options_);
 | 
			
		||||
 | 
			
		||||
  web_preferences.Get(options::kEnableDeprecatedPaste,
 | 
			
		||||
                      &deprecated_paste_enabled_);
 | 
			
		||||
 | 
			
		||||
#if BUILDFLAG(IS_MAC)
 | 
			
		||||
  web_preferences.Get(options::kScrollBounce, &scroll_bounce_);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -472,6 +476,8 @@ void WebContentsPreferences::OverrideWebkitPrefs(
 | 
			
		|||
  prefs->webview_tag = webview_tag_;
 | 
			
		||||
 | 
			
		||||
  prefs->v8_cache_options = v8_cache_options_;
 | 
			
		||||
 | 
			
		||||
  prefs->dom_paste_enabled = deprecated_paste_enabled_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WEB_CONTENTS_USER_DATA_KEY_IMPL(WebContentsPreferences);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,6 +133,7 @@ class WebContentsPreferences
 | 
			
		|||
  blink::mojom::ImageAnimationPolicy image_animation_policy_;
 | 
			
		||||
  std::optional<base::FilePath> preload_path_;
 | 
			
		||||
  blink::mojom::V8CacheOptions v8_cache_options_;
 | 
			
		||||
  bool deprecated_paste_enabled_ = false;
 | 
			
		||||
 | 
			
		||||
#if BUILDFLAG(IS_MAC)
 | 
			
		||||
  bool scroll_bounce_;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,3 +26,16 @@ mojom("plugin") {
 | 
			
		|||
    "//mojo/public/mojom/base",
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mojom("web_contents_utility") {
 | 
			
		||||
  # We don't want Blink variants of these bindings to be generated.
 | 
			
		||||
  disable_variants = true
 | 
			
		||||
 | 
			
		||||
  sources = [ "web_contents_utility.mojom" ]
 | 
			
		||||
 | 
			
		||||
  public_deps = [
 | 
			
		||||
    "//content/public/common:interfaces",
 | 
			
		||||
    "//third_party/blink/public/mojom/tokens",
 | 
			
		||||
    "//url/mojom:url_mojom_origin",
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,17 +25,6 @@ interface ElectronAutofillDriver {
 | 
			
		|||
  HideAutofillPopup();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface ElectronWebContentsUtility {
 | 
			
		||||
  // Informs underlying WebContents that first non-empty layout was performed
 | 
			
		||||
  // by compositor.
 | 
			
		||||
  OnFirstNonEmptyLayout();
 | 
			
		||||
 | 
			
		||||
  SetTemporaryZoomLevel(double zoom_level);
 | 
			
		||||
 | 
			
		||||
  [Sync]
 | 
			
		||||
  DoGetZoomLevel() => (double result);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface ElectronApiIPC {
 | 
			
		||||
  // Emits an event on |channel| from the ipcMain JavaScript object in the main
 | 
			
		||||
  // process.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -226,6 +226,8 @@ v8::Local<v8::Value> Converter<blink::PermissionType>::ToV8(
 | 
			
		|||
      return StringToV8(isolate, "speaker-selection");
 | 
			
		||||
    case blink::PermissionType::WEB_APP_INSTALLATION:
 | 
			
		||||
      return StringToV8(isolate, "web-app-installation");
 | 
			
		||||
    case blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
 | 
			
		||||
      return StringToV8(isolate, "deprecated-sync-clipboard-read");
 | 
			
		||||
    case blink::PermissionType::NUM:
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -205,6 +205,11 @@ inline constexpr std::string_view kEnablePreferredSizeMode =
 | 
			
		|||
inline constexpr std::string_view kHiddenPage = "hiddenPage";
 | 
			
		||||
 | 
			
		||||
inline constexpr std::string_view kSpellcheck = "spellcheck";
 | 
			
		||||
 | 
			
		||||
// Enables the permission managed support for
 | 
			
		||||
// document.execCommand("paste").
 | 
			
		||||
inline constexpr std::string_view kEnableDeprecatedPaste =
 | 
			
		||||
    "enableDeprecatedPaste";
 | 
			
		||||
}  // namespace options
 | 
			
		||||
 | 
			
		||||
// Following are actually command line switches, should be moved to other files.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										25
									
								
								shell/common/web_contents_utility.mojom
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								shell/common/web_contents_utility.mojom
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
module electron.mojom;
 | 
			
		||||
 | 
			
		||||
import "third_party/blink/public/mojom/permissions/permission_status.mojom";
 | 
			
		||||
import "third_party/blink/public/mojom/tokens/tokens.mojom";
 | 
			
		||||
import "url/mojom/origin.mojom";
 | 
			
		||||
 | 
			
		||||
enum PermissionName {
 | 
			
		||||
  DEPRECATED_SYNC_CLIPBOARD_READ,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface ElectronWebContentsUtility {
 | 
			
		||||
  // Informs underlying WebContents that first non-empty layout was performed
 | 
			
		||||
  // by compositor.
 | 
			
		||||
  OnFirstNonEmptyLayout();
 | 
			
		||||
 | 
			
		||||
  SetTemporaryZoomLevel(double zoom_level);
 | 
			
		||||
 | 
			
		||||
  [Sync]
 | 
			
		||||
  DoGetZoomLevel() => (double result);
 | 
			
		||||
 | 
			
		||||
  [Sync]
 | 
			
		||||
  CanAccessClipboardDeprecated(
 | 
			
		||||
      PermissionName name,
 | 
			
		||||
      blink.mojom.LocalFrameToken frame_token) => (blink.mojom.PermissionStatus status);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -31,6 +31,7 @@
 | 
			
		|||
#include "shell/common/gin_helper/promise.h"
 | 
			
		||||
#include "shell/common/node_includes.h"
 | 
			
		||||
#include "shell/common/options_switches.h"
 | 
			
		||||
#include "shell/common/web_contents_utility.mojom.h"
 | 
			
		||||
#include "shell/renderer/api/context_bridge/object_cache.h"
 | 
			
		||||
#include "shell/renderer/api/electron_api_context_bridge.h"
 | 
			
		||||
#include "shell/renderer/api/electron_api_spell_check_client.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,10 +6,12 @@
 | 
			
		|||
 | 
			
		||||
#include "content/public/renderer/render_frame.h"
 | 
			
		||||
#include "shell/common/options_switches.h"
 | 
			
		||||
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 | 
			
		||||
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
 | 
			
		||||
#include "third_party/blink/public/platform/url_conversion.h"
 | 
			
		||||
#include "third_party/blink/public/platform/web_security_origin.h"
 | 
			
		||||
#include "third_party/blink/public/web/web_local_frame.h"
 | 
			
		||||
#include "third_party/blink/public/web/web_view.h"
 | 
			
		||||
 | 
			
		||||
namespace electron {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +23,15 @@ ContentSettingsObserver::ContentSettingsObserver(
 | 
			
		|||
 | 
			
		||||
ContentSettingsObserver::~ContentSettingsObserver() = default;
 | 
			
		||||
 | 
			
		||||
mojom::ElectronWebContentsUtility&
 | 
			
		||||
ContentSettingsObserver::GetWebContentsUtility() {
 | 
			
		||||
  if (!web_contents_utility_) {
 | 
			
		||||
    render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
 | 
			
		||||
        &web_contents_utility_);
 | 
			
		||||
  }
 | 
			
		||||
  return *web_contents_utility_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ContentSettingsObserver::AllowStorageAccessSync(StorageType storage_type) {
 | 
			
		||||
  blink::WebFrame* frame = render_frame()->GetWebFrame();
 | 
			
		||||
  if (frame->GetSecurityOrigin().IsOpaque() ||
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +43,20 @@ bool ContentSettingsObserver::AllowStorageAccessSync(StorageType storage_type) {
 | 
			
		|||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ContentSettingsObserver::AllowReadFromClipboardSync() {
 | 
			
		||||
  blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
 | 
			
		||||
  if (frame->View()->GetWebPreferences().dom_paste_enabled) {
 | 
			
		||||
    blink::mojom::PermissionStatus status{
 | 
			
		||||
        blink::mojom::PermissionStatus::DENIED};
 | 
			
		||||
    GetWebContentsUtility().CanAccessClipboardDeprecated(
 | 
			
		||||
        mojom::PermissionName::DEPRECATED_SYNC_CLIPBOARD_READ,
 | 
			
		||||
        frame->GetLocalFrameToken(), &status);
 | 
			
		||||
    return status == blink::mojom::PermissionStatus::GRANTED;
 | 
			
		||||
  } else {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ContentSettingsObserver::OnDestruct() {
 | 
			
		||||
  delete this;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,10 @@
 | 
			
		|||
#define ELECTRON_SHELL_RENDERER_CONTENT_SETTINGS_OBSERVER_H_
 | 
			
		||||
 | 
			
		||||
#include "content/public/renderer/render_frame_observer.h"
 | 
			
		||||
#include "mojo/public/cpp/bindings/associated_remote.h"
 | 
			
		||||
#include "shell/common/web_contents_utility.mojom.h"
 | 
			
		||||
#include "third_party/blink/public/platform/web_content_settings_client.h"
 | 
			
		||||
#include "url/origin.h"
 | 
			
		||||
 | 
			
		||||
namespace electron {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -22,10 +25,17 @@ class ContentSettingsObserver : public content::RenderFrameObserver,
 | 
			
		|||
 | 
			
		||||
  // blink::WebContentSettingsClient implementation.
 | 
			
		||||
  bool AllowStorageAccessSync(StorageType storage_type) override;
 | 
			
		||||
  bool AllowReadFromClipboardSync() override;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  // content::RenderFrameObserver implementation.
 | 
			
		||||
  void OnDestruct() override;
 | 
			
		||||
 | 
			
		||||
  // A getter for `content_settings_manager_` that ensures it is bound.
 | 
			
		||||
  mojom::ElectronWebContentsUtility& GetWebContentsUtility();
 | 
			
		||||
 | 
			
		||||
  mojo::AssociatedRemote<mojom::ElectronWebContentsUtility>
 | 
			
		||||
      web_contents_utility_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace electron
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,9 +10,9 @@
 | 
			
		|||
#include "base/memory/weak_ptr.h"
 | 
			
		||||
#include "content/public/renderer/render_frame.h"
 | 
			
		||||
#include "content/public/renderer/render_frame_observer.h"
 | 
			
		||||
#include "electron/shell/common/api/api.mojom.h"
 | 
			
		||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
 | 
			
		||||
#include "mojo/public/cpp/bindings/receiver.h"
 | 
			
		||||
#include "shell/common/api/api.mojom.h"
 | 
			
		||||
 | 
			
		||||
namespace electron {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,13 +9,14 @@
 | 
			
		|||
#include "base/memory/ref_counted_memory.h"
 | 
			
		||||
#include "base/trace_event/trace_event.h"
 | 
			
		||||
#include "content/public/renderer/render_frame.h"
 | 
			
		||||
#include "electron/shell/common/api/api.mojom.h"
 | 
			
		||||
#include "ipc/ipc_message_macros.h"
 | 
			
		||||
#include "net/base/net_module.h"
 | 
			
		||||
#include "net/grit/net_resources.h"
 | 
			
		||||
#include "services/service_manager/public/cpp/interface_provider.h"
 | 
			
		||||
#include "shell/common/api/api.mojom.h"
 | 
			
		||||
#include "shell/common/gin_helper/microtasks_scope.h"
 | 
			
		||||
#include "shell/common/options_switches.h"
 | 
			
		||||
#include "shell/common/web_contents_utility.mojom.h"
 | 
			
		||||
#include "shell/common/world_ids.h"
 | 
			
		||||
#include "shell/renderer/renderer_client_base.h"
 | 
			
		||||
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3326,6 +3326,153 @@ describe('navigator.clipboard.write', () => {
 | 
			
		|||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('paste execCommand', () => {
 | 
			
		||||
  const readClipboard: any = (w: BrowserWindow) => {
 | 
			
		||||
    return w.webContents.executeJavaScript(`
 | 
			
		||||
      new Promise((resolve) => {
 | 
			
		||||
        const timeout = setTimeout(() => {
 | 
			
		||||
          resolve('');
 | 
			
		||||
        }, 2000);
 | 
			
		||||
        document.addEventListener('paste', (event) => {
 | 
			
		||||
          clearTimeout(timeout);
 | 
			
		||||
          event.preventDefault();
 | 
			
		||||
          let paste = event.clipboardData.getData("text");
 | 
			
		||||
          resolve(paste);
 | 
			
		||||
        });
 | 
			
		||||
        document.execCommand('paste');
 | 
			
		||||
      });
 | 
			
		||||
    `, true);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  let ses: Electron.Session;
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    ses = session.fromPartition(`paste-execCommand-${Math.random()}`);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  afterEach(() => {
 | 
			
		||||
    ses.setPermissionCheckHandler(null);
 | 
			
		||||
    closeAllWindows();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('is disabled by default', async () => {
 | 
			
		||||
    const w: BrowserWindow = new BrowserWindow({});
 | 
			
		||||
    await w.loadFile(path.join(fixturesPath, 'pages', 'blank.html'));
 | 
			
		||||
    const text = 'Sync Clipboard Disabled by default';
 | 
			
		||||
    clipboard.write({
 | 
			
		||||
      text
 | 
			
		||||
    });
 | 
			
		||||
    const paste = await readClipboard(w);
 | 
			
		||||
    expect(paste).to.be.empty();
 | 
			
		||||
    expect(clipboard.readText()).to.equal(text);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('does not execute with default permissions', async () => {
 | 
			
		||||
    const w: BrowserWindow = new BrowserWindow({
 | 
			
		||||
      webPreferences: {
 | 
			
		||||
        enableDeprecatedPaste: true,
 | 
			
		||||
        session: ses
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    await w.loadFile(path.join(fixturesPath, 'pages', 'blank.html'));
 | 
			
		||||
    const text = 'Sync Clipboard Disabled by default permissions';
 | 
			
		||||
    clipboard.write({
 | 
			
		||||
      text
 | 
			
		||||
    });
 | 
			
		||||
    const paste = await readClipboard(w);
 | 
			
		||||
    expect(paste).to.be.empty();
 | 
			
		||||
    expect(clipboard.readText()).to.equal(text);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('does not execute with permission denied', async () => {
 | 
			
		||||
    const w: BrowserWindow = new BrowserWindow({
 | 
			
		||||
      webPreferences: {
 | 
			
		||||
        enableDeprecatedPaste: true,
 | 
			
		||||
        session: ses
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    await w.loadFile(path.join(fixturesPath, 'pages', 'blank.html'));
 | 
			
		||||
    ses.setPermissionCheckHandler((webContents, permission) => {
 | 
			
		||||
      if (permission === 'deprecated-sync-clipboard-read') {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      return true;
 | 
			
		||||
    });
 | 
			
		||||
    const text = 'Sync Clipboard Disabled by permission denied';
 | 
			
		||||
    clipboard.write({
 | 
			
		||||
      text
 | 
			
		||||
    });
 | 
			
		||||
    const paste = await readClipboard(w);
 | 
			
		||||
    expect(paste).to.be.empty();
 | 
			
		||||
    expect(clipboard.readText()).to.equal(text);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('can trigger paste event when permission is granted', async () => {
 | 
			
		||||
    const w: BrowserWindow = new BrowserWindow({
 | 
			
		||||
      webPreferences: {
 | 
			
		||||
        enableDeprecatedPaste: true,
 | 
			
		||||
        session: ses
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    await w.loadFile(path.join(fixturesPath, 'pages', 'blank.html'));
 | 
			
		||||
    ses.setPermissionCheckHandler((webContents, permission) => {
 | 
			
		||||
      if (permission === 'deprecated-sync-clipboard-read') {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      return false;
 | 
			
		||||
    });
 | 
			
		||||
    const text = 'Sync Clipboard Test';
 | 
			
		||||
    clipboard.write({
 | 
			
		||||
      text
 | 
			
		||||
    });
 | 
			
		||||
    const paste = await readClipboard(w);
 | 
			
		||||
    expect(paste).to.equal(text);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('can trigger paste event when permission is granted for child windows', async () => {
 | 
			
		||||
    const w: BrowserWindow = new BrowserWindow({
 | 
			
		||||
      webPreferences: {
 | 
			
		||||
        session: ses
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    await w.loadFile(path.join(fixturesPath, 'pages', 'blank.html'));
 | 
			
		||||
    w.webContents.setWindowOpenHandler(details => {
 | 
			
		||||
      if (details.url === 'about:blank') {
 | 
			
		||||
        return {
 | 
			
		||||
          action: 'allow',
 | 
			
		||||
          overrideBrowserWindowOptions: {
 | 
			
		||||
            webPreferences: {
 | 
			
		||||
              enableDeprecatedPaste: true,
 | 
			
		||||
              session: ses
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        };
 | 
			
		||||
      } else {
 | 
			
		||||
        return {
 | 
			
		||||
          action: 'deny'
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    ses.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
 | 
			
		||||
      if (requestingOrigin === `${webContents?.opener?.origin}/` &&
 | 
			
		||||
          details.requestingUrl === 'about:blank' &&
 | 
			
		||||
          permission === 'deprecated-sync-clipboard-read') {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      return false;
 | 
			
		||||
    });
 | 
			
		||||
    const childPromise = once(w.webContents, 'did-create-window') as Promise<[BrowserWindow, Electron.DidCreateWindowDetails]>;
 | 
			
		||||
    w.webContents.executeJavaScript('window.open("about:blank")', true);
 | 
			
		||||
    const [childWindow] = await childPromise;
 | 
			
		||||
    expect(childWindow.webContents.opener).to.equal(w.webContents.mainFrame);
 | 
			
		||||
    const text = 'Sync Clipboard Test for Child Window';
 | 
			
		||||
    clipboard.write({
 | 
			
		||||
      text
 | 
			
		||||
    });
 | 
			
		||||
    const paste = await readClipboard(childWindow);
 | 
			
		||||
    expect(paste).to.equal(text);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
ifdescribe((process.platform !== 'linux' || app.isUnityRunning()))('navigator.setAppBadge/clearAppBadge', () => {
 | 
			
		||||
  let w: BrowserWindow;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue