Skip to content

[FEAT] OAuth 로그인 인가 코드 전송 후 회원가입/로그인 성공 분기 작업#177

Merged
aaaaaattt merged 39 commits intodevelopfrom
feat/oauth-login
Oct 17, 2025
Merged

[FEAT] OAuth 로그인 인가 코드 전송 후 회원가입/로그인 성공 분기 작업#177
aaaaaattt merged 39 commits intodevelopfrom
feat/oauth-login

Conversation

@aaaaaattt
Copy link
Collaborator

@aaaaaattt aaaaaattt commented Oct 16, 2025

#️⃣연관된 이슈

ex) #174

📝작업 내용

  • 회원가입 API (postSignupForm) 구현 및 임시 토큰 처리
  • 카카오 로그인 콜백 페이지 및 API 연동
  • 관리자 회원가입 페이지 API 연동
  • Axios 인스턴스 생성 함수(apiInstance) 추가
  • 공통 에러 응답 타입(ErrorResponse) 정의
  • TypeScript 기반의 응답 타입 정의 (RegisterSuccessResponse, KakaoLoginResponse)
  • catch 블록에서 Axios 에러 타입 안전하게 처리

스크린샷 (선택)

💬리뷰 요구사항(선택)

Summary by CodeRabbit

  • New Features

    • Kakao OAuth flow now completes sign-in or directs users to registration when needed, storing tokens and navigating appropriately.
  • Improvements

    • Signup uses a temporary token to finalize registration and auto-signs in on success.
    • Navigation now occurs when confirmation toasts auto-close for more predictable UX.
    • Improved error handling and user-facing messages; submission guarded when temporary token is missing.

aaaaaattt added 29 commits October 15, 2025 12:33
- 임시 확인 용도
- OAuth 일원화
- 로그인 성공 -> accessToken SessionStorage 관리
- 회원 가입 필요 -> temporary Token SessionStorage 관리
- Login , Register 부분 우선 추가
@aaaaaattt aaaaaattt requested a review from ganimjeong October 16, 2025 08:36
@aaaaaattt aaaaaattt requested a review from kanghaeun October 16, 2025 08:36
@aaaaaattt aaaaaattt self-assigned this Oct 16, 2025
@aaaaaattt aaaaaattt added the ✨ Feature 기능 구현 이슈 label Oct 16, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 16, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Refactors authentication and signup to use a shared Axios instance (apiInstance), adds typed server response models and an ErrorResponse type, changes token storage and navigation flows for Kakao login and signup, tightens Axios error handling, and replaces timeout-based navigations with toast onAutoClose handlers.

Changes

Cohort / File(s) Summary
API Instance
src/pages/admin/Login/api/initInstance.ts
New apiInstance Axios instance with 10s timeout, default JSON header, merged config, and baseURL from import.meta.env.VITE_API_BASE_URL.
Kakao Login Callback
src/pages/admin/Login/KakaoCallback.tsx
Replaces direct axios call with apiInstance.post('/auth/kakao/login'); adds LoginSuccessResponse, RegistrationRequiredResponse, and LoginResponse types; navigates to /login if code missing; stores accessToken or temporaryToken and routes on LOGIN_SUCCESS/REGISTRATION_REQUIRED; updates Axios error casting and throws Error with server message.
Signup API
src/pages/admin/Signup/api/signup.ts
Replaces fetch with apiInstance.post('/auth/register'); adds RegisterSuccessResponse type; postSignupForm(formData, tempToken) now sends Authorization header, stores accessToken on success, and maps Axios errors (400/401/409) to user messages.
Signup Form Component
src/pages/admin/Signup/components/SignupForm/index.tsx
Reads temporaryToken from localStorage, aborts with toast if missing, passes token to postSignupForm, shows success toast and uses onAutoClose to navigate to /, and surfaces error messages from caught Error.
Error Type
src/pages/admin/Signup/type/error.ts
Adds exported ErrorResponse interface: { status: number; message: string; detail: string }.
Toast Navigation Changes
src/pages/admin/ClubDetailEdit/Page.tsx, src/pages/user/Apply/components/ApplicationForm/index.tsx
Replaces setTimeout-based delayed navigations after success with immediate navigation via toast onAutoClose callbacks.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant KakaoCallback
    participant apiInstance
    participant Backend
    participant SessionStorage
    participant LocalStorage

    User->>KakaoCallback: OAuth callback (with code)
    KakaoCallback->>apiInstance: POST /auth/kakao/login (code)
    apiInstance->>Backend: forward request
    alt LOGIN_SUCCESS
        Backend-->>apiInstance: { status: "LOGIN_SUCCESS", accessToken }
        apiInstance-->>KakaoCallback: response
        KakaoCallback->>SessionStorage: store accessToken
        KakaoCallback->>User: navigate to "/"
    else REGISTRATION_REQUIRED
        Backend-->>apiInstance: { status: "REGISTRATION_REQUIRED", temporaryToken }
        apiInstance-->>KakaoCallback: response
        KakaoCallback->>LocalStorage: store temporaryToken
        KakaoCallback->>User: navigate to "/signup"
    else Error
        Backend-->>apiInstance: ErrorResponse
        apiInstance-->>KakaoCallback: AxiosError
        KakaoCallback->>User: throw/display Error with server message
    end
