dce-reactkit 3.12.1-beta-cross-server.2 → 3.12.1-beta-cross-server.4

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.
@@ -1,10 +1,8 @@
1
- // Import crypto
2
- import { createHash } from 'crypto';
3
-
4
- // Import jwt
5
- import jwt from 'jwt-simple';
1
+ // Import cryptography lib
2
+ import Cryptr from 'cryptr';
6
3
 
7
4
  // Import shared helpers
5
+ // eslint-disable-next-line import/no-cycle
8
6
  import { internalGetCrossServerCredentialCollection } from '../server/initServer';
9
7
 
10
8
  // Import shared types
@@ -16,57 +14,120 @@ import CrossServerCredential from '../types/CrossServerCredential';
16
14
  import MINUTE_IN_MS from '../constants/MINUTE_IN_MS';
17
15
 
18
16
  /*------------------------------------------------------------------------*/
19
- /* ------------------------------ Encoding ------------------------------ */
17
+ /* --------------------------- Dynamic Imports -------------------------- */
20
18
  /*------------------------------------------------------------------------*/
21
19
 
22
20
  /**
23
- * Validate a JWT token
21
+ * Get a copy of the oauth lib
24
22
  * @author Gabe Abrams
25
- * @param encodedSecret the encoded secret
26
- * @return the secret
23
+ * @return the oauth lib
27
24
  */
