YUI().add("scriptlibrary.CSRF", function (Y) { Y.scriptlibrary = Y.scriptlibrary || {}; Y.scriptlibrary.CSRF = { token: function() { var input = Y.one('input[name="csrfToken"]'); return input ? input.get("value") : null; } } }); YUI().add("scriptlibrary.Request", function(Y) { "use strict"; /** * Represents a response to an HTTP GET or POST. * Instances have the following properties: * * status {Number} The status code of the result (e.g. 200). * * text {String} The response body. * * contentType {String} The content-type header. * * url {String} The URL of the request. * @param ioResponse {Object} The YUI IO response. * @param url {String} The URL of the request. */ var Response = function(ioResponse, url) { this.url = url; this.status = ioResponse.status; this.text = ioResponse.responseText; this.contentType = ioResponse.getResponseHeader("Content-Type"); this.responseHeader = function(key) { return ioResponse.getResponseHeader(key); }; }; /** * Parses the text property of this response as JSON, and returns the resulting object. * @return {Object} The parsed JSON. */ Response.prototype.parseJson = function() { return JSON.parse(this.text); }; var checkCsrfError = function(e) { if (e.responseHeader("X-CSRF-TOKEN-ERROR") === "ERROR") { document.location.reload(); } throw e; }; /** * Creates a request for the given URL. * @param url {String} The URL of the request. */ var Request = function(url) { var ioPromise = function(ioConfig) { return new Y.Promise(function(resolve, reject) { ioConfig.on = { success: function(transaction, response) { resolve(new Response(response, url)); }, failure: function(transaction, response) { reject(new Response(response, url)); } }; Y.io(url, ioConfig); }); }; /** * POSTs the provided data as application/x-www-form-urlencoded. * @param {String|Object} data The data to send. * @param {Object} [headers] request Headers. * @return {Object} A promise that resolves and rejects to a response for the POST request */ this.postForm = function(data, headers) { var requestHeaders = Y.merge(headers || {}, { "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", "X-CSRF-TOKEN": Y.scriptlibrary.CSRF.token() }); return ioPromise({ method: "POST", headers: requestHeaders, data: data }).then(undefined, checkCsrfError); }; /** * POSTs the provided data as application/json. * @param {String|Object} data The data to send. * @param {Object} [headers] (OPTIONAL) Headers that go with the post. * @return {Object} A promise that resolves and rejects to a response for the POST request. */ this.postJson = function(data, headers) { var requestHeaders = Y.merge(headers || {}, { "Content-Type": "application/json; charset=utf-8", "X-CSRF-TOKEN": Y.scriptlibrary.CSRF.token() }); return ioPromise({ method: "POST", headers: requestHeaders, data: JSON.stringify(data) }).then(undefined, checkCsrfError); }; /** * GETs the data at the configured URL. * @param {Object} [data] The data to append to the URL query string. * @param {Object} [headers] (OPTIONAL) Headers that go with the post. * @return {Object} A promise that resolves and rejects to a response for the GET request. */ this.get = function(data, headers) { return ioPromise({ data: data, headers: headers }); }; /** * DELETEs the data at the configured URL. * @param {Object} data The data to append to the URL query string. * @param {Object} [headers] Headers that go with the post. * @return A promise that resolves and rejects to a response for the DELETE request. */ this.sendDelete = function(data, headers) { var requestHeaders = Y.merge(headers || {}, { "X-CSRF-TOKEN": Y.scriptlibrary.CSRF.token() }); return ioPromise({ method: "DELETE", headers: requestHeaders, data: data }).then(undefined, checkCsrfError); }; }; /** * A static method that handles standard JSON-encoded CMS Result<> types. * If the result is successful, then the success data is returned. * If the result is not successful, then the error data is thrown. */ Request.processCmsResult = function(response) { var result = response.parseJson(); if (result && result.mustLogin) { document.location.reload(); return null; } if (result.gracefulApiError) { throw result.message; } if (!result.success) { throw result.error; } return result.data; }; /** * Static method that parses the text of a response as JSON. * * Useful due to being able to do '.then(Request.parseResultJson)', instead of needing to create a new anonymous function. */ Request.parseResultJson = function(response) { var result = response.parseJson(); if (!result.success) { throw result.error; } return result.data; }; /** * Static method that parses the text of a response as JSON. * * Useful due to being able to do '.then(Request.parseJson)', instead of needing to create a new anonymous function. */ Request.parseJson = function(response) { return response.parseJson() }; /** * Handles case where ajax call sent with expired session. * @param {Object} response Response from server. * @returns {Object} Response given. */ Request.handleAuth = function(response) { var result = response.parseJson(); if (result && result.mustLogin) { document.location.reload(); } return result; }; Y.scriptlibrary = Y.scriptlibrary || {}; Y.scriptlibrary.Request = Request; });