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;