Merge pull request #1549 from Bilb/onion-routing-for-new-open-groups
remove fallbacks to node-fetch
This commit is contained in:
commit
a010630775
|
@ -23,7 +23,6 @@ if (environment === 'production') {
|
|||
process.env.HOSTNAME = '';
|
||||
process.env.ALLOW_CONFIG_MUTATIONS = '';
|
||||
process.env.SUPPRESS_NO_CONFIG_WARNING = '';
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '';
|
||||
|
||||
// We could be running againt production but still be in dev mode, we need to handle that
|
||||
if (!isDevelopment) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* global window */
|
||||
|
||||
const FormData = require('form-data');
|
||||
const fetch = require('node-fetch');
|
||||
const insecureNodeFetch = require('node-fetch');
|
||||
|
||||
const BASE_URL = 'https://debuglogs.org';
|
||||
const VERSION = window.getVersion();
|
||||
|
@ -10,7 +10,8 @@ const USER_AGENT = `Session ${VERSION}`;
|
|||
|
||||
// upload :: String -> Promise URL
|
||||
exports.upload = async content => {
|
||||
const signedForm = await fetch(BASE_URL, {
|
||||
window.log.warn('insecureNodeFetch => upload debugLogs');
|
||||
const signedForm = await insecureNodeFetch(BASE_URL, {
|
||||
headers: {
|
||||
'user-agent': USER_AGENT,
|
||||
},
|
||||
|
@ -38,7 +39,7 @@ exports.upload = async content => {
|
|||
filename: `session-desktop-debug-log-${VERSION}.txt`,
|
||||
});
|
||||
|
||||
const result = await fetch(url, {
|
||||
const result = await insecureNodeFetch(url, {
|
||||
method: 'POST',
|
||||
body: form,
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* global log, textsecure, libloki, Signal, Whisper,
|
||||
clearTimeout, getMessageController, libsignal, StringView, window, _,
|
||||
dcodeIO, Buffer, process */
|
||||
const nodeFetch = require('node-fetch');
|
||||
const insecureNodeFetch = require('node-fetch');
|
||||
const { URL, URLSearchParams } = require('url');
|
||||
const FormData = require('form-data');
|
||||
const https = require('https');
|
||||
|
@ -253,7 +253,7 @@ const serverRequest = async (endpoint, options = {}) => {
|
|||
let response;
|
||||
let result;
|
||||
let txtResponse;
|
||||
let mode = 'nodeFetch';
|
||||
let mode = 'insecureNodeFetch';
|
||||
try {
|
||||
const host = url.host.toLowerCase();
|
||||
// log.info('host', host, FILESERVER_HOSTS);
|
||||
|
@ -268,7 +268,12 @@ const serverRequest = async (endpoint, options = {}) => {
|
|||
fetchOptions,
|
||||
options
|
||||
));
|
||||
} else if (window.lokiFeatureFlags.useFileOnionRequests && srvPubKey) {
|
||||
} else if (window.lokiFeatureFlags.useFileOnionRequests) {
|
||||
if (!srvPubKey) {
|
||||
throw new Error(
|
||||
'useFileOnionRequests=true but we do not have a server pubkey set.'
|
||||
);
|
||||
}
|
||||
mode = 'sendViaOnionOG';
|
||||
({ response, txtResponse, result } = await sendViaOnion(
|
||||
srvPubKey,
|
||||
|
@ -277,13 +282,9 @@ const serverRequest = async (endpoint, options = {}) => {
|
|||
options
|
||||
));
|
||||
} else {
|
||||
// disable check for .loki
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = host.match(/\.loki$/i)
|
||||
? '0'
|
||||
: '1';
|
||||
result = await nodeFetch(url, fetchOptions);
|
||||
// always make sure this check is enabled
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1';
|
||||
// we end up here only if window.lokiFeatureFlags.useFileOnionRequests is false
|
||||
log.info(`insecureNodeFetch => plaintext for ${url}`);
|
||||
result = await insecureNodeFetch(url, fetchOptions);
|
||||
|
||||
txtResponse = await result.text();
|
||||
// cloudflare timeouts (504s) will be html...
|
||||
|
@ -1395,23 +1396,13 @@ class LokiPublicChannelAPI {
|
|||
// do we already have this image? no, then
|
||||
|
||||
// download a copy and save it
|
||||
const imageData = await nodeFetch(avatarAbsUrl);
|
||||
// eslint-disable-next-line no-inner-declarations
|
||||
function toArrayBuffer(buf) {
|
||||
const ab = new ArrayBuffer(buf.length);
|
||||
const view = new Uint8Array(ab);
|
||||
// eslint-disable-next-line no-plusplus
|
||||
for (let i = 0; i < buf.length; i++) {
|
||||
view[i] = buf[i];
|
||||
}
|
||||
return ab;
|
||||
}
|
||||
// eslint-enable-next-line no-inner-declarations
|
||||
const imageData = await this.serverAPI.downloadAttachment(
|
||||
avatarAbsUrl
|
||||
);
|
||||
|
||||
const buffer = await imageData.buffer();
|
||||
const newAttributes = await window.Signal.Types.Conversation.maybeUpdateAvatar(
|
||||
this.conversation.attributes,
|
||||
toArrayBuffer(buffer),
|
||||
imageData,
|
||||
{
|
||||
writeNewAttachmentData,
|
||||
deleteAttachmentData,
|
||||
|
|
|
@ -41,9 +41,14 @@ async function allowOnlyOneAtATime(name, process, timeout) {
|
|||
try {
|
||||
innerRetVal = await process();
|
||||
} catch (e) {
|
||||
log.error(
|
||||
`loki_primitives:::allowOnlyOneAtATime - error ${e.code} ${e.message}`
|
||||
);
|
||||
if (typeof e === 'string') {
|
||||
log.error(`loki_primitives:::allowOnlyOneAtATime - error ${e}`);
|
||||
} else {
|
||||
log.error(
|
||||
`loki_primitives:::allowOnlyOneAtATime - error ${e.code} ${e.message}`
|
||||
);
|
||||
}
|
||||
|
||||
// clear timeout timer
|
||||
if (timeout) {
|
||||
if (timeoutTimer !== null) {
|
||||
|
|
|
@ -2,78 +2,93 @@
|
|||
const EventEmitter = require('events');
|
||||
const LokiAppDotNetAPI = require('./loki_app_dot_net_api');
|
||||
|
||||
const nodeFetch = require('node-fetch');
|
||||
const insecureNodeFetch = require('node-fetch');
|
||||
|
||||
/**
|
||||
* Tries to establish a connection with the specified open group url.
|
||||
*
|
||||
* This will try to do an onion routing call if the `useFileOnionRequests` feature flag is set,
|
||||
* or call directly insecureNodeFetch if it's not.
|
||||
*
|
||||
* Returns
|
||||
* * true if useFileOnionRequests is false and no exception where thrown by insecureNodeFetch
|
||||
* * true if useFileOnionRequests is true and we established a connection to the server with onion routing
|
||||
* * false otherwise
|
||||
*
|
||||
*/
|
||||
const validOpenGroupServer = async serverUrl => {
|
||||
// test to make sure it's online (and maybe has a valid SSL cert)
|
||||
try {
|
||||
const url = new URL(serverUrl);
|
||||
|
||||
if (window.lokiFeatureFlags.useFileOnionRequests) {
|
||||
// check for LSRPC
|
||||
if (!window.lokiFeatureFlags.useFileOnionRequests) {
|
||||
// we are not running with onion request
|
||||
// this is an insecure insecureNodeFetch. It will expose the user ip to the serverUrl (not onion routed)
|
||||
log.info(`insecureNodeFetch => plaintext for ${url.toString()}`);
|
||||
|
||||
// this is safe (as long as node's in your trust model)
|
||||
// because
|
||||
const result = await window.tokenlessFileServerAdnAPI.serverRequest(
|
||||
`loki/v1/getOpenGroupKey/${url.hostname}`
|
||||
);
|
||||
|
||||
if (result.response.meta.code === 200) {
|
||||
// supports it
|
||||
const obj = JSON.parse(result.response.data);
|
||||
const pubKey = dcodeIO.ByteBuffer.wrap(
|
||||
obj.data,
|
||||
'base64'
|
||||
).toArrayBuffer();
|
||||
// verify it works...
|
||||
// get around the FILESERVER_HOSTS filter by not using serverRequest
|
||||
const res = await LokiAppDotNetAPI.sendViaOnion(
|
||||
pubKey,
|
||||
url,
|
||||
{ method: 'GET' },
|
||||
{ noJson: true }
|
||||
);
|
||||
if (res.result && res.result.status === 200) {
|
||||
log.info(
|
||||
`loki_public_chat::validOpenGroupServer - onion routing enabled on ${url.toString()}`
|
||||
);
|
||||
// save pubkey for use...
|
||||
window.lokiPublicChatAPI.openGroupPubKeys[serverUrl] = pubKey;
|
||||
return true;
|
||||
}
|
||||
// otherwise fall back
|
||||
} else if (result.response.meta.code !== 404) {
|
||||
// unknown error code
|
||||
log.warn(
|
||||
'loki_public_chat::validOpenGroupServer - unknown error code',
|
||||
result.response.meta
|
||||
);
|
||||
}
|
||||
// we probably have to check the response here
|
||||
await insecureNodeFetch(serverUrl);
|
||||
return true;
|
||||
}
|
||||
// doesn't support it, fallback
|
||||
log.info(
|
||||
`loki_public_chat::validOpenGroupServer - directly contacting ${url.toString()}`
|
||||
// This MUST be an onion routing call, no nodeFetch calls below here.
|
||||
|
||||
/**
|
||||
* this is safe (as long as node's in your trust model)
|
||||
*
|
||||
* First, we need to fetch the open group public key of this open group.
|
||||
* The fileserver have all the open groups public keys.
|
||||
* We need the open group public key because for onion routing we will need to encode
|
||||
* our request with it.
|
||||
* We can just ask the file-server to get the one for the open group we are trying to add.
|
||||
*/
|
||||
|
||||
const result = await window.tokenlessFileServerAdnAPI.serverRequest(
|
||||
`loki/v1/getOpenGroupKey/${url.hostname}`
|
||||
);
|
||||
|
||||
// allow .loki (may only need an agent but not sure
|
||||
// until we have a .loki to test with)
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = url.host.match(/\.loki$/i)
|
||||
? '0'
|
||||
: '1';
|
||||
await nodeFetch(serverUrl);
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1';
|
||||
// const txt = await res.text();
|
||||
if (result.response.meta.code === 200) {
|
||||
// we got the public key of the server we are trying to add.
|
||||
// decode it.
|
||||
const obj = JSON.parse(result.response.data);
|
||||
const pubKey = dcodeIO.ByteBuffer.wrap(
|
||||
obj.data,
|
||||
'base64'
|
||||
).toArrayBuffer();
|
||||
// verify we can make an onion routed call to that open group with the decoded public key
|
||||
// get around the FILESERVER_HOSTS filter by not using serverRequest
|
||||
const res = await LokiAppDotNetAPI.sendViaOnion(
|
||||
pubKey,
|
||||
url,
|
||||
{ method: 'GET' },
|
||||
{ noJson: true }
|
||||
);
|
||||
if (res.result && res.result.status === 200) {
|
||||
log.info(
|
||||
`loki_public_chat::validOpenGroupServer - onion routing enabled on ${url.toString()}`
|
||||
);
|
||||
// save pubkey for use...
|
||||
window.lokiPublicChatAPI.openGroupPubKeys[serverUrl] = pubKey;
|
||||
return true;
|
||||
}
|
||||
// return here, just so we are sure adding some code below won't do a nodeFetch fallback
|
||||
return false;
|
||||
} else if (result.response.meta.code !== 404) {
|
||||
// unknown error code
|
||||
log.warn(
|
||||
'loki_public_chat::validOpenGroupServer - unknown error code',
|
||||
result.response.meta
|
||||
);
|
||||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1';
|
||||
log.warn(
|
||||
`loki_public_chat::validOpenGroupServer - failing to create ${serverUrl}`,
|
||||
e.code,
|
||||
e.message
|
||||
);
|
||||
// bail out if not valid enough
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
class LokiPublicChatFactoryAPI extends EventEmitter {
|
||||
|
|
|
@ -127,8 +127,7 @@ export class LeftPaneContactSection extends React.Component<Props, State> {
|
|||
if (error) {
|
||||
ToastUtils.pushToastError('addContact', error);
|
||||
} else {
|
||||
// tslint:disable-next-line: no-floating-promises
|
||||
ConversationController.getInstance()
|
||||
void ConversationController.getInstance()
|
||||
.getOrCreateAndWait(sessionID, 'private')
|
||||
.then(() => {
|
||||
this.props.openConversationExternal(sessionID);
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { arrayBufferFromFile } from '../../../types/Attachment';
|
||||
import { AttachmentUtil, LinkPreviewUtil } from '../../../util';
|
||||
import { StagedLinkPreviewData } from './SessionCompositionBox';
|
||||
import fetch from 'node-fetch';
|
||||
import { default as insecureNodeFetch } from 'node-fetch';
|
||||
import { fetchLinkPreviewImage } from '../../../util/linkPreviewFetch';
|
||||
import { AbortSignal } from 'abort-controller';
|
||||
import { StagedLinkPreview } from '../../conversation/StagedLinkPreview';
|
||||
|
@ -37,8 +37,10 @@ export const getPreview = async (
|
|||
throw new Error('Link not safe for preview');
|
||||
}
|
||||
|
||||
window.log.info('insecureNodeFetch => plaintext for getPreview()');
|
||||
|
||||
const linkPreviewMetadata = await LinkPreviewUtil.fetchLinkPreviewMetadata(
|
||||
fetch,
|
||||
insecureNodeFetch,
|
||||
url,
|
||||
abortSignal
|
||||
);
|
||||
|
@ -51,8 +53,10 @@ export const getPreview = async (
|
|||
if (imageHref && window.Signal.LinkPreviews.isLinkSafeToPreview(imageHref)) {
|
||||
let objectUrl: void | string;
|
||||
try {
|
||||
window.log.info('insecureNodeFetch => plaintext for getPreview()');
|
||||
|
||||
const fullSizeImage = await fetchLinkPreviewImage(
|
||||
fetch,
|
||||
insecureNodeFetch,
|
||||
imageHref,
|
||||
abortSignal
|
||||
);
|
||||
|
|
|
@ -437,9 +437,9 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
|
|||
const newAdmins = _.sortBy(groupAdmins);
|
||||
|
||||
if (_.isEqual(existingAdmins, newAdmins)) {
|
||||
window.log.info(
|
||||
'Skipping updates of groupAdmins/moderators. No change detected.'
|
||||
);
|
||||
// window.log.info(
|
||||
// 'Skipping updates of groupAdmins/moderators. No change detected.'
|
||||
// );
|
||||
return;
|
||||
}
|
||||
this.set({ groupAdmins });
|
||||
|
|
|
@ -2,8 +2,9 @@ import { allowOnlyOneAtATime } from '../../../js/modules/loki_primitives';
|
|||
import { getGuardNodes } from '../../../ts/data/data';
|
||||
import * as SnodePool from '../snode_api/snodePool';
|
||||
import _ from 'lodash';
|
||||
import fetch from 'node-fetch';
|
||||
import { default as insecureNodeFetch } from 'node-fetch';
|
||||
import { UserUtils } from '../utils';
|
||||
import { snodeHttpsAgent } from '../snode_api/onions';
|
||||
|
||||
type Snode = SnodePool.Snode;
|
||||
|
||||
|
@ -155,23 +156,22 @@ export class OnionPaths {
|
|||
body: JSON.stringify(body),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
timeout: 10000, // 10s, we want a smaller timeout for testing
|
||||
agent: snodeHttpsAgent,
|
||||
};
|
||||
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
|
||||
let response;
|
||||
|
||||
try {
|
||||
// Log this line for testing
|
||||
// curl -k -X POST -H 'Content-Type: application/json' -d '"+fetchOptions.body.replace(/"/g, "\\'")+"'", url
|
||||
response = await fetch(url, fetchOptions);
|
||||
window.log.info('insecureNodeFetch => plaintext for testGuardNode');
|
||||
|
||||
response = await insecureNodeFetch(url, fetchOptions);
|
||||
} catch (e) {
|
||||
if (e.type === 'request-timeout') {
|
||||
log.warn('test timeout for node,', snode);
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1';
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
|
|
|
@ -1,48 +1,15 @@
|
|||
import fetch from 'node-fetch';
|
||||
import https from 'https';
|
||||
import { default as insecureNodeFetch } from 'node-fetch';
|
||||
|
||||
import { Snode } from './snodePool';
|
||||
|
||||
import { lokiOnionFetch, SnodeResponse } from './onions';
|
||||
|
||||
const snodeHttpsAgent = new https.Agent({
|
||||
rejectUnauthorized: false,
|
||||
});
|
||||
|
||||
async function lokiPlainFetch(
|
||||
url: string,
|
||||
fetchOptions: any
|
||||
): Promise<boolean | SnodeResponse> {
|
||||
const { log } = window;
|
||||
|
||||
if (url.match(/https:\/\//)) {
|
||||
// import that this does not get set in lokiFetch fetchOptions
|
||||
fetchOptions.agent = snodeHttpsAgent;
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
} else {
|
||||
log.debug('lokirpc:::lokiFetch - http communication', url);
|
||||
}
|
||||
const response = await fetch(url, fetchOptions);
|
||||
// restore TLS checking
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1';
|
||||
|
||||
if (!response.ok) {
|
||||
throw new window.textsecure.HTTPError('Loki_rpc error', response);
|
||||
}
|
||||
const result = await response.text();
|
||||
|
||||
return {
|
||||
body: result,
|
||||
status: response.status,
|
||||
};
|
||||
}
|
||||
import { lokiOnionFetch, snodeHttpsAgent, SnodeResponse } from './onions';
|
||||
|
||||
interface FetchOptions {
|
||||
method: string;
|
||||
}
|
||||
|
||||
// A small wrapper around node-fetch which deserializes response
|
||||
// returns nodeFetch response or false
|
||||
// returns insecureNodeFetch response or false
|
||||
async function lokiFetch(
|
||||
url: string,
|
||||
options: FetchOptions,
|
||||
|
@ -64,7 +31,23 @@ async function lokiFetch(
|
|||
return await lokiOnionFetch(fetchOptions.body, targetNode);
|
||||
}
|
||||
|
||||
return await lokiPlainFetch(url, fetchOptions);
|
||||
if (url.match(/https:\/\//)) {
|
||||
// import that this does not get set in lokiFetch fetchOptions
|
||||
fetchOptions.agent = snodeHttpsAgent;
|
||||
}
|
||||
window.log.warn(`insecureNodeFetch => lokiFetch of ${url}`);
|
||||
|
||||
const response = await insecureNodeFetch(url, fetchOptions);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new window.textsecure.HTTPError('Loki_rpc error', response);
|
||||
}
|
||||
const result = await response.text();
|
||||
|
||||
return {
|
||||
body: result,
|
||||
status: response.status,
|
||||
};
|
||||
} catch (e) {
|
||||
if (e.code === 'ENOTFOUND') {
|
||||
throw new window.textsecure.NotFoundError('Failed to resolve address', e);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import fetch from 'node-fetch';
|
||||
import { default as insecureNodeFetch } from 'node-fetch';
|
||||
import https from 'https';
|
||||
|
||||
import { Snode } from './snodePool';
|
||||
|
@ -353,7 +353,7 @@ const processOnionResponse = async (
|
|||
}
|
||||
};
|
||||
|
||||
const snodeHttpsAgent = new https.Agent({
|
||||
export const snodeHttpsAgent = new https.Agent({
|
||||
rejectUnauthorized: false,
|
||||
});
|
||||
|
||||
|
@ -457,7 +457,10 @@ const sendOnionRequest = async (
|
|||
const target = useV2 ? '/onion_req/v2' : '/onion_req';
|
||||
|
||||
const guardUrl = `https://${nodePath[0].ip}:${nodePath[0].port}${target}`;
|
||||
const response = await fetch(guardUrl, guardFetchOptions);
|
||||
// no logs for that one as we do need to call insecureNodeFetch to our guardNode
|
||||
// window.log.info('insecureNodeFetch => plaintext for sendOnionRequest');
|
||||
|
||||
const response = await insecureNodeFetch(guardUrl, guardFetchOptions);
|
||||
|
||||
return processOnionResponse(
|
||||
reqIdx,
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// we don't throw or catch here
|
||||
|
||||
import https from 'https';
|
||||
import fetch from 'node-fetch';
|
||||
import { default as insecureNodeFetch } from 'node-fetch';
|
||||
|
||||
import { snodeRpc } from './lokiRpc';
|
||||
import { sendOnionRequestLsrpcDest, SnodeResponse } from './onions';
|
||||
import {
|
||||
sendOnionRequestLsrpcDest,
|
||||
snodeHttpsAgent,
|
||||
SnodeResponse,
|
||||
} from './onions';
|
||||
|
||||
import { sleepFor } from '../../../js/modules/loki_primitives';
|
||||
|
||||
|
@ -17,10 +19,10 @@ import {
|
|||
updateSnodesFor,
|
||||
} from './snodePool';
|
||||
|
||||
const snodeHttpsAgent = new https.Agent({
|
||||
rejectUnauthorized: false,
|
||||
});
|
||||
|
||||
/**
|
||||
* Currently unused. If we need it again, be sure to update it to onion routing rather
|
||||
* than using a plain nodeFetch
|
||||
*/
|
||||
export async function getVersion(
|
||||
node: Snode,
|
||||
retries: number = 0
|
||||
|
@ -30,11 +32,13 @@ export async function getVersion(
|
|||
const { log } = window;
|
||||
|
||||
try {
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const result = await fetch(`https://${node.ip}:${node.port}/get_stats/v1`, {
|
||||
agent: snodeHttpsAgent,
|
||||
});
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1';
|
||||
window.log.warn('insecureNodeFetch => plaintext for getVersion');
|
||||
const result = await insecureNodeFetch(
|
||||
`https://${node.ip}:${node.port}/get_stats/v1`,
|
||||
{
|
||||
agent: snodeHttpsAgent,
|
||||
}
|
||||
);
|
||||
const data = await result.json();
|
||||
if (data.version) {
|
||||
return data.version;
|
||||
|
@ -105,8 +109,9 @@ export async function getSnodesFromSeedUrl(urlObj: URL): Promise<Array<any>> {
|
|||
timeout: 10000,
|
||||
body: JSON.stringify(body),
|
||||
};
|
||||
window.log.info('insecureNodeFetch => plaintext for getSnodesFromSeedUrl');
|
||||
|
||||
const response = await fetch(url, fetchOptions);
|
||||
const response = await insecureNodeFetch(url, fetchOptions);
|
||||
|
||||
if (response.status !== 200) {
|
||||
log.error(
|
||||
|
|
|
@ -108,8 +108,7 @@ export function markNodeUnreachable(snode: Snode): void {
|
|||
for (const [pubkey, nodes] of nodesForPubkey) {
|
||||
const edkeys = _.filter(nodes, edkey => edkey !== snode.pubkey_ed25519);
|
||||
|
||||
// tslint:disable-next-line no-floating-promises
|
||||
internalUpdateSnodesFor(pubkey, edkeys);
|
||||
void internalUpdateSnodesFor(pubkey, edkeys);
|
||||
}
|
||||
|
||||
log.warn(
|
||||
|
@ -137,13 +136,18 @@ function compareSnodes(lhs: any, rhs: any): boolean {
|
|||
return lhs.pubkey_ed25519 === rhs.pubkey_ed25519;
|
||||
}
|
||||
|
||||
// WARNING: this leaks our IP to all snodes but with no other identifying information
|
||||
// except "that a client started up" or "ran out of random pool snodes"
|
||||
// and the order of the list is randomized, so a snode can't tell if it just started or not
|
||||
/**
|
||||
* Request the version of the snode.
|
||||
* THIS IS AN INSECURE NODE FETCH and leaks our IP to all snodes but with no other identifying information
|
||||
* except "that a client started up" or "ran out of random pool snodes"
|
||||
* and the order of the list is randomized, so a snode can't tell if it just started or not
|
||||
*/
|
||||
async function requestVersion(node: any): Promise<void> {
|
||||
const { log } = window;
|
||||
|
||||
const result = await getVersion(node);
|
||||
// WARNING: getVersion is doing an insecure node fetch.
|
||||
// be sure to update getVersion to onion routing if we need this call again.
|
||||
const result = false; // await getVersion(node);
|
||||
|
||||
if (result === false) {
|
||||
return;
|
||||
|
@ -178,9 +182,14 @@ export function getNodesMinVersion(minVersion: string): Array<Snode> {
|
|||
);
|
||||
}
|
||||
|
||||
// now get version for all snodes
|
||||
// also acts an early online test/purge of bad nodes
|
||||
export async function getAllVerionsForRandomSnodePool(): Promise<void> {
|
||||
/**
|
||||
* Currently unused as it makes call over insecure node fetch and we don't need
|
||||
* to filter out nodes by versions anymore.
|
||||
*
|
||||
* now get version for all snodes
|
||||
* also acts an early online test/purge of bad nodes
|
||||
*/
|
||||
export async function getAllVersionsForRandomSnodePool(): Promise<void> {
|
||||
const { log } = window;
|
||||
|
||||
// let count = 0;
|
||||
|
@ -192,7 +201,7 @@ export async function getAllVerionsForRandomSnodePool(): Promise<void> {
|
|||
await requestVersion(node);
|
||||
} catch (e) {
|
||||
log.error(
|
||||
'LokiSnodeAPI::_getAllVerionsForRandomSnodePool - error',
|
||||
'LokiSnodeAPI::_getAllVersionsForRandomSnodePool - error',
|
||||
e.code,
|
||||
e.message
|
||||
);
|
||||
|
@ -211,7 +220,7 @@ export async function getAllVerionsForRandomSnodePool(): Promise<void> {
|
|||
return curVal;
|
||||
}, []);
|
||||
log.debug(
|
||||
`LokiSnodeAPI::_getAllVerionsForRandomSnodePool - ${versions.length} versions retrieved from network!:`,
|
||||
`LokiSnodeAPI::_getAllVersionsForRandomSnodePool - ${versions.length} versions retrieved from network!:`,
|
||||
versions.join(',')
|
||||
);
|
||||
}
|
||||
|
@ -248,8 +257,7 @@ async function getSnodeListFromLokidSeednode(
|
|||
'seed nodes total',
|
||||
seedNodes.length
|
||||
);
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
getSnodeListFromLokidSeednode(seedNodes, retries + 1);
|
||||
void getSnodeListFromLokidSeednode(seedNodes, retries + 1);
|
||||
}, retries * retries * 5000);
|
||||
} else {
|
||||
log.error('loki_snode_api::getSnodeListFromLokidSeednode - failing');
|
||||
|
@ -262,7 +270,7 @@ async function getSnodeListFromLokidSeednode(
|
|||
async function refreshRandomPoolDetail(seedNodes: Array<any>): Promise<void> {
|
||||
const { log } = window;
|
||||
|
||||
// are we running any _getAllVerionsForRandomSnodePool
|
||||
// are we running any _getAllVersionsForRandomSnodePool
|
||||
if (stopGetAllVersionPromiseControl !== false) {
|
||||
// we are, stop them
|
||||
stopGetAllVersionPromiseControl();
|
||||
|
@ -286,8 +294,9 @@ async function refreshRandomPoolDetail(seedNodes: Array<any>): Promise<void> {
|
|||
randomSnodePool.length,
|
||||
'snodes'
|
||||
);
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
getAllVerionsForRandomSnodePool();
|
||||
// Warning: the call below will call getVersions to all existing nodes.
|
||||
// And not with onion routing
|
||||
// void getAllVersionsForRandomSnodePool();
|
||||
} catch (e) {
|
||||
log.warn('LokiSnodeAPI::refreshRandomPool - error', e.code, e.message);
|
||||
/*
|
||||
|
@ -358,8 +367,7 @@ export async function getSnodesFor(pubkey: string): Promise<Array<Snode>> {
|
|||
const freshNodes = _.shuffle(await requestSnodesForPubkey(pubkey));
|
||||
|
||||
const edkeys = freshNodes.map((n: Snode) => n.pubkey_ed25519);
|
||||
// tslint:disable-next-line no-floating-promises
|
||||
internalUpdateSnodesFor(pubkey, edkeys);
|
||||
void internalUpdateSnodesFor(pubkey, edkeys);
|
||||
// TODO: We could probably check that the retuned sndoes are not "unreachable"
|
||||
|
||||
return freshNodes;
|
||||
|
|
|
@ -29,7 +29,6 @@ export function processMessage(message: string, options: any = {}) {
|
|||
const dataPlaintext = new Uint8Array(StringUtils.encode(message, 'base64'));
|
||||
const messageBuf = SignalService.WebSocketMessage.decode(dataPlaintext);
|
||||
if (messageBuf.type === SignalService.WebSocketMessage.Type.REQUEST) {
|
||||
// tslint:disable-next-line no-floating-promises
|
||||
Receiver.handleRequest(messageBuf.request?.body, options);
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { processMessage, SwarmPolling } from './swarmPolling';
|
||||
import fetch from 'node-fetch';
|
||||
import { default as insecureNodeFetch } from 'node-fetch';
|
||||
import { PubKey } from '../types';
|
||||
|
||||
export class SwarmPollingStub extends SwarmPolling {
|
||||
|
@ -12,7 +12,8 @@ export class SwarmPollingStub extends SwarmPolling {
|
|||
method: 'GET',
|
||||
};
|
||||
|
||||
const res = await fetch(
|
||||
// insecureNodeFetch but this is a stub
|
||||
const res = await insecureNodeFetch(
|
||||
`${this.baseUrl}/messages?pubkey=${pubkeyStr}`,
|
||||
get
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { StringUtils } from '../../../../session/utils';
|
||||
|
||||
import fetch from 'node-fetch';
|
||||
import { default as insecureNodeFetch } from 'node-fetch';
|
||||
|
||||
class StubMessageAPI {
|
||||
public ourKey: string;
|
||||
|
@ -23,7 +23,9 @@ class StubMessageAPI {
|
|||
};
|
||||
|
||||
const data64 = StringUtils.decode(data, 'base64');
|
||||
await fetch(
|
||||
// insecureNodeFetch but this is a stub
|
||||
|
||||
await insecureNodeFetch(
|
||||
`${
|
||||
this.baseUrl
|
||||
}/messages?pubkey=${pubKey}×tamp=${messageTimeStamp}&data=${encodeURIComponent(
|
||||
|
|
|
@ -9,7 +9,6 @@ import {
|
|||
IMAGE_WEBP,
|
||||
MIMEType,
|
||||
} from '../types/MIME';
|
||||
import { PromiseUtils } from '../session/utils';
|
||||
|
||||
const MAX_REQUEST_COUNT_WITH_REDIRECTS = 20;
|
||||
// tslint:disable: prefer-for-of
|
||||
|
|
|
@ -4239,14 +4239,6 @@
|
|||
"reasonCategory": "falseMatch",
|
||||
"updated": "2018-09-19T18:13:29.628Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "node_modules/node-fetch/lib/headers.js",
|
||||
"line": "\t\t\t\tself.append(prop, item.toString());",
|
||||
"lineNumber": 40,
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2018-09-19T18:13:29.628Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "node_modules/node-forge/dist/forge.all.min.js",
|
||||
|
|
Loading…
Reference in New Issue