_sendToProxy pass headers/handle response refactor, lint

pull/734/head
Ryan Tharp 5 years ago
parent f2233c20c7
commit ab83f89142

@ -294,12 +294,7 @@ class LokiAppDotNetServerAPI {
}
}
static async _sendToProxy(
fetchOptions,
endpoint,
method,
{ ephemeralKey, symKey, iv }
) {
async _sendToProxy(fetchOptions, method, headers, endpoint) {
const randSnode = await lokiSnodeAPI.getRandomSnodeAddress();
const url = `https://${randSnode.ip}:${randSnode.port}/file_proxy`;
@ -308,7 +303,7 @@ class LokiAppDotNetServerAPI {
body: fetchOptions.body, // might need to b64 if binary...
endpoint,
method,
headers: fetchOptions.headers,
headers,
};
// from https://github.com/sindresorhus/is-stream/blob/master/index.js
@ -334,6 +329,18 @@ class LokiAppDotNetServerAPI {
);
payloadObj.body = false; // free memory
// make temporary key for this request/response
const ephemeralKey = libsignal.Curve.generateKeyPair();
// mix server pub key with our priv key
const symKey = libsignal.Curve.calculateAgreement(
this.pubKey, // server's pubkey
ephemeralKey.privKey // our privkey
);
// some randomness
const iv = libsignal.crypto.getRandomBytes(IV_LENGTH);
// encrypt payloadData with symmetric Key using iv
const cipherBody = await libsignal.crypto.encrypt(symKey, payloadData, iv);
@ -371,7 +378,25 @@ class LokiAppDotNetServerAPI {
'X-Loki-File-Server-Headers': JSON.stringify(finalRequestHeader),
},
};
return nodeFetch(url, firstHopOptions);
const result = await nodeFetch(url, firstHopOptions);
const txtResponse = await result.text();
let response = JSON.parse(txtResponse);
if (response.meta && response.meta.code === 200) {
const cipherBuffer = dcodeIO.ByteBuffer.wrap(
response.data,
'base64'
).toArrayBuffer();
const decryped = await libsignal.crypto.decrypt(symKey, cipherBuffer, iv);
const textDecoder = new TextDecoder();
const json = textDecoder.decode(decryped);
// replace response
response = JSON.parse(json);
} else {
log.warn('file server secure_rpc gave an non-200 response');
}
return { result, txtResponse, response };
}
// make a request to the server
@ -389,8 +414,8 @@ class LokiAppDotNetServerAPI {
url.search = new URLSearchParams(params);
}
const fetchOptions = {};
const headers = {};
try {
const headers = {};
if (forceFreshToken) {
await this.getOrRefreshServerToken(true);
}
@ -414,81 +439,35 @@ class LokiAppDotNetServerAPI {
};
}
let response;
let result;
let response = null;
let TxtResponse = '';
if (
window.lokiFeatureFlags.useSnodeProxy &&
(this.baseServerUrl === 'https://file-dev.lokinet.org' ||
this.baseServerUrl === 'https://file.lokinet.org')
) {
try {
// make temporary key for this request/response
const ephemeralKey = libsignal.Curve.generateKeyPair();
// mix server pub key with our priv key
const symKey = libsignal.Curve.calculateAgreement(
this.pubKey, // server's pubkey
ephemeralKey.privKey // our privkey
);
// some randomness
const iv = libsignal.crypto.getRandomBytes(IV_LENGTH);
result = await this.constructor._sendToProxy(
let txtResponse;
let mode = 'nodeFetch';
try {
if (
window.lokiFeatureFlags.useSnodeProxy &&
(this.baseServerUrl === 'https://file-dev.lokinet.org' ||
this.baseServerUrl === 'https://file.lokinet.org')
) {
mode = '_sendToProxy';
// have to send headers because fetchOptions.headers isn't readable
({ response, txtResponse, result } = await this._sendToProxy(
fetchOptions,
endpoint,
method,
{ ephemeralKey, symKey, iv }
);
TxtResponse = await result.text();
response = JSON.parse(TxtResponse);
if (response.meta && response.meta.code === 200) {
try {
const cipherBuffer = dcodeIO.ByteBuffer.wrap(
response.data,
'base64'
).toArrayBuffer();
const decryped = await libsignal.crypto.decrypt(
symKey,
cipherBuffer,
iv
);
const textDecoder = new TextDecoder();
const json = textDecoder.decode(decryped);
// replace response
response = JSON.parse(json);
} catch (e) {
// useless with the ephemeralKey and iv
log.warn(`serverRequest useSnodeProxy parse ${e} ${TxtResponse}`);
return {
err: e,
statusCode: result.status,
};
}
} else {
log.warn('file server secure_rpc gave an non-200 response');
}
} catch (e) {
log.info('serverRequest _sendToProxy error:', e);
return {
err: e,
};
}
} else {
try {
headers,
endpoint
));
} else {
result = await nodeFetch(url, fetchOptions || undefined);
TxtResponse = await result.text();
response = JSON.parse(TxtResponse);
} catch (e) {
log.info('serverRequest nodeFetch error:', JSON.stringify(e));
return {
err: e,
};
txtResponse = await result.text();
response = JSON.parse(txtResponse);
}
} catch (e) {
log.info(`serverRequest ${mode} error json: ${txtResponse}`);
return {
err: e,
};
}
// if it's a response style with a meta
if (result.status !== 200) {
if (!forceFreshToken && (!response.meta || response.meta.code === 401)) {
@ -767,6 +746,7 @@ class LokiAppDotNetServerAPI {
contentType: 'application/octet-stream',
name: 'content',
filename: 'attachment',
knownLength: buffer.byteLength,
});
return this.uploadData(formData);
@ -1510,6 +1490,7 @@ class LokiPublicChannelAPI {
const primaryPubKey = slavePrimaryMap[slaveKey];
// send out remaining messages for this merged identity
/* eslint-disable no-param-reassign */
if (slavePrimaryMap[slaveKey]) {
// rewrite source, profile
messageData.source = primaryPubKey;
@ -1520,6 +1501,7 @@ class LokiPublicChannelAPI {
messageData.message.profile.avatar = avatar;
messageData.message.profileKey = profileKey;
}
/* eslint-enable no-param-reassign */
this.chatAPI.emit('publicMessage', {
message: messageData,
});

Loading…
Cancel
Save