🚀 مُصادَق: تحديث برمجي جديد 2026-05-03 13:19
This commit is contained in:
@@ -1,73 +1,55 @@
|
||||
/**
|
||||
* مُصادَق — API Client with JWT Auth & Refresh Flow
|
||||
*/
|
||||
window.API = {
|
||||
baseUrl: '/Application/public/api.php',
|
||||
accessToken: localStorage.getItem('access_token'),
|
||||
|
||||
async get(path) {
|
||||
return this._request('GET', path);
|
||||
},
|
||||
|
||||
async post(path, body) {
|
||||
return this._request('POST', path, body);
|
||||
},
|
||||
|
||||
async upload(path, formData) {
|
||||
return this._request('POST', path, formData, true);
|
||||
},
|
||||
|
||||
async _request(method, path, body = null, isFormData = false) {
|
||||
const API = {
|
||||
baseUrl: '/api/v1',
|
||||
|
||||
async request(endpoint, options = {}) {
|
||||
const url = `${this.baseUrl}${endpoint}`;
|
||||
const token = localStorage.getItem('access_token');
|
||||
|
||||
const headers = {
|
||||
'Accept': 'application/json',
|
||||
...(options.body instanceof FormData ? {} : { 'Content-Type': 'application/json' }),
|
||||
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
|
||||
...options.headers
|
||||
};
|
||||
|
||||
if (this.accessToken) {
|
||||
headers['Authorization'] = `Bearer ${this.accessToken}`;
|
||||
}
|
||||
|
||||
if (!isFormData && body) {
|
||||
headers['Content-Type'] = 'application/json';
|
||||
body = JSON.stringify(body);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}${path}`, {
|
||||
method,
|
||||
headers,
|
||||
body
|
||||
});
|
||||
|
||||
if (response.status === 401) {
|
||||
const refreshed = await this.refreshToken();
|
||||
if (refreshed) {
|
||||
return this._request(method, path, body, isFormData);
|
||||
} else {
|
||||
window.location.href = '/login';
|
||||
}
|
||||
const response = await fetch(url, { ...options, headers });
|
||||
|
||||
if (response.status === 401 && !options._retry) {
|
||||
// Attempt token refresh
|
||||
const refreshed = await this.refresh();
|
||||
if (refreshed) {
|
||||
return this.request(endpoint, { ...options, _retry: true });
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
if (!response.ok) throw data;
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('API Error:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
if (!response.ok) {
|
||||
throw new Error(data.message || 'حدث خطأ ما');
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
async refreshToken() {
|
||||
async login(email, password) {
|
||||
const data = await this.request('/auth/login', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ email, password })
|
||||
});
|
||||
localStorage.setItem('access_token', data.data.access_token);
|
||||
return data;
|
||||
},
|
||||
|
||||
async refresh() {
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}/auth/refresh`, { method: 'POST' });
|
||||
if (response.ok) {
|
||||
const result = await response.json();
|
||||
this.accessToken = result.data.access_token;
|
||||
localStorage.setItem('access_token', this.accessToken);
|
||||
const data = await fetch(`${this.baseUrl}/auth/refresh`, { method: 'POST' });
|
||||
if (data.ok) {
|
||||
const result = await data.json();
|
||||
localStorage.setItem('access_token', result.data.access_token);
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
console.error('Refresh failed', e);
|
||||
}
|
||||
localStorage.removeItem('access_token');
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user