You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

authtoken_view.js 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /* global Handlebars, moment */
  2. /**
  3. * @author Christoph Wurst <christoph@owncloud.com>
  4. *
  5. * @copyright Copyright (c) 2016, ownCloud, Inc.
  6. * @license AGPL-3.0
  7. *
  8. * This code is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License, version 3,
  10. * as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Affero General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Affero General Public License, version 3,
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>
  19. *
  20. */
  21. (function(OC, _, $, Handlebars, moment) {
  22. 'use strict';
  23. OC.Settings = OC.Settings || {};
  24. var TEMPLATE_TOKEN =
  25. '<tr data-id="{{id}}">'
  26. + '<td class="has-tooltip" title="{{name}}"><span class="token-name">{{name}}</span></td>'
  27. + '<td><span class="last-activity has-tooltip" title="{{lastActivityTime}}">{{lastActivity}}</span></td>'
  28. + '<td><a class="icon-delete has-tooltip" title="' + t('core', 'Disconnect') + '"></a></td>'
  29. + '<tr>';
  30. var SubView = OC.Backbone.View.extend({
  31. collection: null,
  32. /**
  33. * token type
  34. * - 0: browser
  35. * - 1: device
  36. *
  37. * @see OC\Authentication\Token\IToken
  38. */
  39. type: 0,
  40. _template: undefined,
  41. template: function(data) {
  42. if (_.isUndefined(this._template)) {
  43. this._template = Handlebars.compile(TEMPLATE_TOKEN);
  44. }
  45. return this._template(data);
  46. },
  47. initialize: function(options) {
  48. this.type = options.type;
  49. this.collection = options.collection;
  50. this.on(this.collection, 'change', this.render);
  51. },
  52. render: function() {
  53. var _this = this;
  54. var list = this.$('.token-list');
  55. var tokens = this.collection.filter(function(token) {
  56. return parseInt(token.get('type'), 10) === _this.type;
  57. });
  58. list.html('');
  59. // Show header only if there are tokens to show
  60. this._toggleHeader(tokens.length > 0);
  61. tokens.forEach(function(token) {
  62. var viewData = token.toJSON();
  63. var ts = viewData.lastActivity * 1000;
  64. viewData.lastActivity = OC.Util.relativeModifiedDate(ts);
  65. viewData.lastActivityTime = OC.Util.formatDate(ts, 'LLL');
  66. var html = _this.template(viewData);
  67. var $html = $(html);
  68. $html.find('.has-tooltip').tooltip({container: 'body'});
  69. list.append($html);
  70. });
  71. },
  72. toggleLoading: function(state) {
  73. this.$('.token-list').toggleClass('icon-loading', state);
  74. },
  75. _toggleHeader: function(show) {
  76. this.$('.hidden-when-empty').toggleClass('hidden', !show);
  77. }
  78. });
  79. var AuthTokenView = OC.Backbone.View.extend({
  80. collection: null,
  81. _views: [],
  82. _form: undefined,
  83. _tokenName: undefined,
  84. _addAppPasswordBtn: undefined,
  85. _result: undefined,
  86. _newAppLoginName: undefined,
  87. _newAppPassword: undefined,
  88. _hideAppPasswordBtn: undefined,
  89. _addingToken: false,
  90. initialize: function(options) {
  91. this.collection = options.collection;
  92. var tokenTypes = [0, 1];
  93. var _this = this;
  94. _.each(tokenTypes, function(type) {
  95. var el = type === 0 ? '#sessions' : '#apppasswords';
  96. _this._views.push(new SubView({
  97. el: el,
  98. type: type,
  99. collection: _this.collection
  100. }));
  101. var $el = $(el);
  102. $el.on('click', 'a.icon-delete', _.bind(_this._onDeleteToken, _this));
  103. });
  104. this._form = $('#app-password-form');
  105. this._tokenName = $('#app-password-name');
  106. this._addAppPasswordBtn = $('#add-app-password');
  107. this._addAppPasswordBtn.click(_.bind(this._addAppPassword, this));
  108. this._result = $('#app-password-result');
  109. this._newAppLoginName = $('#new-app-login-name');
  110. this._newAppLoginName.on('focus', _.bind(this._onNewTokenLoginNameFocus, this));
  111. this._newAppPassword = $('#new-app-password');
  112. this._newAppPassword.on('focus', _.bind(this._onNewTokenFocus, this));
  113. this._hideAppPasswordBtn = $('#app-password-hide');
  114. this._hideAppPasswordBtn.click(_.bind(this._hideToken, this));
  115. },
  116. render: function() {
  117. _.each(this._views, function(view) {
  118. view.render();
  119. view.toggleLoading(false);
  120. });
  121. },
  122. reload: function() {
  123. var _this = this;
  124. _.each(this._views, function(view) {
  125. view.toggleLoading(true);
  126. });
  127. var loadingTokens = this.collection.fetch();
  128. $.when(loadingTokens).done(function() {
  129. _this.render();
  130. });
  131. $.when(loadingTokens).fail(function() {
  132. OC.Notification.showTemporary(t('core', 'Error while loading browser sessions and device tokens'));
  133. });
  134. },
  135. _addAppPassword: function() {
  136. var _this = this;
  137. this._toggleAddingToken(true);
  138. var deviceName = this._tokenName.val();
  139. var creatingToken = $.ajax(OC.generateUrl('/settings/personal/authtokens'), {
  140. method: 'POST',
  141. data: {
  142. name: deviceName
  143. }
  144. });
  145. $.when(creatingToken).done(function(resp) {
  146. _this.collection.add(resp.deviceToken);
  147. _this.render();
  148. _this._newAppLoginName.val(resp.loginName);
  149. _this._newAppPassword.val(resp.token);
  150. _this._toggleFormResult(false);
  151. _this._newAppPassword.select();
  152. _this._tokenName.val('');
  153. });
  154. $.when(creatingToken).fail(function() {
  155. OC.Notification.showTemporary(t('core', 'Error while creating device token'));
  156. });
  157. $.when(creatingToken).always(function() {
  158. _this._toggleAddingToken(false);
  159. });
  160. },
  161. _onNewTokenLoginNameFocus: function() {
  162. this._newAppLoginName.select();
  163. },
  164. _onNewTokenFocus: function() {
  165. this._newAppPassword.select();
  166. },
  167. _hideToken: function() {
  168. this._toggleFormResult(true);
  169. },
  170. _toggleAddingToken: function(state) {
  171. this._addingToken = state;
  172. this._addAppPasswordBtn.toggleClass('icon-loading-small', state);
  173. },
  174. _onDeleteToken: function(event) {
  175. var $target = $(event.target);
  176. var $row = $target.closest('tr');
  177. var id = $row.data('id');
  178. var token = this.collection.get(id);
  179. if (_.isUndefined(token)) {
  180. // Ignore event
  181. return;
  182. }
  183. var destroyingToken = token.destroy();
  184. $row.find('.icon-delete').tooltip('hide');
  185. var _this = this;
  186. $.when(destroyingToken).fail(function() {
  187. OC.Notification.showTemporary(t('core', 'Error while deleting the token'));
  188. });
  189. $.when(destroyingToken).always(function() {
  190. _this.render();
  191. });
  192. },
  193. _toggleFormResult: function(showForm) {
  194. this._form.toggleClass('hidden', !showForm);
  195. this._result.toggleClass('hidden', showForm);
  196. }
  197. });
  198. OC.Settings.AuthTokenView = AuthTokenView;
  199. })(OC, _, $, Handlebars, moment);