btc-web3 0.0.1-security → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.

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;