Skip to content
Merged
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
18 changes: 15 additions & 3 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,11 @@ to log in to Overleaf. A stale =geckodriver= process listening on the
default port =4444= should not prevent re-authentication.

By default, authenticated cookies are stored with Emacs ~auth-source~.
The package uses the first plain-file entry in ~auth-sources~, falling
back to =~/.authinfo=. It manages one entry per Overleaf host using
=login git-overleaf= and =port git-overleaf-cookie=.
The package uses the first file entry in ~auth-sources~, including GPG
encrypted files, and falls back to =~/.authinfo.gpg=. When updating an
existing encrypted file it preserves that file's recipients. It manages
one entry per Overleaf host using =login git-overleaf= and
=port git-overleaf-cookie=.
Re-authentication replaces that managed entry instead of appending stale
copies.

Expand All @@ -223,6 +225,16 @@ project discovery asks you to log in again and rerun

** Cookie storage

To use the default encrypted auth-source storage:

#+begin_src elisp
(setopt auth-sources '("~/.authinfo.gpg")
git-overleaf-cookie-storage 'authinfo)
#+end_src

When the encrypted file does not exist yet, EasyPG prompts for the
encryption recipients on the first save.

To store cookies in a plain file:

#+begin_src elisp
Expand Down
16 changes: 13 additions & 3 deletions README.zh.org
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,10 @@ Overleaf。即使有旧的 =geckodriver= 进程占用默认端口 =4444=,也
重新认证。

默认情况下,认证后的 cookies 会存入 Emacs ~auth-source~。本包会使用
~auth-sources~ 中的第一个明文文件条目,并在没有可用条目时回退到
=~/.authinfo=。它按 Overleaf host 管理一条记录,并使用
=login git-overleaf= 与 =port git-overleaf-cookie= 进行定位。
~auth-sources~ 中的第一个文件条目(包括 GPG 加密文件),并在没有可用
条目时回退到 =~/.authinfo.gpg=。更新已有加密文件时会保留原来的加密
收件人。它按 Overleaf host 管理一条记录,并使用 =login git-overleaf=
与 =port git-overleaf-cookie= 进行定位。
重新认证会替换该受管理记录,而不是追加过期副本。

** Firefox cookie 导入
Expand All @@ -199,6 +200,15 @@ cookies,并在找不到有效 Overleaf session cookie 时给出明确失败信

** Cookie 存储

使用默认的加密 auth-source 存储:

#+begin_src elisp
(setopt auth-sources '("~/.authinfo.gpg")
git-overleaf-cookie-storage 'authinfo)
#+end_src

如果加密文件尚不存在,EasyPG 会在第一次保存时提示选择加密收件人。

将 cookies 存入普通文件:

#+begin_src elisp
Expand Down
41 changes: 21 additions & 20 deletions git-overleaf-core.el
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
"Where Overleaf cookies should be persisted across Emacs sessions.

If the value is the symbol `authinfo', cookies are stored in the first
plain auth-source file from `auth-sources', falling back to
`~/.authinfo'.
file entry from `auth-sources', including encrypted `.gpg' files. If
there is no file entry, `~/.authinfo.gpg' is used.

If the value is a string, it is treated as a plain file path where the
serialized cookie alist is stored.
Expand Down Expand Up @@ -570,7 +570,7 @@ ON-ERROR receives an error message string in the foreground."

;;;; Cookie helpers

(defconst git-overleaf--authinfo-default-source "~/.authinfo"
(defconst git-overleaf--authinfo-default-source "~/.authinfo.gpg"
"Fallback authinfo file used by Overleaf cookie helpers.")

(defconst git-overleaf--authinfo-default-user "git-overleaf"
Expand All @@ -586,12 +586,7 @@ ON-ERROR receives an error message string in the foreground."
"Return the expanded authinfo SOURCE file path."
(expand-file-name
(or source
(cl-some
(lambda (entry)
(and (stringp entry)
(not (string-match-p "\\.gpg\\'" entry))
entry))
auth-sources)
(cl-find-if #'stringp auth-sources)
git-overleaf--authinfo-default-source)))

(defun git-overleaf--authinfo-resolve-host (&optional host)
Expand Down Expand Up @@ -679,17 +674,23 @@ read."
resolved-host
resolved-user
resolved-port
secret))
(existing
(with-temp-buffer
(when (file-readable-p file)
(insert-file-contents file)
(flush-lines regexp))
(replace-regexp-in-string "\\`\n+" "" (buffer-string)))))
(with-temp-file file
(insert line)
(unless (string-empty-p existing)
(insert "\n" existing)))
secret)))
(with-temp-buffer
(let ((existing
(progn
(when (file-readable-p file)
(insert-file-contents file)
(goto-char (point-min))
(flush-lines regexp))
(replace-regexp-in-string "\\`\n+" "" (buffer-string)))))
;; Keep this buffer's `epa-file-encrypt-to' value. Reading an
;; existing .gpg file records its recipients buffer-locally, so the
;; following write re-encrypts to the same keys without prompting.
(erase-buffer)
(insert line)
(unless (string-empty-p existing)
(insert "\n" existing))
(write-region nil nil file nil 'silent)))
(set-file-modes file #o600)
(auth-source-forget+ :host resolved-host :user resolved-user :port resolved-port)))

Expand Down
40 changes: 40 additions & 0 deletions test/git-overleaf-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,46 @@
(should (equal (git-overleaf--cookie-key-candidates)
'("overleaf.example" ".overleaf.example")))))

(ert-deftest git-overleaf-test-authinfo-source-supports-gpg ()
(let ((auth-sources '("~/.authinfo.gpg")))
(should (equal (git-overleaf--authinfo-source-file)
(expand-file-name "~/.authinfo.gpg"))))
(let ((auth-sources '(macos-keychain-internet)))
(should (equal (git-overleaf--authinfo-source-file)
(expand-file-name "~/.authinfo.gpg")))))

(ert-deftest git-overleaf-test-authinfo-write-preserves-gpg-recipients ()
(let (written)
(let* ((source "/git-overleaf-test/.authinfo.gpg")
(handler
(lambda (operation &rest args)
(pcase operation
('expand-file-name (car args))
('file-readable-p t)
('insert-file-contents
(setq-local epa-file-encrypt-to '("RECIPIENT"))
(let ((start (point)))
(insert
"machine example.test login git-overleaf port git-overleaf-cookie password b2xk git-overleaf-cookie-record t\n"
"machine other.test login someone port token password keep\n")
(list (car args) (- (point) start))))
('write-region
(setq written
(list (buffer-string) epa-file-encrypt-to)))
('set-file-modes nil)
(_ (error "Unexpected file operation: %S" operation)))))
(file-name-handler-alist
(list (cons (concat "\\`" (regexp-quote source) "\\'") handler)))
(auth-sources (list source)))
(git-overleaf--authinfo-write-secret
nil "example.test" "git-overleaf" "git-overleaf-cookie" "new-cookie")
(should (equal (cadr written) '("RECIPIENT")))
(should (string-prefix-p
"machine example.test login git-overleaf port git-overleaf-cookie password "
(car written)))
(should-not (string-match-p "password b2xk" (car written)))
(should (string-match-p "machine other.test.*password keep" (car written))))))

(ert-deftest git-overleaf-test-sanitize-name ()
(should (equal (git-overleaf--sanitize-name " My Project v2.tex!! ")
"my-project-v2-tex"))
Expand Down
Loading