Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 10x 10x 10x 10x 10x 10x 10x 10x 19x 114x 76x 19x 10x 19x 19x 19x 10x 12x 1x 11x 11x 11x 10x | import crypto from 'crypto'; import querystring from 'querystring'; import {AuthQuery} from '../auth/oauth/types'; import * as ShopifyErrors from '../error'; import {Context} from '../context'; import safeCompare from './safe-compare'; export function stringifyQuery(query: AuthQuery): string { const orderedObj = Object.keys(query) .sort((val1, val2) => val1.localeCompare(val2)) .reduce( (obj: {[key: string]: string | undefined}, key: keyof AuthQuery) => ({ ...obj, [key]: query[key], }), {}, ); return querystring.stringify(orderedObj); } export function generateLocalHmac({ code, timestamp, state, shop, host, }: AuthQuery): string { const queryString = stringifyQuery({ code, timestamp, state, shop, ...(host && {host}), }); return crypto .createHmac('sha256', Context.API_SECRET_KEY) .update(queryString) .digest('hex'); } /** * Uses the received query to validate the contained hmac value against the rest of the query content. * * @param query HTTP Request Query, containing the information to be validated. */ export default function validateHmac(query: AuthQuery): boolean { if (!query.hmac) { throw new ShopifyErrors.InvalidHmacError( 'Query does not contain an HMAC value.', ); } const {hmac} = query; const localHmac = generateLocalHmac(query); return safeCompare(hmac as string, localHmac); } |