PageRenderTime 76ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/openid-connect-server-webapp/src/main/webapp/resources/js/token.js

https://gitlab.com/jslee1/OpenID-Connect-Java-Spring-Server
JavaScript | 508 lines | 359 code | 106 blank | 43 comment | 45 complexity | 96eb760234d60e53b40efb051f0e49d8 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright 2016 The MITRE Corporation
  3. * and the MIT Internet Trust Consortium
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *******************************************************************************/
  17. var AccessTokenModel = Backbone.Model.extend({
  18. idAttribute: 'id',
  19. defaults:{
  20. id:null,
  21. value:null,
  22. idTokenId:null,
  23. refreshTokenId:null,
  24. scopes:[],
  25. clientId:null,
  26. userId:null,
  27. expiration:null
  28. },
  29. urlRoot: 'api/tokens/access'
  30. });
  31. var AccessTokenCollection = Backbone.Collection.extend({
  32. idAttribute: 'id',
  33. model: AccessTokenModel,
  34. url: 'api/tokens/access'
  35. });
  36. var AccessTokenView = Backbone.View.extend({
  37. tagName: 'tr',
  38. initialize:function (options) {
  39. this.options = options;
  40. if (!this.template) {
  41. this.template = _.template($('#tmpl-access-token').html());
  42. }
  43. if (!this.scopeTemplate) {
  44. this.scopeTemplate = _.template($('#tmpl-scope-list').html());
  45. }
  46. if (!this.moreInfoTemplate) {
  47. this.moreInfoTemplate = _.template($('#tmpl-client-more-info-block').html());
  48. }
  49. this.model.bind('change', this.render, this);
  50. },
  51. events: {
  52. 'click .btn-delete':'deleteToken',
  53. 'click .token-substring':'showTokenValue',
  54. 'click .toggleMoreInformation': 'toggleMoreInformation'
  55. },
  56. render:function (eventName) {
  57. var expirationDate = this.model.get("expiration");
  58. if (expirationDate == null) {
  59. expirationDate = "Never";
  60. } else if (!moment(expirationDate).isValid()) {
  61. expirationDate = "Unknown";
  62. } else {
  63. expirationDate = moment(expirationDate).calendar();
  64. }
  65. var json = {token: this.model.toJSON(), client: this.options.client.toJSON(), formattedExpiration: expirationDate};
  66. this.$el.html(this.template(json));
  67. // hide full value
  68. $('.token-full', this.el).hide();
  69. // show scopes
  70. $('.scope-list', this.el).html(this.scopeTemplate({scopes: this.model.get('scopes'), systemScopes: this.options.systemScopeList}));
  71. $('.client-more-info-block', this.el).html(this.moreInfoTemplate({client: this.options.client.toJSON()}));
  72. $(this.el).i18n();
  73. return this;
  74. },
  75. deleteToken:function (e) {
  76. e.preventDefault();
  77. if (confirm($.t("token.token-table.confirm"))) {
  78. var _self = this;
  79. this.model.destroy({
  80. dataType: false, processData: false,
  81. success:function () {
  82. _self.$el.fadeTo("fast", 0.00, function () { //fade
  83. $(this).slideUp("fast", function () { //slide up
  84. $(this).remove(); //then remove from the DOM
  85. // refresh the table in case we removed an id token, too
  86. _self.parentView.refreshTable();
  87. });
  88. });
  89. },
  90. error:function (error, response) {
  91. //Pull out the response text.
  92. var responseJson = JSON.parse(response.responseText);
  93. //Display an alert with an error message
  94. $('#modalAlert div.modal-header').html(responseJson.error);
  95. $('#modalAlert div.modal-body').html(responseJson.error_description);
  96. $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
  97. "backdrop" : "static",
  98. "keyboard" : true,
  99. "show" : true // ensure the modal is shown immediately
  100. });
  101. }
  102. });
  103. this.parentView.delegateEvents();
  104. }
  105. return false;
  106. },
  107. toggleMoreInformation:function(e) {
  108. e.preventDefault();
  109. if ($('.moreInformation', this.el).is(':visible')) {
  110. // hide it
  111. $('.moreInformation', this.el).hide('fast');
  112. $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-right');
  113. $('.moreInformationContainer', this.el).removeClass('alert').removeClass('alert-info').addClass('muted');
  114. } else {
  115. // show it
  116. $('.moreInformation', this.el).show('fast');
  117. $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-down');
  118. $('.moreInformationContainer', this.el).addClass('alert').addClass('alert-info').removeClass('muted');
  119. }
  120. },
  121. close:function () {
  122. $(this.el).unbind();
  123. $(this.el).empty();
  124. },
  125. showTokenValue:function (e) {
  126. e.preventDefault();
  127. $('.token-substring', this.el).hide();
  128. $('.token-full', this.el).show();
  129. }
  130. });
  131. var RefreshTokenModel = Backbone.Model.extend({
  132. idAttribute: 'id',
  133. defaults:{
  134. id:null,
  135. value:null,
  136. scopes:[],
  137. clientId:null,
  138. userId:null,
  139. expiration:null
  140. },
  141. urlRoot: 'api/tokens/refresh'
  142. });
  143. var RefreshTokenCollection = Backbone.Collection.extend({
  144. idAttribute: 'id',
  145. model: RefreshTokenModel,
  146. url: 'api/tokens/refresh'
  147. });
  148. var RefreshTokenView = Backbone.View.extend({
  149. tagName: 'tr',
  150. initialize:function (options) {
  151. this.options = options;
  152. if (!this.template) {
  153. this.template = _.template($('#tmpl-refresh-token').html());
  154. }
  155. if (!this.scopeTemplate) {
  156. this.scopeTemplate = _.template($('#tmpl-scope-list').html());
  157. }
  158. if (!this.moreInfoTemplate) {
  159. this.moreInfoTemplate = _.template($('#tmpl-client-more-info-block').html());
  160. }
  161. this.model.bind('change', this.render, this);
  162. },
  163. events: {
  164. 'click .btn-delete':'deleteToken',
  165. 'click .token-substring':'showTokenValue',
  166. 'click .toggleMoreInformation': 'toggleMoreInformation'
  167. },
  168. render:function (eventName) {
  169. var expirationDate = this.model.get("expiration");
  170. if (expirationDate == null) {
  171. expirationDate = "Never";
  172. } else if (!moment(expirationDate).isValid()) {
  173. expirationDate = "Unknown";
  174. } else {
  175. expirationDate = moment(expirationDate).calendar();
  176. }
  177. var json = {token: this.model.toJSON(), client: this.options.client.toJSON(), formattedExpiration: expirationDate, accessTokenCount: this.options.accessTokenCount};
  178. this.$el.html(this.template(json));
  179. // hide full value
  180. $('.token-full', this.el).hide();
  181. // show scopes
  182. $('.scope-list', this.el).html(this.scopeTemplate({scopes: this.model.get('scopes'), systemScopes: this.options.systemScopeList}));
  183. $('.client-more-info-block', this.el).html(this.moreInfoTemplate({client: this.options.client.toJSON()}));
  184. $(this.el).i18n();
  185. return this;
  186. },
  187. deleteToken:function (e) {
  188. e.preventDefault();
  189. if (confirm($.t('token.token-table.confirm-refresh'))) {
  190. var _self = this;
  191. this.model.destroy({
  192. dataType: false, processData: false,
  193. success:function () {
  194. _self.$el.fadeTo("fast", 0.00, function () { //fade
  195. $(this).slideUp("fast", function () { //slide up
  196. $(this).remove(); //then remove from the DOM
  197. // refresh the table in case the access tokens have changed, too
  198. _self.parentView.refreshTable();
  199. });
  200. });
  201. },
  202. error:function (error, response) {
  203. //Pull out the response text.
  204. var responseJson = JSON.parse(response.responseText);
  205. //Display an alert with an error message
  206. $('#modalAlert div.modal-header').html(responseJson.error);
  207. $('#modalAlert div.modal-body').html(responseJson.error_description);
  208. $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
  209. "backdrop" : "static",
  210. "keyboard" : true,
  211. "show" : true // ensure the modal is shown immediately
  212. });
  213. }
  214. });
  215. _self.parentView.delegateEvents();
  216. }
  217. return false;
  218. },
  219. toggleMoreInformation:function(e) {
  220. e.preventDefault();
  221. if ($('.moreInformation', this.el).is(':visible')) {
  222. // hide it
  223. $('.moreInformation', this.el).hide('fast');
  224. $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-right');
  225. $('.moreInformationContainer', this.el).removeClass('alert').removeClass('alert-info').addClass('muted');
  226. } else {
  227. // show it
  228. $('.moreInformation', this.el).show('fast');
  229. $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-down');
  230. $('.moreInformationContainer', this.el).addClass('alert').addClass('alert-info').removeClass('muted');
  231. }
  232. },
  233. close:function () {
  234. $(this.el).unbind();
  235. $(this.el).empty();
  236. },
  237. showTokenValue:function (e) {
  238. e.preventDefault();
  239. $('.token-substring', this.el).hide();
  240. $('.token-full', this.el).show();
  241. }
  242. });
  243. var TokenListView = Backbone.View.extend({
  244. tagName: 'span',
  245. initialize:function(options) {
  246. this.options = options;
  247. },
  248. events:{
  249. "click .refresh-table":"refreshTable",
  250. 'page .paginator-access':'changePageAccess',
  251. 'page .paginator-refresh':'changePageRefresh'
  252. },
  253. load:function(callback) {
  254. if (this.model.access.isFetched &&
  255. this.model.refresh.isFetched &&
  256. this.options.clientList.isFetched &&
  257. this.options.systemScopeList.isFetched) {
  258. callback();
  259. return;
  260. }
  261. $('#loadingbox').sheet('show');
  262. $('#loading').html(
  263. '<span class="label" id="loading-access">' + $.t('token.token-table.access-tokens') + '</span> ' +
  264. '<span class="label" id="loading-refresh">' + $.t('token.token-table.refresh-tokens') + '</span> ' +
  265. '<span class="label" id="loading-clients">' + $.t('common.clients') + '</span> ' +
  266. '<span class="label" id="loading-scopes">' + $.t('common.scopes') + '</span> '
  267. );
  268. $.when(this.model.access.fetchIfNeeded({success:function(e) {$('#loading-access').addClass('label-success');}}),
  269. this.model.refresh.fetchIfNeeded({success:function(e) {$('#loading-refresh').addClass('label-success');}}),
  270. this.options.clientList.fetchIfNeeded({success:function(e) {$('#loading-clients').addClass('label-success');}}),
  271. this.options.systemScopeList.fetchIfNeeded({success:function(e) {$('#loading-scopes').addClass('label-success');}}))
  272. .done(function() {
  273. $('#loadingbox').sheet('hide');
  274. callback();
  275. });
  276. },
  277. changePageAccess:function(event, num) {
  278. $('.paginator-access', this.el).bootpag({page: num});
  279. $('#access-token-table tbody tr', this.el).each(function(index, element) {
  280. if (Math.ceil((index + 1) / 10) != num) {
  281. $(element).hide();
  282. } else {
  283. $(element).show();
  284. }
  285. });
  286. },
  287. changePageRefresh:function(event, num) {
  288. $('.paginator-refresh', this.el).bootpag({page: num});
  289. $('#refresh-token-table tbody tr', this.el).each(function(index, element) {
  290. if (Math.ceil((index + 1) / 10) != num) {
  291. $(element).hide();
  292. } else {
  293. $(element).show();
  294. }
  295. });
  296. },
  297. refreshTable:function(e) {
  298. $('#loadingbox').sheet('show');
  299. $('#loading').html(
  300. '<span class="label" id="loading-access">' + $.t('token.token-table.access-tokens') + '</span> ' +
  301. '<span class="label" id="loading-refresh">' + $.t('token.token-table.refresh-tokens') + '</span> ' +
  302. '<span class="label" id="loading-clients">' + $.t('common.clients') + '</span> ' +
  303. '<span class="label" id="loading-scopes">' + $.t('common.scopes') + '</span> '
  304. );
  305. var _self = this;
  306. $.when(this.model.access.fetch({success:function(e) {$('#loading-access').addClass('label-success');}}),
  307. this.model.refresh.fetch({success:function(e) {$('#loading-refresh').addClass('label-success');}}),
  308. this.options.clientList.fetch({success:function(e) {$('#loading-clients').addClass('label-success');}}),
  309. this.options.systemScopeList.fetch({success:function(e) {$('#loading-scopes').addClass('label-success');}}))
  310. .done(function(){
  311. _self.render();
  312. $('#loadingbox').sheet('hide');
  313. });
  314. },
  315. togglePlaceholder:function() {
  316. if (this.model.access.length > 0) {
  317. $('#access-token-table', this.el).show();
  318. $('#access-token-table-empty', this.el).hide();
  319. } else {
  320. $('#access-token-table', this.el).hide();
  321. $('#access-token-table-empty', this.el).show();
  322. }
  323. if (this.model.refresh.length > 0) {
  324. $('#refresh-token-table', this.el).show();
  325. $('#refresh-token-table-empty', this.el).hide();
  326. } else {
  327. $('#refresh-token-table', this.el).hide();
  328. $('#refresh-token-table-empty', this.el).show();
  329. }
  330. $('#access-token-count', this.el).html(this.model.access.length);
  331. $('#refresh-token-count', this.el).html(this.model.refresh.length);
  332. },
  333. render: function (eventName) {
  334. // append and render the table structure
  335. $(this.el).html($('#tmpl-token-table').html());
  336. var _self = this;
  337. // set up pagination
  338. var numPagesAccess = Math.ceil(this.model.access.length / 10);
  339. if (numPagesAccess > 1) {
  340. $('.paginator-access', this.el).show();
  341. $('.paginator-access', this.el).bootpag({
  342. total: numPagesAccess,
  343. page: 1
  344. });
  345. } else {
  346. $('.paginator-access', this.el).hide();
  347. }
  348. // count up refresh tokens
  349. var refreshCount = {};
  350. _.each(this.model.access.models, function (token, index) {
  351. // look up client
  352. var client = _self.options.clientList.getByClientId(token.get('clientId'));
  353. var view = new AccessTokenView({model: token, client: client, systemScopeList: _self.options.systemScopeList});
  354. view.parentView = _self;
  355. var element = view.render().el;
  356. $('#access-token-table', _self.el).append(element);
  357. if (Math.ceil((index + 1) / 10) != 1) {
  358. $(element).hide();
  359. }
  360. //console.log(token.get('refreshTokenId'));
  361. var refId = token.get('refreshTokenId');
  362. if (refId != null) {
  363. if (refreshCount[refId]) {
  364. refreshCount[refId] += 1;
  365. } else {
  366. refreshCount[refId] = 1;
  367. }
  368. }
  369. });
  370. //console.log(refreshCount);
  371. // set up pagination
  372. var numPagesRefresh = Math.ceil(this.model.refresh.length / 10);
  373. if (numPagesRefresh > 1) {
  374. $('.paginator-refresh', this.el).show();
  375. $('.paginator-refresh', this.el).bootpag({
  376. total: numPagesRefresh,
  377. page: 1
  378. });
  379. } else {
  380. $('.paginator-refresh', this.el).hide();
  381. }
  382. _.each(this.model.refresh.models, function (token, index) {
  383. // look up client
  384. var client = _self.options.clientList.getByClientId(token.get('clientId'));
  385. var view = new RefreshTokenView({model: token, client: client, systemScopeList: _self.options.systemScopeList, accessTokenCount: refreshCount[token.get('id')]});
  386. view.parentView = _self;
  387. var element = view.render().el;
  388. $('#refresh-token-table', _self.el).append(element);
  389. if (Math.ceil((index + 1) / 10) != 1) {
  390. $(element).hide();
  391. }
  392. });
  393. /*
  394. _.each(this.model.models, function (scope) {
  395. $("#scope-table", this.el).append(new SystemScopeView({model: scope}).render().el);
  396. }, this);
  397. */
  398. this.togglePlaceholder();
  399. $(this.el).i18n();
  400. return this;
  401. }
  402. });