переделал токен
This commit is contained in:
@@ -292,19 +292,18 @@
|
||||
|
||||
<script>
|
||||
(() => {
|
||||
const token = localStorage.getItem('token');
|
||||
const groupSelect = document.getElementById('group-select');
|
||||
const grid = document.getElementById('schedule-grid');
|
||||
const statusLine = document.getElementById('status-line');
|
||||
const weekLabel = document.getElementById('week-label');
|
||||
const datePicker = document.getElementById('date-picker');
|
||||
let weekStart = startOfWeek(new Date());
|
||||
let refreshPromise = null;
|
||||
|
||||
document.getElementById('logout-link').addEventListener('click', () => {
|
||||
localStorage.removeItem('token');
|
||||
localStorage.removeItem('role');
|
||||
localStorage.removeItem('departmentId');
|
||||
localStorage.removeItem('userId');
|
||||
document.getElementById('logout-link').addEventListener('click', async (event) => {
|
||||
event.preventDefault();
|
||||
await logout();
|
||||
window.location.href = '/';
|
||||
});
|
||||
|
||||
document.getElementById('theme-toggle-local').addEventListener('click', () => {
|
||||
@@ -444,17 +443,78 @@
|
||||
return Array.from({ length: 7 }, (_, index) => addDays(weekStart, index));
|
||||
}
|
||||
|
||||
async function fetchJson(url) {
|
||||
async function fetchJson(url, retryOnUnauthorized = true) {
|
||||
const token = localStorage.getItem('token');
|
||||
const response = await fetch(url, {
|
||||
headers: token ? { Authorization: `Bearer ${token}` } : {}
|
||||
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
||||
credentials: 'same-origin'
|
||||
});
|
||||
const data = await response.json().catch(() => null);
|
||||
if (response.status === 401 && retryOnUnauthorized) {
|
||||
const refreshed = await refreshAccessToken();
|
||||
if (refreshed) {
|
||||
return fetchJson(url, false);
|
||||
}
|
||||
clearAuthState();
|
||||
window.location.href = '/';
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error(data?.message || `Ошибка HTTP: ${response.status}`);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
async function refreshAccessToken() {
|
||||
if (refreshPromise) {
|
||||
return refreshPromise;
|
||||
}
|
||||
|
||||
refreshPromise = (async () => {
|
||||
const response = await fetch('/api/auth/refresh', {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin'
|
||||
});
|
||||
const data = await response.json().catch(() => null);
|
||||
if (!response.ok || !data?.token) {
|
||||
return false;
|
||||
}
|
||||
storeAuthState(data);
|
||||
return true;
|
||||
})().finally(() => {
|
||||
refreshPromise = null;
|
||||
});
|
||||
|
||||
return refreshPromise;
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
try {
|
||||
await fetch('/api/auth/logout', {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin'
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn('Не удалось завершить серверную сессию:', error.message);
|
||||
} finally {
|
||||
clearAuthState();
|
||||
}
|
||||
}
|
||||
|
||||
function storeAuthState(data) {
|
||||
if (data.token) localStorage.setItem('token', data.token);
|
||||
if (data.role) localStorage.setItem('role', data.role);
|
||||
if (data.departmentId !== undefined && data.departmentId !== null) {
|
||||
localStorage.setItem('departmentId', data.departmentId);
|
||||
}
|
||||
if (data.userId !== undefined && data.userId !== null) {
|
||||
localStorage.setItem('userId', data.userId);
|
||||
}
|
||||
}
|
||||
|
||||
function clearAuthState() {
|
||||
['token', 'role', 'departmentId', 'userId'].forEach(key => localStorage.removeItem(key));
|
||||
}
|
||||
|
||||
function showStatus(message, isError) {
|
||||
statusLine.textContent = message;
|
||||
statusLine.classList.toggle('error', isError);
|
||||
|
||||
Reference in New Issue
Block a user