<commit_before>import { isDesktopApplication, isNullOrUndefined } from '@/utils';
import { PrivilegesManager } from '@/services/privilegesManager';
import template from '%/directives/account-menu.pug';
import { protocolManager } from 'snjs';
import { PureCtrl } from '@Controllers';
import {
  STRING_ACCOUNT_MENU_UNCHECK_MERGE,
  STRING_SIGN_OUT_CONFIRMATION,
  STRING_ERROR_DECRYPTING_IMPORT,
  STRING_E2E_ENABLED,
  STRING_LOCAL_ENC_ENABLED,
  STRING_ENC_NOT_ENABLED,
  STRING_IMPORT_SUCCESS,
  STRING_REMOVE_PASSCODE_CONFIRMATION,
  STRING_REMOVE_PASSCODE_OFFLINE_ADDENDUM,
  STRING_NON_MATCHING_PASSCODES,
  STRING_NON_MATCHING_PASSWORDS,
  STRING_INVALID_IMPORT_FILE,
  STRING_GENERATING_LOGIN_KEYS,
  STRING_GENERATING_REGISTER_KEYS,
  StringImportError
} from '@/strings';

const ELEMENT_ID_IMPORT_PASSWORD_INPUT = 'import-password-request';

const ELEMENT_NAME_AUTH_EMAIL = 'email';
const ELEMENT_NAME_AUTH_PASSWORD = 'password';
const ELEMENT_NAME_AUTH_PASSWORD_CONF = '<PASSWORD>';

class AccountMenuCtrl extends PureCtrl {
  /* @ngInject */
  constructor(
    $scope,
    $rootScope,
    $timeout,
    alertManager,
    archiveManager,
    appVersion,
    authManager,
    modelManager,
    passcodeManager,
    privilegesManager,
    storageManager,
    syncManager,
  ) {
    super($timeout);
    this.$scope = $scope;
    this.$rootScope = $rootScope;
    this.$timeout = $timeout;
    this.alertManager = alertManager;
    this.archiveManager = archiveManager;
    this.authManager = authManager;
    this.modelManager = modelManager;
    this.passcodeManager = passcodeManager;
    this.privilegesManager = privilegesManager;
    this.storageManager = storageManager;
    this.syncManager = syncManager;

    this.state = {
      appVersion: 'v' + (window.electronAppVersion || appVersion),
      user: this.authManager.user,
      canAddPasscode: !this.authManager.isEphemeralSession(),
      passcodeAutoLockOptions: this.passcodeManager.getAutoLockIntervalOptions(),
      formData: {
        mergeLocal: true,
        ephemeral: false
      },
      mutable: {
        backupEncrypted: this.encryptedBackupsAvailable()
      }
    };

    this.syncStatus = this.syncManager.syncStatus;
    this.syncManager.getServerURL().then((url) => {
      this.setState({
        server: url,
        formData: { ...this.state.formData, url: url }
      });
    });
    this.authManager.checkForSecurityUpdate().then((available) => {
      this.setState({
        securityUpdateAvailable: available
      });
    });
    this.reloadAutoLockInterval();
  }

  $onInit() {
    this.initProps({
      closeFunction: this.closeFunction
    });
  }

  close() {
    this.$timeout(() => {
      this.props.closeFunction()();
    });
  }

  encryptedBackupsAvailable() {
    return !isNullOrUndefined(this.authManager.user) || this.passcodeManager.hasPasscode();
  }

  submitMfaForm() {
    const params = {
      [this.state.formData.mfa.payload.mfa_key]: this.state.formData.userMfaCode
    };
    this.login(params);
  }

  blurAuthFields() {
    const names = [
      ELEMENT_NAME_AUTH_EMAIL,
      ELEMENT_NAME_AUTH_PASSWORD,
      ELEMENT_NAME_AUTH_PASSWORD_CONF
    ];
    for(const name of names) {
      const element = document.getElementsByName(name)[0];
      if(element) {
        element.blur();
      }
    }
  }

  submitAuthForm() {
    if (!this.state.formData.email || !this.state.formData.user_password) {
      return;
    }
    this.blurAuthFields();
    if (this.state.formData.showLogin) {
      this.login();
    } else {
      this.register();
    }
  }

  async setFormDataState(formData) {
    return this.setState({
      formData: {
        ...this.state.formData,
        ...formData
      }
    });
  }

