Skip to content

OTP Verify and Passcode Flow — Consolidated Planning

Purpose: Single reference for OTP verify flow, failure causes, CORS/network issues, dashboard UX, and KV check.
Source: Merged from otp-verify-and-passcode-flow-check, otp-verify-failure-and-dashboard-ux, otp-verify-network-error-cors-analysis-and-fix, otp-verify-page-kv-check-and-dashboard-b6, verify-email-rsc-and-cors-local-debug.


1. Expected vs Actual Behavior

ExpectedActual
OTP input matches KV → success, redirect to passcode/setOften “Invalid or expired code” or “Something went wrong”
Dashboard shows success/failure clearly”예상 장애” shown even when trigger succeeds

2. OTP Verify Flow (Checklist)

  1. Client (verify-email): POST {NEXT_PUBLIC_API_URL}/auth/otp/verify, body { email, code }, credentials: 'include'. Code: 6 digits only, email: trim, toLowerCase.
  2. Zuplo: Route /auth/otp/verify to Auth Worker.
  3. Auth Worker: AUTH_STORE.get('otp:'+email), compare with code. Match → delete OTP, set cookies, 200 { success, next: 'passcode/set' }. Mismatch → 401.
  4. KV key: otp:{email} — email must be lowercase exact match.

3. Failure Causes (Investigation)

CauseCheck
CORSBrowser (x.pregoi.com) → Zuplo cross-origin. Zuplo/Auth Worker must return Access-Control-Allow-Origin. CORS failure → Failed to fetch → “Network error” or “Something went wrong”.
API URLNEXT_PUBLIC_API_URL empty or wrong → request to wrong host.
Email/code mismatchClient normalization (trim, toLowerCase) vs Auth Worker; KV key uses lowercase email.
OTP expiryTTL elapsed; AUTH_STORE returns null.
Server 401”Invalid or expired code” (not catch). “Something went wrong” → fetch failed (network/CORS) before response.

4. CORS / Network Error Analysis

  • verify-email page (fails): Browser directly calls Zuplo. Cross-origin → CORS applies. If Zuplo does not allow x.pregoi.com, browser blocks response → Failed to fetch → “Network error”.
  • Control Plane debug (succeeds): Control Plane Worker calls Zuplo server-to-server. No CORS.
  • Fix: Zuplo CORS policy to allow https://x.pregoi.com (and other tenant origins) for /auth/otp/verify.

5. Passcode Flow

  • Next step after OTP success: passcode/set page. User sets 6-digit passcode.
  • Endpoints: handlePasscodeSet, handlePasscodeRequestReset, handlePasscodeReset, setAuthCookies.

6. Email Flow Dashboard UX

  • Issue: Flow B trigger returns 200 but card shows “예상 장애” — confusing.
  • Fix: Distinguish “expected failure points” (reference) from “current status”. Show green/red based on actual trigger result.
  • B6 (KV code match): After email delivery, add step to verify code matches KV. Green if match, red if not. Auto-run with other Flow B steps.

Implementation status

#ItemWhereStatus
1Zuplo CORS allows tenant origin for /auth/otp/verify (§4)prego-zuplo확인됨 (Auth Worker OAS 조각 — 예: 04-auth-worker-auth-otp-request-n2.oas.json — 에서 POST·OPTIONS에 corsPolicy: "prego-web" 적용. 전체 목록은 prego-zuplo/config/oas-manifest.json. CORS 실패 시 Zuplo에서 prego-web 정책에 tenant origin(예: https://x.pregoi.com) 포함 여부 확인)
2Dashboard: show green/red from actual trigger result, not “예상 장애” (§6)prego-control-plane적용됨 (updateStepCards/updateFlowBCards가 트리거 응답 ok로 카드 상태 설정; .risks는 step-fail일 때만 표시)
3Flow B6: KV code match check after email delivery (§6)prego-control-plane적용됨 (Flow B 실행 시 otp_for_test 있으면 자동 trigger-otp-verify 호출 후 B6 success/fail 표시; E2E 동일)

Update when implemented.


References


한국어

OTP 검증 및 Passcode 플로우 — 통합 기획

목적: OTP 검증 플로우·실패 원인·CORS·네트워크 에러·대시보드 UX·KV 코드 일치(B6)를 한 문서에서 참조.

요약

  • §1 현상: 올바른 OTP 입력 시에도 “Invalid or expired code” 또는 “Something went wrong” 발생. 대시보드 “예상 장애” 문구 혼동.
  • §2 검증 플로우: 클라이언트 POST /auth/otp/verify → Zuplo → Auth Worker AUTH_STORE 비교 → 일치 시 passcode/set 이동.
  • §3 실패 원인: CORS(브라우저→Zuplo cross-origin), API URL 오설정, 이메일/코드 불일치, OTP 만료.
  • §4 CORS: verify-email 페이지는 브라우저가 Zuplo 직접 호출 → CORS 필요. Zuplo에 tenant origin 허용.
  • §5·§6: passcode 설정 플로우, 대시보드 B6(KV 코드 일치) 추가.
Help