Skip to content

[FIX] 로그인 추가 기능 및 로직 수정, modal 스크롤 프리징 처리 - #115

Merged
9g-g9 merged 13 commits into
devfrom
fix/fix-login-error
Aug 13, 2026
Merged

9g-g9 merged 13 commits into
devfrom
fix/fix-login-error

Conversation

@9g-g9

@9g-g9 9g-g9 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

📋 작업 내용

  • 로그인 Soft UX 힌트를 cookie 기준으로 정리하고, 값 검증을 강화했습니다.
  • 이메일 로그인 role 검증을 BE로 위임하고, 비밀번호 변경 후 재로그인 흐름을 맞췄습니다.
  • 프로필 폼 UX(Enter submit 방지, 미변경 시 버튼 비활성)와 Modal/SideNav 스크롤 잠금을 정리했습니다.

🔥 변경 사항

  • Soft UX 힌트(localStorage 이중 저장 제거, cookie만 사용, nickname/role/image sanitize)
  • 이메일 로그인: role 전달 후 BE 검증, FE audience mismatch logout 제거
  • OAuth: 기존 계정 role을 BE가 강제하지 않으므로 FE 세션 롤백 유지
  • 비밀번호 변경 성공 시 로그아웃 → 로그인 이동 + 비밀번호가 변경되었으니 재로그인 해달라는 Toast 안내
  • 프로필 폼: Enter submit 방지, isDirty 없을 때 수정 버튼 disabled
  • useBodyScrollLock 훅 생성, Modalexit(isRendered)까지 스크롤 잠금

✅ 체크리스트

  • 로컬에서 정상 동작을 확인했습니다.
  • 기존 기능에 영향을 주지 않는지 확인했습니다.
  • 불필요한 console.log를 제거했습니다.
  • lint를 통과했습니다.
  • README 또는 문서를 수정했습니다. (필요 시)
  • API 명세와 일치하는지 확인했습니다.

📷 스크린샷 (선택)

  • 비밀번호 변경 시 로그인 페이지로 리턴 (Toast 안내 추가)
image

💬 To Reviewer

  • 이메일 로그인 role mismatch 안내는 BE error code 연동 예정입니다. (현재는 일반 로그인 실패 메시지가 나옴)
  • OAuth 는 아직 role 검증 -> 토큰 발급X 패턴이 들어가있지 않아, 적용 전입니다.
  • Soft UX cookie 값 검증하는 부분을 작성하였는데, 해당 기능이 있을 때 어색하거나 보안성이 좋지 않은 부분이 있다면 말씀주세요.
  • profileImage cookie 값 검증 부분(sanitizeSoftUxProfileImageUrl)과 resolveMoverProfileImageSrc 부분을 합쳐도 괜찮을까요? 둘의 역할이 살짝 다르지만 같은 선이어서 고민하다가 따로 정리하지는 않았습니다.

Summary by CodeRabbit

  • 새로운 기능
    • 비밀번호 변경 후 재로그인 안내 토스트와 안전한 재인증을 지원합니다.
    • 프로필 이미지와 닉네임을 안전하게 정제해 표시합니다.
    • 프로필 편집 중 입력 컨트롤을 비활성화합니다.
  • 버그 수정
    • 변경사항이 없으면 저장 버튼이 비활성화됩니다.
    • 입력창의 Enter 키로 의도치 않게 폼이 제출되지 않습니다.
    • 모달과 사이드 메뉴의 배경 스크롤 처리를 개선했습니다.
    • 유효하지 않은 프로필 이미지 경로가 표시되지 않습니다.

@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
moving-frontend-p2ol Ready Ready Preview Aug 13, 2026 4:54am

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@9g-g9, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 68 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 06d2675e-2bab-4565-bbe3-108c46712806

📥 Commits

Reviewing files that changed from the base of the PR and between 3a6bf95 and c9f8d6b.

📒 Files selected for processing (1)
  • src/lib/utils/preventEnterSubmitOnInput.ts
📝 Walkthrough

Walkthrough

로그인 역할 타입과 OAuth 변환을 정리했습니다. Soft UX 쿠키와 이미지 URL을 정제합니다. 비밀번호 변경 후 재인증과 Toast를 추가했습니다. 프로필 폼의 제출 조건과 Enter 동작을 수정했습니다. 중첩 가능한 본문 스크롤 잠금 훅을 도입했습니다.

