Skip to content

Commit

Permalink
src/Csrf.min.js
Browse files Browse the repository at this point in the history
  • Loading branch information
mariuszkrzaczkowski committed Nov 16, 2023
1 parent 478c829 commit 910815b
Showing 1 changed file with 215 additions and 1 deletion.
216 changes: 215 additions & 1 deletion src/Csrf.min.js
@@ -1 +1,215 @@
CsrfMagic=function(d){if(!d){try{d=new XMLHttpRequest}catch(b){}}if(!d){try{d=new ActiveXObject("Msxml2.XMLHTTP")}catch(b){}}if(!d){try{d=new ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}if(!d){try{d=new ActiveXObject("Msxml2.XMLHTTP.4.0")}catch(b){}}this.csrf=d;var a=this;d.onreadystatechange=function(){a._updateProps();return a.onreadystatechange?a.onreadystatechange():null};a._updateProps()};CsrfMagic.prototype={open:function(f,b,d,e,a){if(f=="POST"){this.csrf_isPost=true}if(e){return this.csrf_open(f,b,d,e,a)}else{return this.csrf_open(f,b,d)}},csrf_open:function(f,b,d,e,a){if(e){return this.csrf.open(f,b,d,e,a)}else{return this.csrf.open(f,b,d)}},send:function(a){if(!this.csrf_isPost){return this.csrf_send(a)}delete this.csrf_isPost;if(a instanceof FormData){a.append(csrfMagicName,csrfMagicToken);return this.csrf_send(a)}else{return this.csrf_send(csrfMagicName+"="+csrfMagicToken+"&"+a)}},csrf_send:function(a){return this.csrf.send(a)},setRequestHeader:function(b,a){if(this.csrf_isPost&&b=="Content-length"){this.csrf_purportedLength=a;return}return this.csrf_setRequestHeader(b,a)},csrf_setRequestHeader:function(b,a){return this.csrf.setRequestHeader(b,a)},abort:function(){return this.csrf.abort()},getAllResponseHeaders:function(){return this.csrf.getAllResponseHeaders()},getResponseHeader:function(a){return this.csrf.getResponseHeader(a)}};CsrfMagic.prototype._updateProps=function(){this.readyState=this.csrf.readyState;if(this.readyState==4){this.responseText=this.csrf.responseText;this.responseXML=this.csrf.responseXML;this.status=this.csrf.status;this.statusText=this.csrf.statusText}};CsrfMagic.process=function(b){if(typeof b=="object"){b[csrfMagicName]=csrfMagicToken;return b}var a=csrfMagicName+"="+csrfMagicToken;if(b){return a+"&"+b}return a};CsrfMagic.end=function(){forms=document.getElementsByTagName("form");for(var b=0;b<forms.length;b++){form=forms[b];var d=form.getAttribute("method");if(d&&d.toUpperCase()!=="POST"){continue}if(form.elements[csrfMagicName]){continue}var a=document.createElement("input");a.setAttribute("name",csrfMagicName);a.setAttribute("value",csrfMagicToken);a.setAttribute("type","hidden");form.appendChild(a)}};if(window.XMLHttpRequest&&window.XMLHttpRequest.prototype&&"\v"!="v"){var x=XMLHttpRequest.prototype;var c=CsrfMagic.prototype;x.csrf_open=x.open;x.csrf_send=x.send;x.csrf_setRequestHeader=x.setRequestHeader;x.open=c.open;x.send=c.send;x.setRequestHeader=c.setRequestHeader}else{if(window.jQuery){jQuery.csrf_ajax=jQuery.ajax;jQuery.ajax=function(a){if(a.type&&a.type.toUpperCase()=="POST"){a=jQuery.extend(true,a,jQuery.extend(true,{},jQuery.ajaxSettings,a));if(a.data&&a.processData&&typeof a.data!="string"){a.data=jQuery.param(a.data)}a.data=CsrfMagic.process(a.data)}return jQuery.csrf_ajax(a)}}if(window.Prototype){Ajax.csrf_getTransport=Ajax.getTransport;Ajax.getTransport=function(){return new CsrfMagic(Ajax.csrf_getTransport())}}if(window.MooTools){Browser.csrf_Request=Browser.Request;Browser.Request=function(){return new CsrfMagic(Browser.csrf_Request())}}if(window.YAHOO){YAHOO.util.Connect.csrf_createXhrObject=YAHOO.util.Connect.createXhrObject;YAHOO.util.Connect.createXhrObject=function(a){obj=YAHOO.util.Connect.csrf_createXhrObject(a);obj.conn=new CsrfMagic(obj.conn);return obj}}if(window.Ext){Ext.lib.Ajax.csrf_createXhrObject=Ext.lib.Ajax.createXhrObject;Ext.lib.Ajax.createXhrObject=function(a){obj=Ext.lib.Ajax.csrf_createXhrObject(a);obj.conn=new CsrfMagic(obj.conn);return obj}}if(window.dojo){dojo.csrf__xhrObj=dojo._xhrObj;dojo._xhrObj=function(){return new CsrfMagic(dojo.csrf__xhrObj())}}};
/**
* @file
*
* Rewrites XMLHttpRequest to automatically send CSRF token with it. In theory
* plays nice with other JavaScript libraries, needs testing though.
*/

// Here are the basic overloaded method definitions
// The wrapper must be set BEFORE onreadystatechange is written to, since
// a bug in ActiveXObject prevents us from properly testing for it.
CsrfMagic = function (real) {
// try to make it ourselves, if you didn't pass it
if (!real)
try {
real = new XMLHttpRequest();
} catch (e) {}
if (!real)
try {
real = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {}
if (!real)
try {
real = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {}
if (!real)
try {
real = new ActiveXObject('Msxml2.XMLHTTP.4.0');
} catch (e) {}
this.csrf = real;
// properties
var csrfMagic = this;
real.onreadystatechange = function () {
csrfMagic._updateProps();
return csrfMagic.onreadystatechange ? csrfMagic.onreadystatechange() : null;
};
csrfMagic._updateProps();
};

CsrfMagic.prototype = {
open: function (method, url, async, username, password) {
if (method == 'POST') this.csrf_isPost = true;
this.csrf_url = url;
// deal with Opera bug, thanks jQuery
if (username) return this.csrf_open(method, url, async, username, password);
else return this.csrf_open(method, url, async);
},
csrf_open: function (method, url, async, username, password) {
if (username) return this.csrf.open(method, url, async, username, password);
else return this.csrf.open(method, url, async);
},

send: function (data) {
let url = null;
try {
url = new URL(this.csrf_url);
} catch (e) {
//for internal urls there could be no domain part
//in that case it's not a valid url
}
//don't add token to external requests
if (url !== null && typeof csrfMagicDomain !== 'undefined' && url.host !== csrfMagicDomain) {
return this.csrf_send(data);
}

if (!this.csrf_isPost) return this.csrf_send(data);
delete this.csrf_isPost;
if (data instanceof FormData) {
data.append(csrfMagicName, csrfMagicToken);
return this.csrf_send(data);
} else {
return this.csrf_send(csrfMagicName + '=' + csrfMagicToken + '&' + data);
}
},
csrf_send: function (data) {
return this.csrf.send(data);
},

setRequestHeader: function (header, value) {
// We have to auto-set this at the end, since we don't know how long the
// nonce is when added to the data.
if (this.csrf_isPost && header == 'Content-length') {
this.csrf_purportedLength = value;
return;
}
return this.csrf_setRequestHeader(header, value);
},
csrf_setRequestHeader: function (header, value) {
return this.csrf.setRequestHeader(header, value);
},

abort: function () {
return this.csrf.abort();
},
getAllResponseHeaders: function () {
return this.csrf.getAllResponseHeaders();
},
getResponseHeader: function (header) {
return this.csrf.getResponseHeader(header);
} // ,
};

// proprietary
CsrfMagic.prototype._updateProps = function () {
this.readyState = this.csrf.readyState;
if (this.readyState == 4) {
this.responseText = this.csrf.responseText;
this.responseXML = this.csrf.responseXML;
this.status = this.csrf.status;
this.statusText = this.csrf.statusText;
}
};
CsrfMagic.process = function (base) {
if (typeof base == 'object') {
base[csrfMagicName] = csrfMagicToken;
return base;
}
var prepend = csrfMagicName + '=' + csrfMagicToken;
if (base) return prepend + '&' + base;
return prepend;
};
// callback function for when everything on the page has loaded
CsrfMagic.end = function () {
// This rewrites forms AGAIN, so in case buffering didn't work this
// certainly will.
forms = document.getElementsByTagName('form');
for (var i = 0; i < forms.length; i++) {
form = forms[i];
var method = form.getAttribute('method');
if (method && method.toUpperCase() !== 'POST') continue;
if (form.elements[csrfMagicName]) continue;
var input = document.createElement('input');
input.setAttribute('name', csrfMagicName);
input.setAttribute('value', csrfMagicToken);
input.setAttribute('type', 'hidden');
form.appendChild(input);
}
};

// Sets things up for Mozilla/Opera/nice browsers
// We very specifically match against Internet Explorer, since they haven't
// implemented prototypes correctly yet.
if (window.XMLHttpRequest && window.XMLHttpRequest.prototype && '\v' != 'v') {
var x = XMLHttpRequest.prototype;
var c = CsrfMagic.prototype;

// Save the original functions
x.csrf_open = x.open;
x.csrf_send = x.send;
x.csrf_setRequestHeader = x.setRequestHeader;

// Notice that CsrfMagic is itself an instantiatable object, but only
// open, send and setRequestHeader are necessary as decorators.
x.open = c.open;
x.send = c.send;
x.setRequestHeader = c.setRequestHeader;
} else {
// The only way we can do this is by modifying a library you have been
// using. We support YUI, script.aculo.us, prototype, MooTools,
// jQuery, Ext and Dojo.
if (window.jQuery) {
// jQuery didn't implement a new XMLHttpRequest function, so we have
// to do this the hard way.
jQuery.csrf_ajax = jQuery.ajax;
jQuery.ajax = function (s) {
if (s.type && s.type.toUpperCase() == 'POST') {
s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
if (s.data && s.processData && typeof s.data != 'string') {
s.data = jQuery.param(s.data);
}
s.data = CsrfMagic.process(s.data);
}
return jQuery.csrf_ajax(s);
};
}
if (window.Prototype) {
// This works for script.aculo.us too
Ajax.csrf_getTransport = Ajax.getTransport;
Ajax.getTransport = function () {
return new CsrfMagic(Ajax.csrf_getTransport());
};
}
if (window.MooTools) {
Browser.csrf_Request = Browser.Request;
Browser.Request = function () {
return new CsrfMagic(Browser.csrf_Request());
};
}
if (window.YAHOO) {
// old YUI API
YAHOO.util.Connect.csrf_createXhrObject = YAHOO.util.Connect.createXhrObject;
YAHOO.util.Connect.createXhrObject = function (transaction) {
obj = YAHOO.util.Connect.csrf_createXhrObject(transaction);
obj.conn = new CsrfMagic(obj.conn);
return obj;
};
}
if (window.Ext) {
// Ext can use other js libraries as loaders, so it has to come last
// Ext's implementation is pretty identical to Yahoo's, but we duplicate
// it for comprehensiveness's sake.
Ext.lib.Ajax.csrf_createXhrObject = Ext.lib.Ajax.createXhrObject;
Ext.lib.Ajax.createXhrObject = function (transaction) {
obj = Ext.lib.Ajax.csrf_createXhrObject(transaction);
obj.conn = new CsrfMagic(obj.conn);
return obj;
};
}
if (window.dojo) {
// NOTE: this doesn't work with latest dojo
dojo.csrf__xhrObj = dojo._xhrObj;
dojo._xhrObj = function () {
return new CsrfMagic(dojo.csrf__xhrObj());
};
}
}

0 comments on commit 910815b

Please sign in to comment.