git-off

git off handles large files in git repos
git clone https://noulin.net/git/git-off.git
Log | Files | Refs | README

cognito_identity_credentials.js (11742B)


      1 var AWS = require('../core');
      2 var CognitoIdentity = require('../../clients/cognitoidentity');
      3 var STS = require('../../clients/sts');
      4 
      5 /**
      6  * Represents credentials retrieved from STS Web Identity Federation using
      7  * the Amazon Cognito Identity service.
      8  *
      9  * By default this provider gets credentials using the
     10  * {AWS.CognitoIdentity.getCredentialsForIdentity} service operation, which
     11  * requires either an `IdentityId` or an `IdentityPoolId` (Amazon Cognito
     12  * Identity Pool ID), which is used to call {AWS.CognitoIdentity.getId} to
     13  * obtain an `IdentityId`. If the identity or identity pool is not configured in
     14  * the Amazon Cognito Console to use IAM roles with the appropriate permissions,
     15  * then additionally a `RoleArn` is required containing the ARN of the IAM trust
     16  * policy for the Amazon Cognito role that the user will log into. If a `RoleArn`
     17  * is provided, then this provider gets credentials using the
     18  * {AWS.STS.assumeRoleWithWebIdentity} service operation, after first getting an
     19  * Open ID token from {AWS.CognitoIdentity.getOpenIdToken}.
     20  *
     21  * In addition, if this credential provider is used to provide authenticated
     22  * login, the `Logins` map may be set to the tokens provided by the respective
     23  * identity providers. See {constructor} for an example on creating a credentials
     24  * object with proper property values.
     25  *
     26  * ## Refreshing Credentials from Identity Service
     27  *
     28  * In addition to AWS credentials expiring after a given amount of time, the
     29  * login token from the identity provider will also expire. Once this token
     30  * expires, it will not be usable to refresh AWS credentials, and another
     31  * token will be needed. The SDK does not manage refreshing of the token value,
     32  * but this can be done through a "refresh token" supported by most identity
     33  * providers. Consult the documentation for the identity provider for refreshing
     34  * tokens. Once the refreshed token is acquired, you should make sure to update
     35  * this new token in the credentials object's {params} property. The following
     36  * code will update the WebIdentityToken, assuming you have retrieved an updated
     37  * token from the identity provider:
     38  *
     39  * ```javascript
     40  * AWS.config.credentials.params.Logins['graph.facebook.com'] = updatedToken;
     41  * ```
     42  *
     43  * Future calls to `credentials.refresh()` will now use the new token.
     44  *
     45  * @!attribute params
     46  *   @return [map] the map of params passed to
     47  *     {AWS.CognitoIdentity.getId},
     48  *     {AWS.CognitoIdentity.getOpenIdToken}, and
     49  *     {AWS.STS.assumeRoleWithWebIdentity}. To update the token, set the
     50  *     `params.WebIdentityToken` property.
     51  * @!attribute data
     52  *   @return [map] the raw data response from the call to
     53  *     {AWS.CognitoIdentity.getCredentialsForIdentity}, or
     54  *     {AWS.STS.assumeRoleWithWebIdentity}. Use this if you want to get
     55  *     access to other properties from the response.
     56  * @!attribute identityId
     57  *   @return [String] the Cognito ID returned by the last call to
     58  *     {AWS.CognitoIdentity.getOpenIdToken}. This ID represents the actual
     59  *     final resolved identity ID from Amazon Cognito.
     60  */
     61 AWS.CognitoIdentityCredentials = AWS.util.inherit(AWS.Credentials, {
     62   /**
     63    * @api private
     64    */
     65   localStorageKey: {
     66     id: 'aws.cognito.identity-id.',
     67     providers: 'aws.cognito.identity-providers.'
     68   },
     69 
     70   /**
     71    * Creates a new credentials object.
     72    * @example Creating a new credentials object
     73    *   AWS.config.credentials = new AWS.CognitoIdentityCredentials({
     74    *
     75    *     // either IdentityPoolId or IdentityId is required
     76    *     // See the IdentityPoolId param for AWS.CognitoIdentity.getID (linked below)
     77    *     // See the IdentityId param for AWS.CognitoIdentity.getCredentialsForIdentity
     78    *     // or AWS.CognitoIdentity.getOpenIdToken (linked below)
     79    *     IdentityPoolId: 'us-east-1:1699ebc0-7900-4099-b910-2df94f52a030',
     80    *     IdentityId: 'us-east-1:128d0a74-c82f-4553-916d-90053e4a8b0f'
     81    *
     82    *     // optional, only necessary when the identity pool is not configured
     83    *     // to use IAM roles in the Amazon Cognito Console
     84    *     // See the RoleArn param for AWS.STS.assumeRoleWithWebIdentity (linked below)
     85    *     RoleArn: 'arn:aws:iam::1234567890:role/MYAPP-CognitoIdentity',
     86    *
     87    *     // optional tokens, used for authenticated login
     88    *     // See the Logins param for AWS.CognitoIdentity.getID (linked below)
     89    *     Logins: {
     90    *       'graph.facebook.com': 'FBTOKEN',
     91    *       'www.amazon.com': 'AMAZONTOKEN',
     92    *       'accounts.google.com': 'GOOGLETOKEN',
     93    *       'api.twitter.com': 'TWITTERTOKEN',
     94    *       'www.digits.com': 'DIGITSTOKEN'
     95    *     },
     96    *
     97    *     // optional name, defaults to web-identity
     98    *     // See the RoleSessionName param for AWS.STS.assumeRoleWithWebIdentity (linked below)
     99    *     RoleSessionName: 'web',
    100    *
    101    *     // optional, only necessary when application runs in a browser
    102    *     // and multiple users are signed in at once, used for caching
    103    *     LoginId: 'example@gmail.com'
    104    *
    105    *   });
    106    * @see AWS.CognitoIdentity.getId
    107    * @see AWS.CognitoIdentity.getCredentialsForIdentity
    108    * @see AWS.STS.assumeRoleWithWebIdentity
    109    * @see AWS.CognitoIdentity.getOpenIdToken
    110    */
    111   constructor: function CognitoIdentityCredentials(params) {
    112     AWS.Credentials.call(this);
    113     this.expired = true;
    114     this.params = params;
    115     this.data = null;
    116     this.identityId = null;
    117     this.loadCachedId();
    118   },
    119 
    120   /**
    121    * Refreshes credentials using {AWS.CognitoIdentity.getCredentialsForIdentity},
    122    * or {AWS.STS.assumeRoleWithWebIdentity}.
    123    *
    124    * @callback callback function(err)
    125    *   Called when the STS service responds (or fails). When
    126    *   this callback is called with no error, it means that the credentials
    127    *   information has been loaded into the object (as the `accessKeyId`,
    128    *   `secretAccessKey`, and `sessionToken` properties).
    129    *   @param err [Error] if an error occurred, this value will be filled
    130    * @see get
    131    */
    132   refresh: function refresh(callback) {
    133     var self = this;
    134     self.createClients();
    135     self.data = null;
    136     self.identityId = null;
    137     self.getId(function(err) {
    138       if (!err) {
    139         if (!self.params.RoleArn) {
    140           self.getCredentialsForIdentity(callback);
    141         } else {
    142           self.getCredentialsFromSTS(callback);
    143         }
    144       } else {
    145         self.clearIdOnNotAuthorized(err);
    146         callback(err);
    147       }
    148     });
    149   },
    150 
    151   /**
    152    * Clears the cached Cognito ID associated with the currently configured
    153    * identity pool ID. Use this to manually invalidate your cache if
    154    * the identity pool ID was deleted.
    155    */
    156   clearCachedId: function clearCache() {
    157     this.identityId = null;
    158     delete this.params.IdentityId;
    159 
    160     var poolId = this.params.IdentityPoolId;
    161     var loginId = this.params.LoginId || '';
    162     delete this.storage[this.localStorageKey.id + poolId + loginId];
    163     delete this.storage[this.localStorageKey.providers + poolId + loginId];
    164   },
    165 
    166   /**
    167    * @api private
    168    */
    169   clearIdOnNotAuthorized: function clearIdOnNotAuthorized(err) {
    170     var self = this;
    171     if (err.code == 'NotAuthorizedException') {
    172       self.clearCachedId();
    173     }
    174   },
    175 
    176   /**
    177    * Retrieves a Cognito ID, loading from cache if it was already retrieved
    178    * on this device.
    179    *
    180    * @callback callback function(err, identityId)
    181    *   @param err [Error, null] an error object if the call failed or null if
    182    *     it succeeded.
    183    *   @param identityId [String, null] if successful, the callback will return
    184    *     the Cognito ID.
    185    * @note If not loaded explicitly, the Cognito ID is loaded and stored in
    186    *   localStorage in the browser environment of a device.
    187    * @api private
    188    */
    189   getId: function getId(callback) {
    190     var self = this;
    191     if (typeof self.params.IdentityId === 'string') {
    192       return callback(null, self.params.IdentityId);
    193     }
    194 
    195     self.cognito.getId(function(err, data) {
    196       if (!err && data.IdentityId) {
    197         self.params.IdentityId = data.IdentityId;
    198         callback(null, data.IdentityId);
    199       } else {
    200         callback(err);
    201       }
    202     });
    203   },
    204 
    205 
    206   /**
    207    * @api private
    208    */
    209   loadCredentials: function loadCredentials(data, credentials) {
    210     if (!data || !credentials) return;
    211     credentials.expired = false;
    212     credentials.accessKeyId = data.Credentials.AccessKeyId;
    213     credentials.secretAccessKey = data.Credentials.SecretKey;
    214     credentials.sessionToken = data.Credentials.SessionToken;
    215     credentials.expireTime = data.Credentials.Expiration;
    216   },
    217 
    218   /**
    219    * @api private
    220    */
    221   getCredentialsForIdentity: function getCredentialsForIdentity(callback) {
    222     var self = this;
    223     self.cognito.getCredentialsForIdentity(function(err, data) {
    224       if (!err) {
    225         self.cacheId(data);
    226         self.data = data;
    227         self.loadCredentials(self.data, self);
    228       } else {
    229         self.clearIdOnNotAuthorized(err);
    230       }
    231       callback(err);
    232     });
    233   },
    234 
    235   /**
    236    * @api private
    237    */
    238   getCredentialsFromSTS: function getCredentialsFromSTS(callback) {
    239     var self = this;
    240     self.cognito.getOpenIdToken(function(err, data) {
    241       if (!err) {
    242         self.cacheId(data);
    243         self.params.WebIdentityToken = data.Token;
    244         self.webIdentityCredentials.refresh(function(webErr) {
    245           if (!webErr) {
    246             self.data = self.webIdentityCredentials.data;
    247             self.sts.credentialsFrom(self.data, self);
    248           }
    249           callback(webErr);
    250         });
    251       } else {
    252         self.clearIdOnNotAuthorized(err);
    253         callback(err);
    254       }
    255     });
    256   },
    257 
    258   /**
    259    * @api private
    260    */
    261   loadCachedId: function loadCachedId() {
    262     var self = this;
    263 
    264     // in the browser we source default IdentityId from localStorage
    265     if (AWS.util.isBrowser() && !self.params.IdentityId) {
    266       var id = self.getStorage('id');
    267       if (id && self.params.Logins) {
    268         var actualProviders = Object.keys(self.params.Logins);
    269         var cachedProviders =
    270           (self.getStorage('providers') || '').split(',');
    271 
    272         // only load ID if at least one provider used this ID before
    273         var intersect = cachedProviders.filter(function(n) {
    274           return actualProviders.indexOf(n) !== -1;
    275         });
    276         if (intersect.length !== 0) {
    277           self.params.IdentityId = id;
    278         }
    279       } else if (id) {
    280         self.params.IdentityId = id;
    281       }
    282     }
    283   },
    284 
    285   /**
    286    * @api private
    287    */
    288   createClients: function() {
    289     this.webIdentityCredentials = this.webIdentityCredentials ||
    290       new AWS.WebIdentityCredentials(this.params);
    291     this.cognito = this.cognito ||
    292       new CognitoIdentity({params: this.params});
    293     this.sts = this.sts || new STS();
    294   },
    295 
    296   /**
    297    * @api private
    298    */
    299   cacheId: function cacheId(data) {
    300     this.identityId = data.IdentityId;
    301     this.params.IdentityId = this.identityId;
    302 
    303     // cache this IdentityId in browser localStorage if possible
    304     if (AWS.util.isBrowser()) {
    305       this.setStorage('id', data.IdentityId);
    306 
    307       if (this.params.Logins) {
    308         this.setStorage('providers', Object.keys(this.params.Logins).join(','));
    309       }
    310     }
    311   },
    312 
    313   /**
    314    * @api private
    315    */
    316   getStorage: function getStorage(key) {
    317     return this.storage[this.localStorageKey[key] + this.params.IdentityPoolId + (this.params.LoginId || '')];
    318   },
    319 
    320   /**
    321    * @api private
    322    */
    323   setStorage: function setStorage(key, val) {
    324     try {
    325       this.storage[this.localStorageKey[key] + this.params.IdentityPoolId + (this.params.LoginId || '')] = val;
    326     } catch (_) {}
    327   },
    328 
    329   /**
    330    * @api private
    331    */
    332   storage: (function() {
    333     try {
    334       return AWS.util.isBrowser() && window.localStorage !== null && typeof window.localStorage === 'object' ?
    335              window.localStorage : {};
    336     } catch (_) {
    337       return {};
    338     }
    339   })()
    340 });