Changes

인증 및 프로필 UX

Layer / File(s) Summary
인증 역할 및 로그인 흐름
src/lib/api/auth.ts, src/lib/auth/role.ts, src/lib/auth/redirect.ts, src/lib/auth/oauth.ts, src/lib/auth/startOAuthLogin.ts, src/components/auth/LoginForm.tsx, src/components/auth/RoleGuard.tsx, src/app/movers/layout.tsx, src/app/(auth)/oauth/[provider]/callback/page.tsx
LoginRoleAuthRole을 분리했습니다. audience를 로그인 역할로 변환합니다. 로그인 후 프론트엔드 audience 불일치 검증과 롤백 처리를 제거했습니다.
Soft UX 쿠키 및 이미지 정제
src/lib/auth/clientStorageHint.ts, src/lib/auth/role.ts, src/lib/auth/nickname.ts, src/lib/auth/profileImage.ts, src/lib/auth/profileCompleted.ts, src/lib/utils/moverProfileImage.ts, src/app/layout.tsx, src/components/common/Header/ProfileMenuTrigger.tsx, src/stores/useAuthStore.ts
Soft UX 힌트를 cookie 기반으로 변경했습니다. 역할, 닉네임, 프로필 이미지의 저장·로드 값을 정제합니다.
비밀번호 변경 후 재인증
src/lib/auth/passwordChangedToast.ts, src/lib/auth/reauthAfterPasswordChange.ts, src/lib/schemas/passwordChangeFields.ts, src/components/profile/CustomerProfileEditForm.tsx, src/components/profile/MoverBasicInfoEditForm.tsx
비밀번호 변경 payload를 판별합니다. 변경 후 로그아웃과 로그인 경로 이동을 수행합니다. 프로필 저장 실패 상태에 따라 일회성 Toast 메시지를 표시합니다.
프로필 폼 상호작용
src/lib/utils/preventEnterSubmitOnInput.ts, src/components/profile/CustomerProfileForm.tsx, src/components/profile/MoverProfileForm.tsx, src/components/profile/MoverProfileEditForm.tsx, src/components/profile/ProfileChipGroup.tsx, src/components/profile/ProfileImageUploader.tsx
입력 중 Enter 제출을 차단합니다. 변경된 폼만 제출합니다. 저장 중 입력 컨트롤을 비활성화하고 저장 후 필요한 필드만 초기화합니다.
중첩 본문 스크롤 잠금
src/hooks/useBodyScrollLock.ts, src/components/common/Header/HeaderSideNav.tsx, src/components/common/Modal/ModalMain.tsx
참조 카운트 기반 useBodyScrollLock을 추가했습니다. 사이드 네비게이션과 모달의 중첩 잠금을 처리하고 기존 인라인 스타일을 복원합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Mergeability Score: 🔵 Low · up to 3a6bf

The profile forms now block accidental Enter submission, but the shared helper performs the event mutation directly instead of returning a decision for the form to apply. This is a bounded implementation risk that should be fixed or explicitly accepted; no broader merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
  participant ProfileEditForm
  participant Reauth
  participant SessionStorage
  participant LoginForm
  participant Toast

  ProfileEditForm->>Reauth: 비밀번호 변경 후 재인증 요청
  Reauth->>SessionStorage: Toast 플래그 저장
  Reauth->>LoginForm: 로그아웃 후 로그인 경로 이동
  LoginForm->>SessionStorage: Toast 플래그 소비
  LoginForm->>Toast: 변경 결과 메시지 렌더링
Loading

Possibly related PRs

Suggested reviewers: yooseohyeon

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 로그인 로직 수정, 추가 기능, 모달 스크롤 잠금 등 변경사항의 주요 내용을 명확하게 요약합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/fix-login-error

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (2)
src/lib/auth/passwordChangedToast.ts (1)

22-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

브라우저 부수효과를 src/lib 밖으로 이동하세요.

