d33d0e1c19117a0347dbadb99a77e9f12483c735
max
  Tue Sep 1 06:56:09 2026 -0700
hgLogin: let users set or change their recovery email address, refs #38197

Adds a page where a signed-in user can set or change the recovery address on
their account, offered in the account menu next to "Change email" -- both in
the top right blue bar popup and on the session page. It is off by default:
set login.recovEmailChange=on in hg.conf to offer it. The page also needs
login.cookieSalt, working outbound mail and the recovEmailVerified column,
and stays hidden where any of those is missing.

The new address is confirmed by mail before it takes effect, so whatever is
on the account keeps working until the link is opened and a typo costs the
user nothing. An account that has a password must supply it, since a
confirmed recovery address can sign in. Once the address does change, the
account's main address is told, the same notice that a change of the main
address already sends.

One signature now covers both the address given at signup and a later
change, so there is a single confirmation path rather than two.

diff --git src/hg/inc/wikiLink.h src/hg/inc/wikiLink.h
index fbab19a8c2d..93b544617af 100644
--- src/hg/inc/wikiLink.h
+++ src/hg/inc/wikiLink.h
@@ -12,30 +12,31 @@
 #define CFG_WIKI_LOGGED_IN_COOKIE "wiki.loggedInCookie"
 #define CFG_WIKI_SESSION_COOKIE "wiki.sessionCookie"
 
 /* hg.conf login system parameter -- using non-wiki login system (hgLogin) if defined */
 #define CFG_LOGIN_SYSTEM_NAME "login.systemName"
 #define CFG_LOGIN_USE_HTTPS "login.https"
 #define CFG_LOGIN_COOKIE_SALT "login.cookieSalt"
 #define CFG_LOGIN_ACCEPT_ANY_ID "login.acceptAnyId"
 #define CFG_LOGIN_ACCEPT_IDX "login.acceptIdx"
 #define CFG_LOGIN_BASICAUTH "login.basicAuth"
 #define CFG_LOGIN_RELATIVE "login.relativeLink"
 /* Enables passwordless email-link sign-in and the "change email" option (default off). */
 #define CFG_LOGIN_EMAIL_LINK "login.emailLink"
 /* Comma-separated list of hosts that hgLogin will return a visitor to after login or logout. */
 #define CFG_APPROVED_HOSTS "login.approvedReturn"
+#define CFG_LOGIN_RECOV_EMAIL_CHANGE "login.recovEmailChange"
 
 /* hg.conf central db parameters */
 #define CFG_CENTRAL_DOMAIN "central.domain"
 #define CFG_CENTRAL_COOKIE "central.cookie"
 
 char *loginSystemName();
 /* Return the wiki host specified in hg.conf, or NULL.  Allocd here. */
 
 boolean loginSystemEnabled();
 /* Return TRUE if login.systemName  parameter is defined in hg.conf . */
 
 boolean loginUseHttps();
 /* Return TRUE unless https is disabled in hg.conf. */
 
 boolean loginUseBasicAuth();
@@ -105,26 +106,32 @@
 /* Return the URL for the user signup  page. */
 
 char *wikiLinkChangePasswordUrl(char *hgsid);
 /* Return the URL for the user change password page, returning to hgSession. */
 
 char *wikiLinkChangePasswordUrlReturning(char *hgsid, char *returnUrl);
 /* Return the URL for the user change password page. */
 
 char *wikiLinkChangeEmailUrl(char *hgsid);
 /* Return the URL for the user change email page, returning to hgSession, or NULL if
  * unavailable. */
 
 char *wikiLinkChangeEmailUrlReturning(char *hgsid, char *returnUrl);
 /* Return the URL for the user change email page, or NULL if unavailable. */
 
+char *wikiLinkChangeRecovEmailUrl(char *hgsid);
+/* Return the URL for the user recovery email page, or NULL if unavailable. */
+
+char *wikiLinkChangeRecovEmailUrlReturning(char *hgsid, char *returnUrl);
+/* Return the URL for the user recovery email page, coming back to returnUrl. */
+
 char *wikiServerAndCgiDir();
 /* return the current full absolute URL up to the CGI name, like
  * http://genome.ucsc.edu/cgi-bin/. If login.relativeLink=on is
  * set, return only /cgi-bin/. Takes care of of non-root location of cgi-bin
  * and https. Result has to be free'd. */
 
 void wikiFixLogoutLinkWithJs();
 /* HTTP Basic Auth requires a strange hack to logout. This code prints a script 
  * that fixes an html link with id=logoutLink */
 
 #endif /* WIKILINK_H */