You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2026/06/04 16:43:10 UTC

(superset) branch master updated: fix: remove registration_hash in the registrations API (#40643)

This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new aa547da9607 fix: remove registration_hash in the registrations API (#40643)
aa547da9607 is described below

commit aa547da960729d34979cbac7284892c2854a4aec
Author: Evan Rusackas <ev...@preset.io>
AuthorDate: Thu Jun 4 09:43:03 2026 -0700

    fix: remove registration_hash in the registrations API (#40643)
    
    Co-authored-by: Claude Code <no...@anthropic.com>
---
 .../src/pages/UserRegistrations/UserRegistrations.test.tsx |  7 ++++++-
 superset-frontend/src/pages/UserRegistrations/index.tsx    | 14 --------------
 superset/security/api.py                                   | 13 ++++++++++++-
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/superset-frontend/src/pages/UserRegistrations/UserRegistrations.test.tsx b/superset-frontend/src/pages/UserRegistrations/UserRegistrations.test.tsx
index 67856b35661..d57cac266ac 100644
--- a/superset-frontend/src/pages/UserRegistrations/UserRegistrations.test.tsx
+++ b/superset-frontend/src/pages/UserRegistrations/UserRegistrations.test.tsx
@@ -30,7 +30,6 @@ const mockUserRegistrations = Array.from({ length: 5 }, (_, i) => ({
   last_name: `Test${i}`,
   email: `user${i}@test.com`,
   registration_date: new Date(2025, 2, 25, 11, 4, 32 + i).toISOString(),
-  registration_hash: `hash${i}`,
 }));
 
 fetchMock.get(userRegistrationsEndpoint, {
@@ -53,4 +52,10 @@ describe('UserRegistrations', () => {
     const calls = fetchMock.callHistory.calls(userRegistrationsEndpoint);
     expect(calls.length).toBeGreaterThan(0);
   });
+
+  test('does not expose the registration hash', async () => {
+    expect(await screen.findByText('User registrations')).toBeVisible();
+    // The activation hash is a bearer token and must not be shown in the UI.
+    expect(screen.queryByText('Registration hash')).not.toBeInTheDocument();
+  });
 });
diff --git a/superset-frontend/src/pages/UserRegistrations/index.tsx b/superset-frontend/src/pages/UserRegistrations/index.tsx
index 07fa3b51c5b..8230b233962 100644
--- a/superset-frontend/src/pages/UserRegistrations/index.tsx
+++ b/superset-frontend/src/pages/UserRegistrations/index.tsx
@@ -40,7 +40,6 @@ export type UserRegistration = {
   last_name: string;
   email: string;
   registration_date: string;
-  registration_hash: string;
 };
 
 export default function UserRegistrations() {
@@ -110,12 +109,6 @@ export default function UserRegistrations() {
         Header: t('Email'),
         Cell: ({ row: { original } }: any) => original.email,
       },
-      {
-        accessor: 'registration_hash',
-        id: 'registration_hash',
-        Header: t('Registration hash'),
-        Cell: ({ row: { original } }: any) => original.registration_hash,
-      },
       {
         accessor: 'registration_date',
         id: 'registration_date',
@@ -177,13 +170,6 @@ export default function UserRegistrations() {
         input: 'search',
         operator: ListViewFilterOperator.Contains,
       },
-      {
-        Header: t('Registration hash'),
-        key: 'registration_hash',
-        id: 'registration_hash',
-        input: 'search',
-        operator: ListViewFilterOperator.Contains,
-      },
       {
         Header: t('Registration date'),
         key: 'registration_date',
diff --git a/superset/security/api.py b/superset/security/api.py
index daff4d98026..c38b3c590fe 100644
--- a/superset/security/api.py
+++ b/superset/security/api.py
@@ -370,6 +370,11 @@ class UserRegistrationsRestAPI(BaseSupersetModelRestApi):
     resource_name = "security/user_registrations"
     datamodel = SQLAInterface(RegisterUser)
     allow_browser_login = True
+    # NOTE: registration_hash is intentionally excluded from both list_columns
+    # and search_columns. It is a bearer token for the
+    # /register/activation/<hash> flow; exposing it in API responses (and thus
+    # logs/caches) or allowing it to be filtered on would let a holder activate
+    # the pending account.
     list_columns = [
         "id",
         "username",
@@ -377,5 +382,11 @@ class UserRegistrationsRestAPI(BaseSupersetModelRestApi):
         "first_name",
         "last_name",
         "registration_date",
-        "registration_hash",
+    ]
+    search_columns = [
+        "username",
+        "email",
+        "first_name",
+        "last_name",
+        "registration_date",
     ]