src/lib 경로 규칙은 순수 함수만 허용합니다. 현재 두 모듈이 저장소, Zustand 상태, 브라우저 이동을 직접 변경합니다.

  • src/lib/auth/passwordChangedToast.ts#L22-L50: sessionStorage 읽기·쓰기·삭제를 Client Hook 또는 UI 경계로 이동하세요.
  • src/lib/auth/reauthAfterPasswordChange.ts#L11-L23: logout 및 window.location.assign() 처리를 Client Hook 또는 호출 컴포넌트로 이동하세요.

As per path instructions, "src/lib/**/*.ts: 순수 함수로 작성하고 부수효과를 두지 않습니다."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/auth/passwordChangedToast.ts` around lines 22 - 50, Move the
sessionStorage read, write, and removal out of markPasswordChangedToast and
consumePasswordChangedToast in src/lib/auth/passwordChangedToast.ts into a
Client Hook or UI boundary, keeping the toast flag selection and message mapping
as pure logic. Also move logout and window.location.assign() out of
src/lib/auth/reauthAfterPasswordChange.ts into a Client Hook or calling
component; update both affected files accordingly.

Source: Path instructions

src/lib/utils/preventEnterSubmitOnInput.ts (1)

7-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

이벤트 차단 부수효과를 컴포넌트 경계로 분리해 주세요.

Line 11에서 event.preventDefault()를 직접 호출합니다. 입력 대상과 Enter 여부를 boolean으로 판정하는 순수 함수와, 반환값에 따라 preventDefault()를 호출하는 form handler를 분리하세요. 이렇게 하면 src/lib 유틸리티가 순수 함수 규칙을 지키고 테스트도 단순해집니다.

As per path instructions, src/lib/**/*.ts는 "순수 함수로 작성하고 부수효과를 두지 않습니다." 규칙을 따릅니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/utils/preventEnterSubmitOnInput.ts` around lines 7 - 11, Refactor
preventEnterSubmitOnInput so the input-target and Enter/composition checks live
in a pure boolean-returning helper, while the form event handler invokes
event.preventDefault() only when that helper returns true. Keep the existing
behavior unchanged and ensure the src/lib utility itself has no side effects.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/profile/MoverProfileEditForm.tsx`:
- Around line 45-47: Update the reset handling in MoverProfileEditForm to use
the submitted formValues rather than the current getValues() result, so only
values actually sent to the server become the new baseline. Alternatively,
ensure reset runs only when the current values still match formValues; preserve
accurate isDirty behavior when inputs change during submission.

In `@src/hooks/useBodyScrollLock.ts`:
- Around line 21-24: Update the body scroll-lock logic around scrollbarWidth so
it preserves the existing computed padding-right and adds scrollbarWidth instead
of replacing it. Set document.body.style.paddingRight to the combined value
while retaining the current overflow and positive-width behavior.

In `@src/lib/auth/role.ts`:
- Around line 35-39: saveRole에서 parseSoftUxAuthRole(role)가 반환되지 않는 경우에도 ADMIN이면
기존 ROLE_STORAGE_KEY 쿠키를 제거한 뒤 반환하도록 수정하세요. CUSTOMER/MOVER 저장 동작은 유지하고, 기존 클라이언트
저장소의 제거 API를 사용해 moving_role 힌트가 남지 않게 하세요.

In `@src/lib/utils/moverProfileImage.ts`:
- Line 5: Update isLocalPublicPath to reject backslash characters before
treating a value as a local public path, so inputs such as "/\\attacker.example"
fail validation while normal single-slash local paths remain accepted.

In `@src/lib/utils/preventEnterSubmitOnInput.ts`:
- Around line 8-11: Update the input check in preventEnterSubmitOnInput so Enter
is prevented only for text-entry input types such as text, password, email, tel,
search, and url; allow file and other non-text input types to proceed normally
while preserving the existing composition and non-input guards.

---

Nitpick comments:
In `@src/lib/auth/passwordChangedToast.ts`:
- Around line 22-50: Move the sessionStorage read, write, and removal out of
markPasswordChangedToast and consumePasswordChangedToast in
src/lib/auth/passwordChangedToast.ts into a Client Hook or UI boundary, keeping
the toast flag selection and message mapping as pure logic. Also move logout and
window.location.assign() out of src/lib/auth/reauthAfterPasswordChange.ts into a
Client Hook or calling component; update both affected files accordingly.

In `@src/lib/utils/preventEnterSubmitOnInput.ts`:
- Around line 7-11: Refactor preventEnterSubmitOnInput so the input-target and
Enter/composition checks live in a pure boolean-returning helper, while the form
event handler invokes event.preventDefault() only when that helper returns true.
Keep the existing behavior unchanged and ensure the src/lib utility itself has
no side effects.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 504da944-ab7a-4f7e-8895-ca7bad780716

📥 Commits

Reviewing files that changed from the base of the PR and between c57dc88 and eb709c5.

📒 Files selected for processing (30)
  • src/app/(auth)/oauth/[provider]/callback/page.tsx
  • src/app/layout.tsx
  • src/app/movers/layout.tsx
  • src/components/auth/LoginForm.tsx
  • src/components/auth/RoleGuard.tsx
  • src/components/common/Header/HeaderSideNav.tsx
  • src/components/common/Header/ProfileMenuTrigger.tsx
  • src/components/common/Modal/ModalMain.tsx
  • src/components/profile/CustomerProfileEditForm.tsx
  • src/components/profile/CustomerProfileForm.tsx
  • src/components/profile/MoverBasicInfoEditForm.tsx
  • src/components/profile/MoverProfileEditForm.tsx
  • src/components/profile/MoverProfileForm.tsx
  • src/hooks/auth/useLoginMutation.ts
  • src/hooks/useBodyScrollLock.ts
  • src/lib/api/auth.ts
  • src/lib/auth/clientStorageHint.ts
  • src/lib/auth/nickname.ts
  • src/lib/auth/oauth.ts
  • src/lib/auth/passwordChangedToast.ts
  • src/lib/auth/profileCompleted.ts
  • src/lib/auth/profileImage.ts
  • src/lib/auth/reauthAfterPasswordChange.ts
  • src/lib/auth/redirect.ts
  • src/lib/auth/role.ts
  • src/lib/auth/startOAuthLogin.ts
  • src/lib/schemas/passwordChangeFields.ts
  • src/lib/utils/moverProfileImage.ts
  • src/lib/utils/preventEnterSubmitOnInput.ts
  • src/stores/useAuthStore.ts

Comment thread src/components/profile/MoverProfileEditForm.tsx Outdated
Comment thread src/hooks/useBodyScrollLock.ts Outdated
Comment thread src/lib/auth/role.ts
Comment thread src/lib/utils/moverProfileImage.ts Outdated
Comment thread src/lib/utils/preventEnterSubmitOnInput.ts Outdated

@juengseulki juengseulki left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

📋 PR 리뷰

전체 변경사항 확인했습니다!

이번 PR은 로그인 Soft UX 힌트 정리, 이메일 로그인 role 검증을 BE 기준으로 정리, 비밀번호 변경 후 재로그인 흐름, 프로필 폼 UX, Modal/SideNav 스크롤 잠금 공통화를 중심으로 확인했습니다.

👍 잘 반영된 부분

  • Soft UX 힌트를 cookie 단일 저장 방식으로 정리하고, 기존 localStorage 값은 clear 시 마이그레이션 정리하도록 한 점이 좋습니다.
  • nickname은 trim + 제어문자 제거 + 길이 제한을 적용하고 있어 Header 표시용 힌트로 사용하기에 적절합니다.
  • role 힌트는 CUSTOMER | MOVER만 허용하고 ADMIN이나 임의 문자열은 저장하지 않도록 분리해 실제 AuthRole과 Soft UX 힌트 역할이 명확해졌습니다.
  • profile image 역시 로컬 경로와 allowlist 기반 https 원격 URL만 허용하고 javascript:, data:, http:, protocol-relative URL을 차단하도록 보완한 점이 좋습니다.
  • 이메일 로그인은 현재 BE 계약에 맞게 role을 요청에 포함하고, FE에서 로그인 성공 후 audience mismatch를 다시 logout하는 로직을 제거한 방향이 맞습니다.
  • 반대로 OAuth는 아직 BE에서 기존 계정 role mismatch를 토큰 발급 전에 차단하지 않으므로 FE 롤백 로직을 유지해 이메일/OAuth 정책 차이를 잘 구분했습니다.
  • 비밀번호 변경 후 서버에서 기존 Refresh Token이 폐기되는 흐름에 맞춰 로컬 세션도 정리하고 hard navigation으로 로그인 페이지로 이동하도록 한 점이 자연스럽습니다.
  • 비밀번호 변경 안내는 sessionStorage one-shot flag로 넘겨 로그인 페이지에서 한 번만 Toast를 표시하도록 구성되어 새 document navigation 이후에도 안내가 유지됩니다.
  • useBodyScrollLock에 참조 카운트를 두어 Modal과 SideNav가 동시에 열리는 경우 한쪽이 닫혀도 다른 쪽의 scroll lock이 풀리지 않도록 한 점이 좋습니다.
  • Modal은 isVisible이 아니라 isRendered 기준으로 잠금을 유지해 exit animation 동안 배경이 먼저 스크롤되는 문제를 방지했습니다.
  • SideNav도 동일 훅을 사용하도록 정리해 body overflow 제어 로직이 중복되지 않게 됐습니다.

🔍 확인 및 제안

1. Soft UX cookie는 현재 역할로 사용한다면 보안상 문제 없어 보입니다

nickname, role, profile image cookie는 클라이언트가 직접 수정할 수 있는 값이므로 인증/인가의 신뢰값으로 사용하면 안 됩니다.

현재 구현은 Header 첫 페인트 등의 Soft UX 힌트 용도로만 사용하고,
실제 세션 및 권한은 access token / 서버 응답을 기준으로 확정하는 구조이므로 현재 사용 범위에서는 괜찮아 보입니다.

특히 role도 parseSoftUxAuthRole()을 별도로 두어 허용값만 사용하는 점이 좋습니다.

2. sanitizeSoftUxProfileImageUrlresolveMoverProfileImageSrc는 지금은 분리 유지가 더 자연스러워 보입니다

둘 다 이미지 URL 검증을 한다는 점은 비슷하지만 책임이 조금 다릅니다.

  • sanitizeSoftUxProfileImageUrl

    • cookie에 저장하거나 cookie에서 읽을 값을 검증
    • 유효하지 않으면 null
    • 길이 제한이나 .., 역슬래시 등 Soft UX 저장값 자체의 방어까지 포함
  • resolveMoverProfileImageSrc

    • 실제 카드/목록에서 렌더링할 이미지 src 결정
    • 유효하지 않으면 기본 이미지 fallback

따라서 완전히 하나로 합치기보다는,
공통으로 쓰는 isSafeProfileImageUrl 같은 작은 predicate만 추출하고
각 함수는 현재 책임을 유지하는 쪽이 더 명확해 보입니다.

3. 이메일 로그인 role 처리

LoginForm에서 audience를 role로 바꿔 BE로 전달하고,
성공 응답 이후에는 FE가 다시 role mismatch를 판단하지 않는 구조로 변경된 점 확인했습니다.

BE가 mismatch 시 토큰 발급 전에 401을 반환한다는 현재 계약과 맞기 때문에
기존처럼 성공 후 logout까지 호출할 필요는 없어 보입니다.

4. 비밀번호 변경 후 재로그인

reauthAfterPasswordChange()에서 Toast flag를 먼저 남긴 뒤
logout({ deferUiClear: true })을 시도하고 실패 여부와 관계없이 로그인 페이지로 hard navigate하도록 되어 있습니다.

이미 BE에서 password 변경 시 Refresh Token을 폐기하는 구조이므로
logout API가 실패하더라도 클라이언트 세션 정리 후 재로그인으로 보내는 현재 정책이 자연스럽습니다.

💬 To Reviewer

말씀해주신 Soft UX cookie 검증과 이미지 helper 분리 여부를 중심으로 확인했습니다.

Soft UX cookie는 사용자가 임의 변경 가능한 값이지만,
현재 코드에서는 실제 인증·인가 결정을 위한 값이 아니라 Header SSR/첫 페인트를 위한 힌트로 사용되고 있습니다.

또 nickname, role, profile image 각각 load/save 시 sanitize를 수행하고 있어
깨진 값이나 예상하지 않은 문자열이 그대로 UI에 사용되는 범위도 줄였습니다.

특히 profile image는 로컬 /...와 허용된 https host만 통과시키고,
protocol-relative URL과 잘못된 scheme을 제외하도록 한 점이 적절합니다.

sanitizeSoftUxProfileImageUrlresolveMoverProfileImageSrc
검증 기준 일부는 공유하지만 반환 정책과 사용 목적이 달라 현재는 분리 유지하는 편이 더 읽기 좋아 보입니다.
필요하다면 나중에 공통 URL 판별 함수만 추출하는 정도가 적절할 것 같습니다.

이메일 로그인은 현재 BE에서 요청 role과 DB role mismatch를 토큰 발급 전에 차단하므로,
FE에서 별도 mismatch logout을 제거한 것도 맞는 방향입니다.
OAuth는 아직 같은 서버 정책이 적용되지 않아 기존 롤백을 유지하고 있어 두 인증 흐름도 잘 구분되어 있습니다.

스크롤 잠금 역시 참조 카운트 기반 공통 훅으로 바꾸면서
Modal exit 기간과 중첩 overlay 상황까지 고려되어 있습니다.

이번 PR에서 설명한 기능들은 전반적으로 빠짐없이 잘 반영된 것으로 보입니다.

수고하셨습니다! 👍

Comment thread src/lib/auth/profileImage.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/utils/preventEnterSubmitOnInput.ts`:
- Around line 3-15: Update preventEnterSubmitOnInput to be a pure predicate that
only returns whether the Enter key should be blocked, without calling
preventDefault; move the event.preventDefault() call into each profile form’s
onKeyDown handler when the utility returns true, preserving the existing
composition, target, and input-type checks.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f25a02bb-339c-49b4-8e46-f51e577c56ef

