@shipfox/client-auth 0.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +39 -0
  3. package/dist/feature.d.ts +0 -4
  4. package/dist/feature.d.ts.map +1 -1
  5. package/dist/feature.js +0 -5
  6. package/dist/feature.js.map +1 -1
  7. package/dist/hooks/api/signup-auth.d.ts +4 -0
  8. package/dist/hooks/api/signup-auth.d.ts.map +1 -1
  9. package/dist/hooks/api/verify-email-auth.d.ts +4 -1
  10. package/dist/hooks/api/verify-email-auth.d.ts.map +1 -1
  11. package/dist/index.d.ts +0 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +0 -1
  14. package/dist/index.js.map +1 -1
  15. package/dist/pages/email-verification-resend-model.d.ts +0 -1
  16. package/dist/pages/email-verification-resend-model.d.ts.map +1 -1
  17. package/dist/pages/email-verification-resend-model.js +0 -4
  18. package/dist/pages/email-verification-resend-model.js.map +1 -1
  19. package/dist/pages/signup-page.d.ts.map +1 -1
  20. package/dist/pages/signup-page.js +90 -36
  21. package/dist/pages/signup-page.js.map +1 -1
  22. package/dist/tsconfig.test.tsbuildinfo +1 -1
  23. package/package.json +19 -42
  24. package/src/feature.ts +0 -1
  25. package/src/index.ts +0 -1
  26. package/src/pages/email-verification-resend-model.test.ts +0 -10
  27. package/src/pages/email-verification-resend-model.ts +0 -6
  28. package/src/pages/signup-page.test.tsx +60 -6
  29. package/src/pages/signup-page.tsx +87 -36
  30. package/test/pages.tsx +0 -7
  31. package/tsconfig.build.tsbuildinfo +1 -1
  32. package/dist/pages/verify-email-page.d.ts +0 -2
  33. package/dist/pages/verify-email-page.d.ts.map +0 -1
  34. package/dist/pages/verify-email-page.js +0 -57
  35. package/dist/pages/verify-email-page.js.map +0 -1
  36. package/dist/routes/verify-email.d.ts +0 -5
  37. package/dist/routes/verify-email.d.ts.map +0 -1
  38. package/dist/routes/verify-email.js +0 -11
  39. package/dist/routes/verify-email.js.map +0 -1
  40. package/src/pages/verify-email-page.test.tsx +0 -82
  41. package/src/pages/verify-email-page.tsx +0 -48
  42. package/src/routes/verify-email.tsx +0 -11
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shipfox/client-auth",
3
3
  "license": "MIT",
4
- "version": "0.2.0",
4
+ "version": "2.0.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/ShipfoxHQ/shipfox.git",
@@ -11,55 +11,32 @@
11
11
  "main": "dist/index.js",
12
12
  "types": "dist/index.d.ts",
13
13
  "imports": {
14
- "#*": {
15
- "types": "./src/*",
16
- "workspace-source": "./src/*",
17
- "development": "./src/*",
18
- "default": "./dist/*"
19
- },
14
+ "#*": "./dist/*",
20
15
  "#test/*": "./test/*"
21
16
  },
22
17
  "exports": {
23
18
  ".": {
24
- "development": {
25
- "types": "./src/index.ts",
26
- "default": "./src/index.ts"
27
- },
28
- "default": {
29
- "types": "./dist/index.d.ts",
30
- "default": "./dist/index.js"
31
- }
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.js"
32
21
  },
33
22
  "./feature": {
34
- "development": {
35
- "types": "./src/feature.ts",
36
- "default": "./src/feature.ts"
37
- },
38
- "default": {
39
- "types": "./dist/feature.d.ts",
40
- "default": "./dist/feature.js"
41
- }
23
+ "types": "./dist/feature.d.ts",
24
+ "default": "./dist/feature.js"
42
25
  },
43
26
  "./routes/*": {
44
- "development": {
45
- "types": "./src/routes/*.tsx",
46
- "default": "./src/routes/*.tsx"
47
- },
48
- "default": {
49
- "types": "./dist/routes/*.d.ts",
50
- "default": "./dist/routes/*.js"
51
- }
27
+ "types": "./dist/routes/*.d.ts",
28
+ "default": "./dist/routes/*.js"
52
29
  }
53
30
  },
