Current Path : /var/www/www-root/data/webdav/www/www.monolith-realty.ru/bitrix/js/security/admin/page/ |
Current File : /var/www/www-root/data/webdav/www/www.monolith-realty.ru/bitrix/js/security/admin/page/user-edit.js |
BX.namespace('BX.Security.UserEdit'); BX.Security.UserEdit.Otp = (function getUserOtp(BX) { "use strict"; var Manager = function(userId, options) { var defaults = { 'successfulUrl': document.location.href, 'deactivateDays' : null, 'availableTypes': null, 'ui': { 'activateButtonId': 'otp-activate', 'deactivateButtonId': 'otp-deactivate', 'defferButtonId': 'otp-deffer', 'mandatoryActivateButtonId': 'otp-mandatory-active', 'reinitializeButtonId': 'otp-reinitialize' } }; options = options || {}; this._options = mergeObjects(defaults, options); this.userId = userId || 0; var modelOptions = { 'availableTypes': this._options.availableTypes, 'successfulUrl': this._options.successfulUrl }; this.device = new Device(this.userId, modelOptions); this.mobile = new Mobile(this.userId, modelOptions); this.recovery = new RecoveryCodes(this.userId, modelOptions); var tmp = null; tmp = BX(this._options.ui.deactivateButtonId); if (tmp) { this.initializeDeactivatePopup(tmp, 'deactivate'); } tmp = BX(this._options.ui.defferButtonId); if (tmp) { this.initializeDeactivatePopup(tmp, 'deffer'); } tmp = BX(this._options.ui.mandatoryActivateButtonId); if (tmp) { this.initializeDeactivatePopup(tmp, 'deffer', 5); } tmp = BX(this._options.ui.activateButtonId); if (tmp) { BX.bind( tmp, 'click', this.mobile.activateOtp.bind(this.mobile) ) } tmp = BX(this._options.ui.reinitializeButtonId); if (tmp) { BX.bind( tmp, 'click', BX.proxy(function onReinitialize() { var elements = window.document.body.querySelectorAll('[data-show-on-reinitialize="yes"]'); [].forEach.call( elements, function showElements(element) { if (element.style.display) element.style.display = ''; else element.style.display = 'none' }, this ); }, this) ) } }; Manager.prototype.initializeDeactivatePopup = function(element, action, startDay) { action = action || 'deactivate'; if (this._options.deactivateDays) { var daysObj = []; for (var i in this._options.deactivateDays) { if (!this._options.deactivateDays.hasOwnProperty(i)) continue; if (startDay && i < startDay) continue; daysObj.push({ 'TEXT': this._options.deactivateDays[i], 'ONCLICK': this.mobile.deactivateOtp.bind(this.mobile, null, action, i) }); } BX.bind( element, 'click', (function (event) { if (event) event.preventDefault(); BX.adminShowMenu(element, daysObj, {'active_class': '', 'close_on_click': true}); }).bind(this) ); } else { BX.bind( element, 'click', this.mobile.deactivateOtp.bind(this, null, action, startDay? startDay: 0) ); } }; /* -----------/Base popup model/--------------*/ var BaseModel = function(userId, options) { var defaults = { 'actionUrl': '/bitrix/admin/security_otp.ajax.php?lang=' + BX.message('LANGUAGE_ID'), 'onCompleteCallback': BX.DoNothing, 'ui': { 'showButtonId': null, 'id': null } }; options = options || {}; this._options = mergeObjects(defaults, options); this.initialized = false; this.popup = null; this.container = null; this.errorContainer = null; this.userId = userId; this.showButton = BX(this._options.ui.showButtonId); this.type = null; this.typeMenu = []; BX.bind( this.showButton, 'click', this.show.bind(this) ); }; BaseModel.prototype.show = function(event) { if (!this.initialized) this.initialize(); else this.cleanPopup(); this.onShow(); if (event) event.preventDefault(); }; // Override this methods if needed;-) BaseModel.prototype.onShow = function() {}; BaseModel.prototype.onInitialize = function() {}; BaseModel.prototype.getSecret = function () {}; BaseModel.prototype.getStartTimestamp = function () {}; BaseModel.prototype.getType = function() { return this.type; }; BaseModel.prototype.initialize = function() { this.initialized = true; this.container = BX(this._options.ui.id); this.popup = this.getPopup(); this.errorContainer = this.container.querySelector('[data-role="error-container"]'); for(var type in this._options.availableTypes) { if (!this._options.availableTypes.hasOwnProperty(type)) continue; this.typeMenu.push({ 'TEXT': this._options.availableTypes[type].title, 'ONCLICK': (function onType(type, isTwoCodeRequired) { if (isTwoCodeRequired === void 0) isTwoCodeRequired = true; this.type = type; this.onShow(true, isTwoCodeRequired); }).bind(this, this._options.availableTypes[type].type, this._options.availableTypes[type]['required_two_code']) }); } var checkCodes = this.container.querySelectorAll('input[data-role="check-code"]'); this.popup.ClearButtons(); this.popup.SetButtons([ { title: BX.message('JS_CORE_WINDOW_SAVE'), id: 'check-button', className: 'adm-btn-save', action: (function proxyCheck(event) { if (event) event.preventDefault(); this.onCheck( checkCodes[0], checkCodes[1] || null // Second check code may be absent for some OtpAlgorithm ); }).bind(this) }, BX.CDialog.btnCancel ]); this.onInitialize(); }; BaseModel.prototype.getPopup = function() { return new BX.CDialog({ title : this.container.getAttribute('data-title') || '', resizable: false, content: this.container }); }; BaseModel.prototype.cleanPopup = function() { [].forEach.call( this.container.querySelectorAll('[data-autoclear="yes"]'), function cleanElement(element) { switch (element.tagName) { case 'INPUT': element.value = ''; break; case 'SELECT': break; default: BX.cleanNode(element); } }, this ); }; BaseModel.prototype.sendRequest = function(action, data, onSuccess, onFailure) { BX.showWait(); data = data || {}; data.action = action || 'check'; data.sessid = BX.bitrix_sessid(); if (!data.userId) data.user = this.userId; data = BX.ajax.prepareData(data); return BX.ajax({ 'method': 'POST', 'dataType': 'json', 'url': this._options['actionUrl'], 'data': data, 'onsuccess': this.onRequestSuccess.bind(this, onSuccess), 'onfailure': this.onRequestFailed.bind(this, onFailure) }); }; BaseModel.prototype.onRequestSuccess = function(callback, response) { BX.closeWait(); if (!response['status']) { this.onRequestFailed(null, response); } else if (response['status'] !== 'ok') { this.onRequestFailed(null, response); } else { callback(response); } }; BaseModel.prototype.onRequestFailed = function(callback, response) { BX.closeWait(); if (!callback) { if (response['error']) this.showError(response['error']); else this.showError(BX.message('SEC_OTP_UNKNOWN_ERROR')); } else { callback(response); } }; BaseModel.prototype.showError = function(errorMessage) { if (!this.errorContainer) return; var errorElement = BX.create('div', { 'children': [ BX.create('div', { 'text': BX.message('SEC_OTP_ERROR_TITLE') }), BX.create('div', { 'html': errorMessage }) ], 'attrs': {'className': "bx-notice error"} }); this.errorContainer.appendChild(errorElement); }; BaseModel.prototype.clearErrors = function() { if (!this.errorContainer) return; BX.cleanNode(this.errorContainer); }; BaseModel.prototype.onCheck = function(sync1, sync2) { this.clearErrors(); this.activate(sync1.value, sync2? sync2.value: ''); }; BaseModel.prototype.activate = function(sync1, sync2) { var data = { 'secret': this.getSecret(), 'type': this.getType(), 'startTimestamp': this.getStartTimestamp(), 'sync1': sync1, 'sync2': sync2 }; this.sendRequest('check_activate', data, BX.proxy(this.onFinish, this)); }; BaseModel.prototype.onFinish = function() { window.location.replace(this._options.successfulUrl); }; BaseModel.prototype.showPopup = function() { this.popup.Show(); this.popup.adjustSizeEx(); BX.defer(this.popup.adjustPos, this.popup)(); }; BaseModel.prototype.showTypeTitle = function(type) { var elements = this.container.querySelectorAll('[data-show-type]'); [].forEach.call( elements, function showHide(el) { if (el.getAttribute('data-show-type') == type) el.style.display = ''; else el.style.display = 'none'; } ) }; BaseModel.prototype.showHideRedundantCodes = function(isTwoCodeRequired) { var elements = this.container.querySelectorAll('[data-require-two-codes="yes"]'); [].forEach.call( elements, function showHide(el) { if (isTwoCodeRequired) el.style.display = ''; else el.style.display = 'none'; } ); }; /* -----------/Device popup/--------------*/ var Device = function(userId, options) { var defaults = { 'ui': { 'showButtonId': 'otp-connect-device', 'id': 'otp-device-popup' } }; options = options || {}; options = mergeObjects(defaults, options); this.secretCodeElement = null; this.startTimestampElement = null; this.typeElement = null; Device.superclass.constructor.call(this, userId, options); }; BX.extend(Device, BaseModel); Device.prototype.onShow = function(typeChosen, isTwoCodeRequired) { if (!typeChosen && this.typeMenu.length) { // User must choose OTP generation algorithm BX.adminShowMenu(this.showButton, this.typeMenu, {'active_class': 'adm-btn-save-active'}); return; } this.showHideRedundantCodes(isTwoCodeRequired); this.showTypeTitle(this.type); this.showPopup(); }; Device.prototype.onInitialize = function() { this.secretCodeElement = this.container.querySelector('[data-role="secret-code"]'); this.typeElement = this.container.querySelector('[data-role="type-selector"]'); this.startTimestampElement = this.container.querySelector('[data-role="start-timestamp"]'); }; Device.prototype.getSecret = function () { return this.secretCodeElement.value; }; Device.prototype.getStartTimestamp = function () { return this.startTimestampElement.value; }; /* -----------/Mobile popup/--------------*/ var Mobile = function(userId, options) { var defaults = { 'ui': { 'showButtonId': 'otp-connect-mobile', 'id': 'otp-mobile-popup' } }; options = options || {}; options = mergeObjects(defaults, options); this.secret = null; this.qrCodeElement = null; this.appSecretElement = null; Mobile.superclass.constructor.call(this, userId, options); }; BX.extend(Mobile, BaseModel); Mobile.prototype.onShow = function(typeChosen) { if (!typeChosen && this.typeMenu.length) { // User must choose OTP generation algorithm BX.adminShowMenu(this.showButton, this.typeMenu, {'active_class': 'adm-btn-save-active'}); return; } this.sendRequest( 'get_vew_params', {'type': this.type || ''}, (function onGetParams(response) { this.secret = response.data.secret; this.type = response.data.type; this.showHideRedundantCodes(response.data.isTwoCodeRequired); this.showTypeTitle(response.data.type); this.drawQrCode(this.qrCodeElement, response.data.provisionUri); this.appSecretElement.innerHTML = BX.util.htmlspecialchars(response.data.appSecretSpaced); this.showPopup(); }).bind(this) ); }; Mobile.prototype.onInitialize = function() { this.qrCodeElement = this.container.querySelector('[data-role="qr-code-block"]'); this.appSecretElement = this.container.querySelector('[data-role="app-code-block"]'); BX.bind( BX('connect-mobile-manual-input'), 'click', function() { BX('connect-by-manual-input').style.display = ''; BX('connect-by-qr').style.display = 'none'; } ); BX.bind( BX('connect-by-manual-input'), 'click', function() { BX('connect-by-manual-input').style.display = 'none'; BX('connect-by-qr').style.display = ''; } ); }; Mobile.prototype.getSecret = function () { return this.secret; }; Mobile.prototype.drawQrCode = function(element, provisionUri) { new QRCode(element, { text: provisionUri, width: 200, height: 200, colorDark : '#000000', colorLight : '#ffffff', correctLevel : QRCode.CorrectLevel.H }); }; Mobile.prototype.deactivateOtp = function(event, action, numDays) { if (event) event.preventDefault(); this.sendRequest( action, {'days': numDays}, (function onDeactivated() { window.location.replace(this._options.successfulUrl); }).bind(this) ); }; Mobile.prototype.activateOtp = function(event) { if (event) event.preventDefault(); this.sendRequest( 'activate', null, (function onActivated() { window.location.replace(this._options.successfulUrl); }).bind(this) ); }; /* -----------/Recovery codes popup/--------------*/ var RecoveryCodes = function(userId, options) { var defaults = { 'actionUrl': '/bitrix/admin/security_otp.ajax.php?lang=' + BX.message('LANGUAGE_ID'), 'publicUrl': '/bitrix/admin/security_otp_recovery_codes.php?lang=' + BX.message('LANGUAGE_ID'), 'ui': { 'showButtonId': 'otp-show-recovery-codes', 'id': 'otp-recovery-codes' } }; options = options || {}; options = mergeObjects(defaults, options); RecoveryCodes.superclass.constructor.call(this, userId, options); }; BX.extend(RecoveryCodes, BaseModel); RecoveryCodes.prototype.onShow = function(regenerate) { regenerate = regenerate || null; this.sendRequest( regenerate? 'regenerate_recovery_codes': 'get_recovery_codes', regenerate? null: {'allow_regenerate': 'Y'}, (function onGetParams(response) { this.drawRecoveryCodes(response.codes); var warningElement = document.body.querySelector('[data-role="otp-recovery-codes-warning"]'); if (warningElement) warningElement.style.display = 'none'; this.showPopup(); }).bind(this) ); }; RecoveryCodes.prototype.onInitialize = function() { // Clear unwanted dialog buttons... this.popup.ClearButtons(); this.codesContainer = this.container.querySelector('[data-role="recoverycodes-container"]'); this.codesContainer.style.display = ''; this.codesTemplate = this.container.querySelector('[data-role="recoverycode-template"]').cloneNode(true); BX.bind( this.container.querySelector('[data-role="print-codes"]'), 'click', (function onPrint() { window.open(this._options['publicUrl'] + '&user=' + this.userId); }).bind(this) ); BX.bind( this.container.querySelector('[data-role="save-codes"]'), 'click', (function onDownload() { window.location.href = this._options['publicUrl'] + '&action=download' + '&user=' + this.userId }).bind(this) ); BX.bind( this.container.querySelector('[data-role="regenerate-codes"]'), 'click', this.onShow.bind(this, true) ); }; RecoveryCodes.prototype.drawRecoveryCodes = function(codes) { // Clean old codes [].forEach.call( this.codesContainer.querySelectorAll('[data-autoclear="yes"]'), function cleanElement(element) { BX.remove(element); }, this ); // Create new:-) [].forEach.call( codes, function drawCode(code) { var node = this.codesTemplate.cloneNode(true); if (!code.used) { BX.adjust(node, { 'text': code.value, 'attrs': { 'className': 'active' } }); } else { node.innerHTML = ''; BX.adjust(node, { 'html': '', 'children': [ BX.create('span', { 'text': code.value }), BX.create('span', { 'text': ' (' + formatDatetime(code.using_date) + ')' }) ], 'attrs': { 'className': 'used' } }); } this.codesContainer.appendChild(node); }, this ); }; /* -----------/Utils/--------------*/ function mergeObjects(origin, add) { for (var p in add) { if (!add.hasOwnProperty(p)) continue; if (add[p] && add[p].constructor === Object) { if (origin[p] && origin[p].constructor === Object) { origin[p] = mergeObjects(origin[p], add[p]); } else { origin[p] = clone(add[p]); } } else { origin[p] = add[p]; } } return origin; } function clone(o) { return JSON.parse(JSON.stringify(o)); } function formatDatetime(timestamp) { var format = null; if (!BX.isAmPmMode()) format = [ ["tommorow", "tommorow, H:i"], ["today", "today, H:i"], ["yesterday", "yesterday, H:i"], ["", BX.date.convertBitrixFormat(BX.message("FORMAT_DATETIME"))] ]; else format = [ ["tommorow", "tommorow, g:i a"], ["today", "today, g:i a"], ["yesterday", "yesterday, g:i a"], ["", BX.date.convertBitrixFormat(BX.message("FORMAT_DATETIME"))] ]; return BX.date.format(format, parseInt(timestamp), BX.date.convertToUTC(new Date())); } return Manager; }(BX));