Skip to content

Commit d7ada2b

Browse files
authored
fix(auth): update service returned identity id to the in-memory store (#14268)
1 parent 1cd12bf commit d7ada2b

File tree

3 files changed

+48
-17
lines changed

3 files changed

+48
-17
lines changed

packages/auth/__tests__/providers/cognito/credentialsProvider/credentialsProvider.test.ts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,20 @@ describe('Guest Credentials', () => {
6969

7070
describe('Happy Path Cases:', () => {
7171
beforeEach(() => {
72+
const identityIdStore = new DefaultIdentityIdStore(sharedInMemoryStorage);
73+
identityIdStore.setAuthConfig(validAuthConfig.Auth!);
7274
cognitoCredentialsProvider =
73-
new CognitoAWSCredentialsAndIdentityIdProvider(
74-
new DefaultIdentityIdStore(sharedInMemoryStorage),
75-
);
75+
new CognitoAWSCredentialsAndIdentityIdProvider(identityIdStore);
7676
credentialsForIdentityIdSpy.mockImplementationOnce(async () => {
7777
return authAPITestParams.CredentialsForIdentityIdResult as GetCredentialsForIdentityOutput;
7878
});
7979
});
80+
8081
afterEach(() => {
8182
cognitoCredentialsProvider.clearCredentials();
8283
credentialsForIdentityIdSpy?.mockReset();
8384
});
85+
8486
test('Should call identityIdClient with no logins to obtain guest creds', async () => {
8587
const res = await cognitoCredentialsProvider.getCredentialsAndIdentityId({
8688
authenticated: false,
@@ -137,6 +139,7 @@ describe('Guest Credentials', () => {
137139
afterAll(() => {
138140
credentialsForIdentityIdSpy?.mockReset();
139141
});
142+
140143
test('Should not throw AuthError when allowGuestAccess is false in the config', async () => {
141144
expect(
142145
await cognitoCredentialsProvider.getCredentialsAndIdentityId({
@@ -145,6 +148,7 @@ describe('Guest Credentials', () => {
145148
}),
146149
).toBe(undefined);
147150
});
151+
148152
test('Should not throw AuthError when there is no Cognito object in the config', async () => {
149153
expect(
150154
await cognitoCredentialsProvider.getCredentialsAndIdentityId({
@@ -160,31 +164,47 @@ describe('Primary Credentials', () => {
160164
let cognitoCredentialsProvider: CognitoAWSCredentialsAndIdentityIdProvider;
161165
describe('Happy Path Cases:', () => {
162166
beforeEach(() => {
167+
const identityIdStore = new DefaultIdentityIdStore(sharedInMemoryStorage);
168+
identityIdStore.setAuthConfig(validAuthConfig.Auth!);
163169
cognitoCredentialsProvider =
164-
new CognitoAWSCredentialsAndIdentityIdProvider(
165-
new DefaultIdentityIdStore(sharedInMemoryStorage),
166-
);
170+
new CognitoAWSCredentialsAndIdentityIdProvider(identityIdStore);
167171
credentialsForIdentityIdSpy.mockImplementation(async () => {
168172
return authAPITestParams.CredentialsForIdentityIdResult as GetCredentialsForIdentityOutput;
169173
});
170174
});
175+
171176
afterEach(() => {
172177
cognitoCredentialsProvider.clearCredentials();
173178
credentialsForIdentityIdSpy?.mockReset();
174179
});
180+
175181
test('Should call identityIdClient with the logins map to obtain primary creds', async () => {
176182
const res = await cognitoCredentialsProvider.getCredentialsAndIdentityId({
177183
authenticated: true,
178184
authConfig: validAuthConfig.Auth!,
179185
tokens: authAPITestParams.ValidAuthTokens,
180186
});
181-
expect(res?.credentials.accessKeyId).toEqual(
182-
authAPITestParams.CredentialsForIdentityIdResult.Credentials
183-
.AccessKeyId,
184-
);
187+
expect(res).toMatchObject({
188+
credentials: {
189+
accessKeyId:
190+
authAPITestParams.CredentialsForIdentityIdResult.Credentials
191+
.AccessKeyId,
192+
expiration:
193+
authAPITestParams.CredentialsForIdentityIdResult.Credentials
194+
.Expiration,
195+
secretAccessKey:
196+
authAPITestParams.CredentialsForIdentityIdResult.Credentials
197+
.SecretKey,
198+
sessionToken:
199+
authAPITestParams.CredentialsForIdentityIdResult.Credentials
200+
.SessionToken,
201+
},
202+
identityId: authAPITestParams.CredentialsForIdentityIdResult.IdentityId,
203+
});
185204

186205
expect(credentialsForIdentityIdSpy).toHaveBeenCalledTimes(1);
187206
});
207+
188208
test('in-memory primary creds are returned if not expired and not past TTL', async () => {
189209
await cognitoCredentialsProvider.getCredentialsAndIdentityId({
190210
authenticated: true,
@@ -211,6 +231,7 @@ describe('Primary Credentials', () => {
211231
// expecting to be called only once becasue in-memory creds should be returned
212232
expect(credentialsForIdentityIdSpy).toHaveBeenCalledTimes(1);
213233
});
234+
214235
test('Should get new credentials when tokens have changed', async () => {
215236
await cognitoCredentialsProvider.getCredentialsAndIdentityId({
216237
authenticated: true,
@@ -239,19 +260,23 @@ describe('Primary Credentials', () => {
239260
expect(credentialsForIdentityIdSpy).toHaveBeenCalledTimes(2);
240261
});
241262
});
263+
242264
describe('Error Path Cases:', () => {
243265
beforeEach(() => {
244266
cognitoCredentialsProvider =
245267
new CognitoAWSCredentialsAndIdentityIdProvider(
246268
new DefaultIdentityIdStore(sharedInMemoryStorage),
247269
);
248270
});
271+
249272
afterEach(() => {
250273
cognitoCredentialsProvider.clearCredentials();
251274
});
275+
252276
afterAll(() => {
253277
credentialsForIdentityIdSpy?.mockReset();
254278
});
279+
255280
test('Should throw AuthError if either Credentials, accessKeyId or secretKey is absent in the response', async () => {
256281
credentialsForIdentityIdSpy.mockImplementationOnce(async () => {
257282
return authAPITestParams.NoAccessKeyCredentialsForIdentityIdResult as GetCredentialsForIdentityOutput;

packages/auth/__tests__/providers/cognito/testUtils/authApiTestParams.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ export const authAPITestParams = {
149149
SessionToken: 'SessionToken',
150150
Expiration: new Date('2023-07-29'),
151151
},
152+
IdentityId:
153+
'I am expected to be returned as a part of the result as I am the source of truth',
152154
$metadata: {},
153155
},
154156
NoAccessKeyCredentialsForIdentityIdResult: {

packages/auth/src/providers/cognito/credentialsProvider/credentialsProvider.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export class CognitoAWSCredentialsAndIdentityIdProvider
129129
clientResult.Credentials.SecretKey
130130
) {
131131
this._nextCredentialsRefresh = new Date().getTime() + CREDENTIALS_TTL;
132+
132133
const res: CredentialsAndIdentityId = {
133134
credentials: {
134135
accessKeyId: clientResult.Credentials.AccessKeyId,
@@ -198,6 +199,8 @@ export class CognitoAWSCredentialsAndIdentityIdProvider
198199
clientResult.Credentials.AccessKeyId &&
199200
clientResult.Credentials.SecretKey
200201
) {
202+
this._nextCredentialsRefresh = new Date().getTime() + CREDENTIALS_TTL;
203+
201204
const res: CredentialsAndIdentityId = {
202205
credentials: {
203206
accessKeyId: clientResult.Credentials.AccessKeyId,
@@ -207,22 +210,23 @@ export class CognitoAWSCredentialsAndIdentityIdProvider
207210
},
208211
identityId,
209212
};
210-
// Store the credentials in-memory along with the expiration
211-
this._credentialsAndIdentityId = {
212-
...res,
213-
isAuthenticatedCreds: true,
214-
associatedIdToken: authTokens.idToken?.toString(),
215-
};
216-
this._nextCredentialsRefresh = new Date().getTime() + CREDENTIALS_TTL;
217213

218214
if (clientResult.IdentityId) {
219215
res.identityId = clientResult.IdentityId;
216+
// note: the following call removes guest identityId from the persistent store (localStorage)
220217
this._identityIdStore.storeIdentityId({
221218
id: clientResult.IdentityId,
222219
type: 'primary',
223220
});
224221
}
225222

223+
// Store the credentials in-memory along with the expiration
224+
this._credentialsAndIdentityId = {
225+
...res,
226+
isAuthenticatedCreds: true,
227+
associatedIdToken: authTokens.idToken?.toString(),
228+
};
229+
226230
return res;
227231
} else {
228232
throw new AuthError({

0 commit comments

Comments
 (0)