TimeTrex/interface/html5/views/my_account/password/ChangePasswordViewController.js

582 lines
16 KiB
JavaScript

export class ChangePasswordViewController extends BaseViewController {
constructor( options = {} ) {
_.defaults( options, {
showPassword: null,
showPhonePassword: null,
mfa_type_array: null,
has_authenticated: false,
api_authentication: null,
api_misc: null,
api_notification_device_token: null,
result_data: []
} );
super( options );
}
init( options ) {
//this._super('initialize', options );
this.permission_id = 'user';
this.viewId = 'ChangePassword';
this.script_name = 'ChangePasswordView';
this.context_menu_name = $.i18n._( 'Passwords / Security' );
this.api = TTAPI.APIUser;
this.api_authentication = TTAPI.APIAuthentication;
this.api_notification_device_token = TTAPI.APINotificationDeviceToken;
this.api_misc = TTAPI.APIMisc;
this.initPermission();
this.render();
this.initData();
}
initOptions( callback ) {
var options = [{ option_name: 'mfa_type' },];
this.initDropDownOptions( options, callback );
}
initPermission() {
super.initPermission();
if ( PermissionManager.validate( 'user', 'edit_own_password' ) ) {
this.showPassword = true;
} else {
this.showPassword = false;
}
if ( PermissionManager.validate( 'user', 'edit_own_phone_password' ) ) {
this.showPhonePassword = true;
} else {
this.showPhonePassword = false;
}
}
render() {
super.render();
}
getCustomContextMenuModel() {
var context_menu_model = {
groups: {
trusted: {
label: $.i18n._( 'Trusted Device' ), id: this.viewId + 'trusted', sort_order: 8000
}
},
exclude: ['default'],
include: [
'save',
'cancel',
{
label: '', //Empty label. vue_icon is displayed instead of text.
id: 'other_header',
menu_align: 'right',
action_group: 'other',
action_group_header: true,
vue_icon: 'tticon tticon-more_vert_black_24dp',
},
{
label: $.i18n._( 'Reauthenticate' ),
id: 'reauthenticate',
menu_align: 'right',
action_group: 'other'
},
{
label: $.i18n._( 'Register API Key' ),
id: 'register_api_key',
menu_align: 'right',
action_group: 'other'
},
{
label: $.i18n._( 'Remove All Trusted Devices' ),
id: 'remove_all_trusted_devices',
menu_align: 'right',
action_group: 'other'
},
{
label: $.i18n._( 'Logout All Sessions' ),
id: 'logout_all_sessions',
menu_align: 'right',
action_group: 'other'
},
]
};
return context_menu_model;
}
onCustomContextClick( id ) {
switch ( id ) {
case 'remove_all_trusted_devices':
this.removeAllTrustedDevices();
break;
case 'reauthenticate':
Global.showAuthenticationModal( this.viewId, 'user_name_multi_factor', {
step: 'password',
type_id: 10,
user_action_message: ''
}, true, ( result ) => {
Global.hideAuthenticationModal();
if ( result.status === true ) {
this.has_authenticated = true;
}
} );
break;
case 'register_api_key':
this.registerAPIKey();
break;
case 'logout_all_sessions':
this.logoutAllSessions();
break;
}
}
registerAPIKey() {
this.api_authentication.registerAPIKeyForCurrentUser( {
onResult: ( result ) => {
if ( result.isValid() ) {
var key = result.getResult();
TAlertManager.showFlexAlert( $.i18n._( 'API Key' ), $.i18n._( 'Below is a new API key for ' ) + LocalCacheData.getLoginUser().user_name + $.i18n._( ' Please copy or write it down for safe keeping, as you will not be able to see it again after this.' ), 'text', key, null, 345, $.i18n._( 'Close' ) );
}
}
} );
}
logoutAllSessions() {
TAlertManager.showConfirmAlert( $.i18n._( 'Which sessions do you want to log out? Note that your current session will not be logged out.' ), $.i18n._( 'Logout' ), ( flag ) => {
this.api_authentication.logoutAllSessions( !flag, {
onResult: ( result ) => {
if ( result.isValid() ) {
TAlertManager.showAlert( $.i18n._( 'Sessions have been logged out.' ) );
}
}
} );
}, $.i18n._( 'Browser/App' ), $.i18n._( '+API Keys' ) );
}
removeAllTrustedDevices() {
this.api_authentication.removeAllTrustedDevices( {
onResult: ( result ) => {
TAlertManager.showAlert( $.i18n._( 'All trusted devices have been removed.' ), $.i18n._( 'Trusted Device' ) );
}
} );
}
saveValidate( context_btn, p_id ) {
// always show
}
setCurrentEditRecordData() {
//Set current edit record data to all widgets
for ( var key in this.current_edit_record ) {
var widget = this.edit_view_ui_dic[key];
if ( Global.isSet( widget ) ) {
switch ( key ) {
case 'user_name':
widget.setValue( LocalCacheData.loginUser.user_name );
break;
case 'phone_id':
if ( !LocalCacheData.loginUser.phone_id ) {
widget.setValue( $.i18n._( 'Not Specified' ) );
} else {
widget.setValue( LocalCacheData.loginUser.phone_id );
}
break;
default:
widget.setValue( this.current_edit_record[key] );
break;
}
}
}
this.collectUIDataToCurrentEditRecord();
this.setEditViewDataDone();
}
openEditView() {
var $this = this;
if ( $this.edit_only_mode && ( this.showPassword || this.showPhonePassword ) ) {
$this.buildContextMenu();
$this.initOptions( () => {
if ( !$this.edit_view ) {
$this.initEditViewUI( 'ChangePassword', 'ChangePasswordEditView.html' );
}
$this.getUserPasswordData( function( result ) {
$this.current_edit_record = result;
$this.initEditView();
} );
} );
}
}
getUserPasswordData( callBack ) {
var $this = this;
var filter = {};
filter.filter_data = {};
filter.filter_data.id = LocalCacheData.loginUser.id;
filter.filter_columns = { id: true, mfa_type_id: true };
$this.api['get' + $this.api.key_name]( filter, {
onResult: function( result ) {
var result_data = result.getResult();
if ( Global.isSet( result_data[0] ) ) {
callBack( result_data[0] );
}
}
} );
}
checkTabPermissions( tab ) {
var retval = false;
switch ( tab ) {
case 'tab_web_password':
if ( this.showPassword ) {
retval = true;
}
break;
case 'tab_quick_punch_password':
if ( this.showPhonePassword ) {
retval = true;
}
break;
default:
retval = super.checkTabPermissions( tab );
break;
}
return retval;
}
onFormItemChange( target, doNotValidate ) {
this.setIsChanged( target );
this.setMassEditingFieldsWhenFormChange( target );
var key = target.getField();
//this.current_edit_record[key] = target.getValue();
var c_value = target.getValue();
switch ( key ) {
case 'mfa_type_id':
this.onMfaTypeChange( c_value );
break;
default:
break;
}
this.current_edit_record[key] = c_value;
}
toggleSaveButton( show_button ) {
var context_menu_array = ContextMenuManager.getMenuModelByMenuId( this.determineContextMenuMountAttributes().id );
context_menu_array.forEach( ( context_btn ) => {
if ( context_btn.id === 'save' ) {
ContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, show_button );
}
} );
}
onMfaTypeChange( mfa_type_id ) {
//Disable "Save" button as the user may quickly press it before the QR code is generated, causing them to miss instructions.
this.toggleSaveButton( false );
//Validate current user to make sure mfa settings can be saved
this.api.validateUser( { id: LocalCacheData.getLoginUser().id }, {
onResult: ( result ) => {
if ( result.isValid() == false ) {
let details = result.getDetails();
let error_string = $.i18n._( 'Validation Error. Unable to turn on Multifactor Authentication.<br><br>' );
if ( Global.isArray( details ) || typeof details === 'object' ) {
error_string += Global.convertValidationErrorToString( details );
} else {
error_string += result.getDescription();
}
this.toggleSaveButton( true );
TAlertManager.showAlert( error_string, $.i18n._( 'Error' ) );
} else {
if ( mfa_type_id === 0 ) {
this.toggleSaveButton( true );
return; //Do not show MFA instructions if MFA is being turned off
}
this.showMfaInstructions( true );
}
//If we need to check app token exists
// let data = {};
// data.filter_data = { id: LocalCacheData.getLoginUser().id };
// this.api_notification_device_token.getNotificationDeviceToken( data, {
// onResult: ( res ) => {
// result = res.getResult();
// if ( Array.isArray( result ) && result.length > 0 ) {
// this.showMfaInstructions( true );
// } else {
// this.showMfaInstructions( false );
// }
// }
// } );
// }
}
} );
}
showMfaInstructions( has_notification_device_token ) {
this.api_misc.generateQRCode( JSON.stringify( {
server_url: Global.getBaseURL( null, false ).replace( '/interface/html5/', '' ), //App does not need the /interface/html5/ part of the URL
user_name: LocalCacheData.getLoginUser().user_name
} ), {
onResult: ( res ) => {
this.toggleSaveButton( true );
let result = res.getResult();
TAlertManager.showModalAlert( 'multifactor_authentication', 'download_instructions', ( flag ) => {
if ( flag === true ) {
this.onSaveClick();
}
}, result );
}
} );
}
onSaveClick( ignoreWarning ) {
var $this = this;
var record = this.current_edit_record;
LocalCacheData.current_doing_context_action = 'save';
if ( !Global.isSet( ignoreWarning ) ) {
ignoreWarning = false;
}
this.clearErrorTips();
var key = this.getEditViewTabIndex();
if ( key === 0 ) {
$this.saveWebPassword( record, function( result ) {
if ( result.isValid() ) {
$this.removeEditView();
} else {
$this.showErrorTips( result, 0 );
}
} );
} else if ( key === 1 ) {
$this.savePhonePassword( record, function( result ) {
if ( result.isValid() ) {
$this.removeEditView();
} else {
$this.showErrorTips( result, 1 );
}
} );
} else if ( key === 2 ) {
$this.saveMultiFactorSettings( record, function( result ) {
if ( result.isValid() ) {
$this.removeEditView();
} else {
$this.showErrorTips( result, 1 );
}
} );
}
}
showErrorTips( result, index ) {
var details = result.getDetails();
var error_list = details;
var tabKey;
var found_in_current_tab = false;
for ( var key in error_list ) {
if ( parseInt( index ) === 0 ) {
if ( this.current_edit_record['web.password'] ) {
tabKey = 'web.' + key;
} else {
continue;
}
}
if ( parseInt( index ) === 1 ) {
if ( this.current_edit_record['phone.password'] ) {
tabKey = 'phone.' + key.replace( 'phone_', '' );
} else {
continue;
}
}
if ( !error_list.hasOwnProperty( key ) ) {
continue;
}
if ( !Global.isSet( this.edit_view_ui_dic[tabKey] ) ) {
continue;
}
if ( this.edit_view_ui_dic[tabKey].is( ':visible' ) ) {
this.edit_view_ui_dic[tabKey].setErrorStyle( error_list[key], true );
found_in_current_tab = true;
}
this.edit_view_error_ui_dic[tabKey] = this.edit_view_ui_dic[tabKey];
}
if ( !found_in_current_tab ) {
this.showEditViewError( result );
}
}
saveWebPassword( record, callBack ) {
var $this = this;
this.api['changePassword']( record['web.password'], record['web.password2'], 'user_name', {
onResult: function( result ) {
callBack( result );
}
} );
}
savePhonePassword( record, callBack ) {
var $this = this;
this.api['changePassword']( record['phone.password'], record['phone.password2'], 'quick_punch_id', {
onResult: function( result ) {
callBack( result );
}
} );
}
saveMultiFactorSettings( record, callBack ) {
this.api.setMultiFactorSettings( this.current_edit_record.mfa_type_id, {
onResult: ( result ) => {
callBack( result );
}
} );
}
buildEditViewUI() {
var $this = this;
super.buildEditViewUI();
var tab_model = {
'tab_web_password': { 'label': $.i18n._( 'Web Password' ) },
'tab_quick_punch_password': { 'label': $.i18n._( 'Quick Punch Password' ) },
'tab_multifactor': {
'label': $.i18n._( 'Multifactor Authentication' ),
init_callback: 'initMultifactorView',
html_template: this.getMultifactorTabHtml()
},
};
this.setTabModel( tab_model );
//Tab 0 start
var tab_web_password = this.edit_view_tab.find( '#tab_web_password' );
var tab_web_password_column1 = tab_web_password.find( '.first-column' );
this.edit_view_tabs[0] = [];
this.edit_view_tabs[0].push( tab_web_password_column1 );
// User Name
var form_item_input = Global.loadWidgetByName( FormItemType.TEXT );
form_item_input.TText( { field: 'user_name' } );
this.addEditFieldToColumn( $.i18n._( 'User Name' ), form_item_input, tab_web_password_column1, '' );
// New Password
form_item_input = Global.loadWidgetByName( FormItemType.PASSWORD_INPUT );
form_item_input.TPasswordInput( { field: 'web.password', width: 200 } );
this.addEditFieldToColumn( $.i18n._( 'New Password' ), form_item_input, tab_web_password_column1 );
// New Password(confirm)
form_item_input = Global.loadWidgetByName( FormItemType.PASSWORD_INPUT );
form_item_input.TPasswordInput( { field: 'web.password2', width: 200 } );
this.addEditFieldToColumn( $.i18n._( 'New Password (Confirm)' ), form_item_input, tab_web_password_column1, '' );
//Tab 1 start
var tab_quick_punch_password = this.edit_view_tab.find( '#tab_quick_punch_password' );
var tab_quick_punch_password_column1 = tab_quick_punch_password.find( '.first-column' );
this.edit_view_tabs[1] = [];
this.edit_view_tabs[1].push( tab_quick_punch_password_column1 );
// Quick Punch ID
form_item_input = Global.loadWidgetByName( FormItemType.TEXT );
form_item_input.TText( { field: 'phone_id' } );
this.addEditFieldToColumn( $.i18n._( 'Quick Punch ID' ), form_item_input, tab_quick_punch_password_column1, '' );
// New Password
form_item_input = Global.loadWidgetByName( FormItemType.PASSWORD_INPUT );
form_item_input.TPasswordInput( { field: 'phone.password', width: 200 } );
this.addEditFieldToColumn( $.i18n._( 'New Quick Punch Password' ), form_item_input, tab_quick_punch_password_column1 );
// New Password(confirm)
form_item_input = Global.loadWidgetByName( FormItemType.PASSWORD_INPUT );
form_item_input.TPasswordInput( { field: 'phone.password2', width: 200 } );
this.addEditFieldToColumn( $.i18n._( 'New Quick Punch Password (Confirm)' ), form_item_input, tab_quick_punch_password_column1, '' );
//Tab 2 start
var tab_multifactor = this.edit_view_tab.find( '#tab_multifactor' );
var tab_multifactor_column1 = tab_multifactor.find( '.first-column' );
this.edit_view_tabs[1] = [];
this.edit_view_tabs[1].push( tab_multifactor_column1 );
// Multifactor Authentication Type
form_item_input = Global.loadWidgetByName( FormItemType.COMBO_BOX );
form_item_input.TComboBox( { field: 'mfa_type_id' } );
form_item_input.setSourceData( this.mfa_type_array );
this.addEditFieldToColumn( $.i18n._( 'Multifactor Type' ), form_item_input, tab_multifactor_column1, '' );
}
initMultifactorView() {
if ( ( Global.getProductEdition() >= 15 ) ) {
this.edit_view_tab.find( '#tab_multifactor' ).find( '.first-column' ).css( 'display', 'block' );
this.edit_view.find( '.permission-defined-div' ).css( 'display', 'none' );
} else {
this.edit_view_tab.find( '#tab_multifactor' ).find( '.first-column' ).css( 'display', 'none' );
this.edit_view.find( '.permission-defined-div' ).css( 'display', 'block' );
this.edit_view.find( '.permission-message' ).html( Global.getUpgradeMessage() );
}
}
getMultifactorTabHtml() {
return `
<div id="tab_multifactor" class="edit-view-tab-outside">
<div class="edit-view-tab" id="tab_multifactor_content_div">
<div class="first-column full-width-column"></div>
<div class="save-and-continue-div permission-defined-div">
<span class="message permission-message"></span>
</div>
</div>
</div>`;
}
}