chore(plugin-cloud): refresh session on ExpiredToken error code (#8904)
Fixes https://github.com/payloadcms/payload/issues/8404 This code will refresh the session token upon receiving an `ExpiredToken` error when `storageClient.getObject()` receives that error. - The `Error Code` detected is determined by the error reported in the issue, and is an actual code from [AWS documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html) for Error Responses. - If the request fails again, the error is thrown.
This commit is contained in:
@@ -1,19 +1,13 @@
|
||||
import type * as AWS from '@aws-sdk/client-s3'
|
||||
import type { CognitoUserSession } from 'amazon-cognito-identity-js'
|
||||
|
||||
import { CognitoIdentityClient } from '@aws-sdk/client-cognito-identity'
|
||||
import * as AWS from '@aws-sdk/client-s3'
|
||||
import { fromCognitoIdentityPool } from '@aws-sdk/credential-providers'
|
||||
import type { GetStorageClient } from './refreshSession.js'
|
||||
|
||||
import { authAsCognitoUser } from './authAsCognitoUser.js'
|
||||
import { refreshSession } from './refreshSession.js'
|
||||
|
||||
export type GetStorageClient = () => Promise<{
|
||||
identityID: string
|
||||
storageClient: AWS.S3
|
||||
}>
|
||||
|
||||
let storageClient: AWS.S3 | null = null
|
||||
let session: CognitoUserSession | null = null
|
||||
let identityID: string
|
||||
export let storageClient: AWS.S3 | null = null
|
||||
export let session: CognitoUserSession | null = null
|
||||
export let identityID: string
|
||||
|
||||
export const getStorageClient: GetStorageClient = async () => {
|
||||
if (storageClient && session?.isValid()) {
|
||||
@@ -23,6 +17,8 @@ export const getStorageClient: GetStorageClient = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
;({ identityID, session, storageClient } = await refreshSession())
|
||||
|
||||
if (!process.env.PAYLOAD_CLOUD_PROJECT_ID) {
|
||||
throw new Error('PAYLOAD_CLOUD_PROJECT_ID is required')
|
||||
}
|
||||
@@ -33,34 +29,6 @@ export const getStorageClient: GetStorageClient = async () => {
|
||||
throw new Error('PAYLOAD_CLOUD_COGNITO_IDENTITY_POOL_ID is required')
|
||||
}
|
||||
|
||||
session = await authAsCognitoUser(
|
||||
process.env.PAYLOAD_CLOUD_PROJECT_ID,
|
||||
process.env.PAYLOAD_CLOUD_COGNITO_PASSWORD,
|
||||
)
|
||||
|
||||
const cognitoIdentity = new CognitoIdentityClient({
|
||||
credentials: fromCognitoIdentityPool({
|
||||
clientConfig: {
|
||||
region: 'us-east-1',
|
||||
},
|
||||
identityPoolId: process.env.PAYLOAD_CLOUD_COGNITO_IDENTITY_POOL_ID,
|
||||
logins: {
|
||||
[`cognito-idp.us-east-1.amazonaws.com/${process.env.PAYLOAD_CLOUD_COGNITO_USER_POOL_ID}`]:
|
||||
session.getIdToken().getJwtToken(),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
const credentials = await cognitoIdentity.config.credentials()
|
||||
|
||||
// @ts-expect-error - Incorrect AWS types
|
||||
identityID = credentials.identityId
|
||||
|
||||
storageClient = new AWS.S3({
|
||||
credentials,
|
||||
region: process.env.PAYLOAD_CLOUD_BUCKET_REGION,
|
||||
})
|
||||
|
||||
return {
|
||||
identityID,
|
||||
storageClient,
|
||||
|
||||
46
packages/payload-cloud/src/utilities/refreshSession.ts
Normal file
46
packages/payload-cloud/src/utilities/refreshSession.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { CognitoIdentityClient } from '@aws-sdk/client-cognito-identity'
|
||||
import * as AWS from '@aws-sdk/client-s3'
|
||||
import { fromCognitoIdentityPool } from '@aws-sdk/credential-providers'
|
||||
|
||||
import { authAsCognitoUser } from './authAsCognitoUser.js'
|
||||
|
||||
export type GetStorageClient = () => Promise<{
|
||||
identityID: string
|
||||
storageClient: AWS.S3
|
||||
}>
|
||||
|
||||
export const refreshSession = async () => {
|
||||
const session = await authAsCognitoUser(
|
||||
process.env.PAYLOAD_CLOUD_PROJECT_ID || '',
|
||||
process.env.PAYLOAD_CLOUD_COGNITO_PASSWORD || '',
|
||||
)
|
||||
|
||||
const cognitoIdentity = new CognitoIdentityClient({
|
||||
credentials: fromCognitoIdentityPool({
|
||||
clientConfig: {
|
||||
region: 'us-east-1',
|
||||
},
|
||||
identityPoolId: process.env.PAYLOAD_CLOUD_COGNITO_IDENTITY_POOL_ID || '',
|
||||
logins: {
|
||||
[`cognito-idp.us-east-1.amazonaws.com/${process.env.PAYLOAD_CLOUD_COGNITO_USER_POOL_ID}`]:
|
||||
session.getIdToken().getJwtToken(),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
const credentials = await cognitoIdentity.config.credentials()
|
||||
|
||||
// @ts-expect-error - Incorrect AWS types
|
||||
const identityID = credentials.identityId
|
||||
|
||||
const storageClient = new AWS.S3({
|
||||
credentials,
|
||||
region: process.env.PAYLOAD_CLOUD_BUCKET_REGION,
|
||||
})
|
||||
|
||||
return {
|
||||
identityID,
|
||||
session,
|
||||
storageClient,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user