(setq debug-on-error t) (defun rbw-get-password () (interactive) (if (rbw/unlocked) (kill-new (rbw/list-all 'rbw/get-pass)) (message "locked vault"))) (defun rbw-get-totp () (interactive) (if (rbw/unlocked) (kill-new (rbw/list-all 'rbw/get-totp)) (message "locked vault"))) (defun rbw-add () (interactive) (let* ((name (read-string "password name: ")) (username (read-string "username: ")) (entry (concat name " " username)) (exists? (car (rbw/gets-pass entry)))) (message exists?) (if exists? (message "entry already exists") (let* ((length (read-number "length: "))) (rbw/generate length name username))))) (defun rbw-get-user () (interactive) (if (rbw/unlocked) (let* ((output (rbw/list-all 'rbw/get-pass "--field user")) (output (string-trim-left output "Username: "))) (kill-new output)) (message "locked vault"))) (defun rbw-generate () (interactive) (let* ((length (read-number "password length: "))) (kill-new (rbw/generate length)))) (defun rbw-sync () (interactive) (let* ((default-directory "/home/luis/")) (shell-command "rbw sync"))) (defun rbw/list-all (getter &optional options entries selected) (let* ((entries (if entries entries (rbw/list))) (entry (completing-read "bitwarden entries: " entries)) (selected (concat selected " " entry)) (selected (string-trim selected)) (result (funcall getter selected options)) ; TODO fix when getter fails (output (car (last result))) (result (car result))) (if result output (rbw/list-all getter options (rbw/extract-multiple output selected) selected)))) (defun rbw/generate (length &optional name user) (let* ((default-directory "/home/luis/") (length (number-to-string length)) (command (concat "rbw generate " length " " name " " user))) (shell-command-to-string command))) (defun rbw/unlocked () (let* ((default-directory "/home/luis/")) (if (string-empty-p (shell-command-to-string "rbw unlocked")) t nil))) (defun rbw/list () (let* ((default-directory "/home/luis/") (output (shell-command-to-string "rbw list")) (output (string-trim output)) (entries (split-string output "\n"))) entries)) (defun rbw/get-pass (entry &optional options) (let* ((default-directory "/home/luis/") (command (concat "rbw get " options " " entry " ; echo $?")) (output (shell-command-to-string command)) (output (string-trim output)) (output (split-string output "\n")) (result (car (last output))) (result (string-equal result "0")) (output (car output))) (list result output))) (defun rbw/get-totp (entry &optional options) (let* ((default-directory "/home/luis/") (command (concat "rbw code " options " " entry " ; echo $?")) (output (shell-command-to-string command)) (output (string-trim output)) (output (split-string output "\n")) (result (car (last output))) (result (string-equal result "0")) (output (car output))) (list result output))) (defun rbw/extract-multiple (output selected) (string-match "\\([^:]*\\)$" output) (let* ((trimmed (string-trim (match-string 1 output))) (splitted (split-string trimmed ", ")) (ending (concat "@" selected)) (splitted (cl-remove-if-not (lambda (x) (string-match ending x)) splitted)) (result-list '())) (dolist (element splitted) (push (car (split-string element ending)) result-list)) (reverse result-list))) (provide 'rbw)