@gofynd/fdk-client-javascript 1.3.1-beta.1 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gofynd/fdk-client-javascript",
|
|
3
|
-
"version": "1.3.1
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"crypto-js": "^4.1.1",
|
|
18
18
|
"joi": "^17.7.0",
|
|
19
19
|
"loglevel": "^1.8.1",
|
|
20
|
-
"query-string": "^7.1.3"
|
|
20
|
+
"query-string": "^7.1.3",
|
|
21
|
+
"@gofynd/fp-signature": "^0.0.2-alpha.1"
|
|
21
22
|
},
|
|
22
23
|
"devDependencies": {
|
|
23
24
|
"axios-cookiejar-support": "^4.0.6",
|
|
@@ -2,7 +2,7 @@ const combineURLs = require("axios/lib/helpers/combineURLs");
|
|
|
2
2
|
const isAbsoluteURL = require("axios/lib/helpers/isAbsoluteURL");
|
|
3
3
|
const axios = require("axios");
|
|
4
4
|
const querystring = require("query-string");
|
|
5
|
-
const { sign } = require("
|
|
5
|
+
const { sign } = require("@gofynd/fp-signature");
|
|
6
6
|
const { FDKServerResponseError } = require("./FDKError");
|
|
7
7
|
const { log, Logger, getLoggerLevel } = require("./Logger");
|
|
8
8
|
const createCurl = require("./curlHelper");
|
|
@@ -73,7 +73,7 @@ function requestInterceptorFn() {
|
|
|
73
73
|
body: transformedData,
|
|
74
74
|
headers: headersToSign,
|
|
75
75
|
};
|
|
76
|
-
sign(signingOptions);
|
|
76
|
+
sign(signingOptions, "1234567");
|
|
77
77
|
|
|
78
78
|
config.headers["x-fp-date"] = signingOptions.headers["x-fp-date"];
|
|
79
79
|
config.headers["x-fp-signature"] = signingOptions.headers["x-fp-signature"];
|
|
@@ -3,7 +3,7 @@ const { FDKTokenIssueError } = require("../common/FDKError");
|
|
|
3
3
|
const { Logger } = require("../common/Logger");
|
|
4
4
|
const BaseOAuthClient = require("../common/BaseOAuthClient");
|
|
5
5
|
const querystring = require("query-string");
|
|
6
|
-
const { sign } = require("
|
|
6
|
+
const { sign } = require("@gofynd/fp-signature");
|
|
7
7
|
|
|
8
8
|
class OAuthClient extends BaseOAuthClient {
|
|
9
9
|
constructor(config) {
|
|
@@ -32,7 +32,7 @@ class OAuthClient extends BaseOAuthClient {
|
|
|
32
32
|
headers: {},
|
|
33
33
|
signQuery: true,
|
|
34
34
|
};
|
|
35
|
-
signingOptions = sign(signingOptions);
|
|
35
|
+
signingOptions = sign(signingOptions, "1234567");
|
|
36
36
|
Logger({ type: "DEBUG", message: "Authorization successful" });
|
|
37
37
|
|
|
38
38
|
return `${this.config.domain}${signingOptions.path}`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const querystring = require("query-string");
|
|
2
2
|
const { fdkAxios } = require("../common/AxiosHelper");
|
|
3
|
-
const { sign } = require("
|
|
3
|
+
const { sign } = require("@gofynd/fp-signature");
|
|
4
4
|
const { FDKTokenIssueError, FDKOAuthCodeError } = require("../common/FDKError");
|
|
5
5
|
const { Logger } = require("../common/Logger");
|
|
6
6
|
const { convertStringToBase64 } = require("../common/utils");
|
|
@@ -86,7 +86,7 @@ class OAuthClient {
|
|
|
86
86
|
headers: {},
|
|
87
87
|
signQuery: true,
|
|
88
88
|
};
|
|
89
|
-
signingOptions = sign(signingOptions);
|
|
89
|
+
signingOptions = sign(signingOptions, "1234567");
|
|
90
90
|
Logger({ level: "INFO", message: "Authorization successful.!" });
|
|
91
91
|
|
|
92
92
|
return `${this.config.domain}${signingOptions.path}`;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export function sign(request: any): any;
|
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const querystring = require("query-string");
|
|
4
|
-
const sha256 = require("crypto-js/sha256");
|
|
5
|
-
const hmacSHA256 = require("crypto-js/hmac-sha256");
|
|
6
|
-
|
|
7
|
-
function hmac(key, string, encoding) {
|
|
8
|
-
return hmacSHA256(string, key).toString();
|
|
9
|
-
}
|
|
10
|
-
function hash(string, encoding) {
|
|
11
|
-
return sha256(string).toString();
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// This function assumes the string has already been percent encoded
|
|
15
|
-
function encodeRfc3986(urlEncodedString) {
|
|
16
|
-
return urlEncodedString.replace(/[!'()*]/g, function (c) {
|
|
17
|
-
return "%" + c.charCodeAt(0).toString(16).toUpperCase();
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function encodeRfc3986Full(str) {
|
|
22
|
-
return str;
|
|
23
|
-
// return encodeRfc3986(encodeURIComponent(str));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const HEADERS_TO_IGNORE = {
|
|
27
|
-
authorization: true,
|
|
28
|
-
connection: true,
|
|
29
|
-
"x-amzn-trace-id": true,
|
|
30
|
-
"user-agent": true,
|
|
31
|
-
expect: true,
|
|
32
|
-
"presigned-expires": true,
|
|
33
|
-
range: true,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const HEADERS_TO_INCLUDE = ["x-fp-.*", "host"];
|
|
37
|
-
|
|
38
|
-
// request: { path | body, [host], [method], [headers], [service], [region] }
|
|
39
|
-
class RequestSigner {
|
|
40
|
-
constructor(request) {
|
|
41
|
-
let headers = (request.headers = request.headers || {});
|
|
42
|
-
this.request = request;
|
|
43
|
-
|
|
44
|
-
if (!request.method && request.body) {
|
|
45
|
-
request.method = "POST";
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!headers.Host && !headers.host) {
|
|
49
|
-
headers.Host = request.hostname || request.host;
|
|
50
|
-
|
|
51
|
-
// If a port is specified explicitly, use it as is
|
|
52
|
-
if (request.port) {
|
|
53
|
-
headers.Host += ":" + request.port;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (!request.hostname && !request.host) {
|
|
57
|
-
request.hostname = headers.Host || headers.host;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
prepareRequest() {
|
|
62
|
-
this.parsePath();
|
|
63
|
-
|
|
64
|
-
let request = this.request;
|
|
65
|
-
let headers = request.headers;
|
|
66
|
-
let query;
|
|
67
|
-
|
|
68
|
-
if (request.signQuery) {
|
|
69
|
-
this.parsedPath.query = query = this.parsedPath.query || {};
|
|
70
|
-
|
|
71
|
-
if (query["x-fp-date"]) {
|
|
72
|
-
this.datetime = query["x-fp-date"];
|
|
73
|
-
} else {
|
|
74
|
-
query["x-fp-date"] = this.getDateTime();
|
|
75
|
-
}
|
|
76
|
-
} else {
|
|
77
|
-
if (!request.doNotModifyHeaders) {
|
|
78
|
-
if (headers["x-fp-date"]) {
|
|
79
|
-
this.datetime = headers["x-fp-date"] || headers["x-fp-date"];
|
|
80
|
-
} else {
|
|
81
|
-
headers["x-fp-date"] = this.getDateTime();
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
delete headers["x-fp-signature"];
|
|
86
|
-
delete headers["X-Fp-Signature"];
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
sign() {
|
|
91
|
-
if (!this.parsedPath) {
|
|
92
|
-
this.prepareRequest();
|
|
93
|
-
}
|
|
94
|
-
if (this.request.signQuery) {
|
|
95
|
-
this.parsedPath.query["x-fp-signature"] = this.signature();
|
|
96
|
-
} else {
|
|
97
|
-
this.request.headers["x-fp-signature"] = this.signature();
|
|
98
|
-
}
|
|
99
|
-
this.request.path = this.formatPath();
|
|
100
|
-
return this.request;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
getDateTime() {
|
|
104
|
-
if (!this.datetime) {
|
|
105
|
-
let headers = this.request.headers;
|
|
106
|
-
let date = new Date(headers.Date || headers.date || new Date());
|
|
107
|
-
|
|
108
|
-
this.datetime = date.toISOString().replace(/[:\-]|\.\d{3}/g, "");
|
|
109
|
-
}
|
|
110
|
-
return this.datetime;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
getDate() {
|
|
114
|
-
return this.getDateTime().substr(0, 8);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
signature() {
|
|
118
|
-
let kCredentials = "1234567";
|
|
119
|
-
let strTosign = this.stringToSign();
|
|
120
|
-
return `v1.1:${hmac(kCredentials, strTosign, "hex")}`;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
stringToSign() {
|
|
124
|
-
return [this.getDateTime(), hash(this.canonicalString(), "hex")].join("\n");
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
canonicalString() {
|
|
128
|
-
if (!this.parsedPath) {
|
|
129
|
-
this.prepareRequest();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
let pathStr = this.parsedPath.path;
|
|
133
|
-
let query = this.parsedPath.query;
|
|
134
|
-
let headers = this.request.headers;
|
|
135
|
-
let queryStr = "";
|
|
136
|
-
let normalizePath = true;
|
|
137
|
-
let decodePath = this.request.doNotEncodePath;
|
|
138
|
-
let decodeSlashesInPath = false;
|
|
139
|
-
let firstValOnly = false;
|
|
140
|
-
let bodyHash = hash(this.request.body || "", "hex");
|
|
141
|
-
if (query) {
|
|
142
|
-
let reducedQuery = Object.keys(query).reduce(function (obj, key) {
|
|
143
|
-
if (!key) {
|
|
144
|
-
return obj;
|
|
145
|
-
}
|
|
146
|
-
obj[encodeRfc3986Full(key)] = !Array.isArray(query[key])
|
|
147
|
-
? query[key]
|
|
148
|
-
: firstValOnly
|
|
149
|
-
? query[key][0]
|
|
150
|
-
: query[key];
|
|
151
|
-
return obj;
|
|
152
|
-
}, {});
|
|
153
|
-
let encodedQueryPieces = [];
|
|
154
|
-
Object.keys(reducedQuery)
|
|
155
|
-
.sort()
|
|
156
|
-
.forEach(function (key) {
|
|
157
|
-
if (!Array.isArray(reducedQuery[key])) {
|
|
158
|
-
encodedQueryPieces.push(
|
|
159
|
-
key + "=" + encodeRfc3986Full(reducedQuery[key])
|
|
160
|
-
);
|
|
161
|
-
} else {
|
|
162
|
-
reducedQuery[key]
|
|
163
|
-
.map(encodeRfc3986Full)
|
|
164
|
-
.sort()
|
|
165
|
-
.forEach(function (val) {
|
|
166
|
-
encodedQueryPieces.push(key + "=" + val);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
queryStr = encodedQueryPieces.join("&");
|
|
171
|
-
}
|
|
172
|
-
if (pathStr !== "/") {
|
|
173
|
-
if (normalizePath) {
|
|
174
|
-
pathStr = pathStr.replace(/\/{2,}/g, "/");
|
|
175
|
-
}
|
|
176
|
-
pathStr = pathStr
|
|
177
|
-
.split("/")
|
|
178
|
-
.reduce(function (path, piece) {
|
|
179
|
-
if (normalizePath && piece === "..") {
|
|
180
|
-
path.pop();
|
|
181
|
-
} else if (!normalizePath || piece !== ".") {
|
|
182
|
-
if (decodePath)
|
|
183
|
-
piece = decodeURIComponent(piece.replace(/\+/g, " "));
|
|
184
|
-
path.push(encodeRfc3986Full(piece));
|
|
185
|
-
}
|
|
186
|
-
return path;
|
|
187
|
-
}, [])
|
|
188
|
-
.join("/");
|
|
189
|
-
if (pathStr[0] !== "/") pathStr = "/" + pathStr;
|
|
190
|
-
if (decodeSlashesInPath) pathStr = pathStr.replace(/%2F/g, "/");
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
let canonicalReq = [
|
|
194
|
-
this.request.method || "GET",
|
|
195
|
-
pathStr,
|
|
196
|
-
queryStr,
|
|
197
|
-
this.canonicalHeaders() + "\n",
|
|
198
|
-
this.signedHeaders(),
|
|
199
|
-
bodyHash,
|
|
200
|
-
].join("\n");
|
|
201
|
-
return canonicalReq;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
canonicalHeaders() {
|
|
205
|
-
let headers = this.request.headers;
|
|
206
|
-
|
|
207
|
-
function trimAll(header) {
|
|
208
|
-
return header.toString().trim().replace(/\s+/g, " ");
|
|
209
|
-
}
|
|
210
|
-
return Object.keys(headers)
|
|
211
|
-
.filter(function (key) {
|
|
212
|
-
let notInIgnoreHeader = HEADERS_TO_IGNORE[key.toLowerCase()] == null;
|
|
213
|
-
if (notInIgnoreHeader) {
|
|
214
|
-
let foundMatch = false;
|
|
215
|
-
for (let t in HEADERS_TO_INCLUDE) {
|
|
216
|
-
foundMatch =
|
|
217
|
-
foundMatch || new RegExp(HEADERS_TO_INCLUDE[t], "ig").test(key);
|
|
218
|
-
}
|
|
219
|
-
return foundMatch;
|
|
220
|
-
} else {
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
})
|
|
224
|
-
.sort(function (a, b) {
|
|
225
|
-
return a.toLowerCase() < b.toLowerCase() ? -1 : 1;
|
|
226
|
-
})
|
|
227
|
-
.map(function (key) {
|
|
228
|
-
return key.toLowerCase() + ":" + trimAll(headers[key]);
|
|
229
|
-
})
|
|
230
|
-
.join("\n");
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
signedHeaders() {
|
|
234
|
-
return Object.keys(this.request.headers)
|
|
235
|
-
.map(function (key) {
|
|
236
|
-
return key.toLowerCase();
|
|
237
|
-
})
|
|
238
|
-
.filter(function (key) {
|
|
239
|
-
let notInIgnoreHeader = HEADERS_TO_IGNORE[key.toLowerCase()] == null;
|
|
240
|
-
if (notInIgnoreHeader) {
|
|
241
|
-
let foundMatch = false;
|
|
242
|
-
for (let t in HEADERS_TO_INCLUDE) {
|
|
243
|
-
foundMatch =
|
|
244
|
-
foundMatch || new RegExp(HEADERS_TO_INCLUDE[t], "ig").test(key);
|
|
245
|
-
}
|
|
246
|
-
return foundMatch;
|
|
247
|
-
} else {
|
|
248
|
-
return false;
|
|
249
|
-
}
|
|
250
|
-
})
|
|
251
|
-
.sort()
|
|
252
|
-
.join(";");
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
parsePath() {
|
|
256
|
-
let path = this.request.path || "/";
|
|
257
|
-
let queryIx = path.indexOf("?");
|
|
258
|
-
let query = null;
|
|
259
|
-
|
|
260
|
-
if (queryIx >= 0) {
|
|
261
|
-
query = querystring.parse(path.slice(queryIx + 1));
|
|
262
|
-
path = path.slice(0, queryIx);
|
|
263
|
-
}
|
|
264
|
-
path = path
|
|
265
|
-
.split("/")
|
|
266
|
-
.map((t) => {
|
|
267
|
-
return encodeURIComponent(decodeURIComponent(t));
|
|
268
|
-
})
|
|
269
|
-
.join("/");
|
|
270
|
-
|
|
271
|
-
this.parsedPath = {
|
|
272
|
-
path: path,
|
|
273
|
-
query: query,
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
formatPath() {
|
|
278
|
-
let path = this.parsedPath.path;
|
|
279
|
-
let query = this.parsedPath.query;
|
|
280
|
-
|
|
281
|
-
if (!query) {
|
|
282
|
-
return path;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// Services don't support empty query string keys
|
|
286
|
-
if (query[""] != null) {
|
|
287
|
-
delete query[""];
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return path + "?" + encodeRfc3986(querystring.stringify(query));
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
function sign(request) {
|
|
295
|
-
return new RequestSigner(request).sign();
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
module.exports = {
|
|
299
|
-
sign: sign,
|
|
300
|
-
};
|