Merge https://github.com/miracl/milagro-mfa-js-client
diff --git a/README.md b/README.md
index 3eb634b..9173e12 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,14 @@
The Mobile App is a JavaScript application, much similar to the PIN Pad. The Mobile App also carries out the operations needed to register and authenticate an end-user, but the user is authenticated to a browser session, rather than to a session on the mobile device.
+##Building automatically the PIN Pad
+You can run the following script to install all dependencies for you and build both the PIN PAD and Mobile App
+```
+ > ./build.sh
+```
+It is building with default Milagro theme.
+The built apps should be placed in `<work-dir>/build/out/browser` and `<work-dir>/build/out/mobile`.
+
##Building the PIN Pad
1. NOTE: You might have to update your package distribution system. For Ubuntu you would need to do: `sudo apt-get update`
diff --git a/browser/bower.json b/browser/bower.json
index 2d4f014..80e55f4 100644
--- a/browser/bower.json
+++ b/browser/bower.json
@@ -7,7 +7,7 @@
],
"dependencies": {
"milagro-crypto": "https://github.com/miracl/milagro-crypto.git#1.0.0",
- "milagro-mfa-js-lib": "https://github.com/miracl/milagro-mfa-js-lib.git#1.0.0",
+ "milagro-mfa-js-lib": "https://github.com/miracl/milagro-mfa-js-lib.git#1.1.0",
"qrcodejs": "0.1.0",
"handlebars": "~3.0.3"
},
diff --git a/browser/js/mpin.js b/browser/js/mpin.js
index 52079bc..2892fb4 100644
--- a/browser/js/mpin.js
+++ b/browser/js/mpin.js
@@ -21,10 +21,9 @@
(function () {
"use strict";
- var lang = {}, hlp = {}, loader, MPIN_URL_BASE, IMAGES_PATH, CSS_FILENAME, TEMPLATE_NAME;
+ var lang = {}, hlp = {}, loader, MPIN_URL_BASE, IMAGES_PATH, CSS_FILENAME;
MPIN_URL_BASE = "%URL_BASE%";
- TEMPLATE_NAME = "%TEMPLATE_NAME%";
- IMAGES_PATH = MPIN_URL_BASE + "/images/" + TEMPLATE_NAME + "/";
+ IMAGES_PATH = MPIN_URL_BASE + "/images/";
CSS_FILENAME = "main.css";
@@ -74,7 +73,8 @@
}
self.mpinLib = new mpinjs({
- server: mpinServer
+ server: mpinServer,
+ authProtocols: options.authProtocols || ""
});
domID = options.targetElement;
@@ -439,7 +439,6 @@
this.mpinLib.cancelMobileAuth();
};
- // Access NUMBER
mpin.prototype.renderMobile = function () {
var callbacks = {}, self = this;
@@ -454,6 +453,43 @@
self.clrInterval.call(self);
self.renderHome.call(self, evt);
};
+
+ callbacks.mpin_action_setup = function () {
+ self.clrInterval.call(self);
+ if (self.opts.mobileConfigURL) {
+ self.renderMobileConfig.call(self);
+ } else {
+ self.renderMobileSetup.call(self);
+ }
+ };
+
+ callbacks.mpin_desktop = function () {
+ self.clrInterval.call(self);
+ self.renderDesktop.call(self);
+ };
+
+ this.render("mobile-qr", callbacks, {mobileOnly: !this.opts.mobileOnly});
+
+ setTimeout(function () {
+ self.getQrParams.call(self);
+ }, 0);
+ };
+
+ // Access NUMBER
+ mpin.prototype.renderMobileAN = function () {
+ var callbacks = {}, self = this;
+
+ this.clrInterval();
+
+ if (this.opts.requestOTP === "1") {
+ this.renderMobileSetup();
+ return;
+ }
+
+ callbacks.mpin_home = function (evt) {
+ self.clrInterval.call(self);
+ self.renderHome.call(self, evt);
+ };
callbacks.mpin_action_setup = function () {
self.clrInterval.call(self);
if (self.opts.mobileConfigURL) {
@@ -488,6 +524,8 @@
}, 0);
};
+
+
mpin.prototype.renderHelp = function (tmplName, callbacks, tmplData) {
var k, self = this;
tmplData = tmplData || {};
@@ -603,7 +641,7 @@
//set Temporary params if enter email and then press tooltip without submit request...
function setTemp () {
self.tmp || (self.tmp = {});
- self.tmp.setupEmail = document.getElementById("emailInput").value;
+ self.tmp.setupEmail = document.getElementById("emailInput").value.toLowerCase();
if (self.opts.setDeviceName) {
self.tmp.setupDeviceName = document.getElementById("deviceInput").value;
}
@@ -671,7 +709,7 @@
//set Temporary params if enter email and then press tooltip without submit request...
function setTemp () {
self.tmp || (self.tmp = {});
- self.tmp.setup2Email = document.getElementById("emailInput").value;
+ self.tmp.setup2Email = document.getElementById("emailInput").value.toLowerCase();
if (self.opts.setDeviceName) {
self.tmp.setup2DeviceName = document.getElementById("deviceInput").value;
}
@@ -984,6 +1022,27 @@
this.clrInterval.call(this);
};
+ mpin.prototype.getQrParams = function () {
+ var self = this;
+ this.mpinLib.getQrUrl("", function (err, data) {
+ var qrElem, expireAfter;
+ if (err) {
+ self.error(4010);
+ }
+
+ var qrElem = document.getElementById("mp_qrcode");
+ new QRCode(qrElem, {
+ text: data.qrUrl,
+ width: 158,
+ height: 158
+ });
+
+ expireAfter = data.ttlSeconds;
+
+ self._getAccess.call(self, expireAfter);
+ });
+ };
+
mpin.prototype.getAccessNumber = function () {
var self = this, drawTimer, timerEl, timer2d, totalSec, timerExpire, expire;
@@ -1057,9 +1116,30 @@
}
self.successLogin.call(self, accData);
+ }, function (accData) {
+ return self.updateStatus(accData);;
});
};
+ mpin.prototype.updateStatus = function (statusData) {
+ var statusText;
+
+ switch (statusData.status) {
+ case "wid":
+ statusText = "<span>Code scanned.<br/>Waiting for authentication...</span>";
+ break;
+ case "user":
+ statusText = "<span>Authenticating user:<br/>" + statusData.userId + "</span>";
+ break;
+ case "expired":
+ statusText = "<span>Authentication expired!</span>";
+ break;
+ }
+
+ document.getElementById("mp_qrcode").removeAttribute('title');
+ statusText && (document.getElementById("mp_qrcode").innerHTML = statusText);
+ };
+
mpin.prototype.renderMobileSetup = function () {
var callbacks = {}, self = this, qrElem, mobileBtnText = "";
callbacks.mpin_home = function () {
@@ -1335,7 +1415,7 @@
};
mpin.prototype.renderSetupDone = function () {
var callbacks = {}, self = this, userId;
- userId = this.readIdentity() || this.identity;
+ userId = this.readIdentity() || this.identity;
callbacks.mpin_home = function () {
self.renderHome.call(self);
};
@@ -1712,7 +1792,7 @@
mpin.prototype.actionSetupHome = function (uId) {
var self = this, _email, _deviceName, _deviceNameInput, removeError, elems = [];
- _email = (uId) ? uId : document.getElementById("emailInput").value;
+ _email = (uId) ? uId : document.getElementById("emailInput").value.toLowerCase();
_deviceNameInput = (document.getElementById("deviceInput")) ? document.getElementById("deviceInput").value.trim() : "";
if ((_email.length === 0 || !this.opts.identityCheckRegex.test(_email)) && !(this.opts.prerollid)) {
@@ -2302,6 +2382,7 @@
"signin_btn_mobile1": "Sign in with Smartphone",
"signin_mobile_btn_text": "Sign in with your Smartphone",
"signin_mobile_header": "Sign in with your phone",
+ "scan_mobile_header": "Scan with the M-Pin app",
"signin_mobile_btn_text2": "Sign in with phone",
"signin_button_mobile": "Sign in with Phone",
"signin_btn_mobile2": "(This is a PUBLIC device I DO NOT trust)",
diff --git a/browser/themes/milagro/sass/_template.scss b/browser/themes/milagro/sass/_template.scss
index e956bb0..d9dfd9d 100644
--- a/browser/themes/milagro/sass/_template.scss
+++ b/browser/themes/milagro/sass/_template.scss
@@ -367,6 +367,13 @@
@mixin buttons-box() {
padding: 5% 5%;
z-index: 99;
+
+ .qrCodeArea {
+ width: 160px;
+ height: 160px;
+ display: block;
+ margin: 0 auto 20px;
+ }
}
@mixin mpin-input-field () {
diff --git a/browser/themes/milagro/views/mobile-qr.handlebars b/browser/themes/milagro/views/mobile-qr.handlebars
new file mode 100644
index 0000000..8109e1d
--- /dev/null
+++ b/browser/themes/milagro/views/mobile-qr.handlebars
@@ -0,0 +1,33 @@
+<div class="mpinHeader mpMobileColor">
+ <div class="mpinLogo"></div>
+ <div class="mpinHome mpPointer" id="mpin_home"></div>
+</div>
+
+<div class="mpinHeaderBig mpPaddTop10 mpPaddBot10 mpMobColor">
+ {{txt "scan_mobile_header"}}
+</div>
+
+<div class="mpinMain mpNoHeight">
+ <div class="mpinBtnBox mpNoPadding">
+
+ <span id="mp_qrcode" class="qrCodeArea">
+ </span>
+
+ <div class="mpinButton mpinMobileBtn mpinBtnClick" id="mpin_action_setup">
+ {{txt "mobile_button_setup"}}
+ </div>
+
+ {{#if data.mobileOnly }}
+ <div class="mpinButton mpinButtonDark mpinBtnClick" id="mpin_desktop">
+ {{txt "mobile_button_signin2"}}
+ </div>
+ {{/if}}
+
+ </div>
+</div>
+
+
+<div class="mpinFooter mpMobileFooter">
+ <div class="mpinPowered"></div>
+ <div class="mpinHelpHub"></div>
+</div>
\ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..e6d99e6
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,47 @@
+#!/usr/bin/env bash
+
+BASE_DIR=$(pwd)
+
+function install_needed_tools {
+ # update package manager cache
+ sudo apt-get update
+
+ # install node package manager npm
+ sudo apt-get install npm curl git
+
+ sudo npm config set prefix /usr/local
+
+ sudo npm install -g n
+ sudo n 0.10.33
+
+ # Install grunt
+ sudo npm install -g grunt-cli
+
+ # Install handlebars
+ sudo npm install -g handlebars@3.0.1
+
+ # install bower
+ sudo npm install -g bower
+}
+
+function build_mpin {
+ APP_TYPE=$1
+ cd "$BASE_DIR/$APP_TYPE"
+
+ # Install required modules for Node
+ sudo npm install
+
+ # Create settings.json
+ cp settings.json_build settings.json
+
+ # Build the app
+ grunt build
+}
+
+install_needed_tools
+
+# Build browser mpin
+build_mpin browser
+
+# Build mobile mpin
+build_mpin mobile
diff --git a/mobile/js/main.js b/mobile/js/main.js
index 488ec78..970122c 100644
--- a/mobile/js/main.js
+++ b/mobile/js/main.js
@@ -1682,7 +1682,7 @@
var _email, _deviceName, _deviceNameInput, _reqData = {}, self = this, elems = [], removeError;
- _email = (uId) ? uId : document.getElementById("emailInput").value;
+ _email = (uId) ? uId : document.getElementById("emailInput").value.toLowerCase();
if (_email.length === 0 || !this.opts.emailCheckRegex.test(_email)) {
document.getElementById("emailInput").focus();