ece2ff8889e304cf8e873063b331ba710bbc21fc
braney
  Thu Aug 13 08:18:44 2026 -0700
urlCommandCatalog: describe hgLogin's login-flow cart variables, refs #37923

diff --git src/hg/utils/urlCommandCatalog/urlCommandCatalog.py src/hg/utils/urlCommandCatalog/urlCommandCatalog.py
index 42bfe447a75..cfb5ff41de5 100755
--- src/hg/utils/urlCommandCatalog/urlCommandCatalog.py
+++ src/hg/utils/urlCommandCatalog/urlCommandCatalog.py
@@ -972,30 +972,50 @@
             c("provider", "action", "hg/hgLogin/hgLogin.c:2265",
               value="<name>", verified=True,
               note="Which configured provider to start a social login with, "
                    "in oauthStart.  Refused unless oauthProviderEnabled(), so "
                    "an unknown name cannot start a redirect."),
             c("code", "action", "hg/hgLogin/hgLogin.c:2322", value="<code>",
               verified=True,
               note="The provider's authorization code, handed back on its "
                    "redirect and exchanged server-side for the user's "
                    "identity."),
             c("state", "action", "hg/hgLogin/hgLogin.c:2293", value="<nonce>",
               verified=True,
               note="The anti-CSRF nonce, compared against the oauth_state "
                    "cart variable that oauthStart saved and then removes, so "
                    "it is single use."),
+            c("oauth_state", "setting", "hg/hgLogin/hgLogin.c:2319",
+              value="<nonce>", persists=True, verified=True,
+              note="The server's copy of the nonce above, saved by oauthStart "
+                   "so it survives the round trip to the provider and removed "
+                   "by oauthReturn once it has been used.  hgLogin writes it "
+                   "and nothing else does: a copy arriving with the request "
+                   "is dropped in dropRequestSuppliedFlowVars before anything "
+                   "reads it, so what the check compares against is always "
+                   "the value oauthStart stored.  Listed here rather than in "
+                   "urlNamesNotCataloged.txt, where it sat until #38037, "
+                   "because a cart variable is reachable from a URL by "
+                   "default and calling this one out of scope is what hid "
+                   "that."),
+            c("oauth_provider", "setting", "hg/hgLogin/hgLogin.c:2320",
+              value="<name>", persists=True, verified=True,
+              note="Which provider the login in flight belongs to, saved by "
+                   "oauthStart alongside oauth_state, removed with it, and "
+                   "server-owned in the same way.  The dispatcher in doMiddle "
+                   "reads it to tell a provider's redirect back to us from "
+                   "any other request carrying a code or error parameter."),
             c("error", "action", "hg/hgLogin/hgLogin.c:2298", value="<code>",
               verified=True, leaks=True,
               note="The provider redirected back with an error instead of a "
                    "code, for instance because the user declined.  Shown "
                    "rather than dropped, so the user is not silently sent to "
                    "the signup page.  hgLogin's excludeVars (hgLogin.c:47) "
                    "covers code, state and provider but not this, so a string "
                    "chosen by whoever wrote the redirect is kept in the "
                    "user's session."),
             c("error_description", "action", "hg/hgLogin/hgLogin.c:2304",
               value="<text>", verified=True, leaks=True,
               note="The provider's human-readable error text, printed through "
                    "htmlEncode.  Leaks into the session for the same reason "
                    "as error."),
             c("newEmail", "action", "hg/hgLogin/hgLogin.c:1219",