Home | History | Annotate | Download | only in resources
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 cr.define('identity_internals', function() {
      6   'use strict';
      7 
      8   /**
      9    * Creates an identity token item.
     10    * @param {!Object} tokenInfo Object containing token information.
     11    * @constructor
     12    */
     13   function TokenListItem(tokenInfo) {
     14     var el = cr.doc.createElement('div');
     15     el.data_ = tokenInfo;
     16     el.__proto__ = TokenListItem.prototype;
     17     el.decorate();
     18     return el;
     19   }
     20 
     21   TokenListItem.prototype = {
     22     __proto__: HTMLDivElement.prototype,
     23 
     24     /** @override */
     25     decorate: function() {
     26       this.textContent = '';
     27       this.id = this.data_.accessToken;
     28 
     29       var table = this.ownerDocument.createElement('table');
     30       var tbody = this.ownerDocument.createElement('tbody');
     31       tbody.appendChild(this.createEntry_(
     32           'accessToken', this.data_.accessToken, 'access-token'));
     33       tbody.appendChild(this.createEntry_(
     34           'extensionName', this.data_.extensionName, 'extension-name'));
     35       tbody.appendChild(this.createEntry_(
     36           'extensionId', this.data_.extensionId, 'extension-id'));
     37       tbody.appendChild(this.createEntry_(
     38           'tokenStatus', this.data_.status, 'token-status'));
     39       tbody.appendChild(this.createEntry_(
     40           'expirationTime', this.data_.expirationTime, 'expiration-time'));
     41       tbody.appendChild(this.createEntryForScopes_());
     42       table.appendChild(tbody);
     43       var tfoot = this.ownerDocument.createElement('tfoot');
     44       tfoot.appendChild(this.createButtons_());
     45       table.appendChild(tfoot);
     46       this.appendChild(table);
     47     },
     48 
     49     /**
     50      * Creates an entry for a single property of the token.
     51      * @param {string} label An i18n label of the token's property name.
     52      * @param {string} value A value of the token property.
     53      * @param {string} accessor Additional class to tag the field for testing.
     54      * @return {HTMLElement} An HTML element with the property name and value.
     55      */
     56     createEntry_: function(label, value, accessor) {
     57       var row = this.ownerDocument.createElement('tr');
     58       var labelField = this.ownerDocument.createElement('td');
     59       labelField.classList.add('label');
     60       labelField.textContent = loadTimeData.getString(label);
     61       row.appendChild(labelField);
     62       var valueField = this.ownerDocument.createElement('td');
     63       valueField.classList.add('value');
     64       valueField.classList.add(accessor);
     65       valueField.textContent = value;
     66       row.appendChild(valueField);
     67       return row;
     68     },
     69 
     70     /**
     71      * Creates an entry for a list of token scopes.
     72      * @return {!HTMLElement} An HTML element with scopes.
     73      */
     74     createEntryForScopes_: function() {
     75       var row = this.ownerDocument.createElement('tr');
     76       var labelField = this.ownerDocument.createElement('td');
     77       labelField.classList.add('label');
     78       labelField.textContent = loadTimeData.getString('scopes');
     79       row.appendChild(labelField);
     80       var valueField = this.ownerDocument.createElement('td');
     81       valueField.classList.add('value');
     82       valueField.classList.add('scope-list');
     83       this.data_.scopes.forEach(function(scope) {
     84         valueField.appendChild(this.ownerDocument.createTextNode(scope));
     85         valueField.appendChild(this.ownerDocument.createElement('br'));
     86       }, this);
     87       row.appendChild(valueField);
     88       return row;
     89     },
     90 
     91     /**
     92      * Creates buttons for the token.
     93      * @return {HTMLElement} An HTML element with actionable buttons for the
     94      *     token.
     95      */
     96     createButtons_: function() {
     97       var row = this.ownerDocument.createElement('tr');
     98       var buttonHolder = this.ownerDocument.createElement('td');
     99       buttonHolder.colSpan = 2;
    100       buttonHolder.classList.add('token-actions');
    101       buttonHolder.appendChild(this.createRevokeButton_());
    102       row.appendChild(buttonHolder);
    103       return row;
    104     },
    105 
    106     /**
    107      * Creates a revoke button with an event sending a revoke token message
    108      * to the controller.
    109      * @return {!HTMLButtonElement} The created revoke button.
    110      * @private
    111      */
    112     createRevokeButton_: function() {
    113       var revokeButton = this.ownerDocument.createElement('button');
    114       revokeButton.classList.add('revoke-button');
    115       revokeButton.addEventListener('click', function() {
    116         chrome.send('identityInternalsRevokeToken',
    117                     [this.data_.extensionId, this.data_.accessToken]);
    118       }.bind(this));
    119       revokeButton.textContent = loadTimeData.getString('revoke');
    120       return revokeButton;
    121     },
    122   };
    123 
    124   /**
    125    * Creates a new list of identity tokens.
    126    * @param {Object=} opt_propertyBag Optional properties.
    127    * @constructor
    128    * @extends {cr.ui.div}
    129    */
    130   var TokenList = cr.ui.define('div');
    131 
    132   TokenList.prototype = {
    133     __proto__: HTMLDivElement.prototype,
    134 
    135     /** @override */
    136     decorate: function() {
    137       this.textContent = '';
    138       this.showTokenNodes_();
    139     },
    140 
    141     /**
    142      * Populates the list of tokens.
    143      */
    144     showTokenNodes_: function() {
    145       this.data_.forEach(function(tokenInfo) {
    146         this.appendChild(new TokenListItem(tokenInfo));
    147       }, this);
    148     },
    149 
    150     /**
    151      * Removes a token node related to the specifed token ID from both the
    152      * internals data source as well as the user internface.
    153      * @param {string} accessToken The id of the token to remove.
    154      * @private
    155      */
    156     removeTokenNode_: function(accessToken) {
    157       var tokenIndex;
    158       for (var index = 0; index < this.data_.length; index++) {
    159         if (this.data_[index].accessToken == accessToken) {
    160           tokenIndex = index;
    161           break;
    162         }
    163       }
    164 
    165       // Remove from the data_ source if token found.
    166       if (tokenIndex)
    167         this.data_.splice(tokenIndex, 1);
    168 
    169       // Remove from the user interface.
    170       var tokenNode = $(accessToken);
    171       if (tokenNode)
    172         this.removeChild(tokenNode);
    173     },
    174   };
    175 
    176   var tokenList_;
    177 
    178   /**
    179    * Initializes the UI by asking the contoller for list of identity tokens.
    180    */
    181   function initialize() {
    182     chrome.send('identityInternalsGetTokens');
    183     tokenList_ = $('token-list');
    184     tokenList_.data_ = [];
    185     tokenList_.__proto__ = TokenList.prototype;
    186     tokenList_.decorate();
    187   }
    188 
    189   /**
    190    * Callback function accepting a list of tokens to be displayed.
    191    * @param {!Token[]} tokens A list of tokens to be displayed
    192    */
    193   function returnTokens(tokens) {
    194     tokenList_.data_ = tokens;
    195     tokenList_.showTokenNodes_();
    196   }
    197 
    198   /**
    199    * Callback function that removes a token from UI once it has been revoked.
    200    * @param {!Array.<string>} accessTokens Array with a single element, which is
    201    * an access token to be removed.
    202    */
    203   function tokenRevokeDone(accessTokens) {
    204     assert(accessTokens.length > 0);
    205     tokenList_.removeTokenNode_(accessTokens[0]);
    206   }
    207 
    208   // Return an object with all of the exports.
    209   return {
    210     initialize: initialize,
    211     returnTokens: returnTokens,
    212     tokenRevokeDone: tokenRevokeDone,
    213   };
    214 });
    215 
    216 document.addEventListener('DOMContentLoaded', identity_internals.initialize);
    217