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/js/modules/loki_public_chat_api.js

234 lines
7.0 KiB
JavaScript

/* global log, window, process, URL, dcodeIO */
const EventEmitter = require('events');
const LokiAppDotNetAPI = require('./loki_app_dot_net_api');
const nodeFetch = require('node-fetch');
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
// 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.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
);
}
}
// doesn't support it, fallback
log.info(
`loki_public_chat::validOpenGroupServer - directly contacting ${url.toString()}`
);
// 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();
} 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;
};
class LokiPublicChatFactoryAPI extends EventEmitter {
constructor(ourKey) {
super();
this.ourKey = ourKey;
this.servers = [];
this.allMembers = [];
this.openGroupPubKeys = {};
// Multidevice states
this.primaryUserProfileName = {};
}
5 years ago
// MessageReceiver.connect calls this
// start polling in all existing registered channels
async open() {
await Promise.all(this.servers.map(server => server.open()));
}
// MessageReceiver.close
async close() {
await Promise.all(this.servers.map(server => server.close()));
}
// server getter/factory
async findOrCreateServer(serverUrl) {
let thisServer = this.servers.find(
server => server.baseServerUrl === serverUrl
);
if (!thisServer) {
log.info(`loki_public_chat::findOrCreateServer - creating ${serverUrl}`);
const serverIsValid = await validOpenGroupServer(serverUrl);
if (!serverIsValid) {
// FIXME: add toast?
log.error(
`loki_public_chat::findOrCreateServer - error: ${serverUrl} is not valid`
);
return null;
}
// after verification then we can start up all the pollers
Integration tests (#975) * add first integration test Session Checking window title Checking window count Can restore from seed * FIXME torevert once found why this crash on app close * [test] add join valid open group test * [test] validate cannot join two times the same open group * [test] move common things to common.js * [test] move tests to separate files * [test] clean * [test] add send message to open group test * [test] lint * [test] rename hooks -> common * [test] add 15s delay before considering test as slow * upgrade electron 8.0.3 and spectron 10.0.0 * [test] signin from seed: validate pubkey * Replace spellchecker in favor of typo-js * [test] refactor common calls to common.js * [test] add two different pubkey, mnemonic and displayname * [test] FIXME unsafe eval needed for now * [test] add: add friends test * [test] working multi instance tests * [test] FIXME disable snodeproxy * [test] update yarn.lock * [test] make tests more robust with restart from scratch each test * [test] add link of two devices test and hard rm of apps before start (rm -r) * remove unused file * [test] lint * [test] add registration from generated pubkey test * [test] add beginning of network stub * [test] stub "token" endpoint * [test] add test of one message on pub group pull * [test] add starting port randomize. looks to help for some bad start with multi instance * [test] add stub for one to one chats (sessions) * [test] clean code * [test] finish add friend test and stub snode server * [test] stub calls during link device test * [test] add a flag to show some logs on stubbed snode * [test] finish link of two device test. check both pubkey matches * [test] add and use function to wrap erase+start+login+stub app * [test] add method to login as friend and closed group test&messages * Revert "[test] FIXME unsafe eval needed for now" This reverts commit de5322fdae6cdab8e3b9bd9a52b7d172c9bc2d26. * [test] apply review * [test] fix lint * [test] fix existing test with new spectron version * [test] fix lint * [test] refactor page objects * [test] add delete account test * [test] add unlink of two device test * [test] make tiny waitForExists -> isExisting * [test] add checks of link new device buttons * upgrade fs-extra@9.0.0 * address pr review * [test] fix spell_check test Co-authored-by: Josh Perez <60019601+josh-signal@users.noreply.github.com>
5 years ago
if (process.env.USE_STUBBED_NETWORK) {
5 years ago
// eslint-disable-next-line global-require
const StubAppDotNetAPI = require('../../integration_test/stubs/stub_app_dot_net_api.js');
Integration tests (#975) * add first integration test Session Checking window title Checking window count Can restore from seed * FIXME torevert once found why this crash on app close * [test] add join valid open group test * [test] validate cannot join two times the same open group * [test] move common things to common.js * [test] move tests to separate files * [test] clean * [test] add send message to open group test * [test] lint * [test] rename hooks -> common * [test] add 15s delay before considering test as slow * upgrade electron 8.0.3 and spectron 10.0.0 * [test] signin from seed: validate pubkey * Replace spellchecker in favor of typo-js * [test] refactor common calls to common.js * [test] add two different pubkey, mnemonic and displayname * [test] FIXME unsafe eval needed for now * [test] add: add friends test * [test] working multi instance tests * [test] FIXME disable snodeproxy * [test] update yarn.lock * [test] make tests more robust with restart from scratch each test * [test] add link of two devices test and hard rm of apps before start (rm -r) * remove unused file * [test] lint * [test] add registration from generated pubkey test * [test] add beginning of network stub * [test] stub "token" endpoint * [test] add test of one message on pub group pull * [test] add starting port randomize. looks to help for some bad start with multi instance * [test] add stub for one to one chats (sessions) * [test] clean code * [test] finish add friend test and stub snode server * [test] stub calls during link device test * [test] add a flag to show some logs on stubbed snode * [test] finish link of two device test. check both pubkey matches * [test] add and use function to wrap erase+start+login+stub app * [test] add method to login as friend and closed group test&messages * Revert "[test] FIXME unsafe eval needed for now" This reverts commit de5322fdae6cdab8e3b9bd9a52b7d172c9bc2d26. * [test] apply review * [test] fix lint * [test] fix existing test with new spectron version * [test] fix lint * [test] refactor page objects * [test] add delete account test * [test] add unlink of two device test * [test] make tiny waitForExists -> isExisting * [test] add checks of link new device buttons * upgrade fs-extra@9.0.0 * address pr review * [test] fix spell_check test Co-authored-by: Josh Perez <60019601+josh-signal@users.noreply.github.com>
5 years ago
thisServer = new StubAppDotNetAPI(this.ourKey, serverUrl);
} else {
thisServer = new LokiAppDotNetAPI(this.ourKey, serverUrl);
if (this.openGroupPubKeys[serverUrl]) {
thisServer.getPubKeyForUrl();
if (!thisServer.pubKeyHex) {
log.warn(
`loki_public_chat::findOrCreateServer - failed to set public key`
);
}
}
Integration tests (#975) * add first integration test Session Checking window title Checking window count Can restore from seed * FIXME torevert once found why this crash on app close * [test] add join valid open group test * [test] validate cannot join two times the same open group * [test] move common things to common.js * [test] move tests to separate files * [test] clean * [test] add send message to open group test * [test] lint * [test] rename hooks -> common * [test] add 15s delay before considering test as slow * upgrade electron 8.0.3 and spectron 10.0.0 * [test] signin from seed: validate pubkey * Replace spellchecker in favor of typo-js * [test] refactor common calls to common.js * [test] add two different pubkey, mnemonic and displayname * [test] FIXME unsafe eval needed for now * [test] add: add friends test * [test] working multi instance tests * [test] FIXME disable snodeproxy * [test] update yarn.lock * [test] make tests more robust with restart from scratch each test * [test] add link of two devices test and hard rm of apps before start (rm -r) * remove unused file * [test] lint * [test] add registration from generated pubkey test * [test] add beginning of network stub * [test] stub "token" endpoint * [test] add test of one message on pub group pull * [test] add starting port randomize. looks to help for some bad start with multi instance * [test] add stub for one to one chats (sessions) * [test] clean code * [test] finish add friend test and stub snode server * [test] stub calls during link device test * [test] add a flag to show some logs on stubbed snode * [test] finish link of two device test. check both pubkey matches * [test] add and use function to wrap erase+start+login+stub app * [test] add method to login as friend and closed group test&messages * Revert "[test] FIXME unsafe eval needed for now" This reverts commit de5322fdae6cdab8e3b9bd9a52b7d172c9bc2d26. * [test] apply review * [test] fix lint * [test] fix existing test with new spectron version * [test] fix lint * [test] refactor page objects * [test] add delete account test * [test] add unlink of two device test * [test] make tiny waitForExists -> isExisting * [test] add checks of link new device buttons * upgrade fs-extra@9.0.0 * address pr review * [test] fix spell_check test Co-authored-by: Josh Perez <60019601+josh-signal@users.noreply.github.com>
5 years ago
}
const gotToken = await thisServer.getOrRefreshServerToken();
if (!gotToken) {
log.warn(
`loki_public_chat::findOrCreateServer - Invalid server ${serverUrl}`
);
return null;
}
if (window.isDev) {
log.info(
`loki_public_chat::findOrCreateServer - set token ${
thisServer.token
} for ${serverUrl}`
);
}
this.servers.push(thisServer);
}
return thisServer;
}
// channel getter/factory
async findOrCreateChannel(serverUrl, channelId, conversationId) {
const server = await this.findOrCreateServer(serverUrl);
if (!server) {
log.error(`Failed to create server for: ${serverUrl}`);
return null;
}
return server.findOrCreateChannel(this, channelId, conversationId);
}
// deallocate resources server uses
unregisterChannel(serverUrl, channelId) {
const i = this.servers.findIndex(
server => server.baseServerUrl === serverUrl
);
if (i === -1) {
log.warn(`Tried to unregister from nonexistent server ${serverUrl}`);
return;
}
const thisServer = this.servers[i];
if (!thisServer) {
log.warn(`Tried to unregister from nonexistent server ${i}`);
return;
}
thisServer.unregisterChannel(channelId);
this.servers.splice(i, 1);
}
// shouldn't this be scoped per conversation?
async getListOfMembers() {
// enable in the next release
/*
let members = [];
await Promise.all(this.servers.map(async server => {
await Promise.all(server.channels.map(async channel => {
const newMembers = await channel.getSubscribers();
members = [...members, ...newMembers];
}));
}));
const results = members.map(member => {
return { authorPhoneNumber: member.username };
});
*/
return this.allMembers;
}
// TODO: make this private (or remove altogether) when
// we switch to polling the server for group members
setListOfMembers(members) {
this.allMembers = members;
}
async setProfileName(profileName) {
await Promise.all(
this.servers.map(async server => {
await server.setProfileName(profileName);
})
);
}
async setHomeServer(homeServer) {
await Promise.all(
this.servers.map(async server => {
// this may fail
// but we can't create a sql table to remember to retry forever
// I think we just silently fail for now
await server.setHomeServer(homeServer);
})
);
}
async setAvatar(url, profileKey) {
await Promise.all(
this.servers.map(async server => {
// this may fail
// but we can't create a sql table to remember to retry forever
// I think we just silently fail for now
await server.setAvatar(url, profileKey);
})
);
}
}
module.exports = LokiPublicChatFactoryAPI;