Loading
sequenceDiagram
    actor User
    participant SignupForm
    participant LocalStorage
    participant apiInstance
    participant Backend
    participant SessionStorage

    User->>SignupForm: submit form
    SignupForm->>LocalStorage: read temporaryToken
    alt token missing
        LocalStorage-->>SignupForm: null
        SignupForm->>User: show error toast (abort)
    else token present
        LocalStorage-->>SignupForm: temporaryToken
        SignupForm->>apiInstance: POST /auth/register (formData + Bearer tempToken)
        apiInstance->>Backend: forward request
        alt REGISTER_SUCCESS
            Backend-->>apiInstance: { status: "REGISTER_SUCCESS", accessToken, refreshToken }
            apiInstance-->>SignupForm: response
            SignupForm->>SessionStorage: store accessToken
            SignupForm->>User: toast -> onAutoClose -> navigate "/"
        else Error
            Backend-->>apiInstance: ErrorResponse
            apiInstance-->>SignupForm: AxiosError
            SignupForm->>User: show mapped error toast
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

🌈 frontend

Suggested reviewers

  • ganimjeong
  • kanghaeun

Poem

🐰 I hopped through headers, tokens, and streams,
Axios stitched dreams into login seams,
Typed responses, no more log-bleats,
Toasts lead the dance with tidy beats,
A rabbit cheers for clean auth schemes! 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and specifically describes the main feature implemented in this pull request: handling the OAuth login authorization code flow and branching between registration and login success flows. It uses concise, descriptive language without extraneous details or file references. The prefix “[FEAT]” appropriately signals that this is a feature addition. Team members scanning the history will understand the purpose of the changes at a glance.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/oauth-login

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @aaaaaattt, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 OAuth 로그인(특히 카카오) 기능을 통합하고, 새로운 사용자(관리자)를 위한 회원가입 워크플로우를 구축하여 애플리케이션의 인증 시스템을 확장합니다. 사용자 경험을 개선하고, API 통신을 표준화하며, 타입 안전성을 높이는 데 중점을 두었습니다.

Highlights

  • 카카오 OAuth 로그인 구현: 인가 코드를 처리하고 로그인 성공 또는 회원가입 필요 여부에 따라 분기하는 로직이 추가되었습니다.
  • 관리자 회원가입 페이지 추가: 새로운 관리자 회원가입 페이지와 관련 API 연동 로직이 구현되었습니다.
  • Axios 인스턴스 중앙화: API 호출을 위한 전역 Axios 인스턴스 생성 함수가 추가되어 일관된 API 통신 환경을 제공합니다.
  • 타입 정의 강화: 공통 에러 응답 타입과 로그인/회원가입 성공 응답 타입이 TypeScript로 명확하게 정의되었습니다.
  • 로그인 페이지 개선: 기존 로그인 페이지에서 불필요한 입력 필드가 제거되고, 카카오 로그인 및 회원가입 버튼이 추가되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이번 PR은 OAuth (카카오) 로그인을 구현하고, 그에 따른 회원가입/로그인 분기 처리를 추가하는 내용입니다. 전반적으로 기능 구현은 잘 이루어졌지만, 몇 가지 개선점을 제안합니다. 주요 피드백은 에러 처리 로직 개선, 토큰 관리의 일관성 및 완전성 확보, 그리고 코드의 견고성을 높이는 방법에 대한 것입니다. 자세한 내용은 각 파일의 주석을 참고해주세요.

