File manager - Edit - /home/webapp69.cm.in.th/u69319090038/Shop/public/js/api.js
Back
// ============================================================ // api.js — Fetch wrapper with automatic JWT refresh + token management // ============================================================ const API_BASE = './api'; // ─── Token Storage (in-memory for security) ────────────────── let _accessToken = null; export const Auth = { setToken(token) { _accessToken = token; }, getToken() { return _accessToken; }, clearToken() { _accessToken = null; }, isLoggedIn() { return !!_accessToken; }, // Save user info to sessionStorage for quick access setUser(user) { sessionStorage.setItem('user', JSON.stringify(user)); }, getUser() { try { return JSON.parse(sessionStorage.getItem('user')); } catch(e) { return null; } }, clearUser() { sessionStorage.removeItem('user'); }, logout() { this.clearToken(); this.clearUser(); } }; // ─── Core Fetch Wrapper ──────────────────────────────────────── async function apiFetch(url, options = {}, retry = true) { const headers = { 'Content-Type': 'application/json', ...(options.headers || {}) }; if (_accessToken) { headers['Authorization'] = `Bearer ${_accessToken}`; } const res = await fetch(url, { ...options, headers, credentials: 'include' }); const data = await res.json().catch(() => ({ success: false, message: 'Invalid server response.' })); // Auto-refresh if access token expired if (res.status === 401 && data.code === 'TOKEN_EXPIRED' && retry) { const refreshed = await silentRefresh(); if (refreshed) { return apiFetch(url, options, false); // Retry once } else { Auth.logout(); redirectToLogin('Session expired. Please login again.'); return null; } } return { ok: res.ok, status: res.status, data }; } // ─── Silent Token Refresh ───────────────────────────────────── async function silentRefresh() { try { const res = await fetch(`${API_BASE}/auth/refresh.php`, { method: 'POST', credentials: 'include' }); const data = await res.json(); if (data.success && data.accessToken) { Auth.setToken(data.accessToken); Auth.setUser(data.user); return true; } } catch (e) { /* network error */ } return false; } // ─── Redirect helpers ───────────────────────────────────────── export function redirectToLogin(msg = '') { const url = msg ? `./auth.php?msg=${encodeURIComponent(msg)}` : './auth.php'; window.location.href = url; } export function redirectHome() { window.location.href = './index.php'; } // ─── Auth guard for protected pages ───────────────────────── export async function requireAuth(requiredRole = null) { // Try refresh if no token in memory if (!Auth.isLoggedIn()) { const refreshed = await silentRefresh(); if (!refreshed) { redirectToLogin('Please login to continue.'); return null; } } const user = Auth.getUser(); if (requiredRole && user?.role !== requiredRole && user?.role !== 'admin') { if (requiredRole === 'seller') { window.location.href = './account.php?upgrade=1'; } else { window.location.href = './index.php'; } return null; } return user; } // ─── API Methods ────────────────────────────────────────────── export const api = { // Auth register: (body) => apiFetch(`${API_BASE}/auth/register.php`, { method: 'POST', body: JSON.stringify(body) }), login: (body) => apiFetch(`${API_BASE}/auth/login.php`, { method: 'POST', body: JSON.stringify(body) }), sendOtp: (identifier, purpose) => apiFetch(`${API_BASE}/auth/send_otp.php`, { method: 'POST', body: JSON.stringify({ identifier, purpose }) }), verifyOtp: (body) => apiFetch(`${API_BASE}/auth/verify_otp.php`, { method: 'POST', body: JSON.stringify(body) }), logout: () => apiFetch(`${API_BASE}/auth/logout.php`, { method: 'POST' }), getProfile: () => apiFetch(`${API_BASE}/auth/profile.php`, { method: 'GET' }), applySeller: (body) => apiFetch(`${API_BASE}/auth/apply_seller.php`,{ method: 'POST', body: JSON.stringify(body) }), // Protected getCart: () => apiFetch(`${API_BASE}/protected/cart.php`, { method: 'GET' }), addToCart: (body) => apiFetch(`${API_BASE}/protected/cart.php`, { method: 'POST', body: JSON.stringify(body) }), updateCart: (body) => apiFetch(`${API_BASE}/protected/cart.php`, { method: 'PUT', body: JSON.stringify(body) }), removeFromCart: (body) => apiFetch(`${API_BASE}/protected/cart.php`, { method: 'DELETE', body: JSON.stringify(body) }), getCheckout: () => apiFetch(`${API_BASE}/protected/checkout.php`, { method: 'GET' }), getSellerCenter: () => apiFetch(`${API_BASE}/protected/seller_center.php`, { method: 'GET' }), // Public products getProducts: (qs) => apiFetch(`${API_BASE}/products/list.php${qs||''}`, { method: 'GET' }), // Seller sellerStats: () => apiFetch(`${API_BASE}/seller/stats.php`, { method: 'GET' }), sellerProducts: () => apiFetch(`${API_BASE}/seller/products.php`, { method: 'GET' }), sellerCreateProduct: (body) => apiFetch(`${API_BASE}/seller/products.php`, { method: 'POST', body: JSON.stringify(body) }), sellerUpdateProduct: (body) => apiFetch(`${API_BASE}/seller/products.php`, { method: 'PUT', body: JSON.stringify(body) }), sellerDeleteProduct: (body) => apiFetch(`${API_BASE}/seller/products.php`, { method: 'DELETE', body: JSON.stringify(body) }), sellerOrders: (qs) => apiFetch(`${API_BASE}/seller/orders.php${qs||''}`, { method: 'GET' }), sellerUpdateOrder: (body) => apiFetch(`${API_BASE}/seller/orders.php`, { method: 'PUT', body: JSON.stringify(body) }), sellerConversations: () => apiFetch(`${API_BASE}/seller/messages.php`, { method: 'GET' }), sellerThread: (bid) => apiFetch(`${API_BASE}/seller/messages.php?buyer_id=${bid}`, { method: 'GET' }), sellerReply: (body) => apiFetch(`${API_BASE}/seller/messages.php`, { method: 'POST', body: JSON.stringify(body) }), }; // ─── Init: Try silent refresh on page load ──────────────────── export async function initAuth() { if (!Auth.isLoggedIn()) { await silentRefresh(); } return Auth.getUser(); }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.26 |
proxy
|
phpinfo
|
Settings