Some refactoring from reviews, and include the token in the message pipeline instead of getting in message_api

pull/447/head
Beaudan Brown 6 years ago
parent b5fd01a468
commit 700ed5d2a8

@ -95,7 +95,7 @@ module.exports = {
saveConversations, saveConversations,
getConversationById, getConversationById,
savePublicServerToken, savePublicServerToken,
getPublicServerTokenByServerName, getPublicServerTokenByServerUrl,
updateConversation, updateConversation,
removeConversation, removeConversation,
getAllConversations, getAllConversations,
@ -795,7 +795,7 @@ async function updateToLokiSchemaVersion1(currentVersion, instance) {
await instance.run( await instance.run(
`CREATE TABLE servers( `CREATE TABLE servers(
server STRING PRIMARY KEY ASC, serverUrl STRING PRIMARY KEY ASC,
token TEXT token TEXT
);` );`
); );
@ -833,7 +833,7 @@ async function updateToLokiSchemaVersion1(currentVersion, instance) {
}; };
const lokiPublicServerData = { const lokiPublicServerData = {
server: 'chat.lokinet.org', serverUrl: 'https://chat.lokinet.org',
token: null, token: null,
}; };
@ -851,24 +851,24 @@ async function updateToLokiSchemaVersion1(currentVersion, instance) {
const publicChatData = { const publicChatData = {
...baseData, ...baseData,
id: `publicChat:1@${lokiPublicServerData.server}`, id: 'publicChat:1@chat.lokinet.org',
server: lokiPublicServerData.server, server: lokiPublicServerData.serverUrl,
name: 'Loki Public Chat', name: 'Loki Public Chat',
channelId: '1', channelId: '1',
}; };
const { server, token } = lokiPublicServerData; const { serverUrl, token } = lokiPublicServerData;
await instance.run( await instance.run(
`INSERT INTO servers ( `INSERT INTO servers (
server, serverUrl,
token token
) values ( ) values (
$server, $serverUrl,
$token $token
);`, );`,
{ {
$server: server, $serverUrl: serverUrl,
$token: token, $token: token,
} }
); );
@ -1622,27 +1622,27 @@ async function removeConversation(id) {
} }
async function savePublicServerToken(data) { async function savePublicServerToken(data) {
const { server, token } = data; const { serverUrl, token } = data;
await db.run( await db.run(
`INSERT OR REPLACE INTO servers ( `INSERT OR REPLACE INTO servers (
server, serverUrl,
token token
) values ( ) values (
$server, $serverUrl,
$token $token
)`, )`,
{ {
$server: server, $serverUrl: serverUrl,
$token: token, $token: token,
} }
); );
} }
async function getPublicServerTokenByServerName(server) { async function getPublicServerTokenByServerUrl(serverUrl) {
const row = await db.get( const row = await db.get(
'SELECT * FROM servers WHERE server = $server;', 'SELECT * FROM servers WHERE serverUrl = $serverUrl;',
{ {
$server: server, $serverUrl: serverUrl,
} }
); );

@ -11,6 +11,7 @@
clipboard, clipboard,
BlockedNumberController, BlockedNumberController,
lokiP2pAPI, lokiP2pAPI,
lokiPublicChatAPI,
JobQueue JobQueue
*/ */
@ -1376,7 +1377,7 @@
options.messageType = message.get('type'); options.messageType = message.get('type');
options.isPublic = this.isPublic(); options.isPublic = this.isPublic();
if (this.isPublic()) { if (this.isPublic()) {
options.channelSettings = this.getPublicSource(); options.publicSendData = await this.getPublicSendData();
} }
const groupNumbers = this.getRecipients(); const groupNumbers = this.getRecipients();
@ -2068,6 +2069,22 @@
conversationId: this.get('id'), conversationId: this.get('id'),
}; };
}, },
async getPublicSendData() {
const serverAPI = lokiPublicChatAPI.findOrCreateServer(
this.get('server')
);
// Can be null if fails
const token = await serverAPI.getOrRefreshServerToken();
const channelAPI = serverAPI.findOrCreateChannel(
this.get('channelId'),
this.id
);
const publicEndpoint = channelAPI.getEndpoint();
return {
publicEndpoint,
token,
};
},
// SIGNAL PROFILES // SIGNAL PROFILES

@ -122,7 +122,7 @@ module.exports = {
getAllPublicConversations, getAllPublicConversations,
getPublicConversationsByServer, getPublicConversationsByServer,
savePublicServerToken, savePublicServerToken,
getPublicServerTokenByServerName, getPublicServerTokenByServerUrl,
getAllGroupsInvolvingId, getAllGroupsInvolvingId,
searchConversations, searchConversations,
@ -773,8 +773,8 @@ async function savePublicServerToken(data) {
await channels.savePublicServerToken(data); await channels.savePublicServerToken(data);
} }
async function getPublicServerTokenByServerName(server) { async function getPublicServerTokenByServerUrl(serverUrl) {
const token = await channels.getPublicServerTokenByServerName(server); const token = await channels.getPublicServerTokenByServerUrl(serverUrl);
return token; return token;
} }

