123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- /*
- *+------------------------------------------------------------------------+
- *| Licensed Materials - Property of IBM
- *| IBM Cognos Products: BI Content Explorer
- *| (C) Copyright IBM Corp. 2015, 2019
- *|
- *| US Government Users Restricted Rights - Use, duplication or disclosure
- *| restricted by GSA ADP Schedule Contract with IBM Corp.
- *+------------------------------------------------------------------------+
- */
- define([
- 'bi/glass/app/ContentView',
- './nls/StringResource',
- 'jquery',
- 'underscore',
- 'doT',
- 'text!./templates/QRSlideoutViewTemplate.html',
- './lib/qrcode/build/qrcode'
- ], function (ContentView, StringResource, $, _, dot, CAMobileTemplate, QRCode) {
- 'use strict';
- var QRSlideoutView = ContentView.extend({
- init: function(options) {
- QRSlideoutView.inherited('init', this, arguments);
- _.extend(this, options);
- this.$el.addClass('caMobilePaneContainer');
- },
- open: function(context, options) {
- this.glassContext = __glassAppController.glassContext; // eslint-disable-line no-undef
- this.options = options;
- this.render();
- return Promise.resolve();
- },
- generateSlideout: function () {
- return dot.template(CAMobileTemplate)({
- 'strings': {
- 'getMobileApp': StringResource.get('getMobileApp').toUpperCase(),
- 'cognosAnalytics': StringResource.get('cognosAnalytics'),
- 'downloadMobileApp': StringResource.get('downloadMobileApp'),
- 'genQRCode': StringResource.get('genQRCode'),
- 'mobileTwoFactor': StringResource.get('mobileTwoFactor'),
- 'learnMore': StringResource.get('learnMore'),
- 'appIos': StringResource.get('appIos'),
- 'appAndroid': StringResource.get('appAndroid'),
- 'appUseMessage': StringResource.get('appUseMessage').toUpperCase(),
- 'getAppMessage': StringResource.get('getAppMessage'),
- 'appIcon': this.options.appIcon
- }
- });
- },
- addEventListeners: function () {
- $('#mobileGenQR').click(this.onGenerateQRClick.bind(this));
- $('.mobileTwoFactorMessage').click(this.onSecondFactorClick.bind(this));
- },
- /**
- * Render the mobile app property page view.
- */
- render: function() {
- var slideoutHtml = this.generateSlideout();
- this.$el.append(slideoutHtml);
- this.addEventListeners();
- return Promise.resolve(this.$el);
- },
- formatSecondFactorCountdownTime: function(startTime, expirationTime) {
- const differenceInTime = expirationTime - startTime;
- const minutes = Math.floor((differenceInTime % (1000 * 60 * 60)) / (1000 * 60));
- const seconds = Math.floor((differenceInTime % (1000 * 60)) / 1000);
- const timeAsString = this.padTimeNumber(minutes) + ':' + this.padTimeNumber(seconds);
- return timeAsString;
- },
- padTimeNumber: function(number) {
- number = String(number);
- while (number.length < 2) {number = '0' + number;}
- return number;
- },
- setCountdownInterval: function(secondFactor) {
- const displayElement = $('.mobileQRTwoFactorTimer');
- const finalTime = Date.parse(secondFactor.expires);
- var now;
- var timer = setInterval(function() {
- now = new Date().getTime();
- var differenceInTime = finalTime - now;
- displayElement.html(this.formatSecondFactorCountdownTime(now, finalTime));
- if (differenceInTime < 0) {
- clearInterval(timer);
- displayElement.html(StringResource.get('tokenExpired'));
- }
- }.bind(this), 1000);
- },
- generateQR: function (deepLink) {
- QRCode.toCanvas(document.getElementById('mobileQRCodeCanvas'), deepLink, function(err) {
- if(err) console.log(err);
- });
- this.hideGenerateQRDialog();
- },
- hideGenerateQRDialog: function () {
- $('#mobileQRCodeCanvas').style = 'width: 200px; height: 200px';
- $('#mobileGenQR').addClass('hidden');
- },
- displayTwoFactor: function (secondFactor) {
- const startTime = new Date().getTime();
- const expirationTime = Date.parse(secondFactor.expires);
- $('.mobileQRTwoFactor').removeClass('hidden');
- $('.mobileQRTwoFactorPin').html(secondFactor.value);
- $('.mobileQRTwoFactorTimer').html(this.formatSecondFactorCountdownTime(startTime, expirationTime));
- },
- /**
- * Generates a QR code and places it into the QRCodeCanvas element
- */
- onGenerateQRClick: function() {
- this.retrieveLoginToken().then(function(response) {
- const secondFactor = response.secondFactor;
- const deepLink = this.formatDeepLink(response);
- this.generateQR(deepLink);
- this.displayTwoFactor(secondFactor);
- this.setCountdownInterval(secondFactor);
- }.bind(this)).catch(function() {
- const deepLink = this.formatDeepLink();
- this.generateQR(deepLink);
- }.bind(this));
- },
- /**
- * Takes in the JSON response of v1/loginToken and outputs a deeplink to the app
- * Also removes the second factor from the response
- */
- formatDeepLink: function(response) {
- // Save the secondFactor locally and remove it from the json
- var deepLink = `camobile://?serverUrl=${encodeURIComponent(this.getServerURL())}`;
- if(response) {
- deepLink = deepLink +
- `&loginToken=${encodeURIComponent(JSON.stringify(response.loginToken))}` +
- `&x-ca-affinity=${encodeURIComponent(response.affinityHeader)}`;
- }
- return deepLink;
- },
- /**
- * Displays the second factor and sets a countdown
- */
- onSecondFactorClick: function() {
- if(!this.secondFactor) {
- return false;
- }
- $('.mobileTwoFactorPin').html(this.secondFactor.value);
- $('.mobileTwoFactor').removeClass('hidden');
- var expirationDate = Date.parse(this.secondFactor.expires);
- var now = new Date().getTime();
- $('.mobileTwoFactorTimer').html(this.formatSecondFactorCountdownTime(now, expirationDate));
- this._createCountdownInterval($('.mobileTwoFactorTimer'), expirationDate);
- },
- /**
- * Call user profile services to retrieve the loginToken
- */
- retrieveLoginToken: function() {
- var options = {
- 'url': 'v1/loginToken',
- 'dataType': 'json',
- 'type': 'POST'
- };
- return this.glassContext.getCoreSvc('.Ajax').ajax(options)
- .then(function(response) {
- const payload = response.data;
- payload.affinityHeader = response.jqXHR.getResponseHeader('x-ca-affinity');
- return Promise.resolve(payload);
- }.bind(this)).catch(this.handleLoginTokenError.bind(this));
- },
- handleLoginTokenError: function(err) {
- this.logger.error(err);
- return Promise.reject(err);
- },
- getServerURL: function() {
- return window.location.origin;
- }
- });
- return QRSlideoutView;
- });
|