Add otp auth flow
Project: http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-js-lib/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-js-lib/commit/f2726680 Tree: http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-js-lib/tree/f2726680 Diff: http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-js-lib/diff/f2726680 Branch: refs/heads/add-documentation Commit: f272668080dc8fe4878ae667b56593fda1e02a53 Parents: b376277 Author: Boyan Bakov <[email protected]> Authored: Fri Dec 18 15:45:16 2015 +0200 Committer: Vladislav Mitov <[email protected]> Committed: Fri Dec 18 18:55:25 2015 +0200 ---------------------------------------------------------------------- example/exampleJquery.html | 2 +- lib/mpin.js | 126 ++++++++++++++++++++++++++++------------ 2 files changed, 90 insertions(+), 38 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-js-lib/blob/f2726680/example/exampleJquery.html ---------------------------------------------------------------------- diff --git a/example/exampleJquery.html b/example/exampleJquery.html index b8826cb..de1b29e 100644 --- a/example/exampleJquery.html +++ b/example/exampleJquery.html @@ -33,7 +33,7 @@ and open the template in the editor. //// MPIN init window.mpin = mpin = new mpinjs({ - server: "http://192.168.10.63:8005" + server: "http://ssodemo.certivox.com" }); mpin.init(function (err, data) { http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-js-lib/blob/f2726680/lib/mpin.js ---------------------------------------------------------------------- diff --git a/lib/mpin.js b/lib/mpin.js index 39e73bf..7db5fd7 100644 --- a/lib/mpin.js +++ b/lib/mpin.js @@ -6,9 +6,9 @@ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -50,8 +50,13 @@ var mpinjs = (function () { Mpin.prototype.init = function (cb) { var self = this, _initUrl; - _initUrl = this.opts.server; - _initUrl += this.opts.rpsPrefix || "/rps/clientSettings"; + if (this.opts.server.slice(-1) === "/") { + _initUrl = this.opts.server; + } else { + _initUrl = this.opts.server + "/"; + } + _initUrl += this.opts.rpsPrefix || "rps"; + _initUrl += "/clientSettings"; this.request({url: _initUrl}, function (err, data) { if (err && cb) { @@ -175,6 +180,8 @@ var mpinjs = (function () { } token = MPINAuth.calculateMPinToken(Users[userId].mpinId, pin, Users[userId].csHex); + delete Users[userId].csHex; + this.addToUser(userId, {token: token, status: Status.register}); return true; @@ -217,7 +224,7 @@ var mpinjs = (function () { _tp2Url = self.generateUrl('permit2', {userId: userId}); _tp2Url += "&signature=" + _signature; - //check cache if exist + //check cache if exist if (Users[userId].timePermitCache && Users[userId].timePermitCache.date === data.date) { var _timePermit2 = Users[userId].timePermitCache.timePermit; var timePermitHex = MPINAuth.addShares(_timePermit1, _timePermit2); @@ -263,7 +270,7 @@ var mpinjs = (function () { Mpin.prototype.finishAuthentication = function (userId, aPin, cb) { - var self = this, _reqData = {}, _userStatus; + var _userStatus; //registered _userStatus = this.getUser(userId, "status"); @@ -273,6 +280,44 @@ var mpinjs = (function () { return cb({code: Errors.wrongFlow.code, type: Errors.wrongFlow.type, message: "Need to call startAuthentication method before this."}, null); } + this._passRequests({userId: userId, aPin: aPin}, cb); + }; + + Mpin.prototype.finishAuthenticationOtp = function (userId, aPin, cb) { + var _userStatus; + + //registered + _userStatus = this.getUser(userId, "status"); + if (_userStatus !== Status.register) { + return cb(Errors.wrongFlow, null); + } else if (!Users[userId].timePermitHex) { + return cb({code: Errors.wrongFlow.code, type: Errors.wrongFlow.type, message: "Need to call startAuthentication method before this."}, null); + } + + this._passRequests({userId: userId, aPin: aPin, otp: true}, function (err, data) { + if (err) { + return cb(err, null); + } + + if (!data.expireTime || !data.ttlSeconds || !data.nowTime) { + return cb(null, null); + } + + data.expireTime = data.expireTime / 1000; + data.nowTime = data.nowTime / 1000; + + cb(null, data); + }); + + }; + + Mpin.prototype._passRequests = function (opts, cb) { + var userId, aPin, otp, self = this, _reqData = {}; + userId = opts.userId; + aPin = opts.aPin; + + otp = opts.otp || false; + _reqData.url = this.generateUrl("pass1"); _reqData.type = "POST"; _reqData.data = this.getAuthData(userId, aPin); @@ -283,42 +328,57 @@ var mpinjs = (function () { _req2Data.url = self.generateUrl("pass2"); _req2Data.type = "POST"; - _req2Data.data = MPINAuth.pass2Request(pass1Data.y, false, "0"); + _req2Data.data = MPINAuth.pass2Request(pass1Data.y, otp, "0"); + _req2Data.data.mpin_id = Users[userId].mpinId; // pass 2 self.request(_req2Data, function (pass2Err, pass2Data) { - var _req3Data = {}; + var otpCode; if (pass2Err) { return cb(pass2Err, null); } + otpCode = pass2Data["OTP"] || false; + if (pass2Data && pass2Data["OTP"]) { delete pass2Data["OTP"]; } - _req3Data.url = self.generateUrl("auth"); - _req3Data.type = "POST"; - _req3Data.data = {mpinResponse: pass2Data}; - - self.request(_req3Data, function (authErr, authData) { - if (authErr) { - if (authErr.status === 401) { - return cb(Errors.wrongPin, null); - } else if (authErr.status === 410) { - self.addToUser(userId, {status: Status.block}); - return cb(Errors.wrongPin, null); - } else { - return cb(Errors.wrongPin, null); - } - } - - cb && cb(null, authData || {}); - }); + self._authenticate({userId: userId, mpinResponse: pass2Data, otpCode: otpCode}, cb); }); }); + + }; + + Mpin.prototype._authenticate = function (opts, cb) { + var _authData = {}, self = this; + + _authData.url = this.generateUrl("auth"); + _authData.type = "POST"; + _authData.data = {mpinResponse: opts.mpinResponse}; + + this.request(_authData, function (authErr, authData) { + if (authErr) { + if (authErr.status === 401) { + return cb(Errors.wrongPin, null); + } else if (authErr.status === 410) { + opts.userId && self.addToUser(opts.userId, {status: Status.block}); + return cb(Errors.wrongPin, null); + } else { + return cb(Errors.wrongPin, null); + } + } + + if (opts.otpCode && authData) { + authData.otp = opts.otpCode; + } + + cb && cb(null, authData || null); + }); }; + Mpin.prototype.getAuthData = function (userId, aPin) { var _auth = {}; @@ -396,7 +456,7 @@ var mpinjs = (function () { } } - cb && cb(null, true); + self._authenticate({mpinResponse: data}, cb); }); }; @@ -513,12 +573,6 @@ var mpinjs = (function () { //store delete mpinData.accounts[delMpinId]; - //change default Identity - for (var mpinId in mpinData.accounts) { - mpinData.defaultIdentity = mpinId; - break; - } - this.storeData(mpinData); }; @@ -552,7 +606,6 @@ var mpinjs = (function () { if (!mpinData) { mpinData = { - defaultIdentity: "", version: "0.3", accounts: {} }; @@ -560,7 +613,6 @@ var mpinjs = (function () { //update Default Identity if (upData.mpinId) { - mpinData.defaultIdentity = upData.mpinId; mpinData.accounts[upData.mpinId] = {}; } @@ -633,7 +685,7 @@ var mpinjs = (function () { _url = options.url || ""; _type = options.type || "GET"; - _parseJson = jsonResponse || true; + _parseJson = (typeof jsonResponse !== "undefined") ? jsonResponse : true; _request.onreadystatechange = function () { if (_request.readyState === 4 && _request.status === 200) { @@ -665,4 +717,4 @@ var mpinjs = (function () { if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') module.exports = mpinjs; else - window.mpinjs = mpinjs; \ No newline at end of file + window.mpinjs = mpinjs;
