Add authenticate with access number and example
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/aad05593 Tree: http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-js-lib/tree/aad05593 Diff: http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-js-lib/diff/aad05593 Branch: refs/heads/add-documentation Commit: aad05593a02d76c3eedfa64d1d679f51ac37e2ef Parents: 181a7fe Author: Boyan Bakov <[email protected]> Authored: Fri Mar 11 16:13:13 2016 +0200 Committer: Boyan Bakov <[email protected]> Committed: Mon Mar 14 11:59:08 2016 +0200 ---------------------------------------------------------------------- example/exampleJquery.html | 41 +++++++++++++-- lib/mpin.js | 111 +++++++++++++++++++++++++++++++++++----- 2 files changed, 135 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-js-lib/blob/aad05593/example/exampleJquery.html ---------------------------------------------------------------------- diff --git a/example/exampleJquery.html b/example/exampleJquery.html index cf86013..c9459c1 100644 --- a/example/exampleJquery.html +++ b/example/exampleJquery.html @@ -11,11 +11,11 @@ and open the template in the editor. <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="../dist/mpinjs.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js" type="text/javascript"></script> - + <style> fieldset { margin: 0 auto; - width: 30%; + width: 50%; } .notActivate { @@ -50,9 +50,11 @@ and open the template in the editor. htmlList = "<ul>"; for (var i in mpinUsers) { htmlList += "<li>" + mpinUsers[i].userId + " "; - htmlList += "<input type='text' placeholder='PIN' size='10'> "; + htmlList += "<input type='text' placeholder='PIN' size='10' class='userPin'> "; if (mpinUsers[i].state === "REGISTERED") { htmlList += "<span class='registered' data-userid='" + mpinUsers[i].userId + "' data-state='" + mpinUsers[i].state + "'>Authenticate</span>"; + htmlList += "<div style='float: right'><input type='text' placeholder='Access Number' size='10' class='userAN'> "; + htmlList += "<span class='auth-accnumber' data-userid='" + mpinUsers[i].userId + "'>Authenticate(AN)</span></div>"; } else { htmlList += "<span class='setup' data-userid='" + mpinUsers[i].userId + "' data-state='" + mpinUsers[i].state + "'>Setup</span>"; } @@ -96,7 +98,7 @@ and open the template in the editor. $(document).on('click', ".registered", function (ev) { var userId, userPin, state; userId = $(ev.currentTarget).data('userid'); - userPin = $(ev.currentTarget).prev("input").val(); + userPin = $(ev.currentTarget).prev("input.userPin").val(); state = $(ev.currentTarget).data('state'); mpin.startAuthentication(userId, function (err, data) { @@ -117,6 +119,37 @@ and open the template in the editor. }); + $(document).on('click', ".auth-accnumber", function (ev) { + var userId, userPin, userAN; + userId = $(ev.currentTarget).data('userid'); + userPin = $(ev.currentTarget).parent("li").find("input.userPin").val(); + userAN = $(ev.currentTarget).prev("input.userAN").val(); + + if (!mpin.checkAccessNumber(userAN)) { + $(".errAccessNumber").remove(); + $(ev.currentTarget).prepend("<span style='color: red' class='errAccessNumber'>Invalid Access Number</span>"); + return; + } + + mpin.startAuthentication(userId, function (err, data) { + if (err) { + console.error("Error :::", err); + return; + } + mpin.finishAuthenticationAN(userId, userPin, userAN, function (err2, data2) { + if (err2) { + console.error("Error :::", err2); + return; + } + + $(ev.currentTarget).append(" :: Successful"); + }); + }); + }); + + + + $("#regButton").click(function (ev) { var usrId; usrId = $("#mpinUsrId").val(); http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-js-lib/blob/aad05593/lib/mpin.js ---------------------------------------------------------------------- diff --git a/lib/mpin.js b/lib/mpin.js index 0b9db1f..e2c2433 100644 --- a/lib/mpin.js +++ b/lib/mpin.js @@ -332,7 +332,7 @@ var mpinjs = (function () { }; - Mpin.prototype.finishAuthentication = function (userId, aPin, cb) { + Mpin.prototype.finishAuthentication = function (userId, pin, cb) { var _userState; //registered @@ -343,10 +343,10 @@ 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); + this._passRequests({userId: userId, pin: pin}, cb); }; - Mpin.prototype.finishAuthenticationOtp = function (userId, aPin, cb) { + Mpin.prototype.finishAuthenticationOtp = function (userId, pin, cb) { var _userState; //registered @@ -357,7 +357,35 @@ 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, otp: true}, function (err, data) { + this._passRequests({userId: userId, pin: pin, 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.finishAuthenticationAN = function (userId, pin, accessNumber, cb) { + var _userState; + + //registered + _userState = this.getUser(userId, "state"); + if (_userState !== States.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, pin: pin, accessNumber: accessNumber.toString()}, function (err, data) { if (err) { return cb(err, null); } @@ -375,23 +403,25 @@ var mpinjs = (function () { }; Mpin.prototype._passRequests = function (opts, cb) { - var userId, aPin, otp, self = this, _reqData = {}; + var userId, pin, otp, accessNumber, self = this, _reqData = {}; userId = opts.userId; - aPin = opts.aPin; + pin = opts.pin; otp = opts.otp || false; + accessNumber = opts.accessNumber || false; _reqData.url = this.generateUrl("pass1"); _reqData.type = "POST"; - _reqData.data = this.getAuthData(userId, aPin); + _reqData.data = this.getAuthData(userId, pin); // pass1 this.request(_reqData, function (pass1Err, pass1Data) { - var _req2Data = {}; + var _req2Data = {}, wid = "0"; _req2Data.url = self.generateUrl("pass2"); _req2Data.type = "POST"; - _req2Data.data = MPINAuth.pass2Request(pass1Data.y, otp, "0"); + accessNumber && (wid = accessNumber); + _req2Data.data = MPINAuth.pass2Request(pass1Data.y, otp, wid); _req2Data.data.mpin_id = Users[userId].mpinId; @@ -408,7 +438,7 @@ var mpinjs = (function () { delete pass2Data["OTP"]; } - self._authenticate({userId: userId, mpinResponse: pass2Data, otpCode: otpCode}, cb); + self._authenticate({userId: userId, mpinResponse: pass2Data, otpCode: otpCode, accessNumber: accessNumber}, cb); }); }); @@ -417,7 +447,12 @@ var mpinjs = (function () { Mpin.prototype._authenticate = function (opts, cb) { var _authData = {}, self = this; - _authData.url = this.generateUrl("auth"); + if (opts.accessNumber) { + _authData.url = this.generateUrl("mobileauth"); + } else { + _authData.url = this.generateUrl("auth"); + } + _authData.type = "POST"; _authData.data = {mpinResponse: opts.mpinResponse}; @@ -447,8 +482,55 @@ var mpinjs = (function () { }); }; + Mpin.prototype.checkAccessNumber = function (accessNumber) { + accessNumber = accessNumber.toString(); + if (!this.settings.accessNumberUseCheckSum || accessNumber.length != this.settings.accessNumberDigits) { + return true; + } else { + if (this.settings.cSum === 1) { + return this.checkAccessNumberSum2(accessNumber, 6); + } else { + return this.checkAccessNumberSum(accessNumber); + } + } + }; + + Mpin.prototype.checkAccessNumberSum = function (accNumber, accLen) { + accLen || (accLen = 1); + + var n = parseInt(accNumber.slice(0, accNumber.length - accLen), 10); + var cSum = parseInt(accNumber.slice(accNumber.length - accLen, accNumber.length), 10); + + var p = 99991; + var g = 11; + var checkSum = ((n * g) % p) % Math.pow(10, accLen); - Mpin.prototype.getAuthData = function (userId, aPin) { + return (checkSum === cSum); + }; + + Mpin.prototype.checkAccessNumberSum2 = function (accNumber, accLen) { + var cSum, checksum, x, w, wid, wid_len, g = 11, sum_d = 0; + wid = accNumber.toString(); + wid = wid.substring(0, accNumber.toString().length - 1); + w = accLen + 1; + sum_d = 0; + wid_len = wid.length; + + for (var i = 0; i < wid_len; i++) { + x = parseInt(wid[i]); + sum_d += (x * w); + w -= 1; + } + checksum = (g - (sum_d % g)) % g; + checksum = (checksum === 10) ? 0 : checksum; + + //get last one digit and compare with checksum result + cSum = accNumber.substr(-1); + cSum = parseInt(cSum); + return (cSum === checksum); + }; + + Mpin.prototype.getAuthData = function (userId, pin) { var _auth = {}; _auth.mpin = Users[userId].mpinId; @@ -456,7 +538,7 @@ var mpinjs = (function () { _auth.timePermit = Users[userId].timePermitHex; _auth.date = Users[userId].currentDate; - return MPINAuth.pass1Request(_auth.mpin, _auth.token, _auth.timePermit, aPin, _auth.date, null); + return MPINAuth.pass1Request(_auth.mpin, _auth.token, _auth.timePermit, pin, _auth.date, null); }; Mpin.prototype.fromHex = function (strData) { @@ -587,6 +669,9 @@ var mpinjs = (function () { case "auth": url = this.settings.authenticateURL; break; + case "mobileauth": + url = this.settings.mobileAuthenticateURL; + break; case "getnumber": url = this.settings.getAccessNumberURL; break;
