Skip to content

Commit 19e0c1f

Browse files
authored
release: develop -> main
2 parents c2e0038 + 6e6a751 commit 19e0c1f

8 files changed

Lines changed: 81 additions & 22 deletions

File tree

src/components/auth/LoginForm.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,14 @@ export function LoginForm({
135135
return;
136136
}
137137

138-
const redirectUrl =
139-
response.user.InterestSetting === false ? ROUTES.INTEREST : resolvedCallbackUrl;
138+
let redirectUrl: string;
139+
if (response.user.InterestSetting === false) {
140+
redirectUrl = resolvedCallbackUrl
141+
? `${ROUTES.INTEREST}?callbackUrl=${encodeURIComponent(resolvedCallbackUrl)}`
142+
: ROUTES.INTEREST;
143+
} else {
144+
redirectUrl = resolvedCallbackUrl;
145+
}
140146

141147
await finalizeLogin(redirectUrl);
142148
},
@@ -173,7 +179,10 @@ export function LoginForm({
173179

174180
const handleSignupNavigation = async () => {
175181
onNavigateAway?.();
176-
await router.push(ROUTES.SIGNUP);
182+
await router.push({
183+
pathname: ROUTES.SIGNUP,
184+
query: resolvedCallbackUrl ? { callbackUrl: resolvedCallbackUrl } : {},
185+
});
177186
};
178187

179188
return (
@@ -299,7 +308,13 @@ export function LoginForm({
299308
</Text>
300309
</button>
301310
) : (
302-
<I18nLink href={ROUTES.SIGNUP}>
311+
<I18nLink
312+
href={
313+
resolvedCallbackUrl
314+
? `${ROUTES.SIGNUP}?callbackUrl=${encodeURIComponent(resolvedCallbackUrl)}`
315+
: ROUTES.SIGNUP
316+
}
317+
>
303318
<Text typo="body_M" color="primary50" css={underlineText}>
304319
{t('signUp')}
305320
</Text>

src/hooks/auth/use-auth-sync.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,49 @@ import { useEffect } from 'react';
22
import { useRouter } from 'next/router';
33
import { useAuthStore } from '@/store/auth';
44
import { ROUTES } from '@/constants';
5+
import { resolveSafeAuthRedirect } from '@/utils/auth-session';
6+
7+
/**
8+
* 인증 플로우 페이지들은 자체적으로 /interest 리다이렉트를 callbackUrl과 함께 처리한다.
9+
* useAuthSync가 이 페이지들에서 동작하면 race condition이 발생하므로 제외한다.
10+
*/
11+
const AUTH_FLOW_PATHNAMES = new Set([
12+
ROUTES.LOGIN,
13+
ROUTES.SIGNUP,
14+
ROUTES.INTEREST,
15+
'/auth/social/callback',
16+
]);
517

618
/**
719
* 사용자 상태를 기준으로 관심사 등록 페이지 리다이렉트를 동기화한다.
20+
* 인증 플로우 페이지에서는 동작하지 않으며, 현재 페이지를 callbackUrl로 보존한다.
821
*/
922
export function useAuthSync() {
1023
const router = useRouter();
1124
const authState = useAuthStore((state) => state.authState);
1225
const user = useAuthStore((state) => state.user);
1326
const isBootstrapped = useAuthStore((state) => state.isBootstrapped);
1427

15-
// InterestSetting 확인 및 리다이렉트
1628
useEffect(() => {
1729
if (!isBootstrapped) return;
1830
if (authState !== 'authenticated' || !user) return;
1931

20-
// InterestSetting이 false이고, 현재 페이지가 관심사 등록 페이지가 아니면 리다이렉트
2132
const skipInterestRedirect =
2233
typeof window !== 'undefined' && window.sessionStorage.getItem('interest_done') === '1';
2334

2435
if (user.InterestSetting !== false && skipInterestRedirect) {
2536
window.sessionStorage.removeItem('interest_done');
2637
}
2738

28-
if (
29-
user.InterestSetting === false &&
30-
!skipInterestRedirect &&
31-
router.pathname !== ROUTES.INTEREST
32-
) {
33-
void router.push(ROUTES.INTEREST);
39+
const isAuthFlowPage = AUTH_FLOW_PATHNAMES.has(router.pathname);
40+
41+
if (user.InterestSetting === false && !skipInterestRedirect && isAuthFlowPage === false) {
42+
const currentPath = resolveSafeAuthRedirect(router.asPath);
43+
const interestUrl =
44+
currentPath !== ROUTES.HOME
45+
? `${ROUTES.INTEREST}?callbackUrl=${encodeURIComponent(currentPath)}`
46+
: ROUTES.INTEREST;
47+
void router.replace(interestUrl);
3448
}
3549
}, [authState, isBootstrapped, router, user]);
3650

src/pages/auth/social/callback.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,16 @@ export default function SocialAuthCallbackPage() {
8787
}
8888

8989
showToast(getAuthFeedback(t, 'social_login_success'));
90-
const redirectUrl =
91-
response.user.InterestSetting === false
92-
? ROUTES.INTEREST
93-
: resolveSafeAuthRedirect(pending.callbackUrl);
90+
const safeCallbackUrl = resolveSafeAuthRedirect(pending.callbackUrl);
91+
let redirectUrl: string;
92+
if (response.user.InterestSetting === false) {
93+
redirectUrl =
94+
safeCallbackUrl === ROUTES.HOME
95+
? ROUTES.INTEREST
96+
: `${ROUTES.INTEREST}?callbackUrl=${encodeURIComponent(safeCallbackUrl)}`;
97+
} else {
98+
redirectUrl = safeCallbackUrl;
99+
}
94100

95101
await router.replace(redirectUrl);
96102
} catch (error) {

src/pages/company/[companyId]/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ export default function ClinicDetailPage({
274274

275275
if (!isLoggedIn) {
276276
openLoginModal({
277-
callbackUrl: reservationUrl,
277+
callbackUrl: router.asPath,
278278
reason: 'reserve',
279279
});
280280
return;

src/pages/company/[companyId]/program/[programId].tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export default function ProgramDetailPage({
127127

128128
if (!isLoggedIn) {
129129
openLoginModal({
130-
callbackUrl: reservationUrl,
130+
callbackUrl: router.asPath,
131131
reason: 'reserve',
132132
});
133133
return;

src/pages/interest/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { useAuthStore } from '@/store/auth';
3030
import { useTranslations } from 'next-intl';
3131
import { useLocalizedRouter } from '@/i18n/navigation';
3232
import { getPrivateI18nServerSideProps } from '@/i18n/page-props';
33+
import { resolveSafeAuthRedirect } from '@/utils/auth-session';
3334
import { getLocalizedCountryOptions } from '@/utils/localized-country-options';
3435

3536
const INTEREST_OPTION_ICONS: Record<InterestOptionId, ReactNode> = {
@@ -162,7 +163,8 @@ export default function InterestPage() {
162163
...(resolvedCountry ? { country: resolvedCountry } : {}),
163164
});
164165
await queryClient.invalidateQueries({ queryKey: QUERY_KEYS.GET_USER_PROFILE });
165-
await router.replace(ROUTES.HOME);
166+
const afterInterestUrl = resolveSafeAuthRedirect(router.query.callbackUrl, ROUTES.HOME);
167+
await router.replace(afterInterestUrl);
166168
},
167169
onError: (error: unknown) => {
168170
showErrorToast(error, { fallbackMessage: t('toast.saveFailed') });

src/pages/login/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,15 @@ export default function Login() {
3535
if (isAuthLoading || !isAuthenticated || !authUser) return;
3636

3737
const callbackUrl = resolveSafeAuthRedirect(router.query.callbackUrl);
38-
const redirectUrl = authUser.InterestSetting === false ? ROUTES.INTEREST : callbackUrl;
38+
let redirectUrl: string;
39+
if (authUser.InterestSetting === false) {
40+
redirectUrl =
41+
callbackUrl === ROUTES.HOME
42+
? ROUTES.INTEREST
43+
: `${ROUTES.INTEREST}?callbackUrl=${encodeURIComponent(callbackUrl)}`;
44+
} else {
45+
redirectUrl = callbackUrl;
46+
}
3947

4048
hasRedirected.current = true;
4149
void router.replace(redirectUrl);

src/pages/signup/index.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,13 @@ export default function Signup() {
260260
{
261261
onSuccess: () => {
262262
// 회원가입 후에는 accessToken이 제공되지 않을 수 있으므로 로그인 페이지로 이동
263+
const callbackUrl = router.query.callbackUrl;
263264
void router.push({
264265
pathname: ROUTES.LOGIN,
265-
query: { notice: 'signup_verification_email_sent' },
266+
query: {
267+
notice: 'signup_verification_email_sent',
268+
...(callbackUrl ? { callbackUrl } : {}),
269+
},
266270
});
267271
},
268272
onError: (error: unknown) => {
@@ -490,7 +494,17 @@ export default function Signup() {
490494
<Text typo="body_M" color="text_secondary">
491495
{t('alreadyHaveAccount')}{' '}
492496
</Text>
493-
<button type="button" css={linkButton} onClick={() => void router.push(ROUTES.LOGIN)}>
497+
<button
498+
type="button"
499+
css={linkButton}
500+
onClick={() => {
501+
const callbackUrl = router.query.callbackUrl;
502+
void router.push({
503+
pathname: ROUTES.LOGIN,
504+
query: callbackUrl ? { callbackUrl } : {},
505+
});
506+
}}
507+
>
494508
<Text typo="body_M" color="primary50" css={underlineText}>
495509
{t('logIn')}
496510
</Text>

0 commit comments

Comments
 (0)