UNPKG

@octopusdeploy/step-packages-public-feed-encryption

Version:

A package that facilitates the generation of an encrypted signature for step package public feed. The encryption method follows the convention of [AWS Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html).

58 lines (44 loc) 2.22 kB
import * as crypto from "crypto"; export type KeyValuePair = { key: string; value: string | undefined; }; export const createHash = (algorithm: string, message: string | Buffer): string => { return crypto.createHash(algorithm).update(message).digest("hex"); }; export const createHmac = (algorithm: string, message: string, secret: string): string => { return crypto.createHmac(algorithm, secret).update(message).digest("hex"); }; const sortKeyValuePairs = (keyValuePairs: KeyValuePair[]): KeyValuePair[] => { return keyValuePairs.sort((a, b): number => (a.key > b.key ? 1 : a.key < b.key ? -1 : 0)); }; const keyValuePairToString = (keyValuePair: KeyValuePair): string => { return `${keyValuePair.key.trim().toLowerCase()}:${keyValuePair.value?.trim().replace(/\s+/g, " ")}\n`; }; const createCanonicalRequest = (algorithm: string, httpMethod: string, headers: KeyValuePair[], payloads: KeyValuePair[]): string => { const sortedHeaders = sortKeyValuePairs(headers); const canonicalHeaders = sortedHeaders.map((pair) => keyValuePairToString(pair)).join(); const signedHeader = sortedHeaders.map((pair) => pair.key.trim().toLowerCase()).join(";"); const canonicalPayloads = sortKeyValuePairs(payloads) .map((pair) => keyValuePairToString(pair)) .join(); const payloadHash = createHash(algorithm, canonicalPayloads); return `${httpMethod}\n${canonicalHeaders}\n${signedHeader}\n${payloadHash}`; }; const createStringToSign = (algorithm: string, canonicalRequest: string, requestTimestamp: string): string => { const canonicalRequestHash = createHash(algorithm, canonicalRequest); return `${algorithm}\n${requestTimestamp}\n${canonicalRequestHash}`; }; export const createSignature = ( algorithm: string, secretKey: string, httpMethod: string, headers: KeyValuePair[], payloads: KeyValuePair[], requestTimestamp: string ): string => { const derivedSecret = createHmac(algorithm, requestTimestamp, secretKey); const canonicalRequest = createCanonicalRequest(algorithm, httpMethod, headers, payloads); const stringToSign = createStringToSign(algorithm, canonicalRequest, requestTimestamp); return createHmac(algorithm, stringToSign, derivedSecret); };