54
31
  "dependencies": {
55
32
  "@swc/helpers": "^0.5.17",
56
33
  "@tanstack/react-form": "^1.32.0",
57
- "@shipfox/api-auth-dto": "2.0.0",
58
- "@shipfox/api-workspaces-dto": "2.0.0",
59
- "@shipfox/client-shell": "0.2.0",
60
- "@shipfox/client-api": "0.2.0",
61
- "@shipfox/client-ui": "0.2.0",
62
- "@shipfox/react-ui": "0.3.1"
34
+ "@shipfox/api-auth-dto": "6.0.0",
35
+ "@shipfox/client-api": "1.0.0",
36
+ "@shipfox/client-shell": "2.0.0",
37
+ "@shipfox/api-workspaces-dto": "6.0.0",
38
+ "@shipfox/client-ui": "2.0.0",
39
+ "@shipfox/react-ui": "0.3.3"
63
40
  },
64
41
  "peerDependencies": {
65
42
  "@tanstack/react-query": "^5.101.0",
@@ -95,12 +72,12 @@
95
72
  "tailwindcss": "^4.1.13",
96
73
  "vite": "^8.0.3",
97
74
  "vitest": "^4.1.5",
98
- "@shipfox/biome": "1.8.1",
99
- "@shipfox/client-test-setup": "0.0.2",
75
+ "@shipfox/client-test-setup": "0.0.3",
76
+ "@shipfox/swc": "1.2.6",
77
+ "@shipfox/vitest": "1.2.3",
78
+ "@shipfox/typescript": "1.1.7",
100
79
  "@shipfox/ts-config": "1.3.8",
101
- "@shipfox/typescript": "1.1.6",
102
- "@shipfox/swc": "1.2.5",
103
- "@shipfox/vitest": "1.2.2"
80
+ "@shipfox/biome": "1.8.2"
104
81
  },
