feat: all project setup
This commit is contained in:
109
lib/api/auth.ts
Normal file
109
lib/api/auth.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
// ============================================================================
|
||||
// Auth API
|
||||
// ============================================================================
|
||||
|
||||
import { api, saveAuthTokens, clearAuthTokens } from "./client";
|
||||
import { STORAGE_KEYS } from "@/lib/utils/constants";
|
||||
import type {
|
||||
User,
|
||||
AuthInitResponse,
|
||||
AuthCompleteRequest,
|
||||
AuthCompleteResponse,
|
||||
AuthRefreshRequest,
|
||||
AuthRefreshResponse,
|
||||
} from "@/lib/types/api";
|
||||
|
||||
export const authApi = {
|
||||
/**
|
||||
* Initialize Telegram auth flow
|
||||
*/
|
||||
init: () => api.get<AuthInitResponse>("/auth/init", { requireAuth: false }),
|
||||
|
||||
/**
|
||||
* Complete auth with one-time token from bot
|
||||
*/
|
||||
complete: async (token: string): Promise<AuthCompleteResponse> => {
|
||||
const data: AuthCompleteRequest = { token };
|
||||
const response = await api.post<AuthCompleteResponse>(
|
||||
"/auth/complete",
|
||||
data,
|
||||
{
|
||||
requireAuth: false,
|
||||
}
|
||||
);
|
||||
|
||||
// Save tokens to storage
|
||||
saveAuthTokens(response.access_token, response.refresh_token);
|
||||
|
||||
// Save user to storage
|
||||
if (typeof window !== "undefined") {
|
||||
localStorage.setItem(STORAGE_KEYS.USER, JSON.stringify(response.user));
|
||||
}
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
/**
|
||||
* Refresh access token
|
||||
*/
|
||||
refresh: async (): Promise<string> => {
|
||||
if (typeof window === "undefined") {
|
||||
throw new Error("Cannot refresh token on server");
|
||||
}
|
||||
|
||||
const refreshToken = localStorage.getItem(STORAGE_KEYS.REFRESH_TOKEN);
|
||||
if (!refreshToken) {
|
||||
throw new Error("No refresh token available");
|
||||
}
|
||||
|
||||
const data: AuthRefreshRequest = { refresh_token: refreshToken };
|
||||
const response = await api.post<AuthRefreshResponse>(
|
||||
"/auth/refresh",
|
||||
data,
|
||||
{
|
||||
requireAuth: false,
|
||||
}
|
||||
);
|
||||
|
||||
// Update access token
|
||||
localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, response.access_token);
|
||||
|
||||
return response.access_token;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get current user info
|
||||
*/
|
||||
me: () => api.get<User>("/auth/me"),
|
||||
|
||||
/**
|
||||
* Logout (clear tokens)
|
||||
*/
|
||||
logout: () => {
|
||||
clearAuthTokens();
|
||||
},
|
||||
|
||||
/**
|
||||
* Get user from storage (no API call)
|
||||
*/
|
||||
getUserFromStorage: (): User | null => {
|
||||
if (typeof window === "undefined") return null;
|
||||
|
||||
const userJson = localStorage.getItem(STORAGE_KEYS.USER);
|
||||
if (!userJson) return null;
|
||||
|
||||
try {
|
||||
return JSON.parse(userJson);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if user is authenticated
|
||||
*/
|
||||
isAuthenticated: (): boolean => {
|
||||
if (typeof window === "undefined") return false;
|
||||
return !!localStorage.getItem(STORAGE_KEYS.ACCESS_TOKEN);
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user