The current csrftoken parser breaks on multiple crsftokens

For example: 

`Cookie: csrftoken=asdfasd; sessionid=asdfasdf; csrftoken=qwertyqwerty`

This can happen when multiple sessions, or multiple csrftokens for different paths.
This commit is contained in:
James 2019-09-23 20:17:32 -05:00 committed by GitHub
parent 5068ea05c3
commit 6c8d4a386b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,26 +1,33 @@
(function() {
// Parse the cookie value for a CSRF token
var csrftoken;
var cookies = ('; ' + document.cookie).split('; csrftoken=');
if (cookies.length == 2)
csrftoken = cookies.pop().split(';').shift();
var cookies = document.cookie.split(';').reduce((p, c) => {
let x = {};
let key = c.split('=')[0].trim();
x[key] = p[key] ? p[key].concat([c.split('=')[1]]) : [c.split('=')[1]];
return Object.assign(p, x);
}, {});
// Collect the URL parameters
var parameters = {};
window.location.hash.substr(1).split('&').forEach(function (entry) {
var eq = entry.indexOf('=');
if (eq >= 0) {
parameters[decodeURIComponent(entry.slice(0, eq))] =
decodeURIComponent(entry.slice(eq + 1));
}
});
window.location.hash
.substr(1)
.split('&')
.forEach(function(entry) {
var eq = entry.indexOf('=');
if (eq >= 0) {
parameters[decodeURIComponent(entry.slice(0, eq))] = decodeURIComponent(entry.slice(eq + 1));
}
});
// Produce a Location fragment string from a parameter object.
function locationQuery(params) {
return '#' + Object.keys(params).map(function (key) {
return encodeURIComponent(key) + '=' +
encodeURIComponent(params[key]);
}).join('&');
return (
'#' +
Object.keys(params)
.map(function(key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
})
.join('&')
);
}
// Derive a fetch URL from the current URL, sans the GraphQL parameters.
var graphqlParamNames = {
@ -40,26 +47,43 @@
// Defines a GraphQL fetcher using the fetch API.
function graphQLFetcher(graphQLParams) {
var headers = {
'Accept': 'application/json',
Accept: 'application/json',
'Content-Type': 'application/json'
};
if (csrftoken) {
headers['X-CSRFToken'] = csrftoken;
var cookies = document.cookie.split(';').reduce((p, c) => {
let x = {};
let key = c.split('=')[0].trim();
x[key] = p[key] ? p[key].concat([c.split('=')[1]]) : [c.split('=')[1]];
return Object.assign(p, x);
}, {});
if (cookies.csrftoken && cookies.csrftoken.length) {
headers['X-CSRFToken'] = cookies.csrftoken.pop();
}
return fetch(fetchURL, {
method: 'post',
headers: headers,
body: JSON.stringify(graphQLParams),
credentials: 'include',
}).then(function (response) {
return response.text();
}).then(function (responseBody) {
try {
return JSON.parse(responseBody);
} catch (error) {
return responseBody;
}
});
function getFetch(headers) {
return fetch(fetchURL, {
method: 'post',
headers: headers,
body: JSON.stringify(graphQLParams),
credentials: 'include'
});
}
return getFetch(headers)
.then(function(response) {
console.log(headers);
return response.text();
})
.then(function(responseBody) {
try {
return JSON.parse(responseBody);
} catch (error) {
if (cookies.csrftoken.length) {
headers['X-CSRFToken'] = cookies.csrftoken.pop();
return getFetch(headers);
}
return responseBody;
}
});
}
// When the query and variables string is edited, update the URL bar so
// that it can be easily shared.
@ -80,11 +104,11 @@
}
var options = {
fetcher: graphQLFetcher,
onEditQuery: onEditQuery,
onEditVariables: onEditVariables,
onEditOperationName: onEditOperationName,
query: parameters.query,
}
onEditQuery: onEditQuery,
onEditVariables: onEditVariables,
onEditOperationName: onEditOperationName,
query: parameters.query
};
if (parameters.variables) {
options.variables = parameters.variables;
}
@ -92,8 +116,5 @@
options.operationName = parameters.operation_name;
}
// Render <GraphiQL /> into the body.
ReactDOM.render(
React.createElement(GraphiQL, options),
document.body
);
ReactDOM.render(React.createElement(GraphiQL, options), document.body);
})();