  async login(extraParams) {
    /** Prevent a timed sync from occuring while signing in. */
    this.syncManager.lockSyncing();
    await this.setFormDataState({
      status: STRING_GENERATING_LOGIN_KEYS,
      authenticating: true
    });
    const response = await this.authManager.login(
      this.state.formData.url,
      this.state.formData.email,
      this.state.formData.user_password,
      this.state.formData.ephemeral,
      this.state.formData.strictSignin,
      extraParams
    );
    const hasError = !response || response.error;
    if (!hasError) {
      await this.onAuthSuccess();
      this.syncManager.unlockSyncing();
      this.syncManager.sync({ performIntegrityCheck: true });
      return;
    }
    this.syncManager.unlockSyncing();
    await this.setFormDataState({
      status: null,
    });
    const error = response
      ? response.error
      : { message: "An unknown error occured." };

    if (error.tag === 'mfa-required' || error.tag === 'mfa-invalid') {
     await this.setFormDataState({
        showLogin: false,
        mfa: error
      });
    } else {
      await this.setFormDataState({<commit_msg>Clear password field on failed login attempts<commit_after>import { isDesktopApplication, isNullOrUndefined } from '@/utils';
import { PrivilegesManager } from '@/services/privilegesManager';
import template from '%/directives/account-menu.pug';
import { protocolManager } from 'snjs';
import { PureCtrl } from '@Controllers';
import {
  STRING_ACCOUNT_MENU_UNCHECK_MERGE,
  STRING_SIGN_OUT_CONFIRMATION,
  STRING_ERROR_DECRYPTING_IMPORT,
  STRING_E2E_ENABLED,
  STRING_LOCAL_ENC_ENABLED,
  STRING_ENC_NOT_ENABLED,
  STRING_IMPORT_SUCCESS,
  STRING_REMOVE_PASSCODE_CONFIRMATION,
  STRING_REMOVE_PASSCODE_OFFLINE_ADDENDUM,
  STRING_NON_MATCHING_PASSCODES,
  STRING_NON_MATCHING_PASSWORDS,
  STRING_INVALID_IMPORT_FILE,
  STRING_GENERATING_LOGIN_KEYS,
  STRING_GENERATING_REGISTER_KEYS,
  StringImportError
} from '@/strings';

const ELEMENT_ID_IMPORT_PASSWORD_INPUT = 'import-password-request';

const ELEMENT_NAME_AUTH_EMAIL = 'email';
const ELEMENT_NAME_AUTH_PASSWORD = 'password';
const ELEMENT_NAME_AUTH_PASSWORD_CONF = '<PASSWORD>';

class AccountMenuCtrl extends PureCtrl {
  /* @ngInject */
  constructor(
    $scope,
    $rootScope,
    $timeout,
    alertManager,
    archiveManager,
    appVersion,
    authManager,
    modelManager,
    passcodeManager,
    privilegesManager,
    storageManager,
    syncManager,
  ) {
    super($timeout);
    this.$scope = $scope;
    this.$rootScope = $rootScope;
    this.$timeout = $timeout;
    this.alertManager = alertManager;
    this.archiveManager = archiveManager;
    this.authManager = authManager;
    this.modelManager = modelManager;
    this.passcodeManager = passcodeManager;
    this.privilegesManager = privilegesManager;
    this.storageManager = storageManager;
    this.syncManager = syncManager;

    this.state = {
      appVersion: 'v' + (window.electronAppVersion || appVersion),
      user: this.authManager.user,
      canAddPasscode: !this.authManager.isEphemeralSession(),
      passcodeAutoLockOptions: this.passcodeManager.getAutoLockIntervalOptions(),
      formData: {
        mergeLocal: true,
        ephemeral: false
      },
      mutable: {
        backupEncrypted: this.encryptedBackupsAvailable()
      }
    };

    this.syncStatus = this.syncManager.syncStatus;
    this.syncManager.getServerURL().then((url) => {
      this.setState({
        server: url,
        formData: { ...this.state.formData, url: url }
      });
    });
    this.authManager.checkForSecurityUpdate().then((available) => {
      this.setState({
        securityUpdateAvailable: available
      });
    });
    this.reloadAutoLockInterval();
  }

  $onInit() {
    this.initProps({
      closeFunction: this.closeFunction
    });
  }

  close() {
    this.$timeout(() => {
      this.props.closeFunction()();
    });
  }

  encryptedBackupsAvailable() {
    return !isNullOrUndefined(this.authManager.user) || this.passcodeManager.hasPasscode();
  }

  submitMfaForm() {
    const params = {
      [this.state.formData.mfa.payload.mfa_key]: this.state.formData.userMfaCode
    };
    this.login(params);
  }

  blurAuthFields() {
    const names = [
      ELEMENT_NAME_AUTH_EMAIL,
      ELEMENT_NAME_AUTH_PASSWORD,
      ELEMENT_NAME_AUTH_PASSWORD_CONF
    ];
    for(const name of names) {
      const element = document.getElementsByName(name)[0];
      if(element) {
        element.blur();
      }
    }
  }

  submitAuthForm() {
    if (!this.state.formData.email || !this.state.formData.user_password) {
      return;
    }
    this.blurAuthFields();
    if (this.state.formData.showLogin) {
      this.login();
    } else {
      this.register();
    }
  }

  async setFormDataState(formData) {
    return this.setState({
      formData: {
        ...this.state.formData,
        ...formData
      }
    });
  }

  async login(extraParams) {
    /** Prevent a timed sync from occuring while signing in. */
    this.syncManager.lockSyncing();
    await this.setFormDataState({
      status: STRING_GENERATING_LOGIN_KEYS,
      authenticating: true
    });
    const response = await this.authManager.login(
      this.state.formData.url,
      this.state.formData.email,
      this.state.formData.user_password,
      this.state.formData.ephemeral,
      this.state.formData.strictSignin,
      extraParams
    );
    const hasError = !response || response.error;
    if (!hasError) {
      await this.onAuthSuccess();
      this.syncManager.unlockSyncing();
      this.syncManager.sync({ performIntegrityCheck: true });
      return;
    }
    this.syncManager.unlockSyncing();
    await this.setFormDataState({
      status: null,
      user_password: null
    });
    const error = response
      ? response.error
      : { message: "An unknown error occured." };

    if (error.tag === 'mfa-required' || error.tag === 'mfa-invalid') {
     await this.setFormDataState({
        showLogin: false,
        mfa: error
      });
    } else {
      await this.setFormDataState({
{'fraction_non_alphanumeric': 0.11297539149888143, 'fraction_numerical': 0.0004067520846044336, 'mean_word_length': 3.106471816283925, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7585482', 'n_tokens_mistral': 3146, 'n_tokens_neox': 3123, 'n_words': 497}