浏览代码

feat: enhance allowlist configuration [TRI-027] (#11)

Lucas Nogueira 3 年之前
父节点
当前提交
d660cab38d

+ 5 - 0
.changes/allowlist-clipboard.md

@@ -0,0 +1,5 @@
+---
+"tauri-utils": patch
+---
+
+The `allowlist` configuration now includes a `clipboard` object, controlling the exposure of the `writeText` and `readText` APIs.

+ 6 - 0
.changes/allowlist-dialog.md

@@ -0,0 +1,6 @@
+---
+"tauri-utils": patch
+"tauri": patch
+---
+
+The dialog allowlist now includes flags for the `message`, `ask` and `confirm` APIs.

+ 5 - 0
.changes/allowlist-process.md

@@ -0,0 +1,5 @@
+---
+"tauri-utils": patch
+---
+
+The `allowlist` configuration now includes a `process` object, controlling the exposure of the `relaunch` and `exit` APIs.

+ 5 - 0
.changes/allowlist-window.md

@@ -0,0 +1,5 @@
+---
+tauri-utils: patch
+---
+
+The `window` allowlist now includes options to enable all window modification APIs: `center`, `close`, `create`, `hide`, `maximize`, `minimize`, `print`, `requestUserAttention`, `setAlwaysOnTop`, `setDecorations`, `setFocus`, `setFullscreen`, `setIcon`, `setMaxSize`, `setMinSize`, `setPosition`, `setResizable`, `setSize`, `setSkipTaskbar`, `setTitle`, `show`, `startDragging`, `unmaximize` and `unminimize`.

+ 230 - 2
core/tauri-utils/src/config.rs

@@ -680,6 +680,75 @@ pub struct WindowAllowlistConfig {
   /// Allows dynamic window creation.
   #[serde(default)]
   pub create: bool,
+  /// Allows centering the window.
+  #[serde(default)]
+  pub center: bool,
+  /// Allows requesting user attention on the window.
+  #[serde(default)]
+  pub request_user_attention: bool,
+  /// Allows setting the resizable flag of the window.
+  #[serde(default)]
+  pub set_resizable: bool,
+  /// Allows changing the window title.
+  #[serde(default)]
+  pub set_title: bool,
+  /// Allows maximizing the window.
+  #[serde(default)]
+  pub maximize: bool,
+  /// Allows unmaximizing the window.
+  #[serde(default)]
+  pub unmaximize: bool,
+  /// Allows minimizing the window.
+  #[serde(default)]
+  pub minimize: bool,
+  /// Allows unminimizing the window.
+  #[serde(default)]
+  pub unminimize: bool,
+  /// Allows showing the window.
+  #[serde(default)]
+  pub show: bool,
+  /// Allows hiding the window.
+  #[serde(default)]
+  pub hide: bool,
+  /// Allows closing the window.
+  #[serde(default)]
+  pub close: bool,
+  /// Allows setting the decorations flag of the window.
+  #[serde(default)]
+  pub set_decorations: bool,
+  /// Allows setting the always_on_top flag of the window.
+  #[serde(default)]
+  pub set_always_on_top: bool,
+  /// Allows setting the window size.
+  #[serde(default)]
+  pub set_size: bool,
+  /// Allows setting the window minimum size.
+  #[serde(default)]
+  pub set_min_size: bool,
+  /// Allows setting the window maximum size.
+  #[serde(default)]
+  pub set_max_size: bool,
+  /// Allows changing the position of the window.
+  #[serde(default)]
+  pub set_position: bool,
+  /// Allows setting the fullscreen flag of the window.
+  #[serde(default)]
+  pub set_fullscreen: bool,
+  /// Allows focusing the window.
+  #[serde(default)]
+  pub set_focus: bool,
+  /// Allows changing the window icon.
+  #[serde(default)]
+  pub set_icon: bool,
+  /// Allows setting the skip_taskbar flag of the window.
+  #[serde(default)]
+  pub set_skip_taskbar: bool,
+  /// Allows start dragging on the window.
+  #[serde(default)]
+  pub start_dragging: bool,
+  /// Allows opening the system dialog to print the window content.
+  #[serde(default)]
+  pub print: bool,
 }
 
 impl Allowlist for WindowAllowlistConfig {
@@ -687,6 +756,29 @@ impl Allowlist for WindowAllowlistConfig {
     let allowlist = Self {
       all: false,
       create: true,
+      center: true,
+      request_user_attention: true,
+      set_resizable: true,
+      set_title: true,
+      maximize: true,
+      unmaximize: true,
+      minimize: true,
+      unminimize: true,
+      show: true,
+      hide: true,
+      close: true,
+      set_decorations: true,
+      set_always_on_top: true,
+      set_size: true,
+      set_min_size: true,
+      set_max_size: true,
+      set_position: true,
+      set_fullscreen: true,
+      set_focus: true,
+      set_icon: true,
+      set_skip_taskbar: true,
+      start_dragging: true,
+      print: true,
     };
     let mut features = allowlist.to_features();
     features.push("window-all");
@@ -699,6 +791,39 @@ impl Allowlist for WindowAllowlistConfig {
     } else {
       let mut features = Vec::new();
       check_feature!(self, features, create, "window-create");
+      check_feature!(self, features, center, "window-center");
+      check_feature!(
+        self,
+        features,
+        request_user_attention,
+        "window-request-user-attention"
+      );
+      check_feature!(self, features, set_resizable, "window-set-resizable");
+      check_feature!(self, features, set_title, "window-set-title");
+      check_feature!(self, features, maximize, "window-maximize");
+      check_feature!(self, features, unmaximize, "window-unmaximize");
+      check_feature!(self, features, minimize, "window-minimize");
+      check_feature!(self, features, unminimize, "window-unminimize");
+      check_feature!(self, features, show, "window-show");
+      check_feature!(self, features, hide, "window-hide");
+      check_feature!(self, features, close, "window-close");
+      check_feature!(self, features, set_decorations, "window-set-decorations");
+      check_feature!(
+        self,
+        features,
+        set_always_on_top,
+        "window-set-always-on-top"
+      );
+      check_feature!(self, features, set_size, "window-set-size");
+      check_feature!(self, features, set_min_size, "window-set-min-size");
+      check_feature!(self, features, set_max_size, "window-set-max-size");
+      check_feature!(self, features, set_position, "window-set-position");
+      check_feature!(self, features, set_fullscreen, "window-set-fullscreen");
+      check_feature!(self, features, set_focus, "window-set-focus");
+      check_feature!(self, features, set_icon, "window-set-icon");
+      check_feature!(self, features, set_skip_taskbar, "window-set-skip-taskbar");
+      check_feature!(self, features, start_dragging, "window-start-dragging");
+      check_feature!(self, features, print, "window-print");
       features
     }
   }
@@ -752,12 +877,21 @@ pub struct DialogAllowlistConfig {
   /// Use this flag to enable all dialog API features.
   #[serde(default)]
   pub all: bool,
-  /// Open dialog window to pick files.
+  /// Allows the API to open a dialog window to pick files.
   #[serde(default)]
   pub open: bool,
-  /// Open dialog window to pick where to save files.
+  /// Allows the API to open a dialog window to pick where to save files.
   #[serde(default)]
   pub save: bool,
+  /// Allows the API to show a message dialog window.
+  #[serde(default)]
+  pub message: bool,
+  /// Allows the API to show a dialog window with Yes/No buttons.
+  #[serde(default)]
+  pub ask: bool,
+  /// Allows the API to show a dialog window with Ok/Cancel buttons.
+  #[serde(default)]
+  pub confirm: bool,
 }
 
 impl Allowlist for DialogAllowlistConfig {
@@ -766,6 +900,9 @@ impl Allowlist for DialogAllowlistConfig {
       all: false,
       open: true,
       save: true,
+      message: true,
+      ask: true,
+      confirm: true,
     };
     let mut features = allowlist.to_features();
     features.push("dialog-all");
@@ -779,6 +916,9 @@ impl Allowlist for DialogAllowlistConfig {
       let mut features = Vec::new();
       check_feature!(self, features, open, "dialog-open");
       check_feature!(self, features, save, "dialog-save");
+      check_feature!(self, features, message, "dialog-message");
+      check_feature!(self, features, ask, "dialog-ask");
+      check_feature!(self, features, confirm, "dialog-confirm");
       features
     }
   }
@@ -965,6 +1105,86 @@ impl Allowlist for ProtocolAllowlistConfig {
   }
 }
 
+/// Allowlist for the process APIs.
+#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[cfg_attr(feature = "schema", derive(JsonSchema))]
+#[serde(rename_all = "camelCase", deny_unknown_fields)]
+pub struct ProcessAllowlistConfig {
+  /// Use this flag to enable all process APIs.
+  #[serde(default)]
+  pub all: bool,
+  /// Enables the relaunch API.
+  #[serde(default)]
+  pub relaunch: bool,
+  /// Enables the exit API.
+  #[serde(default)]
+  pub exit: bool,
+}
+
+impl Allowlist for ProcessAllowlistConfig {
+  fn all_features() -> Vec<&'static str> {
+    let allowlist = Self {
+      all: false,
+      relaunch: true,
+      exit: true,
+    };
+    let mut features = allowlist.to_features();
+    features.push("process-all");
+    features
+  }
+
+  fn to_features(&self) -> Vec<&'static str> {
+    if self.all {
+      vec!["process-all"]
+    } else {
+      let mut features = Vec::new();
+      check_feature!(self, features, relaunch, "process-relaunch");
+      check_feature!(self, features, exit, "process-exit");
+      features
+    }
+  }
+}
+
+/// Allowlist for the clipboard APIs.
+#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
+#[cfg_attr(feature = "schema", derive(JsonSchema))]
+#[serde(rename_all = "camelCase", deny_unknown_fields)]
+pub struct ClipboardAllowlistConfig {
+  /// Use this flag to enable all clipboard APIs.
+  #[serde(default)]
+  pub all: bool,
+  /// Enables the clipboard's `writeText` API.
+  #[serde(default)]
+  pub write_text: bool,
+  /// Enables the clipboard's `readText` API.
+  #[serde(default)]
+  pub read_text: bool,
+}
+
+impl Allowlist for ClipboardAllowlistConfig {
+  fn all_features() -> Vec<&'static str> {
+    let allowlist = Self {
+      all: false,
+      write_text: true,
+      read_text: true,
+    };
+    let mut features = allowlist.to_features();
+    features.push("clipboard-all");
+    features
+  }
+
+  fn to_features(&self) -> Vec<&'static str> {
+    if self.all {
+      vec!["clipboard-all"]
+    } else {
+      let mut features = Vec::new();
+      check_feature!(self, features, write_text, "clipboard-write-text");
+      check_feature!(self, features, read_text, "clipboard-read-text");
+      features
+    }
+  }
+}
+
 /// Allowlist configuration.
 #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
 #[cfg_attr(feature = "schema", derive(JsonSchema))]
