import { HttpRequest } from "@aws-sdk/protocol-http";
import {
FinalizeHandler,
FinalizeHandlerArguments,
FinalizeHandlerOutput,
FinalizeRequestMiddleware,
HandlerExecutionContext,
Pluggable,
RelativeMiddlewareOptions,
} from "@aws-sdk/types";
import { AwsAuthResolvedConfig } from "./configurations";
const isClockSkewed = (newServerTime: number, systemClockOffset: number) =>
Math.abs(getSkewCorrectedDate(systemClockOffset).getTime() - newServerTime) >= 300000;
const getSkewCorrectedDate = (systemClockOffset: number) => new Date(Date.now() + systemClockOffset);
export function awsAuthMiddleware(
options: AwsAuthResolvedConfig
): FinalizeRequestMiddleware {
return (next: FinalizeHandler, context: HandlerExecutionContext): FinalizeHandler =>
async function (args: FinalizeHandlerArguments): Promise> {
if (!HttpRequest.isInstance(args.request)) return next(args);
const signer = typeof options.signer === "function" ? await options.signer() : options.signer;
const output = await next({
...args,
request: await signer.sign(args.request, {
signingDate: new Date(Date.now() + options.systemClockOffset),
signingRegion: context["signing_region"],
signingService: context["signing_service"],
}),
});
const { headers } = output.response as any;
const dateHeader = headers && (headers.date || headers.Date);
if (dateHeader) {
const serverTime = Date.parse(dateHeader);
if (isClockSkewed(serverTime, options.systemClockOffset)) {
options.systemClockOffset = serverTime - Date.now();
}
}
return output;
};
}
export const awsAuthMiddlewareOptions: RelativeMiddlewareOptions = {
name: "awsAuthMiddleware",
tags: ["SIGNATURE", "AWSAUTH"],
relation: "after",
toMiddleware: "retryMiddleware",
override: true,
};
export const getAwsAuthPlugin = (options: AwsAuthResolvedConfig): Pluggable => ({
applyToStack: (clientStack) => {
clientStack.addRelativeTo(awsAuthMiddleware(options), awsAuthMiddlewareOptions);
},
});
export const getSigV4AuthPlugin = getAwsAuthPlugin;