11import { AwsClient } from 'aws4fetch';
22import { CognitoIdentityClient } from '@aws-sdk/client-cognito-identity';
33import { fromCognitoIdentityPool } from '@aws-sdk/credential-provider-cognito-identity';
4- import { useCallback } from 'react';
4+ import { useCallback, useState } from 'react';
55import { useAuth } from 'react-oidc-context';
66import { useRuntimeConfig } from './useRuntimeConfig';
7+ import { AwsCredentialIdentity, AwsCredentialIdentityProvider } from '@smithy/types';
8+
9+ // Credential expiration grace time before considering credentials as expired
10+ const CREDENTIAL_EXPIRY_OFFSET_MILLIS = 30 * 1000;
711
812export const useSigV4 = () => {
913 const { cognitoProps } = useRuntimeConfig();
1014 const { user } = useAuth();
1115
16+ const [cachedCredentials, setCachedCredentials] = useState<{ [key: string]: AwsCredentialIdentity }>({});
17+
18+ const withCachedCredentials = useCallback(async (provider: AwsCredentialIdentityProvider, ...cacheKeys: string[]): Promise<AwsCredentialIdentity> => {
19+ const key = `sigv4/${cacheKeys.join('/')}`;
20+ const cachedCreds = cachedCredentials[key];
21+ if (cachedCreds && cachedCreds.expiration && cachedCreds.expiration.getTime() > Date.now() + CREDENTIAL_EXPIRY_OFFSET_MILLIS) {
22+ return cachedCreds;
23+ }
24+ const credentials = await provider();
25+ setCachedCredentials((prev) => ({ ...prev, [key]: credentials }));
26+ return credentials;
27+ }, [cachedCredentials, setCachedCredentials]);
28+
1229 return useCallback(
1330 async (input: RequestInfo | URL, init?: RequestInit | undefined) => {
1431 if (!cognitoProps) {
@@ -29,7 +46,7 @@ export const useSigV4 = () => {
2946 const cognitoidentity = new CognitoIdentityClient({
3047 credentials: credentialsFromCognitoIdentityPool,
3148 });
32- const credential = await cognitoidentity.config.credentials( );
49+ const credential = await withCachedCredentials( cognitoidentity.config.credentials, cognitoProps.identityPoolId, user.profile.sub );
3350 const awsClient = new AwsClient(credential);
3451 return awsClient.fetch(input, init);
3552 },
0 commit comments