Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion examples/api/src-tauri/capabilities/desktop.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"global-shortcut:allow-register",
"global-shortcut:allow-unregister-all",
{ "identifier": "fs:allow-watch", "allow": ["*", "**/*"] },
"fs:allow-unwatch"
"fs:allow-unwatch",
"clipboard-manager:allow-write-secret"
]
}
8 changes: 8 additions & 0 deletions examples/api/src/views/Clipboard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@
}
}

function writeSecret() {
clipboard.writeSecret(text).then(() => {
onMessage("Wrote secret to the clipboard")
})
.catch(onMessage)
}

async function read() {
try {
const image = await clipboard.readImage()
Expand Down Expand Up @@ -64,6 +71,7 @@
bind:value={text}
/>
<button class="btn" type="button" on:click={writeText}>Write</button>
<button class="btn" type="button" on:click={writeSecret}>Write Secret</button>
<button class="btn" type="button" on:click={writeImage}>Pick Image</button>
<button class="btn" type="button" on:click={read}>Read</button>
</div>
2 changes: 1 addition & 1 deletion plugins/clipboard-manager/api-iife.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions plugins/clipboard-manager/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const COMMANDS: &[&str] = &[
"read_image",
"write_html",
"clear",
"write_secret",
];

fn main() {
Expand Down
20 changes: 19 additions & 1 deletion plugins/clipboard-manager/guest-js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,22 @@ async function clear(): Promise<void> {
await invoke('plugin:clipboard-manager|clear')
}

export { writeText, readText, writeHtml, clear, readImage, writeImage }
/**
* Writes text to clipboard and sets hints for clipboard managers to exclude it
* from history
*
* @returns A promise indicating the success or failure of the operation.
*/
async function writeSecret(text: string): Promise<void> {
await invoke('plugin:clipboard-manager|write_secret', { text })
}

export {
writeText,
readText,
writeHtml,
clear,
readImage,
writeImage,
writeSecret
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!

"$schema" = "../../schemas/schema.json"

[[permission]]
identifier = "allow-write-secret"
description = "Enables the write_secret command without any pre-configured scope."
commands.allow = ["write_secret"]

[[permission]]
identifier = "deny-write-secret"
description = "Denies the write_secret command without any pre-configured scope."
commands.deny = ["write_secret"]
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,32 @@ Denies the write_image command without any pre-configured scope.
<tr>
<td>

`clipboard-manager:allow-write-secret`

</td>
<td>

Enables the write_secret command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`clipboard-manager:deny-write-secret`

</td>
<td>

Denies the write_secret command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`clipboard-manager:allow-write-text`

</td>
Expand Down
12 changes: 12 additions & 0 deletions plugins/clipboard-manager/permissions/schemas/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,18 @@
"const": "deny-write-image",
"markdownDescription": "Denies the write_image command without any pre-configured scope."
},
{
"description": "Enables the write_secret command without any pre-configured scope.",
"type": "string",
"const": "allow-write-secret",
"markdownDescription": "Enables the write_secret command without any pre-configured scope."
},
{
"description": "Denies the write_secret command without any pre-configured scope.",
"type": "string",
"const": "deny-write-secret",
"markdownDescription": "Denies the write_secret command without any pre-configured scope."
},
{
"description": "Enables the write_text command without any pre-configured scope.",
"type": "string",
Expand Down
10 changes: 10 additions & 0 deletions plugins/clipboard-manager/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,13 @@ pub(crate) async fn clear<R: Runtime>(
) -> Result<()> {
clipboard.clear()
}

#[command]
#[cfg(desktop)]
pub(crate) async fn write_secret<R: Runtime>(
_app: AppHandle<R>,
clipboard: State<'_, Clipboard<R>>,
text: &str,
) -> Result<()> {
clipboard.write_secret(text)
}
20 changes: 20 additions & 0 deletions plugins/clipboard-manager/src/desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ use tauri::{image::Image, plugin::PluginApi, AppHandle, Runtime};

use std::{borrow::Cow, sync::Mutex};

#[cfg(desktop)]
use crate::secret::ExcludeSecret;

pub fn init<R: Runtime, C: DeserializeOwned>(
app: &AppHandle<R>,
_api: PluginApi<R, C>,
Expand Down Expand Up @@ -120,4 +123,21 @@ impl<R: Runtime> Clipboard<R> {
clipboard.lock().unwrap().take();
}
}

/// This is the same as write_text but it will set hints using [`arboard::SetExtLinux`], [`arboard::SetExtWindows`], or [`arboard::SetExtApple`] depending on the platform.
#[cfg(desktop)]
pub fn write_secret<'a, T: Into<Cow<'a, str>>>(&self, text: T) -> crate::Result<()> {
match &self.clipboard {
Ok(clipboard) => clipboard
.lock()
.unwrap()
.as_mut()
.unwrap()
.set()
.exclude_secret()
.text(text)
.map_err(Into::into),
Err(e) => Err(crate::Error::Clipboard(e.to_string())),
}
}
}
7 changes: 6 additions & 1 deletion plugins/clipboard-manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ mod mobile;
mod commands;
mod error;

#[cfg(desktop)]
mod secret;

pub use error::{Error, Result};

#[cfg(desktop)]
Expand Down Expand Up @@ -49,7 +52,9 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
commands::read_image,
commands::write_image,
commands::write_html,
commands::clear
commands::clear,
#[cfg(desktop)]
commands::write_secret,
])
.setup(|app, api| {
#[cfg(mobile)]
Expand Down
45 changes: 45 additions & 0 deletions plugins/clipboard-manager/src/secret.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#[cfg(all(
unix,
not(any(target_os = "macos", target_os = "android", target_os = "emscripten")),
))]
use arboard::SetExtLinux;

#[cfg(windows)]
use arboard::SetExtWindows;

#[cfg(target_os = "macos")]
use arboard::SetExtApple;

/// Trait to expose exclude from history functionality from [`arboard`] crate's `SetExt*` extensions.
/// On Linux, it calls [`arboard::SetExtLinux::exclude_from_history`]
/// On MacOS, it calls [`arboard::SetExtApple::exclude_from_history`]
/// On Windows, it calls [`arboard::SetExtWindows::exclude_from_history`], [`arboard::SetExtWindows::exclude_from_cloud`], and [`arboard::SetExtWindows::exclude_from_monitoring`]
pub trait ExcludeSecret<'clipboard> {
fn exclude_secret(self) -> arboard::Set<'clipboard>;
}

#[cfg(all(
unix,
not(any(target_os = "macos", target_os = "android", target_os = "emscripten"))
))]
impl<'clipboard> ExcludeSecret<'clipboard> for arboard::Set<'clipboard> {
fn exclude_secret(self) -> arboard::Set<'clipboard> {
self.exclude_from_history()
}
}

#[cfg(windows)]
impl<'clipboard> ExcludeSecret<'clipboard> for arboard::Set<'clipboard> {
fn exclude_secret(self) -> arboard::Set<'clipboard> {
self.exclude_from_history()
.exclude_from_cloud()
.exclude_from_monitoring()
}
}

#[cfg(target_os = "macos")]
impl<'clipboard> ExcludeSecret<'clipboard> for arboard::Set<'clipboard> {
fn exclude_secret(self) -> arboard::Set<'clipboard> {
self.exclude_from_history()
}
}