📥 Commits

Reviewing files that changed from the base of the PR and between eb709c5 and 3a6bf95.

📒 Files selected for processing (9)
  • src/components/profile/CustomerProfileEditForm.tsx
  • src/components/profile/MoverBasicInfoEditForm.tsx
  • src/components/profile/MoverProfileEditForm.tsx
  • src/components/profile/ProfileChipGroup.tsx
  • src/components/profile/ProfileImageUploader.tsx
  • src/hooks/useBodyScrollLock.ts
  • src/lib/auth/role.ts
  • src/lib/utils/moverProfileImage.ts
  • src/lib/utils/preventEnterSubmitOnInput.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/lib/utils/moverProfileImage.ts
  • src/hooks/useBodyScrollLock.ts
  • src/components/profile/MoverProfileEditForm.tsx
  • src/lib/auth/role.ts
  • src/components/profile/CustomerProfileEditForm.tsx

Comment thread src/lib/utils/preventEnterSubmitOnInput.ts
@9g-g9
9g-g9 merged commit fe6e4a8 into dev Aug 13, 2026
3 checks passed
@9g-g9
9g-g9 requested a review from wndnjs2037 August 13, 2026 08:15
@wndnjs2037

Copy link
Copy Markdown
Collaborator

두 이미지 검증 함수가 //, \, ..을 같은 기준으로 막아서, cookie로 들어오든 DB 값으로 들어오든 우회 지점이 갈라지지 않게 짜신 점이 좋은 것 같습니다.
useBodyScrollLock도 기존 body의 padding-right에 스크롤바 너비를 더하는 방식으로 짜셔서, 모달 열릴 때 기존 여백을 덮어쓰지 않고 그만큼만 더해져 레이아웃이 안 밀리게 될 것 같아요.

Soft UX cookie 검증 관련
어색하거나 보안성이 좋지 않은 부분은 없어보입니다!
cookie는 사용자가 직접 값을 바꿀 수 있지만, sanitizeSoftUxProfileImageUrl, sanitizeSoftUxNickname, parseSoftUxAuthRole이 저장/조회 시마다 값을 다시 걸러내고 있어서 조작된 값이 그대로 화면에 나가지 않는 구조라, 조작해도 인증이 뚫리거나 이상한 값이 노출될 걱정은 없어 보입니다.

이미지 함수 통합 관련
sanitizeSoftUxProfileImageUrl은 실패 시 null, resolveMoverProfileImageSrc는 실패 시 기본 이미지로 대체합니다. 실패했을 때 결과가 서로 달라서, 합치면 한쪽 용도에 맞지 않는 값이 나갈 수 있습니다.
그래서 지금처럼 분리 유지하시고, 겹치는 판별 부분(허용 host/로컬 경로 체크)만 공통으로 뽑아 쓰는 방향이 나아 보입니다.

고생 많으셨습니다 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants