diff --git a/.changeset/fresh-signins-reset.md b/.changeset/fresh-signins-reset.md new file mode 100644 index 00000000000..fb46b45f91f --- /dev/null +++ b/.changeset/fresh-signins-reset.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Fix `useSignIn()` returning a stale resource after resetting sign-in and starting a new SSO flow. diff --git a/packages/clerk-js/src/core/resources/Client.ts b/packages/clerk-js/src/core/resources/Client.ts index 899600f1b8d..c5d8d4b3602 100644 --- a/packages/clerk-js/src/core/resources/Client.ts +++ b/packages/clerk-js/src/core/resources/Client.ts @@ -163,7 +163,7 @@ export class Client extends BaseResource implements ClientResource { this.signUp = new SignUp(data.sign_up); } - if (data.sign_in && this.signIn instanceof SignIn && this.signIn.id === data.sign_in.id) { + if (data.sign_in && this.signIn instanceof SignIn && (this.signIn.id === data.sign_in.id || !this.signIn.id)) { this.signIn.__internal_updateFromJSON(data.sign_in); } else { this.signIn = new SignIn(data.sign_in); diff --git a/packages/clerk-js/src/core/resources/__tests__/Client.test.ts b/packages/clerk-js/src/core/resources/__tests__/Client.test.ts index 5514e1cc855..1cb8c599e67 100644 --- a/packages/clerk-js/src/core/resources/__tests__/Client.test.ts +++ b/packages/clerk-js/src/core/resources/__tests__/Client.test.ts @@ -226,6 +226,44 @@ describe('Client Singleton', () => { expect(client.signIn.id).toBe('test_sign_in_id_v2'); }); + it('preserves sign in identity after resetSignIn when fromJSON receives a new attempt', () => { + const user = createUser({ first_name: 'John', last_name: 'Doe', id: 'user_1' }); + const initialClientJSON: ClientJSON = { + object: 'client', + id: 'test_id', + status: 'active', + last_active_session_id: null, + sign_in: createSignIn({ id: 'test_sign_in_id', status: 'needs_first_factor' }, user), + sign_up: null, + sessions: [], + created_at: Date.now() - 1000, + updated_at: Date.now(), + } as any; + + // @ts-expect-error We cannot mess with the singleton when tests are running in parallel + const client = new Client(initialClientJSON); + client.resetSignIn(); + const resetSignIn = client.signIn; + + client.fromJSON({ + ...initialClientJSON, + sign_in: createSignIn( + { + id: 'test_sign_in_id_v2', + status: 'needs_second_factor', + identifier: 'updated@example.com', + }, + user, + ), + updated_at: Date.now() + 1000, + }); + + expect(client.signIn).toBe(resetSignIn); + expect(client.signIn.id).toBe('test_sign_in_id_v2'); + expect(client.signIn.identifier).toBe('updated@example.com'); + expect(client.signIn.status).toBe('needs_second_factor'); + }); + it('has the same initial properties', () => { const clientJSON = { object: 'client',