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.
		
		
		
		
		
			
		
			
				
	
	
		
			111 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			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);
 | 
						|
}
 |