You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-desktop/ts/session/snode_api/lokiRpc.ts

111 lines
2.7 KiB
TypeScript

import fetch from 'node-fetch';
import https from 'https';
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,
};
}
interface FetchOptions {
method: string;
}
// A small wrapper around node-fetch which deserializes response
// returns nodeFetch response or false
async function lokiFetch(
url: string,
options: FetchOptions,
targetNode?: Snode
): Promise<boolean | SnodeResponse> {
const timeout = 10000;
const method = options.method || 'GET';
const fetchOptions: any = {
...options,
timeout,
method,
};
try {
// Absence of targetNode indicates that we want a direct connection
// (e.g. to connect to a seed node for the first time)
if (window.lokiFeatureFlags.useOnionRequests && targetNode) {
return await lokiOnionFetch(fetchOptions.body, targetNode);
}
return await lokiPlainFetch(url, fetchOptions);
} catch (e) {
if (e.code === 'ENOTFOUND') {
throw new window.textsecure.NotFoundError('Failed to resolve address', e);
}
throw e;
}
}
// Wrapper for a JSON RPC request
// Annoyngly, this is used for Lokid requests too
export async function snodeRpc(
method: string,
params: any,
targetNode: Snode
): Promise<boolean | SnodeResponse> {
const url = `https://${targetNode.ip}:${targetNode.port}/storage_rpc/v1`;
// TODO: The jsonrpc and body field will be ignored on storage server
if (params.pubKey) {
// Ensure we always take a copy
// tslint:disable-next-line no-parameter-reassignment
params = {
...params,
pubKey: window.getStoragePubKey(params.pubKey),
};
}
const body = {
jsonrpc: '2.0',
id: '0',
method,
params,
};
const fetchOptions = {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json',
},
};
return lokiFetch(url, fetchOptions, targetNode);
}