Skip to content

Commit 6b27d54

Browse files
authored
fix(clerk-js): patch active signup resource in Future API (#8558)
1 parent b45777c commit 6b27d54

3 files changed

Lines changed: 144 additions & 2 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/clerk-js': patch
3+
---
4+
5+
Fix Future `signUp.update()` and `signUp.sso()` to patch the active sign-up resource URL when continuing an existing sign-up.

packages/clerk-js/src/core/resources/SignUp.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,7 @@ class SignUpFuture implements SignUpFutureResource {
886886
unsafeMetadata: params.unsafeMetadata ? normalizeUnsafeMetadata(params.unsafeMetadata) : undefined,
887887
};
888888

889-
await this.#resource.__internal_basePatch({ path: this.#resource.pathRoot, body });
889+
await this.#resource.__internal_basePatch({ body });
890890
});
891891
}
892892

@@ -1039,7 +1039,7 @@ class SignUpFuture implements SignUpFutureResource {
10391039
captchaError,
10401040
};
10411041
if (this.#resource.id) {
1042-
return this.#resource.__internal_basePatch({ path: this.#resource.pathRoot, body });
1042+
return this.#resource.__internal_basePatch({ body });
10431043
}
10441044
return this.#resource.__internal_basePost({ path: this.#resource.pathRoot, body });
10451045
};

packages/clerk-js/src/core/resources/__tests__/SignUp.test.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,35 @@ describe('SignUp', () => {
364364
});
365365
});
366366

367+
describe('update', () => {
368+
afterEach(() => {
369+
vi.clearAllMocks();
370+
vi.unstubAllGlobals();
371+
SignUp.clerk = {} as any;
372+
});
373+
374+
it('patches the active sign up resource', async () => {
375+
const mockFetch = vi.fn().mockResolvedValue({
376+
client: null,
377+
response: { id: 'signup_123', first_name: 'Ada' },
378+
});
379+
BaseResource._fetch = mockFetch;
380+
381+
const signUp = new SignUp({ id: 'signup_123' } as any);
382+
await signUp.__internal_future.update({ firstName: 'Ada' });
383+
384+
expect(mockFetch).toHaveBeenCalledWith(
385+
expect.objectContaining({
386+
method: 'PATCH',
387+
path: '/client/sign_ups/signup_123',
388+
body: expect.objectContaining({
389+
firstName: 'Ada',
390+
}),
391+
}),
392+
);
393+
});
394+
});
395+
367396
describe('sendPhoneCode', () => {
368397
afterEach(() => {
369398
vi.clearAllMocks();
@@ -669,6 +698,114 @@ describe('SignUp', () => {
669698
);
670699
});
671700

701+
it('continues an existing sign up via the resource URL', async () => {
702+
vi.stubGlobal('window', { location: { origin: 'https://example.com' } });
703+
704+
const mockBuildUrlWithAuth = vi.fn().mockReturnValue('https://example.com/sso-callback');
705+
SignUp.clerk = {
706+
buildUrlWithAuth: mockBuildUrlWithAuth,
707+
__internal_environment: {
708+
displayConfig: {
709+
captchaOauthBypass: [],
710+
},
711+
},
712+
} as any;
713+
714+
const mockFetch = vi.fn().mockResolvedValue({
715+
client: null,
716+
response: {
717+
id: 'signup_123',
718+
verifications: {
719+
external_account: {
720+
status: 'complete',
721+
},
722+
},
723+
},
724+
});
725+
BaseResource._fetch = mockFetch;
726+
727+
const signUp = new SignUp({ id: 'signup_123' } as any);
728+
await signUp.__internal_future.sso({
729+
strategy: 'oauth_google',
730+
redirectUrl: '/complete',
731+
redirectCallbackUrl: '/sso-callback',
732+
});
733+
734+
expect(mockFetch).toHaveBeenCalledWith(
735+
expect.objectContaining({
736+
method: 'PATCH',
737+
path: '/client/sign_ups/signup_123',
738+
body: expect.objectContaining({
739+
strategy: 'oauth_google',
740+
redirectUrl: 'https://example.com/sso-callback',
741+
actionCompleteRedirectUrl: 'https://example.com/complete',
742+
}),
743+
}),
744+
);
745+
});
746+
747+
it('continues a ticket sign up with sso via the resource URL', async () => {
748+
vi.stubGlobal('window', { location: { origin: 'https://example.com' } });
749+
750+
const mockBuildUrlWithAuth = vi.fn().mockReturnValue('https://example.com/sso-callback');
751+
SignUp.clerk = {
752+
buildUrlWithAuth: mockBuildUrlWithAuth,
753+
__internal_environment: {
754+
displayConfig: {
755+
captchaOauthBypass: [],
756+
},
757+
},
758+
} as any;
759+
760+
const mockFetch = vi
761+
.fn()
762+
.mockResolvedValueOnce({
763+
client: null,
764+
response: { id: 'signup_123' },
765+
})
766+
.mockResolvedValueOnce({
767+
client: null,
768+
response: {
769+
id: 'signup_123',
770+
verifications: {
771+
external_account: {
772+
status: 'complete',
773+
},
774+
},
775+
},
776+
});
777+
BaseResource._fetch = mockFetch;
778+
779+
const signUp = new SignUp();
780+
await signUp.__internal_future.ticket({ ticket: 'provided_ticket' });
781+
await signUp.__internal_future.sso({
782+
strategy: 'oauth_google',
783+
redirectUrl: '/complete',
784+
redirectCallbackUrl: '/sso-callback',
785+
});
786+
787+
expect(mockFetch).toHaveBeenNthCalledWith(
788+
1,
789+
expect.objectContaining({
790+
method: 'POST',
791+
path: '/client/sign_ups',
792+
body: expect.objectContaining({
793+
ticket: 'provided_ticket',
794+
}),
795+
}),
796+
);
797+
expect(mockFetch).toHaveBeenNthCalledWith(
798+
2,
799+
expect.objectContaining({
800+
method: 'PATCH',
801+
path: '/client/sign_ups/signup_123',
802+
body: expect.objectContaining({
803+
strategy: 'oauth_google',
804+
}),
805+
}),
806+
);
807+
});
808+
672809
it('uses popup when provided', async () => {
673810
vi.stubGlobal('window', { location: { origin: 'https://example.com' } });
674811

0 commit comments

Comments
 (0)