-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.js
118 lines (102 loc) · 2.96 KB
/
api.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Original source: https://github.com/nicehash/rest-clients-demo/blob/master/javascript/api.js
import CryptoJS from 'crypto-js'
import request from 'request-promise-native'
import qs from 'qs'
function createNonce () {
let s = ''; const length = 32
do {
s += Math.random().toString(36).substr(2)
} while (s.length < length)
s = s.substr(0, length)
return s
}
const getAuthHeader = (apiKey, apiSecret, time, nonce, organizationId = '', request = {}) => {
const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, apiSecret)
hmac.update(apiKey)
hmac.update('\0')
hmac.update(time)
hmac.update('\0')
hmac.update(nonce)
hmac.update('\0')
hmac.update('\0')
if (organizationId) hmac.update(organizationId)
hmac.update('\0')
hmac.update('\0')
hmac.update(request.method)
hmac.update('\0')
hmac.update(request.path)
hmac.update('\0')
if (request.query) hmac.update(typeof request.query === 'object' ? qs.stringify(request.query) : request.query)
if (request.body) {
hmac.update('\0')
hmac.update(typeof request.body === 'object' ? JSON.stringify(request.body) : request.body)
}
return apiKey + ':' + hmac.finalize().toString(CryptoJS.enc.Hex)
}
class Api {
constructor ({ locale, apiHost, apiKey, apiSecret, orgId }) {
this.locale = locale || 'en'
this.host = apiHost
this.key = apiKey
this.secret = apiSecret
this.org = orgId
this.localTimeDiff = null
}
getTime () {
return request({
uri: this.host + '/api/v2/time',
json: true
})
.then(res => {
this.localTimeDiff = res.serverTime - (+new Date())
this.time = res.serverTime
return res
})
}
apiCall (method, path, { query, body, time } = {}) {
if (this.localTimeDiff === null) {
return Promise.reject(new Error('Get server time first .getTime()'))
}
// query in path
const [pathOnly, pathQuery] = path.split('?')
if (pathQuery) query = { ...qs.parse(pathQuery), ...query }
const nonce = createNonce()
const timestamp = (time || (+new Date() + this.localTimeDiff)).toString()
const options = {
uri: this.host + pathOnly,
method: method,
headers: {
'X-Request-Id': nonce,
'X-User-Agent': 'NHNodeClient',
'X-Time': timestamp,
'X-Nonce': nonce,
'X-User-Lang': this.locale,
'X-Organization-Id': this.org,
'X-Auth': getAuthHeader(this.key, this.secret, timestamp, nonce, this.org, {
method,
path: pathOnly,
query,
body
})
},
qs: query,
body,
json: true,
timeout: 10000
}
return request(options)
}
get (path, options) {
return this.apiCall('GET', path, options)
}
post (path, options) {
return this.apiCall('POST', path, options)
}
put (path, options) {
return this.apiCall('PUT', path, options)
}
delete (path, options) {
return this.apiCall('DELETE', path, options)
}
}
export default Api