83dd847b7449dd0fa83c22a4d60854f8d20d2847
max
  Fri Sep 18 08:51:14 2026 -0700
hgLogin: stop telling a CILogon user that CILogon shares no email address

#Preview2 week - bugs introduced now will need a build patch to fix
QA found three messages on the social sign-in pages claiming the provider does
not give us an address.  That was written when ORCID, which really releases
none, was the only provider reaching those pages.  CILogon does release the
institution's address; we drop it because CILogon never marks it verified and
login.oauth.cilogon.trustEmail is what says we may take it anyway.  Once the
address is dropped, nothing downstream could tell "released nothing" from
"released something we would not take".

oauthFetchIdentity now keeps the dropped address in a separate field that
matching and sign-in never look at, and the three messages read it: the choose
a username page, the confirmation page, and the one that turns down a typed
address that already belongs to an account.  The address box on the choose a
username page starts from it as well, since retyping what we were just handed
is the last thing a person wants to do.  It still has to clear the duplicate
check and be confirmed by mail, exactly as a typed address does.

Three more things on the confirmation page, all from the same QA pass:

The generic "a confirmation email has been sent" paragraph printed below the
"use this address instead" form, so it read as if a mail had already gone to
whatever was about to be typed in.  It now goes above the form.

Correcting the address redisplayed the same page with the new address swapped
in and nothing to say the change had worked.  It now says so.  The rejection
reason for an address that is already in use was set but never printed, so a
refused change looked like nothing happening at all; that is printed now too.

Reworded the unconfirmed-account explanation as QA suggested.

refs #38339

diff --git src/hg/hgLogin/oauthLogin.h src/hg/hgLogin/oauthLogin.h
index 6b74dff85a1..a2bf80bdbcf 100644
--- src/hg/hgLogin/oauthLogin.h
+++ src/hg/hgLogin/oauthLogin.h
@@ -27,30 +27,35 @@
 
 /* Copyright (C) 2026 The Regents of the University of California
  * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
 
 #ifndef OAUTHLOGIN_H
 #define OAUTHLOGIN_H
 
 struct oauthIdentity
 /* An authenticated identity returned by an external OAuth/OpenID provider. */
     {
     struct oauthIdentity *next;
     char *provider;         /* provider short name, e.g. "google" */
     char *subject;          /* stable, unique id from the provider */
     char *email;            /* email reported by provider, or NULL */
     boolean emailVerified;  /* TRUE if the provider asserts the email is verified */
+    char *emailUnverified;  /* an address the provider released that we would not take: it did
+                             * not say the address is verified and hg.conf does not trust this
+                             * provider (see trustEmail).  Never used to match an account or to
+                             * sign anyone in -- only to say why we are asking the user for an
+                             * address, and to offer it back as a starting point. */
     char *displayName;      /* full name from provider, or NULL */
     };
 
 boolean oauthAnyProviderEnabled();
 /* Return TRUE if at least one social login provider is configured. */
 
 boolean oauthProviderEnabled(char *name);
 /* Return TRUE if the named provider is configured (clientId and clientSecret set). */
 
 struct slName *oauthProviderNames();
 /* Return the short names of all configured providers, in the order listed in hg.conf.
  * Do not free (owned by an internal cache). */
 
 char *oauthProviderLabel(char *name);
 /* Return the display label for a provider (falls back to the name).  Do not free. */