diff options
author | Christoph Wurst <christoph@owncloud.com> | 2016-05-19 11:20:22 +0200 |
---|---|---|
committer | Christoph Wurst <christoph@owncloud.com> | 2016-05-23 09:11:12 +0200 |
commit | 74277c25be2f3231e52a73a684bd14452a9ff2aa (patch) | |
tree | ca68eac57db357563e64e9f323df667fcc28f8f6 /settings/js | |
parent | 6495534bcdbbda8aa2748cc9f5d94dcb2bc7a04a (diff) | |
download | nextcloud-server-74277c25be2f3231e52a73a684bd14452a9ff2aa.tar.gz nextcloud-server-74277c25be2f3231e52a73a684bd14452a9ff2aa.zip |
add button to invalidate browser sessions/device tokens
Diffstat (limited to 'settings/js')
-rw-r--r-- | settings/js/authtoken_collection.js | 18 | ||||
-rw-r--r-- | settings/js/authtoken_view.js | 104 |
2 files changed, 110 insertions, 12 deletions
diff --git a/settings/js/authtoken_collection.js b/settings/js/authtoken_collection.js index dd964356d06..a78e053995f 100644 --- a/settings/js/authtoken_collection.js +++ b/settings/js/authtoken_collection.js @@ -26,9 +26,25 @@ OC.Settings = OC.Settings || {}; var AuthTokenCollection = Backbone.Collection.extend({ + model: OC.Settings.AuthToken, + + /** + * Show recently used sessions/devices first + * + * @param {OC.Settigns.AuthToken} t1 + * @param {OC.Settigns.AuthToken} t2 + * @returns {Boolean} + */ + comparator: function (t1, t2) { + var ts1 = parseInt(t1.get('lastActivity'), 10); + var ts2 = parseInt(t2.get('lastActivity'), 10); + return ts1 < ts2; + }, + tokenType: null, - url: OC.generateUrl('/settings/personal/authtokens'), + + url: OC.generateUrl('/settings/personal/authtokens') }); OC.Settings.AuthTokenCollection = AuthTokenCollection; diff --git a/settings/js/authtoken_view.js b/settings/js/authtoken_view.js index 8ca38d80d84..a165a465247 100644 --- a/settings/js/authtoken_view.js +++ b/settings/js/authtoken_view.js @@ -26,62 +26,110 @@ OC.Settings = OC.Settings || {}; var TEMPLATE_TOKEN = - '<tr>' + '<tr data-id="{{id}}">' + '<td>{{name}}</td>' - + '<td>{{lastActivity}}</td>' + + '<td><span class="last-activity" title="{{lastActivityTime}}">{{lastActivity}}</span></td>' + + '<td><a class="icon-delete" title="' + t('core', 'Disconnect') + '"></a></td>' + '<tr>'; var SubView = Backbone.View.extend({ collection: null, + + /** + * token type + * - 0: browser + * - 1: device + * + * @see OC\Authentication\Token\IToken + */ type: 0, - template: Handlebars.compile(TEMPLATE_TOKEN), + + _template: undefined, + + template: function(data) { + if (_.isUndefined(this._template)) { + this._template = Handlebars.compile(TEMPLATE_TOKEN); + } + + return this._template(data); + }, + initialize: function(options) { this.type = options.type; this.collection = options.collection; + + this.on(this.collection, 'change', this.render); }, + render: function() { var _this = this; - var list = this.$el.find('.token-list'); + var list = this.$('.token-list'); var tokens = this.collection.filter(function(token) { - return parseInt(token.get('type')) === _this.type; + return parseInt(token.get('type'), 10) === _this.type; }); list.html(''); + // Show header only if there are tokens to show + console.log(tokens.length > 0); + this._toggleHeader(tokens.length > 0); + tokens.forEach(function(token) { var viewData = token.toJSON(); - viewData.lastActivity = moment(viewData.lastActivity, 'X'). - format('LLL'); + var ts = viewData.lastActivity * 1000; + viewData.lastActivity = OC.Util.relativeModifiedDate(ts); + viewData.lastActivityTime = OC.Util.formatDate(ts, 'LLL'); var html = _this.template(viewData); - list.append(html); + var $html = $(html); + $html.find('.last-activity').tooltip(); + $html.find('.icon-delete').tooltip(); + list.append($html); }); }, + toggleLoading: function(state) { - this.$el.find('.token-list').toggleClass('icon-loading', state); + this.$('.token-list').toggleClass('icon-loading', state); + }, + + _toggleHeader: function(show) { + this.$('.hidden-when-empty').toggleClass('hidden', !show); } }); var AuthTokenView = Backbone.View.extend({ collection: null, + _views: [], + _form: undefined, + _tokenName: undefined, + _addTokenBtn: undefined, + _result: undefined, + _newToken: undefined, + _hideTokenBtn: undefined, + _addingToken: false, + initialize: function(options) { this.collection = options.collection; var tokenTypes = [0, 1]; var _this = this; _.each(tokenTypes, function(type) { + var el = type === 0 ? '#sessions' : '#devices'; _this._views.push(new SubView({ - el: type === 0 ? '#sessions' : '#devices', + el: el, type: type, collection: _this.collection })); + + var $el = $(el); + $el.on('click', 'a.icon-delete', _.bind(_this._onDeleteToken, _this)); }); this._form = $('#device-token-form'); @@ -91,15 +139,18 @@ this._result = $('#device-token-result'); this._newToken = $('#device-new-token'); + this._newToken.on('focus', _.bind(this._onNewTokenFocus, this)); this._hideTokenBtn = $('#device-token-hide'); this._hideTokenBtn.click(_.bind(this._hideToken, this)); }, + render: function() { _.each(this._views, function(view) { view.render(); view.toggleLoading(false); }); }, + reload: function() { var _this = this; @@ -116,6 +167,7 @@ OC.Notification.showTemporary(t('core', 'Error while loading browser sessions and device tokens')); }); }, + _addDeviceToken: function() { var _this = this; this._toggleAddingToken(true); @@ -131,8 +183,9 @@ $.when(creatingToken).done(function(resp) { _this.collection.add(resp.deviceToken); _this.render(); - _this._newToken.text(resp.token); + _this._newToken.val(resp.token); _this._toggleFormResult(false); + _this._newToken.select(); _this._tokenName.val(''); }); $.when(creatingToken).fail(function() { @@ -142,13 +195,42 @@ _this._toggleAddingToken(false); }); }, + + _onNewTokenFocus: function() { + this._newToken.select(); + }, + _hideToken: function() { this._toggleFormResult(true); }, + _toggleAddingToken: function(state) { this._addingToken = state; this._addTokenBtn.toggleClass('icon-loading-small', state); }, + + _onDeleteToken: function(event) { + var $target = $(event.target); + var $row = $target.closest('tr'); + var id = $row.data('id'); + + var token = this.collection.get(id); + if (_.isUndefined(token)) { + // Ignore event + return; + } + + var destroyingToken = token.destroy(); + + var _this = this; + $.when(destroyingToken).fail(function() { + OC.Notification.showTemporary(t('core', 'Error while deleting the token')); + }); + $.when(destroyingToken).always(function() { + _this.render(); + }); + }, + _toggleFormResult: function(showForm) { this._form.toggleClass('hidden', !showForm); this._result.toggleClass('hidden', showForm); |