<?php
require_once __DIR__.'/include/classes/user/CWebUser.php';
require_once __DIR__.'/include/config.inc.php';
CMessageHelper::clear();
$fields = [
'enter' => [T_ZBX_STR, O_OPT, P_SYS, null, null],
'request' => [T_ZBX_STR, O_OPT, null, null, null],
'totp_secret' => [T_ZBX_STR, O_OPT, null, null, null],
'hash_function' => [T_ZBX_STR, O_OPT, null, null, null],
'verification_code' => [T_ZBX_INT, O_OPT, null, null, null],
'qr_code_url' => [T_ZBX_STR, O_OPT, null, null, null],
'duo_code' => [T_ZBX_STR, O_OPT, null, null, null],
'state' => [T_ZBX_STR, O_OPT, null, null, null]
];
check_fields($fields);
$page['scripts'] = ['qrcode.js'];
$redirect_to = (new CUrl('index.php'))->setArgument('form', 'default');
$request = getRequest('request', '');
if ($request != '' && !CHtmlUrlValidator::validateSameSite($request)) {
$request = '';
}
if ($request != '') {
$redirect_to->setArgument('request', $request);
}
try {
$session_data = json_decode(base64_decode(CCookieHelper::get(ZBX_SESSION_NAME)), true);
if (!$session_data || !array_key_exists('confirmid', $session_data)) {
redirect($redirect_to->toString());
}
$session_data_sign = CSessionHelper::get('sign');
$session_data_sign_check = CEncryptHelper::sign(json_encode(array_diff_key($session_data, array_flip(['sign']))));
if (!$session_data_sign || !CEncryptHelper::checkSign($session_data_sign, $session_data_sign_check)) {
throw new Exception(_('Session initialization error.'));
}
if ($request != '') {
CSessionHelper::set('request', $request);
}
$duo_redirect_uri = ((new CUrl($_SERVER['REQUEST_URI']))
->removeArgument('state')
->removeArgument('duo_code'))
->setArgument('request', $request)
->toString();
$full_duo_redirect_url = implode('', [HTTPS ? 'https://' : 'http://', $_SERVER['HTTP_HOST'], $duo_redirect_uri]);
$confirm_data = [
'sessionid' => CSessionHelper::get('confirmid'),
'redirect_uri' => implode('', [HTTPS ? 'https://' : 'http://', $_SERVER['HTTP_HOST'], $duo_redirect_uri])
];
$error = null;
if (!CSessionHelper::has('state') && !hasRequest('enter')) {
$data = CUser::getConfirmData($confirm_data);
if ($data['mfa']['type'] == MFA_TYPE_TOTP) {
session_write_close();
echo (new CView('mfa.login', $data))->getOutput();
exit;
}