Merge branch 'unstable' into feat/ses-825/onboarding2

bumped react and redux to the latest minior versions
pull/3083/head
William Grant 10 months ago
commit b40cf49acf

@ -1,3 +1,4 @@
name: 'Setup and build' name: 'Setup and build'
description: 'Setup and build Session Desktop' description: 'Setup and build Session Desktop'
runs: runs:

@ -2,7 +2,7 @@
"name": "session-desktop", "name": "session-desktop",
"productName": "Session", "productName": "Session",
"description": "Private messaging from your desktop", "description": "Private messaging from your desktop",
"version": "1.12.3", "version": "1.12.4",
"license": "GPL-3.0", "license": "GPL-3.0",
"author": { "author": {
"name": "Oxen Labs", "name": "Oxen Labs",
@ -22,8 +22,8 @@
"lodash": "^4.17.20", "lodash": "^4.17.20",
"ini": "^1.3.6", "ini": "^1.3.6",
"ejs": "^3.1.7", "ejs": "^3.1.7",
"react": "18.2.0", "react": "18.3.1",
"@types/react": "18.2.55", "@types/react": "18.3.3",
"glob-parent": "^6.0.1", "glob-parent": "^6.0.1",
"got": "^11.8.5", "got": "^11.8.5",
"jpeg-js": "^0.4.4", "jpeg-js": "^0.4.4",
@ -70,7 +70,7 @@
"dependencies": { "dependencies": {
"@emoji-mart/data": "^1.1.2", "@emoji-mart/data": "^1.1.2",
"@emoji-mart/react": "^1.1.1", "@emoji-mart/react": "^1.1.1",
"@reduxjs/toolkit": "1.8.5", "@reduxjs/toolkit": "1.9.7",
"@signalapp/better-sqlite3": "^8.4.3", "@signalapp/better-sqlite3": "^8.4.3",
"@types/react-mentions": "^4.1.8", "@types/react-mentions": "^4.1.8",
"abort-controller": "3.0.0", "abort-controller": "3.0.0",
@ -96,7 +96,7 @@
"fs-extra": "9.0.0", "fs-extra": "9.0.0",
"glob": "7.1.2", "glob": "7.1.2",
"image-type": "^4.1.0", "image-type": "^4.1.0",
"libsession_util_nodejs": "https://github.com/oxen-io/libsession-util-nodejs/releases/download/v0.3.4/libsession_util_nodejs-v0.3.4.tar.gz", "libsession_util_nodejs": "https://github.com/oxen-io/libsession-util-nodejs/releases/download/v0.3.19/libsession_util_nodejs-v0.3.19.tar.gz",
"libsodium-wrappers-sumo": "^0.7.9", "libsodium-wrappers-sumo": "^0.7.9",
"linkify-it": "^4.0.1", "linkify-it": "^4.0.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
@ -110,23 +110,23 @@
"pify": "3.0.0", "pify": "3.0.0",
"protobufjs": "^7.2.4", "protobufjs": "^7.2.4",
"rc-slider": "^10.6.2", "rc-slider": "^10.6.2",
"react": "^18.2.0", "react": "18.3.1",
"react-contexify": "^6.0.0", "react-contexify": "^6.0.0",
"react-dom": "^18.2.0", "react-dom": "18.3.1",
"react-draggable": "^4.4.4", "react-draggable": "^4.4.4",
"react-h5-audio-player": "^3.2.0", "react-h5-audio-player": "^3.2.0",
"react-intersection-observer": "^9.7.0", "react-intersection-observer": "^9.7.0",
"react-mentions": "^4.4.9", "react-mentions": "^4.4.9",
"react-qrcode-logo": "^3.0.0", "react-qrcode-logo": "^3.0.0",
"react-redux": "8.0.4", "react-redux": "8.1.3",
"react-toastify": "^6.0.9", "react-toastify": "^6.0.9",
"react-use": "^17.4.0", "react-use": "^17.5.0",
"react-virtualized": "^9.22.4", "react-virtualized": "^9.22.4",
"read-last-lines-ts": "^1.2.1", "read-last-lines-ts": "^1.2.1",
"redux": "4.2.0", "redux": "4.2.1",
"redux-logger": "3.0.6", "redux-logger": "3.0.6",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"redux-promise-middleware": "^6.1.2", "redux-promise-middleware": "^6.2.0",
"rimraf": "2.6.2", "rimraf": "2.6.2",
"sanitize.css": "^12.0.1", "sanitize.css": "^12.0.1",
"semver": "^7.5.4", "semver": "^7.5.4",
@ -163,11 +163,11 @@
"@types/mocha": "5.0.0", "@types/mocha": "5.0.0",
"@types/node-fetch": "^2.5.7", "@types/node-fetch": "^2.5.7",
"@types/pify": "3.0.2", "@types/pify": "3.0.2",
"@types/react": "^18.2.55", "@types/react": "18.3.3",
"@types/react-dom": "^18.2.19", "@types/react-dom": "18.3.0",
"@types/react-redux": "^7.1.24", "@types/react-redux": "^7.1.33",
"@types/react-virtualized": "^9.21.30", "@types/react-virtualized": "^9.21.30",
"@types/redux-logger": "3.0.7", "@types/redux-logger": "3.0.13",
"@types/rimraf": "2.0.2", "@types/rimraf": "2.0.2",
"@types/semver": "5.5.0", "@types/semver": "5.5.0",
"@types/sinon": "9.0.4", "@types/sinon": "9.0.4",

@ -18,7 +18,6 @@ import { OpenGroupUtils } from '../session/apis/open_group_api/utils';
import { getOpenGroupV2ConversationId } from '../session/apis/open_group_api/utils/OpenGroupUtils'; import { getOpenGroupV2ConversationId } from '../session/apis/open_group_api/utils/OpenGroupUtils';
import { getSwarmPollingInstance } from '../session/apis/snode_api'; import { getSwarmPollingInstance } from '../session/apis/snode_api';
import { getConversationController } from '../session/conversations'; import { getConversationController } from '../session/conversations';
import { IncomingMessage } from '../session/messages/incoming/IncomingMessage';
import { Profile, ProfileManager } from '../session/profile_manager/ProfileManager'; import { Profile, ProfileManager } from '../session/profile_manager/ProfileManager';
import { PubKey } from '../session/types'; import { PubKey } from '../session/types';
import { StringUtils, UserUtils } from '../session/utils'; import { StringUtils, UserUtils } from '../session/utils';
@ -37,6 +36,8 @@ import { Registration } from '../util/registration';
import { ReleasedFeatures } from '../util/releaseFeature'; import { ReleasedFeatures } from '../util/releaseFeature';
import { Storage, isSignInByLinking, setLastProfileUpdateTimestamp } from '../util/storage'; import { Storage, isSignInByLinking, setLastProfileUpdateTimestamp } from '../util/storage';
import { SnodeNamespaces } from '../session/apis/snode_api/namespaces';
import { RetrieveMessageItemWithNamespace } from '../session/apis/snode_api/types';
// eslint-disable-next-line import/no-unresolved // eslint-disable-next-line import/no-unresolved
import { ConfigWrapperObjectTypes } from '../webworker/workers/browser/libsession_worker_functions'; import { ConfigWrapperObjectTypes } from '../webworker/workers/browser/libsession_worker_functions';
import { import {
@ -52,18 +53,29 @@ import { HexKeyPair } from './keypairs';
import { queueAllCachedFromSource } from './receiver'; import { queueAllCachedFromSource } from './receiver';
import { EnvelopePlus } from './types'; import { EnvelopePlus } from './types';
function groupByVariant( function groupByNamespace(incomingConfigs: Array<RetrieveMessageItemWithNamespace>) {
incomingConfigs: Array<IncomingMessage<SignalService.ISharedConfigMessage>>
) {
const groupedByVariant: Map< const groupedByVariant: Map<
ConfigWrapperObjectTypes, ConfigWrapperObjectTypes,
Array<IncomingMessage<SignalService.ISharedConfigMessage>> Array<RetrieveMessageItemWithNamespace>
> = new Map(); > = new Map();
incomingConfigs.forEach(incomingConfig => { incomingConfigs.forEach(incomingConfig => {
const { kind } = incomingConfig.message; const { namespace } = incomingConfig;
const wrapperId = LibSessionUtil.kindToVariant(kind); const wrapperId: ConfigWrapperObjectTypes | null =
namespace === SnodeNamespaces.UserProfile
? 'UserConfig'
: namespace === SnodeNamespaces.UserContacts
? 'ContactsConfig'
: namespace === SnodeNamespaces.UserGroups
? 'UserGroupsConfig'
: namespace === SnodeNamespaces.ConvoInfoVolatile
? 'ConvoInfoVolatileConfig'
: null;
if (!wrapperId) {
throw new Error('Unexpected wrapperId');
}
if (!groupedByVariant.has(wrapperId)) { if (!groupedByVariant.has(wrapperId)) {
groupedByVariant.set(wrapperId, []); groupedByVariant.set(wrapperId, []);
@ -75,10 +87,10 @@ function groupByVariant(
} }
async function mergeConfigsWithIncomingUpdates( async function mergeConfigsWithIncomingUpdates(
incomingConfigs: Array<IncomingMessage<SignalService.ISharedConfigMessage>> incomingConfigs: Array<RetrieveMessageItemWithNamespace>
): Promise<Map<ConfigWrapperObjectTypes, IncomingConfResult>> { ): Promise<Map<ConfigWrapperObjectTypes, IncomingConfResult>> {
// first, group by variant so we do a single merge call // first, group by variant so we do a single merge call
const groupedByVariant = groupByVariant(incomingConfigs); const groupedByNamespace = groupByNamespace(incomingConfigs);
const groupedResults: Map<ConfigWrapperObjectTypes, IncomingConfResult> = new Map(); const groupedResults: Map<ConfigWrapperObjectTypes, IncomingConfResult> = new Map();
@ -86,15 +98,15 @@ async function mergeConfigsWithIncomingUpdates(
const publicKey = UserUtils.getOurPubKeyStrFromCache(); const publicKey = UserUtils.getOurPubKeyStrFromCache();
try { try {
for (let index = 0; index < groupedByVariant.size; index++) { for (let index = 0; index < groupedByNamespace.size; index++) {
const variant = [...groupedByVariant.keys()][index]; const variant = [...groupedByNamespace.keys()][index];
const sameVariant = groupedByVariant.get(variant); const sameVariant = groupedByNamespace.get(variant);
if (!sameVariant?.length) { if (!sameVariant?.length) {
continue; continue;
} }
const toMerge = sameVariant.map(msg => ({ const toMerge = sameVariant.map(msg => ({
data: msg.message.data, data: StringUtils.fromBase64ToArray(msg.data),
hash: msg.messageHash, hash: msg.hash,
})); }));
if (window.sessionFeatureFlags.debug.debugLibsessionDumps) { if (window.sessionFeatureFlags.debug.debugLibsessionDumps) {
window.log.info( window.log.info(
@ -105,9 +117,7 @@ async function mergeConfigsWithIncomingUpdates(
for (let dumpIndex = 0; dumpIndex < toMerge.length; dumpIndex++) { for (let dumpIndex = 0; dumpIndex < toMerge.length; dumpIndex++) {
const element = toMerge[dumpIndex]; const element = toMerge[dumpIndex];
window.log.info( window.log.info(
`printDumpsForDebugging: toMerge of ${dumpIndex}:${element.hash}: ${StringUtils.toHex( `printDumpsForDebugging: toMerge of ${dumpIndex}:${element.hash}: ${element.data} `,
element.data
)} `,
StringUtils.toHex(await GenericWrapperActions.dump(variant)) StringUtils.toHex(await GenericWrapperActions.dump(variant))
); );
} }
@ -117,8 +127,8 @@ async function mergeConfigsWithIncomingUpdates(
const needsPush = await GenericWrapperActions.needsPush(variant); const needsPush = await GenericWrapperActions.needsPush(variant);
const needsDump = await GenericWrapperActions.needsDump(variant); const needsDump = await GenericWrapperActions.needsDump(variant);
const mergedTimestamps = sameVariant const mergedTimestamps = sameVariant
.filter(m => hashesMerged.includes(m.messageHash)) .filter(m => hashesMerged.includes(m.hash))
.map(m => m.envelopeTimestamp); .map(m => m.timestamp);
const latestEnvelopeTimestamp = Math.max(...mergedTimestamps); const latestEnvelopeTimestamp = Math.max(...mergedTimestamps);
window.log.debug( window.log.debug(
@ -891,7 +901,7 @@ async function processMergingResults(results: Map<ConfigWrapperObjectTypes, Inco
} }
async function handleConfigMessagesViaLibSession( async function handleConfigMessagesViaLibSession(
configMessages: Array<IncomingMessage<SignalService.ISharedConfigMessage>> configMessages: Array<RetrieveMessageItemWithNamespace>
) { ) {
const userConfigLibsession = await ReleasedFeatures.checkIsUserConfigFeatureReleased(); const userConfigLibsession = await ReleasedFeatures.checkIsUserConfigFeatureReleased();
@ -906,9 +916,8 @@ async function handleConfigMessagesViaLibSession(
window?.log?.debug( window?.log?.debug(
`Handling our sharedConfig message via libsession_util ${JSON.stringify( `Handling our sharedConfig message via libsession_util ${JSON.stringify(
configMessages.map(m => ({ configMessages.map(m => ({
variant: LibSessionUtil.kindToVariant(m.message.kind), namespace: m.namespace,
hash: m.messageHash, hash: m.hash,
seqno: (m.message.seqno as Long).toNumber(),
})) }))
)}` )}`
); );

@ -1,7 +1,7 @@
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
/* eslint-disable more/no-then */ /* eslint-disable more/no-then */
/* eslint-disable @typescript-eslint/no-misused-promises */ /* eslint-disable @typescript-eslint/no-misused-promises */
import { compact, concat, flatten, isEmpty, last, sample, toNumber, uniqBy } from 'lodash'; import { compact, concat, flatten, isEmpty, last, sample, uniqBy } from 'lodash';
import { Data } from '../../../data/data'; import { Data } from '../../../data/data';
import { Snode } from '../../../data/types'; import { Snode } from '../../../data/types';
import { SignalService } from '../../../protobuf'; import { SignalService } from '../../../protobuf';
@ -12,8 +12,6 @@ import * as snodePool from './snodePool';
import { ConversationModel } from '../../../models/conversation'; import { ConversationModel } from '../../../models/conversation';
import { ConfigMessageHandler } from '../../../receiver/configMessage'; import { ConfigMessageHandler } from '../../../receiver/configMessage';
import { decryptEnvelopeWithOurKey } from '../../../receiver/contentMessage';
import { EnvelopePlus } from '../../../receiver/types';
import { updateIsOnline } from '../../../state/ducks/onion'; import { updateIsOnline } from '../../../state/ducks/onion';
import { ReleasedFeatures } from '../../../util/releaseFeature'; import { ReleasedFeatures } from '../../../util/releaseFeature';
import { import {
@ -23,16 +21,19 @@ import {
} from '../../../webworker/workers/browser/libsession_worker_interface'; } from '../../../webworker/workers/browser/libsession_worker_interface';
import { DURATION, SWARM_POLLING_TIMEOUT } from '../../constants'; import { DURATION, SWARM_POLLING_TIMEOUT } from '../../constants';
import { getConversationController } from '../../conversations'; import { getConversationController } from '../../conversations';
import { IncomingMessage } from '../../messages/incoming/IncomingMessage';
import { StringUtils, UserUtils } from '../../utils'; import { StringUtils, UserUtils } from '../../utils';
import { ed25519Str } from '../../utils/String'; import { ed25519Str } from '../../utils/String';
import { NotFoundError } from '../../utils/errors'; import { NotFoundError } from '../../utils/errors';
import { LibSessionUtil } from '../../utils/libsession/libsession_utils'; import { LibSessionUtil } from '../../utils/libsession/libsession_utils';
import { SnodeNamespace, SnodeNamespaces } from './namespaces'; import { SnodeNamespace, SnodeNamespaces } from './namespaces';
import { SnodeAPIRetrieve } from './retrieveRequest'; import { SnodeAPIRetrieve } from './retrieveRequest';
import { RetrieveMessageItem, RetrieveMessagesResultsBatched } from './types'; import {
RetrieveMessageItem,
RetrieveMessageItemWithNamespace,
RetrieveMessagesResultsBatched,
} from './types';
export function extractWebSocketContent( function extractWebSocketContent(
message: string, message: string,
messageHash: string messageHash: string
): null | { ): null | {
@ -266,9 +267,16 @@ export class SwarmPolling {
// check if we just fetched the details from the config namespaces. // check if we just fetched the details from the config namespaces.
// If yes, merge them together and exclude them from the rest of the messages. // If yes, merge them together and exclude them from the rest of the messages.
if (userConfigLibsession && resultsFromAllNamespaces) { if (userConfigLibsession && resultsFromAllNamespaces) {
const userConfigMessages = resultsFromAllNamespaces const userConfigMessages = resultsFromAllNamespaces.filter(m =>
.filter(m => SnodeNamespace.isUserConfigNamespace(m.namespace)) SnodeNamespace.isUserConfigNamespace(m.namespace)
.map(r => r.messages.messages); );
const userConfigMessagesWithNamespace: Array<Array<RetrieveMessageItemWithNamespace>> =
userConfigMessages.map(r => {
return (r.messages.messages || []).map(m => {
return { ...m, namespace: r.namespace };
});
});
allNamespacesWithoutUserConfigIfNeeded = flatten( allNamespacesWithoutUserConfigIfNeeded = flatten(
compact( compact(
@ -284,7 +292,7 @@ export class SwarmPolling {
`received userConfigMessages count: ${userConfigMessagesMerged.length} for key ${pubkey.key}` `received userConfigMessages count: ${userConfigMessagesMerged.length} for key ${pubkey.key}`
); );
try { try {
await this.handleSharedConfigMessages(userConfigMessagesMerged); await this.handleSharedConfigMessages(flatten(userConfigMessagesWithNamespace));
} catch (e) { } catch (e) {
window.log.warn( window.log.warn(
`handleSharedConfigMessages of ${userConfigMessagesMerged.length} failed with ${e.message}` `handleSharedConfigMessages of ${userConfigMessagesMerged.length} failed with ${e.message}`
@ -367,111 +375,55 @@ export class SwarmPolling {
} }
private async handleSharedConfigMessages( private async handleSharedConfigMessages(
userConfigMessagesMerged: Array<RetrieveMessageItem>, userConfigMessagesMerged: Array<RetrieveMessageItemWithNamespace>,
returnDisplayNameOnly?: boolean returnDisplayNameOnly?: boolean
): Promise<string> { ): Promise<string> {
const extractedUserConfigMessage = compact( if (!userConfigMessagesMerged.length) {
userConfigMessagesMerged.map((m: RetrieveMessageItem) => { return '';
return extractWebSocketContent(m.data, m.hash);
})
);
const allDecryptedConfigMessages: Array<IncomingMessage<SignalService.ISharedConfigMessage>> =
[];
for (let index = 0; index < extractedUserConfigMessage.length; index++) {
const userConfigMessage = extractedUserConfigMessage[index];
try {
const envelope: EnvelopePlus = SignalService.Envelope.decode(userConfigMessage.body) as any;
const decryptedEnvelope = await decryptEnvelopeWithOurKey(envelope);
if (!decryptedEnvelope?.byteLength) {
continue;
}
const content = SignalService.Content.decode(new Uint8Array(decryptedEnvelope));
if (content.sharedConfigMessage) {
const asIncomingMsg: IncomingMessage<SignalService.ISharedConfigMessage> = {
envelopeTimestamp: toNumber(envelope.timestamp),
message: content.sharedConfigMessage,
messageHash: userConfigMessage.messageHash,
authorOrGroupPubkey: envelope.source,
authorInGroup: envelope.senderIdentity,
};
allDecryptedConfigMessages.push(asIncomingMsg);
} else {
throw new Error(
'received a message from the namespace reserved for user config but it did not contain a sharedConfigMessage'
);
}
} catch (e) {
window.log.warn(
`failed to decrypt message with hash "${userConfigMessage.messageHash}": ${e.message}`
);
}
} }
if (allDecryptedConfigMessages.length) { try {
try { window.log.info(
window.log.info( `handleConfigMessagesViaLibSession of "${userConfigMessagesMerged.length}" messages with libsession`
`handleConfigMessagesViaLibSession of "${allDecryptedConfigMessages.length}" messages with libsession` );
);
if (returnDisplayNameOnly) {
try {
const keypair = await UserUtils.getUserED25519KeyPairBytes();
if (!keypair || !keypair.privKeyBytes) {
throw new Error('edkeypair not found for current user');
}
const privateKeyEd25519 = keypair.privKeyBytes;
// we take the lastest config message to create the wrapper in memory
const incomingConfigMessages = allDecryptedConfigMessages.map(m => ({
data: m.message.data,
hash: m.messageHash,
}));
await GenericWrapperActions.init('UserConfig', privateKeyEd25519, null); if (returnDisplayNameOnly) {
try {
const keypair = await UserUtils.getUserED25519KeyPairBytes();
if (!keypair || !keypair.privKeyBytes) {
throw new Error('edkeypair not found for current user');
}
if (window.sessionFeatureFlags.debug.debugLibsessionDumps) { const privateKeyEd25519 = keypair.privKeyBytes;
window.log.info(
`printDumpsForDebugging: before merge of UserConfig (should be empty):`,
StringUtils.toHex(await GenericWrapperActions.dump('UserConfig'))
);
}
await GenericWrapperActions.merge('UserConfig', incomingConfigMessages); // we take the lastest config message to create the wrapper in memory
const incomingConfigMessages = userConfigMessagesMerged.map(m => ({
data: StringUtils.fromBase64ToArray(m.data),
hash: m.hash,
}));
if (window.sessionFeatureFlags.debug.debugLibsessionDumps) { await GenericWrapperActions.init('UserConfig', privateKeyEd25519, null);
window.log.info( await GenericWrapperActions.merge('UserConfig', incomingConfigMessages);
`printDumpsForDebugging: after merge of UserConfig:`,
StringUtils.toHex(await GenericWrapperActions.dump('UserConfig'))
);
}
const userInfo = await UserConfigWrapperActions.getUserInfo(); const userInfo = await UserConfigWrapperActions.getUserInfo();
if (!userInfo) { if (!userInfo) {
throw new Error('UserInfo not found'); throw new Error('UserInfo not found');
}
return userInfo.name;
} catch (e) {
window.log.warn(
'LibSessionUtil.initializeLibSessionUtilWrappers failed with',
e.message
);
} finally {
await GenericWrapperActions.free('UserConfig');
} }
return userInfo.name;
return ''; } catch (e) {
window.log.warn('LibSessionUtil.initializeLibSessionUtilWrappers failed with', e.message);
} finally {
await GenericWrapperActions.free('UserConfig');
} }
await ConfigMessageHandler.handleConfigMessagesViaLibSession(allDecryptedConfigMessages); return '';
} catch (e) {
const allMessageHases = allDecryptedConfigMessages.map(m => m.messageHash).join(',');
window.log.warn(
`failed to handle messages hashes "${allMessageHases}" with libsession. Error: "${e.message}"`
);
} }
await ConfigMessageHandler.handleConfigMessagesViaLibSession(userConfigMessagesMerged);
} catch (e) {
const allMessageHases = userConfigMessagesMerged.map(m => m.hash).join(',');
window.log.warn(
`failed to handle messages hashes "${allMessageHases}" with libsession. Error: "${e.message}"`
);
} }
return ''; return '';
} }
@ -737,11 +689,14 @@ export class SwarmPolling {
); );
} }
const userConfigMessages = resultsFromUserProfile const userConfigMessagesWithNamespace: Array<Array<RetrieveMessageItemWithNamespace>> =
.filter(m => SnodeNamespace.isUserConfigNamespace(m.namespace)) resultsFromUserProfile.map(r => {
.map(r => r.messages.messages); return (r.messages.messages || []).map(m => {
return { ...m, namespace: SnodeNamespaces.UserProfile };
});
});
const userConfigMessagesMerged = flatten(compact(userConfigMessages)); const userConfigMessagesMerged = flatten(compact(userConfigMessagesWithNamespace));
if (!userConfigMessagesMerged.length) { if (!userConfigMessagesMerged.length) {
throw new NotFoundError( throw new NotFoundError(
'[pollOnceForOurDisplayName] after merging there are no user config messages' '[pollOnceForOurDisplayName] after merging there are no user config messages'

@ -7,6 +7,8 @@ export type RetrieveMessageItem = {
timestamp: number; timestamp: number;
}; };
export type RetrieveMessageItemWithNamespace = RetrieveMessageItem & { namespace: number };
export type RetrieveMessagesResultsContent = { export type RetrieveMessagesResultsContent = {
hf?: Array<number>; hf?: Array<number>;
messages?: Array<RetrieveMessageItem>; messages?: Array<RetrieveMessageItem>;

@ -9,36 +9,26 @@ import { MessageParams } from '../Message';
interface SharedConfigParams extends MessageParams { interface SharedConfigParams extends MessageParams {
seqno: Long; seqno: Long;
kind: SignalService.SharedConfigMessage.Kind; kind: SignalService.SharedConfigMessage.Kind;
data: Uint8Array; readyToSendData: Uint8Array;
} }
export class SharedConfigMessage extends ContentMessage { export class SharedConfigMessage extends ContentMessage {
public readonly seqno: Long; public readonly seqno: Long;
public readonly kind: SignalService.SharedConfigMessage.Kind; public readonly kind: SignalService.SharedConfigMessage.Kind;
public readonly data: Uint8Array; public readonly readyToSendData: Uint8Array;
constructor(params: SharedConfigParams) { constructor(params: SharedConfigParams) {
super({ timestamp: params.timestamp, identifier: params.identifier }); super({ timestamp: params.timestamp, identifier: params.identifier });
this.data = params.data; this.readyToSendData = params.readyToSendData;
this.kind = params.kind; this.kind = params.kind;
this.seqno = params.seqno; this.seqno = params.seqno;
} }
public contentProto(): SignalService.Content { public contentProto(): SignalService.Content {
return new SignalService.Content({ throw new Error('SharedConfigMessage must not be sent wrapped anymore');
sharedConfigMessage: this.sharedConfigProto(),
});
} }
public ttl(): number { public ttl(): number {
return TTL_DEFAULT.CONFIG_MESSAGE; return TTL_DEFAULT.CONFIG_MESSAGE;
} }
protected sharedConfigProto(): SignalService.SharedConfigMessage {
return new SignalService.SharedConfigMessage({
data: this.data,
kind: this.kind,
seqno: this.seqno,
});
}
} }

@ -379,32 +379,20 @@ async function sendMessagesToSnode(
try { try {
const recipient = PubKey.cast(destination); const recipient = PubKey.cast(destination);
const encryptedAndWrapped = await encryptMessagesAndWrap( const encryptedAndWrapped: Array<Omit<EncryptAndWrapMessageResults, 'data' | 'isSyncMessage'>> =
params.map(m => ({ [];
destination: m.pubkey,
plainTextBuffer: m.message.plainTextBuffer(), params.forEach(m => {
namespace: m.namespace, const wrapped = {
ttl: m.message.ttl(),
identifier: m.message.identifier, identifier: m.message.identifier,
isSyncMessage: MessageSender.isContentSyncMessage(m.message), isSyncMessage: MessageSender.isContentSyncMessage(m.message),
})) namespace: m.namespace,
); ttl: m.message.ttl(),
networkTimestamp: GetNetworkTime.getNowWithNetworkOffset(),
// first update all the associated timestamps of our messages in DB, if the outgoing messages are associated with one. data64: ByteBuffer.wrap(m.message.readyToSendData).toString('base64'),
await Promise.all( };
encryptedAndWrapped.map(async (m, index) => { encryptedAndWrapped.push(wrapped);
// make sure to update the local sent_at timestamp, because sometimes, we will get the just pushed message in the receiver side });
// before we return from the await below.
// and the isDuplicate messages relies on sent_at timestamp to be valid.
const found = await Data.getMessageById(m.identifier);
// make sure to not update the sent timestamp if this a currently syncing message
if (found && !found.get('sentSync')) {
found.set({ sent_at: encryptedAndWrapped[index].networkTimestamp });
await found.commit();
}
})
);
const batchResults = await pRetry( const batchResults = await pRetry(
async () => { async () => {
@ -432,35 +420,6 @@ async function sendMessagesToSnode(
throw new Error('result is empty for sendMessagesToSnode'); throw new Error('result is empty for sendMessagesToSnode');
} }
const isDestinationClosedGroup = getConversationController()
.get(recipient.key)
?.isClosedGroup();
await Promise.all(
encryptedAndWrapped.map(async (message, index) => {
// If message also has a sync message, save that hash. Otherwise save the hash from the regular message send i.e. only closed groups in this case.
if (
message.identifier &&
(message.isSyncMessage || isDestinationClosedGroup) &&
batchResults[index] &&
!isEmpty(batchResults[index]) &&
isString(batchResults[index].body.hash)
) {
const hashFoundInResponse = batchResults[index].body.hash;
const foundMessage = await Data.getMessageById(message.identifier);
if (foundMessage) {
await foundMessage.updateMessageHash(hashFoundInResponse);
await foundMessage.commit();
window?.log?.info(
`updated message ${foundMessage.get('id')} with hash: ${foundMessage.get(
'messageHash'
)}`
);
}
}
})
);
return batchResults; return batchResults;
} catch (e) { } catch (e) {
window.log.warn(`sendMessagesToSnode failed with ${e.message}`); window.log.warn(`sendMessagesToSnode failed with ${e.message}`);

@ -226,7 +226,7 @@ class ConfigurationSyncJob extends PersistedJob<ConfigurationSyncPersistedData>
...m, ...m,
message: { message: {
...m.message, ...m.message,
data: to_hex(m.message.data), readyToSendData: to_hex(m.message.readyToSendData),
}, },
}; };
}) })

@ -130,14 +130,14 @@ async function pendingChangesForPubkey(pubkey: string): Promise<Array<OutgoingCo
} }
variantsNeedingPush.add(variant); variantsNeedingPush.add(variant);
const { data, seqno, hashes } = await GenericWrapperActions.push(variant); const { data: readyToSendData, seqno, hashes } = await GenericWrapperActions.push(variant);
const kind = variantToKind(variant); const kind = variantToKind(variant);
const namespace = await GenericWrapperActions.storageNamespace(variant); const namespace = await GenericWrapperActions.storageNamespace(variant);
results.push({ results.push({
message: new SharedConfigMessage({ message: new SharedConfigMessage({
data, readyToSendData,
kind, kind,
seqno: Long.fromNumber(seqno), seqno: Long.fromNumber(seqno),
timestamp: GetNetworkTime.getNowWithNetworkOffset(), timestamp: GetNetworkTime.getNowWithNetworkOffset(),

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save