/* Authors: * Petr Vobornik * * Copyright (C) 2013 Red Hat * see file 'COPYING' for use and warranty information * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ define(['dojo/_base/declare', 'dojo/_base/lang', 'dojo/Deferred', 'dojo/dom-construct', 'dojo/dom-style', 'dojo/query', 'dojo/on', '../ipa', '../auth', '../reg', '../FieldBinder', '../text', '../util', './LoginScreenBase' ], function(declare, lang, Deferred, construct, dom_style, query, on, IPA, auth, reg, FieldBinder, text, util, LoginScreenBase) { /** * Widget with OTP sync form. * * @class widgets.SyncOTPScreen */ var SyncOTPScreen = declare([LoginScreenBase], { sync_fail: "Token synchronization failed", invalid_credentials: "The username, password or token codes are not correct", sync_success: "Token was synchronized", allow_cancel: true, user: null, //nodes: cancel_btn_node: null, sync_btn_node: null, render_buttons: function(container) { this.cancel_btn_node = IPA.button({ name: 'cancel', label: 'Cancel', 'class': 'btn-default btn-lg', click: lang.hitch(this, this.on_cancel) })[0]; if (this.allow_cancel) { construct.place(this.cancel_btn_node, container); } this.sync_btn_node = IPA.button({ label: text.get('@i18n:password.sync_otp_token', "Sync OTP Token"), 'class': 'btn-primary btn-lg', click: lang.hitch(this, this.on_confirm) })[0]; construct.place(this.sync_btn_node, container); }, refresh: function() { this.reset(); this.get_widget('validation').remove('sync'); if (this.user) { this.get_field('user').set_value([this.user]); this.get_widget('password').focus_input(); } else { this.get_widget('user').focus_input(); } if (this.buttons_node) { this.buttons_node.innerHTML = ""; if (this.allow_cancel) { construct.place(this.cancel_btn_node, this.buttons_node); } construct.create('span', { innerHTML: ' '}, this.buttons_node); construct.place(this.sync_btn_node, this.buttons_node); } }, on_cancel: function() { this.emit('sync-cancel', { source: this }); }, on_confirm: function() { this.sync(); }, sync: function() { var val_summary = this.get_widget('validation'); val_summary.remove('sync'); if (!this.validate()) return; var user = this.get_field('user').get_value()[0]; var password_f = this.get_field('password'); var password = password_f.get_value()[0]; var otp1 = this.get_field('first_code').get_value()[0]; var otp2 = this.get_field('second_code').get_value()[0]; var token = this.get_field('token').get_value()[0]; var p = this.sync_core(user, password, otp1, otp2, token); p.then(lang.hitch(this, function(result) { var msg = this.sync_fail; var evt = 'sync-fail'; var type = 'error'; this.refresh(); if (result === 'ok') { evt = 'sync-success'; msg = this.sync_success; val_summary.add_success('sync', msg); } else if (result === 'invalid-credentials') { msg = this.invalid_credentials; val_summary.add_error('sync', msg); } else { val_summary.add_error('sync', msg); } this.emit(evt, { source: this, message: msg, status: result }); })); }, sync_core: function(user, password, otp1, otp2, token) { var d = new Deferred(); var data = { user: user, password: password, first_code: otp1, second_code: otp2 }; if (token) data.token = token; var handler = function(data, text_status, xhr) { var result = xhr.getResponseHeader("X-IPA-TokenSync-Result"); result = result || 'error'; IPA.hide_activity_icon(); d.resolve(result); }; var request = { url: '/ipa/session/sync_token', data: data, contentType: 'application/x-www-form-urlencoded', processData: true, dataType: 'html', type: 'POST', success: handler, error: handler }; IPA.display_activity_icon(); $.ajax(request); return d.promise; }, setUser: function(value) { this.user = value; this.get_field('user').set_value([value]); }, constructor: function(spec) { spec = spec || {}; this.aside = "

" + this.otp_info_msg + "

"; this.sync_fail = text.get(spec.sync_fail || '@i18n:password.otp_sync_fail', this.sync_fail); this.sync_success = text.get(spec.sync_success || '@i18n:password.otp_sync_success', this.sync_success); this.invalid_credentials = text.get(spec.invalid_credentials || '@i18n:password.otp_sync_invalid', this.invalid_credentials); this.field_specs = SyncOTPScreen.field_specs; } }); SyncOTPScreen.field_specs = [ { $type: 'text', name: 'user', label: text.get('@i18n:login.username', "Username"), show_errors: false, undo: false, required: true }, { $type: 'password', name: 'password', label: text.get('@i18n:login.password', "Password"), show_errors: false, undo: false, required: true }, { $type: 'password', name: 'first_code', label: text.get('@i18n:password.first_otp', "First OTP"), show_errors: false, undo: false, required: true }, { $type: 'password', name: 'second_code', label: text.get('@i18n:password.second_otp', "Second OTP"), show_errors: false, undo: false, required: true }, { $type: 'text', name: 'token', label: text.get('@i18n:password.token_id', "Token ID"), show_errors: false, undo: false } ]; return SyncOTPScreen; });