Fix some issues
This commit is contained in:
+25
-6
@@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}"/>
|
||||
<title>{% block title %}IT Helpdesk{% endblock %} — TechDesk</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"/>
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
|
||||
@@ -438,6 +439,27 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
|
||||
<script>
|
||||
// ── CSRF helper ───────────────────────────────────────────────────────────────
|
||||
// All state-changing fetch() calls must include the CSRF token header.
|
||||
// Use csrfPost(url, body) instead of raw fetch(..., {method:'POST'}) to ensure
|
||||
// the token from the <meta> tag is sent automatically.
|
||||
const _csrfToken = () => document.querySelector('meta[name="csrf-token"]')?.content || '';
|
||||
async function csrfPost(url, body = null) {
|
||||
const opts = {
|
||||
method : 'POST',
|
||||
headers: { 'X-CSRFToken': _csrfToken() },
|
||||
};
|
||||
if (body !== null) {
|
||||
if (typeof body === 'object' && !(body instanceof FormData)) {
|
||||
opts.headers['Content-Type'] = 'application/json';
|
||||
opts.body = JSON.stringify(body);
|
||||
} else {
|
||||
opts.body = body;
|
||||
}
|
||||
}
|
||||
return fetch(url, opts);
|
||||
}
|
||||
|
||||
// ── WebSocket ────────────────────────────────────────────────────────────────
|
||||
{% if current_user.is_authenticated %}
|
||||
const socket = io({
|
||||
@@ -506,7 +528,7 @@ function _bindNotifClick(el) {
|
||||
const link = el.dataset.link;
|
||||
// Mark as read in DB
|
||||
if(el.classList.contains('unread')){
|
||||
try { await fetch(`/api/notifications/${id}/read`, { method: 'POST' }); } catch(_){}
|
||||
try { await csrfPost(`/api/notifications/${id}/read`); } catch(_){}
|
||||
el.classList.remove('unread');
|
||||
const dot = el.querySelector('.notif-dot');
|
||||
if(dot) dot.remove();
|
||||
@@ -567,7 +589,7 @@ function prependNotif(n){
|
||||
}
|
||||
|
||||
async function markAllRead(){
|
||||
try { await fetch('/api/notifications/mark-all-read', { method: 'POST' }); } catch(_){}
|
||||
try { await csrfPost('/api/notifications/mark-all-read'); } catch(_){}
|
||||
updateBadge(0);
|
||||
document.querySelectorAll('.notif-item.unread').forEach(el => {
|
||||
el.classList.remove('unread');
|
||||
@@ -601,10 +623,7 @@ async function sendChat(){
|
||||
chatHistory.push({role:'user',content:msg});
|
||||
const typing = appendTyping();
|
||||
try{
|
||||
const r = await fetch('/chatbot/message',{
|
||||
method:'POST',headers:{'Content-Type':'application/json'},
|
||||
body:JSON.stringify({message:msg,history:chatHistory})
|
||||
});
|
||||
const r = await csrfPost('/chatbot/message', {message:msg,history:chatHistory});
|
||||
const d = await r.json();
|
||||
typing.remove();
|
||||
const reply = d.reply || 'Sorry, I encountered an error.';
|
||||
|
||||
Reference in New Issue
Block a user