Ramble-FE / services / authService.native.ts
authService.native.ts
Raw
import { fetchWithAuth } from "@/lib";
import { AuthResponse, GoogleMobileLoginParams } from "@/types";
import { ResponseUtils, TokenUtils, tokenStorage } from "@/utils";
import { cookieStorage } from "@/utils/cookieStorage";
import Constants from "expo-constants";
import { Platform } from "react-native";

export class AuthService {
    private static readonly API_BASE_URL = Constants.expoConfig?.extra?.apiBaseUrl as string;
    private static readonly CONTENT_TYPE_JSON = "application/json";
    private static readonly DEFAULT_HEADERS = { "Content-Type": AuthService.CONTENT_TYPE_JSON, "Ramble-Client-Platform": Platform.OS, };

    static async loginWithGoogle(params: GoogleMobileLoginParams): Promise<AuthResponse> {
        try {
            const response = await fetch(`${AuthService.API_BASE_URL}/oauth/authorize/google/mobile`, {
                method: "POST",
                headers: AuthService.DEFAULT_HEADERS,
                body: JSON.stringify(params),
            });

            if (!response.ok) {
                await ResponseUtils.handleApiError(response, "Google 로그인");
            }

            const tokens = TokenUtils.extractTokensFromHeaders(response.headers);
            await tokenStorage.setAccessToken(tokens.accessToken); 
            await cookieStorage.setRefreshToken(tokens.cookieHeader);

            return { success: true };
        } catch (error) {
            return { 
                success: false, 
                error: error instanceof Error ? error.message : "Google 로그인에 실패했습니다" 
            };
        }
    }

    static async reissueToken(): Promise<AuthResponse> {
        try {
            const token = await cookieStorage.getRefreshToken();

            const response = await fetch(`${AuthService.API_BASE_URL}/auth/reissue`, {
                method: "POST",
                headers: {
                    ...AuthService.DEFAULT_HEADERS,
                    ...(token ? { "set-cookie": `refresh=${token}` } : {}),
                },
            });

            if (!response.ok) {
                await ResponseUtils.handleApiError(response, "토큰 갱신");
            }

            const tokens = TokenUtils.extractTokensFromHeaders(response.headers);
            await tokenStorage.setAccessToken(tokens.accessToken);
            await cookieStorage.setRefreshToken(tokens.cookieHeader);

            return { success: true };
        } catch (error) {
            await tokenStorage.removeAccessToken();
            await cookieStorage.removeRefreshToken();
            
            return { 
                success: false, 
                error: error instanceof Error ? error.message : "토큰 갱신에 실패했습니다" 
            };
        }
    }

    static async logout(): Promise<AuthResponse> {
        try {
            await fetchWithAuth("/auth/logout", { method: "POST", });
            await tokenStorage.removeAccessToken();
            await cookieStorage.removeRefreshToken();

            return { success: true };
        } catch (error) {
            return { 
                success: false, 
                error: error instanceof Error ? error.message : "로그아웃에 실패했습니다" 
            };
        }
    }

}