mirror of
https://github.com/graphql-python/graphene-django.git
synced 2024-11-26 11:33:44 +03:00
2b08e59bea
The only security risk here is persuading a user to execute a mutation, which is probably not a big risk. To mitigate this risk and still keep the same UX (that is so valuable), would require more work than is proportionate for this PR.
100 lines
2.8 KiB
JavaScript
100 lines
2.8 KiB
JavaScript
(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();
|
|
|
|
// 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));
|
|
}
|
|
});
|
|
// 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('&');
|
|
}
|
|
// Derive a fetch URL from the current URL, sans the GraphQL parameters.
|
|
var graphqlParamNames = {
|
|
query: true,
|
|
variables: true,
|
|
operationName: true
|
|
};
|
|
var otherParams = {};
|
|
for (var k in parameters) {
|
|
if (parameters.hasOwnProperty(k) && graphqlParamNames[k] !== true) {
|
|
otherParams[k] = parameters[k];
|
|
}
|
|
}
|
|
|
|
var fetchURL = locationQuery(otherParams);
|
|
|
|
// Defines a GraphQL fetcher using the fetch API.
|
|
function graphQLFetcher(graphQLParams) {
|
|
var headers = {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json'
|
|
};
|
|
if (csrftoken) {
|
|
headers['X-CSRFToken'] = csrftoken;
|
|
}
|
|
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;
|
|
}
|
|
});
|
|
}
|
|
// When the query and variables string is edited, update the URL bar so
|
|
// that it can be easily shared.
|
|
function onEditQuery(newQuery) {
|
|
parameters.query = newQuery;
|
|
updateURL();
|
|
}
|
|
function onEditVariables(newVariables) {
|
|
parameters.variables = newVariables;
|
|
updateURL();
|
|
}
|
|
function onEditOperationName(newOperationName) {
|
|
parameters.operationName = newOperationName;
|
|
updateURL();
|
|
}
|
|
function updateURL() {
|
|
history.replaceState(null, null, locationQuery(parameters));
|
|
}
|
|
var options = {
|
|
fetcher: graphQLFetcher,
|
|
onEditQuery: onEditQuery,
|
|
onEditVariables: onEditVariables,
|
|
onEditOperationName: onEditOperationName,
|
|
query: parameters.query,
|
|
}
|
|
if (parameters.variables) {
|
|
options.variables = parameters.variables;
|
|
}
|
|
if (parameters.operation_name) {
|
|
options.operationName = parameters.operation_name;
|
|
}
|
|
// Render <GraphiQL /> into the body.
|
|
ReactDOM.render(
|
|
React.createElement(GraphiQL, options),
|
|
document.body
|
|
);
|
|
})();
|