| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| 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 |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| */ |
| |
| var mpin = mpin || {}; |
| |
| (function() { |
| var lang = {}, hlp = {}; |
| var loader; |
| var IMAGES_PATH = "resources/templates/@@templatename/img/"; |
| |
| //CONSTRUCTOR |
| mpin = function(domID, options) { |
| var self = this; |
| |
| loader("js/handlebars.runtime.min.js", function() { |
| loader("js/mpin-all.min.js", function() { |
| loader("js/templates.js", function() { |
| var _options = {}; |
| if (!options.clientSettingsURL) { |
| return console.error("set client Settings"); |
| } |
| |
| //remove _ from global SCOPE |
| _options.client = options; |
| |
| self.ajax(options.clientSettingsURL, function(serverOptions) { |
| if(serverOptions.error === 500) { |
| |
| _options.server = ''; |
| document.getElementById(domID).innerHTML = mpin._.template(mpin.template['offline'], {}); |
| return; |
| } |
| _options.server = serverOptions; |
| self.initialize.call(self, domID, _options); |
| }); |
| }); |
| }); |
| }); |
| |
| }; |
| |
| //CONFIGS |
| mpin.cfg = { |
| // apiVersion: "v0.3", |
| // apiUrl: "https://m-pinapi.certivox.net/", |
| // apiUrl: "http://dtatest.certivox.me/", |
| language: "en", |
| pinSize: 4, |
| requiredOptions: "appID; signatureURL; mpinAuthServerURL; timePermitsURL; seedValue", |
| defaultOptions: { |
| identityCheckRegex: /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, |
| setDeviceName: false, |
| accessNumberUseCheckSum: true |
| }, |
| expireOtpSeconds: 99, |
| touchevents: true |
| }; |
| |
| /** |
| * Mpin Constructor |
| * |
| * @param {type} domID PinPad element ID |
| * @param {type} options |
| * |
| * @returns {Boolean} |
| */ |
| mpin.prototype.initialize = function(domID, options) { |
| this.el = document.getElementById(domID); |
| this.elHelp = document.getElementById('helpContainer'); |
| this.elHelpOverlay = document.getElementsByTagName("help")[0]; |
| this.elHelpHub = document.getElementsByTagName("helpHub")[0]; |
| this.accessNumber = ""; |
| this.currentDate = null; |
| |
| // Register handlebars helper |
| |
| Handlebars.registerHelper("hlp", function(optionalValue) { |
| return hlp.text(optionalValue); |
| }); |
| |
| Handlebars.registerHelper("img", function(imgSrc) { |
| return hlp.img(imgSrc); |
| }); |
| |
| Handlebars.registerHelper("loop", function (n, block) { |
| var accum = ''; |
| for (var i = 0; i < n; ++i) |
| accum += block.fn(i); |
| return accum; |
| }); |
| |
| //options CHECK |
| if (!options || !this.checkOptions(options.server)) { |
| return console.error("Some options are required: " + mpin.cfg.requiredOptions); |
| } |
| |
| //Extend string with extra methods |
| setStringOptions(); |
| |
| //data Source |
| this.ds = this.dataSource(); |
| |
| //set Options |
| this.setDefaults().setOptions(options.server).setOptions(options.client); |
| |
| |
| if (!this.opts.certivoxURL.mpin_endsWith("/")) { |
| this.opts.certivoxURL += "/"; |
| } |
| |
| //if set & exist |
| if (this.opts.language && lang[this.opts.language]) { |
| this.language = this.opts.language; |
| } else { |
| this.language = mpin.cfg.language; |
| } |
| this.setLanguageText(); |
| |
| // Prevent user from scrolling on touch |
| |
| document.ontouchmove = function(e){ e.preventDefault(); } |
| |
| this.renderHomeMobile(); |
| |
| // Simulate OTP |
| // var authData = {}; |
| // authData._mpinOTP = 99; |
| // authData.expireTime = 1414593174295000; |
| // authData.nowTime = 1414593174195000; |
| |
| // this.renderOtp(authData); |
| |
| }; |
| |
| |
| // check minimal required Options |
| // which should be set up |
| mpin.prototype.checkOptions = function(options) { |
| var _opts; |
| _opts = mpin.cfg.requiredOptions.split("; "); |
| for (var k = 0, l = _opts.length; k < l; k++) { |
| if (typeof options[_opts[k]] === "undefined") { |
| return false; |
| } |
| } |
| return true; |
| }; |
| |
| //set defaults OPTIONS |
| mpin.prototype.setDefaults = function() { |
| this.opts || (this.opts = {}); |
| for (var i in mpin.cfg.defaultOptions) { |
| this.opts[i] = mpin.cfg.defaultOptions[i]; |
| } |
| |
| this.opts.useWebSocket = ('WebSocket' in window && window.WebSocket.CLOSING === 2); |
| |
| return this; |
| }; |
| |
| mpin.prototype.setOptions = function(options) { |
| var _i, _opts, _optionName, _options = "stage; allowAddUser; requestOTP; successSetupURL; onSuccessSetup; successLoginURL; onSuccessLogin; onLoaded; onGetPermit; "; |
| _options += "onReactivate; onAccountDisabled; onUnsupportedBrowser; prerollid; onError; onGetSecret; mpinDTAServerURL; signatureURL; verifyTokenURL; certivoxURL; "; |
| _options += "mpinAuthServerURL; registerURL; accessNumberURL; mobileAppFullURL; authenticateHeaders; authTokenFormatter; accessNumberRequestFormatter; "; |
| _options += "registerRequestFormatter; onVerifySuccess; mobileSupport; emailCheckRegex; seedValue; appID; useWebSocket; setupDoneURL; timePermitsURL; timePermitsStorageURL; authenticateURL; "; |
| _options += "language; customLanguageTexts; accessNumberDigits; mobileAuthenticateURL; setDeviceName; getAccessNumberURL; cSum; accessNumberUseCheckSum"; |
| |
| _opts = _options.split("; "); |
| this.opts || (this.opts = {}); |
| |
| for (var _i = 0, _l = _opts.length; _i < _l; _i++) { |
| _optionName = _opts[_i]; |
| if (typeof options[_optionName] !== "undefined") |
| this.opts[_optionName] = options[_optionName]; |
| } |
| |
| MPINAuth.hash_val = this.opts.seedValue; |
| |
| if (this.opts.mpinAuthServerURL.mpin_startsWith("http")) { |
| this.opts.useWebSocket = false; |
| } |
| |
| if (this.opts.mpinAuthServerURL.mpin_startsWith("/")) { |
| var loc = window.location; |
| var newAuthServerURL; |
| if (this.opts.useWebSocket) { |
| newAuthServerURL = (loc.protocol === "https:") ? "wss:" : "ws:"; |
| } else { |
| newAuthServerURL = loc.protocol; |
| } |
| |
| newAuthServerURL += "//" + loc.host + this.opts.mpinAuthServerURL; |
| this.opts.mpinAuthServerURL = newAuthServerURL; |
| } |
| |
| this.opts.mpinAuthServerURL = (this.opts.mpinAuthServerURL.mpin_endsWith("/")) ? this.opts.mpinAuthServerURL.slice(0, this.opts.mpinAuthServerURL.length-1) : this.opts.mpinAuthServerURL; |
| |
| return this; |
| }; |
| |
| //return readyHtml |
| mpin.prototype.readyHtml = function(tmplName, tmplData) { |
| var data = tmplData, html; |
| html = mpin.templates[tmplName]({data:data, cfg: mpin.cfg}); |
| return html; |
| }; |
| |
| |
| mpin.prototype.readyHelpHub= function(tmplName, tmplData) { |
| var data = tmplData, html; |
| html = mpin.templates[tmplName]({data:data, cfg: mpin.cfg}); |
| return html; |
| }; |
| |
| |
| mpin.prototype.render = function(tmplName, callbacks, tmplData) { |
| var data = tmplData || {}, k; |
| this.el.innerHTML = this.readyHtml(tmplName, data); |
| |
| for (k in callbacks) { |
| |
| if (document.getElementById(k) && k !== 'menuBtn') { |
| |
| if (window.navigator.msPointerEnabled) { |
| document.getElementById(k).addEventListener("MSPointerDown", callbacks[k], false); |
| } |
| else { |
| |
| if(mpin.cfg.touchevents) { |
| document.getElementById(k).addEventListener('touchstart', callbacks[k], false); |
| } else { |
| document.getElementById(k).addEventListener('click', callbacks[k], false); |
| } |
| } |
| |
| } else if(document.getElementById(k) && k === 'menuBtn') { |
| document.getElementById('menuBtn').addEventListener('click', callbacks[k], false); |
| } |
| } |
| |
| }; |
| |
| mpin.prototype.renderHelpHub = function(tmplName, tmplData) { |
| var data = tmplData || {}, k, self = this, helphubBtns = {}; |
| |
| // // Dissmiss any open help menus |
| |
| self.dismissHelp(); |
| |
| this.elHelpHub.style.display = 'flex'; |
| this.elHelpHub.style.opacity = "1"; |
| this.elHelpHub.innerHTML = this.readyHelpHub(tmplName, data); |
| |
| helphubBtns.first = function(evt) { |
| // Modify the sequence for the templates |
| // self.renderHelp("help-helphub", callbacks); |
| }; |
| |
| helphubBtns.second = function(evt) { |
| // Modify the sequence for the templates |
| // self.renderHelp("help-helphub", callbacks); |
| }; |
| |
| helphubBtns.details = function(evt) { |
| // Modify the sequence for the templates |
| self.renderHelpHub("helphub-details"); |
| }; |
| |
| helphubBtns.forth = function(evt) { |
| // Modify the sequence for the templates |
| // self.renderHelp("help-helphub", callbacks); |
| }; |
| |
| helphubBtns.enter = function(evt) { |
| self.renderHelpHub("helphub-index"); |
| } |
| |
| helphubBtns.exit = function(evt) { |
| self.dismissHelpHub(); |
| }; |
| |
| for (k in helphubBtns) { |
| if (document.getElementById(k)) { |
| |
| if (window.navigator.msPointerEnabled) { |
| document.getElementById(k).addEventListener("MSPointerDown", helphubBtns[k], false); |
| } |
| else { |
| |
| if(mpin.cfg.touchevents) { |
| document.getElementById(k).addEventListener('touchstart', helphubBtns[k], false); |
| } else { |
| |
| document.getElementById(k).addEventListener('click', helphubBtns[k], false); |
| } |
| |
| } |
| |
| } |
| } |
| |
| }; |
| |
| mpin.prototype.dismissHelp = function() { |
| this.elHelpOverlay.style.display = 'none'; |
| this.elHelpOverlay.style.opacity = '0'; |
| this.elHelp.style.display = 'none'; |
| } |
| |
| mpin.prototype.dismissHelpHub = function() { |
| this.elHelpHub.style.display = 'none'; |
| this.elHelpHub.style.opacity = '0'; |
| } |
| |
| mpin.prototype.setLanguageText = function() { |
| hlp.language = this.language; |
| // setLanguageText |
| if (this.opts.customLanguageTexts && this.opts.customLanguageTexts[this.language]) { |
| for (var k in this.opts.customLanguageTexts[this.language]) { |
| console.log("this.opts.customLanguageTexts[this.language]", this.opts.customLanguageTexts[this.language][k]); |
| if (lang[this.language][k]) { |
| lang[this.language][k] = this.opts.customLanguageTexts[this.language][k]; |
| } |
| } |
| } |
| |
| }; |
| |
| mpin.prototype.renderHomeMobile = function() { |
| |
| var callbacks = {}, self = this, identity, standalone, safari, userAgent, ios; |
| |
| callbacks.mpin_authenticate = function(evt) { |
| // Modify the sequence for the templates |
| self.renderSetupHome.call(self); |
| }; |
| |
| callbacks.ok_dismiss = function(evt) { |
| // Modify the sequence for the templates |
| self.dismissHelp.call(self); |
| }; |
| |
| callbacks.show_more = function(evt) { |
| // Modify the sequence for the templates |
| self.renderHelp("help-helphub", callbacks); |
| }; |
| |
| callbacks.info = function(evt) { |
| // Show the help item |
| self.renderHelp("help-setup-home", callbacks); |
| }; |
| |
| callbacks.mp_action_setup = function(evt) { |
| self.actionSetupHome.call(self); |
| }; |
| |
| identity = this.ds.getDefaultIdentity(); |
| standalone = window.navigator.standalone; |
| userAgent = window.navigator.userAgent.toLowerCase(), |
| safari = /safari\//.test( userAgent ); |
| ios = /iphone|ipod|ipad/.test( userAgent ); |
| |
| // Check browsers |
| |
| function isIos7() { |
| var deviceAgent = userAgent; |
| return /(iphone|ipod|ipad).* os 7_/.test(deviceAgent); |
| } |
| |
| function isIos8() { |
| var deviceAgent = userAgent; |
| return /(iphone|ipod|ipad).* os 8_/.test(deviceAgent); |
| } |
| |
| function isIos6() { |
| var deviceAgent = userAgent; |
| return /(iphone|ipod|ipad).* os 6_/.test(deviceAgent); |
| } |
| |
| function goToIdentity() { |
| // Check if online |
| |
| if(!navigator.onLine) { |
| self.render('offline', callbacks); |
| } |
| |
| // Check if there's identity, redirect to login where 'Add to identity will appear' |
| else if (identity) { |
| |
| totalAccounts = self.ds.getAccounts(); |
| totalAccounts = Object.keys(totalAccounts).length; |
| |
| if (totalAccounts === 0) { |
| self.renderSetupHome(); |
| } else if (totalAccounts === 1 || totalAccounts > 1) { |
| self.renderAccessNumber(); |
| // self.renderLogin(); |
| } |
| |
| } else { |
| // Render renderSetupHome, if no identity exists |
| self.renderSetupHome(); |
| } |
| } |
| |
| // Check if Safari and if it's open as standalone app |
| if(ios) { |
| |
| if ( !standalone && safari ) { |
| |
| // Check if chrome and exit |
| |
| if(userAgent.match('crios')) { |
| goToIdentity(); |
| return; |
| } |
| |
| // Render IOS7 view |
| if(isIos7() || isIos8()) { |
| this.render('ios7-startup', callbacks); |
| |
| } else if(isIos6()) { |
| // Render the IOS6 view - the difference is in the icons |
| this.render('ios6-startup', callbacks); |
| } else { |
| goToIdentity(); |
| } |
| |
| } else if ( standalone && !safari ) { |
| |
| goToIdentity(); |
| |
| } else if ( !standalone && !safari ) { |
| |
| // In app view |
| this.render('ui-webview', callbacks); |
| }; |
| |
| } else { |
| |
| goToIdentity(); |
| } |
| |
| }; |
| |
| mpin.prototype.renderSetupHome = function(email, errorID) { |
| |
| var callbacks = {}, self = this, userId, descHtml, deviceName = "", deviceNameHolder = ""; |
| |
| |
| var totalAccounts = this.ds.getAccounts(); |
| totalAccounts = Object.keys(totalAccounts).length; |
| |
| callbacks.mp_action_home = function(evt) { |
| if (totalAccounts === 0) { |
| self.renderSetupHome(); |
| } else if (totalAccounts === 1) { |
| self.renderAccessNumber(); |
| } else if (totalAccounts > 1) { |
| self.renderAccessNumber(true); |
| } |
| }; |
| callbacks.mp_action_setup = function(evt) { |
| self.actionSetupHome.call(self); |
| }; |
| |
| userId = (email) ? email : ""; |
| |
| if (this.opts.setDeviceName) { |
| |
| //get from localStorage - already set |
| if (this.ds.getDeviceName()) { |
| deviceName = this.ds.getDeviceName(); |
| deviceNameHolder = deviceName; |
| } else { |
| //set only placeholder value |
| deviceNameHolder = this.suggestDeviceName(); |
| deviceName = ""; |
| } |
| } |
| |
| this.render("setup-home", callbacks, {userId: userId, setDeviceName: this.opts.setDeviceName}); |
| |
| // Put placeholder attribute |
| |
| var inputDeviceName = document.getElementById('deviceInput') |
| , inputEmail = document.getElementById('emailInput'); |
| |
| inputDeviceName.placeholder = deviceNameHolder; |
| inputDeviceName.value = deviceName; |
| inputEmail.placeholder = hlp.text("setup_text3"); |
| |
| }; |
| |
| mpin.prototype.renderOtp = function (authData) { |
| var callbacks = {}, self = this, leftSeconds, timerEl, timer2d, drawTimer, totalSec; |
| |
| //draw canvas Clock |
| drawTimer = function (expireOn) { |
| var start, diff; |
| diff = totalSec - expireOn; |
| start = -0.5 + ((diff / totalSec) * 2); |
| start = Math.round(start * 100) / 100; |
| timer2d.clearRect(0, 0, timerEl.width, timerEl.height); |
| |
| timer2d.beginPath(); |
| timer2d.strokeStyle = "#8588ac"; |
| timer2d.arc(20, 20, 18, start * Math.PI, 1.5 * Math.PI); |
| timer2d.lineWidth = 5; |
| timer2d.stroke(); |
| }; |
| |
| function expire (expiresOn) { |
| leftSeconds = (leftSeconds) ? leftSeconds - 1 : Math.floor((expiresOn - (new Date())) / 1000); |
| if (leftSeconds > 0) { |
| document.getElementById("mpin_seconds").innerHTML = leftSeconds; |
| |
| if (document.getElementById("mpTimer")) { |
| drawTimer(leftSeconds); |
| } |
| |
| } else { |
| clearInterval(self.intervalExpire); |
| self.renderOtpExpire(); |
| } |
| } |
| |
| callbacks.mp_action_home = function () { |
| clearInterval(self.intervalExpire); |
| self.renderHomeMobile.call(self); |
| }; |
| |
| callbacks.mpin_help = function () { |
| clearInterval(self.intervalExpire); |
| self.lastView = "renderOtp"; |
| self.renderHelpHub.call(self); |
| }; |
| |
| callbacks.mpin_cancel = function () { |
| clearInterval(self.intervalExpire); |
| self.renderLogin.call(self); |
| }; |
| |
| this.render("otp", callbacks); |
| |
| document.getElementById("mpinOTPNumber").innerHTML = authData._mpinOTP; |
| |
| var timeOffset = new Date() - new Date(authData.nowTime); |
| var expireMSec = new Date(authData.expireTime + timeOffset); |
| |
| totalSec = Math.floor((expireMSec - (new Date())) / 1000); |
| |
| if (document.getElementById("mpTimer")) { |
| timerEl = document.getElementById("mpTimer"); |
| timer2d = timerEl.getContext("2d"); |
| } |
| |
| expire(expireMSec); |
| |
| this.intervalExpire = setInterval(function () { |
| expire(); |
| }, 1000); |
| }; |
| |
| |
| mpin.prototype.renderOtpExpire = function () { |
| var callbacks = {}, self = this; |
| |
| callbacks.mpin_login_now = function () { |
| self.renderLogin.call(self); |
| }; |
| |
| this.render("otp-expire", callbacks); |
| }; |
| |
| |
| mpin.prototype.suggestDeviceName = function() { |
| var suggestName, platform, browser; |
| platform = navigator.platform.toLowerCase(); |
| browser = navigator.userAgent; |
| |
| if (platform.indexOf("mac") !== -1) { |
| platform = "mac"; |
| } else if (platform.indexOf("linux") !== -1) { |
| platform = "lin"; |
| } else if (platform.indexOf("win") !== -1) { |
| platform = "win"; |
| } else if (platform.indexOf("sun") !== -1) { |
| platform = "sun"; |
| } else if (platform.indexOf("iphone") !== -1) { |
| platform = "iOS"; |
| } else { |
| platform = "__"; |
| } |
| |
| if (browser.indexOf("Chrome") !== -1) { |
| browser = "Chrome"; |
| } else if (browser.indexOf("MSIE") !== -1 || browser.indexOf("Trident") !== -1) { |
| browser = "Explorer"; |
| } else if (browser.indexOf("Firefox") !== -1) { |
| browser = "Firefox"; |
| } else if (browser.indexOf("Safari") !== -1) { |
| browser = "Safari"; |
| } else if (browser.indexOf("iPhone") !== -1) { |
| browser = "iPhone"; |
| } else { |
| browser = "_"; |
| } |
| |
| suggestName = platform + browser; |
| |
| return suggestName; |
| }; |
| |
| |
| mpin.prototype.renderSetup = function(email, clientSecretShare, clientSecretParams) { |
| |
| var callbacks = {} |
| , self = this; |
| |
| var totalAccounts = this.ds.getAccounts(); |
| totalAccounts = Object.keys(totalAccounts).length; |
| |
| callbacks.mp_action_home = function(evt) { |
| if (totalAccounts === 0) { |
| self.renderSetupHome(); |
| } else if (totalAccounts === 1) { |
| self.renderAccessNumber(); |
| } else if (totalAccounts > 1) { |
| self.renderAccessNumber(true); |
| } |
| }; |
| callbacks.mpinClear = function() { |
| self.addToPin.call(self, "clear"); |
| }; |
| callbacks.mpinLogin = function() { |
| |
| if(self.pinpadInput.length < mpin.cfg.pinSize ) { |
| |
| return; |
| } |
| |
| self.actionSetup.call(self); |
| }; |
| callbacks.menuBtn = function() { |
| self.toggleButton.call(self); |
| }; |
| |
| callbacks.show_more = function(evt) { |
| // Modify the sequence for the templates |
| self.renderHelpHub("helphub-index", callbacks); |
| }; |
| |
| callbacks.info = function(evt) { |
| // Show the help item |
| self.renderHelp("help-setup-home", callbacks); |
| }; |
| |
| this.render("setup-pin", callbacks, {email: email, pinSize: mpin.cfg.pinSize}); |
| |
| this.enableNumberButtons(false); |
| this.bindNumberButtons(); |
| this.addToPin.call(self, "clear"); |
| |
| //requestSignature |
| this.requestSignature(email, clientSecretShare, clientSecretParams); |
| }; |
| |
| mpin.prototype.renderAccessNumber = function(listAccounts) { |
| |
| var callbacks = {} |
| , self = this |
| , identity = this.ds.getDefaultIdentity() |
| , email = this.getDisplayName(identity) |
| , totalAccounts = this.ds.getAccounts(); |
| |
| totalAccounts = Object.keys(totalAccounts).length; |
| |
| if (!identity) { |
| this.renderSetupHome(); |
| } |
| |
| if (!this.identity) { |
| self.setIdentity(self.ds.getDefaultIdentity(), true); |
| |
| } |
| if(self.opts.requestOTP === "1") { |
| self.renderLogin(); |
| return; |
| } |
| |
| |
| |
| callbacks.mp_action_home = function(evt) { |
| if (document.getElementById("menuBtn").classList.contains("close")) { |
| document.getElementById("menuBtn").onclick(); |
| // self.toggleButton.call(self); |
| } |
| return ; |
| if (totalAccounts === 0) { |
| self.renderSetupHome(); |
| } else if (totalAccounts === 1) { |
| self.renderAccessNumber(); |
| } else if (totalAccounts > 1) { |
| self.renderAccessNumber(true); |
| } |
| }; |
| |
| callbacks.mpinClear = function() { |
| self.addToAcc.call(self, "clear", false); |
| }; |
| |
| callbacks.menuBtn = function() { |
| self.toggleButton.call(self); |
| }; |
| |
| callbacks.mpinLogin = function() { |
| |
| // Validate the number of digits entered |
| if(self.accessNumber.length < self.opts.accessNumberDigits ) { |
| return; |
| } |
| |
| if (!self.opts.accessNumberUseCheckSum) { |
| self.renderLogin.call(self); |
| return; |
| } |
| |
| if(self.opts.cSum === 1 && !self.checkAccessNumberValidity2(self.accessNumber, 6)) { |
| self.renderAccessNumber.call(self); |
| self.addToAcc.call(self, "clear", false); |
| self.display(hlp.text("authPin_errorInvalidAccessNumber"), true); |
| return; |
| } |
| |
| if(!self.checkAccessNumberValidity(self.accessNumber, 1) && self.opts.cSum !== 1) { |
| self.renderAccessNumber.call(self); |
| self.addToAcc.call(self, "clear", false); |
| self.display(hlp.text("authPin_errorInvalidAccessNumber"), true); |
| return; |
| } |
| // Go to renderLogin |
| |
| self.renderLogin(); |
| }; |
| |
| this.render("setup-access", callbacks, {email: email, menu: true}); |
| |
| self.enableNumberButtons(true); |
| self.enableButton(false, "go"); |
| self.enableButton(false, "clear"); |
| self.bindNumberButtons(true); |
| |
| // Clear all numbers if you logged in successfuly |
| |
| self.addToAcc.call(self, "clear", false); |
| |
| if (listAccounts) { |
| this.toggleButton(); |
| } else { |
| this.setIdentity(this.ds.getDefaultIdentity(), true, function() { |
| self.display(hlp.text("pinpad_placeholder_text")); |
| }, function() { |
| return false; |
| }); |
| } |
| |
| } |
| |
| mpin.prototype.renderLogin = function(listAccounts) { |
| |
| var callbacks = {} |
| , self = this |
| , identity = this.ds.getDefaultIdentity() |
| , email = this.getDisplayName(identity) |
| , totalAccounts = this.ds.getAccounts() |
| , pinpadDisplay = document.getElementById("pinpad-input") |
| |
| callbacks.mp_action_home = function(evt) { |
| if (totalAccounts === 0) { |
| self.renderSetupHome(); |
| } else if (totalAccounts === 1) { |
| self.renderAccessNumber(); |
| } else if (totalAccounts > 1) { |
| self.renderAccessNumber(true); |
| } |
| }; |
| |
| callbacks.mpinClear = function() { |
| self.addToPin.call(self, "clear"); |
| }; |
| |
| callbacks.menuBtn = function() { |
| self.toggleButton.call(self); |
| }; |
| |
| callbacks.mpinLogin = function() { |
| |
| if(self.pinpadInput.length < mpin.cfg.pinSize ) { |
| |
| return; |
| } |
| |
| self.actionLogin.call(self); |
| }; |
| |
| this.pinpadInput = ''; |
| this.render("setup", callbacks, {email: email, menu: true, pinSize: mpin.cfg.pinSize}); |
| this.enableNumberButtons(false); |
| this.bindNumberButtons(); |
| |
| // TODO |
| |
| // Help hub callbacks |
| |
| callbacks.ok_dismiss = function(evt) { |
| // Modify the sequence for the templates |
| self.dismissHelp.call(self); |
| }; |
| |
| callbacks.show_more = function(evt) { |
| // Modify the sequence for the templates |
| self.renderHelpHub("helphub-index"); |
| }; |
| |
| // Helphub calbacks |
| |
| document.getElementById('openHelpHub').onclick = function(evt) { |
| self.renderHelpHub("helphub-index"); |
| }; |
| |
| if (listAccounts) { |
| this.toggleButton(); |
| } else { |
| this.setIdentity(this.ds.getDefaultIdentity(), true, function() { |
| self.display(hlp.text("pinpad_placeholder_text")); |
| }, function() { |
| return false; |
| }); |
| } |
| }; |
| |
| mpin.prototype.getAccessNumber = function() { |
| var _request = new XMLHttpRequest(), self = this, expire, drawTimer, timerEl, timer2d, totalSec; |
| |
| this.intervalID || (this.intervalID = {}); |
| |
| //// TIMER CODE |
| if (document.getElementById("mpTimer")) { |
| timerEl = document.getElementById("mpTimer"); |
| timer2d = timerEl.getContext("2d"); |
| } |
| //draw canvas Clock |
| drawTimer = function (expireOn) { |
| |
| var start, diff; |
| diff = totalSec - expireOn; |
| start = -0.5 + ((diff / totalSec) * 2); |
| start = Math.round(start * 100) / 100; |
| |
| timer2d.clearRect(0, 0, timerEl.width, timerEl.height); |
| |
| timer2d.beginPath(); |
| timer2d.strokeStyle = "#8588ac"; |
| timer2d.arc(20, 20, 18, start * Math.PI, 1.5 * Math.PI); |
| timer2d.lineWidth = 5; |
| timer2d.stroke(); |
| }; |
| |
| expire = function (expiresOn) { |
| var expireAfter = Math.floor((expiresOn - (new Date())) / 1000); |
| if (expireAfter <= 0) { |
| if (self.intervalID) { |
| clearInterval(self.intervalID); |
| } |
| self.getAccessNumber(); |
| } else { |
| document.getElementById("mpin_seconds").innerHTML = expireAfter; |
| //////////////////////////////////////////Clockwise |
| ///// Check if Timer Element exist some template did not have timer |
| if (document.getElementById("mpTimer")) { |
| drawTimer(expireAfter); |
| } |
| } |
| }; |
| |
| _request.onreadystatechange = function() { |
| var jsonResponse, expiresOn; |
| if (_request.readyState === 4 && _request.status === 200) { |
| jsonResponse = JSON.parse(_request.responseText); |
| document.getElementById("mp_accessNumber").innerHTML = jsonResponse.accessNumber; |
| if (jsonResponse.webOTP) { |
| self.webOTP = jsonResponse.webOTP; |
| } |
| expiresOn = new Date(); |
| totalSec = 99; |
| expiresOn.setSeconds(expiresOn.getSeconds() + jsonResponse.ttlSeconds); |
| expire(expiresOn); |
| self.intervalID = setInterval(function() { |
| expire(expiresOn); |
| }, 1000); |
| } |
| }; |
| _request.open("POST", this.opts.getAccessNumberURL); |
| // _request.setRequestHeader('Content-Type', 'application/json'); |
| _request.send(); |
| }; |
| |
| //post REQUEST |
| mpin.prototype.getAccess = function() { |
| var _request = new XMLHttpRequest(), self = this; |
| |
| _request.onreadystatechange = function() { |
| var _jsonRes; |
| if (_request.readyState === 4) { |
| if (_request.status === 200) { |
| _jsonRes = JSON.parse(_request.responseText); |
| if (self.opts.onVerifySuccess) { |
| self.opts.onVerifySuccess(_jsonRes); |
| } else { |
| self.successLogin(_jsonRes); |
| } |
| } else { |
| console.log("NOT success !!!"); |
| } |
| } |
| }; |
| |
| _request.open("POST", this.opts.accessNumberURL, true); |
| _request.timeout = 30000; |
| _request.ontimeout = function() { |
| self.getAccess(); |
| }; |
| var _sendParams = {}; |
| if (this.webOTP) { |
| sendParams.webOTP = this.webOTP; |
| _request.send(JSON.stringify(_sendParams)); |
| } else { |
| _request.send(); |
| } |
| return _request; |
| }; |
| |
| mpin.prototype.renderActivateIdentity = function() { |
| var callbacks = {}, self = this, email; |
| email = this.getDisplayName(this.identity); |
| |
| callbacks.mp_action_home = function(evt) { |
| self.renderHomeMobile.call(self); |
| }; |
| callbacks.mpin_action_setup = function(evt) { |
| if (self.checkBtn(this)) |
| self.beforeRenderSetup.call(self, this); |
| }; |
| callbacks.mpin_action_resend = function(evt) { |
| if (self.checkBtn(this)) |
| self.actionResend.call(self, this); |
| }; |
| //identities list |
| callbacks.mpin_accounts = function() { |
| self.renderAccountsBeforeSetup(); |
| }; |
| |
| this.render("activate-identity", callbacks, {email: email}); |
| }; |
| |
| //prevent mpin button multi clicks |
| mpin.prototype.checkBtn = function(btnElem) { |
| var btnClass = btnElem.className; |
| return (btnClass.indexOf("mpinBtnBusy") === -1 && btnClass.indexOf("mpinBtnError") === -1 && btnClass.indexOf("mpinBtnOk") === -1); |
| }; |
| |
| mpin.prototype.mpinButton = function(btnElem, busyText) { |
| |
| var oldHtml = btnElem.innerHTML; |
| addClass(btnElem, "mpinBtnBusy"); |
| |
| btnElem.innerHTML = "<span class='btnLabel'>" + hlp.text(busyText) + "</span>"; |
| return { |
| error: function(errorText) { |
| removeClass(btnElem, "mpinBtnBusy"); |
| addClass(btnElem, "mpinBtnError"); |
| btnElem.innerHTML = "<span class='btnLabel'>" + hlp.text(errorText) + "</span>"; |
| setTimeout(function() { |
| removeClass(btnElem, "mpinBtnError"); |
| btnElem.innerHTML = oldHtml; |
| }, 1500); |
| |
| }, ok: function(okText) { |
| removeClass(btnElem, "mpinBtnBusy"); |
| addClass(btnElem, "mpinBtnOk"); |
| btnElem.innerHTML = "<span class='btnLabel'>" + hlp.text(okText) + "</span>"; |
| setTimeout(function() { |
| removeClass(btnElem, "mpinBtnOk"); |
| btnElem.innerHTML = oldHtml; |
| }, 1500); |
| }}; |
| }; |
| |
| |
| mpin.prototype.beforeRenderSetup = function(btnElem) { |
| |
| var _reqData = {}, regOTT, url, self = this; |
| regOTT = this.ds.getIdentityData(this.identity, "regOTT"); |
| url = this.opts.signatureURL + "/" + this.identity + "?regOTT=" + regOTT; |
| |
| if (btnElem) { |
| var btn = this.mpinButton(btnElem, "setupNotReady_check_info1"); |
| } |
| |
| _reqData.URL = url; |
| _reqData.method = "GET"; |
| //get signature |
| requestRPS(_reqData, function(rpsData) { |
| if (rpsData.errorStatus) { |
| btn.error("setupNotReady_check_info2"); |
| self.error("Activate identity"); |
| return; |
| } |
| var userId = self.getDisplayName(self.identity); |
| self.renderSetup(userId, rpsData.clientSecretShare, rpsData.params); |
| }); |
| |
| |
| }; |
| |
| //custom render |
| mpin.prototype.renderAccountsPanel = function(back) { |
| |
| var self = this, |
| callbacks = {}, |
| renderElem, |
| addEmptyItem, |
| c = 0, |
| mpBack = document.getElementById('mp_back'), |
| menuBtn = document.getElementById('menuBtn'), |
| defaultIdentity; |
| |
| if(!mpBack) { |
| mpBack = document.getElementById("mp_back_not_active"); |
| } |
| |
| if (window.navigator.msPointerEnabled) { |
| menuBtn.style.bottom = '0'; |
| } |
| |
| if(menuBtn) { |
| |
| menuBtn.onclick = function(evt) { |
| document.getElementById('accountTopBar').style.height = ""; |
| menuBtn.className = 'up'; |
| // self.renderAccessNumber(); |
| }; |
| |
| } |
| |
| addEmptyItem = function(cnt) { |
| var p = document.createElement("div"); |
| p.className = "mp_contentEmptyItem"; |
| cnt.appendChild(p); |
| }; |
| |
| addMpinBack = function () { |
| |
| if(document.getElementById('accountTopBar')) { |
| renderElem = document.getElementById('accountTopBar').appendChild(document.createElement("div")); |
| renderElem.id = "mp_back"; |
| mpBack = document.getElementById("mp_back"); |
| |
| if(!document.getElementById("mp_back")) { |
| mpBack = document.getElementById("mp_back_not_active"); |
| } |
| |
| mpBack.innerHTML = self.readyHtml("accounts-panel", {}); |
| } |
| } |
| |
| |
| // Fix for IE compatibillity |
| if(document.body.contains(mpBack) === false || document.body.contains(mpBack) === false) { |
| |
| addMpinBack(); |
| mpBack.style.display = 'block'; |
| |
| document.getElementById("mp_acclist_adduser").onclick = function(evt) { |
| self.renderSetupHome.call(self); |
| }; |
| |
| // Appending happens here |
| |
| var cnt = document.getElementById("mp_accountContent"); |
| this.addUserToList(cnt, this.ds.getDefaultIdentity(), true, 0); |
| |
| for (var i in this.ds.getAccounts()) { |
| c += 1; |
| if (i != this.ds.getDefaultIdentity()) |
| this.addUserToList(cnt, i, false, c); |
| } |
| |
| addEmptyItem(cnt); |
| |
| } |
| |
| //default IDENTITY |
| |
| }; |
| |
| mpin.prototype.renderAccountsBeforeSetupPanel = function(back) { |
| |
| var self = this, |
| callbacks = {}, |
| renderElem, |
| addEmptyItem, |
| c = 0, |
| mpBack = document.getElementById('mp_back_not_active'), |
| menuBtn = document.getElementById('menuBtn'), |
| defaultIdentity; |
| |
| if (window.navigator.msPointerEnabled) { |
| menuBtn.style.bottom = '0'; |
| } |
| |
| addEmptyItem = function(cnt) { |
| var p = document.createElement("div"); |
| p.className = "mp_contentEmptyItem"; |
| cnt.appendChild(p); |
| }; |
| |
| addMpinBack = function () { |
| renderElem = document.getElementById('identityContainer').appendChild(document.createElement("div")); |
| renderElem.id = "mp_back_not_active"; |
| mpBack = document.getElementById("mp_back_not_active"); |
| mpBack.innerHTML = self.readyHtml("accounts-panel-not-active", {}); |
| } |
| |
| |
| // Fix for IE compatibillity |
| if(document.body.contains(mpBack) === false) { |
| |
| addMpinBack(); |
| mpBack.style.display = 'block'; |
| |
| document.getElementById("mp_go_back").onclick = function(evt) { |
| self.renderIdentityNotActive.call(self); |
| }; |
| |
| // Appending happens here |
| |
| var cnt = document.getElementById("mp_accountContent"); |
| this.addUserToList(cnt, this.ds.getDefaultIdentity(), true, 0); |
| |
| for (var i in this.ds.getAccounts()) { |
| c += 1; |
| if (i != this.ds.getDefaultIdentity()) |
| this.addUserToList(cnt, i, false, c); |
| } |
| |
| addEmptyItem(cnt); |
| |
| } |
| |
| //default IDENTITY |
| |
| }; |
| |
| mpin.prototype.renderUserSettingsPanel = function(iD) { |
| |
| var renderElem, name, self = this, name = this.getDisplayName(iD), renderElemVal; |
| |
| if(document.getElementById("mp_back")) { |
| renderElem = document.getElementById("mp_back"); |
| renderElemVal = 'mp_back'; |
| } else { |
| renderElem = document.getElementById("mp_back_not_active"); |
| renderElemVal = 'mp_back_not_active'; |
| } |
| |
| renderElem.innerHTML = this.readyHtml("user-settings", {name: name}); |
| |
| document.getElementById("mp_deluser").onclick = function(evt) { |
| self.renderDeletePanel.call(self, iD); |
| }; |
| document.getElementById("mp_reactivate").onclick = function(evt) { |
| self.renderReactivatePanel.call(self, iD); |
| }; |
| document.getElementById("mp_acclist_cancel").onclick = function(evt) { |
| renderElem.parentNode.removeChild(renderElem); |
| |
| if(renderElemVal === "mp_back") { |
| self.renderAccountsPanel(); |
| } else { |
| self.renderAccountsBeforeSetupPanel(); |
| } |
| }; |
| }; |
| |
| mpin.prototype.renderReactivatePanel = function(iD) { |
| var renderElem, name, self = this; |
| name = this.getDisplayName(iD); |
| |
| if(document.getElementById("mp_back")) { |
| renderElem = document.getElementById("mp_back"); |
| } else { |
| renderElem = document.getElementById("mp_back_not_active"); |
| } |
| |
| renderElem.innerHTML = this.readyHtml("reactivate-panel", {name: name}); |
| |
| document.getElementById("mp_acclist_reactivateuser").onclick = function() { |
| self.actionSetupHome.call(self, self.getDisplayName(iD)); |
| }; |
| document.getElementById("mp_acclist_cancel").onclick = function() { |
| self.renderUserSettingsPanel(iD); |
| }; |
| }; |
| |
| mpin.prototype.renderDeletePanel = function(iD) { |
| var renderElem, name, self = this; |
| name = this.getDisplayName(iD); |
| |
| if(document.getElementById("mp_back")) { |
| renderElem = document.getElementById("mp_back"); |
| } else { |
| renderElem = document.getElementById("mp_back_not_active"); |
| } |
| |
| renderElem.innerHTML = this.readyHtml("delete-panel", {name: name}); |
| |
| document.getElementById("mp_acclist_deluser").onclick = function(evt) { |
| self.deleteIdentity(iD); |
| |
| self.renderHomeMobile.call(self, evt); |
| // Render the identity list too |
| |
| }; |
| document.getElementById("mp_acclist_cancel").onclick = function(evt) { |
| self.renderUserSettingsPanel(iD); |
| }; |
| }; |
| |
| mpin.prototype.renderSetupDone = function() { |
| var callbacks = {}, self = this, userId; |
| |
| userId = this.getDisplayName(this.identity); |
| |
| callbacks.mp_action_home = function() { |
| self.renderHomeMobile.call(self); |
| }; |
| callbacks.mp_action_go = function() { |
| self.renderAccessNumber.call(self); |
| }; |
| |
| this.render("setup-done", callbacks, {userId: userId}); |
| }; |
| |
| mpin.prototype.addUserToList = function(cnt, uId, isDefault, iNumber) { |
| var starClass, divClass, self = this, starButton; |
| |
| if (isDefault) { |
| starClass = "mp_starButtonSelectedState"; |
| divClass = "mp_contentItem one-edge-shadow default"; |
| } else { |
| starClass = "mp_starButtonDefaultState"; |
| divClass = "mp_contentItem one-edge-shadow"; |
| } |
| |
| starButton = document.createElement("div"); |
| var name = this.getDisplayName(uId); |
| starButton.setAttribute("tabindex", "-1"); |
| starButton.className = starClass; |
| starButton.id = "mp_accountItem_" + iNumber; |
| |
| var rowElem = document.createElement("div"); |
| rowElem.className = divClass; |
| rowElem.setAttribute("data-identity", uId); |
| rowElem.appendChild(starButton); |
| |
| var tmplData = {name: name}; |
| rowElem.innerHTML = mpin.templates['user-row']({data:tmplData, cfg: mpin.cfg}); |
| |
| cnt.appendChild(rowElem); |
| rowElem.addEventListener('click', mEventsHandler, false); |
| |
| // document.getElementById('mp_back').remove(); |
| |
| function mEventsHandler(e) { |
| |
| e.stopPropagation(); |
| e.preventDefault(); |
| |
| if(document.getElementById("mp_back")) { |
| var elem = document.getElementById("mp_back"); |
| } else { |
| var elem = document.getElementById("mp_back_not_active"); |
| } |
| |
| elem.parentNode.removeChild(elem); |
| |
| removeClass(document.getElementsByClassName("mp_itemSelected")[0], "mp_itemSelected"); |
| // addClass(rowElem, "mp_itemSelected"); |
| self.ds.setDefaultIdentity(uId); |
| self.setIdentity(uId, true); |
| self.renderAccessNumber(); |
| |
| // Enable pin |
| self.addToAcc.call(self, "clear", false); |
| |
| // Hide the identity list |
| |
| menuBtn = document.getElementById('menuBtn'); |
| |
| document.getElementById('accountTopBar').style.height = ""; |
| menuBtn.className = 'up'; |
| |
| } |
| |
| // Append iNumber, don't use handlebars |
| var innerRowElemName = "mp_btIdSettings_" |
| , innerRowElem = document.getElementById(innerRowElemName) |
| , imgRowElem = hlp.img("settings.svg"); |
| |
| innerRowElem.setAttribute("id",innerRowElemName + iNumber); |
| |
| document.getElementById(innerRowElemName + iNumber).onclick = function(ev) { |
| console.log(uId); |
| self.renderUserSettingsPanel(uId); |
| ev.stopPropagation(); |
| return false; |
| }; |
| }; |
| |
| mpin.prototype.renderIdentityNotActive = function(email) { |
| var callbacks = {}, self = this; |
| var email = email? email: self.getDisplayName(this.identity); |
| |
| callbacks.mp_action_home = function(evt) { |
| self.renderHomeMobile(); |
| // self.renderAccountsBeforeSetup(); |
| }; |
| |
| //Check again |
| callbacks.mpin_action_setup = function() { |
| if (self.checkBtn(this)) |
| self.beforeRenderSetup.call(self, this); |
| }; |
| //email |
| callbacks.mpin_action_resend = function() { |
| if (self.checkBtn(this)) |
| self.actionResend.call(self, this); |
| }; |
| //identities list |
| callbacks.mpin_accounts = function() { |
| |
| self.renderAccountsBeforeSetup(); |
| |
| }; |
| |
| this.render("identity-not-active", callbacks, {email: email}); |
| }; |
| |
| mpin.prototype.bindNumberButtons = function(isAcc) { |
| var self = this, btEls; |
| btEls = document.getElementsByClassName("btn"); |
| |
| function mEventsHandler(e) { |
| |
| e.stopPropagation(); |
| e.preventDefault(); |
| |
| var parent = document.getElementById("inputContainer"); |
| var child = document.getElementById("codes"); |
| |
| if(e.target.hasAttribute("disabled")) { |
| return; |
| } |
| |
| isAcc ? self.addToAcc(e.target.getAttribute("data-value"),"") : self.addToPin(e.target.getAttribute("data-value"),""); |
| } |
| |
| for (var i = 0; i < btEls.length; i++) { |
| |
| // Mobile touch events |
| |
| if (window.navigator.msPointerEnabled) { |
| |
| btEls[i].addEventListener('MSPointerDown', mEventsHandler, false); |
| |
| } |
| else { |
| |
| if(mpin.cfg.touchevents) { |
| btEls[i].addEventListener('touchstart', mEventsHandler, false); |
| } else { |
| |
| btEls[i].addEventListener('click', mEventsHandler, false); |
| } |
| |
| } |
| |
| } |
| }; |
| mpin.prototype.enableNumberButtons = function(enable) { |
| |
| var els = document.getElementsByClassName("btn"); |
| for (var i = 0; i < els.length; i++) { |
| var element = els[i]; |
| if (enable) { |
| element.className = "btn"; |
| element.disabled = false; |
| } else { |
| element.className = "btn disabled"; |
| element.disabled = true; |
| } |
| } |
| }; |
| // |
| mpin.prototype.addToPin = function(digit, iserror) { |
| |
| var digitLen |
| , elemForErrcode = document.getElementById('codes') |
| , self = this; |
| |
| this.pinpadInput || (this.pinpadInput = ""); |
| this.pinpadInput += digit; |
| digitLen = this.pinpadInput.length; |
| |
| if (digit === 'login') { |
| |
| elemForErrcode.style.display = "block"; |
| elemForErrcode.innerHTML = hlp.text("pinpad_placeholder_text"); |
| this.enableNumberButtons(true); |
| |
| return; |
| } |
| |
| if (digit === 'pin') { |
| |
| elemForErrcode.style.display = "block"; |
| elemForErrcode.innerHTML = hlp.text("pinpad_placeholder_text"); |
| |
| this.enableNumberButtons(true); |
| |
| return; |
| } |
| |
| if (digitLen === 1) { |
| |
| // Reset the error codes to original text |
| this.resetDisplay(hlp.text("pinpad_placeholder_text")); |
| this.enableButton(true, "clear"); |
| } |
| |
| // Append circles |
| |
| if (digitLen <= mpin.cfg.pinSize) { |
| this.bindCircles(); |
| } |
| |
| if (digitLen === mpin.cfg.pinSize) { |
| |
| this.enableNumberButtons(false); |
| this.enableButton(true, "go"); |
| this.enableButton(true, "clear"); |
| } |
| |
| if (digit === 'clear') { |
| |
| this.enableNumberButtons(true); |
| this.enableButton(false, "go"); |
| this.enableButton(false, "clear"); |
| this.pinpadInput = ""; |
| this.clearCircles(); |
| |
| } |
| |
| }; |
| |
| // Add to pin ac number |
| |
| mpin.prototype.addToAcc = function(digit, iserror) { |
| |
| var accNumLen |
| , elemForErrcode = document.getElementById('codes') |
| , accNumHolder = document.getElementById('accNumHolder') |
| , self = this; |
| |
| this.accessNumber += digit; |
| accNumLen = this.accessNumber.length; |
| accNumHolder.style.display = 'block'; |
| accNumHolder.innerHTML += digit; |
| |
| // On first click |
| |
| if (accNumLen === 1) { |
| |
| // Reset the error codes |
| this.resetDisplay(hlp.text("pinpad_placeholder_text")); |
| this.enableButton(true, "clear"); |
| } |
| |
| if (accNumLen === this.opts.accessNumberDigits) { |
| |
| // Append the number of circles |
| this.enableNumberButtons(false); |
| this.enableButton(true, "go"); |
| this.enableButton(true, "clear"); |
| } |
| |
| if (digit === 'clear') { |
| |
| // Enter ac numbeer |
| |
| self.display(hlp.text("pinpad_placeholder_text2")); |
| |
| // |
| elemForErrcode.style.display = "block"; |
| elemForErrcode.className = ""; |
| |
| this.enableNumberButtons(true); |
| this.enableButton(false, "go"); |
| this.enableButton(false, "clear"); |
| this.accessNumber = ""; |
| |
| |
| // Clear the ac num |
| |
| if (iserror) { |
| accNumHolder.innerHTML = ""; |
| this.enableNumberButtons(true); |
| |
| } else { |
| this.accessNumber = ""; |
| accNumHolder.innerHTML = ""; |
| this.enableNumberButtons(true); |
| } |
| |
| } |
| |
| }; |
| |
| /** |
| * wrap all buttons function inside ... |
| * |
| * @param {type} enable |
| * @param {type} buttonName |
| * @returns {undefined} |
| */ |
| mpin.prototype.enableButton = function(enable, buttonName) { |
| |
| var buttonValue = {}, _element; |
| buttonValue.go = {id: "mpinLogin", trueClass: "btnLogin", falseClass: "btnLogin disabled"}; |
| buttonValue.clear = {id: "mpinClear", trueClass: "btnClear", falseClass: "btnClear disabled"}; |
| buttonValue.toggle = {id: "mp_toggleButton", trueClass: "mp_DisabledState", falseClass: ""}; |
| _element = document.getElementById(buttonValue[buttonName].id); |
| if (!buttonValue[buttonName] || !_element) { |
| return; |
| } |
| |
| _element.disabled = !enable; |
| _element.className = buttonValue[buttonName][enable + "Class"]; |
| }; |
| //showInPinPadDisplay |
| mpin.prototype.display = function(message, clear) { |
| |
| var elemForErrcode = document.getElementById('codes'); |
| elemForErrcode.style.display = "block"; |
| elemForErrcode.className = "error"; |
| elemForErrcode.innerHTML = message; |
| |
| }; |
| |
| mpin.prototype.resetDisplay = function(message) { |
| |
| var elemForErrcode = document.getElementById('codes'); |
| elemForErrcode.style.display = "none"; |
| elemForErrcode.innerHTML = message; |
| |
| }; |
| |
| mpin.prototype.bindCircles = function() { |
| |
| var pinElement = document.getElementById('pinpad-input'); |
| var newCircle = document.createElement('div'); |
| newCircle.className = "inner-circle"; |
| var circleID = "mpin_circle_" + (this.pinpadInput.length - 1); |
| document.getElementById(circleID).appendChild(newCircle); |
| } |
| |
| mpin.prototype.clearCircles = function() { |
| |
| var pinSize = mpin.cfg.pinSize, circles = []; |
| for (var i = 0; i <= pinSize; i++) { |
| circles[i] = document.getElementById("mpin_circle_" + i); |
| if (circles[i] && circles[i].childNodes[3]) { |
| circles[i].removeChild(circles[i].childNodes[3]); |
| } |
| } |
| } |
| |
| mpin.prototype.getDisplayName = function(uId) { |
| if (!uId) |
| uId = this.identity; |
| try { |
| return JSON.parse(mp_fromHex(uId)).userID; |
| } catch (err) { |
| return uId; |
| } |
| }; |
| |
| mpin.prototype.toggleButton = function() { |
| var self = this; |
| var accountTopBar = document.getElementById('accountTopBar') |
| var menuBtn = document.getElementById("menuBtn"); |
| |
| if (menuBtn && !menuBtn.classList.contains("close")) { |
| |
| // this.setIdentity(this.identity, true, function() { |
| // }, function() { |
| // return false; |
| // }); |
| |
| accountTopBar.style.height = "100%" |
| menuBtn.className = 'close'; |
| |
| removeClass("mp_toggleButton", "mp_SelectedState"); |
| removeClass("mp_panel", "mp_flip"); |
| |
| this.renderAccountsPanel(); |
| |
| |
| } else { |
| |
| if (this.ds.getIdentityToken(this.identity) == "") { |
| identity = this.getDisplayName(this.identity); |
| this.renderIdentityNotActive(identity); |
| return; |
| } |
| |
| } |
| |
| return false; |
| }; |
| |
| |
| mpin.prototype.renderAccountsBeforeSetup = function() { |
| var self = this; |
| var accountTopBar = document.getElementById('identityContainer') |
| |
| |
| this.setIdentity(this.identity, true, function() { |
| }, function() { |
| return false; |
| }); |
| |
| accountTopBar.style.height = "100%" |
| |
| removeClass("mp_toggleButton", "mp_SelectedState"); |
| removeClass("mp_panel", "mp_flip"); |
| |
| this.renderAccountsBeforeSetupPanel(); |
| |
| return false; |
| }; |
| |
| mpin.prototype.actionSetupHome = function(uId) { |
| |
| var _email, _deviceName, _deviceNameInput, _reqData = {}, self = this, elems = [], removeError; |
| |
| _email = (uId) ? uId : document.getElementById("emailInput").value; |
| |
| if (_email.length === 0 || !this.opts.emailCheckRegex.test(_email)) { |
| document.getElementById("emailInput").focus(); |
| |
| elems[0] = document.getElementsByClassName("inputLabel")[0]; |
| elems[1] = document.getElementsByClassName("userLabel")[0]; |
| elems[2] = document.getElementById("emailInput"); |
| |
| removeError = function (event) { |
| elems[0].className = "inputLabel"; |
| elems[1].className = "userLabel"; |
| elems[2].className = ""; |
| |
| elems[2].removeEventListener("touchstart", function () {}); |
| }; |
| |
| |
| elems[0].className += " inputLabelErr"; |
| elems[1].className += " userLabelErr"; |
| elems[2].className = "emailInputErr"; |
| |
| elems[2].removeEventListener("touchstart", function () {}); |
| elems[2].addEventListener("touchstart", removeError); |
| |
| return; |
| } |
| |
| _reqData.URL = this.opts.registerURL; |
| _reqData.method = "PUT"; |
| _reqData.data = { |
| userId: _email, |
| mobile: 1 |
| }; |
| |
| _deviceNameInput = (document.getElementById("deviceInput")) ? document.getElementById("deviceInput").value.trim() : ""; |
| //DEVICE NAME |
| if (!this.ds.getDeviceName() && _deviceNameInput === "") { |
| _deviceName = this.suggestDeviceName(); |
| } else if (!this.ds.getDeviceName() && _deviceNameInput !== "") { |
| _deviceName = _deviceNameInput; |
| } else if (_deviceNameInput !== this.ds.getDeviceName()) { |
| _deviceName = _deviceNameInput; |
| } else { |
| _deviceName = false; |
| } |
| |
| if (_deviceName) { |
| this.ds.setDeviceName(_deviceName); |
| } |
| if (this.opts.setDeviceName) { |
| _reqData.data.deviceName = (_deviceNameInput === "") ? this.suggestDeviceName() : _deviceNameInput; |
| } |
| |
| //register identity |
| requestRPS(_reqData, function(rpsData) { |
| if (rpsData.error) { |
| self.error("Activate First"); |
| return; |
| } |
| self.ds.addIdentity(rpsData.mpinId, ""); |
| self.ds.setIdentityData(rpsData.mpinId, {regOTT: rpsData.regOTT}); |
| |
| self.ds.setDefaultIdentity(rpsData.mpinId); |
| self.identity = rpsData.mpinId; |
| |
| // Check for existing userid and delete the old one |
| self.ds.deleteOldIdentity(rpsData.mpinId); |
| |
| //active = true pass activate IDNETITY Screen |
| if (rpsData.active) { |
| self.beforeRenderSetup(); |
| } else { |
| self.renderActivateIdentity(); |
| } |
| }); |
| }; |
| |
| mpin.prototype.requestSignature = function(email, clientSecretShare, clientSecretParams) { |
| var self = this; |
| |
| requestClientSecret(self.certivoxClientSecretURL(clientSecretParams), clientSecretShare, function(clientSecret) { |
| |
| self.enableNumberButtons(true); |
| self.clientSecret = clientSecret; |
| |
| if (self.opts.onGetSecret) { |
| self.opts.onGetSecret(); |
| } |
| }, function(message, code) { |
| self.error(message, code); |
| }); |
| |
| }; |
| |
| mpin.prototype.error = function(msg) { |
| if (this.opts.onError) { |
| this.opts.onError(msg); |
| } else { |
| console.error("Error : " + msg); |
| } |
| }; |
| |
| mpin.prototype.actionResend = function(btnElem) { |
| var self = this, _reqData = {}, regOTT, _email, btn; |
| |
| regOTT = this.ds.getIdentityData(this.identity, "regOTT"); |
| _email = this.getDisplayName(this.identity); |
| |
| btn = this.mpinButton(btnElem, "setupNotReady_resend_info1"); |
| |
| _reqData.URL = this.opts.registerURL; |
| _reqData.URL += "/" + this.identity; |
| _reqData.method = "PUT"; |
| _reqData.data = { |
| userId: _email, |
| mobile: 1, |
| regOTT: regOTT |
| }; |
| |
| if (this.opts.registerRequestFormatter) { |
| _reqData.postDataFormatter = this.opts.registerRequestFormatter; |
| } |
| if (this.opts.customHeaders) { |
| _reqData.customHeaders = this.opts.customHeaders; |
| } |
| |
| // add identity into URL + regOTT |
| requestRPS(_reqData, function(rpsData) { |
| if (rpsData.error || rpsData.errorStatus) { |
| self.error("Resend problem"); |
| return; |
| } |
| |
| if (self.identity !== rpsData.mpinId) { |
| //delete OLD mpinID |
| self.ds.deleteIdentity(self.identity); |
| |
| //asign new one, create & set as default |
| self.identity = rpsData.mpinId; |
| self.ds.addIdentity(self.identity, ""); |
| self.ds.setDefaultIdentity(self.identity); |
| } |
| |
| //should be already exist only update regOTT |
| self.ds.setIdentityData(self.identity, {regOTT: rpsData.regOTT}); |
| |
| // Check for existing userid and delete the old one |
| self.ds.deleteOldIdentity(rpsData.mpinId); |
| |
| |
| |
| btn.ok("setupNotReady_resend_info2"); |
| }); |
| }; |
| |
| mpin.prototype.actionSetup = function() { |
| |
| var self = this, _pin; |
| _pin = this.pinpadInput; |
| this.ds.addIdentity(this.identity, ""); |
| this.display(hlp.text("verify_pin")); |
| |
| extractPIN(_pin, this.clientSecret, this.identity, function(tokenHex) { |
| |
| self.ds.setIdentityToken(self.identity, tokenHex); |
| self.clientSecret = ""; |
| self.enableNumberButtons(false); |
| self.enableButton(false, "go"); |
| self.ds.setDefaultIdentity(self.identity); |
| self.ds.deleteOldIdentity(self.identity); |
| self.display(hlp.text("setupPin_pleasewait"), false); |
| |
| if (self.opts.setupDoneURL) { |
| var _reqData = {}, url = self.opts.setupDoneURL + "/" + self.identity; |
| |
| _reqData.URL = url; |
| _reqData.method = "POST"; |
| _reqData.data = {}; |
| |
| |
| //get signature |
| requestRPS(_reqData, function(rpsData) { |
| |
| if (rpsData.errorStatus) { |
| self.error("ooops"); |
| return; |
| } |
| self.successSetup(); |
| }); |
| } else { |
| self.successSetup(); |
| } |
| }); |
| }; |
| /** |
| * |
| * @returns {undefined} |
| */ |
| mpin.prototype.actionLogin = function() { |
| |
| var callbacks = {} |
| ,authServer, getAuth |
| , self = this |
| , pinValue = this.pinpadInput |
| , accessNumber; |
| |
| //AlertMessage.clearDisplayWrap(); |
| this.enableNumberButtons(false); |
| this.enableButton(false, "go"); |
| this.enableButton(false, "clear"); |
| this.enableButton(true, "toggle"); |
| |
| this.display(hlp.text("authPin_pleasewait")); |
| |
| //getAuth = this.opts.useWebSocket ? getAuthToken : getAuthTokenAjax; |
| //authServer = this.opts.mpinAuthServerURL; |
| |
| if (this.opts.useWebSocket) { |
| getAuth = getAuthToken; |
| authServer = this.opts.mpinAuthServerURL + "/authenticationToken"; |
| } else { |
| getAuth = getAuthTokenAjax; |
| authServer = this.opts.mpinAuthServerURL; |
| } |
| |
| accessNumber = this.accessNumber; |
| |
| //authServer = this.opts.authenticateURL; |
| getAuth(authServer, this.opts.appID, this.identity, this.ds.getIdentityPermit(this.identity), this.ds.getIdentityToken(this.identity), this.currentDate, |
| this.opts.requestOTP, accessNumber ? accessNumber : "0", pinValue, this.opts.requestOTP ? this.opts.authenticateURL : this.opts.mobileAuthenticateURL, this.opts.authenticateRequestFormatter, this.opts.customHeaders, function(success, errorCode, errorMessage, authData) { |
| |
| if (success) { |
| |
| var iD = self.identity; |
| if (self.opts.requestOTP) { |
| self.renderOtp(authData); |
| return; |
| } |
| |
| self.successLogin(authData, iD); |
| |
| } else if (errorCode === "INVALID") { |
| |
| self.addToPin.call(self, "clear"); |
| self.display(hlp.text("authPin_errorInvalidPin"), true); |
| |
| self.enableNumberButtons(true); |
| |
| self.enableButton(false, "go"); |
| self.enableButton(false, "clear"); |
| self.enableButton(true, "toggle"); |
| |
| } else if (errorCode === "MAXATTEMPTS") { |
| |
| var iD = self.identity; |
| self.deleteIdentity(iD); |
| if (self.opts.onAccountDisabled) { |
| self.opts.onAccountDisabled(iD); |
| } |
| |
| callbacks.mp_action_register = function(evt) { |
| var email = self.getDisplayName(iD); |
| self.renderSetupHome.call(self, email); |
| }; |
| |
| callbacks.mp_action_home = function(evt) { |
| self.renderHomeMobile.call(self); |
| }; |
| |
| // TODO: Register again or select new identity |
| |
| self.render('access-denied', callbacks, {email: self.getDisplayName(iD)}); |
| |
| } else if (errorCode === "INVALIDACCESSNUMBER") { |
| |
| // Render the access number again |
| self.renderAccessNumber.call(self); |
| self.addToAcc.call(self, "clear", false); |
| self.display(hlp.text("authPin_errorInvalidAccessNumber"), true); |
| |
| } else if (errorCode === "NOTAUTHORIZED") { |
| |
| self.display(hlp.text("authPin_errorNotAuthorized"), true); |
| |
| } else if (errorCode === "EXPIRED") { |
| |
| self.display(hlp.text("authPin_errorExpired"), true); |
| |
| } else if (errorCode === "WEBSOCKETERROR") { |
| |
| console.error("WebSocket connection fail! Falling to AJAX"); |
| self.opts.useWebSocket = false; |
| self.actionLogin.call(self); |
| |
| } else { |
| |
| console.error("Authentication error: ", errorCode, errorMessage) |
| self.display(hlp.text("authPin_errorServer"), true); |
| } |
| |
| }, function() { |
| console.log(" Before HandleToken ::::"); |
| }); |
| |
| }; |
| |
| mpin.prototype.setIdentity = function(newIdentity, requestPermit, onSuccess, onFail) { |
| var displayName, accId, self = this; |
| |
| if ((typeof(newIdentity) === "undefined") || (!newIdentity)) |
| displayName = ""; |
| else { |
| this.identity = newIdentity; |
| displayName = this.getDisplayName(this.identity); |
| } |
| |
| accId = document.getElementById('mpinUser'); |
| |
| if(accId) { |
| accId.children[0].innerText = displayName; |
| accId.setAttribute("title", displayName); |
| } |
| |
| // no Identity go to setup HOME |
| if (!this.identity) { |
| this.renderSetupHome(); |
| return; |
| } |
| |
| if (requestPermit) { |
| |
| if (this.ds.getIdentityToken(this.identity) == "") { |
| this.renderIdentityNotActive(displayName); |
| return; |
| } |
| |
| this.enableNumberButtons(false); |
| this.enableButton(false, "go"); |
| this.enableButton(false, "clear"); |
| this.enableButton(true, "toggle"); |
| this.requestPermit(newIdentity, function(timePermitHex) { |
| self.enableNumberButtons(true); |
| }, function(message, statusCode) { |
| if (statusCode === 404) { |
| self.renderIdentityNotActive(displayName); |
| onFail(); |
| } else { |
| // Fatal server error! |
| self.display(hlp.text("pinpad_errorTimePermit") + " " + statusCode, true); |
| self.error("Error getting the time permit.", statusCode); |
| onFail(); |
| } |
| }); |
| } |
| }; |
| |
| mpin.prototype.successSetup = function(authData) { |
| var self = this; |
| if (this.opts.successSetupURL) { |
| window.location = this.opts.successSetupURL; |
| } else if (this.opts.onSuccessSetup) { |
| this.opts.onSuccessSetup(authData, function() { |
| self.renderSetupDone.call(self); |
| }); |
| } else { |
| this.renderSetupDone(); |
| } |
| }; |
| |
| //Get request |
| mpin.prototype.ajax = function(url, cb) { |
| var _request = new XMLHttpRequest(); |
| _request.open("GET", url, true); |
| _request.send(); |
| |
| _request.onreadystatechange = function() { |
| if (_request.readyState === 4 && _request.status === 200) |
| { |
| cb(JSON.parse(_request.responseText)); |
| } else if (_request.readyState === 4 && !navigator.onLine) { |
| cb({error: 500}); |
| } |
| }; |
| |
| }; |
| |
| //Post request |
| mpin.prototype.ajaxPost = function(url, data, cb) { |
| var _request = new XMLHttpRequest(); |
| _request.onreadystatechange = function() { |
| if (_request.readyState === 4 && _request.status === 200) |
| { |
| // Tempory fix |
| if (_request.responseText == '') { |
| cb(true); |
| } |
| } else if (_request.readyState === 4) { |
| cb(false); |
| } |
| }; |
| _request.open("Post", url, true); |
| _request.send(JSON.stringify(data)); |
| }; |
| |
| //new Function |
| mpin.prototype.requestPermit = function(identity, onSuccess, onFail) { |
| var self = this; |
| requestTimePermit(self.certivoxPermitsURL(), self.dtaPermitsURL(), self.opts.authenticateHeaders, |
| self.ds.getIdentityPermitCache(this.identity), this.certivoxPermitsStorageURL(), |
| function(timePermitHex, timePermitCache, currentDate) { |
| self.ds.setIdentityPermit(self.identity, timePermitHex); |
| self.ds.setIdentityPermitCache(mpin.identity, timePermitCache); |
| self.currentDate = currentDate || util.today(); |
| self.ds.save(); |
| self.gotPermit(timePermitHex); |
| onSuccess(timePermitHex); |
| }, |
| function(message, statusCode) { |
| onFail(message, statusCode) |
| }); |
| |
| }; |
| |
| mpin.prototype.deleteIdentity = function(iID) { |
| var newDefaultAccount = "", self = this; |
| |
| this.ds.deleteIdentity(iID); |
| for (var i in this.ds.getAccounts()) { |
| newDefaultAccount = i; |
| break; |
| } |
| |
| if (newDefaultAccount) { |
| this.setIdentity(newDefaultAccount, true, function() { |
| }, function() { |
| return false; |
| }); |
| |
| this.ds.setDefaultIdentity(newDefaultAccount); |
| // Render the identity list panel |
| this.renderAccountsPanel(); |
| } else { |
| this.setIdentity(newDefaultAccount, false); |
| this.ds.setDefaultIdentity(""); |
| this.identity = ""; |
| this.renderSetupHome(); |
| } |
| return false; |
| }; |
| |
| //data Source with static referance |
| mpin.prototype.dataSource = function() { |
| var mpinDs = {}, self = this; |
| this.ds || (this.ds = {}); |
| if (typeof(localStorage['mpin']) === "undefined") { |
| localStorage.setItem("mpin", JSON.stringify({ |
| defaultIdentity: "", |
| version: "0.3", |
| accounts: {} |
| })); |
| } |
| mpinDs.mpin = JSON.parse(localStorage.getItem("mpin")); |
| |
| mpinDs.addIdentity = function(uId, token, permit) { |
| if (!mpinDs.mpin.accounts[uId]) { |
| mpinDs.mpin.accounts[uId] = {"MPinPermit": "", "token": ""}; |
| } |
| //this.mpin.defaultIdentity = uId; |
| mpinDs.setIdentityToken(uId, token); |
| if (permit) |
| mpinDs.setIdentityPermit(uId, permit); |
| }; |
| mpinDs.setIdentityToken = function(uId, value) { |
| mpinDs.mpin.accounts[uId]["token"] = value; |
| mpinDs.save(); |
| }; |
| mpinDs.setIdentityPermit = function(uId, value) { |
| mpinDs.mpin.accounts[uId]["MPinPermit"] = value; |
| mpinDs.save(); |
| }; |
| mpinDs.getIdentityPermit = function(uId) { |
| if (!uId) |
| uId = mpinDs.getDefaultIdentity(); |
| return mpinDs.mpin.accounts[uId]["MPinPermit"]; |
| }; |
| mpinDs.setIdentityPermitCache = function(uId, cache) { |
| if (!uId) { |
| uId = mpinDs.getDefaultIdentity(); |
| } |
| mpinDs.mpin.accounts[uId]["timePermitCache"] = cache; |
| mpinDs.save(); |
| }; |
| mpinDs.getIdentityPermitCache = function(uId) { |
| if (!uId) { |
| uId = mpinDs.getDefaultIdentity(); |
| } |
| return mpinDs.mpin.accounts[uId]["timePermitCache"] || {}; |
| }; |
| mpinDs.getIdentityToken = function(uId) { |
| if (!uId) |
| uId = mpinDs.getDefaultIdentity(); |
| return mpinDs.mpin.accounts[uId]["token"]; |
| }; |
| mpinDs.getDefaultIdentity = function(uId) { |
| return mpinDs.mpin.defaultIdentity; |
| }; |
| mpinDs.setDefaultIdentity = function(uId) { |
| mpinDs.mpin.defaultIdentity = uId; |
| mpinDs.save(); |
| }; |
| mpinDs.deleteOldIdentity = function(uId) { |
| var name = self.getDisplayName(uId); |
| |
| for (var i in this.getAccounts()) { |
| if (i !== uId) { |
| var oName = self.getDisplayName(i); |
| if (oName === name) { |
| mpinDs.deleteIdentity(i); |
| } |
| } |
| } |
| }; |
| mpinDs.deleteIdentity = function(uId) { |
| delete mpinDs.mpin.accounts[uId]; |
| mpinDs.save(); |
| }; |
| mpinDs.save = function() { |
| localStorage.setItem("mpin", JSON.stringify(mpinDs.mpin)); |
| }; |
| mpinDs.getAccounts = function() { |
| return mpinDs.mpin.accounts; |
| }; |
| |
| mpinDs.setIdentityData = function(uId, values) { |
| for (var v in values) { |
| mpinDs.mpin.accounts[uId][v] = values[v]; |
| |
| } |
| mpinDs.save(); |
| }; |
| |
| mpinDs.setDeviceName = function(devId) { |
| mpinDs.mpin.deviceName = devId; |
| mpinDs.save(); |
| }; |
| |
| mpinDs.getDeviceName = function() { |
| var deviceID; |
| deviceID = mpinDs.mpin.deviceName; |
| if (!deviceID) { |
| return false; |
| } |
| |
| return deviceID; |
| }; |
| |
| mpinDs.getIdentityData = function(uId, key) { |
| return mpinDs.mpin.accounts[uId][key]; |
| }; |
| |
| return mpinDs; |
| }; |
| |
| mpin.prototype.successLogin = function(authData, iD) { |
| var callbacks = {}, |
| self = this, |
| totalAccounts; |
| |
| totalAccounts = self.ds.getAccounts(); |
| totalAccounts = Object.keys(totalAccounts).length; |
| |
| callbacks.mp_action_home = function(evt) { |
| if (totalAccounts === 0) { |
| self.renderSetupHome(); |
| } else if (totalAccounts === 1) { |
| self.renderAccessNumber(); |
| } else if (totalAccounts > 1) { |
| self.renderAccessNumber(true); |
| } |
| }; |
| |
| callbacks.mp_action_logout = function(evt) { |
| var that = this; |
| if(authData.logoutURL) { |
| self.ajaxPost( authData.logoutURL, authData.logoutData, function(res) { |
| if (res) { |
| // self.renderAccessNumber(); |
| self.renderAccessNumber.call(self); |
| } else { |
| that.innerHTML = '<span class="btnLabel" id="btnLabelText" style="color: red;">Sign out was unsuccessful !</span>'; |
| setTimeout(function () { |
| self.renderAccessNumber.call(self); |
| }, 2000); |
| } |
| |
| }); |
| } else { |
| |
| // self.renderAccessNumber(); |
| self.renderAccessNumber.call(self); |
| } |
| |
| }; |
| |
| this.render("success-login", callbacks, {email: self.getDisplayName(iD)}); |
| |
| if(authData.logoutURL === '') { |
| var _logoutBtnText = document.getElementById('btnLabelText'); |
| _logoutBtnText.innerText = hlp.text("start_over"); |
| } |
| }; |
| |
| mpin.prototype.certivoxClientSecretURL = function(params) { |
| return this.opts.certivoxURL + "clientSecret?" + params; |
| }; |
| |
| mpin.prototype.certivoxPermitsURL = function() { |
| var mpin_id_bytes, hash_mpin_id_bytes = [], hash_mpin_id_hex, |
| permitsUrl, mpData = mp_fromHex(this.identity); |
| |
| mpin_id_bytes = MPIN.stringtobytes(mpData); |
| hash_mpin_id_bytes = MPIN.HASH_ID(mpin_id_bytes); |
| hash_mpin_id_hex = MPIN.bytestostring(hash_mpin_id_bytes); |
| |
| permitsUrl = this.opts.certivoxURL + "timePermit"; |
| permitsUrl += "?app_id=" + this.opts.appID; |
| permitsUrl += "&mobile=0"; |
| permitsUrl += "&hash_mpin_id=" + hash_mpin_id_hex; |
| return permitsUrl; |
| }; |
| |
| mpin.prototype.dtaPermitsURL = function() { |
| var mpin_idHex = this.identity; |
| return this.opts.timePermitsURL + "/" + mpin_idHex; |
| }; |
| |
| mpin.prototype.certivoxPermitsStorageURL = function() { |
| var that = this; |
| |
| return function(date, storageId) { |
| console.log("timePermitsStorageURL Base: " + that.opts.timePermitsStorageURL) |
| if ((date) && (that.opts.timePermitsStorageURL) && (storageId)) { |
| return that.opts.timePermitsStorageURL + "/" + that.opts.appID + "/" + date + "/" + storageId; |
| } else { |
| return null; |
| } |
| } |
| }; |
| |
| |
| mpin.prototype.gotPermit = function(timePermit) { |
| if (this.opts.onGetPermit) |
| this.opts.onGetPermit(timePermit); |
| }; |
| |
| mpin.prototype.checkAccessNumberValidity = function(sNum, csDigits){ |
| if (!csDigits) { |
| csDigits = 1; |
| } |
| |
| var n = parseInt(sNum.slice(0, sNum.length-csDigits), 10); |
| var cSum = parseInt(sNum.slice(sNum.length-csDigits, sNum.length), 10); |
| |
| var p = 99991; |
| var g = 11; |
| var checkSum = ((n * g) % p) % Math.pow(10, csDigits); |
| |
| return (checkSum == cSum) |
| }; |
| |
| // Better checksum approach |
| // checkAccessNumberValidity2 (accessNumber, Length) |
| mpin.prototype.checkAccessNumberValidity2 = function (number, len) { |
| var cSum, checksum, x, w, wid, wid_len, g = 11, sum_d = 0; |
| wid = number.toString(); |
| wid = wid.substring(0, number.toString().length-1); |
| w = len + 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 = number.substr(-1); |
| cSum = parseInt(cSum); |
| return (cSum === checksum); |
| } |
| |
| function mp_fromHex(s) { |
| if (!s || s.length % 2 != 0) |
| return ''; |
| |
| s = s.toLowerCase(); |
| var digits = '0123456789abcdef'; |
| var result = ''; |
| for (var i = 0; i < s.length; ) { |
| var a = digits.indexOf(s.charAt(i++)); |
| var b = digits.indexOf(s.charAt(i++)); |
| if (a < 0 || b < 0) |
| return ''; |
| result += String.fromCharCode(a * 16 + b); |
| } |
| return result; |
| } |
| ; |
| |
| // HELPERS and Language Dictionary |
| |
| loader = function(url, callback) { |
| var script = document.createElement('script'); |
| script.type = 'text/javascript'; |
| script.src = url; |
| //IE feature detect |
| if (script.readyState) { |
| script.onreadystatechange = callback; |
| } else { |
| script.onload = callback; |
| } |
| document.getElementsByTagName('head')[0].appendChild(script); |
| }; |
| |
| function addClass(elId, className) { |
| var el; |
| if (typeof(elId) === "string") { |
| el = document.getElementById(elId); |
| } else { |
| el = elId; |
| } |
| |
| if (el.className) { |
| var cNames = el.className.split(/\s+/g); |
| if (cNames.indexOf(className) < 0) |
| el.className += " " + className; |
| } else { |
| el.className = className; |
| } |
| } |
| ; |
| |
| function hasClass(elId, className) { |
| var el; |
| if (typeof(elId) == "string") |
| el = document.getElementById(elId); |
| else |
| el = elId; |
| |
| var cNames = el.className.split(/\s+/g); |
| return (cNames.indexOf(className) >= 0) |
| } |
| ; |
| |
| function removeClass(elId, className) { |
| var el; |
| if (typeof(elId) == "string") |
| el = document.getElementById(elId); |
| else |
| el = elId; |
| |
| if ((el) && (el.className)) { |
| var cNames = el.className.split(/\s+/g); |
| cNames.splice(cNames.indexOf(className), 1); |
| el.className = cNames.join(" "); |
| } |
| } |
| ; |
| |
| //private variable |
| //en |
| mpin.lang = {}; |
| mpin.lang.en = { |
| "pinpad_initializing": "Initializing...", |
| "pinpad_errorTimePermit": "ERROR GETTING PERMIT:", |
| "home_alt_mobileOptions": "Mobile Options", |
| "home_button_authenticateMobile_noTrust": "Sign in with Smartphone <br> (This is a PUBLIC device which I DO NOT trust)", |
| "home_button_authenticateMobile_trust": "Sign in with Browser <br> (This is a PERSONAL device which I DO trust)", |
| "home_button_authenticateMobile_intro": "First let's establish trust to choose the best way for you to access this service:", |
| "home_button_authenticateMobile_description": "Get your Mobile Access Number to use with your M-Pin Mobile App to securely authenticate yourself to this service.", |
| "home_button_getMobile": "Get <br/>M-Pin Mobile App", |
| "home_button_getMobile_description": "Install the free M-Pin Mobile App on your Smartphone now! This will enable you to securely authenticate yourself to this service.", |
| "home_button_authenticateBrowser": "Authenticate <br/>with this Browser", |
| "home_button_authenticateBrowser_description": "Enter your M-PIN to securely authenticate yourself to this service.", |
| "home_button_setupBrowser": "Add an <br/>Identity to this Browser", |
| "home_button_setupBrowser_description": "Add your Identity to this web browser to securely authenticate yourself to this service using this machine.", |
| "mobileGet_header": "GET M-PIN MOBILE APP", |
| "mobileGet_text1": "Scan this QR code", |
| "mobileGet_text2": "or open this URL on your mobile:", |
| "mobileGet_button_back": "Back", |
| "mobileAuth_header": "AUTHENTICATE WITH YOUR M-PIN", |
| "mobileAuth_seconds": "seconds", |
| "mobileAuth_text1": "Your Access Number is:", |
| "mobileAuth_text2": "Note: Use this number in the next", |
| "mobileAuth_text3": "with your M-Pin Mobile App.", |
| "mobileAuth_text4": "Warning: Navigating away from this page will interrupt the authentication process and you will need to start again to authenticate successfully.", |
| "otp_signin_header": "Sign in with One-Time Password", |
| "otp_text1": "Your One-Time Password is:", |
| "otp_text2": "Note: The password is only valid for " + mpin.cfg.expireOtpSeconds + " seconds before it expires.", // {0} will be replaced with the max. seconds |
| "otp_seconds": "Remaining:", // {0} will be replaced with the remaining seconds |
| "otp_expired_header": "Your One-Time Password has expired.", |
| "otp_expired_button_home": "Login again to get a new OTP", |
| "setup_header": "Add an identity", |
| "setup_text1": "Email address:", |
| "setup_text2": "Your email address will be used as your identity when M-Pin authenticates you to this service.", |
| "setup_text3": "Enter your email", |
| "setup_error_unathorized": "{0} has not been registered in the system.", // {0} will be replaced with the userID |
| "setup_error_server": "Cannot process the request. Please try again later.", |
| "setup_error_signupexpired": "Your signup request has been expired. Please try again.", |
| "setup_button_setup": "Setup M-Pin", |
| "setupPin_header": "Create your M-Pin with {0} digits", // {0} will be replaced with the pin length |
| "setupPin_initializing": "Initializing...", |
| "setupPin_pleasewait": "Please wait...", |
| "setupPin_button_clear": "Clear", |
| "setupPin_button_done": "Setup Pin", |
| "setupPin_errorSetupPin": "ERROR SETTING PIN: {0}", // {0} is the request status code |
| "setupDone_header": "Congratulations!", |
| "edit_identity": "Edit Identity:", |
| "setupDone_text1": "Your M-Pin Identity:", |
| "setupDone_text2": "is set up successfully.", |
| "setupDone_text3": "", |
| "setupDone_button_go": "Sign in with this M-Pin", |
| "setupReady_header": "VERIFY YOUR IDENTITY", |
| "setupReady_text1": "We have sent you an email to", |
| "setupReady_text2": "Click the link in the email to confirm your identity and proceed", |
| "setupReady_text3": "We have just sent you an email, simply click the link to verify your identity.", |
| "setupReady_button_go": "I confirmed my email", |
| "setupReady_button_go_cont": "Setup your M-Pin now", |
| "setupReady_button_resend": "Resend confirmation email", |
| "setupReady_button_resend_cont": "Send it again", |
| "setupNotReady_header": "YOU MUST VERIFY <br/>YOUR IDENTITY", |
| "setupNotReady_text1": "Your identity", |
| "setupNotReady_text2": "has not been verified.", |
| "setupNotReady_text3": "You need to click the link in the email we sent you, and then choose <br/> 'Setup M-Pin'.", |
| "setupNotReady_check_info1": "Checking", |
| "setupNotReady_check_info2": "Identity not verified!", |
| "setupNotReady_resend_info1": "Sending email", |
| "setupNotReady_resend_info2": "Email sent!", |
| "setupNotReady_button_check": "Setup M-Pin", |
| "setupNotReady_button_resend": "Send the email again", |
| "setupNotReady_button_back": "Go to the identities list", |
| "authPin_header": "Enter your M-Pin", |
| "authPin_button_clear": "Clear", |
| "authPin_button_login": "Login", |
| "authPin_button_next": "Next", |
| "authPin_pleasewait": "Authenticating...", |
| "authPin_success": "Success!", |
| "authPin_errorInvalidPin": "Incorrect Pin!", |
| "authPin_errorInvalidAccessNumber": "Invalid access number!", |
| "authPin_errorNotAuthorized": "You are not authorized!", |
| "authPin_errorExpired": "The auth request expired!", |
| "authPin_errorServer": "Server error!", |
| "deactivated_header": "SECURITY ALERT", |
| "deactivated_text1": "has been de-activated and your M-Pin token has been revoked.", |
| "deactivated_text2": "To re-activate your identity, click on the blue button below to register again.", |
| "deactivated_button_register": "Register again", |
| "account_button_addnew": "Add a new identity to this list", |
| "account_button_delete": "Remove Identity", |
| "account_button_reactivate": "Reset PIN", |
| "account_button_backToList": "Back to identity list", |
| "account_button_cancel": "Cancel and go back", |
| "account_delete_question": "Are you sure you wish to remove this M-Pin Identity from this browser?", |
| "account_delete_button": "Yes, remove it", |
| "account_reactivate_question": "Are you sure you wish to reactivate this M-Pin Identity?", |
| "account_reactivate_button": "Yes, re-activate", |
| "noaccount_header": "No identities have been added to this browser!", |
| "noaccount_button_add": "Add a new identity", |
| "pinpad_placeholder_text": "Enter your PIN", |
| "pinpad_placeholder_setup": "Setup your PIN", |
| "pinpad_placeholder_text2": "Enter access number", |
| "logout_text1": "YOU ARE NOW LOGGED IN", |
| "logout_button": "Logout", |
| "home_button_setupMobile": "Add an identity to this browser", |
| "mobile_splash_text": "INSTALL THE M-PIN MOBILE APP", |
| "mobile_add_home_ios": "Tap the icon to 'Add to homescreen'", |
| "help_text_1": "Simply choose a memorable <b>[4 digit]</b> PIN to assign to this identity by pressing the numbers in sequence followed by the 'Setup' button to setup your PIN for this identity", |
| "help_ok_btn": "Ok, Got it", |
| "help_more_btn": "I'm not sure, tell me more", |
| "logout_btn": "Sign out", |
| "success_header": "Success", |
| "success_text": "You are now signed in as:", |
| "accessdenied_header": "Access Denied", |
| "accessdenied_text": "Your M-Pin identity", |
| "accessdenied_text_cont": "has been removed from this device.", |
| "accessdenied_btn": "Register again", |
| "setup_btn_text": "Setup", |
| "setup_device_label": "Device name:", |
| "verify_pin": "Verifying PIN...", |
| "sign_in": "Sign In", |
| "clear": "Clear", |
| "setup": "Setup", |
| "start_over": "Start Over", |
| "embedded_header": "To function properly, M-Pin should be opened in Safari. To open it in Safari, do one of the following:", |
| "embedded_p1": "1. If your QR Code Reader provides the capability to open the page in Safari, please use this option to do so.", |
| "embedded_p2": "2. Copy the URL from the address bar, open Safari, Paste the URL in its address bar and proceed according the on-screen instructions.", |
| }; |
| // image should have config properties |
| hlp.img = function(imgSrc) { |
| return IMAGES_PATH + imgSrc; |
| }; |
| // translate |
| hlp.text = function(langKey) { |
| return mpin.lang[hlp.language][langKey]; |
| }; |
| |
| var setStringOptions = function() { |
| if (typeof(String.prototype.trim) === "undefined") |
| { |
| String.prototype.mpin_trim = function() { |
| return String(this).replace(/^\s+|\s+$/g, ''); |
| }; |
| } else { |
| String.prototype.mpin_trim = String.prototype.trim; |
| } |
| |
| String.prototype.mpin_endsWith = function(substr) { |
| return this.length >= substr.length && this.substr(this.length - substr.length) == substr; |
| } |
| |
| String.prototype.mpin_startsWith = function (substr) { |
| return this.indexOf(substr) == 0; |
| } |
| |
| if (!String.prototype.mpin_format) { |
| String.prototype.mpin_format = function() { |
| var args = arguments; |
| return this.replace(/{(\d+)}/g, function(match, number) { |
| return typeof args[number] != 'undefined' |
| ? args[number] |
| : match |
| ; |
| }); |
| }; |
| } |
| }; |
| })(); |