methods/login/index.js

import Api from '../../api';
import recognize from '../../automaticRecognition';
import config from '../../config';
import { cleanErrorEvo, manageError } from '../../errorManager';
import { isValid } from '../../validation';
import utility from '../../utility';
import global from '../../global';
import Method from '../Method';

const formModel = {
    container: 'smartlogin-container',
    username: 'username',
    password: 'passw',
    switchEye: 'login_pass_switch_type',
    loginButton: 'frmbutton',
    fbConnect: 'fb_connect',
    operatorChoice: 'operator'
};

/**
 * @memberOf Useris
 * @function login
 *
 * @description Validate and recognize the login object
 * to be sent to the newton adapter for the login.
 *
 * It must be used with the **smartlogin** template.
 *
 * It also manage the facebook login button.
 * Please note that you have to append the facebook access token
 * once you have logged in with facebook before passing useris response to newton.
 * This why we have decided to leave Useris unaware of Facebook.
 *
 * To allow the facebook integration
 * remember that you have to create and configurate a facebook app for your web applications.
 *
 * @param {Object} options Options object
 * @param {Object} [options.element=false] The div element where the html's tmpl will be injected
 * @param {Object} [options.regexObject={}]
 * **Optional** Contains all the regular expressions for input validation
 * (msisdn, pin, email, password and generic regex are allowed)
 * @param {String} [options.acccess_token=''] **Optionals** if true,
 * the tmpl calls will be called with the params access_token filled
 * @param {Boolean} [options.doNotLoad=false] **Optionals** if true,
 * this params will tell useris to not load the template (It doesn't make the apicall)
 * @param {Object} callbackObject Manage the success and error callback
 * @param {function} [callbackObject.onSuccess='no-default']
 * Success callback (code managed by the app)
 * @param {function} [callbackObject.onError='no-default'] Error callback (code managed by the app)
 * @param {function} [callbackObject.onFacebookSuccess='no-default']
 * Facebook success callback (code managed by the app).
 * You have to ovveride the access_token params before passing it to newton
 * @param {function} [callbackObject.onFacebookError='no-default']
 * Facebook error callback (code managed by the app)
 * @param {function} [callbackObject.onTemplateLoaded='no-default']
 * Callback executed when the template has been loaded.

 *
 * @example
 *  Useris.login({
 *      element: document.getElementById('elementId'),
 *      regexObject: {
 *          msidn: '',
 *          pin: '',
 *          email: '',
 *          password: '',
 *          generic: '',
 *          genericPassword: ''
 *      }
 *  }, {
 *      onSuccess: function(userCredentials){
 *          console.log(userCredentials);
 *          callsToNewtonAdapter.login(userCredentials);
 *      },
 *      onError: function(error){
 *          console.log('Error:', error);
 *          manageError(error);
 *      },
 *      onFacebookSuccess: function(userCredentials){
 *          console.log(userCredentials);
 *          FB.login(function(fbResponse){
 *              if(fbResponse.status === 'connected'){
 *                  // override the access_token params
 *                  userCredentials.access_token = FB.getAccessToken();
 *                  callsToNewtonAdapter.login(userCredentials);
 *              }
 *          }
 *      },
 *      onFacebookError: function(error){
 *          console.log('Error:', error);
 *          manageError(error);
 *      },
 *      onTemplateLoaded: function(tmplInfo){
 *          console.log('Template loaded', tmplInfo);
 *      }
 *  });
 *
 * @returns {object}
 * **Msisdn case:**
 * <pre>
 *     {
 *         msisdn: string,
 *         pin: string,
 *         type: 'msisdn',
 *         logged: boolean
 *     }
 * </pre>
 *
 * **Email case:**
 * <pre>
 *     {
 *         email: string,
 *         password: string,
 *         type: 'email',
 *         logged: boolean
 *     }
 * </pre>
 *
 * **Generic case:**
 * <pre>
 *     {
 *         username: string,
 *         password: string,
 *         type: 'generic',
 *         logged: boolean
 *     }
 * </pre>
 */

export default class Login extends Method {
    init = (options) => {
        this.queryParams = utility.getQueryParams();
        this.smartsectionObj = {
            subsection: 'smartlogin',
            loadForm: options.element || false,
            sentpin: this.queryParams.sentpin || 0,
            access_token: options.access_token || '',
            doNotLoad: options.doNotLoad || false
        };
        this.initUserView();
    };

    attachEvents = () => {
        const usernameInput = this.UserViewInstance.getElement(formModel.username);
        const passwordInput = this.UserViewInstance.getElement(formModel.password);
        const switchEye = this.UserViewInstance.getElement(formModel.switchEye);
        const operatorChoiceArray = config.get('operatorList') ? this.UserViewInstance.getElementsByName(formModel.operatorChoice) : false;
        const loginButton = this.UserViewInstance.getElement(formModel.loginButton);
        let facebookButton = false;
        if (config.get('identityFbEnabled')) {
            facebookButton = this.UserViewInstance.getElement(formModel.fbConnect);
        }

        this.UserViewInstance.attachEvent(loginButton, {
            eventName: 'click',
            event: (e) => {
                e.preventDefault();
                cleanErrorEvo();

                let username = usernameInput.value;
                const password = passwordInput.value;

                try {
                    switch (recognize(username, password, this.regexObject)) {
                    case 'MSISDN':
                        if (config.get('enableAliasCheck')) {
                            if (username.indexOf('+') >= 0) {
                                username = username.replace('+', '');
                            }

                            Api.getAlias({
                                msisdn: username
                            }).then((response) => {
                                this.callback('onSuccess', {
                                    alias: response.alias,
                                    pin: password,
                                    type: 'alias',
                                    logged: true
                                });
                            }).catch((error) => {
                                global.logger.log('Error: Can\'t get Alias from this username');
                                manageError(error, formModel.container);
                            });
                        } else if (operatorChoiceArray) {
                            this.callback('onSuccess', {
                                msisdn: username,
                                pin: password,
                                type: 'msisdn',
                                operator: this.UserViewInstance
                                    .getCheckedRadioValue(operatorChoiceArray),
                                logged: true
                            });
                        } else {
                            this.callback('onSuccess', {
                                msisdn: username,
                                pin: password,
                                type: 'msisdn',
                                logged: true
                            });
                        }
                        break;
                    case 'EMAIL':
                        this.callback('onSuccess', {
                            password,
                            email: username,
                            type: 'email',
                            logged: true
                        });
                        break;
                    default:
                        this.callback('onSuccess', {
                            username,
                            password,
                            type: 'generic',
                            logged: true
                        });
                        break;
                    }
                } catch (error) {
                    manageError(error, formModel.container);
                }
            }
        });

        if (switchEye) {
            this.UserViewInstance.attachEvent(switchEye, {
                eventName: 'click',
                event: (e) => {
                    e.preventDefault();
                    this.UserViewInstance.switchInputType(formModel.password, switchEye.id);
                }
            });
        }

        if (facebookButton) {
            this.UserViewInstance.attachEvent(facebookButton, {
                eventName: 'click',
                event: (e) => {
                    e.preventDefault();
                    this.callback('onFacebookSuccess', {
                        type: 'oauth',
                        provider: 'facebook',
                        logged: true
                    });
                }
            });
        }

        if (!config.get('enableAliasCheck')) {
            if (this.queryParams.msisdn) {
                this.UserViewInstance
                    .setValue(formModel.username, decodeURIComponent(this.queryParams.msisdn));
            } else if (this.queryParams.email) {
                this.UserViewInstance
                    .setValue(formModel.username, decodeURIComponent(this.queryParams.email));
            }
        }

        /* add on keyup event listener to disable password input for login
            where is required just the msisdn and not the pin */

        if (config.get('disablePinInput')) {
            this.UserViewInstance.attachEvent(usernameInput, {
                eventName: 'keyup',
                event: () => {
                    const isDisabled = passwordInput.disabled;
                    const value = this.UserViewInstance.getValue(formModel.username);
                    if (isValid(value, this.regexObject.msisdn)) {
                        this.UserViewInstance.disable(formModel.password);
                        this.UserViewInstance.setValue(formModel.password, '');
                    } else if (isDisabled) {
                        passwordInput.disabled = false;
                    }
                }
            });
        }
    }
}