|
|
|
@ -13,12 +13,9 @@ const PUBLICCHAT_CHAN_POLL_EVERY = 20 * 1000; // 20s
|
|
|
|
|
const PUBLICCHAT_DELETION_POLL_EVERY = 5 * 1000; // 5s
|
|
|
|
|
const PUBLICCHAT_MOD_POLL_EVERY = 30 * 1000; // 30s
|
|
|
|
|
|
|
|
|
|
const LOKIFOUNDATION_DEVFILESERVER_PUBKEY =
|
|
|
|
|
'BSZiMVxOco/b3sYfaeyiMWv/JnqokxGXkHoclEx8TmZ6';
|
|
|
|
|
const LOKIFOUNDATION_FILESERVER_PUBKEY =
|
|
|
|
|
'BWJQnVm97sQE3Q1InB4Vuo+U/T1hmwHBv0ipkiv8tzEc';
|
|
|
|
|
const LOKIFOUNDATION_APNS_PUBKEY =
|
|
|
|
|
'BWQqZYWRl0LlotTcUSRJZPvNi8qyt1YSQH3li4EHQNBJ';
|
|
|
|
|
const LOKIFOUNDATION_DEVFILESERVER_PUBKEY = 'BSZiMVxOco/b3sYfaeyiMWv/JnqokxGXkHoclEx8TmZ6';
|
|
|
|
|
const LOKIFOUNDATION_FILESERVER_PUBKEY = 'BWJQnVm97sQE3Q1InB4Vuo+U/T1hmwHBv0ipkiv8tzEc';
|
|
|
|
|
const LOKIFOUNDATION_APNS_PUBKEY = 'BWQqZYWRl0LlotTcUSRJZPvNi8qyt1YSQH3li4EHQNBJ';
|
|
|
|
|
|
|
|
|
|
const urlPubkeyMap = {
|
|
|
|
|
'https://file-dev.getsession.org': LOKIFOUNDATION_DEVFILESERVER_PUBKEY,
|
|
|
|
@ -64,27 +61,15 @@ class LokiAppDotNetServerAPI {
|
|
|
|
|
|
|
|
|
|
// channel getter/factory
|
|
|
|
|
async findOrCreateChannel(chatAPI, channelId, conversationId) {
|
|
|
|
|
let thisChannel = this.channels.find(
|
|
|
|
|
channel => channel.channelId === channelId
|
|
|
|
|
);
|
|
|
|
|
let thisChannel = this.channels.find(channel => channel.channelId === channelId);
|
|
|
|
|
if (!thisChannel) {
|
|
|
|
|
// make sure we're subscribed
|
|
|
|
|
// eventually we'll need to move to account registration/add server
|
|
|
|
|
await this.serverRequest(`channels/${channelId}/subscribe`, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
});
|
|
|
|
|
thisChannel = new LokiPublicChannelAPI(
|
|
|
|
|
chatAPI,
|
|
|
|
|
this,
|
|
|
|
|
channelId,
|
|
|
|
|
conversationId
|
|
|
|
|
);
|
|
|
|
|
log.info(
|
|
|
|
|
'LokiPublicChannelAPI started for',
|
|
|
|
|
channelId,
|
|
|
|
|
'on',
|
|
|
|
|
this.baseServerUrl
|
|
|
|
|
);
|
|
|
|
|
thisChannel = new LokiPublicChannelAPI(chatAPI, this, channelId, conversationId);
|
|
|
|
|
log.info('LokiPublicChannelAPI started for', channelId, 'on', this.baseServerUrl);
|
|
|
|
|
this.channels.push(thisChannel);
|
|
|
|
|
}
|
|
|
|
|
return thisChannel;
|
|
|
|
@ -127,9 +112,7 @@ class LokiAppDotNetServerAPI {
|
|
|
|
|
// Hard coded
|
|
|
|
|
let pubKeyAB;
|
|
|
|
|
if (urlPubkeyMap && urlPubkeyMap[this.baseServerUrl]) {
|
|
|
|
|
pubKeyAB = window.Signal.Crypto.base64ToArrayBuffer(
|
|
|
|
|
urlPubkeyMap[this.baseServerUrl]
|
|
|
|
|
);
|
|
|
|
|
pubKeyAB = window.Signal.Crypto.base64ToArrayBuffer(urlPubkeyMap[this.baseServerUrl]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// do we have their pubkey locally?
|
|
|
|
@ -142,8 +125,7 @@ class LokiAppDotNetServerAPI {
|
|
|
|
|
window.lokiPublicChatAPI.openGroupPubKeys &&
|
|
|
|
|
window.lokiPublicChatAPI.openGroupPubKeys[this.baseServerUrl]
|
|
|
|
|
) {
|
|
|
|
|
pubKeyAB =
|
|
|
|
|
window.lokiPublicChatAPI.openGroupPubKeys[this.baseServerUrl];
|
|
|
|
|
pubKeyAB = window.lokiPublicChatAPI.openGroupPubKeys[this.baseServerUrl];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// else will fail validation later
|
|
|
|
@ -189,10 +171,7 @@ class LokiAppDotNetServerAPI {
|
|
|
|
|
// no big deal if it fails...
|
|
|
|
|
if (res.err || !res.response || !res.response.data) {
|
|
|
|
|
if (res.err) {
|
|
|
|
|
log.error(
|
|
|
|
|
`setProfileName Error ${res.err} ${res.statusCode}`,
|
|
|
|
|
this.baseServerUrl
|
|
|
|
|
);
|
|
|
|
|
log.error(`setProfileName Error ${res.err} ${res.statusCode}`, this.baseServerUrl);
|
|
|
|
|
}
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
@ -243,9 +222,7 @@ class LokiAppDotNetServerAPI {
|
|
|
|
|
if (this.token) {
|
|
|
|
|
return this.token;
|
|
|
|
|
}
|
|
|
|
|
token = await Signal.Data.getPublicServerTokenByServerUrl(
|
|
|
|
|
this.baseServerUrl
|
|
|
|
|
);
|
|
|
|
|
token = await Signal.Data.getPublicServerTokenByServerUrl(this.baseServerUrl);
|
|
|
|
|
}
|
|
|
|
|
if (!token) {
|
|
|
|
|
token = await this.refreshServerToken();
|
|
|
|
@ -360,25 +337,12 @@ class LokiAppDotNetServerAPI {
|
|
|
|
|
// not really an error, from a client's pov, network servers can fail...
|
|
|
|
|
if (e.code === 'ECONNREFUSED') {
|
|
|
|
|
// down
|
|
|
|
|
log.warn(
|
|
|
|
|
'requestToken request can not connect',
|
|
|
|
|
this.baseServerUrl,
|
|
|
|
|
e.message
|
|
|
|
|
);
|
|
|
|
|
log.warn('requestToken request can not connect', this.baseServerUrl, e.message);
|
|
|
|
|
} else if (e.code === 'ECONNRESET') {
|
|
|
|
|
// got disconnected
|
|
|
|
|
log.warn(
|
|
|
|
|
'requestToken request lost connection',
|
|
|
|
|
this.baseServerUrl,
|
|
|
|
|
e.message
|
|
|
|
|
);
|
|
|
|
|
log.warn('requestToken request lost connection', this.baseServerUrl, e.message);
|
|
|
|
|
} else {
|
|
|
|
|
log.error(
|
|
|
|
|
'requestToken request failed',
|
|
|
|
|
this.baseServerUrl,
|
|
|
|
|
e.code,
|
|
|
|
|
e.message
|
|
|
|
|
);
|
|
|
|
|
log.error('requestToken request failed', this.baseServerUrl, e.code, e.message);
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
@ -448,9 +412,7 @@ class LokiAppDotNetServerAPI {
|
|
|
|
|
log.warn('No channelId provided to getModerators!');
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
const res = await this.serverRequest(
|
|
|
|
|
`loki/v1/channels/${channelId}/moderators`
|
|
|
|
|
);
|
|
|
|
|
const res = await this.serverRequest(`loki/v1/channels/${channelId}/moderators`);
|
|
|
|
|
|
|
|
|
|
return (!res.err && res.response && res.response.moderators) || [];
|
|
|
|
|
}
|
|
|
|
@ -590,11 +552,7 @@ class LokiAppDotNetServerAPI {
|
|
|
|
|
|
|
|
|
|
if (res.err || !res.response || !res.response.data) {
|
|
|
|
|
if (res.err) {
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_app_dot_net:::getUsers - Error: ${res.err} for ${pubKeys.join(
|
|
|
|
|
','
|
|
|
|
|
)}`
|
|
|
|
|
);
|
|
|
|
|
log.error(`loki_app_dot_net:::getUsers - Error: ${res.err} for ${pubKeys.join(',')}`);
|
|
|
|
|
}
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
@ -639,10 +597,7 @@ class LokiAppDotNetServerAPI {
|
|
|
|
|
throw new Error(`Failed to upload avatar to ${this.baseServerUrl}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const url =
|
|
|
|
|
response.data &&
|
|
|
|
|
response.data.avatar_image &&
|
|
|
|
|
response.data.avatar_image.url;
|
|
|
|
|
const url = response.data && response.data.avatar_image && response.data.avatar_image.url;
|
|
|
|
|
|
|
|
|
|
if (!url) {
|
|
|
|
|
throw new Error(`Failed to upload data: Invalid url.`);
|
|
|
|
@ -720,9 +675,7 @@ class LokiAppDotNetServerAPI {
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (window.lokiFeatureFlags.useFileOnionRequestsV2) {
|
|
|
|
|
const buffer = dcodeIO.ByteBuffer.fromBase64(
|
|
|
|
|
res.response
|
|
|
|
|
).toArrayBuffer();
|
|
|
|
|
const buffer = dcodeIO.ByteBuffer.fromBase64(res.response).toArrayBuffer();
|
|
|
|
|
return buffer;
|
|
|
|
|
}
|
|
|
|
|
return new Uint8Array(res.response.data).buffer;
|
|
|
|
@ -737,9 +690,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
this.channelId = channelId;
|
|
|
|
|
this.baseChannelUrl = `channels/${this.channelId}`;
|
|
|
|
|
this.conversationId = conversationId;
|
|
|
|
|
this.conversation = window
|
|
|
|
|
.getConversationController()
|
|
|
|
|
.getOrThrow(conversationId);
|
|
|
|
|
this.conversation = window.getConversationController().getOrThrow(conversationId);
|
|
|
|
|
this.lastMessageServerID = null;
|
|
|
|
|
this.modStatus = false;
|
|
|
|
|
this.deleteLastId = 1;
|
|
|
|
@ -755,9 +706,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
|
|
|
|
|
// end properties
|
|
|
|
|
|
|
|
|
|
log.info(
|
|
|
|
|
`registered LokiPublicChannel ${channelId} on ${this.serverAPI.baseServerUrl}`
|
|
|
|
|
);
|
|
|
|
|
log.info(`registered LokiPublicChannel ${channelId} on ${this.serverAPI.baseServerUrl}`);
|
|
|
|
|
// start polling
|
|
|
|
|
this.open();
|
|
|
|
|
}
|
|
|
|
@ -775,12 +724,9 @@ class LokiPublicChannelAPI {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async banUser(pubkey) {
|
|
|
|
|
const res = await this.serverRequest(
|
|
|
|
|
`loki/v1/moderation/blacklist/@${pubkey}`,
|
|
|
|
|
{
|
|
|
|
|
method: 'POST',
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
const res = await this.serverRequest(`loki/v1/moderation/blacklist/@${pubkey}`, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (res.err || !res.response || !res.response.data) {
|
|
|
|
|
if (res.err) {
|
|
|
|
@ -793,9 +739,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
open() {
|
|
|
|
|
log.info(
|
|
|
|
|
`LokiPublicChannel open ${this.channelId} on ${this.serverAPI.baseServerUrl}`
|
|
|
|
|
);
|
|
|
|
|
log.info(`LokiPublicChannel open ${this.channelId} on ${this.serverAPI.baseServerUrl}`);
|
|
|
|
|
if (this.running) {
|
|
|
|
|
log.warn(
|
|
|
|
|
`LokiPublicChannel already open ${this.channelId} on ${this.serverAPI.baseServerUrl}`
|
|
|
|
@ -818,9 +762,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stop() {
|
|
|
|
|
log.info(
|
|
|
|
|
`LokiPublicChannel close ${this.channelId} on ${this.serverAPI.baseServerUrl}`
|
|
|
|
|
);
|
|
|
|
|
log.info(`LokiPublicChannel close ${this.channelId} on ${this.serverAPI.baseServerUrl}`);
|
|
|
|
|
if (!this.running) {
|
|
|
|
|
log.warn(
|
|
|
|
|
`LokiPublicChannel already open ${this.channelId} on ${this.serverAPI.baseServerUrl}`
|
|
|
|
@ -862,11 +804,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
try {
|
|
|
|
|
await this.pollOnceForModerators();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.warn(
|
|
|
|
|
'Error while polling for public chat moderators:',
|
|
|
|
|
e.code,
|
|
|
|
|
e.message
|
|
|
|
|
);
|
|
|
|
|
log.warn('Error while polling for public chat moderators:', e.code, e.message);
|
|
|
|
|
}
|
|
|
|
|
if (this.running) {
|
|
|
|
|
this.timers.moderator = setTimeout(() => {
|
|
|
|
@ -878,9 +816,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
// get moderator status
|
|
|
|
|
async pollOnceForModerators() {
|
|
|
|
|
// get moderator status
|
|
|
|
|
const res = await this.serverRequest(
|
|
|
|
|
`loki/v1/channels/${this.channelId}/moderators`
|
|
|
|
|
);
|
|
|
|
|
const res = await this.serverRequest(`loki/v1/channels/${this.channelId}/moderators`);
|
|
|
|
|
const ourNumberDevice = window.libsession.Utils.UserUtils.getOurPubKeyStrFromCache();
|
|
|
|
|
|
|
|
|
|
// Get the list of moderators if no errors occurred
|
|
|
|
@ -911,15 +847,12 @@ class LokiPublicChannelAPI {
|
|
|
|
|
log.warn(`public chat channel state unknown, skipping set: ${res.err}`);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
let notes =
|
|
|
|
|
res.response && res.response.data && res.response.data.annotations;
|
|
|
|
|
let notes = res.response && res.response.data && res.response.data.annotations;
|
|
|
|
|
if (!notes) {
|
|
|
|
|
// ok if nothing is set yet
|
|
|
|
|
notes = [];
|
|
|
|
|
}
|
|
|
|
|
let settingNotes = notes.filter(
|
|
|
|
|
note => note.type === SETTINGS_CHANNEL_ANNOTATION_TYPE
|
|
|
|
|
);
|
|
|
|
|
let settingNotes = notes.filter(note => note.type === SETTINGS_CHANNEL_ANNOTATION_TYPE);
|
|
|
|
|
if (!settingNotes) {
|
|
|
|
|
// default name, description, avatar
|
|
|
|
|
settingNotes = [
|
|
|
|
@ -936,10 +869,10 @@ class LokiPublicChannelAPI {
|
|
|
|
|
// update settings
|
|
|
|
|
settingNotes[0].value = Object.assign(settingNotes[0].value, settings);
|
|
|
|
|
// commit settings
|
|
|
|
|
const updateRes = await this.serverRequest(
|
|
|
|
|
`loki/v1/${this.baseChannelUrl}`,
|
|
|
|
|
{ method: 'PUT', objBody: { annotations: settingNotes } }
|
|
|
|
|
);
|
|
|
|
|
const updateRes = await this.serverRequest(`loki/v1/${this.baseChannelUrl}`, {
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
objBody: { annotations: settingNotes },
|
|
|
|
|
});
|
|
|
|
|
if (updateRes.err || !updateRes.response || !updateRes.response.data) {
|
|
|
|
|
if (updateRes.err) {
|
|
|
|
|
log.error(`setChannelSettings Error ${updateRes.err}`);
|
|
|
|
@ -967,17 +900,13 @@ class LokiPublicChannelAPI {
|
|
|
|
|
{ method: 'DELETE', params: { ids: serverIds } }
|
|
|
|
|
);
|
|
|
|
|
if (!res.err) {
|
|
|
|
|
const deletedIds = res.response.data
|
|
|
|
|
.filter(d => d.is_deleted)
|
|
|
|
|
.map(d => d.id);
|
|
|
|
|
const deletedIds = res.response.data.filter(d => d.is_deleted).map(d => d.id);
|
|
|
|
|
|
|
|
|
|
if (deletedIds.length > 0) {
|
|
|
|
|
log.info(`deleted ${serverIds} on ${this.baseChannelUrl}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const failedIds = res.response.data
|
|
|
|
|
.filter(d => !d.is_deleted)
|
|
|
|
|
.map(d => d.id);
|
|
|
|
|
const failedIds = res.response.data.filter(d => !d.is_deleted).map(d => d.id);
|
|
|
|
|
|
|
|
|
|
if (failedIds.length > 0) {
|
|
|
|
|
log.warn(`failed to delete ${failedIds} on ${this.baseChannelUrl}`);
|
|
|
|
@ -985,10 +914,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
|
|
|
|
|
// Note: if there is no entry for message, we assume it wasn't found
|
|
|
|
|
// on the server, so it is not treated as explicitly failed
|
|
|
|
|
const ignoredIds = _.difference(
|
|
|
|
|
serverIds,
|
|
|
|
|
_.union(failedIds, deletedIds)
|
|
|
|
|
);
|
|
|
|
|
const ignoredIds = _.difference(serverIds, _.union(failedIds, deletedIds));
|
|
|
|
|
|
|
|
|
|
if (ignoredIds.length > 0) {
|
|
|
|
|
log.warn(`No response for ${ignoredIds} on ${this.baseChannelUrl}`);
|
|
|
|
@ -997,9 +923,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
return { deletedIds, ignoredIds };
|
|
|
|
|
}
|
|
|
|
|
if (canThrow) {
|
|
|
|
|
throw new textsecure.PublicChatError(
|
|
|
|
|
'Failed to delete public chat message'
|
|
|
|
|
);
|
|
|
|
|
throw new textsecure.PublicChatError('Failed to delete public chat message');
|
|
|
|
|
}
|
|
|
|
|
return { deletedIds: [], ignoredIds: [] };
|
|
|
|
|
}
|
|
|
|
@ -1015,11 +939,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
try {
|
|
|
|
|
await this.pollForChannelOnce();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.warn(
|
|
|
|
|
'Error while polling for public chat room details',
|
|
|
|
|
e.code,
|
|
|
|
|
e.message
|
|
|
|
|
);
|
|
|
|
|
log.warn('Error while polling for public chat room details', e.code, e.message);
|
|
|
|
|
}
|
|
|
|
|
if (this.running) {
|
|
|
|
|
this.timers.channel = setTimeout(() => {
|
|
|
|
@ -1072,16 +992,11 @@ class LokiPublicChannelAPI {
|
|
|
|
|
} else {
|
|
|
|
|
// relative URL avatar
|
|
|
|
|
const avatarAbsUrl = this.serverAPI.baseServerUrl + note.value.avatar;
|
|
|
|
|
const {
|
|
|
|
|
writeNewAttachmentData,
|
|
|
|
|
deleteAttachmentData,
|
|
|
|
|
} = window.Signal.Migrations;
|
|
|
|
|
const { writeNewAttachmentData, deleteAttachmentData } = window.Signal.Migrations;
|
|
|
|
|
// do we already have this image? no, then
|
|
|
|
|
|
|
|
|
|
// download a copy and save it
|
|
|
|
|
const imageData = await this.serverAPI.downloadAttachment(
|
|
|
|
|
avatarAbsUrl
|
|
|
|
|
);
|
|
|
|
|
const imageData = await this.serverAPI.downloadAttachment(avatarAbsUrl);
|
|
|
|
|
|
|
|
|
|
const newAttributes = await window.Signal.Types.Conversation.maybeUpdateAvatar(
|
|
|
|
|
this.conversation.attributes,
|
|
|
|
@ -1111,11 +1026,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
try {
|
|
|
|
|
await this.pollOnceForDeletions();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.warn(
|
|
|
|
|
'Error while polling for public chat deletions:',
|
|
|
|
|
e.code,
|
|
|
|
|
e.message
|
|
|
|
|
);
|
|
|
|
|
log.warn('Error while polling for public chat deletions:', e.code, e.message);
|
|
|
|
|
}
|
|
|
|
|
if (this.running) {
|
|
|
|
|
this.timers.delete = setTimeout(() => {
|
|
|
|
@ -1138,18 +1049,10 @@ class LokiPublicChannelAPI {
|
|
|
|
|
|
|
|
|
|
// grab the next 200 deletions from where we last checked
|
|
|
|
|
// eslint-disable-next-line no-await-in-loop
|
|
|
|
|
const res = await this.serverRequest(
|
|
|
|
|
`loki/v1/channel/${this.channelId}/deletes`,
|
|
|
|
|
{ params }
|
|
|
|
|
);
|
|
|
|
|
const res = await this.serverRequest(`loki/v1/channel/${this.channelId}/deletes`, { params });
|
|
|
|
|
|
|
|
|
|
// if any problems, abort out
|
|
|
|
|
if (
|
|
|
|
|
res.err ||
|
|
|
|
|
!res.response ||
|
|
|
|
|
!res.response.data ||
|
|
|
|
|
!res.response.meta
|
|
|
|
|
) {
|
|
|
|
|
if (res.err || !res.response || !res.response.data || !res.response.meta) {
|
|
|
|
|
if (res.statusCode === 403) {
|
|
|
|
|
// token is now invalid
|
|
|
|
|
this.serverAPI.getOrRefreshServerToken(true);
|
|
|
|
@ -1157,9 +1060,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
if (res.err) {
|
|
|
|
|
log.error(`pollOnceForDeletions Error ${res.err}`);
|
|
|
|
|
} else {
|
|
|
|
|
log.error(
|
|
|
|
|
`pollOnceForDeletions Error: Received incorrect response ${res.response}`
|
|
|
|
|
);
|
|
|
|
|
log.error(`pollOnceForDeletions Error: Received incorrect response ${res.response}`);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -1175,20 +1076,11 @@ class LokiPublicChannelAPI {
|
|
|
|
|
|
|
|
|
|
// update where we last checked
|
|
|
|
|
this.deleteLastId = res.response.meta.max_id;
|
|
|
|
|
more =
|
|
|
|
|
res.response.meta.more &&
|
|
|
|
|
res.response.data.length >= params.count &&
|
|
|
|
|
this.running;
|
|
|
|
|
more = res.response.meta.more && res.response.data.length >= params.count && this.running;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static getSigData(
|
|
|
|
|
sigVer,
|
|
|
|
|
noteValue,
|
|
|
|
|
attachmentAnnotations,
|
|
|
|
|
previewAnnotations,
|
|
|
|
|
adnMessage
|
|
|
|
|
) {
|
|
|
|
|
static getSigData(sigVer, noteValue, attachmentAnnotations, previewAnnotations, adnMessage) {
|
|
|
|
|
let sigString = '';
|
|
|
|
|
sigString += adnMessage.text.trim();
|
|
|
|
|
sigString += noteValue.timestamp;
|
|
|
|
@ -1210,10 +1102,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getMessengerData(adnMessage) {
|
|
|
|
|
if (
|
|
|
|
|
!Array.isArray(adnMessage.annotations) ||
|
|
|
|
|
adnMessage.annotations.length === 0
|
|
|
|
|
) {
|
|
|
|
|
if (!Array.isArray(adnMessage.annotations) || adnMessage.annotations.length === 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
const noteValue = adnMessage.annotations[0].value;
|
|
|
|
@ -1293,8 +1182,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
timestamp,
|
|
|
|
|
serverTimestamp:
|
|
|
|
|
new Date(`${adnMessage.created_at}`).getTime() || timestamp,
|
|
|
|
|
serverTimestamp: new Date(`${adnMessage.created_at}`).getTime() || timestamp,
|
|
|
|
|
attachments,
|
|
|
|
|
preview,
|
|
|
|
|
quote,
|
|
|
|
@ -1309,11 +1197,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
try {
|
|
|
|
|
await this.pollOnceForMessages();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.warn(
|
|
|
|
|
'Error while polling for public chat messages:',
|
|
|
|
|
e.code,
|
|
|
|
|
e.message
|
|
|
|
|
);
|
|
|
|
|
log.warn('Error while polling for public chat messages:', e.code, e.message);
|
|
|
|
|
}
|
|
|
|
|
if (this.running) {
|
|
|
|
|
this.timers.message = setTimeout(() => {
|
|
|
|
@ -1386,8 +1270,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
// get our profile name
|
|
|
|
|
const ourNumberDevice = window.libsession.Utils.UserUtils.getOurPubKeyStrFromCache();
|
|
|
|
|
// if no primaryDevicePubKey fall back to ourNumberDevice
|
|
|
|
|
const ourNumberProfile =
|
|
|
|
|
window.storage.get('primaryDevicePubKey') || ourNumberDevice;
|
|
|
|
|
const ourNumberProfile = window.storage.get('primaryDevicePubKey') || ourNumberDevice;
|
|
|
|
|
let lastProfileName = false;
|
|
|
|
|
|
|
|
|
|
// the signature forces this to be async
|
|
|
|
@ -1437,11 +1320,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
// message is one of the object of this.lastMessagesCache
|
|
|
|
|
// testedMessage is the adnMessage object
|
|
|
|
|
const isDuplicate = (message, testedMessage) =>
|
|
|
|
|
DataMessage.isDuplicate(
|
|
|
|
|
message,
|
|
|
|
|
testedMessage,
|
|
|
|
|
testedMessage.user.username
|
|
|
|
|
);
|
|
|
|
|
DataMessage.isDuplicate(message, testedMessage, testedMessage.user.username);
|
|
|
|
|
const isThisMessageDuplicate = this.lastMessagesCache.some(m =>
|
|
|
|
|
isDuplicate(m, adnMessage)
|
|
|
|
|
);
|
|
|
|
@ -1503,8 +1382,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
receivedAt,
|
|
|
|
|
isPublic: true,
|
|
|
|
|
message: {
|
|
|
|
|
body:
|
|
|
|
|
adnMessage.text === timestamp.toString() ? '' : adnMessage.text,
|
|
|
|
|
body: adnMessage.text === timestamp.toString() ? '' : adnMessage.text,
|
|
|
|
|
attachments,
|
|
|
|
|
group: {
|
|
|
|
|
id: this.conversationId,
|
|
|
|
@ -1571,9 +1449,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
// if we received one of our own messages
|
|
|
|
|
if (lastProfileName !== false) {
|
|
|
|
|
// get current profileName
|
|
|
|
|
const profileConvo = window
|
|
|
|
|
.getConversationController()
|
|
|
|
|
.get(ourNumberProfile);
|
|
|
|
|
const profileConvo = window.getConversationController().get(ourNumberProfile);
|
|
|
|
|
const profileName = profileConvo.getProfileName();
|
|
|
|
|
// check to see if it out of sync
|
|
|
|
|
if (profileName !== lastProfileName) {
|
|
|
|
@ -1668,12 +1544,8 @@ class LokiPublicChannelAPI {
|
|
|
|
|
async sendMessage(data, messageTimeStamp) {
|
|
|
|
|
const { quote, attachments, preview } = data;
|
|
|
|
|
const text = data.body || messageTimeStamp.toString();
|
|
|
|
|
const attachmentAnnotations = attachments.map(
|
|
|
|
|
LokiPublicChannelAPI.getAnnotationFromAttachment
|
|
|
|
|
);
|
|
|
|
|
const previewAnnotations = preview.map(
|
|
|
|
|
LokiPublicChannelAPI.getAnnotationFromPreview
|
|
|
|
|
);
|
|
|
|
|
const attachmentAnnotations = attachments.map(LokiPublicChannelAPI.getAnnotationFromAttachment);
|
|
|
|
|
const previewAnnotations = preview.map(LokiPublicChannelAPI.getAnnotationFromPreview);
|
|
|
|
|
|
|
|
|
|
const payload = {
|
|
|
|
|
text,
|
|
|
|
@ -1721,10 +1593,7 @@ class LokiPublicChannelAPI {
|
|
|
|
|
previewAnnotations.map(anno => anno.value),
|
|
|
|
|
mockAdnMessage
|
|
|
|
|
);
|
|
|
|
|
const sig = await libsignal.Curve.async.calculateSignature(
|
|
|
|
|
privKey,
|
|
|
|
|
sigData
|
|
|
|
|
);
|
|
|
|
|
const sig = await libsignal.Curve.async.calculateSignature(privKey, sigData);
|
|
|
|
|
payload.annotations[0].value.sig = StringView.arrayBufferToHex(sig);
|
|
|
|
|
payload.annotations[0].value.sigver = sigVer;
|
|
|
|
|
const res = await this.serverRequest(`${this.baseChannelUrl}/messages`, {
|
|
|
|
|