From 9c2d3006066b274164d5abff2dd3bc2b7c97a910 Mon Sep 17 00:00:00 2001 From: janithjay Date: Tue, 11 Aug 2026 12:15:35 +0530 Subject: [PATCH] Remove unnecessary processUsername utility and userstore prefix processing --- packages/javascript/src/api/getUsersMe.ts | 5 +- .../javascript/src/api/updateMeProfile.ts | 8 +- packages/javascript/src/index.ts | 1 - .../utils/__tests__/processUsername.test.ts | 163 ------------------ .../javascript/src/utils/processUsername.ts | 93 ---------- 5 files changed, 2 insertions(+), 268 deletions(-) delete mode 100644 packages/javascript/src/utils/__tests__/processUsername.test.ts delete mode 100644 packages/javascript/src/utils/processUsername.ts diff --git a/packages/javascript/src/api/getUsersMe.ts b/packages/javascript/src/api/getUsersMe.ts index 31a1c6b5..feabaac1 100644 --- a/packages/javascript/src/api/getUsersMe.ts +++ b/packages/javascript/src/api/getUsersMe.ts @@ -3,7 +3,6 @@ import ThunderIDAPIError from '../errors/ThunderIDAPIError'; import {User} from '../models/user'; -import processUserUsername from '../utils/processUsername'; /** * Configuration for the getUsersMe request @@ -120,12 +119,10 @@ const getUsersMe = async ({url, baseUrl, fetcher, ...requestConfig}: GetUsersMeC const user: User = (await response.json()) as User; const attributes: Record = (user['attributes'] as Record) ?? {}; - const processedUser: User = { + return { ...user, ...attributes, }; - - return processUserUsername(processedUser); } catch (error) { if (error instanceof ThunderIDAPIError) { throw error; diff --git a/packages/javascript/src/api/updateMeProfile.ts b/packages/javascript/src/api/updateMeProfile.ts index 88db638c..8695e5f9 100644 --- a/packages/javascript/src/api/updateMeProfile.ts +++ b/packages/javascript/src/api/updateMeProfile.ts @@ -3,7 +3,6 @@ import ThunderIDAPIError from '../errors/ThunderIDAPIError'; import {User} from '../models/user'; -import processUserUsername from '../utils/processUsername'; /** * Configuration for the updateMeProfile request @@ -122,17 +121,12 @@ const updateMeProfile = async ({ ); } - // Match the read path (`getUsersMe`) — strip the userstore prefix - // (e.g. "DEFAULT/") so consumers receive a clean `userName`. Without - // this, the optimistic-update path would put the prefixed value into - // local state and the UI would flip to "DEFAULT/" after a save. const user: User = (await response.json()) as User; const attributes: Record = (user['attributes'] as Record) ?? {}; - const processedUser: User = { + return { ...user, ...attributes, }; - return processUserUsername(processedUser); } catch (error) { if (error instanceof ThunderIDAPIError) { throw error; diff --git a/packages/javascript/src/index.ts b/packages/javascript/src/index.ts index 5ca8b1d9..df7a82ef 100644 --- a/packages/javascript/src/index.ts +++ b/packages/javascript/src/index.ts @@ -156,7 +156,6 @@ export {default as arrayBufferToBase64url} from './utils/arrayBufferToBase64url' export {default as base64urlToArrayBuffer} from './utils/base64urlToArrayBuffer'; export {default as bem} from './utils/bem'; export {default as formatDate} from './utils/formatDate'; -export {default as processUsername} from './utils/processUsername'; export {default as deepMerge} from './utils/deepMerge'; export {default as extractUserClaimsFromIdToken} from './utils/extractUserClaimsFromIdToken'; export {default as isRecognizedBaseUrlPattern} from './utils/isRecognizedBaseUrlPattern'; diff --git a/packages/javascript/src/utils/__tests__/processUsername.test.ts b/packages/javascript/src/utils/__tests__/processUsername.test.ts deleted file mode 100644 index 2ba78659..00000000 --- a/packages/javascript/src/utils/__tests__/processUsername.test.ts +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2025 The ThunderID Authors -// SPDX-License-Identifier: Apache-2.0 - -import processUsername, {removeUserstorePrefix} from '../processUsername'; - -describe('processUsername', () => { - describe('removeUserstorePrefix', () => { - it('should remove DEFAULT/ prefix from username', () => { - const result: string = removeUserstorePrefix('DEFAULT/john.doe'); - expect(result).toBe('john.doe'); - }); - - it('should remove ASGARDEO_USER/ prefix from username', () => { - const result: string = removeUserstorePrefix('ASGARDEO_USER/jane.doe'); - expect(result).toBe('jane.doe'); - }); - - it('should remove PRIMARY/ prefix from username', () => { - const result: string = removeUserstorePrefix('PRIMARY/admin'); - expect(result).toBe('admin'); - }); - - it('should remove custom userstore prefix from username', () => { - const result: string = removeUserstorePrefix('CUSTOM_STORE/user.name'); - expect(result).toBe('user.name'); - }); - - it('should return original username if no userstore prefix exists', () => { - const result: string = removeUserstorePrefix('jane.doe'); - expect(result).toBe('jane.doe'); - }); - - it('should handle empty string', () => { - const result: string = removeUserstorePrefix(''); - expect(result).toBe(''); - }); - - it('should handle undefined input', () => { - const result: string = removeUserstorePrefix(undefined); - expect(result).toBe(''); - }); - - it('should handle username with only userstore prefix', () => { - const result: string = removeUserstorePrefix('DEFAULT/'); - expect(result).toBe(''); - }); - - it('should not remove lowercase prefixes', () => { - const result: string = removeUserstorePrefix('default/user'); - expect(result).toBe('default/user'); - }); - - it('should not remove mixed case prefixes', () => { - const result: string = removeUserstorePrefix('Default/user'); - expect(result).toBe('Default/user'); - }); - - it('should not remove if prefix contains invalid characters', () => { - const result: string = removeUserstorePrefix('DEFAULT-STORE/user'); - expect(result).toBe('DEFAULT-STORE/user'); - }); - - it('should only remove the first occurrence of userstore prefix', () => { - const result: string = removeUserstorePrefix('DEFAULT/DEFAULT/user'); - expect(result).toBe('DEFAULT/user'); - }); - - it('should handle userstore prefix with numbers', () => { - const result: string = removeUserstorePrefix('STORE123/user'); - expect(result).toBe('user'); - }); - }); - - describe('processUsername', () => { - it('should process DEFAULT/ username in user object', () => { - const user: Record = { - email: 'john@example.com', - givenName: 'John', - username: 'DEFAULT/john.doe', - }; - - const result: Record = processUsername(user); - - expect(result.username).toBe('john.doe'); - expect(result.email).toBe('john@example.com'); - expect(result.givenName).toBe('John'); - }); - - it('should process ASGARDEO_USER/ username in user object', () => { - const user: Record = { - email: 'jane@example.com', - givenName: 'Jane', - username: 'ASGARDEO_USER/jane.doe', - }; - - const result: Record = processUsername(user); - - expect(result.username).toBe('jane.doe'); - expect(result.email).toBe('jane@example.com'); - expect(result.givenName).toBe('Jane'); - }); - - it('should process PRIMARY/ username in user object', () => { - const user: Record = { - email: 'admin@example.com', - givenName: 'Admin', - username: 'PRIMARY/admin', - }; - - const result: Record = processUsername(user); - - expect(result.username).toBe('admin'); - expect(result.email).toBe('admin@example.com'); - expect(result.givenName).toBe('Admin'); - }); - - it('should handle user object without username', () => { - const user: Record = { - email: 'john@example.com', - givenName: 'John', - }; - - const result: Record = processUsername(user); - - expect(result).toEqual(user); - }); - - it('should handle user object with empty username', () => { - const user: Record = { - email: 'john@example.com', - username: '', - }; - - const result: Record = processUsername(user); - - expect(result.username).toBe(''); - expect(result.email).toBe('john@example.com'); - }); - - it('should handle null/undefined user object', () => { - expect(processUsername(null as any)).toBe(null); - expect(processUsername(undefined as any)).toBe(undefined); - }); - - it('should preserve other properties in user object', () => { - const user: Record = { - customProperty: 'customValue', - email: 'jane@example.com', - familyName: 'Doe', - givenName: 'Jane', - username: 'DEFAULT/jane.doe', - }; - - const result: Record = processUsername(user); - - expect(result.username).toBe('jane.doe'); - expect(result.email).toBe('jane@example.com'); - expect(result.givenName).toBe('Jane'); - expect(result.familyName).toBe('Doe'); - expect((result as any).customProperty).toBe('customValue'); - }); - }); -}); diff --git a/packages/javascript/src/utils/processUsername.ts b/packages/javascript/src/utils/processUsername.ts deleted file mode 100644 index ff548b41..00000000 --- a/packages/javascript/src/utils/processUsername.ts +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2025 The ThunderID Authors -// SPDX-License-Identifier: Apache-2.0 - -/** - * Regular expression to match userstore prefixes in usernames. - * Matches patterns like "DEFAULT/", "ASGARDEO_USER/", "PRIMARY/", etc. - * The pattern matches any uppercase letters, numbers, and underscores followed by a forward slash. - */ -const USERSTORE_PREFIX_REGEX = /^[A-Z_][A-Z0-9_]*\//; - -/** - * Removes userstore prefixes from a username if they exist. - * This is commonly used to clean usernames returned from profile endpoints - * that include userstore prefixes like "DEFAULT/", "ASGARDEO_USER/", "PRIMARY/", etc. - * - * @param username - The username string to process - * @returns The username without the userstore prefix, or the original username if no prefix exists - * - * @example - * ```typescript - * const cleanUsername = removeUserstorePrefix("DEFAULT/john.doe"); - * console.log(cleanUsername); // "john.doe" - * - * const thunderidUser = removeUserstorePrefix("ASGARDEO_USER/jane.doe"); - * console.log(thunderidUser); // "jane.doe" - * - * const primaryUser = removeUserstorePrefix("PRIMARY/admin"); - * console.log(primaryUser); // "admin" - * - * const alreadyClean = removeUserstorePrefix("user.name"); - * console.log(alreadyClean); // "user.name" - * - * const emptyInput = removeUserstorePrefix(""); - * console.log(emptyInput); // "" - * ``` - */ -export const removeUserstorePrefix = (username?: string): string => { - if (!username) { - return ''; - } - - return username.replace(USERSTORE_PREFIX_REGEX, ''); -}; - -/** - * Processes a user object to remove userstore prefixes from username fields. - * This is a helper function for processing user objects returned from profile endpoints. - * Handles various username field variations: username, userName, and user_name. - * - * @param user - The user object to process - * @returns The user object with processed username fields - * - * @example - * ```typescript - * const user = { username: "DEFAULT/john.doe", email: "john@example.com" }; - * const processedUser = processUserUsername(user); - * console.log(processedUser.username); // "john.doe" - * - * const camelCaseUser = { userName: "ASGARDEO_USER/jane.doe", email: "jane@example.com" }; - * const processedCamelCaseUser = processUserUsername(camelCaseUser); - * console.log(processedCamelCaseUser.userName); // "jane.doe" - * - * const snakeCaseUser = { user_name: "PRIMARY/admin", email: "admin@example.com" }; - * const processedSnakeCaseUser = processUserUsername(snakeCaseUser); - * console.log(processedSnakeCaseUser.user_name); // "admin" - * ``` - */ -const processUsername = (user: T): T => { - if (!user) { - return user; - } - - const processedUser: T = {...user}; - - // Process username field - if (processedUser.username) { - processedUser.username = removeUserstorePrefix(processedUser.username); - } - - // Process userName field - if (processedUser.userName) { - processedUser.userName = removeUserstorePrefix(processedUser.userName); - } - - // Process user_name field - if (processedUser.user_name) { - processedUser.user_name = removeUserstorePrefix(processedUser.user_name); - } - - return processedUser; -}; - -export default processUsername;