@agnostack/next-shopify 1.15.0-beta.2 → 1.15.0-beta.21
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/CHANGELOG.md +136 -0
- package/dist/lib/handlers/api/auth.js +15 -11
- package/dist/lib/handlers/api/auth.js.map +1 -1
- package/dist/lib/handlers/api/billing.js +13 -9
- package/dist/lib/handlers/api/billing.js.map +1 -1
- package/dist/lib/handlers/api/callback.js +37 -33
- package/dist/lib/handlers/api/callback.js.map +1 -1
- package/dist/lib/handlers/api/index.js +25 -7
- package/dist/lib/handlers/api/index.js.map +1 -1
- package/dist/lib/handlers/api/uninstall.js +12 -8
- package/dist/lib/handlers/api/uninstall.js.map +1 -1
- package/dist/lib/handlers/api/verifiable/appInstallation.js +11 -7
- package/dist/lib/handlers/api/verifiable/appInstallation.js.map +1 -1
- package/dist/lib/handlers/api/verifiable/graph.js +26 -22
- package/dist/lib/handlers/api/verifiable/graph.js.map +1 -1
- package/dist/lib/handlers/api/verifiable/index.js +21 -5
- package/dist/lib/handlers/api/verifiable/index.js.map +1 -1
- package/dist/lib/handlers/api/verifiable/proxy.js +39 -32
- package/dist/lib/handlers/api/verifiable/proxy.js.map +1 -1
- package/dist/lib/handlers/api/verifiable/rest.js +23 -19
- package/dist/lib/handlers/api/verifiable/rest.js.map +1 -1
- package/dist/lib/handlers/api/verifiable/token.js +27 -23
- package/dist/lib/handlers/api/verifiable/token.js.map +1 -1
- package/dist/lib/handlers/api/webhook.js +13 -9
- package/dist/lib/handlers/api/webhook.js.map +1 -1
- package/dist/lib/handlers/index.js +18 -2
- package/dist/lib/handlers/index.js.map +1 -1
- package/dist/lib/handlers/ssr/index.js +18 -2
- package/dist/lib/handlers/ssr/index.js.map +1 -1
- package/dist/lib/handlers/ssr/protect.js +24 -17
- package/dist/lib/handlers/ssr/protect.js.map +1 -1
- package/dist/lib/handlers/ssr/wrap.js +10 -6
- package/dist/lib/handlers/ssr/wrap.js.map +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +24 -5
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/utils/billing.js +23 -18
- package/dist/lib/utils/billing.js.map +1 -1
- package/dist/lib/utils/crypto.d.ts +1 -1
- package/dist/lib/utils/crypto.d.ts.map +1 -1
- package/dist/lib/utils/crypto.js +25 -15
- package/dist/lib/utils/crypto.js.map +1 -1
- package/dist/lib/utils/firebase.js +29 -17
- package/dist/lib/utils/firebase.js.map +1 -1
- package/dist/lib/utils/headers.js +13 -6
- package/dist/lib/utils/headers.js.map +1 -1
- package/dist/lib/utils/index.js +24 -8
- package/dist/lib/utils/index.js.map +1 -1
- package/dist/lib/utils/session.js +64 -59
- package/dist/lib/utils/session.js.map +1 -1
- package/dist/lib/utils/shopify-api-js/oauth.js +23 -16
- package/dist/lib/utils/shopify-api-js/oauth.js.map +1 -1
- package/dist/lib/utils/shopify.js +37 -25
- package/dist/lib/utils/shopify.js.map +1 -1
- package/dist/lib/utils/token.js +15 -11
- package/dist/lib/utils/token.js.map +1 -1
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +19 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/types.d.ts +1 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +1 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/plugins/withShopify.d.ts.map +1 -0
- package/dist/{lib → plugins}/withShopify.js +83 -77
- package/dist/plugins/withShopify.js.map +1 -0
- package/dist/react/hooks/index.js +17 -1
- package/dist/react/hooks/index.js.map +1 -1
- package/dist/react/hooks/useVerification.d.ts +1 -1
- package/dist/react/hooks/useVerification.js +23 -7
- package/dist/react/hooks/useVerification.js.map +1 -1
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +18 -1
- package/dist/react/index.js.map +1 -1
- package/dist/runtime/index.js +17 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/shared/WebCrypto.d.ts +55 -0
- package/dist/shared/WebCrypto.d.ts.map +1 -0
- package/dist/shared/WebCrypto.js +345 -0
- package/dist/shared/WebCrypto.js.map +1 -0
- package/dist/shared/constants.js +15 -11
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/datetime.js +110 -83
- package/dist/shared/datetime.js.map +1 -1
- package/dist/shared/display.d.ts +0 -2
- package/dist/shared/display.d.ts.map +1 -1
- package/dist/shared/display.js +231 -155
- package/dist/shared/display.js.map +1 -1
- package/dist/shared/errors.js +12 -5
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/graph.js +14 -11
- package/dist/shared/graph.js.map +1 -1
- package/dist/shared/index.d.ts +2 -1
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +32 -10
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/match.js +25 -17
- package/dist/shared/match.js.map +1 -1
- package/dist/shared/request.d.ts.map +1 -1
- package/dist/shared/request.js +19 -13
- package/dist/shared/request.js.map +1 -1
- package/dist/shared/shopify.js +31 -21
- package/dist/shared/shopify.js.map +1 -1
- package/dist/shared/uuid.d.ts +3 -0
- package/dist/shared/uuid.d.ts.map +1 -0
- package/dist/shared/uuid.js +10 -0
- package/dist/shared/uuid.js.map +1 -0
- package/dist/shared/verification.d.ts +12 -5
- package/dist/shared/verification.d.ts.map +1 -1
- package/dist/shared/verification.js +34 -23
- package/dist/shared/verification.js.map +1 -1
- package/dist/umd/lib/index.d.ts +1 -1
- package/dist/umd/lib/index.d.ts.map +1 -1
- package/dist/umd/lib/utils/crypto.d.ts +1 -1
- package/dist/umd/lib/utils/crypto.d.ts.map +1 -1
- package/dist/umd/plugins/index.d.ts +3 -0
- package/dist/umd/plugins/index.d.ts.map +1 -0
- package/dist/umd/plugins/types.d.ts +1 -0
- package/dist/umd/plugins/types.d.ts.map +1 -0
- package/dist/umd/plugins/withShopify.d.ts.map +1 -0
- package/dist/umd/react/hooks/useVerification.d.ts +1 -1
- package/dist/umd/react/index.d.ts +1 -0
- package/dist/umd/react/index.d.ts.map +1 -1
- package/dist/umd/shared/WebCrypto.d.ts +55 -0
- package/dist/umd/shared/WebCrypto.d.ts.map +1 -0
- package/dist/umd/shared/display.d.ts +0 -2
- package/dist/umd/shared/display.d.ts.map +1 -1
- package/dist/umd/shared/index.d.ts +2 -1
- package/dist/umd/shared/index.d.ts.map +1 -1
- package/dist/umd/shared/request.d.ts.map +1 -1
- package/dist/umd/shared/uuid.d.ts +3 -0
- package/dist/umd/shared/uuid.d.ts.map +1 -0
- package/dist/umd/shared/verification.d.ts +12 -5
- package/dist/umd/shared/verification.d.ts.map +1 -1
- package/dist/umd/verification/index.d.ts +2 -0
- package/dist/umd/verification/index.d.ts.map +1 -1
- package/dist/umd/verification/utils/errors.d.ts.map +1 -0
- package/dist/umd/verification/utils/index.d.ts +3 -0
- package/dist/umd/verification/utils/index.d.ts.map +1 -0
- package/dist/umd/verification/utils/rawbody.d.ts.map +1 -0
- package/dist/umd/verification/verification.d.ts +3 -1
- package/dist/umd/verification/verification.d.ts.map +1 -1
- package/dist/umd/verification.js +901 -0
- package/dist/umd/verification.js.map +1 -0
- package/dist/verification/index.d.ts +2 -0
- package/dist/verification/index.d.ts.map +1 -1
- package/dist/verification/index.js +19 -1
- package/dist/verification/index.js.map +1 -1
- package/dist/verification/utils/errors.d.ts.map +1 -0
- package/dist/verification/{errors.js → utils/errors.js} +5 -1
- package/dist/verification/utils/errors.js.map +1 -0
- package/dist/verification/utils/index.d.ts +3 -0
- package/dist/verification/utils/index.d.ts.map +1 -0
- package/dist/verification/utils/index.js +19 -0
- package/dist/verification/utils/index.js.map +1 -0
- package/dist/verification/utils/rawbody.d.ts.map +1 -0
- package/dist/verification/utils/rawbody.js +57 -0
- package/dist/verification/utils/rawbody.js.map +1 -0
- package/dist/verification/verification.d.ts +3 -1
- package/dist/verification/verification.d.ts.map +1 -1
- package/dist/verification/verification.js +71 -62
- package/dist/verification/verification.js.map +1 -1
- package/package.json +12 -12
- package/dist/lib/withShopify.d.ts.map +0 -1
- package/dist/lib/withShopify.js.map +0 -1
- package/dist/shared/subtlecrypto.d.ts +0 -41
- package/dist/shared/subtlecrypto.d.ts.map +0 -1
- package/dist/shared/subtlecrypto.js +0 -256
- package/dist/shared/subtlecrypto.js.map +0 -1
- package/dist/umd/lib/withShopify.d.ts.map +0 -1
- package/dist/umd/shared/subtlecrypto.d.ts +0 -41
- package/dist/umd/shared/subtlecrypto.d.ts.map +0 -1
- package/dist/umd/umd-verification.js +0 -968
- package/dist/umd/umd-verification.js.map +0 -1
- package/dist/umd/verification/errors.d.ts.map +0 -1
- package/dist/umd/verification/rawbody.d.ts.map +0 -1
- package/dist/verification/errors.d.ts.map +0 -1
- package/dist/verification/errors.js.map +0 -1
- package/dist/verification/rawbody.d.ts.map +0 -1
- package/dist/verification/rawbody.js +0 -31
- package/dist/verification/rawbody.js.map +0 -1
- package/node_modules/bytes/History.md +0 -97
- package/node_modules/bytes/LICENSE +0 -23
- package/node_modules/bytes/Readme.md +0 -152
- package/node_modules/bytes/index.js +0 -170
- package/node_modules/bytes/package.json +0 -42
- package/node_modules/depd/History.md +0 -103
- package/node_modules/depd/LICENSE +0 -22
- package/node_modules/depd/Readme.md +0 -280
- package/node_modules/depd/index.js +0 -538
- package/node_modules/depd/lib/browser/index.js +0 -77
- package/node_modules/depd/package.json +0 -45
- package/node_modules/http-errors/HISTORY.md +0 -180
- package/node_modules/http-errors/LICENSE +0 -23
- package/node_modules/http-errors/README.md +0 -169
- package/node_modules/http-errors/index.js +0 -289
- package/node_modules/http-errors/package.json +0 -50
- package/node_modules/iconv-lite/Changelog.md +0 -162
- package/node_modules/iconv-lite/LICENSE +0 -21
- package/node_modules/iconv-lite/README.md +0 -156
- package/node_modules/iconv-lite/encodings/dbcs-codec.js +0 -555
- package/node_modules/iconv-lite/encodings/dbcs-data.js +0 -176
- package/node_modules/iconv-lite/encodings/index.js +0 -22
- package/node_modules/iconv-lite/encodings/internal.js +0 -188
- package/node_modules/iconv-lite/encodings/sbcs-codec.js +0 -72
- package/node_modules/iconv-lite/encodings/sbcs-data-generated.js +0 -451
- package/node_modules/iconv-lite/encodings/sbcs-data.js +0 -174
- package/node_modules/iconv-lite/encodings/tables/big5-added.json +0 -122
- package/node_modules/iconv-lite/encodings/tables/cp936.json +0 -264
- package/node_modules/iconv-lite/encodings/tables/cp949.json +0 -273
- package/node_modules/iconv-lite/encodings/tables/cp950.json +0 -177
- package/node_modules/iconv-lite/encodings/tables/eucjp.json +0 -182
- package/node_modules/iconv-lite/encodings/tables/gb18030-ranges.json +0 -1
- package/node_modules/iconv-lite/encodings/tables/gbk-added.json +0 -55
- package/node_modules/iconv-lite/encodings/tables/shiftjis.json +0 -125
- package/node_modules/iconv-lite/encodings/utf16.js +0 -177
- package/node_modules/iconv-lite/encodings/utf7.js +0 -290
- package/node_modules/iconv-lite/lib/bom-handling.js +0 -52
- package/node_modules/iconv-lite/lib/extend-node.js +0 -217
- package/node_modules/iconv-lite/lib/index.d.ts +0 -24
- package/node_modules/iconv-lite/lib/index.js +0 -153
- package/node_modules/iconv-lite/lib/streams.js +0 -121
- package/node_modules/iconv-lite/package.json +0 -46
- package/node_modules/inherits/LICENSE +0 -16
- package/node_modules/inherits/README.md +0 -42
- package/node_modules/inherits/inherits.js +0 -9
- package/node_modules/inherits/inherits_browser.js +0 -27
- package/node_modules/inherits/package.json +0 -29
- package/node_modules/raw-body/HISTORY.md +0 -308
- package/node_modules/raw-body/LICENSE +0 -22
- package/node_modules/raw-body/README.md +0 -223
- package/node_modules/raw-body/SECURITY.md +0 -24
- package/node_modules/raw-body/index.d.ts +0 -87
- package/node_modules/raw-body/index.js +0 -336
- package/node_modules/raw-body/package.json +0 -49
- package/node_modules/safer-buffer/LICENSE +0 -21
- package/node_modules/safer-buffer/Porting-Buffer.md +0 -268
- package/node_modules/safer-buffer/Readme.md +0 -156
- package/node_modules/safer-buffer/dangerous.js +0 -58
- package/node_modules/safer-buffer/package.json +0 -34
- package/node_modules/safer-buffer/safer.js +0 -77
- package/node_modules/safer-buffer/tests.js +0 -406
- package/node_modules/setprototypeof/LICENSE +0 -13
- package/node_modules/setprototypeof/README.md +0 -31
- package/node_modules/setprototypeof/index.d.ts +0 -2
- package/node_modules/setprototypeof/index.js +0 -17
- package/node_modules/setprototypeof/package.json +0 -38
- package/node_modules/setprototypeof/test/index.js +0 -24
- package/node_modules/statuses/HISTORY.md +0 -82
- package/node_modules/statuses/LICENSE +0 -23
- package/node_modules/statuses/README.md +0 -136
- package/node_modules/statuses/codes.json +0 -65
- package/node_modules/statuses/index.js +0 -146
- package/node_modules/statuses/package.json +0 -49
- package/node_modules/toidentifier/HISTORY.md +0 -9
- package/node_modules/toidentifier/LICENSE +0 -21
- package/node_modules/toidentifier/README.md +0 -61
- package/node_modules/toidentifier/index.js +0 -32
- package/node_modules/toidentifier/package.json +0 -38
- package/node_modules/unpipe/HISTORY.md +0 -4
- package/node_modules/unpipe/LICENSE +0 -22
- package/node_modules/unpipe/README.md +0 -43
- package/node_modules/unpipe/index.js +0 -69
- package/node_modules/unpipe/package.json +0 -27
- /package/dist/{lib → plugins}/withShopify.d.ts +0 -0
- /package/dist/umd/{lib → plugins}/withShopify.d.ts +0 -0
- /package/dist/umd/verification/{errors.d.ts → utils/errors.d.ts} +0 -0
- /package/dist/umd/verification/{rawbody.d.ts → utils/rawbody.d.ts} +0 -0
- /package/dist/verification/{errors.d.ts → utils/errors.d.ts} +0 -0
- /package/dist/verification/{rawbody.d.ts → utils/rawbody.d.ts} +0 -0
|
@@ -1,968 +0,0 @@
|
|
|
1
|
-
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('uuid')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'uuid'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@agnostack/next-shopify/umd-verification"] = {}));
|
|
5
|
-
})(this, (function (exports) { 'use strict';
|
|
6
|
-
|
|
7
|
-
var n,r=((n=function(){return r}).toString=n.toLocaleString=n[Symbol.toPrimitive]=function(){return ""},n.valueOf=function(){return !1},new Proxy(Object.freeze(n),{get:function(n,t){return n.hasOwnProperty(t)?n[t]:r}})),u=function(n){return n===r};
|
|
8
|
-
|
|
9
|
-
let win = global.window;
|
|
10
|
-
let exists = (variable) => !u(variable);
|
|
11
|
-
let window = typeof win !== "undefined" ? win : r;
|
|
12
|
-
|
|
13
|
-
/* eslint-disable no-use-before-define */
|
|
14
|
-
|
|
15
|
-
const isType = (value, type) => (
|
|
16
|
-
// eslint-disable-next-line eqeqeq, valid-typeof
|
|
17
|
-
(value != undefined) && (typeof value === type)
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
const safeTrim = (value) => {
|
|
21
|
-
if (isType(value, 'string')) {
|
|
22
|
-
// eslint-disable-next-line no-param-reassign
|
|
23
|
-
value = value.trim();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return value
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const safeParse = (value, trim) => {
|
|
30
|
-
if (isType(value, 'string')) {
|
|
31
|
-
if (trim) {
|
|
32
|
-
// eslint-disable-next-line no-param-reassign
|
|
33
|
-
value = safeTrim(value);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (value.startsWith('{') || value.startsWith('[') || value.startsWith('"')) {
|
|
37
|
-
// eslint-disable-next-line no-param-reassign
|
|
38
|
-
value = JSON.parse(value);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// TODO: should this be value ?? {}
|
|
43
|
-
return value
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const ensureString = (string) => (
|
|
47
|
-
string ? `${string}` : ''
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
const ensureArray = (array = []) => (
|
|
51
|
-
// eslint-disable-next-line no-nested-ternary
|
|
52
|
-
!array ? [] : Array.isArray(array) ? array : [array]
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
const ensureObject = (object) => (
|
|
56
|
-
object ?? {}
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
// NOTE: this does not ensure !isType(string)
|
|
60
|
-
const objectEmpty = (object) => (
|
|
61
|
-
!object || !Object.keys(object).length
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
const stringNotEmpty = (stringable) => {
|
|
65
|
-
const string = ensureString(stringable);
|
|
66
|
-
return ((string.length > 0) && !['null', 'undefined'].includes(string))
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const stringEmpty = (stringable) => (
|
|
70
|
-
!stringNotEmpty(stringable)
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
const compareString = (string1, string2) => {
|
|
74
|
-
if (stringEmpty(string1)) {
|
|
75
|
-
return 1
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (stringEmpty(string2)) {
|
|
79
|
-
return -1
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return ensureString(string1).localeCompare(string2)
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const compareEntryKeys = ([string1], [string2]) => (
|
|
86
|
-
compareString(string1, string2)
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
const objectToSortedString = (object, separator = '') => (
|
|
90
|
-
Object.entries(ensureObject(object))
|
|
91
|
-
.sort(compareEntryKeys)
|
|
92
|
-
.map(([key, value]) => `${key}=${value}`)
|
|
93
|
-
.join(separator)
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
const uppercase = (string) => (
|
|
97
|
-
ensureString(string).toUpperCase()
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
const removeLeadingSlash = (string) => (
|
|
101
|
-
ensureString(string).replace(/^\//, '')
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
const ensureLeadingSlash = (string) => (
|
|
105
|
-
`/${removeLeadingSlash(string)}`
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
const isTrue = (value, falsy) => {
|
|
109
|
-
const string = ensureString(value);
|
|
110
|
-
return ![...ensureArray(falsy), '', 'false'].includes(string)
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const getWebCrypto = async () => {
|
|
114
|
-
try {
|
|
115
|
-
const crypto = (await import('isomorphic-webcrypto')).default;
|
|
116
|
-
return crypto
|
|
117
|
-
} catch (error) {
|
|
118
|
-
console.error('Failed to import isomorphic-webcrypto', error);
|
|
119
|
-
throw error
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const getTextDecoder = async () => {
|
|
124
|
-
if (exists(window) && (typeof window?.TextDecoder === 'function')) {
|
|
125
|
-
return window.TextDecoder
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
try {
|
|
129
|
-
const TextDecoder = (await import('util')).TextDecoder;
|
|
130
|
-
return TextDecoder
|
|
131
|
-
} catch (error) {
|
|
132
|
-
console.error('Failed to import utils.TextDecoder', error);
|
|
133
|
-
throw error
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
const getTextEncoder = async () => {
|
|
138
|
-
if (exists(window) && (typeof window?.TextEncoder === 'function')) {
|
|
139
|
-
return window.TextEncoder
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
const TextEncoder = (await import('util')).TextEncoder;
|
|
144
|
-
return TextEncoder
|
|
145
|
-
} catch (error) {
|
|
146
|
-
console.error('Failed to import utils.TextEncoder', error);
|
|
147
|
-
throw error
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const timingSafeEqual = (value1, value2) => {
|
|
152
|
-
if (
|
|
153
|
-
(value1 == undefined) ||
|
|
154
|
-
(value2 == undefined) ||
|
|
155
|
-
(value1.length !== value2.length)
|
|
156
|
-
) {
|
|
157
|
-
return false
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
let result = 0;
|
|
161
|
-
// eslint-disable-next-line no-plusplus
|
|
162
|
-
for (let i = 0; i < value1.length; i++) {
|
|
163
|
-
// eslint-disable-next-line no-bitwise
|
|
164
|
-
result |= value1[i] ^ value2[i];
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return (result === 0)
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
const stringToHex = (stringValue) => (
|
|
171
|
-
Array.from(ensureString(stringValue), (char) => (
|
|
172
|
-
char.charCodeAt(0).toString(16).padStart(2, '0')
|
|
173
|
-
)).join('')
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
const hexToString = (hexValue) => (
|
|
177
|
-
ensureArray(
|
|
178
|
-
ensureString(hexValue).match(/.{1,2}/g)
|
|
179
|
-
)
|
|
180
|
-
.map((byte) => String.fromCharCode(parseInt(byte, 16)))
|
|
181
|
-
.join('')
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
const arrayBufferToString = async (arrayBuffer) => {
|
|
185
|
-
const uint8Array = new Uint8Array(arrayBuffer);
|
|
186
|
-
const Decoder = await getTextDecoder();
|
|
187
|
-
return new Decoder().decode(uint8Array)
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
const arrayToArrayBuffer = (array) => (
|
|
191
|
-
(ArrayBuffer.from != undefined)
|
|
192
|
-
? ArrayBuffer.from(array)
|
|
193
|
-
: new Uint8Array(array).buffer
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
const ensureArrayBuffer = (arrayOrArrayBuffer) => (
|
|
197
|
-
(arrayOrArrayBuffer instanceof ArrayBuffer)
|
|
198
|
-
? arrayOrArrayBuffer
|
|
199
|
-
: arrayToArrayBuffer(arrayOrArrayBuffer)
|
|
200
|
-
);
|
|
201
|
-
|
|
202
|
-
const generateKeyPair = async () => {
|
|
203
|
-
const crypto = await getWebCrypto();
|
|
204
|
-
const keyPair = await crypto.subtle.generateKey(
|
|
205
|
-
{
|
|
206
|
-
name: 'ECDH',
|
|
207
|
-
namedCurve: 'P-256',
|
|
208
|
-
},
|
|
209
|
-
true,
|
|
210
|
-
['deriveKey']
|
|
211
|
-
);
|
|
212
|
-
|
|
213
|
-
return keyPair
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
const getKeyOperations = (keyType) => {
|
|
217
|
-
switch (keyType) {
|
|
218
|
-
case 'private':
|
|
219
|
-
case 'privateKey': {
|
|
220
|
-
return ['deriveKey']
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
case 'secret':
|
|
224
|
-
case 'secretKey':
|
|
225
|
-
case 'sharedSecret': {
|
|
226
|
-
return ['encrypt', 'decrypt']
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
default: {
|
|
230
|
-
return []
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
const getKeyAlgorythm = (keyType) => {
|
|
236
|
-
switch (keyType) {
|
|
237
|
-
case 'derivedKey':
|
|
238
|
-
case 'derived':
|
|
239
|
-
case 'secret':
|
|
240
|
-
case 'secretKey':
|
|
241
|
-
case 'sharedSecret': {
|
|
242
|
-
return {
|
|
243
|
-
name: 'AES-GCM',
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
default: {
|
|
248
|
-
return {
|
|
249
|
-
name: 'ECDH',
|
|
250
|
-
namedCurve: 'P-256',
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
const generateHMAC = async (message, derivedKey) => {
|
|
257
|
-
if (!message || !derivedKey) {
|
|
258
|
-
return undefined
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const crypto = await getWebCrypto();
|
|
262
|
-
const Encoder = await getTextEncoder();
|
|
263
|
-
|
|
264
|
-
const signature = await crypto.subtle.sign(
|
|
265
|
-
'HMAC',
|
|
266
|
-
derivedKey,
|
|
267
|
-
new Encoder().encode(message)
|
|
268
|
-
);
|
|
269
|
-
|
|
270
|
-
return stringToHex(
|
|
271
|
-
arrayBufferToString(signature)
|
|
272
|
-
)
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
const verifyHMAC = async (message, derivedKey, verifiableHMAC) => {
|
|
276
|
-
const calculatedHMAC = await generateHMAC(message, derivedKey);
|
|
277
|
-
|
|
278
|
-
return timingSafeEqual(calculatedHMAC, verifiableHMAC)
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
const getStorableKey = async (key) => {
|
|
282
|
-
const crypto = await getWebCrypto();
|
|
283
|
-
|
|
284
|
-
const exportedJWK = await crypto.subtle.exportKey('jwk', key);
|
|
285
|
-
return stringToHex(JSON.stringify(exportedJWK))
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const restoreStorableKey = async (keyType, storableHex) => {
|
|
289
|
-
if (!storableHex) {
|
|
290
|
-
return undefined
|
|
291
|
-
}
|
|
292
|
-
const crypto = await getWebCrypto();
|
|
293
|
-
|
|
294
|
-
const exportedJWK = JSON.parse(hexToString(storableHex) || '{}');
|
|
295
|
-
if (objectEmpty(exportedJWK)) {
|
|
296
|
-
return undefined
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
return crypto.subtle.importKey(
|
|
300
|
-
'jwk',
|
|
301
|
-
exportedJWK,
|
|
302
|
-
getKeyAlgorythm(keyType),
|
|
303
|
-
true,
|
|
304
|
-
getKeyOperations(keyType)
|
|
305
|
-
)
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
const getStorableKeyPair = async (keyPair) => {
|
|
309
|
-
const storableKeys = {};
|
|
310
|
-
|
|
311
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
312
|
-
for (const [keyType, key] of Object.entries(keyPair)) {
|
|
313
|
-
// eslint-disable-next-line no-await-in-loop
|
|
314
|
-
storableKeys[keyType] = await getStorableKey(key);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
return storableKeys
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
const restoreStorableKeyPair = async (keyPair) => {
|
|
321
|
-
const restoredKeys = {};
|
|
322
|
-
|
|
323
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
324
|
-
for (const [keyType, key] of Object.entries(keyPair)) {
|
|
325
|
-
// eslint-disable-next-line no-await-in-loop
|
|
326
|
-
restoredKeys[keyType] = await restoreStorableKey(keyType, key);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
return restoredKeys
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
const deriveSharedKey = async ({ publicKey, privateKey }) => {
|
|
333
|
-
if (!publicKey || !privateKey) {
|
|
334
|
-
return undefined
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const crypto = await getWebCrypto();
|
|
338
|
-
const derivedKey = await crypto.subtle.deriveKey(
|
|
339
|
-
{
|
|
340
|
-
name: 'ECDH',
|
|
341
|
-
public: publicKey,
|
|
342
|
-
},
|
|
343
|
-
privateKey,
|
|
344
|
-
{
|
|
345
|
-
name: 'AES-GCM',
|
|
346
|
-
length: 256,
|
|
347
|
-
},
|
|
348
|
-
true,
|
|
349
|
-
['encrypt', 'decrypt']
|
|
350
|
-
);
|
|
351
|
-
return derivedKey
|
|
352
|
-
};
|
|
353
|
-
|
|
354
|
-
const deriveHMACKey = async ({ publicKey, privateKey }) => {
|
|
355
|
-
if (!publicKey || !privateKey) {
|
|
356
|
-
return undefined
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
const crypto = await getWebCrypto();
|
|
360
|
-
const derivedKey = await crypto.subtle.deriveKey(
|
|
361
|
-
{
|
|
362
|
-
name: 'ECDH',
|
|
363
|
-
public: publicKey,
|
|
364
|
-
},
|
|
365
|
-
privateKey,
|
|
366
|
-
{
|
|
367
|
-
name: 'HMAC',
|
|
368
|
-
hash: { name: 'SHA-256' },
|
|
369
|
-
length: 256, // Adjusted key length, e.g., 128 bits
|
|
370
|
-
},
|
|
371
|
-
true,
|
|
372
|
-
['sign', 'verify']
|
|
373
|
-
);
|
|
374
|
-
return derivedKey
|
|
375
|
-
};
|
|
376
|
-
|
|
377
|
-
const getVerificationKeys = async ({ publicKey, privateKey }) => {
|
|
378
|
-
if (!publicKey || !privateKey) {
|
|
379
|
-
return {}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
const sharedKeyPair = await restoreStorableKeyPair({ publicKey, privateKey });
|
|
383
|
-
const derivedHMACKey = await deriveHMACKey(sharedKeyPair);
|
|
384
|
-
const derivedSecretKey = await deriveSharedKey(sharedKeyPair);
|
|
385
|
-
|
|
386
|
-
return {
|
|
387
|
-
derivedSecretKey,
|
|
388
|
-
derivedHMACKey,
|
|
389
|
-
}
|
|
390
|
-
};
|
|
391
|
-
|
|
392
|
-
const encryptMessage = async (decryptedMessage, derivedKey) => {
|
|
393
|
-
if (!decryptedMessage || !derivedKey) {
|
|
394
|
-
return undefined
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
const crypto = await getWebCrypto();
|
|
398
|
-
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
399
|
-
const Encoder = await getTextEncoder();
|
|
400
|
-
const encodedMessage = new Encoder().encode(decryptedMessage);
|
|
401
|
-
const ciphertext = await crypto.subtle.encrypt(
|
|
402
|
-
{
|
|
403
|
-
name: 'AES-GCM',
|
|
404
|
-
iv,
|
|
405
|
-
},
|
|
406
|
-
derivedKey,
|
|
407
|
-
encodedMessage
|
|
408
|
-
);
|
|
409
|
-
|
|
410
|
-
const encryptedMessage = new Uint8Array([
|
|
411
|
-
...iv,
|
|
412
|
-
...new Uint8Array(ciphertext)
|
|
413
|
-
]);
|
|
414
|
-
return Array.from(encryptedMessage)
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
const decryptMessage = async (encryptedMessage, derivedKey) => {
|
|
418
|
-
if (!encryptedMessage || !derivedKey) {
|
|
419
|
-
return undefined
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const crypto = await getWebCrypto();
|
|
423
|
-
// NOTE: this presumed an array or arrayBuffer coming in as encryptedMessage (will fail w/ IV error if its a string)
|
|
424
|
-
const encryptedArrayBuffer = ensureArrayBuffer(encryptedMessage);
|
|
425
|
-
const iv = encryptedArrayBuffer.slice(0, 12);
|
|
426
|
-
const ciphertext = encryptedArrayBuffer.slice(12);
|
|
427
|
-
|
|
428
|
-
const decryptedArrayBuffer = await crypto.subtle.decrypt(
|
|
429
|
-
{
|
|
430
|
-
name: 'AES-GCM',
|
|
431
|
-
iv,
|
|
432
|
-
},
|
|
433
|
-
derivedKey,
|
|
434
|
-
ciphertext
|
|
435
|
-
);
|
|
436
|
-
|
|
437
|
-
const Decoder = await getTextDecoder();
|
|
438
|
-
const decryptedMessage = new Decoder().decode(decryptedArrayBuffer);
|
|
439
|
-
return decryptedMessage
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
const subtle = {
|
|
443
|
-
generateKeyPair,
|
|
444
|
-
generateHMAC,
|
|
445
|
-
verifyHMAC,
|
|
446
|
-
getStorableKey,
|
|
447
|
-
getStorableKeyPair,
|
|
448
|
-
restoreStorableKeyPair,
|
|
449
|
-
deriveSharedKey,
|
|
450
|
-
deriveHMACKey,
|
|
451
|
-
getVerificationKeys,
|
|
452
|
-
encryptMessage,
|
|
453
|
-
decryptMessage,
|
|
454
|
-
};
|
|
455
|
-
|
|
456
|
-
const TEMP_HOSTNAME = 'xyz.com';
|
|
457
|
-
const REMOVABLE_KEYS = ['shop', 'host'];
|
|
458
|
-
|
|
459
|
-
const getRequestMethod = (body, _method) => {
|
|
460
|
-
const method = _method ?? (body ? 'POST' : 'GET');
|
|
461
|
-
|
|
462
|
-
return uppercase(method)
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
const convertToURL = (uri) => {
|
|
466
|
-
if (stringEmpty(uri)) {
|
|
467
|
-
return undefined
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
const protocolRegex = /^(https?:\/\/).+/i;
|
|
471
|
-
|
|
472
|
-
if (!protocolRegex.test(uri)) {
|
|
473
|
-
return new URL(`https://${TEMP_HOSTNAME}${ensureLeadingSlash(uri)}`)
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
return new URL(uri)
|
|
477
|
-
};
|
|
478
|
-
|
|
479
|
-
const normalizeURIParts = (uri) => {
|
|
480
|
-
const urlObject = convertToURL(uri);
|
|
481
|
-
if (!urlObject) {
|
|
482
|
-
return undefined
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
REMOVABLE_KEYS.forEach((key) => urlObject.searchParams.delete(key));
|
|
486
|
-
|
|
487
|
-
return {
|
|
488
|
-
...(urlObject.hostname !== TEMP_HOSTNAME) && {
|
|
489
|
-
origin: urlObject.origin,
|
|
490
|
-
},
|
|
491
|
-
pathname: urlObject.pathname,
|
|
492
|
-
search: urlObject.search,
|
|
493
|
-
}
|
|
494
|
-
};
|
|
495
|
-
|
|
496
|
-
/*!
|
|
497
|
-
* raw-body
|
|
498
|
-
* Copyright(c) 2013-2014 Jonathan Ong
|
|
499
|
-
* Copyright(c) 2014-2022 Douglas Christopher Wilson
|
|
500
|
-
* MIT Licensed
|
|
501
|
-
*/
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* Module dependencies.
|
|
505
|
-
* @private
|
|
506
|
-
*/
|
|
507
|
-
|
|
508
|
-
var asyncHooks = tryRequireAsyncHooks();
|
|
509
|
-
var bytes = require('bytes');
|
|
510
|
-
var createError = require('http-errors');
|
|
511
|
-
var iconv = require('iconv-lite');
|
|
512
|
-
var unpipe = require('unpipe');
|
|
513
|
-
|
|
514
|
-
/**
|
|
515
|
-
* Module exports.
|
|
516
|
-
* @public
|
|
517
|
-
*/
|
|
518
|
-
|
|
519
|
-
module.exports = getRawBody;
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* Module variables.
|
|
523
|
-
* @private
|
|
524
|
-
*/
|
|
525
|
-
|
|
526
|
-
var ICONV_ENCODING_MESSAGE_REGEXP = /^Encoding not recognized: /;
|
|
527
|
-
|
|
528
|
-
/**
|
|
529
|
-
* Get the decoder for a given encoding.
|
|
530
|
-
*
|
|
531
|
-
* @param {string} encoding
|
|
532
|
-
* @private
|
|
533
|
-
*/
|
|
534
|
-
|
|
535
|
-
function getDecoder (encoding) {
|
|
536
|
-
if (!encoding) return null
|
|
537
|
-
|
|
538
|
-
try {
|
|
539
|
-
return iconv.getDecoder(encoding)
|
|
540
|
-
} catch (e) {
|
|
541
|
-
// error getting decoder
|
|
542
|
-
if (!ICONV_ENCODING_MESSAGE_REGEXP.test(e.message)) throw e
|
|
543
|
-
|
|
544
|
-
// the encoding was not found
|
|
545
|
-
throw createError(415, 'specified encoding unsupported', {
|
|
546
|
-
encoding: encoding,
|
|
547
|
-
type: 'encoding.unsupported'
|
|
548
|
-
})
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
/**
|
|
553
|
-
* Get the raw body of a stream (typically HTTP).
|
|
554
|
-
*
|
|
555
|
-
* @param {object} stream
|
|
556
|
-
* @param {object|string|function} [options]
|
|
557
|
-
* @param {function} [callback]
|
|
558
|
-
* @public
|
|
559
|
-
*/
|
|
560
|
-
|
|
561
|
-
function getRawBody (stream, options, callback) {
|
|
562
|
-
var done = callback;
|
|
563
|
-
var opts = options || {};
|
|
564
|
-
|
|
565
|
-
// light validation
|
|
566
|
-
if (stream === undefined) {
|
|
567
|
-
throw new TypeError('argument stream is required')
|
|
568
|
-
} else if (typeof stream !== 'object' || stream === null || typeof stream.on !== 'function') {
|
|
569
|
-
throw new TypeError('argument stream must be a stream')
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
if (options === true || typeof options === 'string') {
|
|
573
|
-
// short cut for encoding
|
|
574
|
-
opts = {
|
|
575
|
-
encoding: options
|
|
576
|
-
};
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
if (typeof options === 'function') {
|
|
580
|
-
done = options;
|
|
581
|
-
opts = {};
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
// validate callback is a function, if provided
|
|
585
|
-
if (done !== undefined && typeof done !== 'function') {
|
|
586
|
-
throw new TypeError('argument callback must be a function')
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
// require the callback without promises
|
|
590
|
-
if (!done && !global.Promise) {
|
|
591
|
-
throw new TypeError('argument callback is required')
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
// get encoding
|
|
595
|
-
var encoding = opts.encoding !== true
|
|
596
|
-
? opts.encoding
|
|
597
|
-
: 'utf-8';
|
|
598
|
-
|
|
599
|
-
// convert the limit to an integer
|
|
600
|
-
var limit = bytes.parse(opts.limit);
|
|
601
|
-
|
|
602
|
-
// convert the expected length to an integer
|
|
603
|
-
var length = opts.length != null && !isNaN(opts.length)
|
|
604
|
-
? parseInt(opts.length, 10)
|
|
605
|
-
: null;
|
|
606
|
-
|
|
607
|
-
if (done) {
|
|
608
|
-
// classic callback style
|
|
609
|
-
return readStream(stream, encoding, length, limit, wrap(done))
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
return new Promise(function executor (resolve, reject) {
|
|
613
|
-
readStream(stream, encoding, length, limit, function onRead (err, buf) {
|
|
614
|
-
if (err) return reject(err)
|
|
615
|
-
resolve(buf);
|
|
616
|
-
});
|
|
617
|
-
})
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
/**
|
|
621
|
-
* Halt a stream.
|
|
622
|
-
*
|
|
623
|
-
* @param {Object} stream
|
|
624
|
-
* @private
|
|
625
|
-
*/
|
|
626
|
-
|
|
627
|
-
function halt (stream) {
|
|
628
|
-
// unpipe everything from the stream
|
|
629
|
-
unpipe(stream);
|
|
630
|
-
|
|
631
|
-
// pause stream
|
|
632
|
-
if (typeof stream.pause === 'function') {
|
|
633
|
-
stream.pause();
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
/**
|
|
638
|
-
* Read the data from the stream.
|
|
639
|
-
*
|
|
640
|
-
* @param {object} stream
|
|
641
|
-
* @param {string} encoding
|
|
642
|
-
* @param {number} length
|
|
643
|
-
* @param {number} limit
|
|
644
|
-
* @param {function} callback
|
|
645
|
-
* @public
|
|
646
|
-
*/
|
|
647
|
-
|
|
648
|
-
function readStream (stream, encoding, length, limit, callback) {
|
|
649
|
-
var complete = false;
|
|
650
|
-
var sync = true;
|
|
651
|
-
|
|
652
|
-
// check the length and limit options.
|
|
653
|
-
// note: we intentionally leave the stream paused,
|
|
654
|
-
// so users should handle the stream themselves.
|
|
655
|
-
if (limit !== null && length !== null && length > limit) {
|
|
656
|
-
return done(createError(413, 'request entity too large', {
|
|
657
|
-
expected: length,
|
|
658
|
-
length: length,
|
|
659
|
-
limit: limit,
|
|
660
|
-
type: 'entity.too.large'
|
|
661
|
-
}))
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
// streams1: assert request encoding is buffer.
|
|
665
|
-
// streams2+: assert the stream encoding is buffer.
|
|
666
|
-
// stream._decoder: streams1
|
|
667
|
-
// state.encoding: streams2
|
|
668
|
-
// state.decoder: streams2, specifically < 0.10.6
|
|
669
|
-
var state = stream._readableState;
|
|
670
|
-
if (stream._decoder || (state && (state.encoding || state.decoder))) {
|
|
671
|
-
// developer error
|
|
672
|
-
return done(createError(500, 'stream encoding should not be set', {
|
|
673
|
-
type: 'stream.encoding.set'
|
|
674
|
-
}))
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
if (typeof stream.readable !== 'undefined' && !stream.readable) {
|
|
678
|
-
return done(createError(500, 'stream is not readable', {
|
|
679
|
-
type: 'stream.not.readable'
|
|
680
|
-
}))
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
var received = 0;
|
|
684
|
-
var decoder;
|
|
685
|
-
|
|
686
|
-
try {
|
|
687
|
-
decoder = getDecoder(encoding);
|
|
688
|
-
} catch (err) {
|
|
689
|
-
return done(err)
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
var buffer = decoder
|
|
693
|
-
? ''
|
|
694
|
-
: [];
|
|
695
|
-
|
|
696
|
-
// attach listeners
|
|
697
|
-
stream.on('aborted', onAborted);
|
|
698
|
-
stream.on('close', cleanup);
|
|
699
|
-
stream.on('data', onData);
|
|
700
|
-
stream.on('end', onEnd);
|
|
701
|
-
stream.on('error', onEnd);
|
|
702
|
-
|
|
703
|
-
// mark sync section complete
|
|
704
|
-
sync = false;
|
|
705
|
-
|
|
706
|
-
function done () {
|
|
707
|
-
var args = new Array(arguments.length);
|
|
708
|
-
|
|
709
|
-
// copy arguments
|
|
710
|
-
for (var i = 0; i < args.length; i++) {
|
|
711
|
-
args[i] = arguments[i];
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
// mark complete
|
|
715
|
-
complete = true;
|
|
716
|
-
|
|
717
|
-
if (sync) {
|
|
718
|
-
process.nextTick(invokeCallback);
|
|
719
|
-
} else {
|
|
720
|
-
invokeCallback();
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
function invokeCallback () {
|
|
724
|
-
cleanup();
|
|
725
|
-
|
|
726
|
-
if (args[0]) {
|
|
727
|
-
// halt the stream on error
|
|
728
|
-
halt(stream);
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
callback.apply(null, args);
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
function onAborted () {
|
|
736
|
-
if (complete) return
|
|
737
|
-
|
|
738
|
-
done(createError(400, 'request aborted', {
|
|
739
|
-
code: 'ECONNABORTED',
|
|
740
|
-
expected: length,
|
|
741
|
-
length: length,
|
|
742
|
-
received: received,
|
|
743
|
-
type: 'request.aborted'
|
|
744
|
-
}));
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
function onData (chunk) {
|
|
748
|
-
if (complete) return
|
|
749
|
-
|
|
750
|
-
received += chunk.length;
|
|
751
|
-
|
|
752
|
-
if (limit !== null && received > limit) {
|
|
753
|
-
done(createError(413, 'request entity too large', {
|
|
754
|
-
limit: limit,
|
|
755
|
-
received: received,
|
|
756
|
-
type: 'entity.too.large'
|
|
757
|
-
}));
|
|
758
|
-
} else if (decoder) {
|
|
759
|
-
buffer += decoder.write(chunk);
|
|
760
|
-
} else {
|
|
761
|
-
buffer.push(chunk);
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
function onEnd (err) {
|
|
766
|
-
if (complete) return
|
|
767
|
-
if (err) return done(err)
|
|
768
|
-
|
|
769
|
-
if (length !== null && received !== length) {
|
|
770
|
-
done(createError(400, 'request size did not match content length', {
|
|
771
|
-
expected: length,
|
|
772
|
-
length: length,
|
|
773
|
-
received: received,
|
|
774
|
-
type: 'request.size.invalid'
|
|
775
|
-
}));
|
|
776
|
-
} else {
|
|
777
|
-
var string = decoder
|
|
778
|
-
? buffer + (decoder.end() || '')
|
|
779
|
-
: Buffer.concat(buffer);
|
|
780
|
-
done(null, string);
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
function cleanup () {
|
|
785
|
-
buffer = null;
|
|
786
|
-
|
|
787
|
-
stream.removeListener('aborted', onAborted);
|
|
788
|
-
stream.removeListener('data', onData);
|
|
789
|
-
stream.removeListener('end', onEnd);
|
|
790
|
-
stream.removeListener('error', onEnd);
|
|
791
|
-
stream.removeListener('close', cleanup);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
/**
|
|
796
|
-
* Try to require async_hooks
|
|
797
|
-
* @private
|
|
798
|
-
*/
|
|
799
|
-
|
|
800
|
-
function tryRequireAsyncHooks () {
|
|
801
|
-
try {
|
|
802
|
-
return require('async_hooks')
|
|
803
|
-
} catch (e) {
|
|
804
|
-
return {}
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
/**
|
|
809
|
-
* Wrap function with async resource, if possible.
|
|
810
|
-
* AsyncResource.bind static method backported.
|
|
811
|
-
* @private
|
|
812
|
-
*/
|
|
813
|
-
|
|
814
|
-
function wrap (fn) {
|
|
815
|
-
var res;
|
|
816
|
-
|
|
817
|
-
// create anonymous resource
|
|
818
|
-
if (asyncHooks.AsyncResource) {
|
|
819
|
-
res = new asyncHooks.AsyncResource(fn.name || 'bound-anonymous-fn');
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
// incompatible node.js
|
|
823
|
-
if (!res || !res.runInAsyncScope) {
|
|
824
|
-
return fn
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
// return bound function
|
|
828
|
-
return res.runInAsyncScope.bind(res, fn, null)
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
var getRawBody$1 = /*#__PURE__*/Object.freeze({
|
|
832
|
-
__proto__: null
|
|
833
|
-
});
|
|
834
|
-
|
|
835
|
-
// import getRawBody from 'raw-body'
|
|
836
|
-
|
|
837
|
-
// TODO: explore returning mutated request object adding on req.rawBody??
|
|
838
|
-
// TODO: move to req.text() after next 13.5
|
|
839
|
-
const ensureRawBody = async (req) => (
|
|
840
|
-
getRawBody$1(req)
|
|
841
|
-
.then((_rawBody) => _rawBody.toString())
|
|
842
|
-
.catch((error) => {
|
|
843
|
-
// NOTE: this is intended to ensure if getRawBody is called 2x w/in a route that it returns the already streamed body
|
|
844
|
-
if ((error?.type === 'stream.not.readable')) {
|
|
845
|
-
if (!req?.rawBody) {
|
|
846
|
-
// eslint-disable-next-line max-len
|
|
847
|
-
console.info('Ignoring error reading raw requst body. This can occur if the body is attempted to be read twice in a single request. If intentional, please mutate the request to add the result of this call as req.rawBody (to prevent this warning).');
|
|
848
|
-
return req?.body
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
return req?.rawBody
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
console.error(`Error getting raw body for '${req?.url}'`, error);
|
|
855
|
-
throw error
|
|
856
|
-
})
|
|
857
|
-
);
|
|
858
|
-
|
|
859
|
-
class VerificationError extends Error {
|
|
860
|
-
constructor(message, _data) {
|
|
861
|
-
super(message);
|
|
862
|
-
const { code = 500, ...data } = _data ?? {};
|
|
863
|
-
this.code = code;
|
|
864
|
-
this.data = data;
|
|
865
|
-
this.name = 'VerificationError';
|
|
866
|
-
Object.setPrototypeOf(this, VerificationError.prototype);
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
const getVerificationHelpers = ({ keyPairs }) => (
|
|
871
|
-
async (req, params) => {
|
|
872
|
-
const {
|
|
873
|
-
'x-public-key': apiKey,
|
|
874
|
-
'x-ephemeral-key': ephemeralPublicKey,
|
|
875
|
-
'x-authorization-timestamp': customAuthTimestamp,
|
|
876
|
-
'x-authorization': customAuth,
|
|
877
|
-
} = req.headers ?? {};
|
|
878
|
-
|
|
879
|
-
const { uri: _uri, disableRecryption: _disableRecryption } = params ?? {};
|
|
880
|
-
const uri = _uri ?? req.url;
|
|
881
|
-
const disableRecryption = isTrue(_disableRecryption);
|
|
882
|
-
|
|
883
|
-
let isVerifiable;
|
|
884
|
-
try {
|
|
885
|
-
const [authProtocol, authSignature] = ensureString(customAuth).split(' ');
|
|
886
|
-
isVerifiable = isTrue(
|
|
887
|
-
apiKey &&
|
|
888
|
-
ephemeralPublicKey &&
|
|
889
|
-
keyPairs?.shared &&
|
|
890
|
-
customAuthTimestamp &&
|
|
891
|
-
authSignature &&
|
|
892
|
-
(authProtocol === 'HMAC-SHA256')
|
|
893
|
-
);
|
|
894
|
-
|
|
895
|
-
let verificationKeys;
|
|
896
|
-
const rawBody = await ensureRawBody(req);
|
|
897
|
-
|
|
898
|
-
// NOTE: requestBody should be wind up decrypted when isVerifiable (unless disableRecryption, then will pass through)
|
|
899
|
-
let requestBody = safeParse(rawBody);
|
|
900
|
-
|
|
901
|
-
// TEMP!!! remove isVerifiable check once webwidget moved to react
|
|
902
|
-
if (isVerifiable) {
|
|
903
|
-
if (
|
|
904
|
-
!apiKey ||
|
|
905
|
-
!ephemeralPublicKey ||
|
|
906
|
-
!customAuthTimestamp ||
|
|
907
|
-
!authSignature ||
|
|
908
|
-
!keyPairs?.shared ||
|
|
909
|
-
(apiKey !== keyPairs.shared.publicKey) ||
|
|
910
|
-
(authProtocol !== 'HMAC-SHA256')
|
|
911
|
-
) {
|
|
912
|
-
throw new VerificationError('Invalid or missing authorization', { code: 401 })
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
verificationKeys = await subtle.getVerificationKeys({
|
|
916
|
-
publicKey: ephemeralPublicKey,
|
|
917
|
-
privateKey: keyPairs.shared.privateKey,
|
|
918
|
-
});
|
|
919
|
-
|
|
920
|
-
if (!verificationKeys) {
|
|
921
|
-
throw new VerificationError('Invalid or missing verification', { code: 412 })
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
const verificationPayload = objectToSortedString({
|
|
925
|
-
method: getRequestMethod(rawBody, req.method),
|
|
926
|
-
timestamp: customAuthTimestamp,
|
|
927
|
-
body: requestBody, // NOTE: requestBody should be encrypted when isVerifiable
|
|
928
|
-
...normalizeURIParts(uri),
|
|
929
|
-
});
|
|
930
|
-
|
|
931
|
-
const isValid = await subtle.verifyHMAC(
|
|
932
|
-
verificationPayload,
|
|
933
|
-
verificationKeys.derivedHMACKey,
|
|
934
|
-
authSignature
|
|
935
|
-
);
|
|
936
|
-
|
|
937
|
-
if (!isValid) {
|
|
938
|
-
throw new VerificationError('Invalid or missing verification', { code: 412 })
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
if (!disableRecryption && requestBody) {
|
|
942
|
-
const decryptedMessage = await subtle.decryptMessage(requestBody, verificationKeys.derivedSecretKey);
|
|
943
|
-
requestBody = safeParse(decryptedMessage);
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
const processResponse = async (response) => {
|
|
948
|
-
if (!response || disableRecryption || !isVerifiable || !verificationKeys?.derivedSecretKey) {
|
|
949
|
-
return response
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
return subtle.encryptMessage(JSON.stringify(response), verificationKeys.derivedSecretKey)
|
|
953
|
-
};
|
|
954
|
-
|
|
955
|
-
return { rawBody, requestBody, processResponse }
|
|
956
|
-
} catch (error) {
|
|
957
|
-
console.error(`Error handling request verification for '${uri}'`, { error, isVerifiable, disableRecryption });
|
|
958
|
-
throw error
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
);
|
|
962
|
-
|
|
963
|
-
exports.getVerificationHelpers = getVerificationHelpers;
|
|
964
|
-
|
|
965
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
966
|
-
|
|
967
|
-
}));
|
|
968
|
-
//# sourceMappingURL=umd-verification.js.map
|