diff --git a/js/modules/loki_app_dot_net_api.js b/js/modules/loki_app_dot_net_api.js index 2760a0d61..eee538a1b 100644 --- a/js/modules/loki_app_dot_net_api.js +++ b/js/modules/loki_app_dot_net_api.js @@ -1,4 +1,4 @@ -/* global log, textsecure, libloki, Signal, Whisper, Headers, ConversationController, +/* global log, textsecure, libloki, Signal, Whisper, ConversationController, clearTimeout, MessageController, libsignal, StringView, window, _, dcodeIO, Buffer, lokiSnodeAPI, TextDecoder */ const nodeFetch = require('node-fetch'); @@ -53,6 +53,12 @@ class LokiAppDotNetServerAPI { channelId, conversationId ); + log.info( + 'LokiPublicChannelAPI started for', + channelId, + 'on', + this.baseServerUrl + ); this.channels.push(thisChannel); } return thisChannel; @@ -220,9 +226,11 @@ class LokiAppDotNetServerAPI { async refreshServerToken() { // if currently not in progress if (this.tokenPromise === null) { + // FIXME: add timeout + // a broken/stuck token endpoint can prevent you from removing channels // set lock this.tokenPromise = new Promise(async res => { - // request the oken + // request the token const token = await this.requestToken(); if (!token) { res(null); @@ -255,11 +263,13 @@ class LokiAppDotNetServerAPI { }; url.search = new URLSearchParams(params); - res = await nodeFetch(url); + res = await this.proxyFetch(url); } catch (e) { + log.error('requestToken request failed', e); return null; } if (!res.ok) { + log.error('requestToken request failed'); return null; } const body = await res.json(); @@ -281,7 +291,7 @@ class LokiAppDotNetServerAPI { }; try { - const res = await nodeFetch( + const res = await this.proxyFetch( `${this.baseServerUrl}/loki/v1/submit_challenge`, options ); @@ -291,7 +301,32 @@ class LokiAppDotNetServerAPI { } } - async _sendToProxy(fetchOptions, method, headers, endpoint) { + async proxyFetch(urlObj, fetchOptions) { + if ( + window.lokiFeatureFlags.useSnodeProxy && + (this.baseServerUrl === 'https://file-dev.lokinet.org' || + this.baseServerUrl === 'https://file.lokinet.org') + ) { + const finalOptions = { ...fetchOptions }; + if (!fetchOptions.method) { + finalOptions.method = 'GET'; + } + const urlStr = urlObj.toString(); + const endpoint = urlStr.replace(`${this.baseServerUrl}/`, ''); + const { response, result } = await this._sendToProxy( + endpoint, + finalOptions + ); + // emulate nodeFetch response... + return { + ok: result.status === 200, + json: () => response, + }; + } + return nodeFetch(urlObj, fetchOptions); + } + + async _sendToProxy(endpoint, fetchOptions) { const randSnode = await lokiSnodeAPI.getRandomSnodeAddress(); const url = `https://${randSnode.ip}:${randSnode.port}/file_proxy`; @@ -299,8 +334,8 @@ class LokiAppDotNetServerAPI { // I think this is a stream, we may need to collect it all? body: fetchOptions.body, // might need to b64 if binary... endpoint, - method, - headers, + method: fetchOptions.method, + headers: fetchOptions.headers, }; // from https://github.com/sindresorhus/is-stream/blob/master/index.js @@ -419,7 +454,7 @@ class LokiAppDotNetServerAPI { } else if (rawBody) { fetchOptions.body = rawBody; } - fetchOptions.headers = new Headers(headers); + fetchOptions.headers = headers; } catch (e) { log.info('serverRequest set up error:', JSON.stringify(e)); return { @@ -438,15 +473,12 @@ class LokiAppDotNetServerAPI { 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, - method, - headers, - endpoint + endpoint, + fetchOptions )); } else { - result = await nodeFetch(url, fetchOptions || undefined); + result = await nodeFetch(url, fetchOptions); txtResponse = await result.text(); response = JSON.parse(txtResponse); } @@ -714,7 +746,7 @@ class LokiAppDotNetServerAPI { options ); if (statusCode !== 200) { - log.warn('Failed to upload data to fileserver'); + log.warn('Failed to upload data to server', this.baseServerUrl); return null; }