Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates CognitoIdentityCredentials to accept AWS.config options #1317

Merged
merged 2 commits into from
Jan 20, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "feature",
"category": "CognitoIdentityCredentials",
"description": "Adds `clientConfig` as an optional parameter to the `CognitoIdentityCredentials` constructor. This parameter can be used to pass in client configuration to the underlying `CognitoIdentity` service client."
}
62 changes: 37 additions & 25 deletions lib/credentials/cognito_identity_credentials.d.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
import {Credentials} from '../credentials';
import {AWSError} from '../error';
import {ConfigurationOptions} from '../config';
import CognitoIdentity = require('../../clients/cognitoidentity');
import STS = require('../../clients/sts');

export class CognitoIdentityCredentials extends Credentials {
/**
* Creates a new credentials object.
*/
constructor(options?: CognitoIdentity.Types.GetIdInput|CognitoIdentity.Types.GetCredentialsForIdentityInput|CognitoIdentity.Types.GetOpenIdTokenInput|STS.Types.AssumeRoleWithWebIdentityRequest);
/**
* Refreshes credentials using AWS.CognitoIdentity.getCredentialsForIdentity(), or AWS.STS.assumeRoleWithWebIdentity().
*/
refresh(callback: (err: AWSError) => void): void;
/**
* Clears the cached Cognito ID associated with the currently configured identity pool ID.
*/
clearCachedId(): void;
/**
* The raw data response from the call to AWS.CognitoIdentity.getCredentialsForIdentity(), or AWS.STS.assumeRoleWithWebIdentity().
*/
data: CognitoIdentity.Types.GetCredentialsForIdentityResponse|STS.Types.AssumeRoleWithWebIdentityResponse;
/**
* The Cognito ID returned by the last call to AWS.CognitoIdentity.getOpenIdToken().
*/
identityId: string;
/**
* The map of params passed to AWS.CognitoIdentity.getId(), AWS.CognitoIdentity.getOpenIdToken(), and AWS.STS.assumeRoleWithWebIdentity().
*/
params: CognitoIdentity.Types.GetIdInput|CognitoIdentity.Types.GetOpenIdTokenInput|STS.Types.AssumeRoleWithWebIdentityRequest;
}
/**
* Creates a new credentials object with optional configuration.
*/
constructor(options: CognitoIdentityCredentials.CognitoIdentityOptions, clientConfig?: ConfigurationOptions);
/**
* Creates a new credentials object.
*/
constructor(options?: CognitoIdentityCredentials.CognitoIdentityOptions);
/**
* Refreshes credentials using AWS.CognitoIdentity.getCredentialsForIdentity(), or AWS.STS.assumeRoleWithWebIdentity().
*/
refresh(callback: (err: AWSError) => void): void;
/**
* Clears the cached Cognito ID associated with the currently configured identity pool ID.
*/
clearCachedId(): void;
/**
* The raw data response from the call to AWS.CognitoIdentity.getCredentialsForIdentity(), or AWS.STS.assumeRoleWithWebIdentity().
*/
data: CognitoIdentity.Types.GetCredentialsForIdentityResponse|STS.Types.AssumeRoleWithWebIdentityResponse;
/**
* The Cognito ID returned by the last call to AWS.CognitoIdentity.getOpenIdToken().
*/
identityId: string;
/**
* The map of params passed to AWS.CognitoIdentity.getId(), AWS.CognitoIdentity.getOpenIdToken(), and AWS.STS.assumeRoleWithWebIdentity().
*/
params: CognitoIdentity.Types.GetIdInput|CognitoIdentity.Types.GetOpenIdTokenInput|STS.Types.AssumeRoleWithWebIdentityRequest;
}

