5f7a14fde8cdb24b01fc0e5eadba145bfd9ecb04
max
  Sat Jul 25 23:16:06 2026 -0700
hgLogin: social login (Google/ORCID), email login link, change email. refs #37929

diff --git src/hg/lib/web.c src/hg/lib/web.c
index f2cff7eb275..cf31e0026d8 100644
--- src/hg/lib/web.c
+++ src/hg/lib/web.c
@@ -1678,34 +1678,37 @@
         char *userName = wikiLinkUserName();
         struct dyString *dy = dyStringNew(512);
         if (userName == NULL)
             {
             // Link straight to the login page (same target hgSession's own Login link uses),
             // rather than bouncing the user through hgSession first.
             char *loginUrl = wikiLinkUserLoginUrl(cart ? cartSessionId(cart) : "");
             dyStringPrintf(dy, "<a class='topRightLink' href='%s' id='loginLink' "
                 "title='Log in to save and share sessions'>Login</a>", loginUrl);
             }
         else
             {
             char *hgsid = cart ? cartSessionId(cart) : NULL;
             char *logoutUrl = wikiLinkUserLogoutUrl(hgsid);
             char *changePwUrl = wikiLinkChangePasswordUrl(hgsid);
+            char *changeEmailUrl = wikiLinkChangeEmailUrl(hgsid);
             dyStringPrintf(dy, "<a class='topRightLink' href='#' id='loginLink' "
                 "title='Account info and sign out' "
-                "data-username=\"%s\" data-logouturl=\"%s\" data-changepwurl=\"%s\">%s</a>",
-                userName, logoutUrl, changePwUrl ? changePwUrl : "", userName);
+                "data-username=\"%s\" data-logouturl=\"%s\" data-changepwurl=\"%s\" "
+                "data-changeemailurl=\"%s\">%s</a>",
+                userName, logoutUrl, changePwUrl ? changePwUrl : "",
+                changeEmailUrl ? changeEmailUrl : "", userName);
             }
         loginLi = dyStringCannibalize(&dy);
         }
     menuStr = replaceChars(menuStr, "<!-- LOGIN_LINK -->", loginLi);
     }
 
 // Fill in the top-right "Share a link" link (placeholder <!-- SHARE_LINK -->).
 // data-sharemode tells topLinks.js what to do:
 //   "session" (hgTracks): save the current view as a session and show a short link; branches on
 //             data-loggedin to either name a session (logged in) or make an anonymous link.
 //   "url" (hgTrackUi): just show the current page URL with the hgsid stripped, for sharing.
     {
     char *shareLi = "";
     boolean isHgTracks = (scriptName && endsWith(scriptName, "hgTracks"));
     boolean isHgTrackUi = (scriptName && endsWith(scriptName, "hgTrackUi"));