PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/modules/security/options_user_settings.php

https://gitlab.com/alexprowars/bitrix
PHP | 364 lines | 354 code | 4 blank | 6 comment | 14 complexity | a7cb6665e993215604ba6e160031720e MD5 | raw file
  1. <?
  2. /**
  3. * @global int $ID - Edited user id
  4. * @global string $strError - Save error
  5. * @global \CUser $USER
  6. * @global CMain $APPLICATION
  7. */
  8. use Bitrix\Security\Mfa\Otp;
  9. use Bitrix\Main\Web\Json;
  10. IncludeModuleLangFile(__FILE__);
  11. if(!CModule::IncludeModule("security") || !CSecurityUser::isActive()):?>
  12. <tr>
  13. <td><?=GetMessage("SEC_OTP_NEW_ACCESS_DENIED")?></td>
  14. </tr>
  15. <?
  16. return;
  17. endif;
  18. ?>
  19. <?if(
  20. $ID <= 0
  21. || ($USER->getID() != $ID && !$USER->CanDoOperation('security_edit_user_otp'))
  22. )
  23. return;
  24. ?>
  25. <?
  26. CJSCore::Init(array('qrcode', 'ajax', 'window'));
  27. $APPLICATION->AddHeadScript('/bitrix/js/security/admin/page/user-edit.js');
  28. $otp = Otp::getByUser($ID);
  29. $deactivateUntil = $otp->getDeactivateUntil();
  30. $availableTypes = Otp::getAvailableTypes();
  31. $availableTypesDescription = \Bitrix\Security\Mfa\Otp::getTypesDescription();
  32. $currentPage = $APPLICATION->GetCurPageParam(
  33. sprintf('%s_active_tab=%s',$tabControl->name, $tabControl->tabs[$tabControl->tabIndex]['DIV']),
  34. array(sprintf('%s_active_tab',$tabControl->name))
  35. );
  36. $deactivateDays = array();
  37. $deactivateDays[] = GetMessage("SEC_OTP_NO_DAYS");
  38. for($i=1; $i <= 10; $i++)
  39. {
  40. $deactivateDays[$i] = FormatDate("ddiff", time()-60*60*24*$i);
  41. }
  42. $jsMessages = array(
  43. 'SEC_OTP_ERROR_TITLE' => GetMessage('SEC_OTP_ERROR_TITLE'),
  44. 'SEC_OTP_UNKNOWN_ERROR' => GetMessage('SEC_OTP_UNKNOWN_ERROR')
  45. );
  46. $jsSettings = array(
  47. 'userId' => (int) $ID,
  48. 'successfulUrl' => $currentPage,
  49. 'deactivateDays' => $deactivateDays,
  50. 'availableTypes' => $availableTypesDescription
  51. )
  52. ?>
  53. <script type="text/javascript">
  54. BX.message(<?=Json::encode($jsMessages)?>);
  55. </script>
  56. <script type="text/javascript">
  57. BX.ready(function() {
  58. var settings = <?=Json::encode($jsSettings)?>;
  59. new BX.Security.UserEdit.Otp(settings.userId, settings);
  60. });
  61. </script>
  62. <!--Popup starts-->
  63. <tr style="display: none;">
  64. <td colspan="2">
  65. <div id="otp-mobile-popup" class="otp-popup otp-mobile" data-title="<?=GetMessage('SEC_OTP_CONNECT_MOBILE_TITLE')?>">
  66. <div class="otp-description">
  67. <ol>
  68. <li><?=GetMessage('SEC_OTP_CONNECT_MOBILE_STEP_1')?></li>
  69. <li><?=GetMessage('SEC_OTP_CONNECT_MOBILE_STEP_2')?></li>
  70. <li><?=GetMessage('SEC_OTP_CONNECT_MOBILE_STEP_3')?></li>
  71. </ol>
  72. </div>
  73. <div class="otp-connect">
  74. <div id="connect-by-qr">
  75. <div class="input-type">
  76. <span class="current"><?=GetMessage('SEC_OTP_MOBILE_SCAN_QR')?></span><span class="separator"><?=GetMessage('SEC_OTP_MOBILE_INPUT_METHODS_SEPARATOR')?></span><a href="#" id="connect-mobile-manual-input"><?=GetMessage('SEC_OTP_MOBILE_MANUAL_INPUT')?></a>
  77. </div>
  78. <div style="margin-bottom: 20px">
  79. <?=GetMessage('SEC_OTP_CONNECT_MOBILE_SCAN_QR')?>
  80. </div>
  81. <div>
  82. <div class="input-wrapper">
  83. <div data-role="qr-code-block" data-autoclear="yes" style="margin-top: 8px; margin-left: 8px;"></div>
  84. </div>
  85. </div>
  86. </div>
  87. <div id="connect-by-manual-input" style="display: none;">
  88. <div class="input-type">
  89. <a href="#" id="connect-mobile-scan-qr"><?=GetMessage('SEC_OTP_MOBILE_SCAN_QR')?></a><span class="separator"><?=GetMessage('SEC_OTP_MOBILE_INPUT_METHODS_SEPARATOR')?></span><span class="current"><?=GetMessage('SEC_OTP_MOBILE_MANUAL_INPUT')?></span>
  90. </div>
  91. <div style="margin-bottom: 20px">
  92. <?=GetMessage('SEC_OTP_CONNECT_MOBILE_MANUAL_INPUT')?>
  93. <span class="type-title" data-show-type="hotp"><?=GetMessage('SEC_OTP_CONNECT_MOBILE_MANUAL_INPUT_HOTP')?></span>
  94. <span class="type-title" data-show-type="totp"><?=GetMessage('SEC_OTP_CONNECT_MOBILE_MANUAL_INPUT_TOTP')?></span>
  95. .
  96. </div>
  97. <div>
  98. <div class="input-wrapper">
  99. <div data-role="app-code-block" data-autoclear="yes" style="margin-left: auto; margin-right: auto; margin-top: 98px; font-weight: bold; text-align: center;">#APP_CODE#</div>
  100. </div>
  101. </div>
  102. </div>
  103. </div>
  104. <div>
  105. <p>
  106. <?=GetMessage('SEC_OTP_CONNECT_MOBILE_INPUT_DESCRIPTION')?>
  107. </p>
  108. <p>
  109. <input type="text" dir="ltr" data-autoclear="yes" data-role="check-code" autocomplete="off" placeholder="<?=GetMessage('SEC_OTP_CONNECT_MOBILE_ENTER_CODE')?>">
  110. </p>
  111. <p data-require-two-codes="yes">
  112. <?=GetMessage('SEC_OTP_CONNECT_MOBILE_INPUT_NEXT_DESCRIPTION')?>
  113. </p>
  114. <p data-require-two-codes="yes">
  115. <input type="text" dir="ltr" data-autoclear="yes" data-role="check-code" autocomplete="off" placeholder="<?=GetMessage('SEC_OTP_CONNECT_MOBILE_ENTER_NEXT_CODE')?>">
  116. </p>
  117. <div data-role="error-container" class="error-wrapper" data-autoclear="yes"></div>
  118. </div>
  119. </div>
  120. <div id="otp-device-popup" class="otp-popup otp-device" data-title="<?=GetMessage('SEC_OTP_CONNECT_DEVICE_TITLE')?>">
  121. <table>
  122. <tr>
  123. <td>
  124. <?=GetMessage("SEC_OTP_TYPE")?>:
  125. </td>
  126. <td>
  127. <?foreach($availableTypes as $value):?>
  128. <span class="type-title" data-show-type="<?=$value?>">
  129. <?=(isset($availableTypesDescription[$value]['title'])? $availableTypesDescription[$value]['title'] : $value)?>
  130. </span>
  131. <?endforeach?>
  132. </td>
  133. </tr>
  134. <tr>
  135. <td>
  136. <?=GetMessage("SEC_OTP_SECRET_KEY")?>:
  137. </td>
  138. <td>
  139. <input type="text" autocomplete="off" data-autoclear="yes" data-role="secret-code" size="40" maxlength="64" value="">
  140. </td>
  141. </tr>
  142. <tr class="heading">
  143. <td colspan="2"><?=GetMessage("SEC_OTP_INIT")?></td>
  144. </tr>
  145. <tr>
  146. <td>
  147. <?=GetMessage("SEC_OTP_PASS1")?>:
  148. </td>
  149. <td>
  150. <input type="text" autocomplete="off" data-autoclear="yes" data-role="check-code" size="8" maxlength="8" value="">
  151. </td>
  152. </tr>
  153. <tr data-require-two-codes="yes">
  154. <td>
  155. <?=GetMessage("SEC_OTP_PASS2")?>:
  156. </td>
  157. <td>
  158. <input type="text" autocomplete="off" data-autoclear="yes" data-role="check-code" size="8" maxlength="8" value="">
  159. </td>
  160. </tr>
  161. <tr>
  162. <td colspan="2">
  163. <div data-role="error-container" class="error-wrapper" data-autoclear="yes"></div>
  164. </td>
  165. </tr>
  166. </table>
  167. </div>
  168. <div id="otp-recovery-codes" class="otp-popup otp-recovery-codes" data-title="<?=GetMessage('SEC_OTP_RECOVERY_CODES_TITLE')?>">
  169. <p>
  170. <?=GetMessage('SEC_OTP_RECOVERY_CODES_DESCRIPTION')?>
  171. </p>
  172. <p>
  173. <?=GetMessage('SEC_OTP_RECOVERY_CODES_WARNING')?>
  174. </p>
  175. <div class="input-wrapper">
  176. <div>
  177. <ol data-role="recoverycodes-container" class="codes-container" style="display: none;">
  178. <li data-role="recoverycode-template" data-autoclear="yes">#CODE#</li>
  179. </ol>
  180. </div>
  181. </div>
  182. <p>
  183. <div style="margin-top: 10px">
  184. <input type="button" data-role="print-codes" value="<?=GetMessage('SEC_OTP_RECOVERY_CODES_PRINT')?>" />
  185. <input type="button" data-role="save-codes" value="<?=GetMessage('SEC_OTP_RECOVERY_CODES_SAVE_FILE')?>" />
  186. </div>
  187. </p>
  188. <p>
  189. <div><?=GetMessage('SEC_OTP_RECOVERY_CODES_REGENERATE_DESCRIPTION')?></div>
  190. <div data-role="error-container" class="error-wrapper" data-autoclear="yes"></div>
  191. <div>
  192. <input type="button" data-role="regenerate-codes" value="<?=GetMessage('SEC_OTP_RECOVERY_CODES_REGENERATE')?>" />
  193. </div>
  194. </p>
  195. <p>
  196. * <?=GetMessage('SEC_OTP_RECOVERY_CODES_NOTE')?>
  197. </p>
  198. </div>
  199. </td>
  200. </tr>
  201. <!--Popup ends-->
  202. <?if (!$otp->isActivated()):?>
  203. <?if (
  204. Otp::isMandatoryUsing()
  205. && $otp->getInitialDate() // User trigger any of OTP mechanisms
  206. && $USER->CanDoOperation('security_edit_user_otp')
  207. && !$otp->canSkipMandatoryByRights()
  208. ):?>
  209. <tr>
  210. <td>
  211. <?if (!$otp->isMandatorySkipped()):?>
  212. <?=BeginNote()?>
  213. <?=getMessage('SEC_OTP_MANDATORY_EXPIRED')?>
  214. <span class="otp-link-button" id="otp-deffer"><?=GetMessage('SEC_OTP_MANDATORY_DEFFER')?></span>
  215. <?=EndNote()?>
  216. <?elseif ($otp->isMandatorySkipped() && $otp->getDeactivateUntil()):?>
  217. <?=BeginNote()?>
  218. <?=getMessage('SEC_OTP_MANDATORY_ALMOST_EXPIRED', array('#DATE#' => $otp->getDeactivateUntil()))?>
  219. <span class="otp-link-button" id="otp-deffer"><?=GetMessage('SEC_OTP_MANDATORY_DEFFER')?></span>
  220. <?=EndNote()?>
  221. <?else:?>
  222. <?=BeginNote()?>
  223. <?=getMessage('SEC_OTP_MANDATORY_DISABLED')?>
  224. <span class="otp-link-button" id="otp-mandatory-active">
  225. <?if (empty($deactivateDays)):?>
  226. <?=GetMessage('SEC_OTP_MANDATORY_ENABLE_DEFAULT')?>
  227. <?else:?>
  228. <?=GetMessage('SEC_OTP_MANDATORY_ENABLE')?>
  229. <?endif;?>
  230. </span>
  231. <?=EndNote()?>
  232. <?endif;?>
  233. </td>
  234. </tr>
  235. <?endif;?>
  236. <tr>
  237. <?if ($otp->isInitialized()):?>
  238. <td style="text-align: left;">
  239. <a class="adm-btn-save adm-btn" id="otp-activate"><?=GetMessage('SEC_OTP_ENABLE')?></a>
  240. <?if ($deactivateUntil):?>
  241. <span>(<?=getMessage('SEC_OTP_DEACTIVATE_UNTIL', array('#DATE#' => $deactivateUntil))?>)</span>
  242. <?endif;?>
  243. </td>
  244. <td style="text-align: right;">
  245. <a class="adm-btn-save adm-btn adm-btn-menu" id="otp-connect-device"><?=GetMessage('SEC_OTP_CONNECT_DEVICE')?></a>
  246. <a class="adm-btn-save adm-btn adm-btn-menu" id="otp-connect-mobile" style="margin-left: 20px;"><?=GetMessage('SEC_OTP_CONNECT_MOBILE')?></a>
  247. </td>
  248. <?else:?>
  249. <td colspan="2">
  250. <a class="adm-btn-save adm-btn adm-btn-menu" id="otp-connect-device"><?=GetMessage('SEC_OTP_CONNECT_DEVICE')?></a>
  251. <a class="adm-btn-save adm-btn adm-btn-menu" id="otp-connect-mobile" style="margin-left: 20px;"><?=GetMessage('SEC_OTP_CONNECT_MOBILE')?></a>
  252. </td>
  253. <?endif;?>
  254. </tr>
  255. <tr>
  256. <td colspan="2">
  257. <div style=" padding: 20px;">
  258. <h3 style="clear:both"><br><?=getMessage('SEC_OTP_DESCRIPTION_INTRO_TITLE')?></h3>
  259. <div style="float: left; margin-right: 20px">
  260. <div style="-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; border: 2px solid #e0e3e5; border-radius: 2px; height: 156px; width: 156px; background: white url(/bitrix/images/security/etoken_pass.png?v2) no-repeat center center;"></div>
  261. </div>
  262. <div>
  263. <?=(IsModuleInstalled('intranet')?
  264. getMessage('SEC_OTP_DESCRIPTION_INTRO_INTRANET'):
  265. getMessage('SEC_OTP_DESCRIPTION_INTRO_SITE'))?>
  266. </div>
  267. <?
  268. if (in_array(LANGUAGE_ID, array('en', 'ru', 'de'), true))
  269. $imageLanguage = LANGUAGE_ID;
  270. else
  271. $imageLanguage = \Bitrix\Main\Localization\Loc::getDefaultLang(LANGUAGE_ID);
  272. ?>
  273. <h3 style="clear:both"><br><?=getMessage('SEC_OTP_DESCRIPTION_USING_TITLE')?></h3>
  274. <div style="float: left; margin-right: 20px">
  275. <div style="-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; border: 2px solid #e0e3e5; border-radius: 2px; padding: 5px 10px; background: white; height: 150px;">
  276. <div style="float: left; background: url(/bitrix/images/security/<?=$imageLanguage?>_login_step0.png) no-repeat top right; width: 220px; height: 120px; padding-top: 20px;" ><?=getMessage('SEC_OTP_DESCRIPTION_USING_STEP_0')?></div>
  277. <div style="float: left; background: url(/bitrix/images/security/<?=$imageLanguage?>_login_step1.png) no-repeat top right; width: 220px; height: 120px; padding-top: 20px; margin-left:20px;"><?=getMessage('SEC_OTP_DESCRIPTION_USING_STEP_1')?></div>
  278. </div>
  279. </div>
  280. <div>
  281. <?=getMessage('SEC_OTP_DESCRIPTION_USING')?>
  282. </div>
  283. <h3 style="clear:both"><br><?=getMessage('SEC_OTP_DESCRIPTION_ACTIVATION_TITLE')?></h3>
  284. <div>
  285. <?=getMessage('SEC_OTP_DESCRIPTION_ACTIVATION')?>
  286. </div>
  287. <?=BeginNote()?>
  288. <h3><?=getMessage('SEC_OTP_DESCRIPTION_ABOUT_TITLE')?></h3>
  289. <div>
  290. <?=getMessage('SEC_OTP_DESCRIPTION_ABOUT')?>
  291. </div>
  292. <?=EndNote()?>
  293. </div>
  294. </td>
  295. </tr>
  296. <?else:?>
  297. <?if (Otp::isRecoveryCodesEnabled()):?>
  298. <?
  299. $codes = \Bitrix\Security\Mfa\RecoveryCodesTable::getList(array(
  300. 'select' => array('ID'),
  301. 'filter' => array('=USER_ID' => $ID),
  302. 'limit' => 1
  303. ))->fetch();
  304. if (!$codes):?>
  305. <tr data-role="otp-recovery-codes-warning">
  306. <td colspan="2">
  307. <?CAdminMessage::ShowMessage(array(
  308. "MESSAGE" => GetMessage('SEC_OTP_WARNING_RECOVERY_CODES'),
  309. "TYPE" => 'ERROR',
  310. "HTML" => true
  311. ));?>
  312. </td>
  313. </tr>
  314. <?endif;?>
  315. <?endif;?>
  316. <tr>
  317. <td style="text-align: left;">
  318. <span><?=GetMessage('SEC_OTP_CONNECTED')?></span>
  319. <?if(
  320. !Otp::isMandatoryUsing()
  321. || $otp->canSkipMandatory()
  322. || $USER->CanDoOperation('security_edit_user_otp')
  323. ):?>
  324. <span class="otp-link-button" id="otp-deactivate"><?=GetMessage('SEC_OTP_DISABLE')?></span>
  325. <?endif;?>
  326. <?if (Otp::isRecoveryCodesEnabled()):?>
  327. <span class="otp-link-button" id="otp-show-recovery-codes"><?=GetMessage('SEC_OTP_RECOVERY_CODES_BUTTON')?></span>
  328. <?endif;?>
  329. <?if ($USER->CanDoOperation('security_edit_user_otp')):?>
  330. <span class="otp-link-button" id="otp-reinitialize"><?=GetMessage('SEC_OTP_SYNC_NOW')?></span>
  331. <?endif;?>
  332. </td>
  333. <td style="text-align: right;">
  334. <a class="adm-btn-save adm-btn adm-btn-menu" id="otp-connect-device"><?=GetMessage('SEC_OTP_CONNECT_NEW_DEVICE')?></a>
  335. <a class="adm-btn-save adm-btn adm-btn-menu" id="otp-connect-mobile" style="margin-left: 20px;"><?=GetMessage('SEC_OTP_CONNECT_NEW_MOBILE')?></a>
  336. </td>
  337. </tr>
  338. <?if ($USER->CanDoOperation('security_edit_user_otp')):?>
  339. <tr class="heading" style="display:none;" data-show-on-reinitialize="yes">
  340. <td colspan="2"><?=GetMessage("SEC_OTP_INIT")?></td>
  341. <input type="hidden" name="profile_module_id[]" value="security">
  342. </tr>
  343. <tr style="display:none;" data-show-on-reinitialize="yes">
  344. <td>
  345. <?=GetMessage("SEC_OTP_PASS1")?>:
  346. </td>
  347. <td>
  348. <input type="text" autocomplete="off" id="security_SYNC1" name="security_SYNC1" size="8" maxlength="8" value="">
  349. </td>
  350. </tr>
  351. <tr style="display:none;" data-show-on-reinitialize="yes">
  352. <td>
  353. <?=GetMessage("SEC_OTP_PASS2")?>:
  354. </td>
  355. <td>
  356. <input type="text" autocomplete="off" id="security_SYNC2" name="security_SYNC2" size="8" maxlength="8" value="">
  357. </td>
  358. </tr>
  359. <?endif;?>
  360. <?endif;?>