// Needed to expose interfaces on the class
declare namespace CognitoIdentityCredentials {
export type CognitoIdentityCredentialsInputs = CognitoIdentity.GetIdInput|CognitoIdentity.GetCredentialsForIdentityInput|CognitoIdentity.GetOpenIdTokenInput|STS.AssumeRoleWithWebIdentityRequest;
export type CognitoIdentityOptions = CognitoIdentityCredentialsInputs & {LoginId?: string}
}
27 changes: 24 additions & 3 deletions lib/credentials/cognito_identity_credentials.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,35 @@ AWS.CognitoIdentityCredentials = AWS.util.inherit(AWS.Credentials, {
* // and multiple users are signed in at once, used for caching
* LoginId: 'example@gmail.com'
*
* }, {
* // optionally provide configuration to apply to the underlying AWS.CognitoIdentity service client
* // if configuration is not provided, then configuration will be pulled from AWS.config
*
* // region should match the region your identity pool is located in
* region: 'us-east-1',
*
* // specify timeout options
* httpOptions: {
* timeout: 100
* }
* });
* @see AWS.CognitoIdentity.getId
* @see AWS.CognitoIdentity.getCredentialsForIdentity
* @see AWS.STS.assumeRoleWithWebIdentity
* @see AWS.CognitoIdentity.getOpenIdToken
* @see AWS.Config
* @note If a region is not provided in the global AWS.config, or
* specified in the `clientConfig` to the CognitoIdentityCredentials
* constructor, you may encounter a 'Missing credentials in config' error
* when calling making a service call.
*/
constructor: function CognitoIdentityCredentials(params) {
constructor: function CognitoIdentityCredentials(params, clientConfig) {
AWS.Credentials.call(this);
this.expired = true;
this.params = params;
this.data = null;
this._identityId = null;
this._clientConfig = AWS.util.copy(clientConfig || {});
this.loadCachedId();
var self = this;
Object.defineProperty(this, 'identityId', {
Expand Down Expand Up @@ -296,10 +313,14 @@ AWS.CognitoIdentityCredentials = AWS.util.inherit(AWS.Credentials, {
* @api private
*/
createClients: function() {
var clientConfig = this._clientConfig;
this.webIdentityCredentials = this.webIdentityCredentials ||
new AWS.WebIdentityCredentials(this.params);
this.cognito = this.cognito ||
new CognitoIdentity({params: this.params});
if (!this.cognito) {
var cognitoConfig = AWS.util.merge({}, clientConfig);
cognitoConfig.params = this.params;
this.cognito = new CognitoIdentity(cognitoConfig);
}
this.sts = this.sts || new STS();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the client config be passed to STS, too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went back and forth on that. Since STS uses a global endpoint, it's fine if the region the user passes in isn't us-east-1.

I would probably also have to update WebIdentityCredentials to accept client config, since it calls STS as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are other configuration options that customers might want to control (e.g., timeouts, retries, http agents, etc.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Sorry, I wasn't clear in my response. I was initially worried that a different region would cause an issue with STS, but discovered that's not the case. I'll update the PR to pass config to STS (and likewise to WebIdentityCredentials as well).

},

Expand Down
11 changes: 11 additions & 0 deletions test/credentials.spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,17 @@ describe 'AWS.CognitoIdentityCredentials', ->
expect(creds.sts).to.eql(sts)
expect(creds.webIdentityCredentials).to.eql(webIdentityCredentials)

it 'uses global config for cognito client if client congif ommitted', ->
creds.createClients();
expect(creds.cognito.config.region).to.equal(AWS.config.region);
expect(creds.cognito.config.httpOptions.timeout).to.equal(AWS.config.httpOptions.timeout);

it 'passes clientConfig to cognito client', ->
creds = new AWS.CognitoIdentityCredentials(initParams, {region: 'us-west-2', httpOptions: {timeout: 50}})
creds.createClients();
expect(creds.cognito.config.region).to.equal('us-west-2');
expect(creds.cognito.config.httpOptions.timeout).to.equal(50);

describe 'refresh', ->
beforeEach -> setupClients()

Expand Down
36 changes: 36 additions & 0 deletions ts/cognitoidentitycredentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {CognitoIdentityCredentials} from '../lib/credentials/cognito_identity_credentials';

const creds1 = new CognitoIdentityCredentials();
const creds2 = new CognitoIdentityCredentials({
IdentityPoolId: 'fake'
});
const creds3: CognitoIdentityCredentials = new CognitoIdentityCredentials({
IdentityId: 'id'
});

const creds4: CognitoIdentityCredentials = new CognitoIdentityCredentials({
IdentityId: 'id',
RoleArn: 'arn'
});

const credOptions: CognitoIdentityCredentials.CognitoIdentityOptions = {
IdentityId: 'id',
Logins: {
'graph.facebook.com': 'FBTOKEN',
'www.amazon.com': 'AMAZONTOKEN',
'accounts.google.com': 'GOOGLETOKEN',
'api.twitter.com': 'TWITTERTOKEN',
'www.digits.com': 'DIGITSTOKEN'
},
LoginId: 'example@gmail.com'
}

const creds5: CognitoIdentityCredentials = new CognitoIdentityCredentials(credOptions);

// test client config
const creds6: CognitoIdentityCredentials = new CognitoIdentityCredentials(credOptions, {
httpOptions: {
timeout: 50
},
region: 'us-west-2'
});