Comment on lines 48 to 51
} catch (e) {
const error = e as AxiosError<ErrorResponse>;
return new Error(error.response?.data.message);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

catch 블록의 에러 처리가 올바르지 않습니다. useEffect 내부의 비동기 함수에서 new Error()를 반환해도 아무런 효과가 없으며, 에러 발생 시 사용자는 로딩 화면에 계속 머물게 됩니다. 에러를 사용자에게 알리고 로그인 페이지 등으로 리디렉션해야 합니다.

      } catch (e) {
        const error = e as AxiosError<ErrorResponse>;
        // TODO: 사용자에게 에러 메시지 표시 (e.g., toast)
        console.error(error.response?.data.message ?? '로그인 중 오류가 발생했습니다.');
        navigate('/login');
      }

Comment on lines 39 to 42
case 'LOGIN_SUCCESS':
localStorage.setItem('accessToken', res.data.accessToken);
navigate('/');
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

LoginSuccessResponserefreshToken이 포함되어 있지만, 저장되지 않고 있습니다. 애플리케이션이 리프레시 토큰을 사용하여 세션을 유지하도록 설계되었다면, refreshTokenlocalStorage나 안전한 쿠키 등에 저장해야 합니다.

Suggested change
case 'LOGIN_SUCCESS':
localStorage.setItem('accessToken', res.data.accessToken);
navigate('/');
break;
case 'LOGIN_SUCCESS':
localStorage.setItem('accessToken', res.data.accessToken);
localStorage.setItem('refreshToken', res.data.refreshToken);
navigate('/');
break;


switch (res.data.status) {
case 'LOGIN_SUCCESS':
localStorage.setItem('accessToken', res.data.accessToken);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

accessTokenlocalStorage에 저장하고 있습니다. 하지만 src/pages/admin/Signup/api/signup.ts에서는 sessionStorage에 저장하고 있어 토큰 저장 방식에 일관성이 없습니다. 애플리케이션의 세션 관리 정책에 따라 localStorage 또는 sessionStorage로 통일하는 것이 좋습니다.

};

export const apiInstance = initInstance({
baseURL: import.meta.env.VITE_API_BASE_URL_LOCAL,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

baseURLVITE_API_BASE_URL_LOCAL로 하드코딩되어 있습니다. 이렇게 하면 개발 환경이 아닌 스테이징이나 프로덕션 환경에 배포할 때 문제가 발생할 수 있습니다. 일반적으로 VITE_API_BASE_URL과 같은 단일 환경 변수를 사용하고, 각 환경에 맞는 .env 파일(예: .env.development, .env.production)에서 해당 변수의 값을 정의하는 것이 좋습니다.

headers: { Authorization: `Bearer ${tempToken}` },
},
);
sessionStorage.setItem('accessToken', response.data.accessToken);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

RegisterSuccessResponserefreshToken이 포함되어 있지만 저장하고 있지 않습니다. accessTokensessionStorage에 저장하고 있습니다. 애플리케이션이 리프레시 토큰을 사용하여 세션을 관리한다면 refreshToken도 함께 저장해야 합니다.

    sessionStorage.setItem('accessToken', response.data.accessToken);
    sessionStorage.setItem('refreshToken', response.data.refreshToken);