@ -1,7 +1,6 @@
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
/* eslint-disable no-loop-func */ /* eslint-disable no-loop-func */
/* global log, dcodeIO, window, callWorker, /* global log, dcodeIO, window, callWorker, lokiP2pAPI, lokiSnodeAPI, textsecure */
lokiP2pAPI, lokiSnodeAPI, lokiPublicChatAPI, textsecure */
const _ = require('lodash'); const _ = require('lodash');
const { rpc } = require('./loki_rpc'); const { rpc } = require('./loki_rpc');
@ -81,7 +80,7 @@ class LokiMessageAPI {
isPing = false, isPing = false,
isPublic = false, isPublic = false,
numConnections = DEFAULT_CONNECTIONS, numConnections = DEFAULT_CONNECTIONS,
channelSettings = null, publicSendData = null,
} = options; } = options;
// Data required to identify a message in a conversation // Data required to identify a message in a conversation
const messageEventData = { const messageEventData = {
@ -90,20 +89,12 @@ class LokiMessageAPI {
}; };
if (isPublic) { if (isPublic) {
// could we emit back to LokiPublicChannelAPI somehow? const { token, publicEndpoint } = publicSendData;
const { server, channelId, conversationId } = channelSettings;
const serverAPI = lokiPublicChatAPI.findOrCreateServer(server);
const token = await serverAPI.getServerToken();
if (!token) { if (!token) {
throw new window.textsecure.PublicChatError( throw new window.textsecure.PublicChatError(
`Failed to retrieve valid token for ${conversationId}` `Failed to retrieve valid token for ${publicEndpoint}`
); );
} }
const channelAPI = serverAPI.findOrCreateChannel(
channelId,
conversationId
);
const publicEndpoint = channelAPI.getEndpoint(conversationId);
const { profile } = data; const { profile } = data;
let displayName = 'Anonymous'; let displayName = 'Anonymous';

@ -46,12 +46,11 @@ class LokiPublicChatAPI extends EventEmitter {
} }
class LokiPublicServerAPI { class LokiPublicServerAPI {
constructor(chatAPI, hostport) { constructor(chatAPI, url) {
this.chatAPI = chatAPI; this.chatAPI = chatAPI;
this.server = hostport;
this.channels = []; this.channels = [];
this.tokenPromise = null; this.tokenPromise = null;
this.baseServerUrl = `https://${this.server}`; this.baseServerUrl = url;
} }
findOrCreateChannel(channelId, conversationId) { findOrCreateChannel(channelId, conversationId) {
let thisChannel = this.channels.find( let thisChannel = this.channels.find(
@ -80,12 +79,14 @@ class LokiPublicServerAPI {
} }
async getOrRefreshServerToken() { async getOrRefreshServerToken() {
let token = await Signal.Data.getPublicServerTokenByServerName(this.server); let token = await Signal.Data.getPublicServerTokenByServerUrl(
this.baseServerUrl
);
if (!token) { if (!token) {
token = await this.refreshServerToken(); token = await this.refreshServerToken();
if (token) { if (token) {
await Signal.Data.savePublicServerToken({ await Signal.Data.savePublicServerToken({
server: this.server, serverUrl: this.baseServerUrl,
token, token,
}); });
} }
@ -176,7 +177,7 @@ class LokiPublicChannelAPI {
} }
getEndpoint() { getEndpoint() {
const endpoint = `https://${this.serverAPI.server}/channels/${ const endpoint = `${this.serverAPI.baseServerUrl}/channels/${
this.channelId this.channelId
}/messages`; }/messages`;
return endpoint; return endpoint;
@ -255,7 +256,10 @@ class LokiPublicChannelAPI {
let timestamp = new Date(adnMessage.created_at).getTime(); let timestamp = new Date(adnMessage.created_at).getTime();
let from = adnMessage.user.username; let from = adnMessage.user.username;
let source; let source;
if (adnMessage.annotations.length) { if (adnMessage.is_deleted) {
return;
}
if (adnMessage.annotations !== []) {
const noteValue = adnMessage.annotations[0].value; const noteValue = adnMessage.annotations[0].value;
({ from, timestamp, source } = noteValue); ({ from, timestamp, source } = noteValue);
} }

@ -34,8 +34,8 @@
async function DHDecrypt(symmetricKey, ivAndCiphertext) { async function DHDecrypt(symmetricKey, ivAndCiphertext) {
const iv = ivAndCiphertext.slice(0, IV_LENGTH); const iv = ivAndCiphertext.slice(0, IV_LENGTH);
const cipherText = ivAndCiphertext.slice(IV_LENGTH); const ciphertext = ivAndCiphertext.slice(IV_LENGTH);
return libsignal.crypto.decrypt(symmetricKey, cipherText, iv); return libsignal.crypto.decrypt(symmetricKey, ciphertext, iv);
} }
class FallBackSessionCipher { class FallBackSessionCipher {
@ -131,18 +131,18 @@
return this._ephemeralPubKeyHex; return this._ephemeralPubKeyHex;
} }
async decrypt(snodeAddress, ivAndCipherTextBase64) { async decrypt(snodeAddress, ivAndCiphertextBase64) {
const ivAndCipherText = dcodeIO.ByteBuffer.wrap( const ivAndCiphertext = dcodeIO.ByteBuffer.wrap(
ivAndCipherTextBase64, ivAndCiphertextBase64,
'base64' 'base64'
).toArrayBuffer(); ).toArrayBuffer();
const symmetricKey = await this._getSymmetricKey(snodeAddress); const symmetricKey = await this._getSymmetricKey(snodeAddress);
try { try {
const decrypted = await DHDecrypt(symmetricKey, ivAndCipherText); const decrypted = await DHDecrypt(symmetricKey, ivAndCiphertext);
const decoder = new TextDecoder(); const decoder = new TextDecoder();
return decoder.decode(decrypted); return decoder.decode(decrypted);
} catch (e) { } catch (e) {
return ivAndCipherText; return ivAndCiphertext;
} }
} }
@ -153,17 +153,15 @@
plainText = textEncoder.encode(plainText); plainText = textEncoder.encode(plainText);
} }
const symmetricKey = await this._getSymmetricKey(snodeAddress); const symmetricKey = await this._getSymmetricKey(snodeAddress);
const cipherText = await DHEncrypt(symmetricKey, plainText); const ciphertext = await DHEncrypt(symmetricKey, plainText);
return dcodeIO.ByteBuffer.wrap(cipherText).toString('base64'); return dcodeIO.ByteBuffer.wrap(ciphertext).toString('base64');
} }
} }
async function decryptToken({ ivAndCipherText64, serverPubKey64 }) { async function decryptToken({ cipherText64, serverPubKey64 }) {
const ivAndCipherText = new Uint8Array( const ivAndCiphertext = new Uint8Array(
dcodeIO.ByteBuffer.fromBase64(ivAndCipherText64).toArrayBuffer() dcodeIO.ByteBuffer.fromBase64(cipherText64).toArrayBuffer()
); );
const iv = ivAndCipherText.slice(0, IV_LENGTH);
const cipherText = ivAndCipherText.slice(IV_LENGTH);
const serverPubKey = new Uint8Array( const serverPubKey = new Uint8Array(
dcodeIO.ByteBuffer.fromBase64(serverPubKey64).toArrayBuffer() dcodeIO.ByteBuffer.fromBase64(serverPubKey64).toArrayBuffer()
@ -174,7 +172,8 @@
privKey privKey
); );
const token = await libsignal.crypto.decrypt(symmetricKey, cipherText, iv); const token = await DHDecrypt(symmetricKey, ivAndCiphertext);
const tokenString = dcodeIO.ByteBuffer.wrap(token).toString('utf8'); const tokenString = dcodeIO.ByteBuffer.wrap(token).toString('utf8');
return tokenString; return tokenString;
} }

@ -50,12 +50,12 @@ function OutgoingMessage(
messageType, messageType,
isPing, isPing,
isPublic, isPublic,
channelSettings, publicSendData,
} = } =
options || {}; options || {};
this.numberInfo = numberInfo; this.numberInfo = numberInfo;
this.isPublic = isPublic; this.isPublic = isPublic;
this.channelSettings = channelSettings; this.publicSendData = publicSendData;
this.senderCertificate = senderCertificate; this.senderCertificate = senderCertificate;
this.online = online; this.online = online;
this.messageType = messageType || 'outgoing'; this.messageType = messageType || 'outgoing';
@ -205,7 +205,7 @@ OutgoingMessage.prototype = {
}; };
options.isPublic = this.isPublic; options.isPublic = this.isPublic;
if (this.isPublic) { if (this.isPublic) {
options.channelSettings = this.channelSettings; options.publicSendData = this.publicSendData;
} }
await lokiMessageAPI.sendMessage(pubKey, data, timestamp, ttl, options); await lokiMessageAPI.sendMessage(pubKey, data, timestamp, ttl, options);
} catch (e) { } catch (e) {

Loading…
Cancel
Save