diff --git a/src/index.ts b/src/index.ts index 7146151..47fc9f9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,7 @@ // tslint:disable-next-line match-default-export-name +import { createHash } from 'crypto'; import { ParsedUrlQueryInput } from 'querystring'; +import * as urlHelpers from 'url'; import { addQueryToUrl } from 'url-transformers'; import { pickBy } from './helpers'; import { catMaybesDictionary, mapValueIfDefined } from './helpers/maybe'; @@ -71,6 +73,7 @@ export type ImgixUrlQueryParams = { cs?: ImgixColorSpace; faceindex?: number; facepad?: number; + s?: string; }; const pickTrueInObject = (obj: Record): Partial> => @@ -87,6 +90,22 @@ const serializeImgixUrlQueryParamListValue = pipe( joinWithComma, undefinedIfEmptyString, ); +const addImgixUrlQueryParamSignature = (url: string, token?: string) => ( + query: ParsedUrlQueryInput, +) => { + if (token === undefined || query.hasOwnProperty('s')) return query; + + const formattedQuery = urlHelpers.format({ query }); + const { pathname } = new urlHelpers.URL(url); + + // https://github.com/imgix/imgix-blueprint#securing-urls + const signatureBase = token + pathname + formattedQuery; + const signature = createHash('md5') + .update(signatureBase) + .digest('hex'); + + return { ...query, s: signature }; +}; const mapToSerializedListValueIfDefined = mapValueIfDefined(serializeImgixUrlQueryParamListValue); @@ -110,12 +129,14 @@ const serializeImgixUrlQueryParamValues = (query: ImgixUrlQueryParams): ParsedUr blur: query.blur, faceindex: query.faceindex, facepad: query.facepad, + s: query.s, }), catMaybesDictionary, )({}); -export const buildImgixUrl = (url: string) => +export const buildImgixUrl = (url: string, token?: string) => pipe( serializeImgixUrlQueryParamValues, + addImgixUrlQueryParamSignature(url, token), query => addQueryToUrl({ url })({ queryToAppend: query }), ); diff --git a/src/tests.ts b/src/tests.ts index 6b4c0c9..b9e43b2 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -10,3 +10,24 @@ assert.strictEqual( }), 'https://foo.com/?auto=format&w=300', ); + +assert.strictEqual( + buildImgixUrl('https://foo.com', 'token')({ + auto: { + format: true, + }, + w: 300, + s: 'signature', + }), + 'https://foo.com/?auto=format&w=300&s=signature', +); + +assert.strictEqual( + buildImgixUrl('https://foo.com', 'token')({ + auto: { + format: true, + }, + w: 300, + }), + 'https://foo.com/?auto=format&w=300&s=d82d76f9f31379083b452f98bcd7f670', +);