@middy/sts
Version:
STS (Security Token Service) credentials middleware for the middy framework
83 lines (71 loc) • 2.32 kB
JavaScript
import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts";
import {
canPrefetch,
catchInvalidSignatureException,
createClient,
createPrefetchClient,
getCache,
getInternal,
modifyCache,
processCache,
} from "@middy/util";
const defaults = {
AwsClient: STSClient,
awsClientOptions: {},
// awsClientAssumeRole: undefined, // Not Applicable, as this is the middleware that defines the roles
awsClientCapture: undefined,
fetchData: {}, // { contextKey: {RoleArn, RoleSessionName} }
disablePrefetch: false,
cacheKey: "sts",
cacheKeyExpiry: {},
cacheExpiry: -1,
setToContext: false,
};
const stsMiddleware = (opts = {}) => {
const options = { ...defaults, ...opts };
const fetch = (request, cachedValues = {}) => {
const values = {};
for (const internalKey of Object.keys(options.fetchData)) {
if (cachedValues[internalKey]) continue;
const assumeRoleOptions = options.fetchData[internalKey];
// Date cannot be used here to assign default session name, possibility of collision when > 1 role defined
assumeRoleOptions.RoleSessionName ??= `middy-sts-session-${Math.ceil(Math.random() * 99999)}`;
const command = new AssumeRoleCommand(assumeRoleOptions);
values[internalKey] = client
.send(command)
.catch((e) => catchInvalidSignatureException(e, client, command))
.then((resp) => ({
accessKeyId: resp.Credentials.AccessKeyId,
secretAccessKey: resp.Credentials.SecretAccessKey,
sessionToken: resp.Credentials.SessionToken,
}))
.catch((e) => {
const value = getCache(options.cacheKey).value ?? {};
value[internalKey] = undefined;
modifyCache(options.cacheKey, value);
throw e;
});
}
return values;
};
let client;
if (canPrefetch(options)) {
client = createPrefetchClient(options);
processCache(options, fetch);
}
const stsMiddlewareBefore = async (request) => {
if (!client) {
client = await createClient(options, request);
}
const { value } = processCache(options, fetch, request);
Object.assign(request.internal, value);
if (options.setToContext) {
const data = await getInternal(Object.keys(options.fetchData), request);
if (options.setToContext) Object.assign(request.context, data);
}
};
return {
before: stsMiddlewareBefore,
};
};
export default stsMiddleware;