From a51e76fd805687fd980eb5c26cc75fbdf84613dc Mon Sep 17 00:00:00 2001 From: jjamming Date: Tue, 14 Apr 2026 11:30:02 +0900 Subject: [PATCH 1/3] chore(deps): bump axios to ^1.15.0 (GHSA-fvcv-3m26-pcqx / CVE-2026-40175) --- package.json | 2 +- pnpm-lock.yaml | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index bea73ed..ffaf871 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "@supabase/supabase-js": "^2.98.0", "@tailwindcss/vite": "^4.1.8", "@tanstack/react-query": "^5.90.8", - "axios": "^1.13.2", + "axios": "^1.15.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^4.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0f8c845..f1a77d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ dependencies: specifier: ^5.90.8 version: 5.90.21(react@19.2.4) axios: - specifier: ^1.13.2 - version: 1.13.6 + specifier: ^1.15.0 + version: 1.15.0 class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -2156,12 +2156,12 @@ packages: possible-typed-array-names: 1.1.0 dev: true - /axios@1.13.6: - resolution: {integrity: sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==} + /axios@1.15.0: + resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==} dependencies: follow-redirects: 1.15.11 form-data: 4.0.5 - proxy-from-env: 1.1.0 + proxy-from-env: 2.1.0 transitivePeerDependencies: - debug dev: false @@ -3760,8 +3760,9 @@ packages: object-assign: 4.1.1 react-is: 16.13.1 - /proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + /proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} dev: false /punycode@2.3.1: From d5ec9755730a0be2a2c83e2e2f255ee6e24082a4 Mon Sep 17 00:00:00 2001 From: jjamming Date: Sun, 17 May 2026 16:35:55 +0900 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20Supabase=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EB=88=84=EB=9D=BD=20=EC=8B=9C=20=EC=95=B1?= =?UTF-8?q?=20=ED=81=AC=EB=9E=98=EC=8B=9C=20=EB=8C=80=EC=8B=A0=20=ED=86=A0?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=95=88=EB=82=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - supabase.ts: 모듈 로드 시 throw 제거. env 누락 시 Proxy 기반 lazy client로 호출 시점에만 SupabaseConfigError 발생 - AuthContext: 미설정 환경에서는 세션 조회/구독을 건너뛰어 앱 부팅 보장 - LoginPage/SignupPage: GitHub OAuth 버튼도 try/catch 처리하여 unhandled rejection 방지 - error.ts: SupabaseConfigError 인식 및 사용자 친화적 메시지 반환 Co-Authored-By: Claude Opus 4.7 (1M context) --- src/lib/contexts/AuthContext.tsx | 7 ++++++- src/lib/error.ts | 5 +++++ src/lib/supabase.ts | 24 ++++++++++++++++++++---- src/pages/LoginPage.tsx | 10 +++++++++- src/pages/SignupPage.tsx | 10 +++++++++- 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/lib/contexts/AuthContext.tsx b/src/lib/contexts/AuthContext.tsx index 5feeab0..98fe200 100644 --- a/src/lib/contexts/AuthContext.tsx +++ b/src/lib/contexts/AuthContext.tsx @@ -1,6 +1,6 @@ import { createContext, useEffect, useState } from "react"; import type { User } from "@supabase/supabase-js"; -import { supabase } from "@/lib/supabase"; +import { supabase, isSupabaseConfigured } from "@/lib/supabase"; interface AuthContextType { user: User | null; @@ -17,6 +17,11 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const [isLoading, setIsLoading] = useState(true); useEffect(() => { + if (!isSupabaseConfigured) { + setIsLoading(false); + return; + } + supabase.auth.getSession().then(({ data: { session } }) => { setUser(session?.user ?? null); setIsLoading(false); diff --git a/src/lib/error.ts b/src/lib/error.ts index 6570fe8..781b4d5 100644 --- a/src/lib/error.ts +++ b/src/lib/error.ts @@ -1,4 +1,5 @@ import { AuthError } from "@supabase/supabase-js"; +import { SupabaseConfigError } from "@/lib/supabase"; const AUTH_ERROR_MESSAGE_MAP: Record = { email_exists: "이미 사용 중인 이메일입니다.", @@ -22,6 +23,10 @@ const AUTH_ERROR_MESSAGE_MAP: Record = { }; export function generateErrorMessage(error: unknown) { + if (error instanceof SupabaseConfigError) { + return error.message; + } + if (error instanceof AuthError && error.code) { return ( AUTH_ERROR_MESSAGE_MAP[error.code] ?? diff --git a/src/lib/supabase.ts b/src/lib/supabase.ts index 31e474d..05fc244 100644 --- a/src/lib/supabase.ts +++ b/src/lib/supabase.ts @@ -1,10 +1,26 @@ -import { createClient } from "@supabase/supabase-js"; +import { createClient, type SupabaseClient } from "@supabase/supabase-js"; const supabaseUrl = import.meta.env.VITE_SUPABASE_URL; const supabaseKey = import.meta.env.VITE_SUPABASE_PUBLISHABLE_DEFAULT_KEY; -if (!supabaseUrl || !supabaseKey) { - throw new Error("Supabase 환경변수가 없거나 잘못되었습니다."); +export const isSupabaseConfigured = Boolean(supabaseUrl && supabaseKey); + +export class SupabaseConfigError extends Error { + constructor() { + super("인증 서비스 설정이 누락되었습니다. 잠시 후 다시 시도해주세요."); + this.name = "SupabaseConfigError"; + } +} + +function createUnconfiguredClient(): SupabaseClient { + const handler: ProxyHandler = { + get() { + throw new SupabaseConfigError(); + }, + }; + return new Proxy({}, handler) as SupabaseClient; } -export const supabase = createClient(supabaseUrl, supabaseKey); +export const supabase: SupabaseClient = isSupabaseConfigured + ? createClient(supabaseUrl, supabaseKey) + : createUnconfiguredClient(); diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index 38461ba..01c87e3 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -41,6 +41,14 @@ const LoginPage = () => { } }; + const handleClickGitHubSignIn = async () => { + try { + await signInWithGitHub(); + } catch (error) { + toast.error(generateErrorMessage(error)); + } + }; + return (
@@ -88,7 +96,7 @@ const LoginPage = () => {