mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-26 18:22:09 +02:00
clipboard kitten: Allow using a password to avoid repeated confirmation prompts when accessing the clipboard
Fixes #8789
This commit is contained in:
@@ -3,7 +3,12 @@
|
||||
package clipboard
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
)
|
||||
@@ -20,10 +25,47 @@ func run_mime_loop(opts *Options, args []string) (err error) {
|
||||
}
|
||||
|
||||
func clipboard_main(cmd *cli.Command, opts *Options, args []string) (rc int, err error) {
|
||||
if opts.Password != "" {
|
||||
if opts.HumanName == "" {
|
||||
return 1, fmt.Errorf("must specify --human-name when using a password")
|
||||
}
|
||||
ptype, val, found := strings.Cut(opts.Password, ":")
|
||||
if !found {
|
||||
return 1, fmt.Errorf("invalid password: %#v no password type specified", opts.Password)
|
||||
}
|
||||
switch ptype {
|
||||
case "text":
|
||||
opts.Password = val
|
||||
case "fd":
|
||||
if fd, err := strconv.Atoi(val); err == nil {
|
||||
if f := os.NewFile(uintptr(fd), "password-fd"); f == nil {
|
||||
return 1, fmt.Errorf("invalid file descriptor: %d", fd)
|
||||
} else {
|
||||
data, err := io.ReadAll(f)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return 1, fmt.Errorf("failed to read from file descriptor: %d with error: %w", fd, err)
|
||||
}
|
||||
opts.Password = strings.TrimRightFunc(string(data), unicode.IsSpace)
|
||||
}
|
||||
|
||||
} else {
|
||||
return 1, fmt.Errorf("not a valid file descriptor number: %#v", val)
|
||||
}
|
||||
case "file":
|
||||
if data, err := os.ReadFile(val); err == nil {
|
||||
opts.Password = strings.TrimRightFunc(string(data), unicode.IsSpace)
|
||||
} else {
|
||||
return 1, fmt.Errorf("failed to read from file: %#v with error: %w", val, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(args) > 0 {
|
||||
return 0, run_mime_loop(opts, args)
|
||||
}
|
||||
|
||||
if opts.Password != "" || opts.HumanName != "" {
|
||||
return 1, fmt.Errorf("cannot use --human-name or --password in filter mode")
|
||||
}
|
||||
return 0, run_plain_text_loop(opts)
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,18 @@ other :code:`text/*` MIME is present.
|
||||
type=bool-set
|
||||
Wait till the copy to clipboard is complete before exiting. Useful if running
|
||||
the kitten in a dedicated, ephemeral window. Only needed in filter mode.
|
||||
|
||||
|
||||
--password
|
||||
A password to use when accessing the clipboard. If the user chooses to accept the password
|
||||
future invocations of the kitten will not have a permission prompt in this tty session. Does not
|
||||
work in filter mode. Must be of the form: text:actual-password or fd:integer (a file descriptor
|
||||
number to read the password from) or file:path-to-file (a file from which to read the password).
|
||||
Note that you must also specify a human friendly name using the :option:`--human-name` flag.
|
||||
|
||||
|
||||
--human-name
|
||||
A human friendly name to show the user when asking for permission to access the clipboard.
|
||||
'''.format
|
||||
help_text = '''\
|
||||
Read or write to the system clipboard.
|
||||
|
||||
@@ -329,9 +329,14 @@ func run_get_loop(opts *Options, args []string) (err error) {
|
||||
if opts.UsePrimary {
|
||||
basic_metadata["loc"] = "primary"
|
||||
}
|
||||
|
||||
lp.OnInitialize = func() (string, error) {
|
||||
lp.QueueWriteString(encode(basic_metadata, "."))
|
||||
if opts.Password != "" {
|
||||
basic_metadata["pw"] = base64.StdEncoding.EncodeToString(utils.UnsafeStringToBytes(opts.Password))
|
||||
}
|
||||
if opts.HumanName != "" {
|
||||
basic_metadata["name"] = base64.StdEncoding.EncodeToString(utils.UnsafeStringToBytes(opts.HumanName))
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
package clipboard
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -80,6 +81,14 @@ func write_loop(inputs []*Input, opts *Options) (err error) {
|
||||
if mime != "" {
|
||||
ans["mime"] = mime
|
||||
}
|
||||
if ptype == "write" {
|
||||
if opts.Password != "" {
|
||||
ans["pw"] = base64.StdEncoding.EncodeToString(utils.UnsafeStringToBytes(opts.Password))
|
||||
}
|
||||
if opts.HumanName != "" {
|
||||
ans["name"] = base64.StdEncoding.EncodeToString(utils.UnsafeStringToBytes(opts.HumanName))
|
||||
}
|
||||
}
|
||||
return ans
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user