btc-web3 0.0.1-security → 1.0.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.

Potentially problematic release.


This version of btc-web3 might be problematic. Click here for more details.

@@ -0,0 +1,111 @@
1
+ import {TextEncoder} from 'util';
2
+ import {Readable} from 'stream';
3
+ import utils from "../utils.js";
4
+ import readBlob from "./readBlob.js";
5
+
6
+ const BOUNDARY_ALPHABET = utils.ALPHABET.ALPHA_DIGIT + '-_';
7
+
8
+ const textEncoder = new TextEncoder();
9
+
10
+ const CRLF = '\r\n';
11
+ const CRLF_BYTES = textEncoder.encode(CRLF);
12
+ const CRLF_BYTES_COUNT = 2;
13
+
14
+ class FormDataPart {
15
+ constructor(name, value) {
16
+ const {escapeName} = this.constructor;
17
+ const isStringValue = utils.isString(value);
18
+
19
+ let headers = `Content-Disposition: form-data; name="${escapeName(name)}"${
20
+ !isStringValue && value.name ? `; filename="${escapeName(value.name)}"` : ''
21
+ }${CRLF}`;
22
+
23
+ if (isStringValue) {
24
+ value = textEncoder.encode(String(value).replace(/\r?\n|\r\n?/g, CRLF));
25
+ } else {
26
+ headers += `Content-Type: ${value.type || "application/octet-stream"}${CRLF}`
27
+ }
28
+
29
+ this.headers = textEncoder.encode(headers + CRLF);
30
+
31
+ this.contentLength = isStringValue ? value.byteLength : value.size;
32
+
33
+ this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT;
34
+
35
+ this.name = name;
36
+ this.value = value;
37
+ }
38
+
39
+ async *encode(){
40
+ yield this.headers;
41
+
42
+ const {value} = this;
43
+
44
+ if(utils.isTypedArray(value)) {
45
+ yield value;
46
+ } else {
47
+ yield* readBlob(value);
48
+ }
49
+
50
+ yield CRLF_BYTES;
51
+ }
52
+
53
+ static escapeName(name) {
54
+ return String(name).replace(/[\r\n"]/g, (match) => ({
55
+ '\r' : '%0D',
56
+ '\n' : '%0A',
57
+ '"' : '%22',
58
+ }[match]));
59
+ }
60
+ }
61
+
62
+ const formDataToStream = (form, headersHandler, options) => {
63
+ const {
64
+ tag = 'form-data-boundary',
65
+ size = 25,
66
+ boundary = tag + '-' + utils.generateString(size, BOUNDARY_ALPHABET)
67
+ } = options || {};
68
+
69
+ if(!utils.isFormData(form)) {
70
+ throw TypeError('FormData instance required');
71
+ }
72
+
73
+ if (boundary.length < 1 || boundary.length > 70) {
74
+ throw Error('boundary must be 10-70 characters long')
75
+ }
76
+
77
+ const boundaryBytes = textEncoder.encode('--' + boundary + CRLF);
78
+ const footerBytes = textEncoder.encode('--' + boundary + '--' + CRLF + CRLF);
79
+ let contentLength = footerBytes.byteLength;
80
+
81
+ const parts = Array.from(form.entries()).map(([name, value]) => {
82
+ const part = new FormDataPart(name, value);
83
+ contentLength += part.size;
84
+ return part;
85
+ });
86
+
87
+ contentLength += boundaryBytes.byteLength * parts.length;
88
+
89
+ contentLength = utils.toFiniteNumber(contentLength);
90
+
91
+ const computedHeaders = {
92
+ 'Content-Type': `multipart/form-data; boundary=${boundary}`
93
+ }
94
+
95
+ if (Number.isFinite(contentLength)) {
96
+ computedHeaders['Content-Length'] = contentLength;
97
+ }
98
+
99
+ headersHandler && headersHandler(computedHeaders);
100
+
101
+ return Readable.from((async function *() {
102
+ for(const part of parts) {
103
+ yield boundaryBytes;
104
+ yield* part.encode();
105
+ }
106
+
107
+ yield footerBytes;
108
+ })());
109
+ };
110
+
111
+ export default formDataToStream;
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ import AxiosError from '../core/AxiosError.js';
4
+ import parseProtocol from './parseProtocol.js';
5
+ import platform from '../platform/index.js';
6
+
7
+ const DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/;
8
+
9
+ /**
10
+ * Parse data uri to a Buffer or Blob
11
+ *
12
+ * @param {String} uri
13
+ * @param {?Boolean} asBlob
14
+ * @param {?Object} options
15
+ * @param {?Function} options.Blob
16
+ *
17
+ * @returns {Buffer|Blob}
18
+ */
19
+ export default function fromDataURI(uri, asBlob, options) {
20
+ const _Blob = options && options.Blob || platform.classes.Blob;
21
+ const protocol = parseProtocol(uri);
22
+
23
+ if (asBlob === undefined && _Blob) {
24
+ asBlob = true;
25
+ }
26
+
27
+ if (protocol === 'data') {
28
+ uri = protocol.length ? uri.slice(protocol.length + 1) : uri;
29
+
30
+ const match = DATA_URL_PATTERN.exec(uri);
31
+
32
+ if (!match) {
33
+ throw new AxiosError('Invalid URL', AxiosError.ERR_INVALID_URL);
34
+ }
35
+
36
+ const mime = match[1];
37
+ const isBase64 = match[2];
38
+ const body = match[3];
39
+ const buffer = Buffer.from(decodeURIComponent(body), isBase64 ? 'base64' : 'utf8');
40
+
41
+ if (asBlob) {
42
+ if (!_Blob) {
43
+ throw new AxiosError('Blob is not supported', AxiosError.ERR_NOT_SUPPORT);
44
+ }
45
+
46
+ return new _Blob([buffer], {type: mime});
47
+ }
48
+
49
+ return buffer;
50
+ }
51
+
52
+ throw new AxiosError('Unsupported protocol ' + protocol, AxiosError.ERR_NOT_SUPPORT);
53
+ }
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Determines whether the specified URL is absolute
5
+ *
6
+ * @param {string} url The URL to test
7
+ *
8
+ * @returns {boolean} True if the specified URL is absolute, otherwise false
9
+ */
10
+ export default function isAbsoluteURL(url) {
11
+ // A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
12
+ // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
13
+ // by any combination of letters, digits, plus, period, or hyphen.
14
+ return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url);
15
+ }
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ import utils from './../utils.js';
4
+
5
+ /**
6
+ * Determines whether the payload is an error thrown by Axios
7
+ *
8
+ * @param {*} payload The value to test
9
+ *
10
+ * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false
11
+ */
12
+ export default function isAxiosError(payload) {
13
+ return utils.isObject(payload) && (payload.isAxiosError === true);
14
+ }
@@ -0,0 +1,67 @@
1
+ 'use strict';
2
+
3
+ import utils from './../utils.js';
4
+ import platform from '../platform/index.js';
5
+
6
+ export default platform.isStandardBrowserEnv ?
7
+
8
+ // Standard browser envs have full support of the APIs needed to test
9
+ // whether the request URL is of the same origin as current location.
10
+ (function standardBrowserEnv() {
11
+ const msie = /(msie|trident)/i.test(navigator.userAgent);
12
+ const urlParsingNode = document.createElement('a');
13
+ let originURL;
14
+
15
+ /**
16
+ * Parse a URL to discover it's components
17
+ *
18
+ * @param {String} url The URL to be parsed
19
+ * @returns {Object}
20
+ */
21
+ function resolveURL(url) {
22
+ let href = url;
23
+
24
+ if (msie) {
25
+ // IE needs attribute set twice to normalize properties
26
+ urlParsingNode.setAttribute('href', href);
27
+ href = urlParsingNode.href;
28
+ }
29
+
30
+ urlParsingNode.setAttribute('href', href);
31
+
32
+ // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
33
+ return {
34
+ href: urlParsingNode.href,
35
+ protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
36
+ host: urlParsingNode.host,
37
+ search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
38
+ hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
39
+ hostname: urlParsingNode.hostname,
40
+ port: urlParsingNode.port,
41
+ pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
42
+ urlParsingNode.pathname :
43
+ '/' + urlParsingNode.pathname
44
+ };
45
+ }
46
+
47
+ originURL = resolveURL(window.location.href);
48
+
49
+ /**
50
+ * Determine if a URL shares the same origin as the current location
51
+ *
52
+ * @param {String} requestURL The URL to test
53
+ * @returns {boolean} True if URL shares the same origin, otherwise false
54
+ */
55
+ return function isURLSameOrigin(requestURL) {
56
+ const parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
57
+ return (parsed.protocol === originURL.protocol &&
58
+ parsed.host === originURL.host);
59
+ };
60
+ })() :
61
+
62
+ // Non standard browser envs (web workers, react-native) lack needed support.
63
+ (function nonStandardBrowserEnv() {
64
+ return function isURLSameOrigin() {
65
+ return true;
66
+ };
67
+ })();
@@ -0,0 +1,2 @@
1
+ // eslint-disable-next-line strict
2
+ export default null;
@@ -0,0 +1,55 @@
1
+ 'use strict';
2
+
3
+ import utils from './../utils.js';
4
+
5
+ // RawAxiosHeaders whose duplicates are ignored by node
6
+ // c.f. https://nodejs.org/api/http.html#http_message_headers
7
+ const ignoreDuplicateOf = utils.toObjectSet([
8
+ 'age', 'authorization', 'content-length', 'content-type', 'etag',
9
+ 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
10
+ 'last-modified', 'location', 'max-forwards', 'proxy-authorization',
11
+ 'referer', 'retry-after', 'user-agent'
12
+ ]);
13
+
14
+ /**
15
+ * Parse headers into an object
16
+ *
17
+ * ```
18
+ * Date: Wed, 27 Aug 2014 08:58:49 GMT
19
+ * Content-Type: application/json
20
+ * Connection: keep-alive
21
+ * Transfer-Encoding: chunked
22
+ * ```
23
+ *
24
+ * @param {String} rawHeaders Headers needing to be parsed
25
+ *
26
+ * @returns {Object} Headers parsed into an object
27
+ */
28
+ export default rawHeaders => {
29
+ const parsed = {};
30
+ let key;
31
+ let val;
32
+ let i;
33
+
34
+ rawHeaders && rawHeaders.split('\n').forEach(function parser(line) {
35
+ i = line.indexOf(':');
36
+ key = line.substring(0, i).trim().toLowerCase();
37
+ val = line.substring(i + 1).trim();
38
+
39
+ if (!key || (parsed[key] && ignoreDuplicateOf[key])) {
40
+ return;
41
+ }
42
+
43
+ if (key === 'set-cookie') {
44
+ if (parsed[key]) {
45
+ parsed[key].push(val);
46
+ } else {
47
+ parsed[key] = [val];
48
+ }
49
+ } else {
50
+ parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
51
+ }
52
+ });
53
+
54
+ return parsed;
55
+ };
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ export default function parseProtocol(url) {
4
+ const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url);
5
+ return match && match[1] || '';
6
+ }
@@ -0,0 +1,15 @@
1
+ const {asyncIterator} = Symbol;
2
+
3
+ const readBlob = async function* (blob) {
4
+ if (blob.stream) {
5
+ yield* blob.stream()
6
+ } else if (blob.arrayBuffer) {
7
+ yield await blob.arrayBuffer()
8
+ } else if (blob[asyncIterator]) {
9
+ yield* blob[asyncIterator]();
10
+ } else {
11
+ yield blob;
12
+ }
13
+ }
14
+
15
+ export default readBlob;
@@ -0,0 +1,55 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Calculate data maxRate
5
+ * @param {Number} [samplesCount= 10]
6
+ * @param {Number} [min= 1000]
7
+ * @returns {Function}
8
+ */
9
+ function speedometer(samplesCount, min) {
10
+ samplesCount = samplesCount || 10;
11
+ const bytes = new Array(samplesCount);
12
+ const timestamps = new Array(samplesCount);
13
+ let head = 0;
14
+ let tail = 0;
15
+ let firstSampleTS;
16
+
17
+ min = min !== undefined ? min : 1000;
18
+
19
+ return function push(chunkLength) {
20
+ const now = Date.now();
21
+
22
+ const startedAt = timestamps[tail];
23
+
24
+ if (!firstSampleTS) {
25
+ firstSampleTS = now;
26
+ }
27
+
28
+ bytes[head] = chunkLength;
29
+ timestamps[head] = now;
30
+
31
+ let i = tail;
32
+ let bytesCount = 0;
33
+
34
+ while (i !== head) {
35
+ bytesCount += bytes[i++];
36
+ i = i % samplesCount;
37
+ }
38
+
39
+ head = (head + 1) % samplesCount;
40
+
41
+ if (head === tail) {
42
+ tail = (tail + 1) % samplesCount;
43
+ }
44
+
45
+ if (now - firstSampleTS < min) {
46
+ return;
47
+ }
48
+
49
+ const passed = startedAt && now - startedAt;
50
+
51
+ return passed ? Math.round(bytesCount * 1000 / passed) : undefined;
52
+ };
53
+ }
54
+
55
+ export default speedometer;
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Syntactic sugar for invoking a function and expanding an array for arguments.
5
+ *
6
+ * Common use case would be to use `Function.prototype.apply`.
7
+ *
8
+ * ```js
9
+ * function f(x, y, z) {}
10
+ * var args = [1, 2, 3];
11
+ * f.apply(null, args);
12
+ * ```
13
+ *
14
+ * With `spread` this example can be re-written.
15
+ *
16
+ * ```js
17
+ * spread(function(x, y, z) {})([1, 2, 3]);
18
+ * ```
19
+ *
20
+ * @param {Function} callback
21
+ *
22
+ * @returns {Function}
23
+ */
24
+ export default function spread(callback) {
25
+ return function wrap(arr) {
26
+ return callback.apply(null, arr);
27
+ };
28
+ }
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Throttle decorator
5
+ * @param {Function} fn
6
+ * @param {Number} freq
7
+ * @return {Function}
8
+ */
9
+ function throttle(fn, freq) {
10
+ let timestamp = 0;
11
+ const threshold = 1000 / freq;
12
+ let timer = null;
13
+ return function throttled(force, args) {
14
+ const now = Date.now();
15
+ if (force || now - timestamp > threshold) {
16
+ if (timer) {
17
+ clearTimeout(timer);
18
+ timer = null;
19
+ }
20
+ timestamp = now;
21
+ return fn.apply(null, args);
22
+ }
23
+ if (!timer) {
24
+ timer = setTimeout(() => {
25
+ timer = null;
26
+ timestamp = Date.now();
27
+ return fn.apply(null, args);
28
+ }, threshold - (now - timestamp));
29
+ }
30
+ };
31
+ }
32
+
33
+ export default throttle;
@@ -0,0 +1,219 @@
1
+ 'use strict';
2
+
3
+ import utils from '../utils.js';
4
+ import AxiosError from '../core/AxiosError.js';
5
+ // temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored
6
+ import PlatformFormData from '../platform/node/classes/FormData.js';
7
+
8
+ /**
9
+ * Determines if the given thing is a array or js object.
10
+ *
11
+ * @param {string} thing - The object or array to be visited.
12
+ *
13
+ * @returns {boolean}
14
+ */
15
+ function isVisitable(thing) {
16
+ return utils.isPlainObject(thing) || utils.isArray(thing);
17
+ }
18
+
19
+ /**
20
+ * It removes the brackets from the end of a string
21
+ *
22
+ * @param {string} key - The key of the parameter.
23
+ *
24
+ * @returns {string} the key without the brackets.
25
+ */
26
+ function removeBrackets(key) {
27
+ return utils.endsWith(key, '[]') ? key.slice(0, -2) : key;
28
+ }
29
+
30
+ /**
31
+ * It takes a path, a key, and a boolean, and returns a string
32
+ *
33
+ * @param {string} path - The path to the current key.
34
+ * @param {string} key - The key of the current object being iterated over.
35
+ * @param {string} dots - If true, the key will be rendered with dots instead of brackets.
36
+ *
37
+ * @returns {string} The path to the current key.
38
+ */
39
+ function renderKey(path, key, dots) {
40
+ if (!path) return key;
41
+ return path.concat(key).map(function each(token, i) {
42
+ // eslint-disable-next-line no-param-reassign
43
+ token = removeBrackets(token);
44
+ return !dots && i ? '[' + token + ']' : token;
45
+ }).join(dots ? '.' : '');
46
+ }
47
+
48
+ /**
49
+ * If the array is an array and none of its elements are visitable, then it's a flat array.
50
+ *
51
+ * @param {Array<any>} arr - The array to check
52
+ *
53
+ * @returns {boolean}
54
+ */
55
+ function isFlatArray(arr) {
56
+ return utils.isArray(arr) && !arr.some(isVisitable);
57
+ }
58
+
59
+ const predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {
60
+ return /^is[A-Z]/.test(prop);
61
+ });
62
+
63
+ /**
64
+ * Convert a data object to FormData
65
+ *
66
+ * @param {Object} obj
67
+ * @param {?Object} [formData]
68
+ * @param {?Object} [options]
69
+ * @param {Function} [options.visitor]
70
+ * @param {Boolean} [options.metaTokens = true]
71
+ * @param {Boolean} [options.dots = false]
72
+ * @param {?Boolean} [options.indexes = false]
73
+ *
74
+ * @returns {Object}
75
+ **/
76
+
77
+ /**
78
+ * It converts an object into a FormData object
79
+ *
80
+ * @param {Object<any, any>} obj - The object to convert to form data.
81
+ * @param {string} formData - The FormData object to append to.
82
+ * @param {Object<string, any>} options
83
+ *
84
+ * @returns
85
+ */
86
+ function toFormData(obj, formData, options) {
87
+ if (!utils.isObject(obj)) {
88
+ throw new TypeError('target must be an object');
89
+ }
90
+
91
+ // eslint-disable-next-line no-param-reassign
92
+ formData = formData || new (PlatformFormData || FormData)();
93
+
94
+ // eslint-disable-next-line no-param-reassign
95
+ options = utils.toFlatObject(options, {
96
+ metaTokens: true,
97
+ dots: false,
98
+ indexes: false
99
+ }, false, function defined(option, source) {
100
+ // eslint-disable-next-line no-eq-null,eqeqeq
101
+ return !utils.isUndefined(source[option]);
102
+ });
103
+
104
+ const metaTokens = options.metaTokens;
105
+ // eslint-disable-next-line no-use-before-define
106
+ const visitor = options.visitor || defaultVisitor;
107
+ const dots = options.dots;
108
+ const indexes = options.indexes;
109
+ const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;
110
+ const useBlob = _Blob && utils.isSpecCompliantForm(formData);
111
+
112
+ if (!utils.isFunction(visitor)) {
113
+ throw new TypeError('visitor must be a function');
114
+ }
115
+
116
+ function convertValue(value) {
117
+ if (value === null) return '';
118
+
119
+ if (utils.isDate(value)) {
120
+ return value.toISOString();
121
+ }
122
+
123
+ if (!useBlob && utils.isBlob(value)) {
124
+ throw new AxiosError('Blob is not supported. Use a Buffer instead.');
125
+ }
126
+
127
+ if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {
128
+ return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);
129
+ }
130
+
131
+ return value;
132
+ }
133
+
134
+ /**
135
+ * Default visitor.
136
+ *
137
+ * @param {*} value
138
+ * @param {String|Number} key
139
+ * @param {Array<String|Number>} path
140
+ * @this {FormData}
141
+ *
142
+ * @returns {boolean} return true to visit the each prop of the value recursively
143
+ */
144
+ function defaultVisitor(value, key, path) {
145
+ let arr = value;
146
+
147
+ if (value && !path && typeof value === 'object') {
148
+ if (utils.endsWith(key, '{}')) {
149
+ // eslint-disable-next-line no-param-reassign
150
+ key = metaTokens ? key : key.slice(0, -2);
151
+ // eslint-disable-next-line no-param-reassign
152
+ value = JSON.stringify(value);
153
+ } else if (
154
+ (utils.isArray(value) && isFlatArray(value)) ||
155
+ ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))
156
+ )) {
157
+ // eslint-disable-next-line no-param-reassign
158
+ key = removeBrackets(key);
159
+
160
+ arr.forEach(function each(el, index) {
161
+ !(utils.isUndefined(el) || el === null) && formData.append(
162
+ // eslint-disable-next-line no-nested-ternary
163
+ indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),
164
+ convertValue(el)
165
+ );
166
+ });
167
+ return false;
168
+ }
169
+ }
170
+
171
+ if (isVisitable(value)) {
172
+ return true;
173
+ }
174
+
175
+ formData.append(renderKey(path, key, dots), convertValue(value));
176
+
177
+ return false;
178
+ }
179
+
180
+ const stack = [];
181
+
182
+ const exposedHelpers = Object.assign(predicates, {
183
+ defaultVisitor,
184
+ convertValue,
185
+ isVisitable
186
+ });
187
+
188
+ function build(value, path) {
189
+ if (utils.isUndefined(value)) return;
190
+
191
+ if (stack.indexOf(value) !== -1) {
192
+ throw Error('Circular reference detected in ' + path.join('.'));
193
+ }
194
+
195
+ stack.push(value);
196
+
197
+ utils.forEach(value, function each(el, key) {
198
+ const result = !(utils.isUndefined(el) || el === null) && visitor.call(
199
+ formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers
200
+ );
201
+
202
+ if (result === true) {
203
+ build(el, path ? path.concat(key) : [key]);
204
+ }
205
+ });
206
+
207
+ stack.pop();
208
+ }
209
+
210
+ if (!utils.isObject(obj)) {
211
+ throw new TypeError('data must be an object');
212
+ }
213
+
214
+ build(obj);
215
+
216
+ return formData;
217
+ }
218
+
219
+ export default toFormData;