scratch-www/src/lib/api.js
Ray Schamp 26e1ee553b Add method to api for submitting forms
Some of our legacy endpoints expect this style rather than json.

Also clean up the way useCsrf works — don't always set json attribute to an empty object.
2016-06-16 17:24:31 -04:00

83 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var defaults = require('lodash.defaults');
var xhr = require('xhr');
var jar = require('./jar');
var log = require('./log');
var urlParams = require('./url-params');
/**
* Helper method that constructs requests to the scratch api.
* Custom arguments:
* - useCsrf [boolean] handles unique csrf token retrieval for POST requests. This prevents
* CSRF forgeries (see: https://www.squarefree.com/securitytips/web-developers.html#CSRF)
*
* It also takes in other arguments specified in the xhr library spec.
*/
module.exports = function (opts, callback) {
defaults(opts, {
host: process.env.API_HOST,
headers: {},
responseType: 'json',
useCsrf: false
});
defaults(opts.headers, {
'X-Requested-With': 'XMLHttpRequest'
});
opts.uri = opts.host + opts.uri;
if (opts.params) {
opts.uri = [opts.uri, urlParams(opts.params)]
.join(opts.uri.indexOf('?') === -1 ? '?' : '&');
}
if (opts.formData) {
opts.body = urlParams(opts.formData);
opts.headers['Content-Type'] = 'application/x-www-form-urlencoded';
}
var apiRequest = function (opts) {
if (opts.host !== '') {
// For IE < 10, we must use XDR for cross-domain requests. XDR does not support
// custom headers.
defaults(opts, {useXDR: true});
delete opts.headers;
if (opts.authentication) {
var authenticationParams = ['x-token=' + opts.authentication];
var parts = opts.uri.split('?');
var qs = (parts[1] || '').split('&').concat(authenticationParams).join('&');
opts.uri = parts[0] + '?' + qs;
}
}
xhr(opts, function (err, res, body) {
if (err) log.error(err);
// Legacy API responses come as lists, and indicate to redirect the client like
// [{success: true, redirect: "/location/to/redirect"}]
try {
if ('redirect' in body[0]) window.location = body[0].redirect;
} catch (err) {
// do nothing
}
callback(err, body, res);
});
}.bind(this);
if (typeof jar.get('scratchlanguage') !== 'undefined') {
opts.headers['Accept-Language'] = jar.get('scratchlanguage') + ', en;q=0.8';
}
if (opts.authentication) {
opts.headers['X-Token'] = opts.authentication;
}
if (opts.useCsrf) {
jar.use('scratchcsrftoken', '/csrf_token/', function (err, csrftoken) {
if (err) return log.error('Error while retrieving CSRF token', err);
opts.headers['X-CSRFToken'] = csrftoken;
apiRequest(opts);
}.bind(this));
} else {
apiRequest(opts);
}
};