react-native-mosquito-transport 0.0.19 → 0.0.22
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/.jshintignore +4 -0
- package/.jshintrc +16 -0
- package/README.md +71 -1
- package/TODO +19 -2
- package/ios/Mosquitodb.swift +14 -5
- package/package.json +17 -17
- package/src/helpers/engine_api.js +34 -0
- package/src/helpers/peripherals.js +57 -135
- package/src/helpers/purger.js +264 -0
- package/src/helpers/sqlite_manager.js +138 -0
- package/src/helpers/utils.js +96 -47
- package/src/helpers/values.js +12 -66
- package/src/helpers/variables.js +45 -11
- package/src/index.d.ts +186 -85
- package/src/index.js +198 -119
- package/src/products/auth/accessor.js +99 -39
- package/src/products/auth/index.js +153 -99
- package/src/products/database/accessor.js +1008 -247
- package/src/products/database/bson.js +16 -0
- package/src/products/database/counter.js +18 -0
- package/src/products/database/index.js +394 -266
- package/src/products/database/types.js +2 -1
- package/src/products/database/validator.js +518 -255
- package/src/products/http_callable/accessor.js +72 -0
- package/src/products/http_callable/counter.js +11 -0
- package/src/products/http_callable/index.js +143 -147
- package/src/products/storage/index.js +109 -93
- package/src/helpers/EngineApi.js +0 -33
package/.jshintignore
ADDED
package/.jshintrc
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"undef": true, // Warns on variables used before declaration
|
|
3
|
+
"esversion": 12,
|
|
4
|
+
"globals": {
|
|
5
|
+
"process": true,
|
|
6
|
+
"clearTimeout": true,
|
|
7
|
+
"setTimeout": true,
|
|
8
|
+
"console": true,
|
|
9
|
+
"Buffer": true,
|
|
10
|
+
"clearInterval": true,
|
|
11
|
+
"setInterval": true,
|
|
12
|
+
"AbortController": true,
|
|
13
|
+
"URLSearchParams": true,
|
|
14
|
+
"URL": true
|
|
15
|
+
}
|
|
16
|
+
}
|
package/README.md
CHANGED
|
@@ -1 +1,71 @@
|
|
|
1
|
-
# react-native-mosquito-transport
|
|
1
|
+
# react-native-mosquito-transport
|
|
2
|
+
|
|
3
|
+
React native javascript sdk for [mosquito-transport](https://github.com/brainbehindx/mosquito-transport).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install react-native-mosquito-transport --save
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
or using yarn
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
yarn add react-native-mosquito-transport
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
import RNMosquitoTransport from "react-native-mosquito-transport";
|
|
21
|
+
|
|
22
|
+
// uses sqlite to cache it data by default
|
|
23
|
+
RNMosquitoTransport.initializeCache();
|
|
24
|
+
|
|
25
|
+
const mclient = new RNMosquitoTransport({
|
|
26
|
+
projectUrl: "http://localhost:3444"
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Additional Documentations
|
|
31
|
+
|
|
32
|
+
- [RNMosquitoTransport Constructor](#RNMosquitoTransportConstructor)
|
|
33
|
+
- [dbName](#dbName)
|
|
34
|
+
- [dbUrl](#dbUrl)
|
|
35
|
+
- [projectUrl](#projectUrl)
|
|
36
|
+
- [disableCache](#disableCache)
|
|
37
|
+
- [maxRetries](#maxRetries)
|
|
38
|
+
- [enableE2E_Encryption](#enableE2E_Encryption)
|
|
39
|
+
- [serverE2E_PublicKey](#serverE2E_PublicKey)
|
|
40
|
+
- [extraHeaders](#extraHeaders)
|
|
41
|
+
- [castBSON](#castBSON)
|
|
42
|
+
- [RNMosquitoTransport Methods](#RNMosquitoTransportMethods)
|
|
43
|
+
- [initialCache](#initialCache)
|
|
44
|
+
- [getDatabase](#getDatabase)
|
|
45
|
+
- [collection](#collection)
|
|
46
|
+
- [auth](#auth)
|
|
47
|
+
- [storage](#storage)
|
|
48
|
+
- [fetchHttp](#fetchHttp)
|
|
49
|
+
- [listenReachableServer](#listenReachableServer)
|
|
50
|
+
- [getSocket](#getSocket)
|
|
51
|
+
- [batchWrite](#batchWrite)
|
|
52
|
+
- [TIMESTAMP](#TIMESTAMP)
|
|
53
|
+
- [AUTH_PROVIDER_ID](#AUTH_PROVIDER_ID)
|
|
54
|
+
- [DOCUMENT_EXTRACTION](#DOCUMENT_EXTRACTION)
|
|
55
|
+
- [GEO_JSON](#GEO_JSON)
|
|
56
|
+
- [FIND_GEO_JSON](#FIND_GEO_JSON)
|
|
57
|
+
- [DoNotEncrypt](#DoNotEncrypt)
|
|
58
|
+
|
|
59
|
+
## RNMosquitoTransport Constructor
|
|
60
|
+
|
|
61
|
+
### dbName
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
### dbUrl
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
### projectUrl
|
|
68
|
+
|
|
69
|
+
this is the base url of
|
|
70
|
+
|
|
71
|
+
### disableCache
|
package/TODO
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
|
-
- fix local cache query on sqlite
|
|
1
|
+
- fix local cache query on sqlite ✅
|
|
2
2
|
- fix and add all mongodb query and update operator
|
|
3
3
|
- reauthenticate
|
|
4
4
|
- change `Object` in d.ts to [key: string]: any
|
|
5
5
|
- add `getServerTimeOffset` method
|
|
6
|
-
- change
|
|
6
|
+
- change undefined to null in `value` ✅
|
|
7
|
+
- `provide functionality to add extra header to MT instance (all outgoing request)` ✅
|
|
8
|
+
- borrowToken
|
|
9
|
+
- `add sqlite` ✅
|
|
10
|
+
- minimize extraction data ✅
|
|
11
|
+
- change `collection().onDisconnect()` to `collection().socket().onDisconnect()` and `collection().socket().onConnect()` ✅
|
|
12
|
+
- add `_foreign_doc` to d.ts ✅
|
|
13
|
+
- tree shake dependencies
|
|
14
|
+
- dynamic import for fs ✅
|
|
15
|
+
- new URL() work around ✅
|
|
16
|
+
- fetchHttp, default retrieval if has body ✅
|
|
17
|
+
- native hashing
|
|
18
|
+
- TextEncoder
|
|
19
|
+
- native storage upload
|
|
20
|
+
- lodashes ✅
|
|
21
|
+
- switch to events package
|
|
22
|
+
- serverTimeOffset
|
|
23
|
+
<!-- - error: "refreshToken retry limit exceeded" <--- no need -->
|
package/ios/Mosquitodb.swift
CHANGED
|
@@ -88,18 +88,23 @@ class MosquitodbUploadTask: NSObject, URLSessionDataDelegate {
|
|
|
88
88
|
let filepath = options["file"] as! String
|
|
89
89
|
let url = options["url"] as! String
|
|
90
90
|
let destination = options["destination"] as! String
|
|
91
|
-
let authorization = options["authorization"] as! String
|
|
92
91
|
|
|
93
92
|
do {
|
|
94
93
|
let rawData = try Data(contentsOf: URL(fileURLWithPath: filepath))
|
|
95
94
|
|
|
96
95
|
var request = URLRequest(url: URL(string: url)!)
|
|
97
96
|
request.httpMethod = "POST"
|
|
97
|
+
|
|
98
|
+
if let extraHeaders = options["extraHeaders"] as? [[String: String]] {
|
|
99
|
+
for (key, value) in extraHeaders {
|
|
100
|
+
request.setValue(value, forHTTPHeaderField: key)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
98
103
|
request.setValue("application/json", forHTTPHeaderField: "Accept")
|
|
99
|
-
request.setValue(authorization, forHTTPHeaderField: "Authorization")
|
|
100
104
|
if options["authToken"] != nil {
|
|
101
105
|
request.setValue(options["authToken"] as? String, forHTTPHeaderField: "Mosquito-Token")
|
|
102
106
|
}
|
|
107
|
+
request.setValue(options["createHash"] as? String, forHTTPHeaderField: "hash-upload");
|
|
103
108
|
request.setValue("buffer/upload", forHTTPHeaderField: "Content-Type")
|
|
104
109
|
request.setValue(destination, forHTTPHeaderField: "Mosquito-Destination")
|
|
105
110
|
|
|
@@ -183,11 +188,15 @@ class MosquitodbDownloadTask: NSObject, URLSessionDownloadDelegate {
|
|
|
183
188
|
func downloadFile(options: [String: Any], completion: @escaping ([Any]?)->()) -> Void {
|
|
184
189
|
let processID = options["processID"] as! String
|
|
185
190
|
let url = options["url"] as! String
|
|
186
|
-
let authorization = options["authorization"] as! String
|
|
187
191
|
|
|
188
192
|
var request = URLRequest(url: URL(string: url)!)
|
|
189
193
|
request.httpMethod = "POST"
|
|
190
|
-
|
|
194
|
+
|
|
195
|
+
if let extraHeaders = options["extraHeaders"] as? [[String: String]] {
|
|
196
|
+
for (key, value) in extraHeaders {
|
|
197
|
+
request.setValue(value, forHTTPHeaderField: key)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
191
200
|
if options["authToken"] != nil {
|
|
192
201
|
request.setValue(options["authToken"] as? String, forHTTPHeaderField: "Mosquito-Token")
|
|
193
202
|
}
|
|
@@ -249,7 +258,7 @@ class MosquitodbDownloadTask: NSObject, URLSessionDownloadDelegate {
|
|
|
249
258
|
"result": "{\"file\": \"\(dest)\"}"
|
|
250
259
|
]
|
|
251
260
|
])
|
|
252
|
-
}else{
|
|
261
|
+
} else {
|
|
253
262
|
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
|
254
263
|
let urlName = mainOptions["urlName"] as! String
|
|
255
264
|
let destDir = documentsURL.appendingPathComponent("mosquito-transport")
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-mosquito-transport",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "React native javascript sdk for mosquito-transport (https://github.com/
|
|
3
|
+
"version": "0.0.22",
|
|
4
|
+
"description": "React native javascript sdk for mosquito-transport (https://github.com/brainbehindx/mosquito-transport)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
|
+
"type": "module",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
9
|
},
|
|
9
10
|
"repository": {
|
|
10
11
|
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/
|
|
12
|
+
"url": "git+https://github.com/brainbehindx/react-native-mosquito-transport.git"
|
|
12
13
|
},
|
|
13
14
|
"keywords": [
|
|
14
15
|
"mosquito-transport",
|
|
@@ -22,23 +23,19 @@
|
|
|
22
23
|
"author": "Anthony Onabanjo <deflexable@gmail.com> (https://github.com/deflexable)",
|
|
23
24
|
"license": "MIT",
|
|
24
25
|
"bugs": {
|
|
25
|
-
"url": "https://github.com/
|
|
26
|
+
"url": "https://github.com/brainbehindx/react-native-mosquito-transport/issues"
|
|
26
27
|
},
|
|
27
|
-
"homepage": "https://github.com/
|
|
28
|
+
"homepage": "https://github.com/brainbehindx/react-native-mosquito-transport#readme",
|
|
28
29
|
"dependencies": {
|
|
29
|
-
"@
|
|
30
|
-
"
|
|
30
|
+
"@turf/turf": "^7.1.0",
|
|
31
|
+
"bson": "^6.8.0",
|
|
31
32
|
"buffer": "^6.0.3",
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"json-buffer": "^3.0.1",
|
|
36
|
-
"lodash.get": "^4.4.2",
|
|
37
|
-
"lodash.isequal": "^4.5.0",
|
|
38
|
-
"lodash.set": "^4.3.2",
|
|
39
|
-
"lodash.unset": "^4.5.2",
|
|
33
|
+
"entity-serializer": "^1.0.2",
|
|
34
|
+
"guard-object": "^1.1.4",
|
|
35
|
+
"lodash": "^4.17.21",
|
|
40
36
|
"react-native-get-random-values": "^1.9.0",
|
|
41
|
-
"
|
|
37
|
+
"react-native-hash": "^3.0.3",
|
|
38
|
+
"simplify-error": "^1.0.1",
|
|
42
39
|
"socket.io-client": "^4.6.2",
|
|
43
40
|
"subscription-listener": "^1.1.2",
|
|
44
41
|
"tweetnacl": "^1.0.3"
|
|
@@ -46,5 +43,8 @@
|
|
|
46
43
|
"peerDependencies": {
|
|
47
44
|
"react": "*",
|
|
48
45
|
"react-native": "*"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/react-native-sqlite-storage": "^6.0.5"
|
|
49
49
|
}
|
|
50
|
-
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { encodeBinary } from './peripherals';
|
|
2
|
+
|
|
3
|
+
const EngineApiBase = (baseApi, ugly, path) =>
|
|
4
|
+
ugly ? `${baseApi}/e2e/${encodeBinary(path)}` : `${baseApi}/${path}`;
|
|
5
|
+
|
|
6
|
+
const apis = {
|
|
7
|
+
_readDocument: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_readDocument'),
|
|
8
|
+
_queryCollection: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_queryCollection'),
|
|
9
|
+
_documentCount: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_documentCount'),
|
|
10
|
+
_writeDocument: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_writeDocument'),
|
|
11
|
+
_writeMapDocument: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_writeMapDocument'),
|
|
12
|
+
_customSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_customSignin'),
|
|
13
|
+
_customSignup: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_customSignup'),
|
|
14
|
+
_googleSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_googleSignin'),
|
|
15
|
+
_appleSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_appleSignin'),
|
|
16
|
+
_facebookSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_facebookSignin'),
|
|
17
|
+
_twitterSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_twitterSignin'),
|
|
18
|
+
_githubSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_githubSignin'),
|
|
19
|
+
_signOut: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_signOut'),
|
|
20
|
+
_refreshAuthToken: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_refreshAuthToken'),
|
|
21
|
+
_uploadFile: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_uploadFile'),
|
|
22
|
+
_deleteFile: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_deleteFile'),
|
|
23
|
+
_deleteFolder: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_deleteFolder'),
|
|
24
|
+
staticStorage: (baseApi) => `${baseApi}/storage`,
|
|
25
|
+
_areYouOk: (baseApi) => `${baseApi}/_areYouOk`,
|
|
26
|
+
// static path
|
|
27
|
+
_listenCollection: (ugly) => ugly ? encodeBinary(apis._listenCollection()) : '_listenCollection',
|
|
28
|
+
_listenDocument: (ugly) => ugly ? encodeBinary(apis._listenDocument()) : '_listenDocument',
|
|
29
|
+
_startDisconnectWriteTask: (ugly) => ugly ? encodeBinary(apis._startDisconnectWriteTask()) : '_startDisconnectWriteTask',
|
|
30
|
+
_cancelDisconnectWriteTask: (ugly) => ugly ? encodeBinary(apis._cancelDisconnectWriteTask()) : '_cancelDisconnectWriteTask',
|
|
31
|
+
_listenUserVerification: (ugly) => ugly ? encodeBinary(apis._listenUserVerification()) : '_listenUserVerification'
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default { ...apis };
|
|
@@ -1,133 +1,46 @@
|
|
|
1
1
|
import { Buffer } from "buffer";
|
|
2
2
|
import { ServerReachableListener } from "./listeners";
|
|
3
|
-
import aes_pkg from 'crypto-js/aes.js';
|
|
4
|
-
import Utf8Encoder from 'crypto-js/enc-utf8.js';
|
|
5
3
|
import naclPkg from 'tweetnacl';
|
|
4
|
+
import getLodash from "lodash/get";
|
|
5
|
+
import { deserialize, serialize } from "entity-serializer";
|
|
6
|
+
import { CONSTANTS, JSHash } from 'react-native-hash';
|
|
6
7
|
|
|
7
|
-
const { encrypt, decrypt } = aes_pkg;
|
|
8
8
|
const { box, randomBytes } = naclPkg;
|
|
9
9
|
|
|
10
|
-
export const simplifyError = (error, message) => ({
|
|
11
|
-
simpleError: { error, message }
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
export const simplifyCaughtError = (e) => e?.simpleError ? e : simplifyError('unexpected_error', `${e}`);
|
|
15
|
-
|
|
16
|
-
export const everyEntrie = (obj, callback) => {
|
|
17
|
-
if (typeof obj !== 'object' || Array.isArray(obj)) return;
|
|
18
|
-
oEntries(obj).forEach(e => {
|
|
19
|
-
callback?.(e);
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const flatEntries = (obj) => oEntries(obj);
|
|
24
|
-
|
|
25
|
-
export const flatRawEntries = () => oEntries(obj, false);
|
|
26
|
-
|
|
27
|
-
export const oEntries = (obj, includeObj = true) => {
|
|
28
|
-
let o = [];
|
|
29
|
-
|
|
30
|
-
Object.entries(obj).forEach(e => {
|
|
31
|
-
o.push(e);
|
|
32
|
-
if (e[1] && typeof e[1] === 'object' && !Array.isArray(e[1])) {
|
|
33
|
-
o = [...o, ...oEntries(e[1])];
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
return o.filter(v => includeObj || typeof v[1] !== 'object' || Array.isArray(v[1]));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const IS_RAW_OBJECT = (e) => e && typeof e === 'object' && !Array.isArray(e) && !(e instanceof Date);
|
|
41
|
-
|
|
42
|
-
export const IS_WHOLE_NUMBER = (v) => typeof v === 'number' && !`${v}`.includes('.');
|
|
43
|
-
|
|
44
|
-
export const IS_DECIMAL_NUMBER = (v) => typeof v === 'number' && `${v}`.includes('.');
|
|
45
|
-
|
|
46
|
-
export const queryEntries = (obj, lastPath = '', exceptions = [], seperator = '.') => {
|
|
47
|
-
let o = [];
|
|
48
|
-
const isArraySeperator = Array.isArray(lastPath);
|
|
49
|
-
|
|
50
|
-
Object.entries(obj).forEach(([key, value]) => {
|
|
51
|
-
if (IS_RAW_OBJECT(value) && !exceptions.includes(key)) {
|
|
52
|
-
o = [
|
|
53
|
-
...o,
|
|
54
|
-
...queryEntries(
|
|
55
|
-
value,
|
|
56
|
-
isArraySeperator ? [...lastPath, key] : `${lastPath}${key}${seperator}`,
|
|
57
|
-
exceptions,
|
|
58
|
-
seperator
|
|
59
|
-
)
|
|
60
|
-
];
|
|
61
|
-
} else o.push(isArraySeperator ? [[...lastPath, key], value] : [`${lastPath}${key}`, value]);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
return o;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export const objToUniqueString = (obj) => {
|
|
68
|
-
const keys = [],
|
|
69
|
-
values = [];
|
|
70
|
-
|
|
71
|
-
if (Array.isArray(obj)) {
|
|
72
|
-
obj.forEach(e => {
|
|
73
|
-
if (IS_RAW_OBJECT(e)) {
|
|
74
|
-
queryEntries(e).map(([k, v]) => {
|
|
75
|
-
keys.push(k);
|
|
76
|
-
values.push(v);
|
|
77
|
-
});
|
|
78
|
-
} else keys.push(Array.isArray(e) ? JSON.stringify(e) : `${e}`);
|
|
79
|
-
});
|
|
80
|
-
} else if (!IS_RAW_OBJECT(obj))
|
|
81
|
-
return `${obj}`;
|
|
82
|
-
else
|
|
83
|
-
queryEntries(obj).map(([k, v]) => {
|
|
84
|
-
keys.push(k);
|
|
85
|
-
values.push(v);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
return [
|
|
89
|
-
...keys.sort(),
|
|
90
|
-
...values.map(v => `${Array.isArray(v) ? JSON.stringify(v) : v}`).sort()
|
|
91
|
-
].join(',');
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export const cloneInstance = (v) => {
|
|
95
|
-
if (v && typeof v === 'object') {
|
|
96
|
-
return Array.isArray(v) ? [...v] : { ...v };
|
|
97
|
-
}
|
|
98
|
-
return v;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
10
|
export const listenReachableServer = (callback, projectUrl) => {
|
|
102
11
|
let lastValue;
|
|
103
12
|
return ServerReachableListener.listenTo(projectUrl, t => {
|
|
104
13
|
if (typeof t === 'boolean' && t !== lastValue) callback?.(t);
|
|
105
14
|
}, true);
|
|
106
|
-
}
|
|
15
|
+
};
|
|
107
16
|
|
|
108
17
|
export const prefixStoragePath = (path, prefix = 'file:///') => {
|
|
109
|
-
|
|
18
|
+
let cleanedPath = path.replace(/^[^/]+:\/{1,3}/, '');
|
|
110
19
|
|
|
111
|
-
|
|
20
|
+
// Continuously remove any remaining protocol patterns until none are left
|
|
21
|
+
while (/^[^/]+:\/{1,3}/.test(cleanedPath)) {
|
|
22
|
+
cleanedPath = cleanedPath.replace(/^[^/]+:\/{1,3}/, '');
|
|
23
|
+
}
|
|
112
24
|
|
|
113
|
-
|
|
114
|
-
|
|
25
|
+
// Remove any leading slashes after protocol removal
|
|
26
|
+
cleanedPath = cleanedPath.replace(/^\/+/, '');
|
|
115
27
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return r === url ? '' : r;
|
|
119
|
-
}
|
|
28
|
+
return `${prefix}${cleanedPath}`;
|
|
29
|
+
};
|
|
120
30
|
|
|
121
31
|
export const niceTry = (promise) => new Promise(async resolve => {
|
|
122
|
-
|
|
123
32
|
try {
|
|
124
33
|
const r = await promise();
|
|
125
34
|
resolve(r);
|
|
126
35
|
} catch (e) { resolve(); }
|
|
127
36
|
});
|
|
128
37
|
|
|
38
|
+
export const normalizeRoute = (route = '') => route.split('').map((v, i, a) =>
|
|
39
|
+
((!i && v === '/') || (i === a.length - 1 && v === '/') || (i && a[i - 1] === '/' && v === '/')) ? '' : v
|
|
40
|
+
).join('');
|
|
41
|
+
|
|
129
42
|
export const shuffleArray = (n) => {
|
|
130
|
-
const array =
|
|
43
|
+
const array = n.slice(0);
|
|
131
44
|
let currentIndex = array.length, randomIndex;
|
|
132
45
|
|
|
133
46
|
while (currentIndex != 0) {
|
|
@@ -143,56 +56,65 @@ export const shuffleArray = (n) => {
|
|
|
143
56
|
}
|
|
144
57
|
|
|
145
58
|
export function sortArrayByObjectKey(arr = [], key) {
|
|
146
|
-
return arr.
|
|
59
|
+
return arr.sort(function (a, b) {
|
|
147
60
|
const left = getLodash(a, key),
|
|
148
61
|
right = getLodash(b, key);
|
|
149
62
|
|
|
150
63
|
return (left > right) ? 1 : (left < right) ? -1 : 0;
|
|
151
64
|
});
|
|
152
|
-
}
|
|
65
|
+
};
|
|
153
66
|
|
|
154
|
-
export
|
|
155
|
-
|
|
156
|
-
|
|
67
|
+
export async function niceHash(str = '') {
|
|
68
|
+
const hash = await JSHash(str, CONSTANTS.HashAlgorithms.md5);
|
|
69
|
+
if (hash.length > str.length) return encodeBinary(str);
|
|
70
|
+
return hash;
|
|
71
|
+
};
|
|
157
72
|
|
|
158
|
-
export const
|
|
159
|
-
|
|
160
|
-
|
|
73
|
+
export const sameInstance = (var1, var2) => {
|
|
74
|
+
try {
|
|
75
|
+
return var1.constructor === var2.constructor &&
|
|
76
|
+
Object.getPrototypeOf(var1) === Object.getPrototypeOf(var2)
|
|
77
|
+
} catch (_) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
161
81
|
|
|
162
|
-
export const serializeE2E = (data, auth_token, serverPublicKey) => {
|
|
82
|
+
export const serializeE2E = async (data, auth_token, serverPublicKey) => {
|
|
163
83
|
const pair = box.keyPair(),
|
|
164
|
-
nonce = randomBytes(box.nonceLength)
|
|
165
|
-
pubBase64 = Buffer.from(pair.publicKey).toString('base64'),
|
|
166
|
-
nonceBase64 = Buffer.from(nonce).toString('base64');
|
|
84
|
+
nonce = randomBytes(box.nonceLength);
|
|
167
85
|
|
|
168
86
|
return [
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
87
|
+
serialize([
|
|
88
|
+
pair.publicKey,
|
|
89
|
+
nonce,
|
|
90
|
+
Buffer.from(
|
|
91
|
+
box(
|
|
92
|
+
serialize([
|
|
93
|
+
data,
|
|
94
|
+
auth_token
|
|
95
|
+
]),
|
|
96
|
+
nonce,
|
|
97
|
+
serverPublicKey,
|
|
98
|
+
pair.secretKey
|
|
99
|
+
)
|
|
178
100
|
)
|
|
179
|
-
)
|
|
101
|
+
]),
|
|
180
102
|
[pair.secretKey, pair.publicKey]
|
|
181
103
|
];
|
|
182
|
-
}
|
|
104
|
+
};
|
|
183
105
|
|
|
184
|
-
export const deserializeE2E = (data, serverPublicKey, clientPrivateKey) => {
|
|
185
|
-
const [binaryNonce, binaryData] = data
|
|
106
|
+
export const deserializeE2E = async (data, serverPublicKey, clientPrivateKey) => {
|
|
107
|
+
const [binaryNonce, binaryData] = deserialize(data),
|
|
186
108
|
baseArray = box.open(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
109
|
+
binaryData,
|
|
110
|
+
binaryNonce,
|
|
111
|
+
serverPublicKey,
|
|
190
112
|
clientPrivateKey
|
|
191
113
|
);
|
|
192
114
|
|
|
193
115
|
if (!baseArray) throw 'Decrypting e2e message failed';
|
|
194
|
-
return
|
|
195
|
-
}
|
|
116
|
+
return deserialize(baseArray);
|
|
117
|
+
};
|
|
196
118
|
|
|
197
119
|
export const encodeBinary = (s) => Buffer.from(s, 'utf8').toString('base64');
|
|
198
120
|
export const decodeBinary = (s) => Buffer.from(s, 'base64').toString('utf8');
|