fix batch

This commit is contained in:
root
2026-06-04 23:09:58 -04:00
parent 6444b61416
commit a18e8b92a6
+92 -85
View File
@@ -373,8 +373,94 @@
let tempBatchCounter = -1; let tempBatchCounter = -1;
let csrfValue = cfg.csrfHash || ''; let csrfValue = cfg.csrfHash || '';
const csrfCookieName = <?= json_encode(config('Security')->csrfCookieName ?? (config('Security')->cookieName ?? 'csrf_cookie_name')) ?>;
let csrfRequestQueue = Promise.resolve();
let dragPayload = null; let dragPayload = null;
function getCookie(name) {
const parts = document.cookie.split(';');
for (let i = 0; i < parts.length; i += 1) {
const part = parts[i].trim();
if (part.startsWith(`${name}=`)) {
return decodeURIComponent(part.slice(name.length + 1));
}
}
return '';
}
function syncCsrfFromCookie() {
if (!csrfCookieName) {
return csrfValue;
}
const cookieValue = getCookie(csrfCookieName);
if (cookieValue) {
csrfValue = cookieValue;
}
return csrfValue;
}
function updateCsrfToken(response, data = null) {
const headerValue = response?.headers?.get?.('X-CSRF-HASH') || '';
if (headerValue) {
csrfValue = headerValue;
return;
}
const bodyValue = data && typeof data === 'object' ? (data.csrf_hash || data.csrfHash || '') : '';
if (bodyValue) {
csrfValue = bodyValue;
return;
}
syncCsrfFromCookie();
}
function withSerializedCsrfRequest(task) {
const run = csrfRequestQueue
.catch(() => undefined)
.then(() => task());
csrfRequestQueue = run.then(() => undefined, () => undefined);
return run;
}
async function postJson(url, form, fallbackError) {
return withSerializedCsrfRequest(async () => {
syncCsrfFromCookie();
if (cfg.csrfToken) {
form.set(cfg.csrfToken, csrfValue);
}
const headers = { 'X-Requested-With': 'XMLHttpRequest' };
if (csrfValue) {
headers['X-CSRF-TOKEN'] = csrfValue;
}
const response = await fetch(url, {
method: 'POST',
headers,
credentials: 'same-origin',
body: form,
});
const text = await response.text();
let data = null;
try {
data = text ? JSON.parse(text) : {};
} catch (_) {
data = {
success: false,
error: text || fallbackError || 'Unexpected response',
};
}
updateCsrfToken(response, data);
if (!response.ok || !data.success) {
throw new Error(data.error || fallbackError || 'Request failed.');
}
return data;
});
}
function openReceiptModal(url) { function openReceiptModal(url) {
if (!url) { if (!url) {
return; return;
@@ -470,23 +556,8 @@
} }
const form = new FormData(); const form = new FormData();
form.append('expense_id', itemId); form.append('expense_id', itemId);
if (cfg.csrfToken) {
form.append(cfg.csrfToken, csrfValue);
}
try { try {
const response = await fetch(cfg.markDonationUrl, { await postJson(cfg.markDonationUrl, form, 'Unable to mark donation right now.');
method: 'POST',
headers: { 'X-Requested-With': 'XMLHttpRequest' },
body: form,
});
const data = await response.json().catch(() => ({ success: false, error: 'Unexpected response' }));
const newHash = response.headers.get('X-CSRF-HASH') || data.csrf_hash;
if (newHash) {
csrfValue = newHash;
}
if (!response.ok || !data.success) {
throw new Error(data.error || 'Unable to mark donation right now.');
}
removeItemFromUI(itemId); removeItemFromUI(itemId);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
@@ -737,23 +808,7 @@
} else { } else {
form.append('admin_id', ''); form.append('admin_id', '');
} }
if (cfg.csrfToken) { postJson(cfg.updateUrl, form, 'Unable to update batch assignment.').then((data) => {
form.append(cfg.csrfToken, csrfValue);
}
fetch(cfg.updateUrl, {
method: 'POST',
headers: { 'X-Requested-With': 'XMLHttpRequest' },
body: form,
}).then(async (response) => {
const data = await response.json().catch(() => ({ success: false, error: 'Unexpected response' }));
const newHash = response.headers.get('X-CSRF-HASH') || data.csrf_hash;
if (newHash) {
csrfValue = newHash;
}
if (!response.ok || !data.success) {
throw new Error(data.error || 'Unable to update batch assignment.');
}
entry.batch_number = batchId; entry.batch_number = batchId;
entry.batchId = batchId; entry.batchId = batchId;
entry.admin_id = (adminId || adminId === 0) ? adminId : null; entry.admin_id = (adminId || adminId === 0) ? adminId : null;
@@ -791,25 +846,7 @@
throw new Error('Batch creation endpoint is not configured.'); throw new Error('Batch creation endpoint is not configured.');
} }
const form = new FormData(); const form = new FormData();
if (cfg.csrfToken) { return postJson(cfg.createBatchUrl, form, 'Unable to create a new batch right now.');
form.append(cfg.csrfToken, csrfValue);
}
const response = await fetch(cfg.createBatchUrl, {
method: 'POST',
headers: { 'X-Requested-With': 'XMLHttpRequest' },
body: form,
});
const data = await response.json().catch(() => ({ success: false, error: 'Unexpected response when creating batch.' }));
const newHash = response.headers.get('X-CSRF-HASH') || data.csrf_hash;
if (newHash) {
csrfValue = newHash;
}
if (!response.ok || !data.success) {
throw new Error(data.error || 'Unable to create a new batch right now.');
}
return data;
} }
async function uploadAdminCheckFile(batchId, adminId, input, statusEl, linkEl) { async function uploadAdminCheckFile(batchId, adminId, input, statusEl, linkEl) {
@@ -827,28 +864,13 @@
form.append('batch_id', batchId); form.append('batch_id', batchId);
form.append('admin_id', adminId ?? 0); form.append('admin_id', adminId ?? 0);
form.append('check_file', file); form.append('check_file', file);
if (cfg.csrfToken) {
form.append(cfg.csrfToken, csrfValue);
}
input.disabled = true; input.disabled = true;
const previous = statusEl.textContent; const previous = statusEl.textContent;
statusEl.textContent = 'Uploading...'; statusEl.textContent = 'Uploading...';
try { try {
const response = await fetch(cfg.checkUploadUrl, { const data = await postJson(cfg.checkUploadUrl, form, 'Unable to upload check file right now.');
method: 'POST',
headers: { 'X-Requested-With': 'XMLHttpRequest' },
body: form,
});
const data = await response.json().catch(() => ({ success: false, error: 'Unexpected response' }));
const newHash = response.headers.get('X-CSRF-HASH') || data.csrf_hash;
if (newHash) {
csrfValue = newHash;
}
if (!response.ok || !data.success) {
throw new Error(data.error || 'Unable to upload check file right now.');
}
const label = data.original_filename || 'View check'; const label = data.original_filename || 'View check';
statusEl.textContent = `Uploaded: ${data.original_filename || 'file'}`; statusEl.textContent = `Uploaded: ${data.original_filename || 'file'}`;
if (linkEl && data.url) { if (linkEl && data.url) {
@@ -979,34 +1001,19 @@
} }
const form = new FormData(); const form = new FormData();
form.append('batch_id', batchId); form.append('batch_id', batchId);
if (cfg.csrfToken) {
form.append(cfg.csrfToken, csrfValue);
}
if (button) { if (button) {
button.disabled = true; button.disabled = true;
button.textContent = 'Locking...'; button.textContent = 'Locking...';
} }
try { try {
const response = await fetch(cfg.lockBatchUrl, { await postJson(cfg.lockBatchUrl, form, 'Unable to lock batch at the moment.');
method: 'POST',
headers: { 'X-Requested-With': 'XMLHttpRequest' },
body: form,
});
const data = await response.json().catch(() => ({ success: false, error: 'Unexpected response' }));
const newHash = response.headers.get('X-CSRF-HASH') || data.csrf_hash;
if (newHash) {
csrfValue = newHash;
}
if (!response.ok || !data.success) {
throw new Error(data.error || 'Unable to lock batch at the moment.');
}
markBatchCardLocked(card); markBatchCardLocked(card);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
alert(err.message || 'Unable to lock the batch. Please try again.'); alert(err.message || 'Unable to lock the batch. Please try again.');
if (button) { if (button) {
button.disabled = false; button.disabled = false;
button.textContent = 'Lock Batch'; button.textContent = 'Submit Batch';
} }
} }
} }