28
- const decodeCredentialSecret = (encodedSecret: string): string => {
29
- // Get the credential encoding salt
30
- const credentialEncodingSalt = process.env.REACTKIT_CRED_ENCODING_SALT;
31
- if (!credentialEncodingSalt) {
25
+ const getOauthLib = async () => {
26
+ // Get the oauth signing library (included with caccl)
27
+ // Ignore because this is assumed to be included with caccl
28
+ try {
29
+ // @ts-ignore
30
+ // eslint-disable-next-line import/no-extraneous-dependencies
31
+ const oauth = await import('oauth-signature');
32
+ return oauth;
33
+ } catch (err) {
32
34
  throw new ErrorWithCode(
33
- 'Cannot decode a cross-server credential secret because the credential encoding salt was not found in env.',
34
- ReactKitErrorCode.CrossServerNoCredentialEncodingSalt,
35
+ 'Could not sign a cross-server request because we could not load the oauth library. Please make sure this app has caccl as one of its dependencies.',
36
+ ReactKitErrorCode.NoOauthLib,
35
37
  );
36
38
  }
37
-
38
- // Decode the secret
39
- return jwt.decode(encodedSecret, credentialEncodingSalt);
40
39
  };
41
40
 
42
41
  /*------------------------------------------------------------------------*/
43
- /* ------------------------------- Signing ------------------------------ */
42
+ /* ------------------------------- Helpers ------------------------------ */
44
43
  /*------------------------------------------------------------------------*/
45
44
 
46
45
  /**
47
- * Sign using sha 256
46
+ * Generate an oauth signature
48
47
  * @author Gabe Abrams
49
48
  * @param opts object containing all arguments
50
- * @param opts.pack the pack to sign
51
- * @param opts.secret the reactkit secret to sign with
52
- * @return the signed hash
49
+ * @param opts.method the http method
50
+ * @param opts.path the http request path
51
+ * @param opts.params the data in the body to sign
52
+ * @param opts.secret the secret to sign with
53
+ * @return the signature
53
54
  */
54
- const genSignature = (
55
+ const genSignature = async (
55
56
  opts: {
56
- pack: string,
57
+ method?: string,
58
+ path?: string,
59
+ params?: { [key: string]: any },
57
60
  secret: string,
58
61
  },
59
- ): string => {
60
- // Generate signature
61
- return (
62
- createHash('sha256')
63
- .update(JSON.stringify({ pack: opts.pack, secret: opts.secret }))
64
- .digest('base64')
65
- );
62
+ ): Promise<string> => {
63
+ // Destructure opts
64
+ const {
65
+ method,
66
+ path,
67
+ params,
68
+ secret,
69
+ } = opts;
70
+
71
+ // Get the oauth library
72
+ const oauth = await getOauthLib();
73
+
74
+ // Order the params alphabetically by key
75
+ const keys = Object.keys(params ?? {});
76
+ keys.sort();
77
+ const orderedParams: {
78
+ [key: string]: any,
79
+ } = {};
80
+ keys.forEach((key) => {
81
+ // Skip oauth_signature
82
+ if (key === 'oauth_signature') {
83
+ return;
84
+ }
85
+
86
+ // Add the param
87
+ orderedParams[key] = (params ?? {})[key];
88
+ });
89
+
90
+ // Generate the signature
91
+ return decodeURIComponent(oauth.generate(
92
+ method ?? 'GET',
93
+ path ?? 'no-path',
94
+ orderedParams,
95
+ secret,
96
+ ));
66
97
  };
67
98
 
68
99
  /**
69
- * Sign data with a private reactkit key, package it into a signed data pack
100
+ * Decrypt an encrypted string using a secret
101
+ * @author Gabe Abrams
102
+ * @param str the encrypted string
103
+ * @return the decrypted string
104
+ */
105
+ const decrypt = async (
106
+ encryptedPack: string,
107
+ ): Promise<string> => {
108
+ // Get the encryption secret
109
+ const { REACTKIT_CRED_ENCODING_SALT } = process.env;
110
+ if (!REACTKIT_CRED_ENCODING_SALT) {
111
+ throw new ErrorWithCode(
112
+ 'Could not decrypt a string because the encryption salt was not set.',
113
+ ReactKitErrorCode.CrossServerNoCredentialEncodingSalt,
114
+ );
115
+ }
116
+
117
+ // Decrypt the string
118
+ const cryptr = new Cryptr(REACTKIT_CRED_ENCODING_SALT);
119
+ const str = cryptr.decrypt(encryptedPack);
120
+
121
+ // Return the decrypted string
122
+ return str;
123
+ };
124
+
125
+ /*------------------------------------------------------------------------*/
126
+ /* ------------------------------- Signing ------------------------------ */
127
+ /*------------------------------------------------------------------------*/
128
+
129
+ /**
130
+ * Sign a request and get the new request params
70
131
  * @author Gabe Abrams
71
132
  * @param opts object containing all arguments
72
133
  * @param opts.method the method to sign
@@ -74,9 +135,9 @@ const genSignature = (
74
135
  * @param opts.params the data in the body to sign
75
136
  * @param opts.key the reactkit key to sign with
76
137
  * @param opts.secret the reactkit secret to sign with
77
- * @return the signed data
138
+ * @return augmented params for the request, including a signature, timestamp, and key
78
139
  */
79
- export const createSignedPack = (
140
+ export const signRequest = async (
80
141
  opts: {
81
142
  method: string,
82
143
  path: string,
@@ -84,111 +145,108 @@ export const createSignedPack = (
84
145
  key: string,
85
146
  secret: string,
86
147
  },
87
- ): string => {
88
- // Create a timestamp
89
- const timestamp = Date.now();
90
-
91
- // Create the pack
92
- const pack = JSON.stringify({
93
- method: opts.method,
94
- path: opts.path,
95
- params: opts.params,
96
- key: opts.key,
97
- timestamp,
98
- });
148
+ ): Promise<{ [key: string]: any }> => {
149
+ // Destructure opts
150
+ const method = opts.method.toUpperCase();
151
+ const {
152
+ path,
153
+ params,
154
+ key,
155
+ secret,
156
+ } = opts;
157
+
158
+ // Augment the params
159
+ const augmentedParams: {
160
+ [key: string]: any,
161
+ } = {
162
+ ...params,
163
+ oauth_consumer_key: key,
164
+ oauth_nonce: Math.random().toString(36),
165
+ oauth_timestamp: Date.now(),
166
+ };
99
167
 
100
- // Generate signature
101
- const signature = genSignature({
102
- pack,
103
- secret: opts.secret,
168
+ // Generate a signature
169
+ const signature = await genSignature({
170
+ method,
171
+ path,
172
+ params,
173
+ secret,
104
174
  });
105
175
 
106
- // Create a signed pack
107
- const signedPack = encodeURIComponent(JSON.stringify({
108
- pack,
109
- signature,
110
- }));
176
+ // Add signature to the augmented params
177
+ augmentedParams.oauth_signature = signature;
111
178
 
112
- // Return the signed pack
113
- return signedPack;
179
+ // Return the augmented params
180
+ return augmentedParams;
114
181
  };
115
182
 
116
183
  /**
117
- * Parse signed pack. Throws an error if invalid
184
+ * Validate a signed request. Throws an error if invalid
118
185
  * @author Gabe Abrams
119
186
  * @param opts object containing all arguments
120
187
  * @param opts.method the method of the data validate
121
188
  * @param opts.path the http request path to validate
122
189
  * @param opts.scope the name of the scope to validate
123
- * @param opts.signedPack the signed data pack to validate
190
+ * @param opts.params the request data to validate
124
191
  * @returns parsed and validated params
125
192
  */
126
- export const parseSignedPack = async (
193
+ export const validateSignedRequest = async (
127
194
  opts: {
128
195
  method: string,
129
196
  path: string,
130
197
  scope: string,
131
- signedPack: string,
198
+ params: { [key: string]: any },
132
199
  },
133
- ): Promise<{ [key: string]: any }> => {
134
- // Extract signature
135
- let pack: string;
136
- let signature: string;
137
- let method: string;
138
- let path: string;
139
- let key: string;
140
- let timestamp: number;
141
- let params: { [k: string]: any };
142
- try {
143
- ({
144
- pack,
145
- signature,
146
- } = JSON.parse(decodeURIComponent(opts.signedPack)));
147
-
148
- // Unpack
149
- ({
150
- method,
151
- path,
152
- params,
153
- key,
154
- timestamp,
155
- } = JSON.parse(pack));
156
- } catch (err) {
157
- throw new ErrorWithCode(
158
- 'Could not validate a cross-server request because the request could not be parsed.',
159
- ReactKitErrorCode.PackUnparseable,
160
- );
161
- }
200
+ ) => {
201
+ /* ---------- Collect Info ---------- */
162
202
 
163
- // Make sure the method and path match
164
- if (method !== opts.method) {
203
+ // Get the signature
204
+ if (!opts.params.oauth_signature) {
165
205
  throw new ErrorWithCode(
166
- 'Could not validate a cross-server request because the method did not match.',
167
- ReactKitErrorCode.PackInvalidMethod,
206
+ 'Could not validate a cross-server request there was no oauth signature.',
207
+ ReactKitErrorCode.CrossServerMissingSignedRequestInfo,
168
208
  );
169
209
  }
170
- if (path !== opts.path) {
210
+ const signature = opts.params.oauth_signature;
211
+
212
+ // Get the timestamp
213
+ if (
214
+ // No timestamp
215
+ !opts.params.oauth_timestamp
216
+ // Invalid timestamp
217
+ || Number.isNaN(Number.parseInt(opts.params.oauth_timestamp, 10))
218
+ ) {
171
219
  throw new ErrorWithCode(
172
- 'Could not validate a cross-server request because the path did not match.',
173
- ReactKitErrorCode.PackInvalidPath,
220
+ 'Could not validate a cross-server request there was no valid oauth timestamp.',
221
+ ReactKitErrorCode.CrossServerMissingSignedRequestInfo,
174
222
  );
175
223
  }
224
+ const timestamp = Number.parseInt(opts.params.oauth_timestamp, 10);
176
225
 
177
- // Make sure the timestamp was recent enough
178
- const elapsedMs = Math.abs(Date.now() - timestamp);
179
- if (elapsedMs < MINUTE_IN_MS) {
226
+ // Get the key
227
+ if (!opts.params.oauth_consumer_key) {
180
228
  throw new ErrorWithCode(
181
- 'Could not validate a cross-server request because the request was too old.',
182
- ReactKitErrorCode.PackInvalidTimestamp,
229
+ 'Could not validate a cross-server request there was no oauth consumer key.',
230
+ ReactKitErrorCode.CrossServerMissingSignedRequestInfo,
183
231
  );
184
232
  }
233
+ const key = opts.params.oauth_consumer_key;
234
+
235
+ // Get the rest of the info
236
+ const {
237
+ method,
238
+ path,
239
+ params,
240
+ } = opts;
241
+
242
+ /* ------- Look Up Credential ------- */
185
243
 
186
244
  // Get the cross-server credential collection
187
245
  const crossServerCredentialCollection = internalGetCrossServerCredentialCollection();
188
246
  if (!crossServerCredentialCollection) {
189
247
  throw new ErrorWithCode(
190
248
  'Could not validate a cross-server request because the cross-server credential collection was not ready in time.',
191
- ReactKitErrorCode.PackInvalidCollection,
249
+ ReactKitErrorCode.SignedRequestInvalidCollection,
192
250
  );
193
251
  }
194
252
 
@@ -197,7 +255,7 @@ export const parseSignedPack = async (
197
255
  if (!crossServerCredential) {
198
256
  throw new ErrorWithCode(
199
257
  'Could not validate a cross-server request because the credential was not found.',
200
- ReactKitErrorCode.PackInvalidCredential,
258
+ ReactKitErrorCode.SignedRequestInvalidCredential,
201
259
  );
202
260
  }
203
261
 
@@ -206,27 +264,37 @@ export const parseSignedPack = async (
206
264
  if (!allowedScopes.includes(opts.scope)) {
207
265
  throw new ErrorWithCode(
208
266
  'Could not validate a cross-server request because the scope was not included.',
209
- ReactKitErrorCode.PackInvalidScope,
267
+ ReactKitErrorCode.SignedRequestInvalidScope,
210
268
  );
211
269
  }
212
270
 
213
271
  // Decode the secret
214
- const secret = decodeCredentialSecret(crossServerCredential.encodedeSecret);
272
+ const secret = await decrypt(crossServerCredential.encodedeSecret);
273
+
274
+ /* -------- Verify Signature -------- */
215
275
 
216
- // Generate signature
217
- const expectedSignature = genSignature({
218
- pack,
276
+ // Generate a new signature to compare
277
+ const expectedSignature = await genSignature({
278
+ method,
279
+ path,
280
+ params,
219
281
  secret,
220
282
  });
221
283
 
222
- // Make sure the signature matches
284
+ // Make sure the signatures match
223
285
  if (signature !== expectedSignature) {
224
286
  throw new ErrorWithCode(
225
287
  'Could not validate a cross-server request because the signature did not match.',
226
- ReactKitErrorCode.PackInvalidSignature,
288
+ ReactKitErrorCode.SignedRequestInvalidSignature,
227
289
  );
228
290
  }
229
291
 
230
- // Return body
231
- return params ?? {};
292
+ // Make sure the timestamp was recent enough
293
+ const elapsedMs = Math.abs(Date.now() - timestamp);
294
+ if (elapsedMs < MINUTE_IN_MS) {
295
+ throw new ErrorWithCode(
296
+ 'Could not validate a cross-server request because the request was too old.',
297
+ ReactKitErrorCode.SignedRequestInvalidTimestamp,
298
+ );
299
+ }
232
300
  };
@@ -17,7 +17,7 @@ import genErrorPage from '../html/genErrorPage';
17
17
  import genInfoPage from '../html/genInfoPage';
18
18
  import parseUserAgent from './parseUserAgent';
19
19
  import getTimeInfoInET from './getTimeInfoInET';
20
- import { parseSignedPack } from './dataSigner';
20
+ import { validateSignedRequest } from './dataSigner';
21
21
 
22
22
  // Import shared types
23
23
  import LogFunction from '../types/LogFunction';
@@ -30,7 +30,6 @@ import LogSourceSpecificInfo from '../types/Log/LogSourceSpecificInfo';
30
30
  import LogBuiltInMetadata from '../types/LogBuiltInMetadata';
31
31
  import LogAction from '../types/LogAction';
32
32
  import LogLevel from '../types/LogLevel';
33
- import ErrorWithCode from '../errors/ErrorWithCode';
34
33
 
35
34
  /**
36
35
  * Generate an express API route handler
@@ -137,7 +136,7 @@ const genRouteHandler = (
137
136
  );
138
137
 
139
138
  // Get body from everywhere it can come from
140
- let requestBody: {
139
+ const requestBody: {
141
140
  [k: string]: any,
142
141
  } = {
143
142
  ...req.body,
@@ -150,27 +149,31 @@ const genRouteHandler = (
150
149
  /*----------------------------------------*/
151
150
 
152
151
  if (crossServerScope) {
153
- // Get the signed pack
154
- const { signedPack } = requestBody;
155
-
156
- // If no pack, throw error
157
- if (!signedPack || typeof signedPack !== 'string') {
158
- throw new ErrorWithCode(
159
- 'Could not process a cross server request because there was no valid signed pack.',
160
- ReactKitErrorCode.CrossServerNoPack,
152
+ try {
153
+ // Validate the request body
154
+ await validateSignedRequest({
155
+ method: req.method ?? 'GET',
156
+ path: req.path,
157
+ scope: crossServerScope,
158
+ params: requestBody,
159
+ });
160
+
161
+ // Valid! Remove oauth values
162
+ Object.keys(requestBody).forEach((key) => {
163
+ if (key.startsWith('oauth_')) {
164
+ delete requestBody[key];
165
+ }
166
+ });
167
+ } catch (err) {
168
+ return handleError(
169
+ res,
170
+ {
171
+ message: `The authenticity of a cross-server request could not be validated because an error occurred: ${(err as any).message ?? 'unknown error'}`,
172
+ code: ((err as any).code ?? ReactKitErrorCode.UnknownCrossServerError),
173
+ status: 401,
174
+ },
161
175
  );
162
176
  }
163
-
164
- // Validate the request
165
- const crossServerParams = await parseSignedPack({
166
- method: req.method ?? 'GET',
167
- path: req.path,
168
- scope: crossServerScope,
169
- signedPack,
170
- });
171
-
172
- // Replace body with params from the pack
173
- requestBody = crossServerParams ?? {};
174
177
  }
175
178
 
176
179
  /*----------------------------------------*/
@@ -586,14 +589,14 @@ const genRouteHandler = (
586
589
  // Main log info
587
590
  const mainLogInfo: LogMainInfo = {
588
591
  id: `${launchInfo ? launchInfo.userId : 'unknown'}-${Date.now()}-${Math.floor(Math.random() * 100000)}-${Math.floor(Math.random() * 100000)}`,
589
- userFirstName: (launchInfo ? launchInfo.userFirstName: 'unknown'),
592
+ userFirstName: (launchInfo ? launchInfo.userFirstName : 'unknown'),
590
593
  userLastName: (launchInfo ? launchInfo.userLastName : 'unknown'),
591
594
  userEmail: (launchInfo ? launchInfo.userEmail : 'unknown'),
592
595
  userId: (launchInfo ? launchInfo.userId : 'unknown'),
593
596
  isLearner: (launchInfo && !!launchInfo.isLearner),
594
597
  isAdmin: (launchInfo && !!launchInfo.isAdmin),
595
598
  isTTM: (launchInfo && !!launchInfo.isTTM),
596
- courseId: (launchInfo ? launchInfo.courseId : 'unknown' ),
599
+ courseId: (launchInfo ? launchInfo.courseId : 'unknown'),
597
600
  courseName: (launchInfo ? launchInfo.contextLabel : 'unknown'),
598
601
  browser,
599
602
  device,
@@ -1,11 +1,86 @@
1
1
  // Import data signer
2
- import { createSignedPack } from '../dataSigner';
2
+ import { signRequest } from '../dataSigner';
3
3
 
4
4
  // Import shared types
5
5
  import ErrorWithCode from '../../errors/ErrorWithCode';
6
6
  import ReactKitErrorCode from '../../types/ReactKitErrorCode';
7
7
  import sendServerToServerRequest from './sendServerToServerRequest';
8
8
 
9
+ /*------------------------------------------------------------------------*/
10
+ /* ----------------------------- Credentials ---------------------------- */
11
+ /*------------------------------------------------------------------------*/
12
+
13
+ /*
14
+ REACTKIT_CROSS_SERVER_CREDENTIALS format:
15
+ |host:key:secret||host:key:secret|...
16
+ */
17
+
18
+ const credentials: {
19
+ host: string,
20
+ key: string,
21
+ secret: string,
22
+ }[] = (
23
+ (process.env.REACTKIT_CROSS_SERVER_CREDENTIALS ?? '')
24
+ // Replace multiple | with a single one
25
+ .replace(/\|+/g, '|')
26
+ // Split by |
27
+ .split('|')
28
+ // Remove empty strings
29
+ .filter((str) => {
30
+ return str.trim().length > 0;
31
+ })
32
+ // Process each credential
33
+ .map((str) => {
34
+ // Split by :
35
+ const parts = str.split(':');
36
+
37
+ // Check for errors
38
+ if (parts.length !== 3) {
39
+ throw new ErrorWithCode(
40
+ 'Invalid REACTKIT_CROSS_SERVER_CREDENTIALS format. Each credential must be in the format |host:key:secret|',
41
+ ReactKitErrorCode.InvalidCrossServerCredentialsFormat,
42
+ );
43
+ }
44
+
45
+ // Return the credential
46
+ return {
47
+ host: parts[0].trim(),
48
+ key: parts[1].trim(),
49
+ secret: parts[2].trim(),
50
+ };
51
+ })
52
+ );
53
+
54
+ /*------------------------------------------------------------------------*/
55
+ /* ------------------------------- Helpers ------------------------------ */
56
+ /*------------------------------------------------------------------------*/
57
+
58
+ /**
59
+ * Get the credential to use for the request to another server
60
+ * @author Gabe Abrams
61
+ * @param host the host of the other server
62
+ * @return the credential to use
63
+ */
64
+ const getCrossServerCredential = (host: string) => {
65
+ // Find the credential
66
+ const credential = credentials.find((cred) => {
67
+ return cred.host.toLowerCase() === host.toLowerCase();
68
+ });
69
+ if (!credential) {
70
+ throw new ErrorWithCode(
71
+ 'Cannot send cross-server signed request there was no credential that matched the host that the request is being sent to.',
72
+ ReactKitErrorCode.CrossServerNoCredentialsToSignWith,
73
+ );
74
+ }
75
+
76
+ // Return credential
77
+ return credential;
78
+ };
79
+
80
+ /*------------------------------------------------------------------------*/
81
+ /* -------------------------------- Main -------------------------------- */
82
+ /*------------------------------------------------------------------------*/
83
+
9
84
  /**
10
85
  * Visit an endpoint on another server
11
86
  * @author Gabe Abrams
@@ -13,10 +88,6 @@ import sendServerToServerRequest from './sendServerToServerRequest';
13
88
  * @param opts.method the method of the endpoint
14
89
  * @param opts.path the path of the other server's endpoint
15
90
  * @param opts.host the host of the other server
16
- * @param [opts.key=process.env.REACTKIT_CROSS_SERVER_CREDENTIAL_KEY] reactkit cross-server
17
- * credential key
18
- * @param [opts.secret=process.env.REACTKIT_CROSS_SERVER_CREDENTIAL_SECRET reactkit cross-server
19
- * credential secret
20
91
  * @param [opts.params={}] query/body parameters to include
21
92
  * @param [opts.responseType=JSON] the response type from the other server
22
93
  */
@@ -25,31 +96,20 @@ const visitEndpointOnAnotherServer = async (
25
96
  method: 'GET' | 'POST' | 'DELETE' | 'PUT',
26
97
  path: string,
27
98
  host: string,
28
- key?: string,
29
- secret?: string,
30
99
  params?: { [key in string]: any },
31
100
  responseType?: 'JSON' | 'Text',
32
101
  },
33
102
  ): Promise<any> => {
34
- // Get cross-server credentials
35
- const key = opts.key ?? process.env.REACTKIT_CROSS_SERVER_KEY;
36
- const secret = opts.secret ?? process.env.REACTKIT_CROSS_SERVER_SECRET;
37
-
38
- // Throw error if no credentials
39
- if (!key || !secret) {
40
- throw new ErrorWithCode(
41
- 'Cannot send cross-server signed request because either or both the key and secret were not included or found in env.',
42
- ReactKitErrorCode.CrossServerNoCredentialsToSignWith,
43
- );
44
- }
103
+ // Get cross-server credential
104
+ const credential = getCrossServerCredential(opts.host);
45
105
 
46
- // Create signed pack
47
- const signedPack = createSignedPack({
106
+ // Sign the request, get new params
107
+ const augmentedParams = await signRequest({
48
108
  method: opts.method,
49
109
  path: opts.path,
50
110
  params: opts.params ?? {},
51
- key,
52
- secret,
111
+ key: credential.key,
112
+ secret: credential.secret,
53
113
  });
54
114
 
55
115
  // Send the request
@@ -57,16 +117,14 @@ const visitEndpointOnAnotherServer = async (
57
117
  path: opts.path,
58
118
  host: opts.host,
59
119
  method: opts.method,
60
- params: {
61
- signedPack,
62
- },
120
+ params: augmentedParams,
63
121
  responseType: opts.responseType,
64
122
  });
65
123
 
66
124
  // Check for failure
67
125
  if (!response || !response.body) {
68
126
  throw new ErrorWithCode(
69
- 'We didn\'t get a response from the other server. Please check your internet connection.',
127
+ 'We didn\'t get a response from the other server. Please check the network between the two connection.',
70
128
  ReactKitErrorCode.NoResponse,
71
129
  );
72
130
  }