├── LICENSE ├── digest-ajax-no-md5.min.js ├── README.md ├── digest-ajax.min.js ├── digest-ajax-no-md5.js └── digest-ajax.js /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Kynec Studios, Andrew Mitchell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /digest-ajax-no-md5.min.js: -------------------------------------------------------------------------------- 1 | /*(c) 2014 Kynec Studios, Andrew Mitchell | MIT License opensource.org/licenses/MIT */ 2 | (function(a){DigestAjax=function(){};DigestAjax.authHelper=function(){return{username:"",password:""}};DigestAjax.UNAUTH_HA1=null;DigestAjax.AUTH_HA1=null;DigestAjax.UNAUTH_USERNAME=null;DigestAjax.AUTH_USERNAME=null;DigestAjax.WWW_AUTHENTICATE="WWW-Authenticate";DigestAjax.ajaxDigest=function(c,e,f,k){var o={},n,d;var j=document.createElement("a");if(typeof c==="object"){o=c;j.href=o.url}else{if(typeof c==="string"){if(typeof e==="string"){n=e?e:null;d=f?f:null}else{if(typeof e==="object"){o=e?e:{};n=f?f:null;d=k?k:null}}j.href=c;o.url=c}}o=a.extend({requestUri:j.pathname+j.search,username:n,password:d,type:"GET"},o);var m=a.Deferred();return m.promise(l());function l(){return a.ajax(o).done(function(q,r,p){m.resolve(q,r,p)}).fail(function(p,r,q){if(p.status===401||p.status===407){h(g(p))}else{m.reject(p,r,q)}})}function h(p){if(o.headers===undefined){o.headers={}}o.headers.Authorization=p;return a.ajax(o).done(function(r,s,q){if(DigestAjax.UNAUTH_HA1!==null){DigestAjax.AUTH_HA1=DigestAjax.UNAUTH_HA1;DigestAjax.UNAUTH_HA1=null}if(DigestAjax.UNAUTH_USERNAME!==null){DigestAjax.AUTH_USERNAME=DigestAjax.UNAUTH_USERNAME;DigestAjax.UNAUTH_USERNAME=null}m.resolve(r,s,q)}).fail(function(q,s,r){if(q.status===401||q.status===407){DigestAjax.AUTH_HA1=null;DigestAjax.AUTH_USERNAME=null}m.reject(q,s,r)})}function g(D){var v=D.getResponseHeader(DigestAjax.WWW_AUTHENTICATE);if(v!==undefined&&v!==null){var s=b(v);var p=s.qop;var B="auth";if(p!==undefined&&p.toLowerCase()==="auth-int"){B="auth-int"}var x=s.algorithm;var A;var u;var C;if(DigestAjax.AUTH_HA1!==null){A=DigestAjax.AUTH_HA1;u=DigestAjax.AUTH_USERNAME}else{if(o.username===null||o.password===null){var q=a.extend({username:"",password:""},DigestAjax.authHelper());a.extend(o,q)}if(x!==undefined&&x.toLowerCase()==="md5-sess"){C=i();A=CryptoJS.MD5(CryptoJS.MD5(o.username+":"+s.realm+":"+o.password)+":"+s.nonce+":"+C)}else{A=CryptoJS.MD5(o.username+":"+s.realm+":"+o.password)}u=o.username;DigestAjax.UNAUTH_HA1=A;DigestAjax.UNAUTH_USERNAME=o.username}var y,r;if(B==="auth-int"){var w=o.data?o.data:"";y=CryptoJS.MD5(o.type+":"+o.requestUri+":"+CryptoJS.MD5(w))}else{y=CryptoJS.MD5(o.type+":"+o.requestUri)}var r,t;if(s.qop===undefined){r=CryptoJS.MD5(A+":"+s.nonce+":"+y)}else{if(C===undefined){C=i()}t="00000001";r=CryptoJS.MD5(A+":"+s.nonce+":"+t+":"+C+":"+B+":"+y)}var z=[];z.push('Digest username="',u,'",');z.push('realm="',s.realm,'",');z.push('nonce="',s.nonce,'",');z.push('uri="',o.requestUri,'",');z.push("qop=",B,",");if(t!==undefined){z.push("nc=",t,",")}if(C!==undefined){z.push('cnonce="',C,'",')}if(s.opaque!==undefined){z.push('opaque="',s.opaque,'",')}z.push('response="',r,'"');return z.join("")}}function b(s){var r={};var q=/([^"',\s]*)="([^"]*)/gm;var p=null;do{p=q.exec(s);if(p!==null){r[p[1]]=p[2]}}while(p!==null);return r}function i(){var p="abcdef0123456789";var s="";for(var r=0;r<8;r++){var q=Math.floor(Math.random()*p.length);s+=p.substr(q,1)}return s}};DigestAjax.ajaxDigestType=function(e,c,d,f,b){if(typeof d==="string"){b=f;f=d}if(typeof d!=="object"){d={}}d.type=e;return DigestAjax.ajaxDigest(c,d,f,b)};DigestAjax.getDigest=function(c,d,e,b){return DigestAjax.ajaxDigestType("GET",c,d,e,b)};DigestAjax.postDigest=function(c,d,e,b){return DigestAjax.ajaxDigestType("POST",c,d,e,b)};DigestAjax.putDigest=function(c,d,e,b){return DigestAjax.ajaxDigestType("PUT",c,d,e,b)};DigestAjax.deleteDigest=function(c,d,e,b){return DigestAjax.ajaxDigestType("DELETE",c,d,e,b)};a.extend({authHelper:function(b){DigestAjax.authHelper=b},ajaxDigest:DigestAjax.ajaxDigest,ajaxDigestType:DigestAjax.ajaxDigestType,getDigest:DigestAjax.getDigest,postDigest:DigestAjax.postDigest,putDigest:DigestAjax.putDigest,deleteDigest:DigestAjax.deleteDigest})}(jQuery)); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | digest-ajax 2 | =========== 3 | 4 | Digest Authentication for JavaScript jQuery AJAX Requests 5 | 6 | **digest-ajax** extends the functionality of jQuery's AJAX request by resubmitting a failed authentication request (401 and 407) with user-provided credentials. 7 | 8 | ####Requirements 9 | 10 | Requires jQuery (though a future version may make this requirement optional). Also depends on CryptoJS for MD5 digest. The main version is bundled with the CryptoJS MD5 rollup, though a non-bundled version is available. 11 | 12 | ##Syntax 13 | 14 | **digest-ajax** uses nearly identical syntax to jQuery's AJAX method. Below is an example to request a resource with Digest authentication: 15 | 16 | ``` 17 | $.ajaxDigest('http://example.com/resource', { 18 | username: 'user', 19 | password: 'pass' 20 | }).done(function(data, textStatus, jqXHR) { 21 | alert('Retrieved data!'); 22 | }).fail(function(jqXHR, textStatus, errorThrown) { 23 | alert('Request failed :('); 24 | }); 25 | ``` 26 | 27 | **digest-ajax's** ajaxDigest method returns the jQuery Deferred object's Promise interface, upon which done, fail, and always can be called just like normal AJAX syntax. These functions will only fire upon a successful or failed authentication. 28 | 29 | **digest-ajax** will submit an unauthenticated request first, and then attempt a second request with authentication if an appropriate WWW-Authenticate header is found, calling the returned Promise interface only once. 30 | 31 | All request functions can be made with the following parameters: 32 | 33 | - $.ajaxDigest(settings) 34 | - $.ajaxDigest(url, settings) 35 | - $.ajaxDigest(url, settings, username, password) 36 | 37 | Where 'settings' is the normal jQuery AJAX Object settings parameter, 'url' is the normal jQuery AJAX String url parameter, and username and password are String credentials to use for authentication. The username and password can also be set in the 'settings' object as 'username' and 'password' properties respectively. 38 | 39 | ##Auth Helper 40 | 41 | Rather than hard-coding a username and password (though perfectly viable), **digest-ajax** provides a callback method to retrieve a user's username and password dynamically. This can be achieved by returning an Object with the 'username' and 'password' property set: 42 | 43 | ``` 44 | $.authHelper(function() { 45 | //Ex: get username/password from elements 46 | var username = $('#username').val(); 47 | var password = $('#password').val(); 48 | return { 49 | username: username, 50 | password: password 51 | }; 52 | }); 53 | 54 | 55 | //Or without jQuery 56 | DigestAjax.authHelper = function() { 57 | /* Return username/password logic */ 58 | } 59 | ``` 60 | 61 | ##Credentials Cache 62 | 63 | Upon making a successful request, **digest-ajax** will store the username and generated Digest HA1 value that made the succcessful request. Subsequent requests will attempt to use the stores username and HA1 to authenticate if prompted. Should the credentials fail, it will forget the stored credentials. 64 | 65 | ##Methods 66 | 67 | Other than the ajaxDigest method, there are multiple method shorthands for different AJAX requests. The methods are stored on the global DigestAjax object, and can be accessed via the object or through jQuery. The following is a list of methods available with **digest-ajax**: 68 | 69 | - **DigestAjax.ajaxDigest()** and **$.ajaxDigest()** (Defaults to GET) 70 | - **DigestAjax.getDigest()** and **$.getDigest()** 71 | - **DigestAjax.postDigest() and **$.postDigest()** 72 | - **DigestAjax.putDigest()**** and **$.putDigest()** 73 | - **DigestAjax.deleteDigest()** and **$.deleteDigest()** 74 | - **DigestAjax.authHelper** (Assign to a function for credential callback) 75 | - **$.authHelper(callback)** (Pass a function parameter for credential callback) 76 | 77 | ##License 78 | 79 | **digest-ajax** is released under the MIT License. If you are incorporating it in a large work though, or if you have general comments about it, I would love to hear about it! 80 | -------------------------------------------------------------------------------- /digest-ajax.min.js: -------------------------------------------------------------------------------- 1 | /*(c) 2014 Kynec Studios, Andrew Mitchell | MIT License opensource.org/licenses/MIT */ 2 | (function(a){DigestAjax=function(){};DigestAjax.authHelper=function(){return{username:"",password:""}};DigestAjax.UNAUTH_HA1=null;DigestAjax.AUTH_HA1=null;DigestAjax.UNAUTH_USERNAME=null;DigestAjax.AUTH_USERNAME=null;DigestAjax.WWW_AUTHENTICATE="WWW-Authenticate";DigestAjax.ajaxDigest=function(c,e,f,k){var o={},n,d;var j=document.createElement("a");if(typeof c==="object"){o=c;j.href=o.url}else{if(typeof c==="string"){if(typeof e==="string"){n=e?e:null;d=f?f:null}else{if(typeof e==="object"){o=e?e:{};n=f?f:null;d=k?k:null}}j.href=c;o.url=c}}o=a.extend({requestUri:j.pathname+j.search,username:n,password:d,type:"GET"},o);var m=a.Deferred();return m.promise(l());function l(){return a.ajax(o).done(function(q,r,p){m.resolve(q,r,p)}).fail(function(p,r,q){if(p.status===401||p.status===407){h(g(p))}else{m.reject(p,r,q)}})}function h(p){if(o.headers===undefined){o.headers={}}o.headers.Authorization=p;return a.ajax(o).done(function(r,s,q){if(DigestAjax.UNAUTH_HA1!==null){DigestAjax.AUTH_HA1=DigestAjax.UNAUTH_HA1;DigestAjax.UNAUTH_HA1=null}if(DigestAjax.UNAUTH_USERNAME!==null){DigestAjax.AUTH_USERNAME=DigestAjax.UNAUTH_USERNAME;DigestAjax.UNAUTH_USERNAME=null}m.resolve(r,s,q)}).fail(function(q,s,r){if(q.status===401||q.status===407){DigestAjax.AUTH_HA1=null;DigestAjax.AUTH_USERNAME=null}m.reject(q,s,r)})}function g(D){var v=D.getResponseHeader(DigestAjax.WWW_AUTHENTICATE);if(v!==undefined&&v!==null){var s=b(v);var p=s.qop;var B="auth";if(p!==undefined&&p.toLowerCase()==="auth-int"){B="auth-int"}var x=s.algorithm;var A;var u;var C;if(DigestAjax.AUTH_HA1!==null){A=DigestAjax.AUTH_HA1;u=DigestAjax.AUTH_USERNAME}else{if(o.username===null||o.password===null){var q=a.extend({username:"",password:""},DigestAjax.authHelper());a.extend(o,q)}if(x!==undefined&&x.toLowerCase()==="md5-sess"){C=i();A=CryptoJS.MD5(CryptoJS.MD5(o.username+":"+s.realm+":"+o.password)+":"+s.nonce+":"+C)}else{A=CryptoJS.MD5(o.username+":"+s.realm+":"+o.password)}u=o.username;DigestAjax.UNAUTH_HA1=A;DigestAjax.UNAUTH_USERNAME=o.username}var y,r;if(B==="auth-int"){var w=o.data?o.data:"";y=CryptoJS.MD5(o.type+":"+o.requestUri+":"+CryptoJS.MD5(w))}else{y=CryptoJS.MD5(o.type+":"+o.requestUri)}var r,t;if(s.qop===undefined){r=CryptoJS.MD5(A+":"+s.nonce+":"+y)}else{if(C===undefined){C=i()}t="00000001";r=CryptoJS.MD5(A+":"+s.nonce+":"+t+":"+C+":"+B+":"+y)}var z=[];z.push('Digest username="',u,'",');z.push('realm="',s.realm,'",');z.push('nonce="',s.nonce,'",');z.push('uri="',o.requestUri,'",');z.push("qop=",B,",");if(t!==undefined){z.push("nc=",t,",")}if(C!==undefined){z.push('cnonce="',C,'",')}if(s.opaque!==undefined){z.push('opaque="',s.opaque,'",')}z.push('response="',r,'"');return z.join("")}}function b(s){var r={};var q=/([^"',\s]*)="([^"]*)/gm;var p=null;do{p=q.exec(s);if(p!==null){r[p[1]]=p[2]}}while(p!==null);return r}function i(){var p="abcdef0123456789";var s="";for(var r=0;r<8;r++){var q=Math.floor(Math.random()*p.length);s+=p.substr(q,1)}return s}};DigestAjax.ajaxDigestType=function(e,c,d,f,b){if(typeof d==="string"){b=f;f=d}if(typeof d!=="object"){d={}}d.type=e;return DigestAjax.ajaxDigest(c,d,f,b)};DigestAjax.getDigest=function(c,d,e,b){return DigestAjax.ajaxDigestType("GET",c,d,e,b)};DigestAjax.postDigest=function(c,d,e,b){return DigestAjax.ajaxDigestType("POST",c,d,e,b)};DigestAjax.putDigest=function(c,d,e,b){return DigestAjax.ajaxDigestType("PUT",c,d,e,b)};DigestAjax.deleteDigest=function(c,d,e,b){return DigestAjax.ajaxDigestType("DELETE",c,d,e,b)};a.extend({authHelper:function(b){DigestAjax.authHelper=b},ajaxDigest:DigestAjax.ajaxDigest,ajaxDigestType:DigestAjax.ajaxDigestType,getDigest:DigestAjax.getDigest,postDigest:DigestAjax.postDigest,putDigest:DigestAjax.putDigest,deleteDigest:DigestAjax.deleteDigest})}(jQuery));var CryptoJS=CryptoJS||function(z,d){var f={},h=f.lib={},e=function(){},b=h.Base={extend:function(a){e.prototype=this;var g=new e;a&&g.mixIn(a);g.hasOwnProperty("init")||(g.init=function(){g.$super.init.apply(this,arguments)});g.init.prototype=g;g.$super=this;return g},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var g in a){a.hasOwnProperty(g)&&(this[g]=a[g])}a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},c=h.WordArray=b.extend({init:function(a,g){a=this.words=a||[];this.sigBytes=g!=d?g:4*a.length},toString:function(a){return(a||y).stringify(this)},concat:function(k){var n=this.words,l=k.words,m=this.sigBytes;k=k.sigBytes;this.clamp();if(m%4){for(var p=0;p>>2]|=(l[p>>>2]>>>24-8*(p%4)&255)<<24-8*((m+p)%4)}}else{if(65535>>2]=l[p>>>2]}}else{n.push.apply(n,l)}}this.sigBytes+=k;return this},clamp:function(){var a=this.words,g=this.sigBytes;a[g>>>2]&=4294967295<<32-8*(g%4);a.length=z.ceil(g/4)},clone:function(){var a=b.clone.call(this);a.words=this.words.slice(0);return a},random:function(g){for(var l=[],k=0;k>>2]>>>24-8*(p%4)&255;q.push((n>>>4).toString(16));q.push((n&15).toString(16))}return q.join("")},parse:function(k){for(var l=k.length,n=[],m=0;m>>3]|=parseInt(k.substr(m,2),16)<<24-4*(m%8)}return new c.init(n,l/2)}},o=w.Latin1={stringify:function(k){var l=k.words;k=k.sigBytes;for(var n=[],m=0;m>>2]>>>24-8*(m%4)&255))}return n.join("")},parse:function(k){for(var l=k.length,n=[],m=0;m>>2]|=(k.charCodeAt(m)&255)<<24-8*(m%4)}return new c.init(n,l)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(o.stringify(a)))}catch(k){throw Error("Malformed UTF-8 data")}},parse:function(a){return o.parse(unescape(encodeURIComponent(a)))}},j=h.BufferedBlockAlgorithm=b.extend({reset:function(){this._data=new c.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(p){var r=this._data,u=r.words,t=r.sigBytes,s=this.blockSize,n=t/(4*s),n=p?z.ceil(n):z.max((n|0)-this._minBufferSize,0);p=n*s;t=z.min(4*p,t);if(p){for(var q=0;q>>32-t)+s}function f(r,s,p,u,q,t,n){r=r+(s&u|p&~u)+q+n;return(r<>>32-t)+s}function g(r,s,p,u,q,t,n){r=r+(s^p^u)+q+n;return(r<>>32-t)+s}function e(r,s,p,u,q,t,n){r=r+(p^(s|~u))+q+n;return(r<>>32-t)+s}for(var b=CryptoJS,c=b.lib,i=c.WordArray,k=c.Hasher,c=b.algo,h=[],j=0;64>j;j++){h[j]=4294967296*o.abs(o.sin(j+1))|0}c=c.MD5=k.extend({_doReset:function(){this._hash=new i.init([1732584193,4023233417,2562383102,271733878])},_doProcessBlock:function(Q,N){for(var V=0;16>V;V++){var P=N+V,n=Q[P];Q[P]=(n<<8|n>>>24)&16711935|(n<<24|n>>>8)&4278255360}var V=this._hash.words,P=Q[N+0],n=Q[N+1],O=Q[N+2],L=Q[N+3],J=Q[N+4],H=Q[N+5],F=Q[N+6],E=Q[N+7],p=Q[N+8],m=Q[N+9],l=Q[N+10],a=Q[N+11],M=Q[N+12],K=Q[N+13],I=Q[N+14],G=Q[N+15],U=V[0],T=V[1],S=V[2],R=V[3],U=d(U,T,S,R,P,7,h[0]),R=d(R,U,T,S,n,12,h[1]),S=d(S,R,U,T,O,17,h[2]),T=d(T,S,R,U,L,22,h[3]),U=d(U,T,S,R,J,7,h[4]),R=d(R,U,T,S,H,12,h[5]),S=d(S,R,U,T,F,17,h[6]),T=d(T,S,R,U,E,22,h[7]),U=d(U,T,S,R,p,7,h[8]),R=d(R,U,T,S,m,12,h[9]),S=d(S,R,U,T,l,17,h[10]),T=d(T,S,R,U,a,22,h[11]),U=d(U,T,S,R,M,7,h[12]),R=d(R,U,T,S,K,12,h[13]),S=d(S,R,U,T,I,17,h[14]),T=d(T,S,R,U,G,22,h[15]),U=f(U,T,S,R,n,5,h[16]),R=f(R,U,T,S,F,9,h[17]),S=f(S,R,U,T,a,14,h[18]),T=f(T,S,R,U,P,20,h[19]),U=f(U,T,S,R,H,5,h[20]),R=f(R,U,T,S,l,9,h[21]),S=f(S,R,U,T,G,14,h[22]),T=f(T,S,R,U,J,20,h[23]),U=f(U,T,S,R,m,5,h[24]),R=f(R,U,T,S,I,9,h[25]),S=f(S,R,U,T,L,14,h[26]),T=f(T,S,R,U,p,20,h[27]),U=f(U,T,S,R,K,5,h[28]),R=f(R,U,T,S,O,9,h[29]),S=f(S,R,U,T,E,14,h[30]),T=f(T,S,R,U,M,20,h[31]),U=g(U,T,S,R,H,4,h[32]),R=g(R,U,T,S,p,11,h[33]),S=g(S,R,U,T,a,16,h[34]),T=g(T,S,R,U,I,23,h[35]),U=g(U,T,S,R,n,4,h[36]),R=g(R,U,T,S,J,11,h[37]),S=g(S,R,U,T,E,16,h[38]),T=g(T,S,R,U,l,23,h[39]),U=g(U,T,S,R,K,4,h[40]),R=g(R,U,T,S,P,11,h[41]),S=g(S,R,U,T,L,16,h[42]),T=g(T,S,R,U,F,23,h[43]),U=g(U,T,S,R,m,4,h[44]),R=g(R,U,T,S,M,11,h[45]),S=g(S,R,U,T,G,16,h[46]),T=g(T,S,R,U,O,23,h[47]),U=e(U,T,S,R,P,6,h[48]),R=e(R,U,T,S,E,10,h[49]),S=e(S,R,U,T,I,15,h[50]),T=e(T,S,R,U,H,21,h[51]),U=e(U,T,S,R,M,6,h[52]),R=e(R,U,T,S,L,10,h[53]),S=e(S,R,U,T,l,15,h[54]),T=e(T,S,R,U,n,21,h[55]),U=e(U,T,S,R,p,6,h[56]),R=e(R,U,T,S,G,10,h[57]),S=e(S,R,U,T,F,15,h[58]),T=e(T,S,R,U,K,21,h[59]),U=e(U,T,S,R,J,6,h[60]),R=e(R,U,T,S,a,10,h[61]),S=e(S,R,U,T,O,15,h[62]),T=e(T,S,R,U,m,21,h[63]);V[0]=V[0]+U|0;V[1]=V[1]+T|0;V[2]=V[2]+S|0;V[3]=V[3]+R|0},_doFinalize:function(){var p=this._data,q=p.words,m=8*this._nDataBytes,r=8*p.sigBytes;q[r>>>5]|=128<<24-r%32;var n=o.floor(m/4294967296);q[(r+64>>>9<<4)+15]=(n<<8|n>>>24)&16711935|(n<<24|n>>>8)&4278255360;q[(r+64>>>9<<4)+14]=(m<<8|m>>>24)&16711935|(m<<24|m>>>8)&4278255360;p.sigBytes=4*(q.length+1);this._process();p=this._hash;q=p.words;for(m=0;4>m;m++){r=q[m],q[m]=(r<<8|r>>>24)&16711935|(r<<24|r>>>8)&4278255360}return p},clone:function(){var l=k.clone.call(this);l._hash=this._hash.clone();return l}});b.MD5=k._createHelper(c);b.HmacMD5=k._createHmacHelper(c)})(Math); -------------------------------------------------------------------------------- /digest-ajax-no-md5.js: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Kynec Studios, Andrew Mitchell 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | (function($) { 25 | DigestAjax = function() {}; 26 | 27 | //////////////////////////////////////////////////////////////////////////// 28 | // AuthHelper Function 29 | //////////////////////////////////////////////////////////////////////////// 30 | /** 31 | * This function is intended to be overriden to help supply credentials. 32 | *

33 | * Instead of hard-coding a username/password in settings and passing 34 | * it on each AJAX request, this method is called whenever a request 35 | * is challenged for credentials. This method should return an Object 36 | * with the username/password which will then be used to 37 | * authenticate. 38 | *

39 | * By default this method will return an empty username/password combo, 40 | * but it can be overriden to prompt the user for a username and/or 41 | * password. 42 | * @returns {Object} Object that must contain a 'username' and 43 | * 'password' key/value pair 44 | */ 45 | DigestAjax.authHelper = function() { 46 | return { 47 | username: '', 48 | password: '' 49 | }; 50 | }; 51 | //////////////////////////////////////////////////////////////////////////// 52 | // HA1/Username Store 53 | //////////////////////////////////////////////////////////////////////////// 54 | /**Temporary storage of a generated HA1 value*/ 55 | DigestAjax.UNAUTH_HA1 = null; 56 | /** 57 | * If Digest authentication succeeds, the temporary HA1 is transferred to 58 | * this value, where it is used for future requests. 59 | */ 60 | DigestAjax.AUTH_HA1 = null; 61 | /**Temporary storage of provided username*/ 62 | DigestAjax.UNAUTH_USERNAME = null; 63 | /** 64 | * If Digest authentication succeeds, username is stored in this value for 65 | * future requests. 66 | */ 67 | DigestAjax.AUTH_USERNAME = null; 68 | /** 69 | * Value of the WWW-Authenticate header name to retrieve. This can be 70 | * changed if the server is returning authentication information on a 71 | * different header name value. This is commonly the case when avoiding 72 | * built-in browser authentication prompts. 73 | */ 74 | DigestAjax.WWW_AUTHENTICATE = 'WWW-Authenticate'; 75 | //////////////////////////////////////////////////////////////////////////// 76 | // Primary AJAX Digest Authentication Function 77 | //////////////////////////////////////////////////////////////////////////// 78 | /** 79 | * Submits an AJAX request with optional credentials to handle 80 | * Digest authentication. 81 | * @param {(String | Object)} url the URL of the request, or settings Object 82 | * @param {(Object | String)} settings settings Object, or username 83 | * @param {String} username username, or password if username was provided 84 | * instead of settings 85 | * @param {String} password password 86 | * @returns {Promise} promise interface to call back for AJAX results 87 | */ 88 | DigestAjax.ajaxDigest = function(url, settings, username, password) { 89 | //Settings, username, and password variables 90 | var s = {}, u, p; 91 | 92 | //Extract the path from the URL, which is used for qop 93 | var a = document.createElement('a'); 94 | if (typeof url === 'object') { 95 | //ajaxDigest(settings) 96 | s = url; 97 | a.href = s.url; 98 | } 99 | else if (typeof url === 'string') { 100 | if (typeof settings === 'string') { 101 | //ajaxDigest(url, username, password) 102 | u = settings ? settings : null; 103 | p = username ? username : null; 104 | } 105 | else if (typeof settings === 'object') { 106 | //ajaxDigest(url, settings, username, password) 107 | s = settings ? settings : {}; 108 | u = username ? username : null; 109 | p = password ? password : null; 110 | } 111 | a.href = url; 112 | s.url = url; 113 | } 114 | 115 | s = $.extend({ 116 | requestUri: a.pathname + a.search, 117 | username: u, 118 | password: p, 119 | type: 'GET' 120 | }, s); 121 | 122 | var dfd = $.Deferred(); 123 | return dfd.promise(doAjaxUnauthorized()); 124 | 125 | function doAjaxUnauthorized() { 126 | //If the request is successful, invoke callbacks immediately 127 | //without using Digest authentication 128 | return $.ajax(s) 129 | .done(function(data, textStatus, jqXHR) { 130 | dfd.resolve(data, textStatus, jqXHR); 131 | }) 132 | .fail(function(jqXHR, textStatus, errorThrown) { 133 | //Only attempt Digest authentication on a 401/407 response 134 | if (jqXHR.status === 401 || jqXHR.status === 407) { 135 | doAjaxAuthorized(createAuthorizationHeader(jqXHR)); 136 | } 137 | else { 138 | dfd.reject(jqXHR, textStatus, errorThrown); 139 | } 140 | }); 141 | } 142 | 143 | function doAjaxAuthorized(header) { 144 | if (s.headers === undefined) { 145 | s.headers = {}; 146 | } 147 | s.headers.Authorization = header; 148 | return $.ajax(s) 149 | .done(function(data, textStatus, jqXHR) { 150 | if (DigestAjax.UNAUTH_HA1 !== null) { 151 | DigestAjax.AUTH_HA1 = DigestAjax.UNAUTH_HA1; 152 | DigestAjax.UNAUTH_HA1 = null; 153 | } 154 | if (DigestAjax.UNAUTH_USERNAME !== null) { 155 | DigestAjax.AUTH_USERNAME = DigestAjax.UNAUTH_USERNAME; 156 | DigestAjax.UNAUTH_USERNAME = null; 157 | } 158 | dfd.resolve(data, textStatus, jqXHR); 159 | }) 160 | .fail(function(jqXHR, textStatus, errorThrown) { 161 | if (jqXHR.status === 401 || jqXHR.status === 407) { 162 | DigestAjax.AUTH_HA1 = null; 163 | DigestAjax.AUTH_USERNAME = null; 164 | } 165 | dfd.reject(jqXHR, textStatus, errorThrown); 166 | }); 167 | } 168 | 169 | function createAuthorizationHeader(xhr) { 170 | var header = xhr.getResponseHeader(DigestAjax.WWW_AUTHENTICATE); 171 | if (header !== undefined && header !== null) { 172 | var params = parseWWWAuthenticateHeader(header); 173 | 174 | var qop = params.qop; 175 | var clientQop = 'auth'; 176 | if (qop !== undefined && qop.toLowerCase() === 'auth-int') { 177 | clientQop = 'auth-int'; 178 | } 179 | 180 | //HA1 Calculation 181 | var algorithm = params.algorithm; 182 | var ha1; 183 | var username; 184 | var cnonce; 185 | if (DigestAjax.AUTH_HA1 !== null) { 186 | ha1 = DigestAjax.AUTH_HA1; 187 | username = DigestAjax.AUTH_USERNAME; 188 | } 189 | else { 190 | if (s.username === null || s.password === null) { 191 | var auth = $.extend({ 192 | username: '', 193 | password: '' 194 | }, DigestAjax.authHelper()); 195 | $.extend(s, auth); 196 | } 197 | if (algorithm !== undefined && algorithm.toLowerCase() === 'md5-sess') { 198 | cnonce = generateCnonce(); 199 | ha1 = CryptoJS.MD5(CryptoJS.MD5(s.username + ':' 200 | + params.realm + ':' + s.password) + ':' 201 | + params.nonce + ':' + cnonce); 202 | } 203 | else { 204 | ha1 = CryptoJS.MD5(s.username + ':' + params.realm + ':' + s.password); 205 | } 206 | username = s.username; 207 | DigestAjax.UNAUTH_HA1 = ha1; 208 | DigestAjax.UNAUTH_USERNAME = s.username; 209 | } 210 | 211 | //HA2 Calculation 212 | var ha2, response; 213 | if (clientQop === 'auth-int') { 214 | var body = s.data ? s.data : ''; 215 | ha2 = CryptoJS.MD5(s.type + ':' + s.requestUri + ':' + CryptoJS.MD5(body)); 216 | } 217 | else { 218 | ha2 = CryptoJS.MD5(s.type + ':' + s.requestUri); 219 | } 220 | 221 | //Response Calculation 222 | var response, nc; 223 | if (params.qop === undefined) { 224 | response = CryptoJS.MD5(ha1 + ':' + params.nonce + ':' + ha2); 225 | } 226 | else { 227 | //Cnonce Calculation 228 | if (cnonce === undefined) { 229 | //Cnonce may have been generated already for MD5-sess algorithm 230 | cnonce = generateCnonce(); 231 | } 232 | nc = '00000001'; 233 | response = CryptoJS.MD5(ha1 + ':' + params.nonce + ':' 234 | + nc + ':' + cnonce + ':' + clientQop + ':' + ha2); 235 | } 236 | 237 | var sb = []; 238 | sb.push('Digest username="', username, '",'); 239 | sb.push('realm="', params.realm, '",'); 240 | sb.push('nonce="', params.nonce, '",'); 241 | sb.push('uri="', s.requestUri, '",'); 242 | sb.push('qop=', clientQop, ','); 243 | if (nc !== undefined) { 244 | sb.push('nc=', nc, ','); 245 | } 246 | if (cnonce !== undefined) { 247 | sb.push('cnonce="', cnonce, '",'); 248 | } 249 | if (params.opaque !== undefined) { 250 | sb.push('opaque="', params.opaque, '",'); 251 | } 252 | sb.push('response="', response, '"'); 253 | return sb.join(''); 254 | } 255 | } 256 | function parseWWWAuthenticateHeader(header) { 257 | var params = {}; 258 | var regex = /([^"',\s]*)="([^"]*)/gm; 259 | var result = null; 260 | do { 261 | result = regex.exec(header); 262 | if (result !== null) { 263 | params[result[1]] = result[2]; 264 | } 265 | } 266 | while (result !== null); 267 | return params; 268 | } 269 | function generateCnonce() { 270 | var cnonceChars = 'abcdef0123456789'; 271 | var cnonce = ''; 272 | for (var i = 0; i < 8; i++) { 273 | var randNum = Math.floor(Math.random() * cnonceChars.length); 274 | cnonce += cnonceChars.substr(randNum, 1); 275 | } 276 | return cnonce; 277 | } 278 | }; 279 | DigestAjax.ajaxDigestType = function(type, url, settings, username, password) { 280 | if (typeof settings === 'string') { 281 | password = username; 282 | username = settings; 283 | } 284 | 285 | if (typeof settings !== 'object') { 286 | settings = {}; 287 | } 288 | settings.type = type; 289 | return DigestAjax.ajaxDigest(url, settings, username, password); 290 | }; 291 | DigestAjax.getDigest = function(url, settings, username, password) { 292 | return DigestAjax.ajaxDigestType('GET', url, settings, username, password); 293 | }; 294 | DigestAjax.postDigest = function(url, settings, username, password) { 295 | return DigestAjax.ajaxDigestType('POST', url, settings, username, password); 296 | }; 297 | DigestAjax.putDigest = function(url, settings, username, password) { 298 | return DigestAjax.ajaxDigestType('PUT', url, settings, username, password); 299 | }; 300 | DigestAjax.deleteDigest = function(url, settings, username, password) { 301 | return DigestAjax.ajaxDigestType('DELETE', url, settings, username, password); 302 | }; 303 | $.extend({ 304 | authHelper: function(call) { 305 | DigestAjax.authHelper = call; 306 | }, 307 | ajaxDigest: DigestAjax.ajaxDigest, 308 | ajaxDigestType: DigestAjax.ajaxDigestType, 309 | getDigest: DigestAjax.getDigest, 310 | postDigest: DigestAjax.postDigest, 311 | putDigest: DigestAjax.putDigest, 312 | deleteDigest: DigestAjax.deleteDigest 313 | }); 314 | } (jQuery)); -------------------------------------------------------------------------------- /digest-ajax.js: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Kynec Studios, Andrew Mitchell 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | (function($) { 25 | DigestAjax = function() {}; 26 | 27 | //////////////////////////////////////////////////////////////////////////// 28 | // AuthHelper Function 29 | //////////////////////////////////////////////////////////////////////////// 30 | /** 31 | * This function is intended to be overriden to help supply credentials. 32 | *

33 | * Instead of hard-coding a username/password in settings and passing 34 | * it on each AJAX request, this method is called whenever a request 35 | * is challenged for credentials. This method should return an Object 36 | * with the username/password which will then be used to 37 | * authenticate. 38 | *

39 | * By default this method will return an empty username/password combo, 40 | * but it can be overriden to prompt the user for a username and/or 41 | * password. 42 | * @returns {Object} Object that must contain a 'username' and 43 | * 'password' key/value pair 44 | */ 45 | DigestAjax.authHelper = function() { 46 | return { 47 | username: '', 48 | password: '' 49 | }; 50 | }; 51 | //////////////////////////////////////////////////////////////////////////// 52 | // HA1/Username Store 53 | //////////////////////////////////////////////////////////////////////////// 54 | /**Temporary storage of a generated HA1 value*/ 55 | DigestAjax.UNAUTH_HA1 = null; 56 | /** 57 | * If Digest authentication succeeds, the temporary HA1 is transferred to 58 | * this value, where it is used for future requests. 59 | */ 60 | DigestAjax.AUTH_HA1 = null; 61 | /**Temporary storage of provided username*/ 62 | DigestAjax.UNAUTH_USERNAME = null; 63 | /** 64 | * If Digest authentication succeeds, username is stored in this value for 65 | * future requests. 66 | */ 67 | DigestAjax.AUTH_USERNAME = null; 68 | /** 69 | * Value of the WWW-Authenticate header name to retrieve. This can be 70 | * changed if the server is returning authentication information on a 71 | * different header name value. This is commonly the case when avoiding 72 | * built-in browser authentication prompts. 73 | */ 74 | DigestAjax.WWW_AUTHENTICATE = 'WWW-Authenticate'; 75 | //////////////////////////////////////////////////////////////////////////// 76 | // Primary AJAX Digest Authentication Function 77 | //////////////////////////////////////////////////////////////////////////// 78 | /** 79 | * Submits an AJAX request with optional credentials to handle 80 | * Digest authentication. 81 | * @param {(String | Object)} url the URL of the request, or settings Object 82 | * @param {(Object | String)} settings settings Object, or username 83 | * @param {String} username username, or password if username was provided 84 | * instead of settings 85 | * @param {String} password password 86 | * @returns {Promise} promise interface to call back for AJAX results 87 | */ 88 | DigestAjax.ajaxDigest = function(url, settings, username, password) { 89 | //Settings, username, and password variables 90 | var s = {}, u, p; 91 | 92 | //Extract the path from the URL, which is used for qop 93 | var a = document.createElement('a'); 94 | if (typeof url === 'object') { 95 | //ajaxDigest(settings) 96 | s = url; 97 | a.href = s.url; 98 | } 99 | else if (typeof url === 'string') { 100 | if (typeof settings === 'string') { 101 | //ajaxDigest(url, username, password) 102 | u = settings ? settings : null; 103 | p = username ? username : null; 104 | } 105 | else if (typeof settings === 'object') { 106 | //ajaxDigest(url, settings, username, password) 107 | s = settings ? settings : {}; 108 | u = username ? username : null; 109 | p = password ? password : null; 110 | } 111 | a.href = url; 112 | s.url = url; 113 | } 114 | 115 | s = $.extend({ 116 | requestUri: a.pathname + a.search, 117 | username: u, 118 | password: p, 119 | type: 'GET' 120 | }, s); 121 | 122 | 123 | var dfd = $.Deferred(); 124 | return dfd.promise(doAjaxUnauthorized()); 125 | 126 | function doAjaxUnauthorized() { 127 | //If the request is successful, invoke callbacks immediately 128 | //without using Digest authentication 129 | return $.ajax(s) 130 | .done(function(data, textStatus, jqXHR) { 131 | dfd.resolve(data, textStatus, jqXHR); 132 | }) 133 | .fail(function(jqXHR, textStatus, errorThrown) { 134 | //Only attempt Digest authentication on a 401/407 response 135 | if (jqXHR.status === 401 || jqXHR.status === 407) { 136 | doAjaxAuthorized(createAuthorizationHeader(jqXHR)); 137 | } 138 | else { 139 | dfd.reject(jqXHR, textStatus, errorThrown); 140 | } 141 | }); 142 | } 143 | 144 | function doAjaxAuthorized(header) { 145 | if (s.headers === undefined) { 146 | s.headers = {}; 147 | } 148 | s.headers.Authorization = header; 149 | return $.ajax(s) 150 | .done(function(data, textStatus, jqXHR) { 151 | if (DigestAjax.UNAUTH_HA1 !== null) { 152 | DigestAjax.AUTH_HA1 = DigestAjax.UNAUTH_HA1; 153 | DigestAjax.UNAUTH_HA1 = null; 154 | } 155 | if (DigestAjax.UNAUTH_USERNAME !== null) { 156 | DigestAjax.AUTH_USERNAME = DigestAjax.UNAUTH_USERNAME; 157 | DigestAjax.UNAUTH_USERNAME = null; 158 | } 159 | dfd.resolve(data, textStatus, jqXHR); 160 | }) 161 | .fail(function(jqXHR, textStatus, errorThrown) { 162 | if (jqXHR.status === 401 || jqXHR.status === 407) { 163 | DigestAjax.AUTH_HA1 = null; 164 | DigestAjax.AUTH_USERNAME = null; 165 | } 166 | dfd.reject(jqXHR, textStatus, errorThrown); 167 | }); 168 | } 169 | 170 | function createAuthorizationHeader(xhr) { 171 | var header = xhr.getResponseHeader(DigestAjax.WWW_AUTHENTICATE); 172 | if (header !== undefined && header !== null) { 173 | var params = parseWWWAuthenticateHeader(header); 174 | 175 | var qop = params.qop; 176 | var clientQop = 'auth'; 177 | if (qop !== undefined && qop.toLowerCase() === 'auth-int') { 178 | clientQop = 'auth-int'; 179 | } 180 | 181 | //HA1 Calculation 182 | var algorithm = params.algorithm; 183 | var ha1; 184 | var username; 185 | var cnonce; 186 | if (DigestAjax.AUTH_HA1 !== null) { 187 | ha1 = DigestAjax.AUTH_HA1; 188 | username = DigestAjax.AUTH_USERNAME; 189 | } 190 | else { 191 | if (s.username === null || s.password === null) { 192 | var auth = $.extend({ 193 | username: '', 194 | password: '' 195 | }, DigestAjax.authHelper()); 196 | $.extend(s, auth); 197 | } 198 | if (algorithm !== undefined && algorithm.toLowerCase() === 'md5-sess') { 199 | cnonce = generateCnonce(); 200 | ha1 = CryptoJS.MD5(CryptoJS.MD5(s.username + ':' 201 | + params.realm + ':' + s.password) + ':' 202 | + params.nonce + ':' + cnonce); 203 | } 204 | else { 205 | ha1 = CryptoJS.MD5(s.username + ':' + params.realm + ':' + s.password); 206 | } 207 | username = s.username; 208 | DigestAjax.UNAUTH_HA1 = ha1; 209 | DigestAjax.UNAUTH_USERNAME = s.username; 210 | } 211 | 212 | //HA2 Calculation 213 | var ha2, response; 214 | if (clientQop === 'auth-int') { 215 | var body = s.data ? s.data : ''; 216 | ha2 = CryptoJS.MD5(s.type + ':' + s.requestUri + ':' + CryptoJS.MD5(body)); 217 | } 218 | else { 219 | ha2 = CryptoJS.MD5(s.type + ':' + s.requestUri); 220 | } 221 | 222 | //Response Calculation 223 | var response, nc; 224 | if (params.qop === undefined) { 225 | response = CryptoJS.MD5(ha1 + ':' + params.nonce + ':' + ha2); 226 | } 227 | else { 228 | //Cnonce Calculation 229 | if (cnonce === undefined) { 230 | //Cnonce may have been generated already for MD5-sess algorithm 231 | cnonce = generateCnonce(); 232 | } 233 | nc = '00000001'; 234 | response = CryptoJS.MD5(ha1 + ':' + params.nonce + ':' 235 | + nc + ':' + cnonce + ':' + clientQop + ':' + ha2); 236 | } 237 | 238 | var sb = []; 239 | sb.push('Digest username="', username, '",'); 240 | sb.push('realm="', params.realm, '",'); 241 | sb.push('nonce="', params.nonce, '",'); 242 | sb.push('uri="', s.requestUri, '",'); 243 | sb.push('qop=', clientQop, ','); 244 | if (nc !== undefined) { 245 | sb.push('nc=', nc, ','); 246 | } 247 | if (cnonce !== undefined) { 248 | sb.push('cnonce="', cnonce, '",'); 249 | } 250 | if (params.opaque !== undefined) { 251 | sb.push('opaque="', params.opaque, '",'); 252 | } 253 | sb.push('response="', response, '"'); 254 | return sb.join(''); 255 | } 256 | } 257 | function parseWWWAuthenticateHeader(header) { 258 | var params = {}; 259 | var regex = /([^"',\s]*)="([^"]*)/gm; 260 | var result = null; 261 | do { 262 | result = regex.exec(header); 263 | if (result !== null) { 264 | params[result[1]] = result[2]; 265 | } 266 | } 267 | while (result !== null); 268 | return params; 269 | } 270 | function generateCnonce() { 271 | var cnonceChars = 'abcdef0123456789'; 272 | var cnonce = ''; 273 | for (var i = 0; i < 8; i++) { 274 | var randNum = Math.floor(Math.random() * cnonceChars.length); 275 | cnonce += cnonceChars.substr(randNum, 1); 276 | } 277 | return cnonce; 278 | } 279 | }; 280 | DigestAjax.ajaxDigestType = function(type, url, settings, username, password) { 281 | if (typeof settings === 'string') { 282 | password = username; 283 | username = settings; 284 | } 285 | 286 | if (typeof settings !== 'object') { 287 | settings = {}; 288 | } 289 | settings.type = type; 290 | return DigestAjax.ajaxDigest(url, settings, username, password); 291 | }; 292 | DigestAjax.getDigest = function(url, settings, username, password) { 293 | return DigestAjax.ajaxDigestType('GET', url, settings, username, password); 294 | }; 295 | DigestAjax.postDigest = function(url, settings, username, password) { 296 | return DigestAjax.ajaxDigestType('POST', url, settings, username, password); 297 | }; 298 | DigestAjax.putDigest = function(url, settings, username, password) { 299 | return DigestAjax.ajaxDigestType('PUT', url, settings, username, password); 300 | }; 301 | DigestAjax.deleteDigest = function(url, settings, username, password) { 302 | return DigestAjax.ajaxDigestType('DELETE', url, settings, username, password); 303 | }; 304 | $.extend({ 305 | authHelper: function(call) { 306 | DigestAjax.authHelper = call; 307 | }, 308 | ajaxDigest: DigestAjax.ajaxDigest, 309 | ajaxDigestType: DigestAjax.ajaxDigestType, 310 | getDigest: DigestAjax.getDigest, 311 | postDigest: DigestAjax.postDigest, 312 | putDigest: DigestAjax.putDigest, 313 | deleteDigest: DigestAjax.deleteDigest 314 | }); 315 | } (jQuery)); 316 | 317 | 318 | //////////////////////////////////////////////////////////////////////////////// 319 | // Included CryptoJS MD5 rollup 320 | //////////////////////////////////////////////////////////////////////////////// 321 | /* 322 | CryptoJS v3.1.2 323 | code.google.com/p/crypto-js 324 | (c) 2009-2013 by Jeff Mott. All rights reserved. 325 | code.google.com/p/crypto-js/wiki/License 326 | */ 327 | var CryptoJS=CryptoJS||function(s,p){var m={},l=m.lib={},n=function(){},r=l.Base={extend:function(b){n.prototype=this;var h=new n;b&&h.mixIn(b);h.hasOwnProperty("init")||(h.init=function(){h.$super.init.apply(this,arguments)});h.init.prototype=h;h.$super=this;return h},create:function(){var b=this.extend();b.init.apply(b,arguments);return b},init:function(){},mixIn:function(b){for(var h in b)b.hasOwnProperty(h)&&(this[h]=b[h]);b.hasOwnProperty("toString")&&(this.toString=b.toString)},clone:function(){return this.init.prototype.extend(this)}}, 328 | q=l.WordArray=r.extend({init:function(b,h){b=this.words=b||[];this.sigBytes=h!=p?h:4*b.length},toString:function(b){return(b||t).stringify(this)},concat:function(b){var h=this.words,a=b.words,j=this.sigBytes;b=b.sigBytes;this.clamp();if(j%4)for(var g=0;g>>2]|=(a[g>>>2]>>>24-8*(g%4)&255)<<24-8*((j+g)%4);else if(65535>>2]=a[g>>>2];else h.push.apply(h,a);this.sigBytes+=b;return this},clamp:function(){var b=this.words,h=this.sigBytes;b[h>>>2]&=4294967295<< 329 | 32-8*(h%4);b.length=s.ceil(h/4)},clone:function(){var b=r.clone.call(this);b.words=this.words.slice(0);return b},random:function(b){for(var h=[],a=0;a>>2]>>>24-8*(j%4)&255;g.push((k>>>4).toString(16));g.push((k&15).toString(16))}return g.join("")},parse:function(b){for(var a=b.length,g=[],j=0;j>>3]|=parseInt(b.substr(j, 330 | 2),16)<<24-4*(j%8);return new q.init(g,a/2)}},a=v.Latin1={stringify:function(b){var a=b.words;b=b.sigBytes;for(var g=[],j=0;j>>2]>>>24-8*(j%4)&255));return g.join("")},parse:function(b){for(var a=b.length,g=[],j=0;j>>2]|=(b.charCodeAt(j)&255)<<24-8*(j%4);return new q.init(g,a)}},u=v.Utf8={stringify:function(b){try{return decodeURIComponent(escape(a.stringify(b)))}catch(g){throw Error("Malformed UTF-8 data");}},parse:function(b){return a.parse(unescape(encodeURIComponent(b)))}}, 331 | g=l.BufferedBlockAlgorithm=r.extend({reset:function(){this._data=new q.init;this._nDataBytes=0},_append:function(b){"string"==typeof b&&(b=u.parse(b));this._data.concat(b);this._nDataBytes+=b.sigBytes},_process:function(b){var a=this._data,g=a.words,j=a.sigBytes,k=this.blockSize,m=j/(4*k),m=b?s.ceil(m):s.max((m|0)-this._minBufferSize,0);b=m*k;j=s.min(4*b,j);if(b){for(var l=0;l>>32-j)+k}function m(a,k,b,h,l,j,m){a=a+(k&h|b&~h)+l+m;return(a<>>32-j)+k}function l(a,k,b,h,l,j,m){a=a+(k^b^h)+l+m;return(a<>>32-j)+k}function n(a,k,b,h,l,j,m){a=a+(b^(k|~h))+l+m;return(a<>>32-j)+k}for(var r=CryptoJS,q=r.lib,v=q.WordArray,t=q.Hasher,q=r.algo,a=[],u=0;64>u;u++)a[u]=4294967296*s.abs(s.sin(u+1))|0;q=q.MD5=t.extend({_doReset:function(){this._hash=new v.init([1732584193,4023233417,2562383102,271733878])}, 335 | _doProcessBlock:function(g,k){for(var b=0;16>b;b++){var h=k+b,w=g[h];g[h]=(w<<8|w>>>24)&16711935|(w<<24|w>>>8)&4278255360}var b=this._hash.words,h=g[k+0],w=g[k+1],j=g[k+2],q=g[k+3],r=g[k+4],s=g[k+5],t=g[k+6],u=g[k+7],v=g[k+8],x=g[k+9],y=g[k+10],z=g[k+11],A=g[k+12],B=g[k+13],C=g[k+14],D=g[k+15],c=b[0],d=b[1],e=b[2],f=b[3],c=p(c,d,e,f,h,7,a[0]),f=p(f,c,d,e,w,12,a[1]),e=p(e,f,c,d,j,17,a[2]),d=p(d,e,f,c,q,22,a[3]),c=p(c,d,e,f,r,7,a[4]),f=p(f,c,d,e,s,12,a[5]),e=p(e,f,c,d,t,17,a[6]),d=p(d,e,f,c,u,22,a[7]), 336 | c=p(c,d,e,f,v,7,a[8]),f=p(f,c,d,e,x,12,a[9]),e=p(e,f,c,d,y,17,a[10]),d=p(d,e,f,c,z,22,a[11]),c=p(c,d,e,f,A,7,a[12]),f=p(f,c,d,e,B,12,a[13]),e=p(e,f,c,d,C,17,a[14]),d=p(d,e,f,c,D,22,a[15]),c=m(c,d,e,f,w,5,a[16]),f=m(f,c,d,e,t,9,a[17]),e=m(e,f,c,d,z,14,a[18]),d=m(d,e,f,c,h,20,a[19]),c=m(c,d,e,f,s,5,a[20]),f=m(f,c,d,e,y,9,a[21]),e=m(e,f,c,d,D,14,a[22]),d=m(d,e,f,c,r,20,a[23]),c=m(c,d,e,f,x,5,a[24]),f=m(f,c,d,e,C,9,a[25]),e=m(e,f,c,d,q,14,a[26]),d=m(d,e,f,c,v,20,a[27]),c=m(c,d,e,f,B,5,a[28]),f=m(f,c, 337 | d,e,j,9,a[29]),e=m(e,f,c,d,u,14,a[30]),d=m(d,e,f,c,A,20,a[31]),c=l(c,d,e,f,s,4,a[32]),f=l(f,c,d,e,v,11,a[33]),e=l(e,f,c,d,z,16,a[34]),d=l(d,e,f,c,C,23,a[35]),c=l(c,d,e,f,w,4,a[36]),f=l(f,c,d,e,r,11,a[37]),e=l(e,f,c,d,u,16,a[38]),d=l(d,e,f,c,y,23,a[39]),c=l(c,d,e,f,B,4,a[40]),f=l(f,c,d,e,h,11,a[41]),e=l(e,f,c,d,q,16,a[42]),d=l(d,e,f,c,t,23,a[43]),c=l(c,d,e,f,x,4,a[44]),f=l(f,c,d,e,A,11,a[45]),e=l(e,f,c,d,D,16,a[46]),d=l(d,e,f,c,j,23,a[47]),c=n(c,d,e,f,h,6,a[48]),f=n(f,c,d,e,u,10,a[49]),e=n(e,f,c,d, 338 | C,15,a[50]),d=n(d,e,f,c,s,21,a[51]),c=n(c,d,e,f,A,6,a[52]),f=n(f,c,d,e,q,10,a[53]),e=n(e,f,c,d,y,15,a[54]),d=n(d,e,f,c,w,21,a[55]),c=n(c,d,e,f,v,6,a[56]),f=n(f,c,d,e,D,10,a[57]),e=n(e,f,c,d,t,15,a[58]),d=n(d,e,f,c,B,21,a[59]),c=n(c,d,e,f,r,6,a[60]),f=n(f,c,d,e,z,10,a[61]),e=n(e,f,c,d,j,15,a[62]),d=n(d,e,f,c,x,21,a[63]);b[0]=b[0]+c|0;b[1]=b[1]+d|0;b[2]=b[2]+e|0;b[3]=b[3]+f|0},_doFinalize:function(){var a=this._data,k=a.words,b=8*this._nDataBytes,h=8*a.sigBytes;k[h>>>5]|=128<<24-h%32;var l=s.floor(b/ 339 | 4294967296);k[(h+64>>>9<<4)+15]=(l<<8|l>>>24)&16711935|(l<<24|l>>>8)&4278255360;k[(h+64>>>9<<4)+14]=(b<<8|b>>>24)&16711935|(b<<24|b>>>8)&4278255360;a.sigBytes=4*(k.length+1);this._process();a=this._hash;k=a.words;for(b=0;4>b;b++)h=k[b],k[b]=(h<<8|h>>>24)&16711935|(h<<24|h>>>8)&4278255360;return a},clone:function(){var a=t.clone.call(this);a._hash=this._hash.clone();return a}});r.MD5=t._createHelper(q);r.HmacMD5=t._createHmacHelper(q)})(Math); --------------------------------------------------------------------------------