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

fix(@aws-amplify/core): Use identityPoolRegion param correctly #10709

Merged
merged 7 commits into from Dec 2, 2022
7 changes: 7 additions & 0 deletions .circleci/config.yml
Expand Up @@ -443,6 +443,13 @@ jobs:
working_directory: ~/amplify-js-samples-staging/samples
steps:
- prepare_test_env
- integ_test_js:
test_name: 'React Credentials Different Region'
framework: react
category: auth
sample_name: credentials-auth
spec: credentials-auth
browser: << parameters.browser >>
- integ_test_js:
test_name: 'React Custom Authenticator'
framework: react
Expand Down
26 changes: 26 additions & 0 deletions packages/auth/__tests__/auth-configure-test.ts
@@ -1,4 +1,5 @@
import { AuthClass as Auth } from '../src/Auth';
import { Credentials } from '@aws-amplify/core';

describe('configure test', () => {
test('throw error when storage is empty', () => {
Expand All @@ -18,4 +19,29 @@ describe('configure test', () => {
expect(e).not.toBeNull();
}
});

test('configure Credentials correctly when using different region', () => {
const opts = {
userPoolId: 'us-east-1_awdasd',
userPoolWebClientId: 'awsUserPoolsWebClientId',
region: 'us-east-1',
identityPoolId: 'awsCognitoIdentityPoolId',
identityPoolRegion: 'us-east-2',
};

const spyOn = jest.spyOn(Credentials, 'configure');

const auth = new Auth(null);
expect.assertions(1);

auth.configure(opts);
expect(spyOn).toBeCalledWith(
expect.objectContaining({
region: 'us-east-1',
identityPoolRegion: 'us-east-2',
identityPoolId: 'awsCognitoIdentityPoolId',
userPoolId: 'us-east-1_awdasd',
})
);
});
});
3 changes: 2 additions & 1 deletion packages/auth/src/Auth.ts
Expand Up @@ -196,11 +196,12 @@ export class AuthClass {

this.Credentials.configure({
mandatorySignIn,
region: identityPoolRegion || region,
region,
userPoolId,
identityPoolId,
refreshHandlers,
storage: this._storage,
identityPoolRegion
});

// initialize cognitoauth client if hosted ui options provided
Expand Down
135 changes: 135 additions & 0 deletions packages/core/__tests__/Credentials-test.ts
@@ -1,6 +1,14 @@
import { CredentialsClass as Credentials } from '../src/Credentials';
import { Amplify } from '../src/Amplify';
import { Hub } from '../src/Hub';
import {
CognitoIdentityClient,
GetCredentialsForIdentityCommand,
GetIdCommand,
} from '@aws-sdk/client-cognito-identity';
jest.mock('@aws-sdk/client-cognito-identity');
import { fromCognitoIdentity } from '@aws-sdk/credential-provider-cognito-identity';
jest.mock('@aws-sdk/credential-provider-cognito-identity');
const session = {};

const user = {
Expand Down Expand Up @@ -93,6 +101,133 @@ describe('Credentials test', () => {
});
});

describe('different regions', () => {
const userPoolId = 'us-west-2:aaaaaaaaa';
const identityPoolId = 'us-east-1:bbbbbbbb';
const identityPoolRegion = 'us-east-1';
const region = 'us-west-2';

beforeAll(() => {
CognitoIdentityClient.mockImplementation(params => {
return {
send: params => {
if (params instanceof GetIdCommand) {
return { IdentityId: '123' };
}
if (params instanceof GetCredentialsForIdentityCommand) {
return {
Credentials: {
AccessKeyId: 'accessKey',
Expiration: 0,
SecretKey: 'secretKey',
SessionToken: 'sessionToken',
},
IdentityId: '123',
};
}
},
};
});

fromCognitoIdentity.mockImplementation(params => {
return async () => {
return {};
};
});
});

test('should use identityPoolRegion param for credentials for federation', async () => {
expect.assertions(2);

const credentials = new Credentials(null);

credentials.configure({
userPoolId,
identityPoolId,
identityPoolRegion,
region,
});

await credentials._setCredentialsFromFederation({
provider: 'google',
token: 'token',
identity_id: '123',
});

expect(CognitoIdentityClient).toHaveBeenCalledWith(
expect.objectContaining({ region: identityPoolRegion })
);

expect(fromCognitoIdentity).toBeCalledWith(
expect.objectContaining({
identityId: '123',
logins: {
'accounts.google.com': 'token',
},
})
);
});

test('should use identityPoolRegion param for credentials from session', async () => {
expect.assertions(2);

const credentials = new Credentials(null);

credentials.configure({
userPoolId,
identityPoolId,
identityPoolRegion,
region,
});

const session = {
getIdToken: () => {
return {
getJwtToken: () => {
return 'token';
},
};
},
};

await credentials._setCredentialsFromSession(session);

expect(CognitoIdentityClient).toHaveBeenCalledWith(
expect.objectContaining({ region: identityPoolRegion })
);

expect(GetIdCommand).toBeCalledWith({
IdentityPoolId: identityPoolId,
Logins: {
[`cognito-idp.${region}.amazonaws.com/${userPoolId}`]: 'token',
},
});
});

test('should use identityPoolRegion param for credentials for guest', async () => {
expect.assertions(2);

const credentials = new Credentials(null);

credentials.configure({
userPoolId,
identityPoolId,
identityPoolRegion,
region,
});

await credentials._setCredentialsForGuest();

expect(CognitoIdentityClient).toHaveBeenCalledWith(
expect.objectContaining({ region: identityPoolRegion })
);

expect(GetIdCommand).toBeCalledWith({
IdentityPoolId: identityPoolId,
});
});
});

describe('getCredSource test', () => {
test('happy case', () => {
const credentials = new Credentials(null);
Expand Down
18 changes: 9 additions & 9 deletions packages/core/src/Credentials.ts
Expand Up @@ -265,7 +265,7 @@ export class CredentialsClass {
parseAWSExports(this._config || {}).Auth
);
}
const { identityPoolId, region, mandatorySignIn } = this._config;
const { identityPoolId, region, mandatorySignIn, identityPoolRegion } = this._config;

if (mandatorySignIn) {
return Promise.reject(
Expand All @@ -282,7 +282,7 @@ export class CredentialsClass {
);
}

if (!region) {
if (!identityPoolRegion && !region) {
logger.debug('region is not configured for getting the credentials');
return Promise.reject(
'region is not configured for getting the credentials'
Expand All @@ -292,7 +292,7 @@ export class CredentialsClass {
const identityId = (this._identityId = await this._getGuestIdentityId());

const cognitoClient = new CognitoIdentityClient({
region,
region: identityPoolRegion || region,
customUserAgent: getAmplifyUserAgent(),
});

Expand Down Expand Up @@ -396,20 +396,20 @@ export class CredentialsClass {
const logins = {};
logins[domain] = token;

const { identityPoolId, region } = this._config;
const { identityPoolId, region, identityPoolRegion } = this._config;
if (!identityPoolId) {
logger.debug('No Cognito Federated Identity pool provided');
return Promise.reject('No Cognito Federated Identity pool provided');
}
if (!region) {
if (!identityPoolRegion && !region) {
logger.debug('region is not configured for getting the credentials');
return Promise.reject(
'region is not configured for getting the credentials'
);
}

const cognitoClient = new CognitoIdentityClient({
region,
region: identityPoolRegion || region,
customUserAgent: getAmplifyUserAgent(),
});

Expand All @@ -435,12 +435,12 @@ export class CredentialsClass {
private _setCredentialsFromSession(session): Promise<ICredentials> {
logger.debug('set credentials from session');
const idToken = session.getIdToken().getJwtToken();
const { region, userPoolId, identityPoolId } = this._config;
const { region, userPoolId, identityPoolId, identityPoolRegion } = this._config;
if (!identityPoolId) {
logger.debug('No Cognito Federated Identity pool provided');
return Promise.reject('No Cognito Federated Identity pool provided');
}
if (!region) {
if (!identityPoolRegion && !region) {
logger.debug('region is not configured for getting the credentials');
return Promise.reject(
'region is not configured for getting the credentials'
Expand All @@ -451,7 +451,7 @@ export class CredentialsClass {
logins[key] = idToken;

const cognitoClient = new CognitoIdentityClient({
region,
region: identityPoolRegion || region,
customUserAgent: getAmplifyUserAgent(),
});

Expand Down