Some refactoring from reviews, and include the token in the message pipeline instead of getting in message_api
This commit is contained in:
parent
b5fd01a468
commit
700ed5d2a8
32
app/sql.js
32
app/sql.js
|
@ -95,7 +95,7 @@ module.exports = {
|
|||
saveConversations,
|
||||
getConversationById,
|
||||
savePublicServerToken,
|
||||
getPublicServerTokenByServerName,
|
||||
getPublicServerTokenByServerUrl,
|
||||
updateConversation,
|
||||
removeConversation,
|
||||
getAllConversations,
|
||||
|
@ -795,7 +795,7 @@ async function updateToLokiSchemaVersion1(currentVersion, instance) {
|
|||
|
||||
await instance.run(
|
||||
`CREATE TABLE servers(
|
||||
server STRING PRIMARY KEY ASC,
|
||||
serverUrl STRING PRIMARY KEY ASC,
|
||||
token TEXT
|
||||
);`
|
||||
);
|
||||
|
@ -833,7 +833,7 @@ async function updateToLokiSchemaVersion1(currentVersion, instance) {
|
|||
};
|
||||
|
||||
const lokiPublicServerData = {
|
||||
server: 'chat.lokinet.org',
|
||||
serverUrl: 'https://chat.lokinet.org',
|
||||
token: null,
|
||||
};
|
||||
|
||||
|
@ -851,24 +851,24 @@ async function updateToLokiSchemaVersion1(currentVersion, instance) {
|
|||
|
||||
const publicChatData = {
|
||||
...baseData,
|
||||
id: `publicChat:1@${lokiPublicServerData.server}`,
|
||||
server: lokiPublicServerData.server,
|
||||
id: 'publicChat:1@chat.lokinet.org',
|
||||
server: lokiPublicServerData.serverUrl,
|
||||
name: 'Loki Public Chat',
|
||||
channelId: '1',
|
||||
};
|
||||
|
||||
const { server, token } = lokiPublicServerData;
|
||||
const { serverUrl, token } = lokiPublicServerData;
|
||||
|
||||
await instance.run(
|
||||
`INSERT INTO servers (
|
||||
server,
|
||||
serverUrl,
|
||||
token
|
||||
) values (
|
||||
$server,
|
||||
$serverUrl,
|
||||
$token
|
||||
);`,
|
||||
{
|
||||
$server: server,
|
||||
$serverUrl: serverUrl,
|
||||
$token: token,
|
||||
}
|
||||
);
|
||||
|
@ -1622,27 +1622,27 @@ async function removeConversation(id) {
|
|||
}
|
||||
|
||||
async function savePublicServerToken(data) {
|
||||
const { server, token } = data;
|
||||
const { serverUrl, token } = data;
|
||||
await db.run(
|
||||
`INSERT OR REPLACE INTO servers (
|
||||
server,
|
||||
serverUrl,
|
||||
token
|
||||
) values (
|
||||
$server,
|
||||
$serverUrl,
|
||||
$token
|
||||
)`,
|
||||
{
|
||||
$server: server,
|
||||
$serverUrl: serverUrl,
|
||||
$token: token,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async function getPublicServerTokenByServerName(server) {
|
||||
async function getPublicServerTokenByServerUrl(serverUrl) {
|
||||
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,
|
||||
BlockedNumberController,
|
||||
lokiP2pAPI,
|
||||
lokiPublicChatAPI,
|
||||
JobQueue
|
||||
*/
|
||||
|
||||
|
@ -1376,7 +1377,7 @@
|
|||
options.messageType = message.get('type');
|
||||
options.isPublic = this.isPublic();
|
||||
if (this.isPublic()) {
|
||||
options.channelSettings = this.getPublicSource();
|
||||
options.publicSendData = await this.getPublicSendData();
|
||||
}
|
||||
|
||||
const groupNumbers = this.getRecipients();
|
||||
|
@ -2068,6 +2069,22 @@
|
|||
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
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ module.exports = {
|
|||
getAllPublicConversations,
|
||||
getPublicConversationsByServer,
|
||||
savePublicServerToken,
|
||||
getPublicServerTokenByServerName,
|
||||
getPublicServerTokenByServerUrl,
|
||||
getAllGroupsInvolvingId,
|
||||
|
||||
searchConversations,
|
||||
|
@ -773,8 +773,8 @@ async function savePublicServerToken(data) {
|
|||
await channels.savePublicServerToken(data);
|
||||
}
|
||||
|
||||
async function getPublicServerTokenByServerName(server) {
|
||||
const token = await channels.getPublicServerTokenByServerName(server);
|
||||
async function getPublicServerTokenByServerUrl(serverUrl) {
|
||||
const token = await channels.getPublicServerTokenByServerUrl(serverUrl);
|
||||
return token;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* eslint-disable no-await-in-loop */
|
||||
/* eslint-disable no-loop-func */
|
||||
/* global log, dcodeIO, window, callWorker,
|
||||
lokiP2pAPI, lokiSnodeAPI, lokiPublicChatAPI, textsecure */
|
||||
/* global log, dcodeIO, window, callWorker, lokiP2pAPI, lokiSnodeAPI, textsecure */
|
||||
|
||||
const _ = require('lodash');
|
||||
const { rpc } = require('./loki_rpc');
|
||||
|
@ -81,7 +80,7 @@ class LokiMessageAPI {
|
|||
isPing = false,
|
||||
isPublic = false,
|
||||
numConnections = DEFAULT_CONNECTIONS,
|
||||
channelSettings = null,
|
||||
publicSendData = null,
|
||||
} = options;
|
||||
// Data required to identify a message in a conversation
|
||||
const messageEventData = {
|
||||
|
@ -90,20 +89,12 @@ class LokiMessageAPI {
|
|||
};
|
||||
|
||||
if (isPublic) {
|
||||
// could we emit back to LokiPublicChannelAPI somehow?
|
||||
const { server, channelId, conversationId } = channelSettings;
|
||||
const serverAPI = lokiPublicChatAPI.findOrCreateServer(server);
|
||||
const token = await serverAPI.getServerToken();
|
||||
const { token, publicEndpoint } = publicSendData;
|
||||
if (!token) {
|
||||
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;
|
||||
let displayName = 'Anonymous';
|
||||
|
|
|
@ -46,12 +46,11 @@ class LokiPublicChatAPI extends EventEmitter {
|
|||
}
|
||||
|
||||
class LokiPublicServerAPI {
|
||||
constructor(chatAPI, hostport) {
|
||||
constructor(chatAPI, url) {
|
||||
this.chatAPI = chatAPI;
|
||||
this.server = hostport;
|
||||
this.channels = [];
|
||||
this.tokenPromise = null;
|
||||
this.baseServerUrl = `https://${this.server}`;
|
||||
this.baseServerUrl = url;
|
||||
}
|
||||
findOrCreateChannel(channelId, conversationId) {
|
||||
let thisChannel = this.channels.find(
|
||||
|
@ -80,12 +79,14 @@ class LokiPublicServerAPI {
|
|||
}
|
||||
|
||||
async getOrRefreshServerToken() {
|
||||
let token = await Signal.Data.getPublicServerTokenByServerName(this.server);
|
||||
let token = await Signal.Data.getPublicServerTokenByServerUrl(
|
||||
this.baseServerUrl
|
||||
);
|
||||
if (!token) {
|
||||
token = await this.refreshServerToken();
|
||||
if (token) {
|
||||
await Signal.Data.savePublicServerToken({
|
||||
server: this.server,
|
||||
serverUrl: this.baseServerUrl,
|
||||
token,
|
||||
});
|
||||
}
|
||||
|
@ -176,7 +177,7 @@ class LokiPublicChannelAPI {
|
|||
}
|
||||
|
||||
getEndpoint() {
|
||||
const endpoint = `https://${this.serverAPI.server}/channels/${
|
||||
const endpoint = `${this.serverAPI.baseServerUrl}/channels/${
|
||||
this.channelId
|
||||
}/messages`;
|
||||
return endpoint;
|
||||
|
@ -255,7 +256,10 @@ class LokiPublicChannelAPI {
|
|||
let timestamp = new Date(adnMessage.created_at).getTime();
|
||||
let from = adnMessage.user.username;
|
||||
let source;
|
||||
if (adnMessage.annotations.length) {
|
||||
if (adnMessage.is_deleted) {
|
||||
return;
|
||||
}
|
||||
if (adnMessage.annotations !== []) {
|
||||
const noteValue = adnMessage.annotations[0].value;
|
||||
({ from, timestamp, source } = noteValue);
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
|
||||
async function DHDecrypt(symmetricKey, ivAndCiphertext) {
|
||||
const iv = ivAndCiphertext.slice(0, IV_LENGTH);
|
||||
const cipherText = ivAndCiphertext.slice(IV_LENGTH);
|
||||
return libsignal.crypto.decrypt(symmetricKey, cipherText, iv);
|
||||
const ciphertext = ivAndCiphertext.slice(IV_LENGTH);
|
||||
return libsignal.crypto.decrypt(symmetricKey, ciphertext, iv);
|
||||
}
|
||||
|
||||
class FallBackSessionCipher {
|
||||
|
@ -131,18 +131,18 @@
|
|||
return this._ephemeralPubKeyHex;
|
||||
}
|
||||
|
||||
async decrypt(snodeAddress, ivAndCipherTextBase64) {
|
||||
const ivAndCipherText = dcodeIO.ByteBuffer.wrap(
|
||||
ivAndCipherTextBase64,
|
||||
async decrypt(snodeAddress, ivAndCiphertextBase64) {
|
||||
const ivAndCiphertext = dcodeIO.ByteBuffer.wrap(
|
||||
ivAndCiphertextBase64,
|
||||
'base64'
|
||||
).toArrayBuffer();
|
||||
const symmetricKey = await this._getSymmetricKey(snodeAddress);
|
||||
try {
|
||||
const decrypted = await DHDecrypt(symmetricKey, ivAndCipherText);
|
||||
const decrypted = await DHDecrypt(symmetricKey, ivAndCiphertext);
|
||||
const decoder = new TextDecoder();
|
||||
return decoder.decode(decrypted);
|
||||
} catch (e) {
|
||||
return ivAndCipherText;
|
||||
return ivAndCiphertext;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,17 +153,15 @@
|
|||
plainText = textEncoder.encode(plainText);
|
||||
}
|
||||
const symmetricKey = await this._getSymmetricKey(snodeAddress);
|
||||
const cipherText = await DHEncrypt(symmetricKey, plainText);
|
||||
return dcodeIO.ByteBuffer.wrap(cipherText).toString('base64');
|
||||
const ciphertext = await DHEncrypt(symmetricKey, plainText);
|
||||
return dcodeIO.ByteBuffer.wrap(ciphertext).toString('base64');
|
||||
}
|
||||
}
|
||||
|
||||
async function decryptToken({ ivAndCipherText64, serverPubKey64 }) {
|
||||
const ivAndCipherText = new Uint8Array(
|
||||
dcodeIO.ByteBuffer.fromBase64(ivAndCipherText64).toArrayBuffer()
|
||||
async function decryptToken({ cipherText64, serverPubKey64 }) {
|
||||
const ivAndCiphertext = new Uint8Array(
|
||||
dcodeIO.ByteBuffer.fromBase64(cipherText64).toArrayBuffer()
|
||||
);
|
||||
const iv = ivAndCipherText.slice(0, IV_LENGTH);
|
||||
const cipherText = ivAndCipherText.slice(IV_LENGTH);
|
||||
|
||||
const serverPubKey = new Uint8Array(
|
||||
dcodeIO.ByteBuffer.fromBase64(serverPubKey64).toArrayBuffer()
|
||||
|
@ -174,7 +172,8 @@
|
|||
privKey
|
||||
);
|
||||
|
||||
const token = await libsignal.crypto.decrypt(symmetricKey, cipherText, iv);
|
||||
const token = await DHDecrypt(symmetricKey, ivAndCiphertext);
|
||||
|
||||
const tokenString = dcodeIO.ByteBuffer.wrap(token).toString('utf8');
|
||||
return tokenString;
|
||||
}
|
||||
|
|
|
@ -50,12 +50,12 @@ function OutgoingMessage(
|
|||
messageType,
|
||||
isPing,
|
||||
isPublic,
|
||||
channelSettings,
|
||||
publicSendData,
|
||||
} =
|
||||
options || {};
|
||||
this.numberInfo = numberInfo;
|
||||
this.isPublic = isPublic;
|
||||
this.channelSettings = channelSettings;
|
||||
this.publicSendData = publicSendData;
|
||||
this.senderCertificate = senderCertificate;
|
||||
this.online = online;
|
||||
this.messageType = messageType || 'outgoing';
|
||||
|
@ -205,7 +205,7 @@ OutgoingMessage.prototype = {
|
|||
};
|
||||
options.isPublic = this.isPublic;
|
||||
if (this.isPublic) {
|
||||
options.channelSettings = this.channelSettings;
|
||||
options.publicSendData = this.publicSendData;
|
||||
}
|
||||
await lokiMessageAPI.sendMessage(pubKey, data, timestamp, ttl, options);
|
||||
} catch (e) {
|
||||
|
|
Loading…
Reference in New Issue