Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/wild-insects-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clerk/ui": patch
---

Fixed unhandled TypeError when `unsafeMetadata` is passed to `<SignUp />`
10 changes: 9 additions & 1 deletion packages/ui/src/components/SignUp/SignUpStart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,15 @@ function SignUpStartInternal(): JSX.Element {
}, [] as Array<FormControlState>);

if (unsafeMetadata) {
fieldsToSubmit.push({ id: 'unsafeMetadata', value: unsafeMetadata } as any);
const noop = () => {};
fieldsToSubmit.push({
id: 'unsafeMetadata',
value: unsafeMetadata,
clearFeedback: noop,
setValue: noop,
onChange: noop,
setError: noop,
} as any);
}

if (fields.ticket || hasExistingSignUpWithTicket) {
Expand Down
40 changes: 40 additions & 0 deletions packages/ui/src/components/SignUp/__tests__/SignUpStart.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ClerkAPIResponseError } from '@clerk/shared/error';
import { OAUTH_PROVIDERS } from '@clerk/shared/oauth';
import type { SignUpResource } from '@clerk/shared/types';
import { describe, expect, it, vi } from 'vitest';
Expand Down Expand Up @@ -452,6 +453,45 @@ describe('SignUpStart', () => {
);
});

it('does not throw when unsafeMetadata is set and signUp.create rejects with an API error', async () => {
const { wrapper, fixtures, props } = await createFixtures(f => {
f.withEmailAddress();
f.withPassword();
});
fixtures.signUp.create.mockRejectedValueOnce(
new ClerkAPIResponseError('Error', {
data: [
{
code: 'form_password_pwned',
long_message: 'Password has been found in an online data breach.',
message: 'Password has been found in an online data breach.',
meta: { param_name: 'password' },
},
],
status: 422,
}),
);
props.setProps({ unsafeMetadata: { foo: 'bar' } });

Object.defineProperty(window, 'location', {
writable: true,
value: { href: 'http://localhost/sign-up?__clerk_ticket=test_ticket' },
});
Object.defineProperty(window, 'history', {
writable: true,
value: { replaceState: vi.fn() },
});

render(
<CardStateProvider>
<SignUpStart />
</CardStateProvider>,
{ wrapper },
);

await waitFor(() => expect(fixtures.signUp.create).toHaveBeenCalled());
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
});

it('removes the ticket from the url when completing the sign up', async () => {
const { wrapper, fixtures } = await createFixtures(f => {
f.withEmailAddress();
Expand Down
Loading