Refactor auth.utils.ts
Refactor auth.utils.ts into smaller modules for better organization and maintainability. Split functions into networkUtils.ts, responseUtils.ts, and toastUtils.ts based on their purpose.
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
import { supabase } from '@/lib/supabase';
|
import { supabase } from '@/lib/supabase';
|
||||||
import { handleNetworkError, showAuthToast } from './auth.utils';
|
import { handleNetworkError, showAuthToast } from '@/utils/auth';
|
||||||
|
|
||||||
export const resetPassword = async (email: string) => {
|
export const resetPassword = async (email: string) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
|
||||||
import { supabase } from '@/lib/supabase';
|
import { supabase } from '@/lib/supabase';
|
||||||
import { handleNetworkError, parseResponse, showAuthToast, verifyServerConnection } from './auth.utils';
|
import {
|
||||||
|
handleNetworkError,
|
||||||
|
parseResponse,
|
||||||
|
showAuthToast,
|
||||||
|
verifyServerConnection
|
||||||
|
} from '@/utils/auth';
|
||||||
|
|
||||||
export const signIn = async (email: string, password: string) => {
|
export const signIn = async (email: string, password: string) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
import { supabase } from '@/lib/supabase';
|
import { supabase } from '@/lib/supabase';
|
||||||
import { showAuthToast } from './auth.utils';
|
import { showAuthToast } from '@/utils/auth';
|
||||||
|
|
||||||
export const signOut = async (): Promise<void> => {
|
export const signOut = async (): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
|
|
||||||
import { supabase } from '@/lib/supabase';
|
import { supabase } from '@/lib/supabase';
|
||||||
import { handleNetworkError, parseResponse, showAuthToast } from './auth.utils';
|
import {
|
||||||
|
handleNetworkError,
|
||||||
|
parseResponse,
|
||||||
|
showAuthToast
|
||||||
|
} from '@/utils/auth';
|
||||||
|
|
||||||
export const signUp = async (email: string, password: string, username: string) => {
|
export const signUp = async (email: string, password: string, username: string) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
6
src/utils/auth/index.ts
Normal file
6
src/utils/auth/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
// 모든 인증 관련 유틸리티 함수들을 내보냅니다
|
||||||
|
export * from './toastUtils';
|
||||||
|
export * from './networkUtils';
|
||||||
|
export * from './responseUtils';
|
||||||
|
export * from './validationUtils';
|
||||||
@@ -1,13 +1,9 @@
|
|||||||
|
|
||||||
import { toast } from '@/hooks/useToast.wrapper';
|
|
||||||
import { supabase } from '@/lib/supabase';
|
import { supabase } from '@/lib/supabase';
|
||||||
|
|
||||||
// 토스트 메시지 표시 유틸리티 함수
|
/**
|
||||||
export const showAuthToast = (title: string, description: string, variant: 'default' | 'destructive' = 'default') => {
|
* 네트워크 오류 메시지 처리 유틸리티 함수
|
||||||
toast({ title, description, variant });
|
*/
|
||||||
};
|
|
||||||
|
|
||||||
// 에러 메시지 처리 유틸리티 함수
|
|
||||||
export const handleNetworkError = (error: any): string => {
|
export const handleNetworkError = (error: any): string => {
|
||||||
if (error.message && error.message.includes('fetch')) {
|
if (error.message && error.message.includes('fetch')) {
|
||||||
return '서버 연결에 실패했습니다. 네트워크 연결을 확인해주세요.';
|
return '서버 연결에 실패했습니다. 네트워크 연결을 확인해주세요.';
|
||||||
@@ -26,91 +22,9 @@ export const handleNetworkError = (error: any): string => {
|
|||||||
return error.message || '예상치 못한 오류가 발생했습니다.';
|
return error.message || '예상치 못한 오류가 발생했습니다.';
|
||||||
};
|
};
|
||||||
|
|
||||||
// 응답 파싱 유틸리티 함수 개선
|
/**
|
||||||
export const parseResponse = async (response: Response) => {
|
* CORS 문제 확인
|
||||||
try {
|
*/
|
||||||
// 비어있는 응답 또는 401 응답을 먼저 확인
|
|
||||||
if (response.status === 401) {
|
|
||||||
if (response.headers.get('content-length') === '0' || await response.clone().text() === '') {
|
|
||||||
return {
|
|
||||||
error: '인증 실패: 잘못된 인증 정보 또는 서버 설정 문제',
|
|
||||||
status: 401
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 응답 내용 확인 (디버깅용)
|
|
||||||
const responseText = await response.text();
|
|
||||||
console.log('응답 원본:', responseText, 'Status:', response.status);
|
|
||||||
|
|
||||||
// 빈 응답 또는 공백만 있는 응답 처리
|
|
||||||
if (!responseText || responseText.trim() === '') {
|
|
||||||
if (response.status === 401) {
|
|
||||||
return {
|
|
||||||
error: '인증 실패: 서버가 인증을 거부했습니다.',
|
|
||||||
status: 401
|
|
||||||
};
|
|
||||||
} else if (response.status === 404) {
|
|
||||||
return {
|
|
||||||
error: '서버 경로를 찾을 수 없습니다. Supabase URL을 확인하세요.',
|
|
||||||
status: 404
|
|
||||||
};
|
|
||||||
} else if (response.status >= 200 && response.status < 300) {
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
status: response.status,
|
|
||||||
message: '서버가 성공 상태를 반환했지만 응답 내용이 없습니다.'
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
error: `서버가 빈 응답을 반환했습니다 (상태 코드: ${response.status})`,
|
|
||||||
status: response.status
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return JSON.parse(responseText);
|
|
||||||
} catch (parseError) {
|
|
||||||
console.error('JSON 파싱 오류:', parseError, '원본 텍스트:', responseText);
|
|
||||||
|
|
||||||
// HTTP 상태 코드에 따른 적절한 오류 메시지 반환
|
|
||||||
if (response.status === 401) {
|
|
||||||
return {
|
|
||||||
error: '인증 실패: 이메일 또는 비밀번호가 올바르지 않습니다.',
|
|
||||||
status: 401
|
|
||||||
};
|
|
||||||
} else if (response.status === 404) {
|
|
||||||
return {
|
|
||||||
error: '서버 경로를 찾을 수 없습니다. Supabase URL을 확인하세요.',
|
|
||||||
status: 404
|
|
||||||
};
|
|
||||||
} else if (response.status >= 500) {
|
|
||||||
return {
|
|
||||||
error: '서버 내부 오류가 발생했습니다.',
|
|
||||||
status: response.status
|
|
||||||
};
|
|
||||||
} else if (response.status >= 200 && response.status < 300) {
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
status: response.status,
|
|
||||||
message: '서버가 성공 상태를 반환했지만 JSON 형식이 아닙니다.'
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
error: `응답 형식 오류 (상태 코드: ${response.status}): 서버가 올바른 JSON 응답을 반환하지 않았습니다.`,
|
|
||||||
status: response.status,
|
|
||||||
rawResponse: responseText
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (parseError) {
|
|
||||||
console.error('응답 파싱 오류:', parseError);
|
|
||||||
throw parseError;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// CORS 문제 확인
|
|
||||||
export const hasCorsIssue = (error: any): boolean => {
|
export const hasCorsIssue = (error: any): boolean => {
|
||||||
if (!error) return false;
|
if (!error) return false;
|
||||||
|
|
||||||
@@ -123,7 +37,9 @@ export const hasCorsIssue = (error: any): boolean => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Supabase 연결 상태 확인
|
/**
|
||||||
|
* Supabase 연결 상태 확인
|
||||||
|
*/
|
||||||
export const checkSupabaseConnection = async (): Promise<boolean> => {
|
export const checkSupabaseConnection = async (): Promise<boolean> => {
|
||||||
try {
|
try {
|
||||||
const { data, error } = await supabase.auth.getSession();
|
const { data, error } = await supabase.auth.getSession();
|
||||||
@@ -150,7 +66,9 @@ export const checkSupabaseConnection = async (): Promise<boolean> => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 서버 연결 상태 검사 (개선 버전)
|
/**
|
||||||
|
* 서버 연결 상태 검사
|
||||||
|
*/
|
||||||
export const verifyServerConnection = async (): Promise<{
|
export const verifyServerConnection = async (): Promise<{
|
||||||
connected: boolean;
|
connected: boolean;
|
||||||
message: string;
|
message: string;
|
||||||
@@ -216,14 +134,3 @@ export const verifyServerConnection = async (): Promise<{
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 서버 URL 검증
|
|
||||||
export const validateServerUrl = (url: string): boolean => {
|
|
||||||
try {
|
|
||||||
// URL 유효성 검사
|
|
||||||
new URL(url);
|
|
||||||
return true;
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
86
src/utils/auth/responseUtils.ts
Normal file
86
src/utils/auth/responseUtils.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* 응답 파싱 유틸리티 함수
|
||||||
|
*/
|
||||||
|
export const parseResponse = async (response: Response) => {
|
||||||
|
try {
|
||||||
|
// 비어있는 응답 또는 401 응답을 먼저 확인
|
||||||
|
if (response.status === 401) {
|
||||||
|
if (response.headers.get('content-length') === '0' || await response.clone().text() === '') {
|
||||||
|
return {
|
||||||
|
error: '인증 실패: 잘못된 인증 정보 또는 서버 설정 문제',
|
||||||
|
status: 401
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 응답 내용 확인 (디버깅용)
|
||||||
|
const responseText = await response.text();
|
||||||
|
console.log('응답 원본:', responseText, 'Status:', response.status);
|
||||||
|
|
||||||
|
// 빈 응답 또는 공백만 있는 응답 처리
|
||||||
|
if (!responseText || responseText.trim() === '') {
|
||||||
|
if (response.status === 401) {
|
||||||
|
return {
|
||||||
|
error: '인증 실패: 서버가 인증을 거부했습니다.',
|
||||||
|
status: 401
|
||||||
|
};
|
||||||
|
} else if (response.status === 404) {
|
||||||
|
return {
|
||||||
|
error: '서버 경로를 찾을 수 없습니다. Supabase URL을 확인하세요.',
|
||||||
|
status: 404
|
||||||
|
};
|
||||||
|
} else if (response.status >= 200 && response.status < 300) {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
status: response.status,
|
||||||
|
message: '서버가 성공 상태를 반환했지만 응답 내용이 없습니다.'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
error: `서버가 빈 응답을 반환했습니다 (상태 코드: ${response.status})`,
|
||||||
|
status: response.status
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return JSON.parse(responseText);
|
||||||
|
} catch (parseError) {
|
||||||
|
console.error('JSON 파싱 오류:', parseError, '원본 텍스트:', responseText);
|
||||||
|
|
||||||
|
// HTTP 상태 코드에 따른 적절한 오류 메시지 반환
|
||||||
|
if (response.status === 401) {
|
||||||
|
return {
|
||||||
|
error: '인증 실패: 이메일 또는 비밀번호가 올바르지 않습니다.',
|
||||||
|
status: 401
|
||||||
|
};
|
||||||
|
} else if (response.status === 404) {
|
||||||
|
return {
|
||||||
|
error: '서버 경로를 찾을 수 없습니다. Supabase URL을 확인하세요.',
|
||||||
|
status: 404
|
||||||
|
};
|
||||||
|
} else if (response.status >= 500) {
|
||||||
|
return {
|
||||||
|
error: '서버 내부 오류가 발생했습니다.',
|
||||||
|
status: response.status
|
||||||
|
};
|
||||||
|
} else if (response.status >= 200 && response.status < 300) {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
status: response.status,
|
||||||
|
message: '서버가 성공 상태를 반환했지만 JSON 형식이 아닙니다.'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
error: `응답 형식 오류 (상태 코드: ${response.status}): 서버가 올바른 JSON 응답을 반환하지 않았습니다.`,
|
||||||
|
status: response.status,
|
||||||
|
rawResponse: responseText
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (parseError) {
|
||||||
|
console.error('응답 파싱 오류:', parseError);
|
||||||
|
throw parseError;
|
||||||
|
}
|
||||||
|
};
|
||||||
13
src/utils/auth/toastUtils.ts
Normal file
13
src/utils/auth/toastUtils.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
import { toast } from '@/hooks/useToast.wrapper';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 인증 관련 토스트 메시지 표시 유틸리티 함수
|
||||||
|
*/
|
||||||
|
export const showAuthToast = (
|
||||||
|
title: string,
|
||||||
|
description: string,
|
||||||
|
variant: 'default' | 'destructive' = 'default'
|
||||||
|
) => {
|
||||||
|
toast({ title, description, variant });
|
||||||
|
};
|
||||||
13
src/utils/auth/validationUtils.ts
Normal file
13
src/utils/auth/validationUtils.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* 서버 URL 검증
|
||||||
|
*/
|
||||||
|
export const validateServerUrl = (url: string): boolean => {
|
||||||
|
try {
|
||||||
|
// URL 유효성 검사
|
||||||
|
new URL(url);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user