47 lines
2.2 KiB
HTML
47 lines
2.2 KiB
HTML
{{define "csrf_script"}}
|
|
<script>
|
|
// Auto-applies CSRF protection to every plain <form method=post> and every
|
|
// same-origin mutating fetch() call on this page — no per-form or per-fetch-call
|
|
// changes needed anywhere else in this codebase. See internal/webui/csrf.go for
|
|
// the server-side check this token has to satisfy.
|
|
window.__csrfToken = {{.csrf_token}};
|
|
(function() {
|
|
var token = window.__csrfToken;
|
|
if (!token) return; // no session cookie yet (e.g. the login page itself)
|
|
|
|
// Exposed so content injected later (e.g. an AJAX-swapped settings section,
|
|
// see webmail_settings_chrome.html) can get the same treatment — forms
|
|
// added after DOMContentLoaded already fired would otherwise submit with no
|
|
// token and get rejected by the server-side check.
|
|
window.__applyCsrfToForms = function(root) {
|
|
(root || document).querySelectorAll('form').forEach(function(form) {
|
|
if ((form.getAttribute('method') || '').toLowerCase() !== 'post') return;
|
|
if (form.querySelector('input[name="csrf_token"]')) return;
|
|
var input = document.createElement('input');
|
|
input.type = 'hidden';
|
|
input.name = 'csrf_token';
|
|
input.value = token;
|
|
form.appendChild(input);
|
|
});
|
|
};
|
|
document.addEventListener('DOMContentLoaded', function() { window.__applyCsrfToForms(document); });
|
|
|
|
var mutating = { POST: true, PUT: true, PATCH: true, DELETE: true };
|
|
var originalFetch = window.fetch.bind(window);
|
|
window.fetch = function(url, options) {
|
|
options = options || {};
|
|
var method = (options.method || 'GET').toUpperCase();
|
|
var isAbsolute = /^https?:\/\//i.test(url);
|
|
var isSameOrigin = !isAbsolute || url.indexOf(window.location.origin) === 0;
|
|
if (mutating[method] && isSameOrigin) {
|
|
options = Object.assign({}, options);
|
|
var headers = new Headers(options.headers || {});
|
|
headers.set('X-CSRF-Token', token);
|
|
options.headers = headers;
|
|
}
|
|
return originalFetch(url, options);
|
|
};
|
|
})();
|
|
</script>
|
|
{{end}}
|