Creating a sign-in view

With a custom sign-in view, you can replace the default IBM® Cognos® Analytics sign-in page. You can use your own branding and make other changes to the sign-in page.

A high-level overview of the structure of the JavaScript required to perform a sign-in is shown here.

The SampleLogin.zip sample is an example of a view that replace the built-in sign-in view with an alternate version. The SampleWelcome.zip sample contains a spec.json file that defines the view. This file is shown here.

{
	"name": "Sample_Login",
	"schemaVersion": "2.0",
	"extensions": [{
		"perspective":"Sample login",
		"type": "login",
		"features": [{
			"id": "com.sample.login",
			"excludeItems":["com.ibm.bi.glass.navbar","com.ibm.bi.glass.appbar"],
			"content": {
				"type":"v1/ext/Sample_Login/login/js/views/SampleLoginView",
				"options": {
					"info":{
							"title":"Sample login"
							}
				}
			},
			"cssStyles": ["v1/ext/Sample_Login/login/css/SampleLoginCSS.css"]
		}]
	}]
}

This spec.json file is similar to the same file for the SampleWelcome.zip sample except that the value of the type element is login and the Application and Navigation bars are excluded from this view.

A high-level overview of the structure of the JavaScript required to perform a sign-in is shown here.

   /**
   * @typedef {Object} LoginError
   * @property {string} message - error message
   */
   /**
   * performs a login
   *
   * @public
   * @param {Object[]} loginPrompts - object containing the login prompts
   * @param {string} loginPrompts[].name - name of the login prompt
   * @param {string} loginPrompts[].value - value of the login prompt
   * @return {Promise<undefined|LoginError} promise resolved with no object when 
   * the login is successful, rejected with an error when it fails.
   *
   */
   signin: function(loginPrompts)

The SampleLoginView.js file is shown here.

/**
 * Licensed Materials - Property of IBM
 * IBM Cognos Products: BI Glass
 * Copyright IBM Corp. 2017
 * US Government Users Restricted Rights - Use, duplication or disclosure restricted 
 * by GSA ADP Schedule Contract with IBM Corp.
 */
define(['q',
  'text!./SampleLoginView.html',
  ], function(Q, html) {
  'use strict';

  var ContentView = function(){
    
    /**
     * Called by the AppController whenever this view is created
     *
     * @public
     * @returns {Promise} promise resolved to the root DOM element for this view.
     */
    this.open = function(context, options) {
      this.logger = context.logger;
      this.options = options;
      var deferred = Q.defer();
        
      var root = document.createElement('div');
      root.setAttribute('class','welcome');
      
      root.innerHTML = html;
      
      var loginBtn = root.getElementsByClassName('sample.loginBtn')[0];
      loginBtn.onclick = function() {
        document.getElementsByClassName('sampleIncorrectLoginText')[0].innerHTML='';
        var uid = document.getElementsByClassName('sample.username')[0].value;
        var pwd = document.getElementsByClassName('sample.password')[0].value;
        var loginPrompts = [
          {name:'CAMNamespace',value:'CognosEx'},
          {name:'h_CAM_action',value:'logonAs'},
          {name:'CAMUsername',value:uid},
          {name:'CAMPassword',value:pwd}
        ];
        this.signin(loginPrompts).catch(this._loginError.bind(this));
      }.bind(this);


      deferred.resolve(root);
      return deferred.promise;
    },
    
    /**
     * Called by the AppController whenever this view is destroyed
     *
     * @public
     */
    this.close = function() {
      this.logger.info('close');
    },
    
    /**
     * Called by the AppController whenever this view is shown
     *
     * @public
     */
    this.onShow = function() {
      this.logger.info('onShow');
    },
    
    /**
     *
     * The live code below retreives the product's error message.
     * If you would like to include your own error message, use the following 
     * commented code instead:
     *
     * this._loginError = function() {
     *   document.getElementsByClassName('sampleIncorrectLoginText')[0].innerHTML=
     *   'You have entered an invalid username/password combination.';
     *   this.logger.error('loginError',arguments);
     *   },
     *
     *
     */
    this._loginError = function(error) {
      document.getElementsByClassName(
      'sampleIncorrectLoginText')[0].innerHTML=error.message;
      this.logger.error('loginError',arguments);
    },
    
    /**
     * Called by the AppController whenever this view is hidden
     *
     * @public
     */
    this.onHide = function() {
      this.logger.info('onHide');
    },
    
    /**
     * Called by the AppController whenever display Info is required for this view
     *
     * @public
     * @returns {Object} displayInfo - The displayInfo for this view.
     * @returns {string} displayInfo.title - The title.
     * @returns {string} displayInfo.icon - The icon.
     */
    this.getDisplayInfo = function() {
      this.logger.info('getDisplayInfo');
      return {
        'title':this.options.info.title,
        'icon': this.options.info.icon
      };      
    }

  };

  return ContentView;

});

A sign-in view uses one additional method.

promise login(credentials)
This method submits a sign-in request and returns a promise object that is rejected if the sign-in attempt fails.
credentials
Contains the sign-in information.
[{name:'CAMNamespace',value:'<namespace>'},
{name:'h_CAM_action',value:'logonAs'},
{name:'CAMUsername',value:<username>},
{name:'CAMPassword',value:<password>}]