diff --git a/agc_2-X/trunk/docs/AGENT_API.txt b/agc_2-X/trunk/docs/AGENT_API.txt index 1c0fd7e8..ce25e3f7 100644 --- a/agc_2-X/trunk/docs/AGENT_API.txt +++ b/agc_2-X/trunk/docs/AGENT_API.txt @@ -451,7 +451,7 @@ LEAD DATA (must populate at least one) vendor_lead_code rank owner -OPTIONAL NON-LEAD TRIGGERS - +OPTIONAL NON-LEAD TRIGGERS (these still require a lead to be on the agent screen) - formreload scriptreload script2reload diff --git a/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql b/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql index b238c2f1..322a8c47 100644 --- a/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql +++ b/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql @@ -2020,7 +2020,8 @@ agent_notifications ENUM('0','1','2','3','4','5','6','7') default '0', demographic_quotas ENUM('0','1','2','3','4','5','6','7') default '0', log_latency_gaps ENUM('0','1','2','3','4','5','6','7') default '1', inbound_credits ENUM('0','1','2','3','4','5','6','7') default '0', -weekday_resets ENUM('0','1','2','3','4','5','6','7') default '0' +weekday_resets ENUM('0','1','2','3','4','5','6','7') default '0', +two_factor_auth_agent_hours SMALLINT(5) default '0' ) ENGINE=MyISAM; CREATE TABLE vicidial_campaigns_list_mix ( @@ -5441,4 +5442,4 @@ INSERT INTO `wallboard_reports` VALUES ('AGENTS_AND_QUEUES','Agents and Queues', UPDATE system_settings set vdc_agent_api_active='1'; -UPDATE system_settings SET db_schema_version='1697',db_schema_update_date=NOW(),reload_timestamp=NOW(); +UPDATE system_settings SET db_schema_version='1698',db_schema_update_date=NOW(),reload_timestamp=NOW(); diff --git a/agc_2-X/trunk/extras/upgrade_2.14.sql b/agc_2-X/trunk/extras/upgrade_2.14.sql index 7f11ad7d..3a02ace4 100644 --- a/agc_2-X/trunk/extras/upgrade_2.14.sql +++ b/agc_2-X/trunk/extras/upgrade_2.14.sql @@ -2427,3 +2427,7 @@ ALTER TABLE phones MODIFY conf_secret VARCHAR(100) default 'test'; ALTER TABLE servers MODIFY conf_secret VARCHAR(100) default 'test'; UPDATE system_settings SET db_schema_version='1697',db_schema_update_date=NOW() where db_schema_version < 1697; + +ALTER TABLE system_settings ADD two_factor_auth_agent_hours SMALLINT(5) default '0'; + +UPDATE system_settings SET db_schema_version='1698',db_schema_update_date=NOW() where db_schema_version < 1698; diff --git a/agc_2-X/trunk/www/agc/css/style.css b/agc_2-X/trunk/www/agc/css/style.css index bbe14745..4e3ff056 100644 --- a/agc_2-X/trunk/www/agc/css/style.css +++ b/agc_2-X/trunk/www/agc/css/style.css @@ -35,6 +35,12 @@ div.text_input { overflow: auto; font-size: 10px; font-family: sans-serif; } animation: blink .75s linear infinite; } +.adminmenu_style_selected + { + background-color: white; + } +.adminmenu_style_selected:hover{background-color: #E6E6E6;} + @-webkit-keyframes blink { 0% { opacity: 1; } 50% { opacity: 1; } diff --git a/agc_2-X/trunk/www/agc/images/2FA_icon.png b/agc_2-X/trunk/www/agc/images/2FA_icon.png new file mode 100644 index 00000000..c77b11d3 Binary files /dev/null and b/agc_2-X/trunk/www/agc/images/2FA_icon.png differ diff --git a/agc_2-X/trunk/www/agc/images/2FA_icon_white.png b/agc_2-X/trunk/www/agc/images/2FA_icon_white.png new file mode 100644 index 00000000..d2ce1f27 Binary files /dev/null and b/agc_2-X/trunk/www/agc/images/2FA_icon_white.png differ diff --git a/agc_2-X/trunk/www/agc/images/icon_black_inbound.png b/agc_2-X/trunk/www/agc/images/icon_black_inbound.png new file mode 100644 index 00000000..5674f91b Binary files /dev/null and b/agc_2-X/trunk/www/agc/images/icon_black_inbound.png differ diff --git a/agc_2-X/trunk/www/agc/images/icon_chat.png b/agc_2-X/trunk/www/agc/images/icon_chat.png new file mode 100644 index 00000000..a5ba95b0 Binary files /dev/null and b/agc_2-X/trunk/www/agc/images/icon_chat.png differ diff --git a/agc_2-X/trunk/www/agc/images/icon_email.png b/agc_2-X/trunk/www/agc/images/icon_email.png new file mode 100644 index 00000000..2f36041c Binary files /dev/null and b/agc_2-X/trunk/www/agc/images/icon_email.png differ diff --git a/agc_2-X/trunk/www/agc/options-example.php b/agc_2-X/trunk/www/agc/options-example.php index db2baa6e..7a04c3be 100644 --- a/agc_2-X/trunk/www/agc/options-example.php +++ b/agc_2-X/trunk/www/agc/options-example.php @@ -28,6 +28,7 @@ # 230418-1008 - Added astguiclient_disabled option # 230418-1548 - Added dial_override_limit option # 230617-0815 - Added dead_logging_version option +# 231109-0830 - Changed link_to_grey_version to disabled by default # $conf_silent_prefix = '5'; # vicidial_conferences prefix to enter silently and muted for recording @@ -63,7 +64,7 @@ $conf_check_attempts = '3'; # number of attempts to try before loosing webserver $focus_blur_enabled = '0'; # set to 1 to enable the focus/blur enter key blocking(some IE instances have issues) $consult_custom_delay = '2'; # number of seconds to delay consultative transfers when custom fields are active $mrglock_ig_select_ct = '4'; # number of seconds to leave in-group select screen open if agent select is disabled -$link_to_grey_version = '1'; # show link to old grey version of agent screen at login screen, next to timeclock link +$link_to_grey_version = '0'; # show link to old grey version of agent screen at login screen, next to timeclock link $use_agent_colors = '1'; # agent chat colors $no_empty_session_warnings=0; # set to 1 to disable empty session warnings on agent screen $logged_in_refresh_link = '0'; # set to 1 to allow clickable "Logged in as..." link at top to force Javascript refresh diff --git a/agc_2-X/trunk/www/agc/vdc_db_query.php b/agc_2-X/trunk/www/agc/vdc_db_query.php index bfd7a0f5..d7302e51 100644 --- a/agc_2-X/trunk/www/agc/vdc_db_query.php +++ b/agc_2-X/trunk/www/agc/vdc_db_query.php @@ -539,10 +539,11 @@ # 230617-1605 - Fix for issue when agent goes ready, one of the fixes from Issue #1473 # 230801-0810 - More useful error output for manDiaLskip # 230927-2037 - Added agent_search_ingroup_list campaign and agent_search_list ingroup options +# 231108-0819 - Added several fields to update_settings related to manual dial calls # -$version = '2.14-432'; -$build = '230927-2037'; +$version = '2.14-433'; +$build = '231108-0819'; $php_script = 'vdc_db_query.php'; $mel=1; # Mysql Error Log enabled = 1 $mysql_log_count=913; @@ -2182,7 +2183,7 @@ if ($ACTION == 'update_settings') ##### grab the data from vicidial_campaigns for the campaign - $stmt="SELECT wrapup_seconds,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,dial_timeout,wrapup_bypass,wrapup_message,wrapup_after_hotkey,manual_dial_timeout,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override FROM vicidial_campaigns where campaign_id='$campaign' LIMIT 1;"; + $stmt="SELECT wrapup_seconds,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,dial_timeout,wrapup_bypass,wrapup_message,wrapup_after_hotkey,manual_dial_timeout,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,campaign_cid,omit_phone_code,use_internal_dnc,use_campaign_dnc,dial_prefix,manual_dial_prefix,three_way_dial_prefix FROM vicidial_campaigns where campaign_id='$campaign' LIMIT 1;"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00594',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -2203,6 +2204,18 @@ if ($ACTION == 'update_settings') $manual_dial_timeout = trim("$row[10]"); $in_man_dial_next_ready_seconds = trim("$row[11]"); $in_man_dial_next_ready_seconds_override = trim("$row[12]"); + $campaign_cid = trim("$row[13]"); + $omit_phone_code = trim("$row[14]"); + $use_internal_dnc = trim("$row[15]"); + $use_campaign_dnc = trim("$row[16]"); + $dial_prefix = trim("$row[17]"); + $manual_dial_prefix = trim("$row[18]"); + $three_way_dial_prefix = trim("$row[19]"); + + if (strlen($manual_dial_prefix) < 1) + {$manual_dial_prefix = $dial_prefix;} + if (strlen($three_way_dial_prefix) < 1) + {$three_way_dial_prefix = $dial_prefix;} } if ( ($manual_dial_timeout < 1) or (strlen($manual_dial_timeout) < 1) ) @@ -2262,6 +2275,13 @@ if ($ACTION == 'update_settings') $SettingS_InfO .= "wrapup_after_hotkey: " . $wrapup_after_hotkey . "\n"; $SettingS_InfO .= "manual_dial_timeout: " . $manual_dial_timeout . "\n"; $SettingS_InfO .= "in_man_dial_next_ready_seconds: " . $in_man_dial_next_ready_seconds . "\n"; + $SettingS_InfO .= "campaign_cid: " . $campaign_cid . "\n"; + $SettingS_InfO .= "omit_phone_code: " . $omit_phone_code . "\n"; + $SettingS_InfO .= "use_internal_dnc: " . $use_internal_dnc . "\n"; + $SettingS_InfO .= "use_campaign_dnc: " . $use_campaign_dnc . "\n"; + $SettingS_InfO .= "dial_prefix: " . $dial_prefix . "\n"; + $SettingS_InfO .= "dial_manual_prefix: " . $manual_dial_prefix . "\n"; + $SettingS_InfO .= "dial_three_way_prefix: " . $three_way_dial_prefix . "\n"; $SettingS_InfO .= "\n"; } echo $SettingS_InfO; diff --git a/agc_2-X/trunk/www/agc/vicidial.php b/agc_2-X/trunk/www/agc/vicidial.php index 6ca25488..f49c14a4 100644 --- a/agc_2-X/trunk/www/agc/vicidial.php +++ b/agc_2-X/trunk/www/agc/vicidial.php @@ -725,10 +725,12 @@ # 230615-0842 - Added dead_stop_recording feature # 230810-1652 - Added force_per_call_notes campaign setting # 230927-2036 - Added agent_search_ingroup_list campaign and agent_search_list ingroup options +# 231108-0820 - Added several fields to update_settings related to manual dial calls +# 231109-0827 - Added 2FA for agent screen logins # -$version = '2.14-692c'; -$build = '230927-2036'; +$version = '2.14-693c'; +$build = '231109-0827'; $php_script = 'vicidial.php'; $mel=1; # Mysql Error Log enabled = 1 $mysql_log_count=103; @@ -780,6 +782,12 @@ if (isset($_GET["new_pass1"])) {$new_pass1=$_GET["new_pass1"];} elseif (isset($_POST["new_pass1"])) {$new_pass1=$_POST["new_pass1"];} if (isset($_GET["new_pass2"])) {$new_pass2=$_GET["new_pass2"];} elseif (isset($_POST["new_pass2"])) {$new_pass2=$_POST["new_pass2"];} +if (isset($_GET["stage"])) {$stage=$_GET["stage"];} + elseif (isset($_POST["stage"])) {$stage=$_POST["stage"];} +if (isset($_GET["rank"])) {$rank=$_GET["rank"];} + elseif (isset($_POST["rank"])) {$rank=$_POST["rank"];} +if (isset($_GET["auth_entry"])) {$auth_entry=$_GET["auth_entry"];} + elseif (isset($_POST["auth_entry"])) {$auth_entry=$_POST["auth_entry"];} if (!isset($phone_login)) { @@ -804,6 +812,9 @@ if (!isset($flag_channels)) $DB=preg_replace("/[^0-9a-z]/","",$DB); $VD_login = preg_replace('/[^-_0-9\p{L}]/u','',$VD_login); +$stage = preg_replace('/[^-_0-9\p{L}]/u','',$stage); +$rank = preg_replace('/[^-_0-9\p{L}]/u','',$rank); +$auth_entry = preg_replace('/[^-_0-9\p{L}]/u','',$auth_entry); $forever_stop=0; @@ -828,7 +839,7 @@ $random = (rand(1000000, 9999999) + 10000000); ############################################# ##### START SYSTEM_SETTINGS AND USER LANGUAGE LOOKUP ##### -$stmt = "SELECT use_non_latin,vdc_header_date_format,vdc_customer_date_format,vdc_header_phone_format,webroot_writable,timeclock_end_of_day,vtiger_url,enable_vtiger_integration,outbound_autodial_active,enable_second_webform,user_territories_active,static_agent_url,custom_fields_enabled,pllb_grouping_limit,qc_features_active,allow_emails,callback_time_24hour,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_third_webform,default_language,active_modules,allow_chats,chat_url,default_phone_code,agent_screen_colors,manual_auto_next,agent_xfer_park_3way,admin_web_directory,agent_script,agent_push_events,agent_push_url,agent_logout_link,agentonly_callback_campaign_lock,manual_dial_validation,mute_recordings,enable_second_script,enable_first_webform,recording_buttons,outbound_cid_any,browser_call_alerts,manual_dial_phone_strip,require_password_length,pass_hash_enabled,agent_hidden_sound_seconds,agent_hidden_sound,agent_hidden_sound_volume,agent_screen_timer,agent_hide_hangup,allow_web_debug,max_logged_in_agents,login_kickall,agent_notifications,inbound_credits FROM system_settings;"; +$stmt = "SELECT use_non_latin,vdc_header_date_format,vdc_customer_date_format,vdc_header_phone_format,webroot_writable,timeclock_end_of_day,vtiger_url,enable_vtiger_integration,outbound_autodial_active,enable_second_webform,user_territories_active,static_agent_url,custom_fields_enabled,pllb_grouping_limit,qc_features_active,allow_emails,callback_time_24hour,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_third_webform,default_language,active_modules,allow_chats,chat_url,default_phone_code,agent_screen_colors,manual_auto_next,agent_xfer_park_3way,admin_web_directory,agent_script,agent_push_events,agent_push_url,agent_logout_link,agentonly_callback_campaign_lock,manual_dial_validation,mute_recordings,enable_second_script,enable_first_webform,recording_buttons,outbound_cid_any,browser_call_alerts,manual_dial_phone_strip,require_password_length,pass_hash_enabled,agent_hidden_sound_seconds,agent_hidden_sound,agent_hidden_sound_volume,agent_screen_timer,agent_hide_hangup,allow_web_debug,max_logged_in_agents,login_kickall,agent_notifications,inbound_credits,two_factor_auth_agent_hours,two_factor_container FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01001',$VD_login,$server_ip,$session_name,$one_mysql_log);} #if ($DB) {echo "$stmt\n";} @@ -892,6 +903,8 @@ if ($qm_conf_ct > 0) $SSlogin_kickall = $row[53]; $SSagent_notifications = $row[54]; $SSinbound_credits = $row[55]; + $SStwo_factor_auth_hours = $row[56]; + $SStwo_factor_container = $row[57]; if ( ($SSagent_hidden_sound == '---NONE---') or ($SSagent_hidden_sound == '') ) {$SSagent_hidden_sound_seconds=0;} } else @@ -1006,7 +1019,7 @@ $conf_check_attempts = '3'; # number of attempts to try before loosing webserver $focus_blur_enabled = '0'; # set to 1 to enable the focus/blur enter key blocking(some IE instances have issues) $consult_custom_delay = '2'; # number of seconds to delay consultative transfers when customfields are active $mrglock_ig_select_ct = '4'; # number of seconds to leave in-group select screen open if agent select is disabled -$link_to_grey_version = '1'; # show link to old grey version of agent screen at login screen, next to timeclock link +$link_to_grey_version = '0'; # show link to old grey version of agent screen at login screen, next to timeclock link $no_empty_session_warnings=0; # set to 1 to disable empty session warnings on agent screen $logged_in_refresh_link = '0'; # set to 1 to allow clickable "Logged in as..." link at top to force Javascript refresh $webphone_call_seconds = '0'; # set to 1 or higher to have the agent phone(if set to webphone) called X seconds after login @@ -1750,6 +1763,587 @@ else if($auth>0) { + # check for 2FA being active, and if so, see if there is a non-expired 2FA auth + $VALID_2FA=1; + + if ( ($SStwo_factor_auth_hours > 0) and ($SStwo_factor_container != '') and ($SStwo_factor_container != '---DISABLED---') ) + { + $stmt="SELECT count(*) from vicidial_two_factor_auth where user='$VD_login' and auth_stage='1' and auth_exp_date > NOW();"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01XXX',$VD_login,$server_ip,$session_name,$one_mysql_log);} + $auth_check_to_print = mysqli_num_rows($rslt); + if ($auth_check_to_print < 1) + {$VALID_2FA=0;} + else + { + $row=mysqli_fetch_row($rslt); + $VALID_2FA = $row[0]; + } + } + if ($VALID_2FA < 1) + { + $subhead_font = "style=\"font-family:HELVETICA;font-size:14;color:BLACK;font-weight:bold;\""; + + echo "\"Two-Factor-Authentication\" "._QXZ("Two-Factor-Authentication"),"
\n"; + + if ( ($SStwo_factor_auth_hours < 1) or ($SStwo_factor_container == '') or ($SStwo_factor_container == '---DISABLED---') ) + { + echo _QXZ("Two-Factor-Authentication is disabled on your system. Please contact your system administrator")." $SStwo_factor_auth_hours|$SStwo_factor_container\n"; + exit; + } + + $stmt="SELECT full_name,email,mobile_number,user_group from vicidial_users where user='$VD_login' and active='Y' and api_only_user != '1';"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01XXX',$VD_login,$server_ip,$session_name,$one_mysql_log);} + $row=mysqli_fetch_row($rslt); + $LOGfullname = $row[0]; + $LOGemail = $row[1]; + $LOGmobile_number = $row[2]; + $LOGuser_group = $row[3]; + $OBSCUREemail = $LOGemail; + $OBSCUREmobile_number = $LOGmobile_number; + + # first character and last 6 characters + $temp_emailARY = explode('@',$OBSCUREemail); + $field_temp_val = $temp_emailARY[0]; + $OBSCUREemail = substr($field_temp_val,0,2) . str_repeat(".", (strlen($field_temp_val) - 2)) . '@' . $temp_emailARY[1]; + # first 3 digits and last 2 digits + $field_temp_val = $OBSCUREmobile_number; + $OBSCUREmobile_number = substr($field_temp_val,0,3) . str_repeat("x", (strlen($field_temp_val) - 5)) . substr($field_temp_val,-2,2); + + ### BEGIN Gather 2FA settings container details ### + $valid_2FA_config=0; + $active_2FA_methods=0; + $auth_code_expire_minutes='30'; + $auth_code_attempts='10'; + $auth_code_length='6'; + $email_auth=''; + $email_from=''; + $email_subject=''; + $email_message=''; + $phone_auth=''; + $phone_prefix=''; + $phone_server_ip=''; + $phone_cid_number=''; + $phone_message_override=''; + $sms_auth=''; + $sms_cid_number=''; + $sms_url=''; + $stmt = "SELECT container_entry FROM vicidial_settings_containers where container_id='$SStwo_factor_container';"; + $rslt=mysql_to_mysqli($stmt, $link); + $SCinfo_ct = mysqli_num_rows($rslt); + if ($DB) {echo "$SCinfo_ct|$stmt\n";} + if ($SCinfo_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $TFAcontainer_entry = $row[0]; + $TFAcontainer_entry = preg_replace("/\r|\t|\'|\"/",'',$TFAcontainer_entry); + $TFAcontainer_entry = preg_replace("/ => | =>|=> /",'=>',$TFAcontainer_entry); + $two_factor_settings = explode("\n",$TFAcontainer_entry); + $two_factor_settings_ct = count($two_factor_settings); + $tfal=0; + while ($two_factor_settings_ct >= $tfal) + { + if (preg_match("/^auth_code_expire_minutes=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/auth_code_expire_minutes=>/",'',$two_factor_settings[$tfal]); + $auth_code_expire_minutes = $two_factor_settings[$tfal]; + } + if (preg_match("/^auth_code_attempts=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/auth_code_attempts=>/",'',$two_factor_settings[$tfal]); + $auth_code_attempts = $two_factor_settings[$tfal]; + } + if (preg_match("/^auth_code_length=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/auth_code_length=>/",'',$two_factor_settings[$tfal]); + $auth_code_length = $two_factor_settings[$tfal]; + } + if (preg_match("/^email_auth=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/email_auth=>/",'',$two_factor_settings[$tfal]); + $email_auth = $two_factor_settings[$tfal]; + $active_2FA_methods++; + } + if (preg_match("/^email_from=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/email_from=>/",'',$two_factor_settings[$tfal]); + $email_from = $two_factor_settings[$tfal]; + $valid_2FA_config++; + } + if (preg_match("/^email_subject=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/email_subject=>/",'',$two_factor_settings[$tfal]); + $email_subject = $two_factor_settings[$tfal]; + } + if (preg_match("/^email_message=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/email_message=>/",'',$two_factor_settings[$tfal]); + $email_message = $two_factor_settings[$tfal]; + } + if (preg_match("/^phone_auth=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/phone_auth=>/",'',$two_factor_settings[$tfal]); + $phone_auth = $two_factor_settings[$tfal]; + $active_2FA_methods++; + } + if (preg_match("/^phone_prefix=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/phone_prefix=>/",'',$two_factor_settings[$tfal]); + $phone_prefix = $two_factor_settings[$tfal]; + } + if (preg_match("/^phone_server_ip=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/phone_server_ip=>/",'',$two_factor_settings[$tfal]); + $phone_server_ip = $two_factor_settings[$tfal]; + $valid_2FA_config++; + } + if (preg_match("/^phone_cid_number=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/phone_cid_number=>/",'',$two_factor_settings[$tfal]); + $phone_cid_number = $two_factor_settings[$tfal]; + } + if (preg_match("/^phone_message_override=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/phone_message_override=>/",'',$two_factor_settings[$tfal]); + $phone_message_override = $two_factor_settings[$tfal]; + } + if (preg_match("/^sms_auth=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/sms_auth=>/",'',$two_factor_settings[$tfal]); + $sms_auth = $two_factor_settings[$tfal]; + $active_2FA_methods++; + } + if (preg_match("/^sms_cid_number=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/sms_cid_number=>/",'',$two_factor_settings[$tfal]); + $sms_cid_number = $two_factor_settings[$tfal]; + } + if (preg_match("/^sms_url=>/",$two_factor_settings[$tfal])) + { + $two_factor_settings[$tfal] = preg_replace("/sms_url=>/",'',$two_factor_settings[$tfal]); + $sms_url = $two_factor_settings[$tfal]; + $valid_2FA_config++; + } + + $tfal++; + } + } + ### END Gather 2FA settings container details ### + if ( ($valid_2FA_config < 1) or ($active_2FA_methods < 1) ) + { + echo "
"._QXZ("Two-Factor-Authentication is not properly configured on your system. Please contact your system administrator")."

$valid_2FA_config|$SStwo_factor_auth_hours|$SStwo_factor_container

\n"; + exit; + } + if ( (strlen($LOGemail) < 4) and (strlen($LOGmobile_number) < 2) ) + { + echo _QXZ("Your User account is not configured for Two-Factor-Authentication. Please contact your system administrator. (no email or mobile number)").".\n"; + exit; + } + + $show_form=1; + if ( ($stage=='SUBMIT') or ($stage==_QXZ("SUBMIT")) ) + { + $auth_fail=0; + echo "
"; + if (strlen($rank) < 2) + { + echo _QXZ("Please go back and enter a valid authorization code")." |1|" . strlen($rank) . "|"; $auth_fail++; + } + else + { + $stmt="SELECT count(*) from vicidial_two_factor_auth where user='$VD_login' and auth_code='$rank' and auth_stage='0' and auth_code_exp_date > NOW() and (auth_attempts < $auth_code_attempts);"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $auth_check_to_print = mysqli_num_rows($rslt); + if ($auth_check_to_print < 1) + {echo _QXZ("Please go back and enter a valid authorization code")." |2|$auth_check_to_print"; $auth_fail++;} + else + { + $row=mysqli_fetch_row($rslt); + if ($row[0] < 1) + {echo _QXZ("Please go back and enter a valid authorization code")." |3|$row[0]"; $auth_fail++;} + else + { + $stmt="UPDATE vicidial_two_factor_auth SET auth_stage='1', auth_attempts=(auth_attempts + 1) where user='$VD_login' and auth_stage='0' and auth_code='$rank';"; + $rslt=mysql_to_mysqli($stmt, $link); + + $stmt = "INSERT INTO vicidial_agent_function_log set agent_log_id='0',user='$VD_login',function='2FA_good',event_time=NOW(),campaign_id='-ADMIN-',user_group='$LOGuser_group',lead_id='0',uniqueid='SUCCESS',caller_code='$ip',stage='',comments='';"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + + echo _QXZ("Authorization code accepted, you may now continue")."

\n"; + + echo ""._QXZ("Agent web client: 2FA Auth")."\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "$DBoutput"; + echo "
\n"; + echo "
\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + # echo "\n"; + echo "\n"; + echo "


"; + echo ""; + echo "\n"; + echo "\n"; + echo "\n"; + echo "
\"Agent
  \n"; + echo "

"._QXZ("VERSION:")." $version       "._QXZ("BUILD:")." $build
\n"; + echo "\n\n"; + echo "\n\n"; + echo "$LoginLoadingBox"; + echo "
\n"; + echo "$INSERT_before_body_close"; + echo "\n\n"; + echo "\n\n"; + exit; + } + } + } + if ($auth_fail > 0) + { + $stmt="UPDATE vicidial_two_factor_auth SET auth_attempts=(auth_attempts + 1) where user='$VD_login' and auth_stage='0';"; + $rslt=mysql_to_mysqli($stmt, $link); + + $auth_failed_attempts=1; + $stmt="SELECT auth_attempts from vicidial_two_factor_auth where user='$VD_login' and auth_stage='0' order by auth_code_exp_date desc limit 1;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $auth_attempt_to_print = mysqli_num_rows($rslt); + if ($auth_attempt_to_print > 0) + { + $row=mysqli_fetch_row($rslt); + $auth_failed_attempts = $row[0]; + } + if ($auth_failed_attempts >= $auth_code_attempts) + { + $stmt="UPDATE vicidial_users set failed_login_count='$auth_failed_attempts',last_ip='$ip' where user='$VD_login';"; + $rslt=mysql_to_mysqli($stmt, $link); + } + } + echo "
\n"; + exit; + } + + ##### BEGIN send out AUTH CODE and show auth-code entry page ##### + if ($auth_entry > 0) + { + $ACbegin = '1'; + $ACend = '9'; + $i=1; + while($i < $auth_code_length) + { + $ACbegin .= '0'; + $ACend .= '9'; + $i++; + } + $NEWauth_code = rand($ACbegin, $ACend); + $auth_exp_date = date("Y-m-d H:i:s", mktime(date("H")+$SStwo_factor_auth_hours,date("i"),date("s"),date("m"),date("d"),date("Y"))); + $auth_code_exp_date = date("Y-m-d H:i:s", mktime(date("H"),date("i")+$auth_code_expire_minutes,date("s"),date("m"),date("d"),date("Y"))); + + ### insert auth_code into vicidial_two_factor_auth table + $stmt="INSERT INTO vicidial_two_factor_auth SET auth_date=NOW(),auth_exp_date='$auth_exp_date',user='$VD_login',auth_stage='0',auth_code='$NEWauth_code',auth_code_exp_date='$auth_code_exp_date',auth_method='$stage',auth_attempts='0';"; + $rslt=mysql_to_mysqli($stmt, $link); + $affected_rows = mysqli_affected_rows($link); + if ($DB) {echo "$affected_rows|$stmt\n";} + + # invalidate all older auth_code entries + if ($affected_rows > 0) + { + $stmt="UPDATE vicidial_two_factor_auth SET auth_stage='6' where user='$VD_login' and auth_stage!='6' and auth_code!='$NEWauth_code';"; + $rslt=mysql_to_mysqli($stmt, $link); + $affected_rows = mysqli_affected_rows($link); + if ($DB) {echo "$affected_rows|$stmt\n";} + } + + ### Send auth code by EMAIL + if ($stage == 'EMAIL') + { + $email_message = preg_replace('/--A--auth_code--B--/i',"$NEWauth_code",$email_message); + + // To send HTML mail, the Content-type header must be set + $headers = 'MIME-Version: 1.0' . "\r\n"; + $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; + + // Create email headers + $headers .= 'From: ' . $email_from . "\r\n" . 'Reply-To: ' . $email_from . "\r\n" . 'X-Mailer: PHP/' . phpversion(); + + $body = "" . $email_message . ""; + + $success = mail($LOGemail, $email_subject, $body, $headers ); + if ($success) + { + $stmt = "INSERT INTO vicidial_agent_function_log set agent_log_id='0',user='$VD_login',function='2FA_send',event_time=NOW(),campaign_id='-ADMIN-',user_group='$LOGuser_group',lead_id='0',uniqueid='SUCCESS',caller_code='$ip',stage='$stage',comments='EMAIL: $LOGemail';"; + + echo "
"._QXZ("Your authorization code has been sent by %1s to",0,'',$stage).": $OBSCUREemail
\n"; + } + else + { + $stmt = "INSERT INTO vicidial_agent_function_log set agent_log_id='0',user='$VD_login',function='2FA_send',event_time=NOW(),campaign_id='-ADMIN-',user_group='$LOGuser_group',lead_id='0',uniqueid='ERROR',caller_code='$ip',stage='$stage',comments='EMAIL: $LOGemail';"; + + $error_msg = error_get_last()['message']; + echo "$error_msg"; + } + + ### LOG INSERTION Admin Log Table ### + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + } + + ### Send auth code by PHONE + if ($stage == 'PHONE') + { + $context_2FA = '2FA_say_auth_code'; + if (strlen($phone_message_override) > 0) {$context_2FA = $phone_message_override;} + if (strlen($ext_context) < 1) {$ext_context='default';} + $local_DEF = 'Local/'; + $local_AMP = '@'; + $Local_dial_timeout = '60000'; + $Ndialstring = "$phone_prefix$LOGmobile_number"; + $VMvariable = "Variable: access_code=$NEWauth_code"; + ### insert a NEW record to the vicidial_manager table to be processed + $stmtB = "INSERT INTO vicidial_manager(uniqueid,entry_date,status,response,server_ip,channel,action,callerid,cmd_line_b,cmd_line_c,cmd_line_d,cmd_line_e,cmd_line_f,cmd_line_g,cmd_line_h,cmd_line_i,cmd_line_j,cmd_line_k) values('',NOW(),'NEW','N','$phone_server_ip','','Originate','$VqueryCID','Exten: s','Context: $context_2FA','Channel: $local_DEF$Ndialstring$local_AMP$ext_context','Priority: 1','Callerid: $phone_cid_number','Timeout: $Local_dial_timeout','$VMvariable','','','')"; + $rslt=mysql_to_mysqli($stmtB, $link); + + $stmt = "INSERT INTO vicidial_agent_function_log set agent_log_id='0',user='$VD_login',function='2FA_send',event_time=NOW(),campaign_id='-ADMIN-',user_group='$LOGuser_group',lead_id='0',uniqueid='SUCCESS',caller_code='$ip',stage='$stage',comments='PHONE: $LOGmobile_number';"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + + echo "
"._QXZ("Your authorization code has been sent by %1s to",0,'',$stage).": $OBSCUREmobile_number
\n"; + } + + ### Send auth code by SMS + if ($stage == 'SMS') + { + $sms_url = preg_replace('/--A--auth_code--B--/i',"$NEWauth_code",$sms_url); + $sms_url = preg_replace('/--A--mobile_number--B--/i',"$LOGmobile_number",$sms_url); + + ### insert a new url log entry + $SQL_log = "$sms_url"; + $SQL_log = preg_replace('/;/','',$SQL_log); + $SQL_log = addslashes($SQL_log); + $stmt = "INSERT INTO vicidial_url_log SET uniqueid='2FA',url_date=NOW(),url_type='2FA_SMS',url='$SQL_log',url_response='';"; + # if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $affected_rows = mysqli_affected_rows($link); + $url_id = mysqli_insert_id($link); + + $URLstart_sec = date("U"); + + ### grab the call_start_url ### + # if ($DB > 0) {echo "$sms_url
\n";} + $SCUfile = file("$sms_url"); + if ( !($SCUfile) ) + { + $error_array = error_get_last(); + $error_type = $error_array["type"]; + $error_message = $error_array["message"]; + $error_line = $error_array["line"]; + $error_file = $error_array["file"]; + } + + if ($DB > 0) {echo "$SCUfile[0]
\n";} + + ### update url log entry + $URLend_sec = date("U"); + $URLdiff_sec = ($URLend_sec - $URLstart_sec); + if ($SCUfile) + { + $SCUfile_contents = implode("", $SCUfile); + $SCUfile_contents = preg_replace('/;/','',$SCUfile_contents); + $SCUfile_contents = addslashes($SCUfile_contents); + } + else + { + $SCUfile_contents = "PHP ERROR: Type=$error_type - Message=$error_message - Line=$error_line - File=$error_file"; + } + $stmt = "UPDATE vicidial_url_log SET response_sec='$URLdiff_sec',url_response='$SCUfile_contents' where url_log_id='$url_id';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $affected_rows = mysqli_affected_rows($link); + + $stmt = "INSERT INTO vicidial_agent_function_log set agent_log_id='0',user='$VD_login',function='2FA_send',event_time=NOW(),campaign_id='-ADMIN-',user_group='$LOGuser_group',lead_id='0',uniqueid='SUCCESS',caller_code='$ip',stage='$stage',comments='SMS: $LOGmobile_number';"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + + echo "
"._QXZ("Your authorization code has been sent by %1s to",0,'',$stage).": $OBSCUREmobile_number
\n"; + } + + echo ""._QXZ("Agent web client: 2FA Auth")."\n"; + echo "\n"; + echo "\n"; + + echo "
\n"; + echo "
\n"; + echo ""; + + echo "
\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + # echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + # echo "\n"; + echo "
\n"; + + echo "\n"; + + echo "\n"; + + + echo "\n"; + echo "
"._QXZ("Please enter the Auth Code that you have received by %1s into the field below, and click the SUBMIT button",0,'',$stage).". "._QXZ("To resend your auth code, click here to go back").".
 
"._QXZ("Authorization Code").":
\n"; + exit; + } + ##### END send out AUTH CODE and show auth-code entry page ##### + + ##### BEGIN choose how to send out AUTH CODE page ##### + else + { + if ($show_form > 0) + { + echo ""._QXZ("Agent web client: 2FA Auth")."\n"; + echo "\n"; + echo "\n"; + + echo "
\n"; + echo "
\n"; + echo ""; + + echo "
\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + # echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + # echo "\n"; + echo "
\n"; + + echo "\n"; + + echo "\n"; + + #echo "\n"; + echo "
"._QXZ("Your account has Two-Factor-Authorization enabled on it. In order to log in, you will need to verify your identity by submitting a temporary authorization code. Click on the icon below for the delivery method you would like to use to receive your authorization code").":

\n"; + + echo "\n"; + $displayed_2FA=0; + if ( (preg_match("/YES/i",$email_auth)) and (strlen($LOGemail) > 3) ) + { + echo " 0) {echo " onclick=\"send_2FA('EMAIL');\"";} echo ">\n"; + echo "\n"; + echo "\n"; + echo "\n"; + $displayed_2FA++; + } + if ( (preg_match("/YES/i",$phone_auth)) and (strlen($LOGmobile_number) > 1) ) + { + echo " 0) {echo " onclick=\"send_2FA('PHONE');\"";} echo ">\n"; + echo "\n"; + echo "\n"; + echo "\n"; + $displayed_2FA++; + } + if ( (preg_match("/YES/i",$sms_auth)) and (strlen($LOGmobile_number) > 1) ) + { + echo " 0) {echo " onclick=\"send_2FA('SMS');\"";} echo ">\n"; + echo "\n"; + echo "\n"; + echo "\n"; + $displayed_2FA++; + } + if ($displayed_2FA < 1) + { + echo _QXZ("Your User account is not configured for Two-Factor-Authentication. Please contact your system administrator").".\n"; + exit; + } + echo "
"._QXZ("Email you an auth code")."
"._QXZ("Send an email to").":
$OBSCUREemail
"._QXZ("Call you and play an auth code")."
"._QXZ("Place a phone call to").":
$OBSCUREmobile_number
"._QXZ("Text-Message you an auth code")."
"._QXZ("Send a message to").":
$OBSCUREmobile_number

 \n"; + + echo "
\n"; + exit; + } + } + ##### END choose how to send out AUTH CODE page ##### + } + if ($VUforce_change_password == 'Y') { echo "