Comment on lines 35 to 41
toast.success('회원가입 완료!', {
style: { backgroundColor: theme.colors.primary, color: 'white' },
duration: 1000,
});
setTimeout(() => {
navigate(`/`);
}, 1000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

토스트 메시지를 보여준 후 setTimeout을 사용해 페이지를 이동시키는 방식은 불안정할 수 있습니다. 예를 들어 토스트 표시 시간이 변경되면 setTimeout의 시간도 함께 수정해야 합니다. 사용하시는 sonner 라이브러리는 토스트가 사라질 때 호출되는 onAutoCloseonDismiss 같은 콜백 함수를 제공합니다. 이를 사용하면 더 견고한 코드를 작성할 수 있습니다.

      toast.success('회원가입 완료!', {
        style: { backgroundColor: theme.colors.primary, color: 'white' },
        duration: 1000,
        onAutoClose: () => navigate('/'),
      });

Comment on lines 42 to 50
} catch (e: any) {
toast.error(e.message, {
duration: 1000,
style: {
backgroundColor: 'white',
color: theme.colors.error,
},
});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

catch 블록에서 에러 타입을 any로 지정하는 것은 타입스크립트에서 권장되지 않습니다. unknown으로 타입을 지정한 후, 타입 가드를 통해 타입을 좁혀서 사용하는 것이 더 안전합니다. postSignupForm 함수는 Error 객체를 throw하므로, instanceof Error를 사용하여 확인할 수 있습니다.

    } catch (e: unknown) {
      if (e instanceof Error) {
        toast.error(e.message, {
          duration: 1000,
          style: {
            backgroundColor: 'white',
            color: theme.colors.error,
          },
        });
      }
    }

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/pages/admin/Signup/components/SignupForm/index.tsx (1)

42-50: Replace any with proper error typing.

Using any defeats TypeScript's type safety and causes the pipeline to fail. Since postSignupForm throws Error objects, type the catch parameter as unknown and narrow to Error.

Apply this diff:

-    } catch (e: any) {
-      toast.error(e.message, {
+    } catch (e: unknown) {
+      const errorMessage = e instanceof Error ? e.message : '알 수 없는 오류가 발생했습니다.';
+      toast.error(errorMessage, {
         duration: 1000,
         style: {
           backgroundColor: 'white',
♻️ Duplicate comments (4)
src/pages/admin/Login/api/initInstance.ts (1)

19-19: Hardcoded baseURL limits environment portability.

Using VITE_API_BASE_URL_LOCAL prevents deployment to staging or production. Consider using a single environment variable (e.g., VITE_API_BASE_URL) and defining it per environment in .env.development, .env.production, etc.

src/pages/admin/Login/KakaoCallback.tsx (2)

40-40: Missing refreshToken storage prevents session renewal.

The server returns refreshToken in both LOGIN_SUCCESS and during signup (RegisterSuccessResponse), but only accessToken is stored. Without the refresh token, the app cannot renew expired access tokens, forcing users to re-authenticate.

Store the refreshToken alongside accessToken:

           case 'LOGIN_SUCCESS':
             localStorage.setItem('accessToken', res.data.accessToken);
+            localStorage.setItem('refreshToken', res.data.refreshToken);
             navigate('/');

And in src/pages/admin/Signup/api/signup.ts:

     sessionStorage.setItem('accessToken', response.data.accessToken);
+    sessionStorage.setItem('refreshToken', response.data.refreshToken);

Also applies to: 44-44


48-51: Critical: Error handling returns Error instead of handling it.

Returning new Error(...) in a useEffect callback has no effect. The user remains stuck on the loading spinner indefinitely when login fails.

Handle the error by showing user feedback and navigating away:

       } catch (e) {
         const error = e as AxiosError<ErrorResponse>;
-        return new Error(error.response?.data.message);
+        // TODO: Display error message via toast
+        console.error(error.response?.data.message ?? '로그인 중 오류가 발생했습니다.');
+        navigate('/login');
       }
src/pages/admin/Signup/api/signup.ts (1)

21-21: Missing refreshToken storage prevents session renewal.

The RegisterSuccessResponse includes a refreshToken, but only the accessToken is stored. This prevents the application from refreshing expired tokens, forcing users to re-authenticate.

Apply this diff:

     sessionStorage.setItem('accessToken', response.data.accessToken);
+    sessionStorage.setItem('refreshToken', response.data.refreshToken);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8b9894 and 4b43dac.

📒 Files selected for processing (5)
  • src/pages/admin/Login/KakaoCallback.tsx (1 hunks)
  • src/pages/admin/Login/api/initInstance.ts (1 hunks)
  • src/pages/admin/Signup/api/signup.ts (1 hunks)
  • src/pages/admin/Signup/components/SignupForm/index.tsx (1 hunks)
  • src/pages/admin/Signup/type/error.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/pages/admin/Signup/components/SignupForm/index.tsx (1)
src/pages/admin/Signup/api/signup.ts (1)
  • postSignupForm (12-39)
src/pages/admin/Signup/api/signup.ts (3)
src/pages/admin/Signup/type/signup.ts (1)
  • SignupFormInputs (1-7)
src/pages/admin/Login/api/initInstance.ts (1)
  • apiInstance (18-20)
src/pages/admin/Signup/type/error.ts (1)
  • ErrorResponse (1-5)
src/pages/admin/Login/KakaoCallback.tsx (2)
src/pages/admin/Login/api/initInstance.ts (1)
  • apiInstance (18-20)
src/pages/admin/Signup/type/error.ts (1)
  • ErrorResponse (1-5)
🪛 GitHub Actions: Dongarium FE CI/CD
src/pages/admin/Signup/components/SignupForm/index.tsx

[error] 42-42: ESLint: Unexpected any. Specify a different type. @typescript-eslint/no-explicit-any

🪛 GitHub Check: lint
src/pages/admin/Signup/components/SignupForm/index.tsx

[failure] 42-42:
Unexpected any. Specify a different type

🔇 Additional comments (8)
src/pages/admin/Signup/type/error.ts (1)

1-5: LGTM!

Clean and well-structured error type definition that standardizes server error responses across the authentication flow.

src/pages/admin/Login/api/initInstance.ts (1)

4-16: LGTM!

The instance creation pattern with configurable defaults is well-structured and provides good flexibility for header merging and timeout configuration.

src/pages/admin/Signup/components/SignupForm/index.tsx (1)

26-31: LGTM!

Good defensive check for the temporary token with clear user feedback via toast on missing token.

src/pages/admin/Login/KakaoCallback.tsx (2)

8-19: LGTM!

Clean discriminated union types for modeling the login response states.


27-30: LGTM!

Appropriate early exit when authorization code is missing.

src/pages/admin/Signup/api/signup.ts (3)

6-10: LGTM!

Well-defined response type with proper discriminated union via the status field.


14-20: LGTM!

Correct use of Bearer token in Authorization header for authenticated signup request.


27-36: LGTM!

Comprehensive error handling with user-friendly messages mapped from HTTP status codes.


switch (res.data.status) {
case 'LOGIN_SUCCESS':
localStorage.setItem('accessToken', res.data.accessToken);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Inconsistent token storage breaks authentication.

Line 40 stores accessToken in localStorage, but src/pages/admin/Signup/api/signup.ts (Line 21) uses sessionStorage. This inconsistency will cause authentication failures when tokens are retrieved from the wrong storage location.

Standardize on one storage mechanism. If the app should persist across browser sessions, use localStorage consistently:

 // In src/pages/admin/Signup/api/signup.ts, Line 21
-    sessionStorage.setItem('accessToken', response.data.accessToken);
+    localStorage.setItem('accessToken', response.data.accessToken);

Or if sessions should end when the browser closes, use sessionStorage consistently:

-            localStorage.setItem('accessToken', res.data.accessToken);
+            sessionStorage.setItem('accessToken', res.data.accessToken);

Also applies to: 21-21

🤖 Prompt for AI Agents
In src/pages/admin/Login/KakaoCallback.tsx around line 40, the code stores
accessToken in localStorage while src/pages/admin/Signup/api/signup.ts (line 21)
uses sessionStorage; change the storage call here from
localStorage.setItem('accessToken', ...) to
sessionStorage.setItem('accessToken', ...) (or alternatively change the signup
file if you decide to standardize on localStorage) and then search the repo for
other accessToken/session token reads/writes and make them consistent to the
chosen storage mechanism.

Comment on lines 22 to 38
} catch (e: unknown) {
if (axios.isAxiosError(e)) {
const error = e as AxiosError<ErrorResponse>;
const status = error.response?.status;
const detailMsg = error.response?.data.detail;
switch (status) {
case 400:
throw new Error(`입력 오류: ${detailMsg}`);
case 401:
throw new Error(`권한 오류: ${detailMsg}`);
case 409:
throw new Error(`중복 오류: ${detailMsg}`);
default:
throw new Error(`알 수 없는 오류: ${e.message}`);
}
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Non-Axios errors are not propagated.

The error handling only catches Axios errors. Network failures, timeouts, or other non-Axios errors will fall through silently without notifying the caller.

Apply this diff to ensure all errors are properly propagated:

       }
+      throw new Error('알 수 없는 오류가 발생했습니다.');
     }
   }
 };
🤖 Prompt for AI Agents
In src/pages/admin/Signup/api/signup.ts around lines 22 to 38, the catch block
only handles Axios errors and silently swallows non-Axios exceptions; update the
catch to rethrow non-Axios errors so callers are notified: after the
axios.isAxiosError branch, add a fallback that throws the original error (or
converts unknown to an Error via new Error(String(e))) so network failures,
timeouts, or other exceptions are propagated; keep existing Axios-specific
switch logic intact.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4505c99 and 2f2eeaf.

📒 Files selected for processing (1)
  • src/pages/admin/Signup/components/SignupForm/index.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/pages/admin/Signup/components/SignupForm/index.tsx (2)
src/pages/admin/Signup/api/signup.ts (1)
  • postSignupForm (12-39)
src/styles/theme.ts (1)
  • theme (3-10)
🔇 Additional comments (2)
src/pages/admin/Signup/components/SignupForm/index.tsx (2)

38-38: Good improvement using onAutoClose.

This change correctly addresses the previous review feedback by replacing setTimeout with the onAutoClose callback, making the navigation directly tied to the toast lifecycle.


40-49: Safer error handling implemented correctly.

This change correctly addresses the previous review feedback by using unknown type with an instanceof Error guard. The implementation aligns well with the API layer, which consistently throws Error objects as shown in the postSignupForm implementation.

Comment on lines 26 to 31
const temporaryToken = localStorage.getItem('temporaryToken');

if (!temporaryToken) {
toast.error('회원가입을 위한 토큰이 존재하지 않습니다.');
return;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Remove temporaryToken after successful signup.

The guard logic correctly prevents submission when the token is missing. However, after successful signup (when postSignupForm completes and stores the accessToken in sessionStorage), the temporaryToken should be removed from localStorage to prevent reuse and maintain clean state.

Add cleanup after line 34:

     try {
       await postSignupForm(signupFormValue, temporaryToken);
+      localStorage.removeItem('temporaryToken');
       toast.success('회원가입 완료!', {

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/pages/admin/Signup/components/SignupForm/index.tsx around lines 26-31
(and after line 34), the temporaryToken is read from localStorage but never
removed after a successful signup; update the success path after postSignupForm
completes (where you store accessToken in sessionStorage) to call
localStorage.removeItem('temporaryToken') so the token is cleaned up only on
successful signup, leaving failure/error paths unchanged.

@ganimjeong
Copy link
Contributor

헉 아직 허스키 안되시나요?? 제가 말씀드린 파일은 존재하나요? (바쁘시면 나중에 확인하셔도 돼요)

@aaaaaattt
Copy link
Collaborator Author

.husky 파일이랑 pre-commit 파일 확인했는데 작동을 안하더라고요 사용하는 기준 shell이나운영체제 차이가 있을 수도 있을 것 같네요(저는 zsh 사용중입니다)

@aaaaaattt aaaaaattt merged commit dffd841 into develop Oct 17, 2025
5 checks passed
@aaaaaattt aaaaaattt deleted the feat/oauth-login branch October 17, 2025 07:37
ganimjeong pushed a commit that referenced this pull request Oct 27, 2025
…ogin

[FEAT] OAuth 로그인 인가 코드 전송 후 회원가입/로그인 성공 분기 작업
ganimjeong pushed a commit that referenced this pull request Oct 27, 2025
…ogin

[FEAT] OAuth 로그인 인가 코드 전송 후 회원가입/로그인 성공 분기 작업
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 기능 구현 이슈

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants