-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
80 lines (63 loc) · 2.04 KB
/
index.js
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/**
* A simple HMAC validator for shopify app instaltation stages at present
* This is designed as a backend package as it requires the secret key to be surfaced to the function,
* This can be used using a serverless function, Google or amazon lambda would do the trick if you
* are purely building client side.
*/
const crypto = require('crypto')
const queryString = require('query-string')
// helpers
const isString = (value) => {
return typeof value === 'string' || value instanceof String;
}
const isObject = (value) => {
return value && typeof value === 'object' && value.constructor === Object;
}
/**
* checkHmacValidity
* @param {sting} secret - Shopify app secret, ( found in partner dashboard)
* @param {string // object} qs ( string or object of query passed from shopify including hmac)
*/
const checkHmacValidity = (secret, qs) => {
// should we add a message
if (!secret || !qs) { return false }
// QS object
let obj = {}
// if qs is a string
if(isString(qs)) {
// generate object
obj = queryString.parse(qs)
}
if(isObject(qs)) {
// set object
obj = qs
}
// no hmac what are we doing here ?
if (!obj.hmac) { return false }
const hmac = obj.hmac
const removeHmac = (key, {[key]: _, ...rest}) => rest
obj = removeHmac("hmac", obj)
let input = queryString.stringify(obj)
let hash = crypto.createHmac('SHA256', secret).update(input).digest('hex')
// validate and return
return hash === hmac
}
/**
*
* @param {sting} secret - Shopify app secret, ( found in partner dashboard)
* @param {string} rawBody - raw body of the request
* @param {string} hmac - Header HMAC
*/
const checkWebhookHmacValidity = (secret, rawBody, hmac) => {
if(!secret || !rawBody || !hmac) { return false}
// Nothing fancy here
const hash = crypto.createHmac('SHA256', secret).update(rawBody).digest('base64')
return hash === hmac
}
const createRawBody = (bodyObject) => Buffer.from(JSON.stringify(bodyObject)).toString('utf8')
module.exports = {
default: checkHmacValidity,
checkHmacValidity,
checkWebhookHmacValidity,
createRawBody,
}