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/lib/wikiLink.c src/hg/lib/wikiLink.c index 3fcf8cb6f8a..1ff97e99831 100644 --- src/hg/lib/wikiLink.c +++ src/hg/lib/wikiLink.c @@ -692,28 +692,54 @@ struct dyString *dy = dyStringNew(256); dyStringPrintf(dy, "%s?hgLogin.do.changeEmailPage=1&returnto=%s", loginUrl(), returnUrl); return dyStringCannibalize(&dy); } char *wikiLinkChangeEmailUrl(char *hgsid) /* Return the URL for the user change email page, returning to hgSession, or NULL if * unavailable. */ { char *retEnc = encodedHgSessionReturnUrl(hgsid); char *result = wikiLinkChangeEmailUrlReturning(hgsid, retEnc); freez(&retEnc); return result; } +char *wikiLinkChangeRecovEmailUrlReturning(char *hgsid, char *returnUrl) +/* Return the URL for the page where a user sets or changes their recovery email address, or + * NULL if unavailable. Supported only by the hgLogin login system, and only when the admin + * has turned it on with login.recovEmailChange in hg.conf. hgLogin checks the rest of what + * the feature needs (a cookie salt to sign the confirmation link, working outbound mail, and + * the recovEmailVerified column) and sends the user back to the login page if any is missing. */ +{ +if (!loginSystemEnabled()) + return NULL; +if (!cfgOptionBooleanDefault(CFG_LOGIN_RECOV_EMAIL_CHANGE, FALSE)) + return NULL; +struct dyString *dy = dyStringNew(256); +dyStringPrintf(dy, "%s?hgLogin.do.changeRecovEmailPage=1&returnto=%s", loginUrl(), returnUrl); +return dyStringCannibalize(&dy); +} + +char *wikiLinkChangeRecovEmailUrl(char *hgsid) +/* Return the URL for the recovery email page, returning to hgSession, or NULL if + * unavailable. */ +{ +char *retEnc = encodedHgSessionReturnUrl(hgsid); +char *result = wikiLinkChangeRecovEmailUrlReturning(hgsid, retEnc); +freez(&retEnc); +return result; +} + void wikiFixLogoutLinkWithJs() /* HTTP Basic Auth requires a strange hack to logout. This code prints a script * that fixes an html link with id=logoutLink */ { struct dyString *dy = dyStringNew(4096); // logoutJs.h is a stringified .js file #include "logoutJs.h" dyStringAppend(dy, cdwLogoutJs); dyStringPrintf(dy, "$('#logoutLink').click( function() { logout('/', 'http://cirm.ucsc.edu'); return false; });\n"); jsInline(dy->string); dyStringFree(&dy); printf("<script src='//cdnjs.cloudflare.com/ajax/libs/bowser/1.6.1/bowser.min.js'></script>"); }