105
82
  "scripts": {
106
83
  "build": "shipfox-swc",
package/src/feature.ts CHANGED
@@ -8,7 +8,6 @@ export const authFeature = defineClientFeature({
8
8
  {path: '/auth/logout', parent: 'root', impl: '@shipfox/client-auth/routes/logout'},
9
9
  {path: '/auth/reset', parent: 'root', impl: '@shipfox/client-auth/routes/reset'},
10
10
  {path: '/auth/signup', parent: 'root', impl: '@shipfox/client-auth/routes/signup'},
11
- {path: '/auth/verify-email', parent: 'root', impl: '@shipfox/client-auth/routes/verify-email'},
12
11
  {
13
12
  path: '/setup/workspaces/new',
14
13
  parent: 'root',
package/src/index.ts CHANGED
@@ -8,7 +8,6 @@ export * from './pages/login-page.js';
8
8
  export * from './pages/logout-page.js';
9
9
  export * from './pages/password-reset-page.js';
10
10
  export * from './pages/signup-page.js';
11
- export * from './pages/verify-email-page.js';
12
11
  export * from './pages/workspace-onboarding-page.js';
13
12
  export * from './state/auth.js';
14
13
  export {
@@ -1,19 +1,9 @@
1
- import {EMAIL_VERIFICATION_RESEND_COOLDOWN_SECONDS} from '@shipfox/api-auth-dto';
2
1
  import {
3
- getLocalResendAvailableAt,
4
2
  getResendRemainingSeconds,
5
3
  parseNextResendAvailableAt,
6
4
  } from './email-verification-resend-model.js';
7
5
 
8
6
  describe('email verification resend model', () => {
9
- test('creates local cooldown targets from the shared cooldown', () => {
10
- const now = Date.UTC(2026, 4, 11, 12, 0, 0);
11
-
12
- const result = getLocalResendAvailableAt(now);
13
-
14
- expect(result).toBe(now + EMAIL_VERIFICATION_RESEND_COOLDOWN_SECONDS * 1000);
15
- });
16
-
17
7
  test('rounds remaining cooldown seconds up for display', () => {
18
8
  const now = Date.UTC(2026, 4, 11, 12, 0, 0);
19
9
 
@@ -1,9 +1,3 @@
1
- import {EMAIL_VERIFICATION_RESEND_COOLDOWN_SECONDS} from '@shipfox/api-auth-dto';
2
-
3
- export function getLocalResendAvailableAt(now: number): number {
4
- return now + EMAIL_VERIFICATION_RESEND_COOLDOWN_SECONDS * 1000;
5
- }
6
-
7
1
  export function getResendRemainingSeconds(params: {
8
2
  nextResendAvailableAt: number | undefined;
9
3
  now: number;
@@ -1,5 +1,5 @@
1
1
  import {configureApiClient} from '@shipfox/client-api';
2
- import {act, fireEvent, screen} from '@testing-library/react';
2
+ import {act, fireEvent, screen, waitFor} from '@testing-library/react';
3
3
  import {pageUserFactory} from '#test/factories/user.js';
4
4
  import {renderAuthPage} from '#test/pages.js';
5
5
  import {jsonResponse, requestUrl} from '#test/utils.js';
@@ -7,6 +7,12 @@ import {SignupPage} from './signup-page.js';
7
7
 
8
8
  const SUBMITTED_EMAIL_RE = /new@example.com/;
9
9
  const RESEND_COUNTDOWN_RE = /^Resend in \d+s$/;
10
+ function emailChallenge() {
11
+ return {
12
+ id: '019f814f-3cfd-779a-82f2-6588eefd572c',
13
+ next_resend_available_at: new Date(Date.now() + 60_000).toISOString(),
14
+ };
15
+ }
10
16
 
11
17
  describe('SignupPage', () => {
12
18
  beforeEach(() => {
@@ -24,7 +30,7 @@ describe('SignupPage', () => {
24
30
  }
25
31
  if (url === 'https://api.example.test/auth/signup' && input instanceof Request) {
26
32
  signupBody = await input.json();
27
- return jsonResponse({user}, {status: 201});
33
+ return jsonResponse({user, email_challenge: emailChallenge()}, {status: 201});
28
34
  }
29
35
  throw new Error(`Unexpected request: ${url}`);
30
36
  });
@@ -51,6 +57,50 @@ describe('SignupPage', () => {
51
57
  expect(screen.getByRole('link', {name: 'Log in'})).toHaveAttribute('href', '/auth/login');
52
58
  });
53
59
 
60
+ test('submits the eight-digit verification code with its signup challenge', async () => {
61
+ const user = pageUserFactory.build({email: 'new@example.com', name: 'New User'});
62
+ let confirmBody: unknown;
63
+ const session = {token: 'access-token', user};
64
+ const fetchImpl = vi.fn().mockImplementation(async (input: RequestInfo | URL) => {
65
+ const url = requestUrl(input);
66
+ if (url === 'https://api.example.test/auth/me') {
67
+ return jsonResponse({code: 'unauthorized', message: 'Unauthorized'}, {status: 401});
68
+ }
69
+ if (url === 'https://api.example.test/auth/signup') {
70
+ return jsonResponse({user, email_challenge: emailChallenge()}, {status: 201});
71
+ }
72
+ if (
73
+ url === 'https://api.example.test/auth/verify-email/confirm' &&
74
+ input instanceof Request
75
+ ) {
76
+ confirmBody = await input.json();
77
+ return jsonResponse(session);
78
+ }
79
+ if (url === 'https://api.example.test/auth/refresh') {
80
+ return jsonResponse(session);
81
+ }
82
+ throw new Error(`Unexpected request: ${url}`);
83
+ });
84
+ configureApiClient({fetchImpl});
85
+
86
+ renderAuthPage('/auth/signup', <SignupPage />);
87
+ fireEvent.change(await screen.findByLabelText('Name'), {target: {value: 'New User'}});
88
+ fireEvent.change(screen.getByLabelText('Email'), {target: {value: user.email}});
89
+ fireEvent.change(screen.getByLabelText('Password'), {target: {value: 'long secure password'}});
90
+ fireEvent.click(screen.getByRole('button', {name: 'Create account'}));
91
+ await screen.findByRole('heading', {name: 'Check your email'});
92
+ fireEvent.change(screen.getByLabelText('Verification code'), {target: {value: '12345678'}});
93
+ fireEvent.click(screen.getByRole('button', {name: 'Verify email'}));
94
+
95
+ await waitFor(() => {
96
+ expect(confirmBody).toEqual({
97
+ email: user.email,
98
+ challenge_id: emailChallenge().id,
99
+ code: '12345678',
100
+ });
101
+ });
102
+ });
103
+
54
104
  test('keeps credentials when switching to login', async () => {
55
105
  const fetchImpl = vi
56
106
  .fn()
@@ -179,7 +229,9 @@ describe('SignupPage', () => {
179
229
  .mockResolvedValueOnce(
180
230
  jsonResponse({code: 'unauthorized', message: 'Unauthorized'}, {status: 401}),
181
231
  )
182
- .mockResolvedValueOnce(jsonResponse({user}, {status: 201}));
232
+ .mockResolvedValueOnce(
233
+ jsonResponse({user, email_challenge: emailChallenge()}, {status: 201}),
234
+ );
183
235
  configureApiClient({fetchImpl});
184
236
 
185
237
  renderAuthPage('/auth/signup', <SignupPage />);
@@ -211,7 +263,7 @@ describe('SignupPage', () => {
211
263
  .mockResolvedValueOnce(
212
264
  jsonResponse({code: 'unauthorized', message: 'Unauthorized'}, {status: 401}),
213
265
  )
214
- .mockResolvedValueOnce(jsonResponse({user}, {status: 201}))
266
+ .mockResolvedValueOnce(jsonResponse({user, email_challenge: emailChallenge()}, {status: 201}))
215
267
  .mockResolvedValueOnce(
216
268
  jsonResponse({next_resend_available_at: nextResendAvailableAt}, {status: 200}),
217
269
  );
@@ -245,7 +297,7 @@ describe('SignupPage', () => {
245
297
  .mockResolvedValueOnce(
246
298
  jsonResponse({code: 'unauthorized', message: 'Unauthorized'}, {status: 401}),
247
299
  )
248
- .mockResolvedValueOnce(jsonResponse({user}, {status: 201}))
300
+ .mockResolvedValueOnce(jsonResponse({user, email_challenge: emailChallenge()}, {status: 201}))
249
301
  .mockResolvedValueOnce(
250
302
  jsonResponse({code: 'server-error', message: 'Server error'}, {status: 500}),
251
303
  );
@@ -273,7 +325,9 @@ describe('SignupPage', () => {
273
325
  .mockResolvedValueOnce(
274
326
  jsonResponse({code: 'unauthorized', message: 'Unauthorized'}, {status: 401}),
275
327
  )
276
- .mockResolvedValueOnce(jsonResponse({user}, {status: 201}));
328
+ .mockResolvedValueOnce(
329
+ jsonResponse({user, email_challenge: emailChallenge()}, {status: 201}),
330
+ );
277
331
  configureApiClient({fetchImpl});
278
332
 
279
333
  renderAuthPage('/auth/signup', <SignupPage />);
@@ -1,4 +1,4 @@
1
- import {signupBodySchema} from '@shipfox/api-auth-dto';
1
+ import {signupBodySchema, verifyEmailConfirmBodySchema} from '@shipfox/api-auth-dto';
2
2
  import {displayNameFieldError} from '@shipfox/client-ui';
3
3
  import {Button, ButtonLink} from '@shipfox/react-ui/button';
4
4
  import {Callout} from '@shipfox/react-ui/callout';
@@ -13,10 +13,9 @@ import {useEffect, useRef, useState} from 'react';
13
13
  import {AuthShell} from '#/components/auth-shell.js';
14
14
  import {useRefreshAuth} from '#hooks/api/refresh-auth.js';
15
15
  import {useSignupAuth} from '#hooks/api/signup-auth.js';
16
- import {useResendEmailVerificationAuth} from '#hooks/api/verify-email-auth.js';
16
+ import {useResendEmailVerificationAuth, useVerifyEmailAuth} from '#hooks/api/verify-email-auth.js';
17
17
  import {authFormDraftAtom, initialAuthFormDraft} from '#state/auth.js';
18
18
  import {
19
- getLocalResendAvailableAt,
20
19
  getResendRemainingSeconds,
21
20
  parseNextResendAvailableAt,
22
21
  } from './email-verification-resend-model.js';
@@ -30,6 +29,7 @@ import {
30
29
 
31
30
  export function SignupPage() {
32
31
  const signup = useSignupAuth();
32
+ const verifyEmail = useVerifyEmailAuth();
33
33
  const resendEmailVerification = useResendEmailVerificationAuth();
34
34
  const refreshAuth = useRefreshAuth();
35
35
  const navigate = useNavigate();
@@ -38,7 +38,7 @@ export function SignupPage() {
38
38
  const invitationPreview = useInvitationContext(invitationToken);
39
39
  const invitationPending = pendingInvitation(invitationPreview.data);
40
40
  const [authFormDraft, setAuthFormDraft] = useAtom(authFormDraftAtom);
41
- const [submittedEmail, setSubmittedEmail] = useState<string | undefined>();
41
+ const [emailChallenge, setEmailChallenge] = useState<{email: string; id: string} | undefined>();
42
42
  const [now, setNow] = useState(() => Date.now());
43
43
  const [nextResendAvailableAt, setNextResendAvailableAt] = useState<number | undefined>();
44
44
  const [formError, setFormError] = useState<string | undefined>();
@@ -90,9 +90,16 @@ export function SignupPage() {
90
90
  return;
91
91
  }
92
92
 
93
- setSubmittedEmail(result.user.email);
93
+ if (!result.email_challenge) {
94
+ throw new Error('Signup did not return an email verification challenge');
95
+ }
96
+ setEmailChallenge({email: result.user.email, id: result.email_challenge.id});
97
+ verificationForm.reset();
94
98
  setResendError(undefined);
95
- restartLocalCooldown();
99
+ setNow(Date.now());
100
+ setNextResendAvailableAt(
101
+ parseNextResendAvailableAt(result.email_challenge.next_resend_available_at),
102
+ );
96
103
  } catch (error) {
97
104
  const mapped = signupErrorToFormError(error);
98
105
  if (mapped.kind === 'field') {
@@ -107,8 +114,29 @@ export function SignupPage() {
107
114
  },
108
115
  });
109
116
 
117
+ const verificationForm = useForm({
118
+ defaultValues: {code: ''},
119
+ onSubmit: async ({value}) => {
120
+ if (!emailChallenge || verifyEmail.isPending) return;
121
+
122
+ setResendError(undefined);
123
+ try {
124
+ await verifyEmail.mutateAsync({
125
+ email: emailChallenge.email,
126
+ challenge_id: emailChallenge.id,
127
+ code: value.code,
128
+ });
129
+ await refreshAuth();
130
+ toast.success('Your email is verified. You are now logged in.');
131
+ await navigate({to: '/', replace: true});
132
+ } catch (error) {
133
+ setResendError(authErrorMessage(error));
134
+ }
135
+ },
136
+ });
137
+
110
138
  useEffect(() => {
111
- if (!submittedEmail || !nextResendAvailableAt) {
139
+ if (!emailChallenge || !nextResendAvailableAt) {
112
140
  return;
113
141
  }
114
142
 
@@ -126,13 +154,7 @@ export function SignupPage() {
126
154
  }
127
155
  }, 1000);
128
156
  return () => window.clearInterval(handle);
129
- }, [nextResendAvailableAt, submittedEmail]);
130
-
131
- function restartLocalCooldown() {
132
- const current = Date.now();
133
- setNow(current);
134
- setNextResendAvailableAt(getLocalResendAvailableAt(current));
135
- }
157
+ }, [emailChallenge, nextResendAvailableAt]);
136
158
 
137
159
  // When arriving from an invitation link, prefill the email and lock it.
138
160
  useEffect(() => {
@@ -156,17 +178,18 @@ export function SignupPage() {
156
178
  }, [form, setAuthFormDraft]);
157
179
 
158
180
  async function onResendVerificationEmail() {
159
- if (!submittedEmail || isResendCoolingDown || resendEmailVerification.isPending) return;
181
+ if (!emailChallenge || isResendCoolingDown || resendEmailVerification.isPending) return;
160
182
 
161
183
  setResendError(undefined);
162
184
  try {
163
- const result = await resendEmailVerification.mutateAsync({email: submittedEmail});
185
+ const result = await resendEmailVerification.mutateAsync({
186
+ email: emailChallenge.email,
187
+ challenge_id: emailChallenge.id,
188
+ });
164
189
  const nextAvailableAt = parseNextResendAvailableAt(result.next_resend_available_at);
165
190
  setNow(Date.now());
166
191
  if (nextAvailableAt !== undefined) {
167
192
  setNextResendAvailableAt(nextAvailableAt);
168
- } else {
169
- restartLocalCooldown();
170
193
  }
171
194
  toast.success('If another verification email can be sent, it will arrive shortly.');
172
195
  } catch (error) {
@@ -174,21 +197,49 @@ export function SignupPage() {
174
197
  }
175
198
  }
176
199
 
177
- if (submittedEmail) {
200
+ if (emailChallenge) {
178
201
  return (
179
202
  <AuthShell
180
203
  title="Check your email"
181
- description={`We sent a verification link to ${submittedEmail}.`}
204
+ description={`We sent an eight-digit verification code to ${emailChallenge.email}.`}
182
205
  >
183
206
  {resendError ? (
184
207
  <Callout role="alert" type="error">
185
208
  {resendError}
186
209
  </Callout>
187
210
  ) : null}
188
- <Callout role="alert" type="success">
189
- Click the verification link to activate your account, then come back to log in.
190
- </Callout>
191
- <div className="flex flex-col gap-8">
211
+ <form
212
+ className="flex flex-col gap-8"
213
+ noValidate
214
+ onSubmit={(event) => {
215
+ event.preventDefault();
216
+ void verificationForm.handleSubmit();
217
+ }}
218
+ >
219
+ <verificationForm.Field
220
+ name="code"
221
+ validators={{
222
+ onBlur: verifyEmailConfirmBodySchema.shape.code,
223
+ onSubmit: verifyEmailConfirmBodySchema.shape.code,
224
+ }}
225
+ >
226
+ {(field) => (
227
+ <FormField label="Verification code" id="verification-code" error={fieldError(field)}>
228
+ <FormFieldInput
229
+ autoComplete="one-time-code"
230
+ inputMode="numeric"
231
+ maxLength={8}
232
+ pattern="[0-9]{8}"
233
+ value={field.state.value}
234
+ onChange={(event) => field.handleChange(event.target.value.replace(/\D/gu, ''))}
235
+ onBlur={field.handleBlur}
236
+ />
237
+ </FormField>
238
+ )}
239
+ </verificationForm.Field>
240
+ <Button className="w-full" type="submit" isLoading={verifyEmail.isPending}>
241
+ Verify email
242
+ </Button>
192
243
  <Button
193
244
  aria-disabled={isResendCoolingDown ? true : undefined}
194
245
  className="w-full aria-disabled:cursor-not-allowed aria-disabled:opacity-70"
@@ -203,18 +254,18 @@ export function SignupPage() {
203
254
  ? `Resend in ${resendRemainingSeconds}s`
204
255
  : 'Resend verification email'}
205
256
  </Button>
206
- <Button
207
- className="w-full"
208
- variant="transparent"
209
- type="button"
210
- onClick={() => {
211
- setSubmittedEmail(undefined);
212
- setResendError(undefined);
213
- }}
214
- >
215
- Use another email
216
- </Button>
217
- </div>
257
+ </form>
258
+ <Button
259
+ className="w-full"
260
+ variant="transparent"
261
+ type="button"
262
+ onClick={() => {
263
+ setEmailChallenge(undefined);
264
+ setResendError(undefined);
265
+ }}
266
+ >
267
+ Use another email
268
+ </Button>
218
269
  <Text size="sm" className="text-center text-foreground-neutral-subtle">
219
270
  Already verified?{' '}
220
271
  <ButtonLink asChild variant="interactive" underline>
package/test/pages.tsx CHANGED
@@ -13,7 +13,6 @@ import {AuthProvider} from '#components/auth-provider.js';
13
13
  import {LoginPage} from '#pages/login-page.js';
14
14
  import {PasswordResetPage} from '#pages/password-reset-page.js';
15
15
  import {SignupPage} from '#pages/signup-page.js';
16
- import {VerifyEmailPage} from '#pages/verify-email-page.js';
17
16
 
18
17
  function createTestRouter(path: string, element: ReactElement) {
19
18
  const rootRoute = createRootRoute({
@@ -44,18 +43,12 @@ function createTestRouter(path: string, element: ReactElement) {
44
43
  path: '/auth/reset',
45
44
  component: () => (path.split('?')[0] === '/auth/reset' ? element : <PasswordResetPage />),
46
45
  });
47
- const verifyEmailRoute = createRoute({
48
- getParentRoute: () => rootRoute,
49
- path: '/auth/verify-email',
50
- component: () => (path.split('?')[0] === '/auth/verify-email' ? element : <VerifyEmailPage />),
51
- });
52
46
  const routeTree = rootRoute.addChildren([
53
47
  indexRoute,
54
48
  workspaceRoute,
55
49
  loginRoute,
56
50
  signupRoute,
57
51
  passwordResetRoute,
58
- verifyEmailRoute,
59
52
  ]);
60
53
  return createRouter({
61
54
  history: createMemoryHistory({initialEntries: [path]}),