@@ -1003,6 +1223,12 @@ pub struct AllowlistConfig {
   /// Custom protocol allowlist.
   #[serde(default)]
   pub protocol: ProtocolAllowlistConfig,
+  /// Process API allowlist.
+  #[serde(default)]
+  pub process: ProcessAllowlistConfig,
+  /// Clipboard APIs allowlist.
+  #[serde(default)]
+  pub clipboard: ClipboardAllowlistConfig,
 }
 
 impl Allowlist for AllowlistConfig {
@@ -1018,6 +1244,8 @@ impl Allowlist for AllowlistConfig {
     features.extend(OsAllowlistConfig::all_features());
     features.extend(PathAllowlistConfig::all_features());
     features.extend(ProtocolAllowlistConfig::all_features());
+    features.extend(ProcessAllowlistConfig::all_features());
+    features.extend(ClipboardAllowlistConfig::all_features());
     features
   }
 

+ 125 - 53
core/tauri/Cargo.toml

@@ -1,11 +1,6 @@
 [package]
-name = "tauri"
-version = "1.0.0-beta.8"
-authors = [ "Tauri Programme within The Commons Conservancy" ]
-categories = [ "gui", "web-programming" ]
-license = "Apache-2.0 OR MIT"
-homepage = "https://tauri.studio"
-repository = "https://github.com/tauri-apps/tauri"
+authors = ["Tauri Programme within The Commons Conservancy"]
+categories = ["gui", "web-programming"]
 description = "Make tiny, secure apps for all desktop platforms with Tauri"
 edition = "2021"
 rust-version = "1.56"
@@ -14,9 +9,14 @@ exclude = [
   "/.scripts",
   ".license_template",
   "CHANGELOG.md",
-  "/target"
+  "/target",
 ]
+homepage = "https://tauri.studio"
+license = "Apache-2.0 OR MIT"
+name = "tauri"
 readme = "README.md"
+repository = "https://github.com/tauri-apps/tauri"
+version = "1.0.0-beta.8"
 
 [package.metadata.docs.rs]
 default-features = false
@@ -26,11 +26,11 @@ default-target = "x86_64-unknown-linux-gnu"
 targets = [
   "x86_64-pc-windows-msvc",
   "x86_64-unknown-linux-gnu",
-  "x86_64-apple-darwin"
+  "x86_64-apple-darwin",
 ]
 
 [package.metadata.cargo-udeps.ignore]
-normal = [ "attohttpc" ]
+normal = ["attohttpc"]
 
 [dependencies]
 serde_json = { version = "1.0", features = [ "raw_value" ] }
@@ -46,16 +46,16 @@ tauri-macros = { version = "1.0.0-beta.5", path = "../tauri-macros" }
 tauri-utils = { version = "1.0.0-beta.3", path = "../tauri-utils" }
 tauri-runtime-wry = { version = "0.2.1", path = "../tauri-runtime-wry", optional = true }
 rand = "0.8"
-tempfile = "3"
 semver = "1.0"
 serde_repr = "0.1"
+state = "0.5"
+tar = "0.4"
+tempfile = "3"
 zip = "0.5"
 ignore = "0.4"
 either = "1.6"
-tar = "0.4"
 flate2 = "1.0"
 http = "0.2"
-state = "0.5"
 bincode = "1.3"
 dirs-next = "2.0"
 percent-encoding = "2.1"
@@ -78,8 +78,8 @@ regex = "1.5"
 glob = "0.3"
 
 [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
-gtk = { version = "0.14", features = [ "v3_20" ] }
 glib = "0.14"
+gtk = {version = "0.14", features = ["v3_20"]}
 
 [target."cfg(target_os = \"macos\")".dependencies]
 embed_plist = "1.2"
@@ -88,15 +88,15 @@ embed_plist = "1.2"
 cfg_aliases = "0.1.1"
 
 [dev-dependencies]
+mockito = "0.30"
 proptest = "1.0.0"
-serde_json = "1.0"
-tauri = { path = "." }
-serde = { version = "1.0", features = [ "derive" ] }
 quickcheck = "1.0.3"
 quickcheck_macros = "1.0.0"
+serde = {version = "1.0", features = ["derive"]}
+serde_json = "1.0"
+tauri = {path = "."}
 tokio-test = "0.4.2"
 tokio = { version = "1.15", features = [ "full" ] }
-mockito = "0.30"
 
 [features]
 default = [ "wry", "compression" ]
@@ -106,46 +106,118 @@ wry = [ "tauri-runtime-wry" ]
 cli = [ "clap" ]
 custom-protocol = [ "tauri-macros/custom-protocol" ]
 api-all = [
-  "notification-all",
+  "clipboard-all",
+  "dialog-all",
+  "fs-all",
   "global-shortcut-all",
-  "shell-all",
+  "http-all",
+  "notification-all",
   "os-all",
-  "dialog-all",
-  "updater",
   "path-all",
-  "protocol-all"
+  "process-all",
+  "protocol-all",
+  "shell-all",
+  "window-all"
+]
+macos-private-api = ["tauri-runtime/macos-private-api", "tauri-runtime-wry/macos-private-api"]
+clipboard-all = ["clipboard-write-text", "clipboard-read-text"]
+clipboard-read-text = []
+clipboard-write-text = []
+dialog-all = ["dialog-open", "dialog-save", "dialog-message", "dialog-ask"]
+dialog-ask = []
+dialog-confirm = []
+dialog-message = []
+dialog-open = []
+dialog-save = []
+fs-all = [
+  "fs-copy-file",
+  "fs-create-dir",
+  "fs-read-binary-file",
+  "fs-read-dir",
+  "fs-read-text-file",
+  "fs-remove-dir",
+  "fs-remove-file",
+  "fs-rename-file",
+  "fs-write-binary-file",
+  "fs-write-file"
+]
+fs-copy-file = []
+fs-create-dir = []
+fs-read-binary-file = []
+fs-read-dir = []
+fs-read-text-file = []
+fs-remove-dir = []
+fs-remove-file = []
+fs-rename-file = []
+fs-write-binary-file = ["base64"]
+fs-write-file = []
+global-shortcut-all = []
+http-all = ["http-request"]
+http-request = []
+notification-all = ["notify-rust", "dialog-ask"]
+os-all = ["os_info"]
+path-all = []
+process-all = ["process-relaunch", "process-exit"]
+process-exit = []
+process-relaunch = []
+protocol-all = ["protocol-asset"]
+protocol-asset = []
+reqwest-client = ["reqwest", "bytes"]
+shell-all = ["shell-execute", "shell-open"]
+shell-execute = ["shared_child", "os_pipe"]
+shell-open = ["open"]
+system-tray = ["tauri-runtime/system-tray", "tauri-runtime-wry/system-tray"]
+updater = ["minisign-verify", "base64", "dialog-ask"]
+window-all = [
+  "window-create",
+  "window-center",
+  "window-request-user-attention",
+  "window-set-resizable",
+  "window-set-title",
+  "window-maximize",
+  "window-unmaximize",
+  "window-minimize",
+  "window-unminimize",
+  "window-show",
+  "window-hide",
+  "window-close",
+  "window-set-decorations",
+  "window-set-always-on-top",
+  "window-set-size",
+  "window-set-min-size",
+  "window-set-max-size",
+  "window-set-position",
+  "window-set-fullscreen",
+  "window-set-focus",
+  "window-set-icon",
+  "window-set-skip-taskbar",
+  "window-start-dragging",
+  "window-print",
 ]
-updater = [ "minisign-verify", "base64" ]
-system-tray = [ "tauri-runtime/system-tray", "tauri-runtime-wry/system-tray" ]
-macos-private-api = [ "tauri-runtime/macos-private-api", "tauri-runtime-wry/macos-private-api" ]
-reqwest-client = [ "reqwest", "bytes" ]
-fs-all = [ "fs-write-binary-file" ]
-fs-read-text-file = [ ]
-fs-read-binary-file = [ ]
-fs-write-file = [ ]
-fs-write-binary-file = [ "base64" ]
-fs-read-dir = [ ]
-fs-copy-file = [ ]
-fs-create-dir = [ ]
-fs-remove-dir = [ ]
-fs-remove-file = [ ]
-fs-rename-file = [ ]
-path-all = [ ]
-window-all = [ ]
 window-create = [ ]
-shell-all = [ "shell-open", "shell-execute" ]
-shell-execute = [ "shared_child", "os_pipe" ]
-shell-open = [ "open" ]
-dialog-all = [ "dialog-open", "dialog-save" ]
-dialog-open = [ ]
-dialog-save = [ ]
-http-all = [ ]
-http-request = [ ]
-notification-all = [ "notify-rust" ]
-global-shortcut-all = [ ]
-os-all = [ "os_info" ]
-protocol-all = [ "protocol-asset" ]
-protocol-asset = [ ]
+window-center = [ ]
+window-request-user-attention = [ ]
+window-set-resizable = [ ]
+window-set-title = [ ]
+window-maximize = [ ]
+window-unmaximize = [ ]
+window-minimize = [ ]
+window-unminimize = [ ]
+window-show = [ ]
+window-hide = [ ]
+window-close = [ ]
+window-set-decorations = [ ]
+window-set-always-on-top = [ ]
+window-set-size = [ ]
+window-set-min-size = [ ]
+window-set-max-size = [ ]
+window-set-position = [ ]
+window-set-fullscreen = [ ]
+window-set-focus = [ ]
+window-set-icon = [ ]
+window-set-skip-taskbar = [ ]
+window-start-dragging = [ ]
+window-print = [ ]
 egui = ["epi", "tauri-runtime-wry/egui"]
 
 [[example]]

+ 34 - 0
core/tauri/build.rs

@@ -27,6 +27,27 @@ fn main() {
     // window
     window_all: { any(api_all, feature = "window-all") },
     window_create: { any(window_all, feature = "window-create") },
+    window_center: { any(window_all, feature = "window-center") },
+    window_request_user_attention: { any(window_all, feature = "window-request-user-attention") },
+    window_set_resizable: { any(window_all, feature = "window-set-resizable") },
+    window_set_title: { any(window_all, feature = "window-set-title") },
+    window_maximize: { any(window_all, feature = "window-maximize") },
+    window_unmaximize: { any(window_all, feature = "window-unmaximize") },
+    window_show: { any(window_all, feature = "window-show") },
+    window_hide: { any(window_all, feature = "window-hide") },
+    window_close: { any(window_all, feature = "window-close") },
+    window_set_decorations: { any(window_all, feature = "window-set-decorations") },
+    window_set_always_on_top: { any(window_all, feature = "window-set-always-on-top") },
+    window_set_size: { any(window_all, feature = "window-set-size") },
+    window_set_min_size: { any(window_all, feature = "window-set-min-size") },
+    window_set_max_size: { any(window_all, feature = "window-set-max-size") },
+    window_set_position: { any(window_all, feature = "window-set-position") },
+    window_set_fullscreen: { any(window_all, feature = "window-set-fullscreen") },
+    window_set_focus: { any(window_all, feature = "window-set-focus") },
+    window_set_icon: { any(window_all, feature = "window-set-icon") },
+    window_set_skip_taskbar: { any(window_all, feature = "window-set-skip-taskbar") },
+    window_start_dragging: { any(window_all, feature = "window-start-dragging") },
+    window_print: { any(window_all, feature = "window-print") },
 
     // shell
     shell_all: { any(api_all, feature = "shell-all") },
@@ -37,6 +58,9 @@ fn main() {
     dialog_all: { any(api_all, feature = "dialog-all") },
     dialog_open: { any(dialog_all, feature = "dialog-open") },
     dialog_save: { any(dialog_all, feature = "dialog-save") },
+    dialog_message: { any(dialog_all, feature = "dialog-message") },
+    dialog_ask: { any(dialog_all, feature = "dialog-ask") },
+    dialog_confirm: { any(dialog_all, feature = "dialog-confirm") },
 
     // http
     http_all: { any(api_all, feature = "http-all") },
@@ -60,5 +84,15 @@ fn main() {
     // protocol
     protocol_all: { any(api_all, feature = "protocol-all") },
     protocol_asset: { any(protocol_all, feature = "protocol-asset") },
+
+    // process
+    process_all: { any(api_all, feature = "process-all") },
+    process_relaunch: { any(protocol_all, feature = "process-relaunch") },
+    process_exit: { any(protocol_all, feature = "process-exit") },
+
+    // clipboard
+    clipboard_all: { any(api_all, feature = "clipboard-all") },
+    clipboard_write_text: { any(protocol_all, feature = "clipboard-write-text") },
+    clipboard_read_text: { any(protocol_all, feature = "clipboard-read-text") },
   }
 }

+ 23 - 7
core/tauri/src/endpoints/clipboard.rs

@@ -3,10 +3,9 @@
 // SPDX-License-Identifier: MIT
 
 use super::InvokeResponse;
-use crate::{
-  runtime::{ClipboardManager, Runtime},
-  window::Window,
-};
+#[cfg(any(clipboard_write_text, clipboard_read_text))]
+use crate::runtime::ClipboardManager;
+use crate::{runtime::Runtime, window::Window};
 use serde::Deserialize;
 
 /// The API descriptor.
@@ -20,11 +19,28 @@ pub enum Cmd {
 }
 
 impl Cmd {
+  #[allow(unused_variables)]
   pub fn run<R: Runtime>(self, window: Window<R>) -> crate::Result<InvokeResponse> {
-    let mut clipboard = window.app_handle.clipboard_manager();
     match self {
-      Self::WriteText(text) => Ok(clipboard.write_text(text)?.into()),
-      Self::ReadText => Ok(clipboard.read_text()?.into()),
+      #[cfg(clipboard_write_text)]
+      Self::WriteText(text) => Ok(
+        window
+          .app_handle
+          .clipboard_manager()
+          .write_text(text)?
+          .into(),
+      ),
+      #[cfg(not(clipboard_write_text))]
+      Self::WriteText(_) => Err(crate::Error::ApiNotAllowlisted(
+        "clipboard > readText".to_string(),
+      )),
+
+      #[cfg(clipboard_read_text)]
+      Self::ReadText => Ok(window.app_handle.clipboard_manager().read_text()?.into()),
+      #[cfg(not(clipboard_read_text))]
+      Self::ReadText => Err(crate::Error::ApiNotAllowlisted(
+        "clipboard > writeText".to_string(),
+      )),
     }
   }
 }

+ 32 - 37
core/tauri/src/endpoints/dialog.rs

@@ -5,14 +5,12 @@
 use super::InvokeResponse;
 #[cfg(any(dialog_open, dialog_save))]
 use crate::api::dialog::FileDialogBuilder;
-use crate::{
-  api::dialog::{ask as ask_dialog, confirm as confirm_dialog, message as message_dialog},
-  runtime::Runtime,
-  Window,
-};
+use crate::{runtime::Runtime, Window};
 use serde::Deserialize;
 
-use std::{path::PathBuf, sync::mpsc::channel};
+use std::path::PathBuf;
+#[cfg(any(dialog_message, dialog_ask, dialog_confirm))]
+use std::sync::mpsc::channel;
 
 #[allow(dead_code)]
 #[derive(Deserialize)]
@@ -90,31 +88,50 @@ impl Cmd {
       #[cfg(not(dialog_save))]
       Self::SaveDialog { .. } => Err(crate::Error::ApiNotAllowlisted("dialog > save".to_string())),
 
+      #[cfg(dialog_message)]
       Self::MessageDialog { message } => {
         let exe = std::env::current_exe()?;
-        message_dialog(
+        crate::api::dialog::message(
           Some(&window),
           &window.app_handle.package_info().name,
           message,
         );
         Ok(().into())
       }
+      #[cfg(not(dialog_message))]
+      Self::MessageDialog { .. } => Err(crate::Error::ApiNotAllowlisted(
+        "dialog > message".to_string(),
+      )),
+
+      #[cfg(dialog_ask)]
       Self::AskDialog { title, message } => {
-        let answer = ask(
-          &window,
+        let (tx, rx) = channel();
+        crate::api::dialog::ask(
+          Some(&window),
           title.unwrap_or_else(|| window.app_handle.package_info().name.clone()),
           message,
-        )?;
-        Ok(answer)
+          move |m| tx.send(m).unwrap(),
+        );
+        Ok(rx.recv().unwrap().into())
       }
+      #[cfg(not(dialog_ask))]
+      Self::AskDialog { .. } => Err(crate::Error::ApiNotAllowlisted("dialog > ask".to_string())),
+
+      #[cfg(dialog_confirm)]
       Self::ConfirmDialog { title, message } => {
-        let answer = confirm(
-          &window,
+        let (tx, rx) = channel();
+        crate::api::dialog::confirm(
+          Some(&window),
           title.unwrap_or_else(|| window.app_handle.package_info().name.clone()),
           message,
-        )?;
-        Ok(answer)
+          move |m| tx.send(m).unwrap(),
+        );
+        Ok(rx.recv().unwrap().into())
       }
+      #[cfg(not(dialog_confirm))]
+      Self::ConfirmDialog { .. } => Err(crate::Error::ApiNotAllowlisted(
+        "dialog > confirm".to_string(),
+      )),
     }
   }
 }
@@ -193,25 +210,3 @@ pub fn save<R: Runtime>(
   dialog_builder.save_file(move |p| tx.send(p).unwrap());
   Ok(rx.recv().unwrap().into())
 }
-
-/// Shows a dialog with a yes/no question.
-pub fn ask<R: Runtime>(
-  window: &Window<R>,
-  title: String,
-  message: String,
-) -> crate::Result<InvokeResponse> {
-  let (tx, rx) = channel();
-  ask_dialog(Some(window), title, message, move |m| tx.send(m).unwrap());
-  Ok(rx.recv().unwrap().into())
-}
-
-/// Shows a dialog with a ok/cancel message.
-pub fn confirm<R: Runtime>(
-  window: &Window<R>,
-  title: String,
-  message: String,
-) -> crate::Result<InvokeResponse> {
-  let (tx, rx) = channel();
-  confirm_dialog(Some(window), title, message, move |m| tx.send(m).unwrap());
-  Ok(rx.recv().unwrap().into())
-}

+ 18 - 3
core/tauri/src/endpoints/http.rs

@@ -4,19 +4,22 @@
 
 use super::InvokeResponse;
 
-use crate::api::http::{Client, ClientBuilder, HttpRequestBuilder};
-use once_cell::sync::Lazy;
+use crate::api::http::{ClientBuilder, HttpRequestBuilder};
 use serde::Deserialize;
 
+#[cfg(http_request)]
 use std::{
   collections::HashMap,
   sync::{Arc, Mutex},
 };
 
 type ClientId = u32;
-type ClientStore = Arc<Mutex<HashMap<ClientId, Client>>>;
+#[cfg(http_request)]
+type ClientStore = Arc<Mutex<HashMap<ClientId, crate::api::http::Client>>>;
 
+#[cfg(http_request)]
 fn clients() -> &'static ClientStore {
+  use once_cell::sync::Lazy;
   static STORE: Lazy<ClientStore> = Lazy::new(Default::default);
   &STORE
 }
@@ -39,6 +42,7 @@ pub enum Cmd {
 impl Cmd {
   pub async fn run(self) -> crate::Result<InvokeResponse> {
     match self {
+      #[cfg(http_request)]
       Self::CreateClient { options } => {
         let client = options.unwrap_or_default().build()?;
         let mut store = clients().lock().unwrap();
@@ -46,11 +50,22 @@ impl Cmd {
         store.insert(id, client);
         Ok(InvokeResponse::from(id))
       }
+      #[cfg(not(http_request))]
+      Self::CreateClient { .. } => Err(crate::Error::ApiNotAllowlisted(
+        "http > request".to_string(),
+      )),
+
+      #[cfg(http_request)]
       Self::DropClient { client } => {
         let mut store = clients().lock().unwrap();
         store.remove(&client);
         Ok(().into())
       }
+      #[cfg(not(http_request))]
+      Self::DropClient { .. } => Err(crate::Error::ApiNotAllowlisted(
+        "http > request".to_string(),
+      )),
+
       #[cfg(http_request)]
       Self::HttpRequest { client, options } => {
         return make_request(client, *options).await.map(Into::into);

+ 17 - 5
core/tauri/src/endpoints/process.rs

@@ -2,10 +2,10 @@
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-License-Identifier: MIT
 
-use std::process::exit;
-
 use super::InvokeResponse;
-use crate::{api::process::restart, Manager, Runtime, Window};
+#[cfg(process_relaunch)]
+use crate::Manager;
+use crate::{Runtime, Window};
 use serde::Deserialize;
 
 /// The API descriptor.
@@ -20,18 +20,30 @@ pub enum Cmd {
 }
 
 impl Cmd {
+  #[allow(unused_variables)]
   pub fn run<R: Runtime>(self, window: Window<R>) -> crate::Result<InvokeResponse> {
     match self {
+      #[cfg(process_relaunch)]
       Self::Relaunch => Ok({
-        restart(&window.state());
+        crate::api::process::restart(&window.state());
         ().into()
       }),
+      #[cfg(not(process_relaunch))]
+      Self::Relaunch => Err(crate::Error::ApiNotAllowlisted(
+        "process > relaunch".to_string(),
+      )),
+
+      #[cfg(process_exit)]
       Self::Exit { exit_code } => {
         // would be great if we can have a handler inside tauri
         // who close all window and emit an event that user can catch
         // if they want to process something before closing the app
-        exit(exit_code);
+        std::process::exit(exit_code);
       }
+      #[cfg(not(process_exit))]
+      Self::Exit { .. } => Err(crate::Error::ApiNotAllowlisted(
+        "process > exit".to_string(),
+      )),
     }
   }
 }

+ 74 - 0
core/tauri/src/endpoints/window.rs

@@ -85,6 +85,52 @@ pub enum WindowManagerCmd {
   InternalToggleMaximize,
 }
 
+impl WindowManagerCmd {
+  fn into_allowlist_error(self) -> crate::Error {
+    match self {
+      Self::Center => crate::Error::ApiNotAllowlisted("window > center".to_string()),
+      Self::RequestUserAttention(_) => {
+        crate::Error::ApiNotAllowlisted("window > requestUserAttention".to_string())
+      }
+      Self::SetResizable(_) => crate::Error::ApiNotAllowlisted("window > setResizable".to_string()),
+      Self::SetTitle(_) => crate::Error::ApiNotAllowlisted("window > setTitle".to_string()),
+      Self::Maximize => crate::Error::ApiNotAllowlisted("window > maximize".to_string()),
+      Self::Unmaximize => crate::Error::ApiNotAllowlisted("window > unmaximize".to_string()),
+      Self::ToggleMaximize => {
+        crate::Error::ApiNotAllowlisted("window > maximize and window > unmaximize".to_string())
+      }
+      Self::Minimize => crate::Error::ApiNotAllowlisted("window > minimize".to_string()),
+      Self::Unminimize => crate::Error::ApiNotAllowlisted("window > unminimize".to_string()),
+      Self::Show => crate::Error::ApiNotAllowlisted("window > show".to_string()),
+      Self::Hide => crate::Error::ApiNotAllowlisted("window > hide".to_string()),
+      Self::Close => crate::Error::ApiNotAllowlisted("window > close".to_string()),
+      Self::SetDecorations(_) => {
+        crate::Error::ApiNotAllowlisted("window > setDecorations".to_string())
+      }
+      Self::SetAlwaysOnTop(_) => {
+        crate::Error::ApiNotAllowlisted("window > setAlwaysOnTop".to_string())
+      }
+      Self::SetSize(_) => crate::Error::ApiNotAllowlisted("window > setSize".to_string()),
+      Self::SetMinSize(_) => crate::Error::ApiNotAllowlisted("window > setMinSize".to_string()),
+      Self::SetMaxSize(_) => crate::Error::ApiNotAllowlisted("window > setMaxSize".to_string()),
+      Self::SetPosition(_) => crate::Error::ApiNotAllowlisted("window > setPosition".to_string()),
+      Self::SetFullscreen(_) => {
+        crate::Error::ApiNotAllowlisted("window > setFullscreen".to_string())
+      }
+      Self::SetIcon { .. } => crate::Error::ApiNotAllowlisted("window > setIcon".to_string()),
+      Self::SetSkipTaskbar(_) => {
+        crate::Error::ApiNotAllowlisted("window > setSkipTaskbar".to_string())
+      }
+      Self::StartDragging => crate::Error::ApiNotAllowlisted("window > startDragging".to_string()),
+      Self::Print => crate::Error::ApiNotAllowlisted("window > print".to_string()),
+      Self::InternalToggleMaximize => {
+        crate::Error::ApiNotAllowlisted("window > maximize and window > unmaximize".to_string())
+      }
+      _ => crate::Error::ApiNotAllowlisted("window > all".to_string()),
+    }
+  }
+}
+
 /// The API descriptor.
 #[derive(Deserialize)]
 #[serde(tag = "cmd", content = "data", rename_all = "camelCase")]
@@ -150,38 +196,63 @@ impl Cmd {
           WindowManagerCmd::PrimaryMonitor => return Ok(window.primary_monitor()?.into()),
           WindowManagerCmd::AvailableMonitors => return Ok(window.available_monitors()?.into()),
           // Setters
+          #[cfg(window_center)]
           WindowManagerCmd::Center => window.center()?,
+          #[cfg(window_request_user_attention)]
           WindowManagerCmd::RequestUserAttention(request_type) => {
             window.request_user_attention(request_type)?
           }
+          #[cfg(window_set_resizable)]
           WindowManagerCmd::SetResizable(resizable) => window.set_resizable(resizable)?,
+          #[cfg(window_set_title)]
           WindowManagerCmd::SetTitle(title) => window.set_title(&title)?,
+          #[cfg(window_maximize)]
           WindowManagerCmd::Maximize => window.maximize()?,
+          #[cfg(window_unmaximize)]
           WindowManagerCmd::Unmaximize => window.unmaximize()?,
+          #[cfg(all(window_maximize, window_unmaximize))]
           WindowManagerCmd::ToggleMaximize => match window.is_maximized()? {
             true => window.unmaximize()?,
             false => window.maximize()?,
           },
+          #[cfg(window_minimize)]
           WindowManagerCmd::Minimize => window.minimize()?,
+          #[cfg(window_unminimize)]
           WindowManagerCmd::Unminimize => window.unminimize()?,
+          #[cfg(window_show)]
           WindowManagerCmd::Show => window.show()?,
+          #[cfg(window_hide)]
           WindowManagerCmd::Hide => window.hide()?,
+          #[cfg(window_close)]
           WindowManagerCmd::Close => window.close()?,
+          #[cfg(window_set_decorations)]
           WindowManagerCmd::SetDecorations(decorations) => window.set_decorations(decorations)?,
+          #[cfg(window_set_always_on_top)]
           WindowManagerCmd::SetAlwaysOnTop(always_on_top) => {
             window.set_always_on_top(always_on_top)?
           }
+          #[cfg(window_set_size)]
           WindowManagerCmd::SetSize(size) => window.set_size(size)?,
+          #[cfg(window_set_min_size)]
           WindowManagerCmd::SetMinSize(size) => window.set_min_size(size)?,
+          #[cfg(window_set_max_size)]
           WindowManagerCmd::SetMaxSize(size) => window.set_max_size(size)?,
+          #[cfg(window_set_position)]
           WindowManagerCmd::SetPosition(position) => window.set_position(position)?,
+          #[cfg(window_set_fullscreen)]
           WindowManagerCmd::SetFullscreen(fullscreen) => window.set_fullscreen(fullscreen)?,
+          #[cfg(window_set_focus)]
           WindowManagerCmd::SetFocus => window.set_focus()?,
+          #[cfg(window_set_icon)]
           WindowManagerCmd::SetIcon { icon } => window.set_icon(icon.into())?,
+          #[cfg(window_set_skip_taskbar)]
           WindowManagerCmd::SetSkipTaskbar(skip) => window.set_skip_taskbar(skip)?,
+          #[cfg(window_start_dragging)]
           WindowManagerCmd::StartDragging => window.start_dragging()?,
+          #[cfg(window_print)]
           WindowManagerCmd::Print => window.print()?,
           // internals
+          #[cfg(all(window_maximize, window_unmaximize))]
           WindowManagerCmd::InternalToggleMaximize => {
             if window.is_resizable()? {
               match window.is_maximized()? {
@@ -190,9 +261,12 @@ impl Cmd {
               }
             }
           }
+          _ => return Err(cmd.into_allowlist_error()),
         }
       }
     }
+
+    #[allow(unreachable_code)]
     Ok(().into())
   }
 }

+ 8 - 10
core/tauri/src/manager.rs

@@ -34,8 +34,6 @@ use crate::{runtime::menu::Menu, MenuEvent};
 use regex::{Captures, Regex};
 use serde::Serialize;
 use serde_json::Value as JsonValue;
-#[cfg(protocol_asset)]
-use std::io::SeekFrom;
 use std::{
   borrow::Cow,
   collections::{HashMap, HashSet},
@@ -44,16 +42,10 @@ use std::{
   sync::{Arc, Mutex, MutexGuard},
 };
 use tauri_macros::default_runtime;
-#[cfg(protocol_asset)]
-use tauri_runtime::http::HttpRange;
 use tauri_utils::{
   assets::{AssetKey, CspHash},
   html::{CSP_TOKEN, INVOKE_KEY_TOKEN, SCRIPT_NONCE_TOKEN, STYLE_NONCE_TOKEN},
 };
-#[cfg(protocol_asset)]
-use tokio::io::{AsyncReadExt, AsyncSeekExt};
-#[cfg(protocol_asset)]
-use url::Position;
 use url::Url;
 
 const WINDOW_RESIZED_EVENT: &str = "tauri://resize";
@@ -369,6 +361,8 @@ impl<R: Runtime> WindowManager<R> {
 
     #[cfg(protocol_asset)]
     if !registered_scheme_protocols.contains(&"asset".into()) {
+      use tokio::io::{AsyncReadExt, AsyncSeekExt};
+      use url::Position;
       let asset_scope = self.state().get::<crate::Scopes>().asset_protocol.clone();
       let window_url = Url::parse(&pending.url).unwrap();
       let window_origin =
@@ -419,7 +413,8 @@ impl<R: Runtime> WindowManager<R> {
             // Get the file size
             let file_size = file.metadata().await.unwrap().len();
             // parse the range
-            let range = HttpRange::parse(range.to_str().unwrap(), file_size).unwrap();
+            let range =
+              crate::runtime::http::HttpRange::parse(range.to_str().unwrap(), file_size).unwrap();
 
             // FIXME: Support multiple ranges
             // let support only 1 range for now
@@ -448,7 +443,10 @@ impl<R: Runtime> WindowManager<R> {
                 format!("bytes {}-{}/{}", range.start, last_byte, file_size),
               );
 
-              file.seek(SeekFrom::Start(range.start)).await.unwrap();
+              file
+                .seek(std::io::SeekFrom::Start(range.start))
+                .await
+                .unwrap();
               file.take(real_length).read_to_end(&mut buf).await.unwrap();
             }
 

+ 37 - 0
docs/api/config.md

@@ -220,6 +220,29 @@ In addition to the JSON defined on the `tauri.conf.json` file, Tauri reads a pla
         property: "window", optional: true, type: "object", child: <Properties anchorRoot="tauri.allowlist.window" rows={[
           { property: "all", type: "boolean", description: `Use this flag to enable all window API features.` },
           { property: "create", optional: true, type: "boolean", description: `Allows dynamic window creation.` },
+          { property: "center", optional: true, type: "boolean", description: `Allows centering the window.` },
+          { property: "requestUserAttention", optional: true, type: "boolean", description: `Allows requesting user attention on the window.` },
+          { property: "setResizable", optional: true, type: "boolean", description: `Allows setting the resizable flag of the window.` },
+          { property: "setTitle", optional: true, type: "boolean", description: `Allows changing the window title.` },
+          { property: "maximize", optional: true, type: "boolean", description: `Allows maximizing the window.` },
+          { property: "unmaximize", optional: true, type: "boolean", description: `Allows unmaximizing the window.` },
+          { property: "minimize", optional: true, type: "boolean", description: `Allows minimizing the window.` },
+          { property: "unminimize", optional: true, type: "boolean", description: `Allows unminimizing the window.` },
+          { property: "show", optional: true, type: "boolean", description: `Allows showing the window.` },
+          { property: "hide", optional: true, type: "boolean", description: `Allows hiding the window.` },
+          { property: "close", optional: true, type: "boolean", description: `Allows closing the window.` },
+          { property: "setDecorations", optional: true, type: "boolean", description: `Allows setting the decorations flag of the window.` },
+          { property: "setAlwaysOnTop", optional: true, type: "boolean", description: `Allows setting the always_on_top flag of the window.` },
+          { property: "setSize", optional: true, type: "boolean", description: `Allows setting the window size.` },
+          { property: "setMinSize", optional: true, type: "boolean", description: `Allows setting the window minimum size.` },
+          { property: "setMaxSize", optional: true, type: "boolean", description: `Allows setting the window maximum size.` },
+          { property: "setPosition", optional: true, type: "boolean", description: `Allows changing the position of the window.` },
+          { property: "setFullscreen", optional: true, type: "boolean", description: `Allows setting the fullscreen flag of the window.` },
+          { property: "setFocus", optional: true, type: "boolean", description: `Allows focusing the window.` },
+          { property: "setIcon", optional: true, type: "boolean", description: `Allows changing the window icon.` },
+          { property: "setSkipTaskbar", optional: true, type: "boolean", description: `Allows setting the skip_taskbar flag of the window.` },
+          { property: "startDragging", optional: true, type: "boolean", description: `Allows start dragging on the window.` },
+          { property: "print", optional: true, type: "boolean", description: `Allows opening the system dialog to print the window content.` },
         ]}/>
       },
       {
@@ -269,6 +292,20 @@ In addition to the JSON defined on the `tauri.conf.json` file, Tauri reads a pla
           { property: "asset", optional: true, type: "boolean", description: `Enables the `asset` custom protocol, used to access files with streaming support.` },
         ]}/>
       },
+      {
+        property: "process", optional: true, type: "object", child: <Properties anchorRoot="tauri.allowlist.process" rows={[
+          { property: "all", type: "boolean", description: `Use this flag to enable all process APIs.` },
+          { property: "relaunch", optional: true, type: "boolean", description: `Enables the relaunch API.` },
+          { property: "exit", optional: true, type: "boolean", description: `Enables the exit API.` },
+        ]}/>
+      },
+      {
+        property: "clipboard", optional: true, type: "object", child: <Properties anchorRoot="tauri.allowlist.clipboard" rows={[
+          { property: "all", type: "boolean", description: `Use this flag to enable all clipboard APIs.` },
+          { property: "writeText", optional: true, type: "boolean", description: `Enables the writeText API.` },
+          { property: "readText", optional: true, type: "boolean", description: `Enables the readText API.` },
+        ]}/>
+      },
     ]} />
   },
   {

+ 303 - 5
tooling/cli.rs/schema.json

@@ -43,8 +43,16 @@
       "default": {
         "allowlist": {
           "all": false,
+          "clipboard": {
+            "all": false,
+            "readText": false,
+            "writeText": false
+          },
           "dialog": {
             "all": false,
+            "ask": false,
+            "confirm": false,
+            "message": false,
             "open": false,
             "save": false
           },
@@ -80,6 +88,11 @@
           "path": {
             "all": false
           },
+          "process": {
+            "all": false,
+            "exit": false,
+            "relaunch": false
+          },
           "protocol": {
             "all": false,
             "asset": false,
@@ -94,7 +107,30 @@
           },
           "window": {
             "all": false,
-            "create": false
+            "center": false,
+            "close": false,
+            "create": false,
+            "hide": false,
+            "maximize": false,
+            "minimize": false,
+            "print": false,
+            "requestUserAttention": false,
+            "setAlwaysOnTop": false,
+            "setDecorations": false,
+            "setFocus": false,
+            "setFullscreen": false,
+            "setIcon": false,
+            "setMaxSize": false,
+            "setMinSize": false,
+            "setPosition": false,
+            "setResizable": false,
+            "setSize": false,
+            "setSkipTaskbar": false,
+            "setTitle": false,
+            "show": false,
+            "startDragging": false,
+            "unmaximize": false,
+            "unminimize": false
           }
         },
         "bundle": {
@@ -160,10 +196,26 @@
           "default": false,
           "type": "boolean"
         },
+        "clipboard": {
+          "description": "Clipboard APIs allowlist.",
+          "default": {
+            "all": false,
+            "readText": false,
+            "writeText": false
+          },
+          "allOf": [
+            {
+              "$ref": "#/definitions/ClipboardAllowlistConfig"
+            }
+          ]
+        },
         "dialog": {
           "description": "Dialog API allowlist.",
           "default": {
             "all": false,
+            "ask": false,
+            "confirm": false,
+            "message": false,
             "open": false,
             "save": false
           },
@@ -253,6 +305,19 @@
             }
           ]
         },
+        "process": {
+          "description": "Process API allowlist.",
+          "default": {
+            "all": false,
+            "exit": false,
+            "relaunch": false
+          },
+          "allOf": [
+            {
+              "$ref": "#/definitions/ProcessAllowlistConfig"
+            }
+          ]
+        },
         "protocol": {
           "description": "Custom protocol allowlist.",
           "default": {
@@ -285,7 +350,30 @@
           "description": "Window API allowlist.",
           "default": {
             "all": false,
-            "create": false
+            "center": false,
+            "close": false,
+            "create": false,
+            "hide": false,
+            "maximize": false,
+            "minimize": false,
+            "print": false,
+            "requestUserAttention": false,
+            "setAlwaysOnTop": false,
+            "setDecorations": false,
+            "setFocus": false,
+            "setFullscreen": false,
+            "setIcon": false,
+            "setMaxSize": false,
+            "setMinSize": false,
+            "setPosition": false,
+            "setResizable": false,
+            "setSize": false,
+            "setSkipTaskbar": false,
+            "setTitle": false,
+            "show": false,
+            "startDragging": false,
+            "unmaximize": false,
+            "unminimize": false
           },
           "allOf": [
             {
@@ -770,6 +858,28 @@
       },
       "additionalProperties": false
     },
+    "ClipboardAllowlistConfig": {
+      "description": "Allowlist for the clipboard APIs.",
+      "type": "object",
+      "properties": {
+        "all": {
+          "description": "Use this flag to enable all clipboard APIs.",
+          "default": false,
+          "type": "boolean"
+        },
+        "readText": {
+          "description": "Enables the clipboard's `readText` API.",
+          "default": false,
+          "type": "boolean"
+        },
+        "writeText": {
+          "description": "Enables the clipboard's `writeText` API.",
+          "default": false,
+          "type": "boolean"
+        }
+      },
+      "additionalProperties": false
+    },
     "DebConfig": {
       "description": "Configuration for Debian (.deb) bundles.",
       "type": "object",
@@ -809,13 +919,28 @@
           "default": false,
           "type": "boolean"
         },
+        "ask": {
+          "description": "Allows the API to show a dialog window with Yes/No buttons.",
+          "default": false,
+          "type": "boolean"
+        },
+        "confirm": {
+          "description": "Allows the API to show a dialog window with Ok/Cancel buttons.",
+          "default": false,
+          "type": "boolean"
+        },
+        "message": {
+          "description": "Allows the API to show a message dialog window.",
+          "default": false,
+          "type": "boolean"
+        },
         "open": {
-          "description": "Open dialog window to pick files.",
+          "description": "Allows the API to open a dialog window to pick files.",
           "default": false,
           "type": "boolean"
         },
         "save": {
-          "description": "Open dialog window to pick where to save files.",
+          "description": "Allows the API to open a dialog window to pick where to save files.",
           "default": false,
           "type": "boolean"
         }
@@ -1051,6 +1176,28 @@
       "type": "object",
       "additionalProperties": true
     },
+    "ProcessAllowlistConfig": {
+      "description": "Allowlist for the process APIs.",
+      "type": "object",
+      "properties": {
+        "all": {
+          "description": "Use this flag to enable all process APIs.",
+          "default": false,
+          "type": "boolean"
+        },
+        "exit": {
+          "description": "Enables the exit API.",
+          "default": false,
+          "type": "boolean"
+        },
+        "relaunch": {
+          "description": "Enables the relaunch API.",
+          "default": false,
+          "type": "boolean"
+        }
+      },
+      "additionalProperties": false
+    },
     "ProtocolAllowlistConfig": {
       "description": "Allowlist for the custom protocols.",
       "type": "object",
@@ -1149,8 +1296,16 @@
           "description": "The allowlist configuration.",
           "default": {
             "all": false,
+            "clipboard": {
+              "all": false,
+              "readText": false,
+              "writeText": false
+            },
             "dialog": {
               "all": false,
+              "ask": false,
+              "confirm": false,
+              "message": false,
               "open": false,
               "save": false
             },
@@ -1186,6 +1341,11 @@
             "path": {
               "all": false
             },
+            "process": {
+              "all": false,
+              "exit": false,
+              "relaunch": false
+            },
             "protocol": {
               "all": false,
               "asset": false,
@@ -1200,7 +1360,30 @@
             },
             "window": {
               "all": false,
-              "create": false
+              "center": false,
+              "close": false,
+              "create": false,
+              "hide": false,
+              "maximize": false,
+              "minimize": false,
+              "print": false,
+              "requestUserAttention": false,
+              "setAlwaysOnTop": false,
+              "setDecorations": false,
+              "setFocus": false,
+              "setFullscreen": false,
+              "setIcon": false,
+              "setMaxSize": false,
+              "setMinSize": false,
+              "setPosition": false,
+              "setResizable": false,
+              "setSize": false,
+              "setSkipTaskbar": false,
+              "setTitle": false,
+              "show": false,
+              "startDragging": false,
+              "unmaximize": false,
+              "unminimize": false
             }
           },
           "allOf": [
@@ -1356,10 +1539,125 @@
           "default": false,
           "type": "boolean"
         },
+        "center": {
+          "description": "Allows centering the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "close": {
+          "description": "Allows closing the window.",
+          "default": false,
+          "type": "boolean"
+        },
         "create": {
           "description": "Allows dynamic window creation.",
           "default": false,
           "type": "boolean"
+        },
+        "hide": {
+          "description": "Allows hiding the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "maximize": {
+          "description": "Allows maximizing the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "minimize": {
+          "description": "Allows minimizing the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "print": {
+          "description": "Allows opening the system dialog to print the window content.",
+          "default": false,
+          "type": "boolean"
+        },
+        "requestUserAttention": {
+          "description": "Allows requesting user attention on the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setAlwaysOnTop": {
+          "description": "Allows setting the always_on_top flag of the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setDecorations": {
+          "description": "Allows setting the decorations flag of the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setFocus": {
+          "description": "Allows focusing the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setFullscreen": {
+          "description": "Allows setting the fullscreen flag of the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setIcon": {
+          "description": "Allows changing the window icon.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setMaxSize": {
+          "description": "Allows setting the window maximum size.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setMinSize": {
+          "description": "Allows setting the window minimum size.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setPosition": {
+          "description": "Allows changing the position of the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setResizable": {
+          "description": "Allows setting the resizable flag of the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setSize": {
+          "description": "Allows setting the window size.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setSkipTaskbar": {
+          "description": "Allows setting the skip_taskbar flag of the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "setTitle": {
+          "description": "Allows changing the window title.",
+          "default": false,
+          "type": "boolean"
+        },
+        "show": {
+          "description": "Allows showing the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "startDragging": {
+          "description": "Allows start dragging on the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "unmaximize": {
+          "description": "Allows unmaximizing the window.",
+          "default": false,
+          "type": "boolean"
+        },
+        "unminimize": {
+          "description": "Allows unminimizing the window.",
+          "default": false,
+          "type": "boolean"
         }
       },
       "additionalProperties": false