Skip to content
Snippets Groups Projects
Commit cca06da2 authored by Bryce Johnson's avatar Bryce Johnson Committed by Phil Hughes
Browse files

Standardize access to CSRF token in JavaScript

parent 6c0473ef
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -3,6 +3,7 @@
 
import '../lib/utils/url_utility';
import { HIDDEN_CLASS } from '../lib/utils/constants';
import csrf from '../lib/utils/csrf';
 
function toggleLoading($el, $icon, loading) {
if (loading) {
Loading
Loading
@@ -36,9 +37,7 @@ export default class BlobFileDropzone {
maxFiles: 1,
addRemoveLinks: true,
previewsContainer: '.dropzone-previews',
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content'),
},
headers: csrf.headers,
init: function () {
this.on('addedfile', function () {
toggleLoading(submitButton, submitButtonLoadingIcon, false);
Loading
Loading
Loading
Loading
@@ -2,6 +2,7 @@
/* global Dropzone */
import _ from 'underscore';
import './preview_markdown';
import csrf from './lib/utils/csrf';
 
window.DropzoneInput = (function() {
function DropzoneInput(form) {
Loading
Loading
@@ -50,9 +51,7 @@ window.DropzoneInput = (function() {
paramName: 'file',
maxFilesize: maxFileSize,
uploadMultiple: false,
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
headers: csrf.headers,
previewContainer: false,
processing: function() {
return $('.div-dropzone-alert').alert('close');
Loading
Loading
@@ -260,9 +259,7 @@ window.DropzoneInput = (function() {
dataType: 'json',
processData: false,
contentType: false,
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
headers: csrf.headers,
beforeSend: function() {
showSpinner();
return closeAlertMessage();
Loading
Loading
/*
This module provides easy access to the CSRF token and caches
it for re-use. It also exposes some values commonly used in relation
to the CSRF token (header key and headers object).
If you need to refresh the csrfToken for some reason, just call `init` and
then use the accessors as you would normally.
If you need to compose a headers object, use the spread operator:
```
headers: {
...csrf.headers,
someOtherHeader: '12345',
}
```
*/
const csrf = {
init() {
const tokenEl = document.querySelector('meta[name=csrf-token]');
if (tokenEl !== null) {
this.csrfToken = tokenEl.getAttribute('content');
} else {
this.csrfToken = null;
}
},
get token() {
return this.csrfToken;
},
get headerKey() {
return 'X-CSRF-Token';
},
get headers() {
if (this.csrfToken !== null) {
return {
[this.headerKey]: this.token,
};
}
return {};
},
};
csrf.init();
// use our cached token for any $.rails-generated AJAX requests
if ($.rails) {
$.rails.csrfToken = () => csrf.token;
}
export default csrf;
import Vue from 'vue';
import VueResource from 'vue-resource';
import csrf from '../lib/utils/csrf';
 
Vue.use(VueResource);
 
Loading
Loading
@@ -18,9 +19,7 @@ Vue.http.interceptors.push((request, next) => {
// New Vue Resource version uses Headers, we are expecting a plain object to render pagination
// and polling.
Vue.http.interceptors.push((request, next) => {
if ($.rails) {
request.headers.set('X-CSRF-Token', $.rails.csrfToken());
}
request.headers.set(csrf.headerKey, csrf.token);
 
next((response) => {
// Headers object has a `forEach` property that iterates through all values.
Loading
Loading
import csrf from '~/lib/utils/csrf';
describe('csrf', () => {
beforeEach(() => {
this.tokenKey = 'X-CSRF-Token';
this.token = 'pH1cvjnP9grx2oKlhWEDvUZnJ8x2eXsIs1qzyHkF3DugSG5yTxR76CWeEZRhML2D1IeVB7NEW0t5l/axE4iJpQ==';
});
it('returns the correct headerKey', () => {
expect(csrf.headerKey).toBe(this.tokenKey);
});
describe('when csrf token is in the DOM', () => {
beforeEach(() => {
setFixtures(`
<meta name="csrf-token" content="${this.token}">
`);
csrf.init();
});
it('returns the csrf token', () => {
expect(csrf.token).toBe(this.token);
});
it('returns the csrf headers object', () => {
expect(csrf.headers[this.tokenKey]).toBe(this.token);
});
});
describe('when csrf token is not in the DOM', () => {
beforeEach(() => {
setFixtures(`
<meta name="some-other-token">
`);
csrf.init();
});
it('returns null for token', () => {
expect(csrf.token).toBeNull();
});
it('returns empty object for headers', () => {
expect(typeof csrf.headers).toBe('object');
expect(Object.keys(csrf.headers).length).toBe(0);
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment