Skip to content
Snippets Groups Projects
join-controllers.js 16.9 KiB
Newer Older
angular.module('cesium.join.controllers', ['cesium.services'])
  .config(function($stateProvider) {
      .state('app.join', {
        url: "/join",
        views: {
          'menuContent': {
            templateUrl: "templates/home/home.html",
            controller: 'JoinCtrl'
          }
        }
      })
  .controller('JoinCtrl', JoinController)
  .controller('JoinChooseAccountTypeModalCtrl', JoinChooseAccountTypeModalController)
  .controller('JoinModalCtrl', JoinModalController)
function JoinController($scope, $timeout, $controller, Modals, csWallet) {
  // Initialize the super class and extend it.
  angular.extend(this, $controller('HomeCtrl', {$scope: $scope}));

  $scope.showJoinModal = function() {
    if ($scope.loading) return $timeout($scope.showJoinModal, 500); // recursive call

    if (!csWallet.isLogin() && !$scope.error) {
      return $timeout(Modals.showJoin, 300);
    }
  };
  $scope.$on('$ionicView.enter', $scope.showJoinModal);

function JoinChooseAccountTypeModalController($scope, $state, Modals, UIUtils, csConfig, csCurrency) {
  'ngInject';

  $scope.formData = {};
  $scope.slides = {
    slider: null,
    options: {
      loop: false,
      effect: 'slide',
      speed: 500
    }
  };
  $scope.loading = true;

  $scope.load = function() {
    if ($scope.loading) {
      return csCurrency.get()
        .then(function (currency) {
          if (!currency) return;
          $scope.currency = currency;
          $scope.formData.currency = currency.name;
          $scope.loading = false;
        })
        .catch(UIUtils.onError('ERROR.GET_CURRENCY_FAILED'));
    }
  };
  $scope.$on('modal.shown', $scope.load);

  $scope.$on("$ionicSlides.sliderInitialized", function(event, data){
    // Disable swipe
    data.slider.lockSwipes();
  });

  $scope.slidePrev = function() {
    $scope.slides.slider.unlockSwipes();
    $scope.slides.slider.slidePrev();
    $scope.slides.slider.lockSwipes();
  };

  $scope.slideNext = function() {
    $scope.slides.slider.unlockSwipes();
    $scope.slides.slider.slideNext();
    $scope.slides.slider.lockSwipes();
  };
  $scope.selectAccountTypeAndClose = function(type) {
    $scope.formData.accountType = type;
    $scope.closeModal($scope.formData);
  };

  /**
   * Catch click for quick fix
   * @param fix
   */
  $scope.doQuickFix = function(event) {
    if (event == 'settings') {
      $scope.closeModal();
      $state.go('app.settings');
    }
  };

  $scope.showHelpModal = function(helpAnchor) {
    Modals.showHelp({anchor: helpAnchor});
  };

  // TODO DEV only
  //$timeout(function() {
   //$scope.selectCurrency('g1');
   //$scope.selectAccountTypeAndClose('member');
   //}, 400);
function JoinModalController($scope, $state, $interval, $q, $timeout, Device, UIUtils, CryptoUtils, csSettings, Modals, csWallet, BMA, parameters) {
    pseudo: parameters.uid || '',
    pubkey: parameters.pubkey || undefined
  $scope.slides = {
    slider: null,
    options: {
      loop: false,
      effect: 'slide',
      speed: 500,
      pager: false,
      showPager: false
  $scope.slideBehavior = {};
  $scope.loading = true;
  $scope.isLicenseRead = Device.isIOS(); // always enable the button, on IOS  fix #554
  $scope.showUsername = false;
  $scope.showPassword = false;
  $scope.formData.computing=false;
  $scope.smallscreen = UIUtils.screen.isSmall();
  $scope.userIdPattern = BMA.constants.regexp.USER_ID;
  $scope.accountAvailable = !!parameters.pubkey;
  // Read input parameters
  $scope.currency = parameters.currency;
  $scope.accountType = parameters.accountType || 'member';

  $scope.load = function() {
    if ($scope.loading) {

      // Get the wallet
      wallet = (parameters.walletId && csWallet.children.get(parameters.walletId)) ||
        (parameters.pubkey && csWallet.children.getByPubkey(parameters.pubkey)) ||
        ((!parameters.pubkey || csWallet.isUserPubkey(parameters.pubkey)) && csWallet);
      if (!wallet) throw new Error("Cannot found the corresponding wallet, from parameters.pubkey or parameters.walletId");

      console.debug("[join] Starting join modal on wallet {0}".format(wallet.id));

      if ($scope.accountType === 'member') {
        $scope.licenseFileUrl = csSettings.getLicenseUrl();
        if ($scope.licenseFileUrl) {
          // Use HTML in iframe, when original file is markdown (fix #538)
          if ( $scope.licenseFileUrl.substring($scope.licenseFileUrl.length - 3) != '.txt') {
            $scope.licenseFileUrl = $scope.licenseFileUrl + '.html';
          }
          if (!$scope.isLicenseRead) {
            //$scope.startListenLicenseBottom();

            // Make sure to enable the next button when error occured - Fix issue #592
            $timeout(function() {
              if (!$scope.isLicenseRead) {
                $scope.isLicenseRead = true;
              }
            }, 5000);

      $scope.slideBehavior = $scope.computeSlideBehavior();
      $scope.loading = false;
  };
  $scope.$on('modal.shown', $scope.load);
  $scope.$on("$ionicSlides.sliderInitialized", function(event, data){
    // Disable swipe
    data.slider.lockSwipes();
  });

  $scope.slidePrev = function() {
    $scope.slides.slider.unlockSwipes();
    $scope.slides.slider.slidePrev();
    $scope.slides.slider.lockSwipes();
  $scope.slideNext = function() {
    $scope.slides.slider.unlockSwipes();
    $scope.slides.slider.slideNext();
    $scope.slides.slider.lockSwipes();
  };

  $scope.showAccountPubkey = function() {
    if (parameters.pubkey && parameters.pseudo === $scope.formData.pseudo) {
      $scope.formData.pubkey = parameters.pubkey;
      $scope.formData.computing = false;
      return;
    }

    $scope.formData.computing=true;
    CryptoUtils.scryptKeypair($scope.formData.username, $scope.formData.password)
      .then(function(keypair) {
        $scope.formData.pubkey = CryptoUtils.util.encode_base58(keypair.signPk);
        return $scope.checkAccountAvailable();
      })
      .then(function() {
        return $timeout(function(){
          $scope.formData.computing=false;
        }, 400);
        $scope.formData.pubkey = undefined;
        UIUtils.onError('ERROR.CRYPTO_UNKNOWN_ERROR')(err);
  $scope.formDataChanged = function() {
    $scope.formData.computing=false;
    $scope.formData.pubkey=null;
  $scope.getCurrentFormName = function() {
    var index = $scope.slides.slider.activeIndex;
    if($scope.accountType === 'member') {
      index += ($scope.licenseFileUrl ? 0 : 1); // skip index 0, when no license file
      index += (parameters.pubkey && index >= 2 ? 2 : 0); // skip salt+pass, if already a pubkey
      if (index === 0) return "licenseForm";
      if (index === 1) return "pseudoForm";
      if (index === 2) return "saltForm";
      if (index === 3) return "passwordForm";
      if (index === 4) return "confirmForm";
    }
    else {
      if (index === 0) return "saltForm";
      if (index === 1) return "passwordForm";
      if (index === 2) return "confirmForm";
    }
  };
  $scope.computeSlideBehavior = function() {
    var formName = $scope.getCurrentFormName();

        hasPreviousButton: false,
        hasNextButton: false,
        hasAcceptButton: true
      };
        helpAnchor: 'join-pseudo',
        hasPreviousButton: $scope.licenseFileUrl && true,
        hasNextButton: true,
        focus: 'pseudo'
        helpAnchor: 'join-salt',
        hasPreviousButton: $scope.accountType === 'member',
        hasNextButton: true,
        focus: 'salt'
        helpAnchor: 'join-password',
        hasPreviousButton: true,
        hasNextButton: true,
        focus: 'password'
        hasPreviousButton: true,
        hasNextButton: false,
        hasSendButton: true,
        helpAnchor: 'join-pubkey'
    else {
      behavior = {
        hasPreviousButton: false,
        hasNextButton: true
      };
    }

    // removeIf(device)
    // Focus input text (only if NOT device, to avoid keyboard opening)
ArnaudCerisier's avatar
ArnaudCerisier committed
    // FIXME: this cause issue #464
    /*if (behavior.focus) {
      $timeout(function(){
        $focus(behavior.focus);
      }, 100);
ArnaudCerisier's avatar
ArnaudCerisier committed
    }*/
    // endRemoveIf(device)

    return behavior;
  };


  $scope.doNext = function() {
    var formName = $scope.getCurrentFormName();
    if (formName && $scope[formName]){
      $scope[formName].$submitted=true;
      if(!$scope[formName].$valid) {
        return;
      }
      if (formName === "pseudoForm" && $scope.uiAlreadyUsed) {
        return;
      }
      if (formName === "passwordForm") {

    $scope.slideNext();

    $scope.slideBehavior = $scope.computeSlideBehavior();
  $scope.doPrev = function() {
    $scope.slidePrev();
    $scope.slideBehavior = $scope.computeSlideBehavior();
  };

  $scope.doNewAccount = function(confirm) {

    if (!confirm) {
      var messageKey = ($scope.accountType === 'member') ? 'ACCOUNT.NEW.CONFIRMATION_MEMBER_ACCOUNT' :
        'ACCOUNT.NEW.CONFIRMATION_WALLET_ACCOUNT';

      return UIUtils.alert.confirm(messageKey, undefined,
        {
          cssClass: 'warning',
          okText: $scope.accountType == 'member' ? 'COMMON.BTN_SEND' : 'COMMON.BTN_CONTINUE',
          okType: 'button-assertive'
        })
        .then(function(confirm) {
          if (confirm) {
            $scope.doNewAccount(true);
    var onErrorLogout = function(message) {
      return function(err) {
        if (parameter.uid) {
          wallet.unauth()
            .then(function(){
              UIUtils.onError(message)(err);
            });
        }
        else {
          wallet.logout()
            .then(function(){
              UIUtils.onError(message)(err);
            });
        }
        throw new Error('CANCELLED');
Benoit Lavenier's avatar
Benoit Lavenier committed
      };
    };
    UIUtils.loading.show();
Benoit Lavenier's avatar
Benoit Lavenier committed
        auth: true,
        isNew: true,
        method: 'SCRYPT_DEFAULT',
        expectedPubkey: $scope.formData.pubkey,
        showMethods: false
      })
      .then(function() {
        if ($scope.accountType === "member") {
          $scope.closeModal();
          csSettings.data.wallet = csSettings.data.wallet || {};
          csSettings.data.wallet.alertIfUnusedWallet = false; // do not alert if empty
          var needSelf = angular.isUndefined(parameters.uid) || angular.isUndefined(parameters.blockUid) ||
            (parameters.uid !== $scope.formData.pseudo);
Benoit Lavenier's avatar
Benoit Lavenier committed
            wallet.setSelf(parameters.uid, parameters.blockUid);
          }

          // Self promise (if need)
          var selfPromise = needSelf ?
            wallet.self($scope.formData.pseudo, false/*do NOT load membership here*/)
              .catch(onErrorLogout('ERROR.SEND_IDENTITY_FAILED')) :
            $q.when();

          return selfPromise
            .then(function() {
              // Send membership IN
              return wallet.membership.inside()
                .catch(function(err) {
                  if (err && err.ucode != BMA.errorCodes.MEMBERSHIP_ALREADY_SEND) return;
                  onErrorLogout('ERROR.SEND_MEMBERSHIP_IN_FAILED')(err);
                });
            .then(function() {

              $scope.closeModal();

              // Redirect to wallet
              if (wallet.isDefault()) {
                return $state.go('app.view_wallet');
              } else {
                return $state.go('app.view_wallet_by_id', {id: wallet.id});
              }
            })
            .then(function() {
              // Wait 2s (for wallet load)
              // then ask to download revocation file
              return $timeout(function() {
                // Hide the loading indicator, if wallet already loaded
                if (wallet.isDataLoaded({requirements: true})) {
                  UIUtils.loading.hide();
                }
                return $scope.downloadRevocationRegistration();
              },
              2000);
            });
        }
        else{
          $scope.closeModal();
          // Redirect to wallet
          if (wallet.isDefault()) {
            $state.go('app.view_wallet');
          }
          else {
            $state.go('app.view_wallet_by_id', {id: wallet.id});
          }
        }
      })
      .catch(function(err) {
        UIUtils.loading.hide();
        if (err === 'CANCELLED') return;
        if (err && err.ucode != BMA.errorCodes.MEMBERSHIP_ALREADY_SEND) {
          console.error("[wallet] Node: already membership", err);
          return; // OK
        }
        else {
          UIUtils.alert.error('ERROR.UNKNOWN_ERROR');
        }
  $scope.downloadRevocationRegistration = function() {
    return UIUtils.alert.confirm('DOWNLOAD.POPUP_REVOKE_MESSAGE', 'DOWNLOAD.POPUP_TITLE', {
        cssClass: 'warning',
        okText: 'COMMON.BTN_DOWNLOAD',
        okType: 'button-assertive',
        cancelText: 'COMMON.BTN_LATER'
      })
    .then(function(confirm) {
      if (!confirm) return;
  $scope.showHelpModal = function(helpAnchor) {
    Modals.showHelp({anchor: helpAnchor});
  };
  $scope.startListenLicenseBottom = function(){
    var iframeEl = angular.element(document.querySelector('.modal #iframe-license'));
    iframeEl = iframeEl && iframeEl.length ? iframeEl[0] : undefined;
    if (!iframeEl || !iframeEl.contentWindow) {
      console.debug('[join] Waiting license frame to be load...');
      return $timeout($scope.startListenLicenseBottom, 1000);
    $scope.licenseBottomInterval = $interval(function(){
      var yPos = iframeEl.contentWindow.document.body.scrollTop;
      var scrollHeight = iframeEl.contentWindow.document.body.scrollHeight;
      var clientHeight = iframeEl.contentWindow.document.body.clientHeight;
      var isBottom = (scrollHeight - clientHeight === yPos);
      if(isBottom){
        $scope.isLicenseRead = true;
        $scope.stopListenLicenseBottom();
  $scope.stopListenLicenseBottom = function() {
    if ($scope.licenseBottomInterval) {
      $interval.cancel($scope.licenseBottomInterval);
      delete $scope.licenseBottomInterval;
    }
  };
  $scope.$on('modal.hidden', $scope.stopListenLicenseBottom);

  $scope.checkUid = function(){
    if (!$scope.formData.pseudo || $scope.formData.pseudo.length < 3) {
      $scope.formData.computing=false;
      delete $scope.uiAlreadyUsed;
    $scope.formData.computing=true;
    // Same has given uid + self block: skip control
    if (parameters.uid && uid === parameters.uid) {
      $scope.formData.computing=false;
      $scope.uiAlreadyUsed = false;
      return;
    }
    else {
      // search on uid
      BMA.wot.lookup({ search: uid })
        .then(function(res) {
          $scope.uiAlreadyUsed = (res.results || []).some(function(pub){
              return (pub.uids || []).some(function(idty) {
                });
            });
          $scope.formData.computing=false;
        })
        .catch(function(err){
          console.error(err);
          $scope.formData.computing=false;
          $scope.uiAlreadyUsed = false;
        });
    }
  $scope.$watch('formData.pseudo', $scope.checkUid, true);

  $scope.checkAccountAvailable = function() {
    if (parameters.pubkey) {
      $scope.accountAvailable = true;
      return;
    }

    delete $scope.accountAvailable;
    // Search for tx source, from pubkey
    return BMA.tx.sources({ pubkey:  $scope.formData.pubkey })
      .then(function(res) {
        $scope.accountAvailable = !res || !res.sources.length;
      })
      .catch(function(err) {
        console.error(err);
        $scope.accountAvailable = false;
      });
  };

  $scope.identifierRecovery = function() {
    // Go back
    $scope.slides.slider.unlockSwipes();
    for (var i = 0; i < 2; i++) {
      $scope.slides.slider.slidePrev();
    }
    $scope.slides.slider.lockSwipes();
    // Recompute behavior
    $scope.slideBehavior = $scope.computeSlideBehavior();
  // TODO: remove auto add account when done
Benoit Lavenier's avatar
Benoit Lavenier committed
  /*$timeout(function() {
    //$scope.selectAccountType('member');
    $scope.formData.username="azertypoi";
    $scope.formData.confirmUsername=$scope.formData.username;
    $scope.formData.password="azertypoi";
    $scope.formData.confirmPassword=$scope.formData.password;
    $scope.formData.pseudo="azertypoi";
    //$scope.doNext();
    //$scope.doNext();
Benoit Lavenier's avatar
Benoit Lavenier committed
  }, 400);*/