Skip to content

Cleaned csrf_protection_controller for very basic eslint rules #1380

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,79 +1,88 @@
const nameCheck = /^[-_a-zA-Z0-9]{4,22}$/;
const tokenCheck = /^[-_\/+a-zA-Z0-9]{24,}$/;

// Generate and double-submit a CSRF token in a form field and a cookie, as defined by Symfony's SameOriginCsrfTokenManager
document.addEventListener('submit', function (event) {
generateCsrfToken(event.target);
}, true);

// When @hotwired/turbo handles form submissions, send the CSRF token in a header in addition to a cookie
// The `framework.csrf_protection.check_header` config option needs to be enabled for the header to be checked
document.addEventListener('turbo:submit-start', function (event) {
const h = generateCsrfHeaders(event.detail.formSubmission.formElement);
Object.keys(h).map(function (k) {
event.detail.formSubmission.fetchRequest.headers[k] = h[k];
});
});

// When @hotwired/turbo handles form submissions, remove the CSRF cookie once a form has been submitted
document.addEventListener('turbo:submit-end', function (event) {
removeCsrfToken(event.detail.formSubmission.formElement);
});
const tokenCheck = /^[-_/+a-zA-Z0-9]{24,}$/;

export function generateCsrfToken(formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');

if (!csrfField) {
return;
}

let csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');
let csrfToken = csrfField.value;

if (!csrfCookie && nameCheck.test(csrfToken)) {
csrfField.setAttribute('data-csrf-protection-cookie-value', (csrfCookie = csrfToken));
csrfToken = btoa(
String.fromCharCode.apply(null, (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(18))),
);
csrfField.defaultValue = csrfToken;
csrfField.dispatchEvent(new Event('change', { bubbles: true }));
}

if (csrfCookie && tokenCheck.test(csrfToken)) {
const cookie = `${csrfCookie}_${csrfToken}=${csrfCookie}; path=/; samesite=strict`;
document.cookie = window.location.protocol === 'https:' ? `__Host-${cookie}; secure` : cookie;
}
}

export function generateCsrfToken (formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
export function generateCsrfHeaders(formElement) {
const headers = {};
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');

if (!csrfField) {
return;
}
if (!csrfField) {
return headers;
}

let csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');
let csrfToken = csrfField.value;
const csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');

if (!csrfCookie && nameCheck.test(csrfToken)) {
csrfField.setAttribute('data-csrf-protection-cookie-value', csrfCookie = csrfToken);
csrfField.defaultValue = csrfToken = btoa(String.fromCharCode.apply(null, (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(18))));
csrfField.dispatchEvent(new Event('change', { bubbles: true }));
}
if (tokenCheck.test(csrfField.value) && nameCheck.test(csrfCookie)) {
headers[csrfCookie] = csrfField.value;
}

if (csrfCookie && tokenCheck.test(csrfToken)) {
const cookie = csrfCookie + '_' + csrfToken + '=' + csrfCookie + '; path=/; samesite=strict';
document.cookie = window.location.protocol === 'https:' ? '__Host-' + cookie + '; secure' : cookie;
}
return headers;
}

export function generateCsrfHeaders (formElement) {
const headers = {};
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
export function removeCsrfToken(formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');

if (!csrfField) {
return headers;
}
if (!csrfField) {
return;
}

const csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');
const csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');

if (tokenCheck.test(csrfField.value) && nameCheck.test(csrfCookie)) {
headers[csrfCookie] = csrfField.value;
}
if (tokenCheck.test(csrfField.value) && nameCheck.test(csrfCookie)) {
const cookie = `${csrfCookie}_${csrfField.value}=0; path=/; samesite=strict; max-age=0`;

return headers;
document.cookie = window.location.protocol === 'https:' ? `__Host-${cookie}; secure` : cookie;
}
}

export function removeCsrfToken (formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');

if (!csrfField) {
return;
}

const csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');
// Generate and double-submit a CSRF token in a form field and a cookie, as defined by Symfony's SameOriginCsrfTokenManager
document.addEventListener(
'submit',
(event) => {
generateCsrfToken(event.target);
},
true,
);

if (tokenCheck.test(csrfField.value) && nameCheck.test(csrfCookie)) {
const cookie = csrfCookie + '_' + csrfField.value + '=0; path=/; samesite=strict; max-age=0';
// When @hotwired/turbo handles form submissions, send the CSRF token in a header in addition to a cookie
// The `framework.csrf_protection.check_header` config option needs to be enabled for the header to be checked
document.addEventListener('turbo:submit-start', (event) => {
const h = generateCsrfHeaders(event.detail.formSubmission.formElement);
// eslint-disable-next-line array-callback-return
Object.keys(h).map((k) => {
// eslint-disable-next-line no-param-reassign
event.detail.formSubmission.fetchRequest.headers[k] = h[k];
});
});

document.cookie = window.location.protocol === 'https:' ? '__Host-' + cookie + '; secure' : cookie;
}
}
// When @hotwired/turbo handles form submissions, remove the CSRF cookie once a form has been submitted
document.addEventListener('turbo:submit-end', (event) => {
removeCsrfToken(event.detail.formSubmission.formElement);
});

/* stimulusFetch: 'lazy' */
export default 'csrf-protection-controller';
Loading