(searchParams?: NextAppSearchParams)
| 71 | } |
| 72 | |
| 73 | export default function getSignInCallbackUrl(searchParams?: NextAppSearchParams): string { |
| 74 | const callbackParams = new URLSearchParams(); |
| 75 | |
| 76 | if (typeof searchParams?.source === 'string' && searchParams?.source) { |
| 77 | callbackParams.set('source', searchParams?.source); |
| 78 | } |
| 79 | |
| 80 | // Order matters: tests assert this exact emission order through the |
| 81 | // sign-in callback redirect (see getSignInCallbackUrl.test.ts). |
| 82 | const trackingParams = [ |
| 83 | 'im_ref', |
| 84 | '_saasquatch', |
| 85 | 'rsCode', |
| 86 | 'rsShareMedium', |
| 87 | 'rsEngagementMedium', |
| 88 | 'utm_source', |
| 89 | 'utm_medium', |
| 90 | 'utm_campaign', |
| 91 | 'utm_term', |
| 92 | 'utm_content', |
| 93 | ] as const; |
| 94 | for (const trackingParam of trackingParams) { |
| 95 | const value = searchParams?.[trackingParam]; |
| 96 | if (typeof value === 'string' && value) { |
| 97 | callbackParams.set(trackingParam, value); |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | // Always route through /users/after-sign-in to ensure stytch verification check |
| 102 | if ( |
| 103 | typeof searchParams?.callbackPath === 'string' && |
| 104 | isValidCallbackPath(searchParams.callbackPath) |
| 105 | ) { |
| 106 | callbackParams.set('callbackPath', searchParams.callbackPath); |
| 107 | } |
| 108 | |
| 109 | // Preserve signup=true so an OAuth error bounce (see parseSignInRedirectContext |
| 110 | // in user.server.ts) can send the user back to the create-account UI instead |
| 111 | // of the plain sign-in UI. |
| 112 | if (searchParams?.signup === 'true') { |
| 113 | callbackParams.set('signup', 'true'); |
| 114 | } |
| 115 | |
| 116 | return `/users/after-sign-in${callbackParams.size > 0 ? `?${callbackParams.toString()}` : ''}`; |
| 117 | } |
no test coverage detected