From 529635ec9a0fdfe5d2b3410dc7090378d388dcf5 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Mon, 18 Aug 2025 08:36:13 -0500 Subject: feat(auth-config): Retry auth-source-search when failed - Add `cj/ensure-auth` and `cj/ensure-auth-before` helpers and advice `cj/auth-source-search-retry` around `auth-source-search` to loop (killing the gpg-agent and retrying) until the `.authinfo.gpg` file is decrypted. - Include usage examples for wrapping other entry points (e.g., GPT toggle, mu4e, Tramp, Dirvish). - Fix indentation in an existing test. --- modules/auth-config.el | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'modules') diff --git a/modules/auth-config.el b/modules/auth-config.el index 43849f20..5dbce2ef 100644 --- a/modules/auth-config.el +++ b/modules/auth-config.el @@ -38,6 +38,47 @@ :config (setq epg-gpg-program "gpg2")) ;; force use gpg2 (not gpg v.1) +;; ----------------------------- Ensure-Auth-Before ---------------------------- + +(defun cj/ensure-auth-before (&rest _args) + "Ensure .authinfo.gpg is unlocked before calling the real function." + (cj/ensure-auth)) + +(defun cj/ensure-auth () + "Make sure .authinfo.gpg is decrypted (loops on failure)." + (interactive) + (auth-source-search :max 1)) + +(with-eval-after-load 'auth-source + (defun cj/auth-source-search-retry (orig-fun &rest args) + "Advice around `auth-source-search' to loop until we get non-nil." + (let (res) + (while (not (setq res (apply orig-fun args))) + ;; user hit RET or wrong passphrase → kill agent & retry + (message "Auth failed or cancelled; killing gpg-agent and retrying…") + (start-process "gpgconf-kill-gpg-agent" nil + "gpgconf" "--kill" "gpg-agent") + (sleep-for 0.5)) + res)) + + (advice-add 'auth-source-search :around #'cj/auth-source-search-retry)) + +;; Example: run it before your GPT toggle +;;(advice-add 'cj/toggle-gptel :before #'cj/ensure-auth-before) + +;; Example: before mu4e actually sends a message +;;(advice-add 'smtpmail-send-it ; or `mu4e~proc-send` if you prefer +;; :before #'cj/ensure-auth-before) + +;; Example: before Tramp prompts for a password +;; (advice-add 'tramp-read-passwd ; wherever Tramp reads your passphrase +;; :before #'cj/ensure-auth-before) + +;; ;; Example: before Dirvish opens a remote directory +;; (advice-add 'dirvish-find-file ; or the exact entry-point you use +;; :before #'cj/ensure-auth-before) + + (provide 'auth-config) ;;; auth-config.el ends here. @@ -50,7 +91,7 @@ (ert-deftest auth-config/authinfo-file-exists () "Verify that `authinfo-file` actually exists on disk." (should (and (stringp authinfo-file) - (file-exists-p authinfo-file)))) + (file-exists-p authinfo-file)))) (ert-deftest auth-config/gpg2-is-on-path () "Verify that the `gpg2` executable is on the user’s PATH." -- cgit v1.2.3