Statistics page redesign #60
@@ -165,7 +165,7 @@ window.onload = async function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchPlayerUi() {
|
async function fetchPlayerUi() {
|
||||||
const res = await fetch('/api/settings/player-admin-status-ui', { method: 'GET' });
|
const res = await fetch('/api/settings/player-admin-status-ui', { method: 'GET', cache: 'no-store' });
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
const msg = data.message || data.error || `Erreur (${res.status})`;
|
const msg = data.message || data.error || `Erreur (${res.status})`;
|
||||||
@@ -254,7 +254,7 @@ window.onload = async function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchAppVersionState() {
|
async function fetchAppVersionState() {
|
||||||
const res = await fetch('/api/settings/app-version', { method: 'GET' });
|
const res = await fetch('/api/settings/app-version', { method: 'GET', cache: 'no-store' });
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
const msg = data.message || data.error || `Erreur (${res.status})`;
|
const msg = data.message || data.error || `Erreur (${res.status})`;
|
||||||
@@ -338,7 +338,7 @@ window.onload = async function () {
|
|||||||
async function refreshAppVersionPreview() {
|
async function refreshAppVersionPreview() {
|
||||||
if (!appVersionPreviewEl) return;
|
if (!appVersionPreviewEl) return;
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/version', { method: 'GET' });
|
const res = await fetch('/api/version', { method: 'GET', cache: 'no-store' });
|
||||||
if (!res.ok) throw new Error(`Erreur (${res.status})`);
|
if (!res.ok) throw new Error(`Erreur (${res.status})`);
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
const line = `${data?.date || ''} - ${data?.version || ''} - ${data?.message || ''}`.trim();
|
const line = `${data?.date || ''} - ${data?.version || ''} - ${data?.message || ''}`.trim();
|
||||||
@@ -462,7 +462,7 @@ window.onload = async function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchCompletionModal() {
|
async function fetchCompletionModal() {
|
||||||
const res = await fetch('/api/settings/completion-modal', { method: 'GET' });
|
const res = await fetch('/api/settings/completion-modal', { method: 'GET', cache: 'no-store' });
|
||||||
if (!res.ok) throw new Error(`Erreur (${res.status})`);
|
if (!res.ok) throw new Error(`Erreur (${res.status})`);
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
return normalizeCompletionModal(data);
|
return normalizeCompletionModal(data);
|
||||||
@@ -806,7 +806,7 @@ window.onload = async function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchOscarDates() {
|
async function fetchOscarDates() {
|
||||||
const res = await fetch('/api/settings/oscar-dates', { method: 'GET' });
|
const res = await fetch('/api/settings/oscar-dates', { method: 'GET', cache: 'no-store' });
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
const msg = data.message || data.error || `Erreur (${res.status})`;
|
const msg = data.message || data.error || `Erreur (${res.status})`;
|
||||||
@@ -877,7 +877,7 @@ window.onload = async function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchWinners() {
|
async function fetchWinners() {
|
||||||
const res = await fetch('/api/settings/winners', { method: 'GET' });
|
const res = await fetch('/api/settings/winners', { method: 'GET', cache: 'no-store' });
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
const msg = data.message || data.error || `Erreur (${res.status})`;
|
const msg = data.message || data.error || `Erreur (${res.status})`;
|
||||||
@@ -1130,7 +1130,7 @@ window.onload = async function () {
|
|||||||
|
|
||||||
async function fetchActiveYear() {
|
async function fetchActiveYear() {
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/settings/year', { method: 'GET' });
|
const res = await fetch('/api/settings/year', { method: 'GET', cache: 'no-store' });
|
||||||
if (!res.ok) throw new Error('Failed to fetch active year');
|
if (!res.ok) throw new Error('Failed to fetch active year');
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
const year = Number(data?.year);
|
const year = Number(data?.year);
|
||||||
@@ -1537,6 +1537,7 @@ window.onload = async function () {
|
|||||||
const res = await fetch('/api/admin/db/backups', {
|
const res = await fetch('/api/admin/db/backups', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: { 'Authorization': `Bearer ${token}` },
|
headers: { 'Authorization': `Bearer ${token}` },
|
||||||
|
cache: 'no-store',
|
||||||
});
|
});
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
|||||||
@@ -152,6 +152,9 @@ async function listBackupFiles() {
|
|||||||
router.get("/db/backups", async (req, res) => {
|
router.get("/db/backups", async (req, res) => {
|
||||||
try {
|
try {
|
||||||
requireAdmin(req);
|
requireAdmin(req);
|
||||||
|
// Admin + auth-scoped data: never allow caching.
|
||||||
|
res.setHeader("Cache-Control", "private, no-store, must-revalidate");
|
||||||
|
res.setHeader("Vary", "Authorization");
|
||||||
const backups = await listBackupFiles();
|
const backups = await listBackupFiles();
|
||||||
return res.status(200).json({ backups });
|
return res.status(200).json({ backups });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -227,6 +230,8 @@ router.post("/db/backup", async (req, res) => {
|
|||||||
router.get("/db/backups/:name", async (req, res) => {
|
router.get("/db/backups/:name", async (req, res) => {
|
||||||
try {
|
try {
|
||||||
requireAdmin(req);
|
requireAdmin(req);
|
||||||
|
res.setHeader("Cache-Control", "private, no-store, must-revalidate");
|
||||||
|
res.setHeader("Vary", "Authorization");
|
||||||
const safe = safeBackupFileName(req.params?.name);
|
const safe = safeBackupFileName(req.params?.name);
|
||||||
if (!safe) return res.status(400).json({ message: "Invalid backup name" });
|
if (!safe) return res.status(400).json({ message: "Invalid backup name" });
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user