5872e3a9d5f3d2916bbf10f359011b9d04fc3b93
max
  Wed Aug 26 03:18:39 2026 -0700
Revert "Share a link: create the session only when the user asks, and copy in one click"

This reverts commit 3f97b357c59.  The change was work in progress and was
committed by mistake; web.c still has the matching data-shortlink part
uncommitted, so this half does not stand on its own.  The genark syncFtp commit
that went out with it is fine and stays.

diff --git src/hg/hgSession/hgSession.c src/hg/hgSession/hgSession.c
index f94bfdbb1df..56c7a75a81d 100644
--- src/hg/hgSession/hgSession.c
+++ src/hg/hgSession/hgSession.c
@@ -1037,73 +1037,70 @@
  * sessionName is the human-readable (decoded) name; the client uses it as the rename "old name". */
 {
 struct dyString *dyUrl = dyStringNew(0);
 addSessionLink(dyUrl, encUserName, encSessionName, FALSE, TRUE);
 puts("Content-Type:application/json\n");
 printf("{\"name\": \"%s\", \"url\": \"%s\"}\n",
        jsonStringEscape(sessionName), jsonStringEscape(dyUrl->string));
 dyStringFree(&dyUrl);
 hDisconnectCentral(&conn);
 }
 
 void doSaveSessionJson(char *userName)
 /* AJAX endpoint behind the "Share a link" menu button.  Save the current cart as a named session
  * and print JSON {"name": <session name>, "url": <shareable link>}.  When the user is not logged
  * in (or hgsShareAnon is set), save under the reserved anonymous user "l" with a random token
- * name.  When logged in, the caller supplies the name (a typed name, or a random internal
- * "_XXXXXXXX" name generated client-side).  Saved shared by link so the link works for anyone.
- * Reuses saveCartAsSession() and addSessionLink(). */
+ * name.  When logged in with no name given, generate a short random name.  Saved shared by link so
+ * the link works for anyone.  Reuses saveCartAsSession() and addSessionLink(). */
 {
 struct sqlConnection *conn = hConnectCentral();
 if (!sqlTableExists(conn, namedSessionTable))
     {
     saveSessionJsonError(conn, "Required session table does not exist in the central database.");
     return;
     }
 
 boolean anon = isEmpty(userName) || cgiBoolean(hgsShareAnon);
 // Read the requested name from the request, not the cart (hgSession's Save form leaves a sticky
 // value in the cart under this same variable that would otherwise shadow ours).
 char *sessionName = trimSpaces(cloneString(cgiUsualString(hgsNewSessionName, "")));
 
 /* Keep our control variables out of the saved session contents and the user's own cart. */
 cartRemove(cart, hgsDoSaveSessionJson);
 cartRemove(cart, hgsShareAnon);
 cartRemove(cart, hgsNewSessionName);
 cartRemove(cart, hgsNewSessionShare);
 
 char *encUserName = NULL;
 char *encSessionName = NULL;
 if (anon)
     {
     encUserName = "l";                    /* reserved anonymous user -> short link /s/l/<token> */
-    /* The caller may supply a client-generated token so the Share dialog can show the exact link
-     * before the user commits; fall back to a server-generated token when none is given (e.g. the
-     * hgc BLAT "Share a link" button). */
-    if (isEmpty(sessionName))
-        sessionName = makeRandomKey(96);  /* 16 URL-safe alphanumeric chars */
-    encSessionName = cgiEncodeFull(sessionName);
+    sessionName = makeRandomKey(96);      /* 16 URL-safe alphanumeric chars; no encoding needed */
+    encSessionName = sessionName;
     }
 else
     {
-    /* Logged-in callers always supply a name: the caller either typed one or generated a random
-     * internal "_XXXXXXXX" name client-side (sessRandomShareName in hgSession.js, shared by the
-     * top-right "Share a link" menu in topLinks.js), so we no longer auto-name here. */
     if (isEmpty(sessionName))
         {
-        saveSessionJsonError(conn, "Please provide a name for this session.");
-        return;
+        /* One-click share: auto-name the session.  "_" is kept verbatim by cgiEncodeFull (unlike
+         * "-"), so the short link /s/<user>/<name> stays clean. */
+        char randName[32];
+        char *rk = makeRandomKey(48);     /* 8 URL-safe alphanumeric chars */
+        safef(randName, sizeof randName, "share_%s", rk);
+        freeMem(rk);
+        sessionName = cloneString(randName);
         }
     encUserName = cgiEncodeFull(userName);
     encSessionName = cgiEncodeFull(sessionName);
     }
 
 saveCartAsSession(conn, encUserName, encSessionName, 1);  /* shared by link */
 saveSessionJsonResult(conn, encUserName, encSessionName, sessionName);
 }
 
 void doRenameSessionJson(char *userName)
 /* AJAX endpoint for the "Specify name" step of the Share dialog: rename an existing session
  * (hgsOldSessionName -> hgsNewSessionName) under the current user.  Logged-in only.  Rejects a
  * name already in use rather than overwriting it.  Returns {"name","url"} or {"error"}. */
 {
 struct sqlConnection *conn = hConnectCentral();