From 0bf072f0e5d26016e61fbe68a5c0fec60e13e5e3 Mon Sep 17 00:00:00 2001 From: Azul Date: Wed, 14 Nov 2012 12:21:00 +0100 Subject: removed outdated django remote and all related files Also cleaned up the specs a bit --- Readme.md | 8 +-- spec/DjangoSpecRunner.html | 75 --------------------------- spec/RestfulSpecRunner.html | 75 --------------------------- spec/django/login.js | 69 ------------------------- spec/django/signup.js | 50 ------------------ spec/helper.js | 44 ++++++++++++++++ spec/login_spec.js | 78 ++++++++++++++++++++++++++++ spec/restful/login.js | 78 ---------------------------- spec/restful/session.js | 39 -------------- spec/restful/signup.js | 32 ------------ spec/runner.html | 75 +++++++++++++++++++++++++++ spec/session_spec.js | 39 ++++++++++++++ spec/signup_spec.js | 32 ++++++++++++ spec/specHelper.js | 44 ---------------- src/plainXHR.js | 120 -------------------------------------------- 15 files changed, 272 insertions(+), 586 deletions(-) delete mode 100644 spec/DjangoSpecRunner.html delete mode 100644 spec/RestfulSpecRunner.html delete mode 100644 spec/django/login.js delete mode 100644 spec/django/signup.js create mode 100644 spec/helper.js create mode 100644 spec/login_spec.js delete mode 100644 spec/restful/login.js delete mode 100644 spec/restful/session.js delete mode 100644 spec/restful/signup.js create mode 100644 spec/runner.html create mode 100644 spec/session_spec.js create mode 100644 spec/signup_spec.js delete mode 100644 spec/specHelper.js delete mode 100644 src/plainXHR.js diff --git a/Readme.md b/Readme.md index bc80cd7..6c38a6b 100644 --- a/Readme.md +++ b/Readme.md @@ -1,8 +1,7 @@ -imported to github from: https://code.google.com/p/srp-js/ +originally imported to github from: https://code.google.com/p/srp-js/ License: [New BSD License](http://www.opensource.org/licenses/bsd-license.php) - Many websites today require some form of authentication to access the site's full functionality. Unfortunately, many of these websites do not use secure authentication protocols. In some cases, websites will store user passwords in their database. If the database ever becomes compromised, an attacker could authenticate as any user he wanted. @@ -15,6 +14,7 @@ The Secure Remote Password protocol addresses this problem. First presented by T This project aims to provide a strong javascript implementation of SRP that will provide some peace of mind when using websites that do not use HTTPS. Due to the nature of HTTP, it is not invulnerable to man-in-the-middle attacks, but it should provide strong security against passive eavesdroppers, which are increasingly common in the age of wireless internet. -To accompany the Javascript implementation of the client, the [original repository](https://code.google.com/p/srp-js/) had a django server. +[ruby-srp](https://github.com/leapcode/ruby-srp) contains client and server implementations in ruby that work with the current version of srp-js. It also ships an example using srp-js as the client. + +The [original repository](https://code.google.com/p/srp-js/) had code working with a django server. -[ruby-srp](https://github.com/leapcode/ruby-srp) contains client and server implementations in ruby that work with srp-js. It also ships an example using srp-js as the client. diff --git a/spec/DjangoSpecRunner.html b/spec/DjangoSpecRunner.html deleted file mode 100644 index 5920745..0000000 --- a/spec/DjangoSpecRunner.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - Jasmine Spec Runner - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - -
Username:
Password:
- -
- - diff --git a/spec/RestfulSpecRunner.html b/spec/RestfulSpecRunner.html deleted file mode 100644 index f880720..0000000 --- a/spec/RestfulSpecRunner.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - Jasmine Spec Runner - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
Username:
Password:
- -
- - diff --git a/spec/django/login.js b/spec/django/login.js deleted file mode 100644 index d13f695..0000000 --- a/spec/django/login.js +++ /dev/null @@ -1,69 +0,0 @@ -describe("Login", function() { - - it("has an identify function", function() { - var srp = new SRP(); - expect(typeof srp.identify).toBe('function'); - }); - - describe("(INTEGRATION)", function (){ - // a valid auth attempt for the user / password given in the spec runner: - var a = 'af141ae6'; - var B = '887005895b1f5528b4e4dfdce914f73e763b96d3c901d2f41d8b8cd26255a75'; - var salt = '5d3055e0acd3ddcfc15'; - var M = 'be6d7db2186d5f6a2c55788479b6eaf75229a7ca0d9e7dc1f886f1970a0e8065' - var M2 = '2547cf26318519090f506ab73a68995a2626b1c948e6f603ef9e1b0b78bf0f7b'; - var A, callback; - - - beforeEach(function() { - var srp = new SRP(); - var session = new srp.Session(); - this.srp = new SRP(null, session) - A = session.calculateAndSetA(a); - - specHelper.setupFakeXHR.apply(this); - - this.srp.success = sinon.spy(); - }); - - afterEach(function() { - this.xhr.restore(); - }); - - it("works with XML responses", function(){ - this.srp.identify(); - - this.expectRequest('handshake/', 'I=user&A='+A); - this.respondXML(""); - this.expectRequest('authenticate/', 'M='+M); - this.respondXML(""+M2+""); - - expect(this.srp.success).toHaveBeenCalled(); - }); - - it("works with JSON responses", function(){ - this.srp.identify(); - - this.expectRequest('handshake/', 'I=user&A='+A); - this.respondJSON({s: salt, B: B}); - this.expectRequest('authenticate/', 'M='+M); - this.respondJSON({M: M2}); - - expect(this.srp.success).toHaveBeenCalled(); - }); - - it("rejects B = 0", function(){ - this.srp.error = sinon.spy(); - this.srp.identify(); - - this.expectRequest('handshake/', 'I=user&A='+A); - this.respondJSON({s: salt, B: 0}); - // aborting if B=0 - expect(this.requests).toEqual([]); - expect(this.srp.error).toHaveBeenCalled(); - }); - }); - - -}); - diff --git a/spec/django/signup.js b/spec/django/signup.js deleted file mode 100644 index 383dd14..0000000 --- a/spec/django/signup.js +++ /dev/null @@ -1,50 +0,0 @@ -describe("Signup", function() { - - beforeEach(function() { - this.srp = new SRP(); - specHelper.setupFakeXHR.apply(this); - }); - - afterEach(function() { - this.xhr.restore(); - }); - - it("has a register function", function() { - expect(typeof this.srp.register).toBe('function'); - }); - - it("receives the salt from /register/salt", function(){ - var callback = sinon.spy(); - this.srp.remote.sendVerifier = callback; - this.srp.register(); - this.expectRequest('register/salt/', "I=user") - this.respondXML("5d3055e0acd3ddcfc15"); - expect(callback).toHaveBeenCalledWith(this.srp.session, this.srp.registered_user); - }); - - it("identifies after successful registration (INTEGRATION)", function(){ - var callback = sinon.spy(); - this.srp.identify = callback; - this.srp.register(); - this.expectRequest('register/salt/', "I=user") - this.respondXML("5d3055e0acd3ddcfc15"); - this.expectRequest('register/user/', "v=adcd57b4a4a05c2e205b0b7b30014d9ff635d8d8db2f502f08e9b9c132800c44"); - this.respondXML(""); - expect(callback).toHaveBeenCalled(); - }); - - it("identifies after successful registration with JSON (INTEGRATION)", function(){ - var callback = sinon.spy(); - this.srp.identify = callback; - this.srp.register(); - this.expectRequest('register/salt/', "I=user") - this.respondJSON({salt: "5d3055e0acd3ddcfc15"}); - this.expectRequest('register/user/', "v=adcd57b4a4a05c2e205b0b7b30014d9ff635d8d8db2f502f08e9b9c132800c44"); - this.respondJSON({ok: true}); - expect(callback).toHaveBeenCalled(); - }); - - -}); - - diff --git a/spec/helper.js b/spec/helper.js new file mode 100644 index 0000000..11327af --- /dev/null +++ b/spec/helper.js @@ -0,0 +1,44 @@ +var specHelper = (function() { + // HELPERS + + function setupFakeXHR() { + this.xhr = sinon.useFakeXMLHttpRequest(); + var requests = this.requests = []; + this.xhr.onCreate = function (xhr) { + requests.push(xhr); + }; + this.expectRequest = expectRequest; + this.respondJSON = respondJSON; + this.respondXML = respondXML; + } + + // TODO: validate http verb + function expectRequest(url, content, verb) { + expect(this.requests.length).toBe(1); + expect(this.requests[0].url).toBe(url); + expect(decodeURI(this.requests[0].requestBody)).toBe(content); + if (verb) { + expect(this.requests[0].method).toBe(verb); + } + } + + function respondXML(content) { + var request = this.requests.pop(); + header = { "Content-Type": "application/xml;charset=utf-8" }; + body = '\n'; + body += content; + request.respond(200, header, body); + } + + function respondJSON(object) { + var request = this.requests.pop(); + header = { "Content-Type": "application/json;charset=utf-8" }; + body = JSON.stringify(object); + request.respond(200, header, body); + } + + return { + setupFakeXHR: setupFakeXHR, + } + +})(); diff --git a/spec/login_spec.js b/spec/login_spec.js new file mode 100644 index 0000000..4df62a8 --- /dev/null +++ b/spec/login_spec.js @@ -0,0 +1,78 @@ +describe("Login", function() { + + it("has an identify function", function() { + var srp = new SRP(jqueryRest()); + expect(typeof srp.identify).toBe('function'); + }); + + describe("(Compatibility with py-srp)", function (){ + // these need to be the same as in the spec runner: + var login = "testuser"; + var password = "password"; + // a valid auth attempt for the user / password given in the spec runner: + var a = 'a5cccf937ea1bf72df5cf8099442552f5664da6780a75436d5a59bc77a8a9993'; + var A = 'e67d222244564ccd2e37471f226b999a4e987f3d494c7d80e0d36169efd6c6c6d857a96924c25fc165e5e9b0212a31c30701ec376dc32e36be00bbcd6d2104789d368af984e26fc094374f90ee5746478f14cec45c7e131a3cbce15fe79e98894213dac4e63c3f73f644fe25aa8707bc58859dfd1b36972e4e34169db2622899'; + // just for the sake of having a complete set of test vars: + var b = '6aa5c88d1877af9907ccefad31083e1102a7121dc04706f681f66c8680fb7f05'; + var B = 'd56a80aaafdf9f70598b5d1184f122f326a333fafd37ab76d6f7fba4a9c4ee59545be056335150bd64f04880bc8e76949469379fe9de17cf6f36f3ee11713d05f63050486bc73c545163169999ff01b55c0ca4e90d8856a6e3d3a6ffc70b70d993a5308a37a5c2399874344e083e72b3c9afa083d312dfe9096ea9a65023f135'; + var salt = '628365a0'; + var K = 'db6ec0bdab81742315861a828323ff492721bdcd114077a4124bc425e4bf328b'; + var M = '640e51d5ac5461591c31811221261f0e0eae7c08ce43c85e9556adbd94ed8c26'; + var M2 = '49e48f8ac8c4da0e8a7374f73eeedbee2266e123d23fc1be1568523fc9c24b1e'; + var V = '6f5fb78184161f4191babaf1a700ff70e4d261054d002466d05f2ec2b45fc8807dbd7ce25dc3c882331eb8bf72a22caf2868e3438477be7ab151d3281d00aa1a9fc5cb6a725abd99e11882f77d52b56b83f95c0ba0b8fbbf4ee1fbb445c35adb5d1aaa48ba761c4a4417f6bb821fb61956c919e47740b316b960653303fe7190'; + var A_, callback; + + + beforeEach(function() { + this.srp = new SRP(jqueryRest()); + + specHelper.setupFakeXHR.apply(this); + + A_ = this.srp.session.calculateAndSetA(a) + }); + + afterEach(function() { + this.xhr.restore(); + }); + + it("calculates the same A", function(){ + expect(A_).toBe(A); + }); + + it("calculates the same verifier", function(){ + expect(this.srp.session.getV().toString(16)).toBe(V); + }); + + it("calculates the same key", function(){ + this.srp.session.calculations(salt, B); + expect(this.srp.session.key()).toBe(K); + }); + + it("works with JSON responses", function(){ + var success = sinon.spy(); + this.srp.identify(success); + + this.expectRequest('sessions.json', 'login=' +login+ '&A=' +A, 'POST'); + this.respondJSON({salt: salt, B: B}); + this.expectRequest('sessions/'+login+'.json', 'client_auth='+M, 'PUT'); + this.respondJSON({M2: M2}); + + expect(success).toHaveBeenCalled(); + }); + + it("rejects B = 0", function(){ + var success = sinon.spy(); + var error = sinon.spy(); + this.srp.identify(success, error); + + this.expectRequest('sessions.json', 'login=' +login+ '&A=' +A, 'POST'); + this.respondJSON({salt: salt, B: 0}); + // aborting if B=0 + expect(this.requests).toEqual([]); + expect(error).toHaveBeenCalled(); + expect(success).not.toHaveBeenCalled(); + }); + }); + + +}); diff --git a/spec/restful/login.js b/spec/restful/login.js deleted file mode 100644 index 4df62a8..0000000 --- a/spec/restful/login.js +++ /dev/null @@ -1,78 +0,0 @@ -describe("Login", function() { - - it("has an identify function", function() { - var srp = new SRP(jqueryRest()); - expect(typeof srp.identify).toBe('function'); - }); - - describe("(Compatibility with py-srp)", function (){ - // these need to be the same as in the spec runner: - var login = "testuser"; - var password = "password"; - // a valid auth attempt for the user / password given in the spec runner: - var a = 'a5cccf937ea1bf72df5cf8099442552f5664da6780a75436d5a59bc77a8a9993'; - var A = 'e67d222244564ccd2e37471f226b999a4e987f3d494c7d80e0d36169efd6c6c6d857a96924c25fc165e5e9b0212a31c30701ec376dc32e36be00bbcd6d2104789d368af984e26fc094374f90ee5746478f14cec45c7e131a3cbce15fe79e98894213dac4e63c3f73f644fe25aa8707bc58859dfd1b36972e4e34169db2622899'; - // just for the sake of having a complete set of test vars: - var b = '6aa5c88d1877af9907ccefad31083e1102a7121dc04706f681f66c8680fb7f05'; - var B = 'd56a80aaafdf9f70598b5d1184f122f326a333fafd37ab76d6f7fba4a9c4ee59545be056335150bd64f04880bc8e76949469379fe9de17cf6f36f3ee11713d05f63050486bc73c545163169999ff01b55c0ca4e90d8856a6e3d3a6ffc70b70d993a5308a37a5c2399874344e083e72b3c9afa083d312dfe9096ea9a65023f135'; - var salt = '628365a0'; - var K = 'db6ec0bdab81742315861a828323ff492721bdcd114077a4124bc425e4bf328b'; - var M = '640e51d5ac5461591c31811221261f0e0eae7c08ce43c85e9556adbd94ed8c26'; - var M2 = '49e48f8ac8c4da0e8a7374f73eeedbee2266e123d23fc1be1568523fc9c24b1e'; - var V = '6f5fb78184161f4191babaf1a700ff70e4d261054d002466d05f2ec2b45fc8807dbd7ce25dc3c882331eb8bf72a22caf2868e3438477be7ab151d3281d00aa1a9fc5cb6a725abd99e11882f77d52b56b83f95c0ba0b8fbbf4ee1fbb445c35adb5d1aaa48ba761c4a4417f6bb821fb61956c919e47740b316b960653303fe7190'; - var A_, callback; - - - beforeEach(function() { - this.srp = new SRP(jqueryRest()); - - specHelper.setupFakeXHR.apply(this); - - A_ = this.srp.session.calculateAndSetA(a) - }); - - afterEach(function() { - this.xhr.restore(); - }); - - it("calculates the same A", function(){ - expect(A_).toBe(A); - }); - - it("calculates the same verifier", function(){ - expect(this.srp.session.getV().toString(16)).toBe(V); - }); - - it("calculates the same key", function(){ - this.srp.session.calculations(salt, B); - expect(this.srp.session.key()).toBe(K); - }); - - it("works with JSON responses", function(){ - var success = sinon.spy(); - this.srp.identify(success); - - this.expectRequest('sessions.json', 'login=' +login+ '&A=' +A, 'POST'); - this.respondJSON({salt: salt, B: B}); - this.expectRequest('sessions/'+login+'.json', 'client_auth='+M, 'PUT'); - this.respondJSON({M2: M2}); - - expect(success).toHaveBeenCalled(); - }); - - it("rejects B = 0", function(){ - var success = sinon.spy(); - var error = sinon.spy(); - this.srp.identify(success, error); - - this.expectRequest('sessions.json', 'login=' +login+ '&A=' +A, 'POST'); - this.respondJSON({salt: salt, B: 0}); - // aborting if B=0 - expect(this.requests).toEqual([]); - expect(error).toHaveBeenCalled(); - expect(success).not.toHaveBeenCalled(); - }); - }); - - -}); diff --git a/spec/restful/session.js b/spec/restful/session.js deleted file mode 100644 index b7f16f0..0000000 --- a/spec/restful/session.js +++ /dev/null @@ -1,39 +0,0 @@ -describe("Session", function() { - - // data gathered from py-srp and ruby-srp - var compare = { - username: "UC6LTQ", - password: "PVSQ7DCEIR0B", - salt: "d6ed8dba", - v: "c86a8c04a4f71cb10bfe3fedb74bae545b9a20e0f3e95b6334fce1cb3384a296f75d774a3829ffd63f405f13f58ffbae415fd234b08b996c11e8618c17961defcebb1d244b388b75cf36882ee97182a900ebeaf7cffa0a83eed294f3a9449a06beb88954952759d2957b80ef851f4cc4fcaa6001fee4f00c273ecdd712d48371", - aa: "4decb8543891f5a744b1e9b5bc375a474bfe3c5417e1db176cefcc7ba915338a14f309f8e0a4c7641bc9c9b9bd2e91c4d1beda1772c30d0350c9ba44f7c5911dfe6bb593ac2a2b30f1f6e5ec8a656cb4947c1907cf62f8d7283cbe32eb44b02158b51091ae130afa6063bb28cdea9ae159d4f222571e146f8715bfa31af09868", - a: "d498c3d024ec17689b5320e33fc349a3f3f91320384155b3043fa410c90eab71", - bb: "5f5bedd1f95b6b0d6809614f162e49753acce6979e1041f4da5bfa91e1dadd2a5470270ed102a49c5f74fd42f2b61a8a1a43218159a22b31a7cbd4670679480e56d0e4e72a22c07e07102ff063045d0c3c96085dec1cc2959453e0299890bd95af76403cec6ec5f212667a75ae6f4a8327183d72c3ee85792ca43820fbccf244", - m: "bc30b8781e67a657e93d0a6cf7e7847fc60f79e2b0641e9c26b3522bc8f974cc" - } - - var session; - - beforeEach(function() { - var srp = new SRP(jqueryRest()); - session = new srp.Session(compare.username, compare.password); - }); - - it("has the proper username", function() { - expect(session.getI()).toBe(compare.username); - }); - - it("calculates the proper verifier", function() { - expect(session.getV(compare.salt).toString(16)).toBe(compare.v); - }); - - it("calculates the proper A", function() { - expect(session.calculateAndSetA(compare.a)).toBe(compare.aa); - }); - - it("calculates the proper M", function() { - session.calculateAndSetA(compare.a); - session.calculations(compare.salt, compare.bb); - expect(session.getM()).toBe(compare.m); - }); -}); diff --git a/spec/restful/signup.js b/spec/restful/signup.js deleted file mode 100644 index e4d70df..0000000 --- a/spec/restful/signup.js +++ /dev/null @@ -1,32 +0,0 @@ -describe("Signup", function() { - - beforeEach(function() { - this.srp = new SRP(jqueryRest()); - specHelper.setupFakeXHR.apply(this); - }); - - afterEach(function() { - this.xhr.restore(); - }); - - it("has a register function", function() { - expect(typeof this.srp.register).toBe('function'); - }); - - it("calculates the right x", function(){ - expect(this.srp.session.calcX("7686acb8").toString(16)).toBe('84d6bb567ddf584b1d8c8728289644d45dbfbb02deedd05c0f64db96740f0398'); - }); - - it("identifies after successful registration (INTEGRATION)", function(){ - var callback = sinon.spy(); - this.srp.identify = callback; - this.srp.session.getSalt = function() {return "4c78c3f8"}; - this.srp.register(); - this.expectRequest('users.json', "user[login]=testuser&user[password_salt]=4c78c3f8&user[password_verifier]=474c26aa42d11f20544a00f7bf9711c4b5cf7aab95ed448df82b95521b96668e7480b16efce81c861870302560ddf6604c67df54f1d04b99d5bb9d0f02c6051ada5dc9d594f0d4314e12f876cfca3dcd99fc9c98c2e6a5e04298b11061fb8549a22cde0564e91514080df79bca1c38c682214d65d590f66b3719f954b078b83c", 'POST') - this.respondJSON({password_salt: "4c78c3f8", login: "testuser", ok: "true"}); - expect(callback).toHaveBeenCalled(); - }); - -}); - - diff --git a/spec/runner.html b/spec/runner.html new file mode 100644 index 0000000..5f4727c --- /dev/null +++ b/spec/runner.html @@ -0,0 +1,75 @@ + + + + + Jasmine Spec Runner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
Username:
Password:
+ +
+ + diff --git a/spec/session_spec.js b/spec/session_spec.js new file mode 100644 index 0000000..b7f16f0 --- /dev/null +++ b/spec/session_spec.js @@ -0,0 +1,39 @@ +describe("Session", function() { + + // data gathered from py-srp and ruby-srp + var compare = { + username: "UC6LTQ", + password: "PVSQ7DCEIR0B", + salt: "d6ed8dba", + v: "c86a8c04a4f71cb10bfe3fedb74bae545b9a20e0f3e95b6334fce1cb3384a296f75d774a3829ffd63f405f13f58ffbae415fd234b08b996c11e8618c17961defcebb1d244b388b75cf36882ee97182a900ebeaf7cffa0a83eed294f3a9449a06beb88954952759d2957b80ef851f4cc4fcaa6001fee4f00c273ecdd712d48371", + aa: "4decb8543891f5a744b1e9b5bc375a474bfe3c5417e1db176cefcc7ba915338a14f309f8e0a4c7641bc9c9b9bd2e91c4d1beda1772c30d0350c9ba44f7c5911dfe6bb593ac2a2b30f1f6e5ec8a656cb4947c1907cf62f8d7283cbe32eb44b02158b51091ae130afa6063bb28cdea9ae159d4f222571e146f8715bfa31af09868", + a: "d498c3d024ec17689b5320e33fc349a3f3f91320384155b3043fa410c90eab71", + bb: "5f5bedd1f95b6b0d6809614f162e49753acce6979e1041f4da5bfa91e1dadd2a5470270ed102a49c5f74fd42f2b61a8a1a43218159a22b31a7cbd4670679480e56d0e4e72a22c07e07102ff063045d0c3c96085dec1cc2959453e0299890bd95af76403cec6ec5f212667a75ae6f4a8327183d72c3ee85792ca43820fbccf244", + m: "bc30b8781e67a657e93d0a6cf7e7847fc60f79e2b0641e9c26b3522bc8f974cc" + } + + var session; + + beforeEach(function() { + var srp = new SRP(jqueryRest()); + session = new srp.Session(compare.username, compare.password); + }); + + it("has the proper username", function() { + expect(session.getI()).toBe(compare.username); + }); + + it("calculates the proper verifier", function() { + expect(session.getV(compare.salt).toString(16)).toBe(compare.v); + }); + + it("calculates the proper A", function() { + expect(session.calculateAndSetA(compare.a)).toBe(compare.aa); + }); + + it("calculates the proper M", function() { + session.calculateAndSetA(compare.a); + session.calculations(compare.salt, compare.bb); + expect(session.getM()).toBe(compare.m); + }); +}); diff --git a/spec/signup_spec.js b/spec/signup_spec.js new file mode 100644 index 0000000..e4d70df --- /dev/null +++ b/spec/signup_spec.js @@ -0,0 +1,32 @@ +describe("Signup", function() { + + beforeEach(function() { + this.srp = new SRP(jqueryRest()); + specHelper.setupFakeXHR.apply(this); + }); + + afterEach(function() { + this.xhr.restore(); + }); + + it("has a register function", function() { + expect(typeof this.srp.register).toBe('function'); + }); + + it("calculates the right x", function(){ + expect(this.srp.session.calcX("7686acb8").toString(16)).toBe('84d6bb567ddf584b1d8c8728289644d45dbfbb02deedd05c0f64db96740f0398'); + }); + + it("identifies after successful registration (INTEGRATION)", function(){ + var callback = sinon.spy(); + this.srp.identify = callback; + this.srp.session.getSalt = function() {return "4c78c3f8"}; + this.srp.register(); + this.expectRequest('users.json', "user[login]=testuser&user[password_salt]=4c78c3f8&user[password_verifier]=474c26aa42d11f20544a00f7bf9711c4b5cf7aab95ed448df82b95521b96668e7480b16efce81c861870302560ddf6604c67df54f1d04b99d5bb9d0f02c6051ada5dc9d594f0d4314e12f876cfca3dcd99fc9c98c2e6a5e04298b11061fb8549a22cde0564e91514080df79bca1c38c682214d65d590f66b3719f954b078b83c", 'POST') + this.respondJSON({password_salt: "4c78c3f8", login: "testuser", ok: "true"}); + expect(callback).toHaveBeenCalled(); + }); + +}); + + diff --git a/spec/specHelper.js b/spec/specHelper.js deleted file mode 100644 index 11327af..0000000 --- a/spec/specHelper.js +++ /dev/null @@ -1,44 +0,0 @@ -var specHelper = (function() { - // HELPERS - - function setupFakeXHR() { - this.xhr = sinon.useFakeXMLHttpRequest(); - var requests = this.requests = []; - this.xhr.onCreate = function (xhr) { - requests.push(xhr); - }; - this.expectRequest = expectRequest; - this.respondJSON = respondJSON; - this.respondXML = respondXML; - } - - // TODO: validate http verb - function expectRequest(url, content, verb) { - expect(this.requests.length).toBe(1); - expect(this.requests[0].url).toBe(url); - expect(decodeURI(this.requests[0].requestBody)).toBe(content); - if (verb) { - expect(this.requests[0].method).toBe(verb); - } - } - - function respondXML(content) { - var request = this.requests.pop(); - header = { "Content-Type": "application/xml;charset=utf-8" }; - body = '\n'; - body += content; - request.respond(200, header, body); - } - - function respondJSON(object) { - var request = this.requests.pop(); - header = { "Content-Type": "application/json;charset=utf-8" }; - body = JSON.stringify(object); - request.respond(200, header, body); - } - - return { - setupFakeXHR: setupFakeXHR, - } - -})(); diff --git a/src/plainXHR.js b/src/plainXHR.js deleted file mode 100644 index c03c90a..0000000 --- a/src/plainXHR.js +++ /dev/null @@ -1,120 +0,0 @@ -// -// SRP JS - Plain XHR module -// -// This is deprecated - unless you are using srp-js with the original drupal -// server side I recommend you use a different API such as restful.js -// -// This code has been largely refactored, tests are still passing but I did -// not test it with the server itself. - -SRP.prototype.Remote = function() { - - // Perform ajax requests at the specified path, with the specified parameters - // Calling back the specified function. - function ajaxRequest(url, params, callback) - { - if( window.XMLHttpRequest) { - xhr = new XMLHttpRequest(); - } - else if (window.ActiveXObject){ - try{ - xhr = new ActiveXObject("Microsoft.XMLHTTP"); - }catch (e){} - } - else - { - session.error_message("Ajax not supported."); - return; - } - if(xhr){ - xhr.onreadystatechange = function() { - if(xhr.readyState == 4 && xhr.status == 200) { - callback(parseResponse()); - } - }; - xhr.open("POST", url, true); - xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); - xhr.setRequestHeader("Content-length", params.length); - xhr.send(params); - } - else - { - session.error_message("Ajax failed."); - } - } - - function parseResponse() { - if (responseIsXML()) { - return parseXML(xhr.responseXML); - } else if (responseIsJSON()) { - return JSON.parse(xhr.responseText); - } - } - - function responseIsXML() { - return (xhr.responseType == 'document') || - (xhr.getResponseHeader("Content-Type").indexOf('application/xml') >= 0); - } - - function responseIsJSON() { - return (xhr.responseType == 'json') || - (xhr.getResponseHeader("Content-Type").indexOf('application/json') >= 0); - } - - function parseXML(xml) { - if (xml.getElementsByTagName("r").length > 0) { - return parseAttributesOfElement(xml.getElementsByTagName("r")[0]); - } else { - return parseNodes(xml.childNodes); - } - } - - function parseAttributesOfElement(elem) { - var response = {}; - for (var i = 0; i < elem.attributes.length; i++) { - var attrib = elem.attributes[i]; - if (attrib.specified) { - response[attrib.name] = attrib.value; - } - } - return response; - } - - function parseNodes(nodes) { - var response = {}; - for (var i = 0; i < nodes.length; i++) { - var node = nodes[i]; - response[node.tagName] = node.textContent || true; - } - return response; - } - - // Drupal version fetches the salt from the server. No idea why but this - // should still do it. - this.register = function(session, callback) - { - function receive_salt(response) { - if(response.salt) - { - var s = response.salt; - var v = session.getV(s); - that.sendVerifier(session, callback); - } - } - - var that = this; - ajaxRequest("register/salt/", "I="+session.getI(), receive_salt); - }; - - this.sendVerifier = function(session, callback) { - ajaxRequest("register/user/", "v="+session.getV().toString(16), callback); - }; - - this.handshake = function(session, callback) { - ajaxRequest("handshake/", "I="+session.getI()+"&A="+session.getAstr(), callback); - }; - - this.authenticate = function(session, callback) { - ajaxRequest("authenticate/", "M="+session.getM(), callback); - }; -}; -- cgit v1.2.3