fix: IBK 기업은행 점검 기간 중에는 서비스 이용을 차단 - #180
Conversation
WalkthroughLoginPage에 3월 1일 자정부터 정오까지의 유지보수 시간대 기능을 추가하고, 유지보수 모달 UI와 조건부 로그인 옵션을 구현했습니다. Payment.Information.tsx의 문법 오류를 수정했습니다. Changes
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/pages/LoginPage.tsx`:
- Around line 86-99: Frontend currently hides the Google login Button
(GOOGLE_LOGIN_URL) when isMaintenance is true, but the backend OAuth endpoint
(/oauth2/authorization/google) must also enforce the same maintenance logic;
update the authentication server's OAuth entry (the handler that processes
requests to /oauth2/authorization/google) to call the same maintenance check
(isMaintenanceTime() or equivalent) and return an HTTP 503 (or an appropriate
error status) with a maintenance message when true, while keeping the frontend
guard for UX; ensure the backend log includes context and the same maintenance
condition is centralized/shared if possible so both front and back use the same
predicate.
- Around line 19-28: Replace the local-time, year-less check in
isMaintenanceTime with an absolute UTC timestamp comparison for the one-time
2026-03-01 window (e.g., compute start/end via Date.UTC(2026, 2, 1, 0, 0, 0) and
Date.UTC(2026, 2, 1, 12, 0, 0) and compare against Date.now() or new
Date().getTime() in UTC), update the React effect that relies on it (the
useEffect that shows/hides the UI) to re-evaluate periodically or set a timer
(setInterval or setTimeout to the end time) so the UI updates when maintenance
ends, and ensure the same absolute-time check is implemented on the backend
OAuth enforcement path so UI hiding cannot be bypassed by direct endpoint calls
(reference isMaintenanceTime and the relevant useEffect).
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (2)
src/pages/LoginPage.tsxsrc/pages/Payment/Payment.Information.tsx
| // IBK 기업은행 점검 시간 체크 함수 | ||
| const isMaintenanceTime = (): boolean => { | ||
| const now = new Date(); | ||
| const month = now.getMonth() + 1; // 0-based이므로 +1 | ||
| const date = now.getDate(); | ||
| const hours = now.getHours(); | ||
|
|
||
| // 3월 1일 0시~12시 (0시부터 11시 59분까지) | ||
| return month === 3 && date === 1 && hours >= 0 && hours < 12; | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Check if the file exists and examine its structure
cd src/pages && ls -la LoginPage.tsx
wc -l LoginPage.tsxRepository: dkuaegis/aegis-join
Length of output: 143
🏁 Script executed:
# Read the LoginPage.tsx file to see the actual implementation
cat -n src/pages/LoginPage.tsx | head -80Repository: dkuaegis/aegis-join
Length of output: 3161
🏁 Script executed:
# Search for any maintenance-related server logic or configuration
rg "maintenance|MAINTENANCE|점검|2026-03-01" --type ts --type tsx --type js --type json -iRepository: dkuaegis/aegis-join
Length of output: 90
🏁 Script executed:
# Search for OAuth or API blocking logic related to maintenance
rg "oauth2.*google|authorization.*google" -A 5 -B 5 --type ts --type tsx --type jsRepository: dkuaegis/aegis-join
Length of output: 90
🏁 Script executed:
# Search for maintenance-related logic without file type specification
rg "maintenance|MAINTENANCE|점검|2026-03-01" -iRepository: dkuaegis/aegis-join
Length of output: 1059
🏁 Script executed:
# Search for server configuration or environment files that might contain maintenance logic
fd -e json -e config -e env | head -20Repository: dkuaegis/aegis-join
Length of output: 232
🏁 Script executed:
# Search for any OAuth blocking or server-side validation
rg "oauth|authorization|google" -i | grep -E "(block|maintenance|check|verify)" -iRepository: dkuaegis/aegis-join
Length of output: 45
🏁 Script executed:
# Check if there's a backend directory or if this is frontend-only
ls -laRepository: dkuaegis/aegis-join
Length of output: 1459
🏁 Script executed:
# Examine package.json to understand the project structure
cat package.json | head -50Repository: dkuaegis/aegis-join
Length of output: 1569
🏁 Script executed:
# Search for any service or API files that might handle OAuth
fd -e ts -e js | grep -E "(service|api|oauth)" | head -20Repository: dkuaegis/aegis-join
Length of output: 262
🏁 Script executed:
# Check the main API file to understand OAuth implementation
cat -n src/api/api.ts | head -100Repository: dkuaegis/aegis-join
Length of output: 1429
🏁 Script executed:
# Check if there's any maintenance blocking in the OAuth or login flow
cat -n src/api/errorMessage.tsRepository: dkuaegis/aegis-join
Length of output: 3688
🏁 Script executed:
# Look at the full LoginPage to see where GOOGLE_LOGIN_URL is used
cat -n src/pages/LoginPage.tsx | tail -70Repository: dkuaegis/aegis-join
Length of output: 2617
로컬 시각 기반 점검 판별로 운영 기준 시각과 불일치 및 매년 반복 차단됩니다.
현재 구현은 브라우저의 로컬 시간대를 따르므로 사용자 위치 시간대에 따라 오판 가능성이 있고, 연도 조건이 없어 매년 3월 1일마다 반복 차단됩니다. 일회성 2026년 3월 1일 점검이라면 절대 시각 기반 비교로 고정해야 합니다.
🔧 제안 수정안
+const MAINTENANCE_START_MS = Date.parse("2026-03-01T00:00:00+09:00");
+const MAINTENANCE_END_MS = Date.parse("2026-03-01T12:00:00+09:00");
+
// IBK 기업은행 점검 시간 체크 함수
const isMaintenanceTime = (): boolean => {
- const now = new Date();
- const month = now.getMonth() + 1; // 0-based이므로 +1
- const date = now.getDate();
- const hours = now.getHours();
-
- // 3월 1일 0시~12시 (0시부터 11시 59분까지)
- return month === 3 && date === 1 && hours >= 0 && hours < 12;
+ const nowMs = Date.now();
+ return nowMs >= MAINTENANCE_START_MS && nowMs < MAINTENANCE_END_MS;
};추가로 useEffect 의존성 배열이 비어있어 페이지를 열어둔 상태에서 점검 해제 시각 전환이 반영되지 않습니다. 또한 UI 숨김만으로는 서버 측 OAuth 엔드포인트 직접 접근을 차단하지 못하므로, 백엔드에서도 유사한 점검 시간 검증이 필요합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/pages/LoginPage.tsx` around lines 19 - 28, Replace the local-time,
year-less check in isMaintenanceTime with an absolute UTC timestamp comparison
for the one-time 2026-03-01 window (e.g., compute start/end via Date.UTC(2026,
2, 1, 0, 0, 0) and Date.UTC(2026, 2, 1, 12, 0, 0) and compare against Date.now()
or new Date().getTime() in UTC), update the React effect that relies on it (the
useEffect that shows/hides the UI) to re-evaluate periodically or set a timer
(setInterval or setTimeout to the end time) so the UI updates when maintenance
ends, and ensure the same absolute-time check is implemented on the backend
OAuth enforcement path so UI hiding cannot be bypassed by direct endpoint calls
(reference isMaintenanceTime and the relevant useEffect).
There was a problem hiding this comment.
이번만 핫픽스로 하고 이후에 기존 코드로 롤백하고자 하는데도 문제가 있나요?
There was a problem hiding this comment.
@KwonDeaGeun, 일회성 핫픽스 후 롤백하신다면 연도 조건 누락으로 인한 매년 반복 차단 문제는 해결됩니다.
다만 다음 두 가지는 일회성 핫픽스라도 여전히 고려가 필요합니다:
-
타임존 문제: 현재 코드는
new Date()로 로컬 시각을 사용하므로, 해외에 있는 사용자나 시스템 시간대 설정이 다른 사용자는 의도하지 않은 시간에 차단되거나 차단이 풀릴 수 있습니다. 한국 시각 기준으로 정확히 제어하려면 KST(UTC+9) 고정이 필요합니다. -
백엔드 검증 부재: UI에서만 Google 로그인 버튼을 숨겨도, 사용자가
GOOGLE_LOGIN_URL을 직접 브라우저 주소창에 입력하거나 개발자 도구로 우회하면 OAuth 인증이 진행됩니다. 점검 기간 중 실제로 차단하려면 백엔드에서도 동일한 시간 체크가 필요합니다.
핫픽스로 급하게 적용하시는 상황이라면 현재 코드로도 대부분의 한국 사용자에게는 정상 작동할 것으로 보입니다. 하지만 가능하다면 위 두 가지를 추가로 보완하시는 것을 권장드립니다.
| {!isMaintenance && ( | ||
| <Button | ||
| onClick={() => { | ||
| Analytics.safeTrack("Google_Login_Click", { | ||
| category: "Auth", | ||
| method: "Google", | ||
| }); | ||
| }} | ||
| className="w-full" | ||
| asChild | ||
| > | ||
| <a href={GOOGLE_LOGIN_URL}>Google로 로그인</a> | ||
| </Button> | ||
| )} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 점검/로그인 차단 관련 로직이 저장소 내에 존재하는지 확인
rg -n -C2 'oauth2/authorization/google|isMaintenanceTime|isMaintenance' --type typescript --type tsx --type tsRepository: dkuaegis/aegis-join
Length of output: 97
🏁 Script executed:
#!/bin/bash
# 백엔드 OAuth 엔드포인트 관련 로직 검색
rg -n -C3 'oauth2|authorization|google' --type java --type kotlin --type python --type js -iRepository: dkuaegis/aegis-join
Length of output: 93
🏁 Script executed:
#!/bin/bash
# 점검 모드 관련 서버 사이드 로직 확인
rg -n 'maintenance|점검|isMaintenanceTime' -A3 -B3 | head -100Repository: dkuaegis/aegis-join
Length of output: 2449
🏁 Script executed:
#!/bin/bash
# 백엔드 OAuth 구현 및 인증 엔드포인트 찾기
fd -e java -e kt -e py | head -20Repository: dkuaegis/aegis-join
Length of output: 45
🏁 Script executed:
#!/bin/bash
# GOOGLE_LOGIN_URL 정의 및 OAuth 엔드포인트 확인
rg -n "GOOGLE_LOGIN_URL|oauth2/authorization"Repository: dkuaegis/aegis-join
Length of output: 261
🏁 Script executed:
#!/bin/bash
# 인증/OAuth 관련 서버 사이드 로직 검색
rg -n "authorize|oauth|authentication|Authorization" -C2 | head -150Repository: dkuaegis/aegis-join
Length of output: 802
🏁 Script executed:
#!/bin/bash
# 저장소 전체 구조 확인 - 백엔드 코드 유무
find . -name "*.java" -o -name "*.kt" -o -name "*.py" -o -name "application.yml" -o -name "application.yaml" 2>/dev/null | head -20Repository: dkuaegis/aegis-join
Length of output: 45
🏁 Script executed:
#!/bin/bash
# package.json 및 프로젝트 구조 확인
cat package.json | head -30Repository: dkuaegis/aegis-join
Length of output: 997
🏁 Script executed:
#!/bin/bash
# 환경 변수 및 API 설정 확인
rg -n "VITE_API_URL|API_BASE_URL|backends|proxy"Repository: dkuaegis/aegis-join
Length of output: 389
OAuth 엔드포인트 접근 차단이 백엔드에서도 강제되어야 합니다.
현재 구현은 프론트엔드에서만 버튼을 숨기고 있어, /oauth2/authorization/google에 직접 접근할 경우 점검 시간 차단을 우회할 수 있습니다. 이 저장소는 프론트엔드만 포함하고 있으므로, 백엔드 OAuth 엔드포인트에서도 isMaintenanceTime() 로직과 동일한 조건으로 요청을 거부하도록 구현되었는지 확인이 필요합니다. 프론트 가드는 UX 안내용으로 유지하고, 실제 차단은 백엔드 인증 엔드포인트에서 시행되어야 합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/pages/LoginPage.tsx` around lines 86 - 99, Frontend currently hides the
Google login Button (GOOGLE_LOGIN_URL) when isMaintenance is true, but the
backend OAuth endpoint (/oauth2/authorization/google) must also enforce the same
maintenance logic; update the authentication server's OAuth entry (the handler
that processes requests to /oauth2/authorization/google) to call the same
maintenance check (isMaintenanceTime() or equivalent) and return an HTTP 503 (or
an appropriate error status) with a maintenance message when true, while keeping
the frontend guard for UX; ensure the backend log includes context and the same
maintenance condition is centralized/shared if possible so both front and back
use the same predicate.
Summary by CodeRabbit
릴리스 노트
New Features
Bug Fixes