Skip to content

[react] Update profile data edit API endpoints to use PUT /users/me#9

Draft
janithjay wants to merge 1 commit into
thunder-id:mainfrom
janithjay:feat/profile-edit-put
Draft

[react] Update profile data edit API endpoints to use PUT /users/me#9
janithjay wants to merge 1 commit into
thunder-id:mainfrom
janithjay:feat/profile-edit-put

Conversation

@janithjay

@janithjay janithjay commented Jun 26, 2026

Copy link
Copy Markdown

Purpose

Currently, the <UserProfile />component attempts to save changes by making a PATCH request using the SCIM2 format to a non-existent /scim2/Me endpoint. This prevents self-service profile updates from persisting.

This PR resolves this limitation by migrating the self-service profile read and update path on the React & Javascript SDKs from SCIM-based PATCH (/scim2/Me) to standard JSON-based PUT (/users/me), aligning with the existing endpoint supported by the backend (GET & PUT on /users/me). This enables profile updates to work end-to-end.

Approach

Endpoint & Method Realignment

  • Updated the base URL in updateMeProfile.ts (JS SDK) and getScim2Me.ts (JS SDK) to target ${baseUrl}/users/me instead of ${baseUrl}/scim2/Me.
  • Updated the HTTP method for profile updates to PUT and request headers to Content-Type: application/json.
  • Updated updateMeProfile.ts (React SDK) HTTP wrapper configuration to default to PUT.

Payload Structure Formatting

  • Wrapped the attributes inside an attributes wrapper object (e.g. { attributes: payload }) to match the backend UpdateSelfUserRequest payload contract.
  • Stripped out any nullor undefined properties from the attributes payload inside UserProfile.tsx before dispatching the request.

Response Handling

  • Backend returns attributes nested under the attributes field of the User object. Flattened these nested attributes back to the top-level User object inside updateMeProfile.ts and getScim2Me.ts to preserve backward compatibility for downstream React UI component attributes resolution.

React State Syncing

Added an useEffect hook in BaseUserProfile.tsx to listen to updates on profile or flattenedProfile and automatically reset/sync the local input states, resolving any stale UI rendering after a successful profile update.

Test Assertions:

Updated the unit tests inside updateMeProfile.test.ts and getScim2Me.test.ts to validate the new PUT/GET behavior, URL paths, content-type headers, and payload attributes structure.

Related Issues

Related PRs

  • N/A

Checklist

  • Followed the contribution guidelines.
  • Manual test round performed and verified.
  • Documentation provided. (Add links if there are any)
  • Tests provided. (Add links if there are any)
    • Unit Tests
    • Integration Tests
  • Breaking changes. (Fill if applicable)
    • Breaking changes section filled.
    • breaking change label added.

Security checks

  • Followed secure coding standards in WSO2 Secure Coding Guidelines
  • Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets.

Summary by CodeRabbit

  • New Features

    • Profile fetching and updates now use a newer user profile path and return richer profile data.
    • Theme preferences now support inheriting branding settings.
    • Authorization requests only include scope information when scopes are provided.
  • Bug Fixes

    • Profile edits now merge changes more reliably and keep the form in sync with incoming updates.
    • Session setup can now include the latest user profile data when available.
    • Theme CSS variable naming is now consistent with the current prefix.
  • Tests

    • Updated automated coverage for profile, auth, and theme behavior.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Profile read (getScim2Me) and write (updateMeProfile) flows are migrated from SCIM /scim2/Me (PATCH) to /users/me (GET/PUT) with JSON headers and attribute-merged response shapes. The React ThunderIDProvider, UserProfile, and BaseUserProfile components are updated accordingly. Auth scope omission, CSS variable prefix rename, error fixture cleanup, and callback test isolation are also included.

Changes

Users me profile migration

Layer / File(s) Summary
Read user profile from /users/me
packages/javascript/src/api/getScim2Me.ts, packages/javascript/src/api/__tests__/getScim2Me.test.ts
getScim2Me defaults to /users/me, sends JSON headers, and merges nested attributes into the returned user object. Tests assert the new URL, response shape, and header enforcement.
PUT profile updates through /users/me
packages/javascript/src/api/updateMeProfile.ts, packages/react/src/api/updateMeProfile.ts, packages/javascript/src/api/__tests__/updateMeProfile.test.ts
updateMeProfile sends { attributes: payload } via PUT to /users/me with JSON headers; response attributes are merged back. The React fetcher fallback changes from PATCH to PUT. Tests cover success, error, header enforcement, and custom fetcher paths.
Profile editor merges attributes before update
packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx, packages/react/src/components/presentation/UserProfile/UserProfile.tsx
BaseUserProfile adds a useEffect to resync editedUser when props change while preserving in-flight edits. UserProfile.handleProfileUpdate deep-merges existing profile.attributes with the incoming payload and prunes null/undefined keys before calling updateMeProfile.
Session hydration from /users/me
packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx
updateSession conditionally fetches /users/me via getScim2Me when signed in and fetchUserProfile is enabled, merging the result into profileData before setting user/userProfile.

Auth, theme, and regression fixes

Layer / File(s) Summary
Omit empty scope parameter
packages/javascript/src/utils/getAuthorizeRequestUrlParams.ts
scope URL parameter is only added when options.scopes is not undefined; previously an empty string was always sent.
Callback tests: cleanup and provider context
packages/react/src/components/auth/Callback/__tests__/Callback.test.tsx, packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx, packages/react/package.json
Callback and TokenCallback tests call cleanup() in afterEach. TokenCallback tests remove the useThunderID mock and wrap renders with ThunderIDContext.Provider. @vitest/browser-playwright is added to devDependencies.
Error fixture, theme prefix, and config field
packages/javascript/src/errors/__tests__/ThunderIDAPIError.test.ts, packages/javascript/src/theme/createTheme.test.ts, packages/javascript/src/models/config.ts
Structured error fixture removes message.defaultValue. Theme tests replace --thunder-* with --thunderid-* CSS variable prefix. ThemePreferences adds optional inheritFromBranding boolean.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Poem

🐇 Hopping from /scim2/Me to /users/me today,
With JSON headers and attributes merged just right,
The rabbit refactored, PUT replaced PATCH's way,
Deep-merged the fields and cleaned up null's blight.
Now tests run tidy, cleanup() every night!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main API endpoint and method change in the PR.
Description check ✅ Passed The description follows the template and covers purpose, approach, issue link, checklist, and security items.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx (1)

23-47: 📐 Maintainability & Code Quality | 🟡 Minor

Type thunderIDContext as ThunderIDContext

The thunderIDContext fixture is currently declared with : any. This forces TypeScript to treat the entire context object as unsafe, triggering @typescript-eslint/no-unsafe-assignment errors when its properties are accessed in the test assertions and render calls.

Change the declaration to const thunderIDContext: ThunderIDContext = ... (or a compatible shape) to satisfy the type checker and ensure the tests validate the actual context contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx`
around lines 23 - 47, The TokenCallback test fixture is using an unsafe
any-typed context object, which causes type-checking issues in the assertions
and render setup. Update the thunderIDContext declaration to use
ThunderIDContext (or a compatible typed shape) and keep the existing mocked
methods like getStorageManager, signIn, and signUp typed accordingly so the test
exercises the real context contract without unsafe assignments.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/javascript/src/api/__tests__/getScim2Me.test.ts`:
- Around line 24-37: The test fixture for getScim2Me uses a broad Record<string,
unknown> shape, which leaves mockUserResponse.attributes typed as unknown and
triggers the unsafe spread in mockUser. Update the mock definitions in
getScim2Me.test.ts so mockUserResponse has an explicit attributes type (or use
satisfies with a precise interface), and keep mockUser built from that strongly
typed attributes object to satisfy the lint rule.

In `@packages/javascript/src/api/__tests__/updateMeProfile.test.ts`:
- Around line 54-62: The test assertions are reading mocked fetch calls through
an untyped/any path, which is triggering ESLint. In the updateMeProfile test
cases, cast the first entry from Mock.mock.calls to a typed tuple like [string,
RequestInit] before destructuring, and use the typed RequestInit/body access for
JSON.parse instead of going through any. Apply the same cleanup in the other
affected assertions as well, using the existing fetch mock and RequestInit
references to keep the types explicit.

In `@packages/javascript/src/api/getScim2Me.ts`:
- Around line 137-142: The normalization block in getScim2Me currently spreads
user['attributes'] directly, which lets the index signature collapse
processedUser and the return value to any. Narrow or cast attributes to a
concrete object type before flattening inside getScim2Me, then build
processedUser from that typed value and pass the typed result into
processUserUsername so the new path stays lint-clean.

In `@packages/javascript/src/api/updateMeProfile.ts`:
- Around line 144-149: The update path in updateMeProfile currently spreads
user['attributes'] directly, which leaves the merged result unsafe and triggers
no-unsafe-assignment/no-unsafe-return. Narrow or type attributes as an object
before constructing processedUser, then return the typed flattened user through
processUserUsername so the helper stays type-safe like the read path.
- Around line 113-116: The request setup in updateMeProfile should not allow
callers to override the new PUT contract. In the requestInit object used by
updateMeProfile, ensure the spread of requestConfig happens before the method
assignment, or explicitly reassign method after spreading, so a caller cannot
pass a different HTTP verb and bypass the /users/me PUT migration.

In `@packages/react/package.json`:
- Around line 54-58: The devDependencies block in package.json has a duplicated
`@vitest/browser-playwright` entry, which creates an invalid/ambiguous manifest.
Remove one of the duplicate entries from the package manifest and keep only a
single `@vitest/browser-playwright` key alongside the other devDependencies.

In `@packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx`:
- Around line 145-147: The useEffect in BaseUserProfile is overwriting the
entire editedUser state whenever flattenedProfile or profile changes, which
clobbers other in-flight edits tracked by editingFields. Update this sync logic
so it only merges in refreshed values for fields that are not currently being
edited, or skip resetting editedUser while any field is dirty. Keep the fix
localized to the BaseUserProfile state synchronization path around setEditedUser
and editingFields.

In `@packages/react/src/components/presentation/UserProfile/UserProfile.tsx`:
- Around line 78-87: The `updatedAttributes` merge in `UserProfile` is shallow,
so nested patches from `BaseUserProfile` (for example `name.givenName`)
overwrite sibling fields in `attributes`. Update the merge logic to deep-merge
`payload` into the existing `profile['attributes']` document instead of using a
top-level spread, and keep the existing cleanup that removes `undefined`/`null`
values before the `PUT`.

In `@packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx`:
- Around line 21-29: The ThunderIDProvider import list includes an unused
HttpResponse symbol, which keeps the lint error active. Remove HttpResponse from
the imports in ThunderIDProvider so the remaining symbols like
ThunderIDRuntimeError, generateFlattenedUserProfile, and UserProfile are the
only referenced imports.
- Around line 59-109: The hardcoded DEFAULT_USER_PROFILE_SCHEMAS in
ThunderIDProvider is causing BaseUserProfile to render only the six built-in
fields and hide any custom or extension profile attributes. Update the schemas
flow so it comes from the authoritative profile metadata when available, or keep
schemas empty when using the flattened object from
generateFlattenedUserProfile(), ensuring BaseUserProfile can still surface all
non-default fields.
- Around line 214-227: In ThunderIDProvider’s user-profile load flow, the
/users/me failure path is leaving profileData populated from claims only, which
makes the profile editable without a full attributes snapshot. Update the logic
around getScim2Me and the subsequent setUser/setUserProfile so that, when the
fetch fails, you either keep the previously fetched profile.attributes state or
mark the profile as read-only instead of falling back to a claims-only editable
profile. Make sure the downstream PUT /users/me merge path still has a complete
attributes object, using the existing profileData, generateFlattenedUserProfile,
and DEFAULT_USER_PROFILE_SCHEMAS flow as the key points to adjust.

---

Outside diff comments:
In
`@packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx`:
- Around line 23-47: The TokenCallback test fixture is using an unsafe any-typed
context object, which causes type-checking issues in the assertions and render
setup. Update the thunderIDContext declaration to use ThunderIDContext (or a
compatible typed shape) and keep the existing mocked methods like
getStorageManager, signIn, and signUp typed accordingly so the test exercises
the real context contract without unsafe assignments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cce87ffa-d726-4f5b-b942-01afbf49a26f

📥 Commits

Reviewing files that changed from the base of the PR and between a4f4283 and 3071aa8.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (18)
  • packages/browser/package.json
  • packages/javascript/package.json
  • packages/javascript/src/api/__tests__/getScim2Me.test.ts
  • packages/javascript/src/api/__tests__/updateMeProfile.test.ts
  • packages/javascript/src/api/getScim2Me.ts
  • packages/javascript/src/api/updateMeProfile.ts
  • packages/javascript/src/errors/__tests__/ThunderIDAPIError.test.ts
  • packages/javascript/src/theme/createTheme.test.ts
  • packages/javascript/src/utils/getAuthorizeRequestUrlParams.ts
  • packages/react-router/package.json
  • packages/react/package.json
  • packages/react/src/api/updateMeProfile.ts
  • packages/react/src/components/auth/Callback/__tests__/Callback.test.tsx
  • packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx
  • packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx
  • packages/react/src/components/presentation/UserProfile/UserProfile.tsx
  • packages/react/src/contexts/ThunderID/ThunderIDContext.ts
  • packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx
💤 Files with no reviewable changes (1)
  • packages/javascript/src/errors/tests/ThunderIDAPIError.test.ts

Comment thread packages/javascript/src/api/__tests__/getScim2Me.test.ts
Comment thread packages/javascript/src/api/__tests__/updateMeProfile.test.ts
Comment thread packages/javascript/src/api/getScim2Me.ts Outdated
Comment thread packages/javascript/src/api/updateMeProfile.ts
Comment thread packages/javascript/src/api/updateMeProfile.ts
Comment thread packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx Outdated
Comment thread packages/react/src/components/presentation/UserProfile/UserProfile.tsx Outdated
Comment thread packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx Outdated
Comment thread packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx Outdated
Comment thread packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx Outdated
@janithjay janithjay force-pushed the feat/profile-edit-put branch from 3071aa8 to 50bf8a9 Compare June 26, 2026 09:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx`:
- Around line 59-107: The default user profile schema in ThunderIDProvider is
still using snake_case keys, which no longer match the /users/me contract.
Update DEFAULT_USER_PROFILE_SCHEMAS to use the camelCase attribute names
expected by the read/write flow and tests, and make sure the corresponding
schema entries in ThunderIDProvider stay consistent with the values used when
hydrating and saving the profile.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9ed55479-ef81-47dd-945d-14055369fa96

📥 Commits

Reviewing files that changed from the base of the PR and between 3071aa8 and 50bf8a9.

📒 Files selected for processing (14)
  • packages/javascript/src/api/__tests__/getScim2Me.test.ts
  • packages/javascript/src/api/__tests__/updateMeProfile.test.ts
  • packages/javascript/src/api/getScim2Me.ts
  • packages/javascript/src/api/updateMeProfile.ts
  • packages/javascript/src/errors/__tests__/ThunderIDAPIError.test.ts
  • packages/javascript/src/theme/createTheme.test.ts
  • packages/javascript/src/utils/getAuthorizeRequestUrlParams.ts
  • packages/react/src/api/updateMeProfile.ts
  • packages/react/src/components/auth/Callback/__tests__/Callback.test.tsx
  • packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx
  • packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx
  • packages/react/src/components/presentation/UserProfile/UserProfile.tsx
  • packages/react/src/contexts/ThunderID/ThunderIDContext.ts
  • packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx
💤 Files with no reviewable changes (1)
  • packages/javascript/src/errors/tests/ThunderIDAPIError.test.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/react/src/contexts/ThunderID/ThunderIDContext.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/react/src/components/auth/Callback/tests/Callback.test.tsx
  • packages/javascript/src/utils/getAuthorizeRequestUrlParams.ts
  • packages/javascript/src/theme/createTheme.test.ts
  • packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx

Comment on lines +59 to +107
const DEFAULT_USER_PROFILE_SCHEMAS: Schema[] = [
{
name: 'username',
displayName: 'Username',
type: 'STRING',
mutability: 'READ_ONLY',
required: true,
displayOrder: '0',
},
{
name: 'email',
displayName: 'Email',
type: 'STRING',
mutability: 'READ_WRITE',
required: true,
displayOrder: '1',
},
{
name: 'given_name',
displayName: 'First Name',
type: 'STRING',
mutability: 'READ_WRITE',
required: false,
displayOrder: '2',
},
{
name: 'family_name',
displayName: 'Last Name',
type: 'STRING',
mutability: 'READ_WRITE',
required: false,
displayOrder: '3',
},
{
name: 'phone_number',
displayName: 'Phone Number',
type: 'STRING',
mutability: 'READ_WRITE',
required: false,
displayOrder: '4',
},
{
name: 'picture',
displayName: 'Profile Picture URL',
type: 'STRING',
mutability: 'READ_WRITE',
required: false,
displayOrder: '5',
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Align the default schema keys with the new /users/me contract.

These defaults still use snake_case names like given_name and family_name, but the new read/write path and its tests operate on camelCase attributes like givenName and familyName. With this schema list, the profile UI hydrates from one key set and PUT /users/me persists another, so built-in fields can render stale/blank values and save under the wrong attribute names.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx` around lines 59
- 107, The default user profile schema in ThunderIDProvider is still using
snake_case keys, which no longer match the /users/me contract. Update
DEFAULT_USER_PROFILE_SCHEMAS to use the camelCase attribute names expected by
the read/write flow and tests, and make sure the corresponding schema entries in
ThunderIDProvider stay consistent with the values used when hydrating and saving
the profile.

@janithjay janithjay force-pushed the feat/profile-edit-put branch from 50bf8a9 to fbaff18 Compare June 26, 2026 09:53
@janithjay janithjay marked this pull request as draft June 30, 2026 04:34
@janithjay janithjay force-pushed the feat/profile-edit-put branch from fbaff18 to 1f7e1f5 Compare June 30, 2026 08:17
@janithjay janithjay marked this pull request as ready for review June 30, 2026 08:26
@JayaShakthi97 JayaShakthi97 changed the title Update profile data edit API endpoints to /users/me and switch from PATCH to PUT (React package) [react] Update profile data edit API endpoints to use PUT /users/me Jun 30, 2026
@janithjay janithjay marked this pull request as draft June 30, 2026 11:11
@janithjay janithjay force-pushed the feat/profile-edit-put branch from 1f7e1f5 to 0bfd8b3 Compare June 30, 2026 12:48
@janithjay janithjay force-pushed the feat/profile-edit-put branch from 0bfd8b3 to 8199b64 Compare June 30, 2026 13:29
@janithjay janithjay marked this pull request as ready for review June 30, 2026 16:40

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/javascript/src/api/updateMeProfile.ts`:
- Around line 106-108: The updateMeProfile helper is still wrapping any runtime
payload directly into attributes, so non-object values can slip through. Add a
guard in updateMeProfile before building the data object to reject null, arrays,
and primitives, and only proceed when payload is a plain object. Use the
updateMeProfile payload handling around the attributes assignment to locate the
change and make the validation happen before the request body is constructed.
- Around line 113-120: The updateMeProfile request setup is merging
requestConfig.headers with object spread, which loses values when headers is a
Headers instance or header tuples. In updateMeProfile, normalize
requestConfig.headers with new Headers(...) before adding Accept and
Content-Type so existing auth/routing headers are preserved in the RequestInit
headers.

In
`@packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx`:
- Around line 73-77: The shared test fixtures in TokenCallback.test.tsx are
still typed as any, which keeps the unsafe-assignment warnings around the render
setup. Update the reusable ThunderIDContext fixture and the onNavigate/onError
callback mocks to use real types inferred from TokenCallback and
ThunderIDContext, then reuse those typed fixtures across all test cases so the
render calls no longer rely on any.

In `@packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx`:
- Around line 145-159: The sync logic in BaseUserProfile’s useEffect and
setEditedUser currently starts from prev, so keys that disappear from nextUser
remain in editedUser. Update the merge in this effect to rebuild the edited
state from the refreshed profile and remove any non-editing fields that are no
longer present in nextUser, while still preserving fields currently being edited
via editingFields.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bf8c426c-d3cc-4435-b789-632dd98ac63f

📥 Commits

Reviewing files that changed from the base of the PR and between 1f7e1f5 and 8199b64.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • packages/javascript/src/api/__tests__/getScim2Me.test.ts
  • packages/javascript/src/api/__tests__/updateMeProfile.test.ts
  • packages/javascript/src/api/getScim2Me.ts
  • packages/javascript/src/api/updateMeProfile.ts
  • packages/javascript/src/errors/__tests__/ThunderIDAPIError.test.ts
  • packages/javascript/src/models/config.ts
  • packages/javascript/src/theme/createTheme.test.ts
  • packages/javascript/src/utils/getAuthorizeRequestUrlParams.ts
  • packages/react/package.json
  • packages/react/src/api/updateMeProfile.ts
  • packages/react/src/components/auth/Callback/__tests__/Callback.test.tsx
  • packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx
  • packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx
  • packages/react/src/components/presentation/UserProfile/UserProfile.tsx
  • packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx
💤 Files with no reviewable changes (1)
  • packages/javascript/src/errors/tests/ThunderIDAPIError.test.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/react/src/components/presentation/UserProfile/UserProfile.tsx
  • packages/javascript/src/utils/getAuthorizeRequestUrlParams.ts
  • packages/javascript/src/api/getScim2Me.ts
  • packages/react/src/components/auth/Callback/tests/Callback.test.tsx
  • packages/javascript/src/theme/createTheme.test.ts
  • packages/react/package.json
  • packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx

Comment thread packages/javascript/src/api/updateMeProfile.ts
Comment thread packages/javascript/src/api/updateMeProfile.ts
Comment on lines +73 to +77
render(
<ThunderIDContext.Provider value={thunderIDContext}>
<TokenCallback onNavigate={onNavigate} />
</ThunderIDContext.Provider>,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git ls-files 'packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx' \
  'packages/react/src/**/ThunderIDContext*' \
  'packages/react/src/**/ThunderID*' \
  'packages/react/src/**/context*' \
  'packages/react/src/**/test*' | sed 's#^`#FILE` #'

printf '\n--- TokenCallback.test.tsx ---\n'
cat -n packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx

printf '\n--- ThunderIDContext search ---\n'
rg -n --hidden --glob '!**/node_modules/**' 'ThunderIDContext|mockSignIn|mockSignUp|no-unsafe-assignment|any' packages/react/src

Repository: thunder-id/javascript-sdks

Length of output: 50382


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,220p' packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx

Repository: thunder-id/javascript-sdks

Length of output: 5856


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n--- ThunderIDContext.ts ---\n'
cat -n packages/react/src/contexts/ThunderID/ThunderIDContext.ts

printf '\n--- useThunderID.ts ---\n'
cat -n packages/react/src/contexts/ThunderID/useThunderID.ts

printf '\n--- ThunderIDProvider.tsx (relevant type/value slices) ---\n'
sed -n '1,120p' packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx
printf '\n...\n'
sed -n '430,470p' packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx

Repository: thunder-id/javascript-sdks

Length of output: 18777


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n--- TokenCallback.tsx ---\n'
cat -n packages/react/src/components/auth/Callback/TokenCallback.tsx

printf '\n--- related prop/type search ---\n'
rg -n 'type .*TokenCallback|interface .*TokenCallback|onNavigate|onError' packages/react/src/components/auth/Callback packages/react/src/components/auth

Repository: thunder-id/javascript-sdks

Length of output: 26389


Type the shared test fixtures

thunderIDContext, onNavigate, and onError are still any, so these renders keep the unsafe-assignment noise. Give the shared context fixture and callback mocks real types and reuse them across the four cases.

🧰 Tools
🪛 ESLint

[error] 74-74: Unsafe assignment of an any value.

(@typescript-eslint/no-unsafe-assignment)


[error] 75-75: Unsafe assignment of an any value.

(@typescript-eslint/no-unsafe-assignment)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react/src/components/auth/Callback/__tests__/TokenCallback.test.tsx`
around lines 73 - 77, The shared test fixtures in TokenCallback.test.tsx are
still typed as any, which keeps the unsafe-assignment warnings around the render
setup. Update the reusable ThunderIDContext fixture and the onNavigate/onError
callback mocks to use real types inferred from TokenCallback and
ThunderIDContext, then reuse those typed fixtures across all test cases so the
render calls no longer rely on any.

Source: Linters/SAST tools

Comment on lines +145 to +159
useEffect(() => {
const nextUser = flattenedProfile ?? profile;
if (!nextUser) return;

setEditedUser((prev: any) => {
if (!prev) return nextUser;

const updated = {...prev};
Object.keys(nextUser).forEach((key) => {
if (!editingFields[key]) {
updated[key] = nextUser[key];
}
});
return updated;
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Drop keys that disappeared from the refreshed profile.

This sync starts from prev, so any field missing from nextUser stays in editedUser indefinitely. That leaves stale values available when the field is reopened and can re-submit removed data on a later save.

Suggested fix
     setEditedUser((prev: any) => {
       if (!prev) return nextUser;
 
-      const updated = {...prev};
-      Object.keys(nextUser).forEach((key) => {
-        if (!editingFields[key]) {
-          updated[key] = nextUser[key];
-        }
-      });
+      const updated = {...nextUser};
+      Object.keys(prev).forEach((key) => {
+        if (editingFields[key]) {
+          updated[key] = prev[key];
+        }
+      });
       return updated;
     });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
const nextUser = flattenedProfile ?? profile;
if (!nextUser) return;
setEditedUser((prev: any) => {
if (!prev) return nextUser;
const updated = {...prev};
Object.keys(nextUser).forEach((key) => {
if (!editingFields[key]) {
updated[key] = nextUser[key];
}
});
return updated;
});
useEffect(() => {
const nextUser = flattenedProfile ?? profile;
if (!nextUser) return;
setEditedUser((prev: any) => {
if (!prev) return nextUser;
const updated = {...nextUser};
Object.keys(prev).forEach((key) => {
if (editingFields[key]) {
updated[key] = prev[key];
}
});
return updated;
});
🧰 Tools
🪛 ESLint

[error] 149-149: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)


[error] 152-152: Unsafe assignment of an any value.

(@typescript-eslint/no-unsafe-assignment)


[error] 155-155: Unsafe assignment of an any value.

(@typescript-eslint/no-unsafe-assignment)


[error] 155-155: Unsafe member access [key] on an any value.

(@typescript-eslint/no-unsafe-member-access)


[error] 158-158: Unsafe return of a value of type any.

(@typescript-eslint/no-unsafe-return)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx`
around lines 145 - 159, The sync logic in BaseUserProfile’s useEffect and
setEditedUser currently starts from prev, so keys that disappear from nextUser
remain in editedUser. Update the merge in this effect to rebuild the edited
state from the refreshed profile and remove any non-editing fields that are no
longer present in nextUser, while still preserving fields currently being edited
via editingFields.

Comment thread packages/javascript/src/api/getScim2Me.ts
Comment thread packages/javascript/src/models/config.ts
@janithjay janithjay marked this pull request as draft July 2, 2026 04:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants