Subject: [PATCH 2/8] Update plstore-id calculation including user-name

From: Xiyue Deng <[email-masked]>
Date: Fri, 15 Aug 2025 03:06:08 -0700

One way to use OAuth2 authentication is to use predefined
`client-id'/`client-secret' values that are already registered,
e.g. thunderbird, evolution.  Meanwhile, plstore-id calculation only
considers `auth-url', `token-url', `scope', and `client-id'.  When
trying to use predefined client-{id,secret} values, it unfortunately
results in the same value of plstore-id when registering multiple
accounts on the same service, preventing users to use multiple
accounts.

This patch adds `user-name' to be part of the values when calculating
plstore-id so that different accounts on the same service using
predefined values will be stored separately.

* plstore/oauth2/oauth2.el (oauth2-compute-id): Add user-name
parameter and include it when calculating plstore-id.
* plstore/oauth2/oauth2.el (oauth2-auth-and-store): Add user-name
parameter and update oauth2-compute-id invocation to include
user-name.
---
 oauth2.el | 43 ++++++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 17 deletions(-)

diff --git a/oauth2.el b/oauth2.el
index 0da4883bc3..ef9d70c256 100644
--- a/oauth2.el
+++ b/oauth2.el
@@ -257,40 +257,49 @@ TOKEN should be obtained with `oauth2-request-access'."
     auth-url client-id scope state redirect-uri)
    redirect-uri))
 
-(defun oauth2-compute-id (auth-url token-url scope client-id)
-  "Compute an unique id based on AUTH-URL, TOKEN-URL, SCOPE, and CLIENT-ID.
-This allows to store the token in an unique way."
-  (secure-hash 'sha512 (concat auth-url token-url scope client-id)))
+(defun oauth2-compute-id (auth-url token-url scope client-id user-name)
+  "Compute an unique id mainly to use as plstore id.
+The result is computed using AUTH-URL, TOKEN-URL, SCOPE, CLIENT-ID, and
+USER-NAME to ensure the plstore id is unique."
+  (secure-hash 'sha512 (concat auth-url token-url scope client-id user-name)))
 
 ;;;###autoload
 (defun oauth2-auth-and-store (auth-url token-url scope client-id client-secret
-                                       &optional redirect-uri state)
+                                       &optional redirect-uri state user-name)
   "Request access to a resource and store it.
 AUTH-URL and TOKEN-URL are provided by the service provider.  CLIENT-ID
 and CLIENT-SECRET should be generated by the service provider when a
 user registers an application.  SCOPE identifies the resources that your
 application can access on the user's behalf.  STATE is a string that
 your application uses to maintain the state between the request and
-redirect response.
+redirect response. USER-NAME is the login user name and is required to
+provide a unique plstore id for users on the same service provider.
 
 Returns an `oauth2-token'."
   ;; We store a MD5 sum of all URL
   (oauth2--with-plstore
-   (let* ((plstore-id (oauth2-compute-id auth-url token-url scope client-id))
+   (let* ((plstore-id (oauth2-compute-id auth-url token-url scope client-id
+                                         user-name))
           (plist (cdr (plstore-get plstore plstore-id))))
+     (oauth2--do-trivia "user-name: %s\nplstore-id: %s"
+                        user-name plstore-id)
      ;; Check if we found something matching this access
      (if plist
          ;; We did, return the token object
-         (make-oauth2-token :plstore-id plstore-id
-                            :client-id client-id
-                            :client-secret client-secret
-                            :access-token (plist-get plist :access-token)
-                            :refresh-token (plist-get plist :refresh-token)
-                            :request-timestamp (plist-get plist
-                                                          :request-timestamp)
-                            :auth-url auth-url
-                            :token-url token-url
-                            :access-response (plist-get plist :access-response))
+         (progn
+           (oauth2--do-trivia "Found matching plstore-id from plstore.")
+           (make-oauth2-token :plstore-id plstore-id
+                              :client-id client-id
+                              :client-secret client-secret
+                              :access-token (plist-get plist :access-token)
+                              :refresh-token (plist-get plist :refresh-token)
+                              :request-timestamp (plist-get plist
+                                                            :request-timestamp)
+                              :auth-url auth-url
+                              :token-url token-url
+                              :access-response (plist-get plist
+                                                          :access-response)))
+       (oauth2--do-trivia "Requesting new oauth2-token.")
        (let ((token (oauth2-auth auth-url token-url
                                  client-id client-secret scope state
                                  redirect-uri)))
-- 
2.47.2