fix: add return types for libsession wrapper functions

pull/2620/head
Audric Ackermann 2 years ago
parent 90804491d6
commit 4bfcf91193

@ -3,32 +3,25 @@ import { QRCode } from 'react-qr-svg';
import { Avatar, AvatarSize } from '../avatar/Avatar';
import { YourSessionIDPill, YourSessionIDSelectable } from '../basic/YourSessionIDPill';
import { SyncUtils, ToastUtils, UserUtils } from '../../session/utils';
import { YourSessionIDPill, YourSessionIDSelectable } from '../basic/YourSessionIDPill';
import { ConversationModel } from '../../models/conversation';
import { getConversationController } from '../../session/conversations';
import autoBind from 'auto-bind';
import { editProfileModal } from '../../state/ducks/modalDialog';
import { uploadOurAvatar } from '../../interactions/conversationInteractions';
import { ConversationTypeEnum } from '../../models/conversationAttributes';
import { MAX_USERNAME_BYTES } from '../../session/constants';
import { getConversationController } from '../../session/conversations';
import { ConfigurationSync } from '../../session/utils/job_runners/jobs/ConfigurationSyncJob';
import { sanitizeSessionUsername } from '../../session/utils/String';
import { editProfileModal } from '../../state/ducks/modalDialog';
import { pickFileForAvatar } from '../../types/attachments/VisualAttachment';
import { setLastProfileUpdateTimestamp } from '../../util/storage';
import { SessionButton, SessionButtonType } from '../basic/SessionButton';
import { SessionSpinner } from '../basic/SessionSpinner';
import { SessionIconButton } from '../icon';
import { SessionWrapperModal } from '../SessionWrapperModal';
import { pickFileForAvatar } from '../../types/attachments/VisualAttachment';
import { sanitizeSessionUsername } from '../../session/utils/String';
import { setLastProfileUpdateTimestamp } from '../../util/storage';
import { ConversationTypeEnum } from '../../models/conversationAttributes';
import { MAX_USERNAME_BYTES } from '../../session/constants';
import { SharedConfigMessage } from '../../session/messages/outgoing/controlMessage/SharedConfigMessage';
import { callLibSessionWorker } from '../../webworker/workers/browser/libsession_worker_interface';
import { SignalService } from '../../protobuf';
import Long from 'long';
import { GetNetworkTime } from '../../session/apis/snode_api/getNetworkTime';
import { getMessageQueue } from '../../session/sending';
import { SnodeNamespaces } from '../../session/apis/snode_api/namespaces';
import { from_string } from 'libsodium-wrappers-sumo';
interface State {
profileName: string;
@ -350,27 +343,8 @@ async function commitProfileEdits(newName: string, scaledAvatarUrl: string | nul
await conversation.commit();
if (window.sessionFeatureFlags.useSharedUtilForUserConfig) {
await callLibSessionWorker(['UserConfig', 'setName', newName]);
const pointer = conversation.get('avatarPointer');
const profileKey = conversation.get('profileKey');
if (profileKey && pointer) {
await callLibSessionWorker([
'UserConfig',
'setProfilePicture',
pointer,
from_string(profileKey),
]);
} else {
await callLibSessionWorker(['UserConfig', 'setProfilePicture', '', new Uint8Array()]);
}
const message = new SharedConfigMessage({
data: (await callLibSessionWorker(['UserConfig', 'dump'])) as Uint8Array,
kind: SignalService.SharedConfigMessage.Kind.USER_PROFILE,
seqno: Long.fromNumber(0),
timestamp: GetNetworkTime.getNowWithNetworkOffset(),
});
await getMessageQueue().sendSyncMessage({ message, namespace: SnodeNamespaces.UserProfile });
await ConfigurationSync.queueNewJobIfNeeded();
await setLastProfileUpdateTimestamp(Date.now());
} else {
await setLastProfileUpdateTimestamp(Date.now());

@ -44,7 +44,7 @@ import { LeftPaneSectionContainer } from './LeftPaneSectionContainer';
import { getLatestReleaseFromFileServer } from '../../session/apis/file_server_api/FileServerApi';
import { forceRefreshRandomSnodePool } from '../../session/apis/snode_api/snodePool';
import { initializeLibSessionUtilWrappers } from '../../session/utils/libsession/libsession_utils';
import { LibSessionUtil } from '../../session/utils/libsession/libsession_utils';
import { isDarkTheme } from '../../state/selectors/theme';
import { ThemeStateType } from '../../themes/constants/colors';
import { switchThemeTo } from '../../themes/switchTheme';
@ -193,7 +193,7 @@ const triggerAvatarReUploadIfNeeded = async () => {
* This function is called only once: on app startup with a logged in user
*/
const doAppStartUp = async () => {
await initializeLibSessionUtilWrappers();
await LibSessionUtil.initializeLibSessionUtilWrappers();
void setupTheme();
// this generates the key to encrypt attachments locally
@ -201,6 +201,8 @@ const doAppStartUp = async () => {
await runners.avatarDownloadRunner.loadJobsFromDb();
runners.avatarDownloadRunner.startProcessing();
await runners.configurationSyncRunner.loadJobsFromDb();
runners.configurationSyncRunner.startProcessing();
// trigger a sync message if needed for our other devices
void triggerSyncIfNeeded();

@ -1,41 +1,31 @@
import {
AsyncWrapper,
AsyncObjectWrapper,
ConfigDumpDataNode,
ConfigDumpRow,
GetAllDumps,
GetByPubkeyConfigDump,
GetByVariantAndPubkeyConfigDump,
SaveConfigDump,
ConfigDumpRowWithoutData,
} from '../../types/sqlSharedTypes';
import { ConfigWrapperObjectTypes } from '../../webworker/workers/browser/libsession_worker_functions';
import { channels } from '../channels';
const getByVariantAndPubkey: AsyncWrapper<GetByVariantAndPubkeyConfigDump> = (
variant: ConfigWrapperObjectTypes,
pubkey: string
) => {
return channels.getConfigDumpByVariantAndPubkey(variant, pubkey);
};
const getByPubkey: AsyncWrapper<GetByPubkeyConfigDump> = (pubkey: string) => {
return channels.getConfigDumpsByPk(pubkey);
};
const saveConfigDump: AsyncWrapper<SaveConfigDump> = (dump: ConfigDumpRow) => {
return channels.saveConfigDump(dump);
};
const getAllDumpsWithData: AsyncWrapper<GetAllDumps> = () => {
return channels.getAllDumpsWithData();
};
const getAllDumpsWithoutData: AsyncWrapper<GetAllDumps> = () => {
return channels.getAllDumpsWithoutData();
};
export const ConfigDumpData = {
getByVariantAndPubkey,
getByPubkey,
saveConfigDump,
getAllDumpsWithData,
getAllDumpsWithoutData,
export const ConfigDumpData: AsyncObjectWrapper<ConfigDumpDataNode> = {
getByVariantAndPubkey: (variant: ConfigWrapperObjectTypes, pubkey: string) => {
return channels.getByVariantAndPubkey(variant, pubkey);
},
getMessageHashesByVariantAndPubkey: (variant: ConfigWrapperObjectTypes, pubkey: string) => {
return channels.getMessageHashesByVariantAndPubkey(variant, pubkey);
},
saveConfigDump: (dump: ConfigDumpRow) => {
console.warn('saveConfigDump', dump);
return channels.saveConfigDump(dump);
},
saveCombinedMessageHashesForMatching: (dump: ConfigDumpRowWithoutData) => {
console.warn('saveCombinedMessageHashesForMatching', dump);
return channels.saveCombinedMessageHashesForMatching(dump);
},
getAllDumpsWithData: () => {
return channels.getAllDumpsWithData();
},
getAllDumpsWithoutData: () => {
return channels.getAllDumpsWithoutData();
},
};

@ -40,6 +40,7 @@ import { setLastProfileUpdateTimestamp } from '../util/storage';
import { getSodiumRenderer } from '../session/crypto';
import { encryptProfile } from '../util/crypto/profileEncrypter';
import { uploadFileToFsWithOnionV4 } from '../session/apis/file_server_api/FileServerApi';
import { ConfigurationSync } from '../session/utils/job_runners/jobs/ConfigurationSyncJob';
export const getCompleteUrlForV2ConvoId = async (convoId: string) => {
if (convoId.match(openGroupV2ConversationIdRegex)) {
@ -449,7 +450,11 @@ export async function uploadOurAvatar(newAvatarDecrypted?: ArrayBuffer) {
if (newAvatarDecrypted) {
await setLastProfileUpdateTimestamp(Date.now());
await SyncUtils.forceSyncConfigurationNowIfNeeded(true);
if (window.sessionFeatureFlags.useSharedUtilForUserConfig) {
await ConfigurationSync.queueNewJobIfNeeded();
} else {
await SyncUtils.forceSyncConfigurationNowIfNeeded(true);
}
} else {
window.log.info(
`Reuploading avatar finished at ${newTimestampReupload}, newAttachmentPointer ${fileUrl}`

@ -1247,6 +1247,10 @@ function updateToSessionSchemaVersion31(currentVersion: number, db: BetterSqlite
// ;
// `);
// for manually flagging conversations as :unread"
db.exec(`ALTER TABLE ${CONVERSATIONS_TABLE} ADD COLUMN markedAsUnread BOOLEAN;`);
// Didn't find any reference to this serverTimestamp in the unprocessed table needed.
db.exec(`ALTER TABLE unprocessed DROP COLUMN serverTimestamp;`);
// we need to populate those fields with the current state of the conversation so let's throw null until this is done

@ -48,8 +48,6 @@ import {
} from './database_utility';
import {
ConfigDumpDataNode,
ConfigDumpRow,
MsgDuplicateSearchOpenGroup,
UnprocessedDataNode,
UnprocessedParameter,
@ -70,7 +68,7 @@ import {
initDbInstanceWith,
isInstanceInitialized,
} from './sqlInstance';
import { ConfigWrapperObjectTypes } from '../webworker/workers/browser/libsession_worker_functions';
import { configDumpData } from './sql_calls/config_dump';
// tslint:disable: no-console function-name non-literal-fs-path
@ -1964,92 +1962,6 @@ function removeV2OpenGroupRoom(conversationId: string) {
});
}
/**
* Config dumps sql calls
*/
const configDumpData: ConfigDumpDataNode = {
getConfigDumpByVariantAndPubkey: (variant: ConfigWrapperObjectTypes, pubkey: string) => {
const rows = assertGlobalInstance()
.prepare('SELECT * from configDump WHERE variant = $variant AND pubkey = $pubkey;')
.get({
pubkey,
variant,
});
if (!rows) {
return [];
}
throw new Error(`getConfigDumpByVariantAndPubkey: rows: ${JSON.stringify(rows)} `);
return rows;
},
getConfigDumpsByPubkey: (pubkey: string) => {
const rows = assertGlobalInstance()
.prepare('SELECT * from configDump WHERE pubkey = $pubkey;')
.get({
pubkey,
});
if (!rows) {
return [];
}
throw new Error(`getConfigDumpsByPubkey: rows: ${JSON.stringify(rows)} `);
return rows;
},
saveConfigDump: ({ data, pubkey, variant, combinedMessageHashes }: ConfigDumpRow) => {
assertGlobalInstance()
.prepare(
`INSERT OR REPLACE INTO configDump (
pubkey,
variant,
combinedMessageHashes,
data
) values (
$pubkey,
$variant,
$combinedMessageHashes,
$data,
);`
)
.run({
pubkey,
variant,
combinedMessageHashes,
data,
});
},
getAllDumpsWithData: () => {
const rows = assertGlobalInstance()
.prepare('SELECT variant, publicKey, combinedMessageHashes, data from configDump;')
.get();
if (!rows) {
return [];
}
throw new Error(`getAllDumpsWithData: rows: ${JSON.stringify(rows)} `);
return rows;
},
getAllDumpsWithoutData: () => {
const rows = assertGlobalInstance()
.prepare('SELECT variant, publicKey, combinedMessageHashes from configDump;')
.get();
if (!rows) {
return [];
}
throw new Error(`getAllDumpsWithoutData: rows: ${JSON.stringify(rows)} `);
return rows;
},
};
/**
* Others
*/

@ -0,0 +1,147 @@
/**
* Config dumps sql calls
*/
import { compact, flatten, isEmpty, uniq } from 'lodash';
import {
ConfigDumpDataNode,
ConfigDumpRow,
ConfigDumpRowWithoutData,
} from '../../types/sqlSharedTypes';
import { ConfigWrapperObjectTypes } from '../../webworker/workers/browser/libsession_worker_functions';
import { assertGlobalInstance } from '../sqlInstance';
type CombinedMessageHashes = { combinedMessageHashes?: string };
function parseRow(
row: Pick<ConfigDumpRow, 'data' | 'publicKey' | 'variant'> & CombinedMessageHashes
): ConfigDumpRow | null {
const parsedNoData = parseRowNoData(row);
if (!parsedNoData) {
return null;
}
return { ...parsedNoData, data: row.data };
}
function parseRowNoData(
row: Pick<ConfigDumpRow, 'data' | 'publicKey' | 'variant'> & CombinedMessageHashes
): ConfigDumpRowWithoutData | null {
const toRet: ConfigDumpRowWithoutData = {
publicKey: row.publicKey,
variant: row.variant,
combinedMessageHashes: [],
};
toRet.combinedMessageHashes = parseRowMessageHashes(row);
return toRet;
}
function parseRowMessageHashes(row: CombinedMessageHashes): Array<string> {
if (!isEmpty(row.combinedMessageHashes) && row.combinedMessageHashes) {
try {
return JSON.parse(row.combinedMessageHashes) || [];
} catch (e) {
console.warn('parseRowMessageHashes row failed');
}
}
return [];
}
export const configDumpData: ConfigDumpDataNode = {
getByVariantAndPubkey: (variant: ConfigWrapperObjectTypes, publicKey: string) => {
const rows = assertGlobalInstance()
.prepare(
'SELECT publicKey, variant, combinedMessageHashes, data from configDump WHERE variant = $variant AND publicKey = $publicKey;'
)
.all({
publicKey,
variant,
});
if (!rows) {
return [];
}
return compact(rows.map(parseRow));
},
getMessageHashesByVariantAndPubkey: (variant: ConfigWrapperObjectTypes, publicKey: string) => {
const rows = assertGlobalInstance()
.prepare(
'SELECT combinedMessageHashes from configDump WHERE variant = $variant AND publicKey = $publicKey;'
)
.all({
publicKey,
variant,
});
if (!rows) {
return [];
}
return uniq(flatten(rows.map(parseRowMessageHashes)));
},
getAllDumpsWithData: () => {
const rows = assertGlobalInstance()
.prepare('SELECT variant, publicKey, combinedMessageHashes, data from configDump;')
.all();
if (!rows) {
return [];
}
return compact(rows.map(parseRow));
},
getAllDumpsWithoutData: () => {
const rows = assertGlobalInstance()
.prepare('SELECT variant, publicKey, combinedMessageHashes from configDump;')
.all();
if (!rows) {
return [];
}
return compact(rows.map(parseRowNoData));
},
saveConfigDump: ({ data, publicKey, variant, combinedMessageHashes }: ConfigDumpRow) => {
assertGlobalInstance()
.prepare(
`INSERT OR REPLACE INTO configDump (
publicKey,
variant,
combinedMessageHashes,
data
) values (
$publicKey,
$variant,
$combinedMessageHashes,
$data
);`
)
.run({
publicKey,
variant,
combinedMessageHashes: JSON.stringify(combinedMessageHashes || []),
data,
});
},
saveCombinedMessageHashesForMatching: ({
publicKey,
variant,
combinedMessageHashes,
}: ConfigDumpRowWithoutData) => {
assertGlobalInstance()
.prepare(
`UPDATE configDump SET
combinedMessageHashes = $combinedMessageHashes
WHERE publicKey=$publicKey AND variant=$variant;`
)
.run({
publicKey,
variant,
combinedMessageHashes: JSON.stringify(combinedMessageHashes || []),
});
},
};

@ -1,5 +1,5 @@
import _, { isEmpty } from 'lodash';
import { ContactInfo, ProfilePicture } from 'session_util_wrapper';
import _, { compact, flattenDeep, isEmpty, isEqual } from 'lodash';
import { ConfigDumpData } from '../data/configDump/configDump';
import { Data, hasSyncedInitialConfigurationItem } from '../data/data';
import { ConversationInteraction } from '../interactions';
import { ConversationTypeEnum } from '../models/conversationAttributes';
@ -13,12 +13,17 @@ import { getConversationController } from '../session/conversations';
import { IncomingMessage } from '../session/messages/incoming/IncomingMessage';
import { ProfileManager } from '../session/profile_manager/ProfileManager';
import { UserUtils } from '../session/utils';
import { ConfigurationSync } from '../session/utils/job_runners/jobs/ConfigurationSyncJob';
import { toHex } from '../session/utils/String';
import { configurationMessageReceived, trigger } from '../shims/events';
import { BlockedNumberController } from '../util';
import { getLastProfileUpdateTimestamp, setLastProfileUpdateTimestamp } from '../util/storage';
import { ConfigWrapperObjectTypes } from '../webworker/workers/browser/libsession_worker_functions';
import { callLibSessionWorker } from '../webworker/workers/browser/libsession_worker_interface';
import {
ContactsWrapperActions,
GenericWrapperActions,
UserConfigWrapperActions,
} from '../webworker/workers/browser/libsession_worker_interface';
import { removeFromCache } from './cache';
import { handleNewClosedGroup } from './closedGroups';
import { EnvelopePlus } from './types';
@ -30,7 +35,7 @@ type IncomingConfResult = {
latestSentTimestamp: number;
};
function protobufSharedConfigTypeToWrapper(
function pbKindToVariant(
kind: SignalService.SharedConfigMessage.Kind
): ConfigWrapperObjectTypes | null {
switch (kind) {
@ -45,59 +50,44 @@ function protobufSharedConfigTypeToWrapper(
async function mergeConfigsWithIncomingUpdates(
incomingConfig: IncomingMessage<SignalService.ISharedConfigMessage>
) {
const kindMessageMap: Map<SignalService.SharedConfigMessage.Kind, IncomingConfResult> = new Map();
const allKinds = [incomingConfig.message.kind];
for (let index = 0; index < allKinds.length; index++) {
const kind = allKinds[index];
const currentKindMessages = [incomingConfig];
if (!currentKindMessages) {
continue;
}
const toMerge = currentKindMessages.map(m => m.message.data);
): Promise<{ kind: SignalService.SharedConfigMessage.Kind; result: IncomingConfResult }> {
const { kind } = incomingConfig.message;
const wrapperId = protobufSharedConfigTypeToWrapper(kind);
if (!wrapperId) {
throw new Error(`Invalid kind: ${kind}`);
}
const toMerge = [incomingConfig.message.data];
await callLibSessionWorker([wrapperId, 'merge', toMerge]);
const needsPush = ((await callLibSessionWorker([wrapperId, 'needsPush'])) || false) as boolean;
const needsDump = ((await callLibSessionWorker([wrapperId, 'needsDump'])) || false) as boolean;
const messageHashes = currentKindMessages.map(m => m.messageHash);
const latestSentTimestamp = Math.max(...currentKindMessages.map(m => m.envelopeTimestamp));
const incomingConfResult: IncomingConfResult = {
latestSentTimestamp,
messageHashes,
needsDump,
needsPush,
};
kindMessageMap.set(kind, incomingConfResult);
const wrapperId = pbKindToVariant(kind);
if (!wrapperId) {
throw new Error(`Invalid kind: ${kind}`);
}
return kindMessageMap;
await GenericWrapperActions.merge(wrapperId, toMerge);
const needsPush = await GenericWrapperActions.needsPush(wrapperId);
const needsDump = await GenericWrapperActions.needsDump(wrapperId);
const messageHashes = [incomingConfig.messageHash];
const latestSentTimestamp = incomingConfig.envelopeTimestamp;
const incomingConfResult: IncomingConfResult = {
latestSentTimestamp,
messageHashes,
needsDump,
needsPush,
};
return { kind, result: incomingConfResult };
}
async function handleUserProfileUpdate(result: IncomingConfResult) {
async function handleUserProfileUpdate(result: IncomingConfResult): Promise<IncomingConfResult> {
const updatedUserName = await UserConfigWrapperActions.getName();
console.warn('got', updatedUserName);
if (result.needsDump) {
return;
return result;
}
const updatedUserName = (await callLibSessionWorker(['UserConfig', 'getName'])) as
| string
| undefined;
const updatedProfilePicture = (await callLibSessionWorker([
'UserConfig',
'getProfilePicture',
])) as ProfilePicture;
// fetch our own conversation
const userPublicKey = UserUtils.getOurPubKeyStrFromCache();
if (!userPublicKey) {
return;
if (!updatedUserName) {
debugger;
}
const updatedProfilePicture = await UserConfigWrapperActions.getProfilePicture();
const picUpdate = !isEmpty(updatedProfilePicture.key) && !isEmpty(updatedProfilePicture.url);
@ -106,16 +96,15 @@ async function handleUserProfileUpdate(result: IncomingConfResult) {
picUpdate ? updatedProfilePicture.url : null,
picUpdate ? updatedProfilePicture.key : null
);
return result;
}
async function handleContactsUpdate(result: IncomingConfResult) {
async function handleContactsUpdate(result: IncomingConfResult): Promise<IncomingConfResult> {
if (result.needsDump) {
return;
return result;
}
const allContacts = (await callLibSessionWorker(['ContactsConfig', 'getAll'])) as Array<
ContactInfo
>;
const allContacts = await ContactsWrapperActions.getAll();
for (let index = 0; index < allContacts.length; index++) {
const wrapperConvo = allContacts[index];
@ -161,7 +150,7 @@ async function handleContactsUpdate(result: IncomingConfResult) {
await existingConvo.commit();
}
// we still need to handle the the `name` (sync) and the `profilePicture` (asynchronous)
// we still need to handle the the `name` (synchronous) and the `profilePicture` (asynchronous)
await ProfileManager.updateProfileOfContact(
existingConvo.id,
wrapperConvo.name,
@ -170,36 +159,85 @@ async function handleContactsUpdate(result: IncomingConfResult) {
);
}
}
return result;
}
async function processMergingResults(
envelope: EnvelopePlus,
results: Map<SignalService.SharedConfigMessage.Kind, IncomingConfResult>
result: { kind: SignalService.SharedConfigMessage.Kind; result: IncomingConfResult }
) {
const keys = [...results.keys()];
const pubkey = envelope.source;
for (let index = 0; index < keys.length; index++) {
const kind = keys[index];
const result = results.get(kind);
const { kind, result: incomingResult } = result;
if (!result) {
continue;
}
if (!incomingResult) {
await removeFromCache(envelope);
return;
}
try {
switch (kind) {
case SignalService.SharedConfigMessage.Kind.USER_PROFILE:
await handleUserProfileUpdate(result);
break;
case SignalService.SharedConfigMessage.Kind.CONTACTS:
await handleContactsUpdate(result);
break;
}
} catch (e) {
throw e;
try {
let finalResult = incomingResult;
switch (kind) {
case SignalService.SharedConfigMessage.Kind.USER_PROFILE:
finalResult = await handleUserProfileUpdate(incomingResult);
break;
case SignalService.SharedConfigMessage.Kind.CONTACTS:
finalResult = await handleContactsUpdate(incomingResult);
break;
default:
throw new Error(`processMergingResults unknown kind of contact : ${kind}`);
}
const variant = pbKindToVariant(kind);
if (!variant) {
throw new Error('unknown variant');
}
// We need to get the existing message hashes and combine them with the latest from the
// service node to ensure the next push will properly clean up old messages
const oldMessageHashesWithDup = (
await ConfigDumpData.getByVariantAndPubkey(variant, envelope.source)
).map(m => m.combinedMessageHashes);
const oldMessageHashes = new Set(...flattenDeep(compact(oldMessageHashesWithDup)));
const allMessageHashes = new Set([...oldMessageHashes, ...finalResult.messageHashes]);
const finalResultsHashes = new Set([...finalResult.messageHashes]);
// lodash does deep compare of Sets
const messageHashesChanged = !isEqual(oldMessageHashes, finalResultsHashes);
if (finalResult.needsDump) {
// The config data had changes so regenerate the dump and save it
const dump = await GenericWrapperActions.dump(variant);
await ConfigDumpData.saveConfigDump({
data: dump,
publicKey: pubkey,
variant,
combinedMessageHashes: [...allMessageHashes],
});
} else if (messageHashesChanged) {
// The config data didn't change but there were different messages on the service node
// so just update the message hashes so the next sync can properly remove any old ones
await ConfigDumpData.saveCombinedMessageHashesForMatching({
publicKey: pubkey,
variant,
combinedMessageHashes: [...allMessageHashes],
});
}
console.warn('all dumps in DB: ', await ConfigDumpData.getAllDumpsWithoutData());
await removeFromCache(envelope);
} catch (e) {
window.log.error(`processMergingResults failed with ${e.message}`);
await removeFromCache(envelope);
return;
}
await removeFromCache(envelope);
// Now that the local state has been updated, trigger a config sync (this will push any
// pending updates and properly update the state)
if (result.result.needsPush) {
await ConfigurationSync.queueNewJobIfNeeded();
}
}
async function handleConfigMessageViaLibSession(
@ -218,11 +256,11 @@ async function handleConfigMessageViaLibSession(
return;
}
window?.log?.info(`Handling our profileUdpates via libsession_util.`);
window?.log?.info('Handling our profileUdpates via libsession_util.');
const kindMessagesMap = await mergeConfigsWithIncomingUpdates(configMessage);
const incomingMergeResult = await mergeConfigsWithIncomingUpdates(configMessage);
await processMergingResults(envelope, kindMessagesMap);
await processMergingResults(envelope, incomingMergeResult);
}
async function handleOurProfileUpdate(

@ -231,7 +231,7 @@ export class MessageQueue {
pubkey,
}: {
pubkey: PubKey;
message: ClosedGroupNewMessage | CallMessage;
message: ClosedGroupNewMessage | CallMessage | SharedConfigMessage;
namespace: SnodeNamespaces;
}): Promise<boolean | number> {
let rawMessage;
@ -258,6 +258,7 @@ export class MessageQueue {
*/
public async processPending(device: PubKey, isSyncMessage: boolean = false) {
const messages = await this.pendingMessageCache.getForDevice(device);
console.warn('processPending', messages);
const jobQueue = this.getJobQueue(device);
messages.forEach(async message => {

@ -124,7 +124,7 @@ export async function send(
? SnodeNamespaces.ClosedGroupMessage
: SnodeNamespaces.UserMessages;
}
let timestamp = networkTimestamp;
const timestamp = networkTimestamp;
// the user config namespaces requires a signature to be added
let signOpts: SnodeSignatureResult | undefined;
if (SnodeNamespace.isUserConfigNamespace(namespace)) {
@ -247,7 +247,7 @@ export async function sendMessageToSnode({
window?.log?.info(
`loki_message:::sendMessage - Successfully stored message to ${ed25519Str(pubKey)} via ${
snode.ip
}:${snode.port}`
}:${snode.port} on namespace: ${namespace}`
);
}
}

@ -4,7 +4,7 @@ import {
FakeSleepForMultiJob,
} from '../../../test/session/unit/utils/job_runner/FakeSleepForJob';
import { AvatarDownload } from './jobs/AvatarDownloadJob';
import { ConfigurationSyncJob } from './jobs/ConfigurationSyncJob';
import { ConfigurationSync } from './jobs/ConfigurationSyncJob';
import { PersistedJob, TypeOfPersistedData } from './PersistedJob';
export function persistedJobFromData<T extends TypeOfPersistedData>(
@ -16,7 +16,7 @@ export function persistedJobFromData<T extends TypeOfPersistedData>(
switch (data.jobType) {
case 'ConfigurationSyncJobType':
return (new ConfigurationSyncJob(data) as unknown) as PersistedJob<T>;
return (new ConfigurationSync.ConfigurationSyncJob(data) as unknown) as PersistedJob<T>;
case 'AvatarDownloadJobType':
return (new AvatarDownload.AvatarDownloadJob(data) as unknown) as PersistedJob<T>;

@ -1,5 +1,17 @@
import { from_string } from 'libsodium-wrappers-sumo';
import { isNumber } from 'lodash';
import Long from 'long';
import { v4 } from 'uuid';
import { sleepFor } from '../../Promise';
import { UserUtils } from '../..';
import { SignalService } from '../../../../protobuf';
import { UserConfigWrapperActions } from '../../../../webworker/workers/browser/libsession_worker_interface';
import { GetNetworkTime } from '../../../apis/snode_api/getNetworkTime';
import { SnodeNamespaces } from '../../../apis/snode_api/namespaces';
import { getConversationController } from '../../../conversations';
import { SharedConfigMessage } from '../../../messages/outgoing/controlMessage/SharedConfigMessage';
import { getMessageQueue } from '../../../sending';
import { PubKey } from '../../../types';
import { runners } from '../JobRunner';
import {
AddJobCheckReturn,
ConfigurationSyncPersistedData,
@ -8,36 +20,76 @@ import {
} from '../PersistedJob';
const defaultMsBetweenRetries = 3000;
const defaultMaxAttempts = 3;
export class ConfigurationSyncJob extends PersistedJob<ConfigurationSyncPersistedData> {
class ConfigurationSyncJob extends PersistedJob<ConfigurationSyncPersistedData> {
constructor({
identifier,
nextAttemptTimestamp,
maxAttempts,
currentRetry,
}: Pick<ConfigurationSyncPersistedData, 'identifier' | 'currentRetry' | 'maxAttempts'> &
Partial<Pick<ConfigurationSyncPersistedData, 'nextAttemptTimestamp'>>) {
}: Partial<
Pick<
ConfigurationSyncPersistedData,
'identifier' | 'nextAttemptTimestamp' | 'currentRetry' | 'maxAttempts'
>
>) {
super({
jobType: 'ConfigurationSyncJobType',
identifier: identifier || v4(),
delayBetweenRetries: defaultMsBetweenRetries,
maxAttempts: maxAttempts,
maxAttempts: isNumber(maxAttempts) ? maxAttempts : defaultMaxAttempts,
currentRetry: isNumber(currentRetry) ? currentRetry : 0,
nextAttemptTimestamp: nextAttemptTimestamp || Date.now() + defaultMsBetweenRetries,
currentRetry,
});
}
public async run(): Promise<RunJobResult> {
// blablha do everything from the notion page, and if success, return true.
window.log.warn(
`running job ${this.persistedData.jobType} with id:"${this.persistedData.identifier}" `
);
window.log.debug(`ConfigurationSyncJob starting ${this.persistedData.identifier}`);
const us = UserUtils.getOurPubKeyStrFromCache();
const conversation = getConversationController().get(us);
if (!us || !conversation) {
window.log.warn('did not find our own conversation');
return RunJobResult.PermanentFailure;
}
const name = conversation.get('displayNameInProfile');
const pointer = conversation.get('avatarPointer');
const profileKey = conversation.get('profileKey');
await UserConfigWrapperActions.setName(name || '');
if (profileKey && pointer) {
await UserConfigWrapperActions.setProfilePicture(pointer, from_string(profileKey));
} else {
await UserConfigWrapperActions.setProfilePicture('', new Uint8Array());
}
const data = await UserConfigWrapperActions.push();
const message = new SharedConfigMessage({
data: data.data,
kind: SignalService.SharedConfigMessage.Kind.USER_PROFILE,
seqno: Long.fromNumber(data.seqno),
timestamp: GetNetworkTime.getNowWithNetworkOffset(),
});
await sleepFor(5000);
window.log.warn(
`running job ${this.persistedData.jobType} with id:"${this.persistedData.identifier}" done and returning failed `
const result = await getMessageQueue().sendToPubKeyNonDurably({
message,
namespace: SnodeNamespaces.UserProfile,
pubkey: PubKey.cast(us),
});
console.warn(
`ConfigurationSyncJob sendToPubKeyNonDurably ${this.persistedData.identifier} returned: "${result}"`
);
if (isNumber(result)) {
// try {
// markAsPushed
// }
debugger;
return RunJobResult.Success;
}
return RunJobResult.RetryJobIfPossible;
}
@ -59,3 +111,16 @@ export class ConfigurationSyncJob extends PersistedJob<ConfigurationSyncPersiste
return [];
}
}
/**
* Queue a new Sync Configuration if needed job.
* A ConfigurationSyncJob can only be added if there is none of the same type queued already.
*/
async function queueNewJobIfNeeded() {
await runners.configurationSyncRunner.addJob(new ConfigurationSyncJob({}));
}
export const ConfigurationSync = {
ConfigurationSyncJob,
queueNewJobIfNeeded,
};

@ -1,28 +1,77 @@
import { difference } from 'lodash';
import { difference, isEqual } from 'lodash';
import { UserUtils } from '..';
import { ConfigDumpData } from '../../../data/configDump/configDump';
import { ConfigWrapperObjectTypes } from '../../../webworker/workers/browser/libsession_worker_functions';
import { callLibSessionWorker } from '../../../webworker/workers/browser/libsession_worker_interface';
import {
GenericWrapperActions,
UserConfigWrapperActions,
} from '../../../webworker/workers/browser/libsession_worker_interface';
import { getConversationController } from '../../conversations';
import { ConfigurationSync } from '../job_runners/jobs/ConfigurationSyncJob';
export async function initializeLibSessionUtilWrappers() {
// TODO complete this list
const requiredVariants: Array<ConfigWrapperObjectTypes> = ['UserConfig', 'ContactsConfig']; // 'conversations'
async function insertUserProfileIntoWrapper() {
const us = UserUtils.getOurPubKeyStrFromCache();
const ourConvo = getConversationController().get(us);
if (!ourConvo) {
throw new Error('insertUserProfileIntoWrapper needs a ourConvo to exist');
}
const currentWrapperName = await UserConfigWrapperActions.getName();
const currentWrapperProfileUrl = await UserConfigWrapperActions.getProfilePicture();
const currentDbName = ourConvo.get('displayNameInProfile') || '';
if (!isEqual(currentDbName, currentWrapperName)) {
await UserConfigWrapperActions.setName(currentDbName);
}
}
/**
* Right after we migrated, we won't have any dumps in DB. We must create them from our database state,
*/
async function createConfigDumpsFromDbFirstStart(privateKeyEd25519: Uint8Array) {
let countCreated = 0;
try {
// build the userconfig
await UserConfigWrapperActions.init(privateKeyEd25519, null);
countCreated++;
} catch (e) {
window.log.warn('Failed to init the UserConfig with createConfigDumpsFromDbFirstStart');
}
if (countCreated > 0) {
await ConfigurationSync.queueNewJobIfNeeded();
}
}
async function initializeLibSessionUtilWrappers() {
const keypair = await UserUtils.getUserED25519KeyPairBytes();
if (!keypair) {
if (!keypair || !keypair.privKeyBytes) {
throw new Error('edkeypair not found for current user');
}
const privateKeyEd25519 = keypair.privKeyBytes;
const dumps = await ConfigDumpData.getAllDumpsWithData();
let dumps = await ConfigDumpData.getAllDumpsWithData();
if (!dumps?.length) {
await createConfigDumpsFromDbFirstStart(privateKeyEd25519);
}
// refetch them as the createConfigDumpsFromDb might have created them
dumps = await ConfigDumpData.getAllDumpsWithData();
const userVariantsBuildWithoutErrors = new Set<ConfigWrapperObjectTypes>();
for (let index = 0; index < dumps.length; index++) {
const dump = dumps[index];
try {
await callLibSessionWorker([
await GenericWrapperActions.init(
dump.variant,
'init',
privateKeyEd25519,
dump.data.length ? dump.data : null,
]);
dump.data.length ? dump.data : null
);
userVariantsBuildWithoutErrors.add(dump.variant);
} catch (e) {
@ -31,14 +80,16 @@ export async function initializeLibSessionUtilWrappers() {
}
}
// TODO complete this list
const requiredVariants: Array<ConfigWrapperObjectTypes> = ['UserConfig', 'ContactsConfig']; // 'conversations'
console.warn('requiredVariants: FIXME add conversation volatile wrapper as required ');
const missingRequiredVariants: Array<ConfigWrapperObjectTypes> = difference(requiredVariants, [
...userVariantsBuildWithoutErrors.values(),
]);
for (let index = 0; index < missingRequiredVariants.length; index++) {
const missingVariant = missingRequiredVariants[index];
await callLibSessionWorker([missingVariant, 'init', privateKeyEd25519, null]);
await GenericWrapperActions.init(missingVariant, privateKeyEd25519, null);
}
}
export const LibSessionUtil = { initializeLibSessionUtilWrappers };

@ -35,7 +35,6 @@ describe('libsession_wrapper', () => {
expect(pushResult.seqno).to.be.eq(0);
expect(pushResult.data.length).to.be.eq(256);
expect(conf.encryptionDomain()).to.be.eq('UserProfile');
expect(conf.storageNamespace()).to.be.eq(2);
expect(to_hex(pushResult.data)).to.be.deep.eq(
'9ffb5347e061ac40d937ae4f1a890031475bdc11653f94c8ae1d516ffda71d9ee9cdaf9fbaeb15d835cdc7b3b6ecc120361f004ff172dd5e757c80ede10e88945536e6841255a7bca73664ab8a0607fcfe2579c05bb3d9d4b34ac1de2921e703783ce39e317a512cb9d4e3b59176cbde47b5ba24a03065bf8fefe3e8ca2609e0ad10c7c9c3f81dc6d3a399bda0c190e8a228d0acb22863ab84c2d0c411be74dac4de1f8bc18539635db01ea1ef7f28e505703d67786cb419690edd4bd8c92926fc1d6449eaccc31d7d9639e1b36222e5672b87d1e34b7860308c3f40b3997f39fecf6ceb889323826fa69e001816307799fc9fed302a90faa1e43f7cd7367c3c'

@ -9,6 +9,13 @@ export type AsyncWrapper<T extends (...args: any) => any> = (
...args: Parameters<T>
) => Promise<ReturnType<T>>;
/**
* This type is used to build from an objectType filled with functions, a new object type where all the functions their async equivalent
*/
export type AsyncObjectWrapper<Type extends Record<string, (...args: any) => any>> = {
[Property in keyof Type]: AsyncWrapper<Type[Property]>;
};
export type MsgDuplicateSearchOpenGroup = Array<{
sender: string;
serverTimestamp: number;
@ -25,28 +32,33 @@ export type UpdateLastHashType = {
export type ConfigDumpRow = {
variant: ConfigWrapperObjectTypes; // the variant this entry is about. (user pr, contacts, ...)
pubkey: string; // either our pubkey if a dump for our own swarm or the closed group pubkey
publicKey: string; // either our pubkey if a dump for our own swarm or the closed group pubkey
data: Uint8Array; // the blob returned by libsession.dump() call
combinedMessageHashes?: string; // array of lastHashes to keep track of, stringified
combinedMessageHashes: Array<string>; // array of lastHashes to keep track of
// we might need to add a `seqno` field here.
};
// ========== configdump
export type ConfigDumpRowWithoutData = Pick<
ConfigDumpRow,
'publicKey' | 'combinedMessageHashes' | 'variant'
>;
export type GetByVariantAndPubkeyConfigDump = (
variant: ConfigWrapperObjectTypes,
pubkey: string
) => Array<ConfigDumpRow>;
export type GetByPubkeyConfigDump = (pubkey: string) => Array<ConfigDumpRow>;
export type SaveConfigDump = (dump: ConfigDumpRow) => void;
export type GetAllDumps = () => Array<ConfigDumpRow>;
// ========== configdump
export type ConfigDumpDataNode = {
getConfigDumpByVariantAndPubkey: GetByVariantAndPubkeyConfigDump;
getConfigDumpsByPubkey: GetByPubkeyConfigDump;
saveConfigDump: SaveConfigDump;
getAllDumpsWithData: GetAllDumps;
getAllDumpsWithoutData: GetAllDumps;
getByVariantAndPubkey: (
variant: ConfigWrapperObjectTypes,
publicKey: string
) => Array<ConfigDumpRow>;
getMessageHashesByVariantAndPubkey: (
variant: ConfigWrapperObjectTypes,
publicKey: string
) => Array<string>;
saveConfigDump: (dump: ConfigDumpRow) => void;
saveCombinedMessageHashesForMatching: (row: ConfigDumpRowWithoutData) => void;
getAllDumpsWithData: () => Array<ConfigDumpRow>;
getAllDumpsWithoutData: () => Array<ConfigDumpRowWithoutData>;
};
// ========== unprocessed

@ -1,6 +1,5 @@
import {
BaseConfigActions,
BaseConfigWrapper,
ContactsConfigActionsType,
UserConfigActionsType,
} from 'session_util_wrapper';
@ -20,9 +19,4 @@ type ContactsConfigFunctions =
| [ContactsConfig, ...BaseConfigActions]
| [ContactsConfig, ...ContactsConfigActionsType];
/**Those are the actions inherited from BaseConfigWrapper to ClosedGroupConfigWrapper */
// type ClosedGroupConfigFromBase = [ClosedGroupConfig, ...BaseConfigActions];
// type ClosedGroupConfigFunctions = ClosedGroupConfigFromBase;
//| ClosedGroupConfigFunctions;
export type LibSessionWorkerFunctions = UserConfigFunctions | ContactsConfigFunctions;

@ -1,7 +1,14 @@
import { WorkerInterface } from '../../worker_interface';
import { join } from 'path';
import { getAppRootPath } from '../../../node/getRootPath';
import { LibSessionWorkerFunctions } from './libsession_worker_functions';
import { ConfigWrapperObjectTypes, LibSessionWorkerFunctions } from './libsession_worker_functions';
import {
BaseWrapperActionsCalls,
ContactInfo,
ContactsWrapperActionsCalls,
UserConfigWrapperActionsCalls,
} from 'session_util_wrapper';
let libsessionWorkerInterface: WorkerInterface | undefined;
@ -26,8 +33,138 @@ const internalCallLibSessionWorker = async ([
return libsessionWorkerInterface?.callWorker(config, fnName, ...args);
};
export const callLibSessionWorker = async (
callToMake: LibSessionWorkerFunctions
): Promise<unknown> => {
export const GenericWrapperActions = {
init: async (
wrapperId: ConfigWrapperObjectTypes,
ed25519Key: Uint8Array,
dump: Uint8Array | null
) =>
/** base wrapper generic actions */
callLibSessionWorker([wrapperId, 'init', ed25519Key, dump]) as Promise<void>,
confirmPushed: async (wrapperId: ConfigWrapperObjectTypes, seqno: number) =>
callLibSessionWorker([wrapperId, 'confirmPushed', seqno]) as ReturnType<
BaseWrapperActionsCalls['confirmPushed']
>,
dump: async (wrapperId: ConfigWrapperObjectTypes) =>
callLibSessionWorker([wrapperId, 'dump']) as Promise<
ReturnType<BaseWrapperActionsCalls['dump']>
>,
merge: async (wrapperId: ConfigWrapperObjectTypes, toMerge: Array<Uint8Array>) =>
callLibSessionWorker([wrapperId, 'merge', toMerge]) as Promise<
ReturnType<BaseWrapperActionsCalls['merge']>
>,
needsDump: async (wrapperId: ConfigWrapperObjectTypes) =>
callLibSessionWorker([wrapperId, 'needsDump']) as Promise<
ReturnType<BaseWrapperActionsCalls['needsDump']>
>,
needsPush: async (wrapperId: ConfigWrapperObjectTypes) =>
callLibSessionWorker([wrapperId, 'needsPush']) as Promise<
ReturnType<BaseWrapperActionsCalls['needsPush']>
>,
push: async (wrapperId: ConfigWrapperObjectTypes) =>
callLibSessionWorker([wrapperId, 'push']) as Promise<
ReturnType<BaseWrapperActionsCalls['push']>
>,
storageNamespace: async (wrapperId: ConfigWrapperObjectTypes) =>
callLibSessionWorker([wrapperId, 'storageNamespace']) as Promise<
ReturnType<BaseWrapperActionsCalls['storageNamespace']>
>,
};
export const UserConfigWrapperActions: UserConfigWrapperActionsCalls = {
/* Reuse the GenericWrapperActions with the UserConfig argument */
init: async (ed25519Key: Uint8Array, dump: Uint8Array | null) =>
GenericWrapperActions.init('UserConfig', ed25519Key, dump),
confirmPushed: async (seqno: number) => GenericWrapperActions.confirmPushed('UserConfig', seqno),
dump: async () => GenericWrapperActions.dump('UserConfig'),
merge: async (toMerge: Array<Uint8Array>) => GenericWrapperActions.merge('UserConfig', toMerge),
needsDump: async () => GenericWrapperActions.needsDump('UserConfig'),
needsPush: async () => GenericWrapperActions.needsPush('UserConfig'),
push: async () => GenericWrapperActions.push('UserConfig'),
storageNamespace: async () => GenericWrapperActions.storageNamespace('UserConfig'),
/** UserConfig wrapper specific actions */
getName: async () =>
callLibSessionWorker(['UserConfig', 'getName']) as Promise<
ReturnType<UserConfigWrapperActionsCalls['getName']>
>,
getProfilePicture: async () =>
callLibSessionWorker(['UserConfig', 'getProfilePicture']) as Promise<
ReturnType<UserConfigWrapperActionsCalls['getProfilePicture']>
>,
setName: async (name: string) =>
callLibSessionWorker(['UserConfig', 'setName', name]) as Promise<
ReturnType<UserConfigWrapperActionsCalls['setName']>
>,
setProfilePicture: async (url: string, key: Uint8Array) =>
callLibSessionWorker(['UserConfig', 'setProfilePicture', url, key]) as Promise<
ReturnType<UserConfigWrapperActionsCalls['setProfilePicture']>
>,
};
export const ContactsWrapperActions: ContactsWrapperActionsCalls = {
/* Reuse the GenericWrapperActions with the ContactConfig argument */
init: async (ed25519Key: Uint8Array, dump: Uint8Array | null) =>
GenericWrapperActions.init('ContactsConfig', ed25519Key, dump),
confirmPushed: async (seqno: number) =>
GenericWrapperActions.confirmPushed('ContactsConfig', seqno),
dump: async () => GenericWrapperActions.dump('ContactsConfig'),
merge: async (toMerge: Array<Uint8Array>) =>
GenericWrapperActions.merge('ContactsConfig', toMerge),
needsDump: async () => GenericWrapperActions.needsDump('ContactsConfig'),
needsPush: async () => GenericWrapperActions.needsPush('ContactsConfig'),
push: async () => GenericWrapperActions.push('ContactsConfig'),
storageNamespace: async () => GenericWrapperActions.storageNamespace('ContactsConfig'),
/** ContactsConfig wrapper specific actions */
get: async (pubkeyHex: string) =>
callLibSessionWorker(['ContactsConfig', 'get', pubkeyHex]) as Promise<
ReturnType<ContactsWrapperActionsCalls['get']>
>,
getOrCreate: async (pubkeyHex: string) =>
callLibSessionWorker(['ContactsConfig', 'getOrCreate', pubkeyHex]) as Promise<
ReturnType<ContactsWrapperActionsCalls['getOrCreate']>
>,
getAll: async () =>
callLibSessionWorker(['ContactsConfig', 'getAll']) as Promise<
ReturnType<ContactsWrapperActionsCalls['getAll']>
>,
erase: async (pubkeyHex: string) =>
callLibSessionWorker(['ContactsConfig', 'erase', pubkeyHex]) as Promise<
ReturnType<ContactsWrapperActionsCalls['erase']>
>,
set: async (contact: ContactInfo) =>
callLibSessionWorker(['ContactsConfig', 'set', contact]) as Promise<
ReturnType<ContactsWrapperActionsCalls['set']>
>,
setApproved: async (pubkeyHex: string, approved: boolean) =>
callLibSessionWorker(['ContactsConfig', 'setApproved', pubkeyHex, approved]) as Promise<
ReturnType<ContactsWrapperActionsCalls['setApproved']>
>,
setApprovedMe: async (pubkeyHex: string, approvedMe: boolean) =>
callLibSessionWorker(['ContactsConfig', 'setApprovedMe', pubkeyHex, approvedMe]) as Promise<
ReturnType<ContactsWrapperActionsCalls['setApprovedMe']>
>,
setBlocked: async (pubkeyHex: string, blocked: boolean) =>
callLibSessionWorker(['ContactsConfig', 'setBlocked', pubkeyHex, blocked]) as Promise<
ReturnType<ContactsWrapperActionsCalls['setBlocked']>
>,
setName: async (pubkeyHex: string, name: string) =>
callLibSessionWorker(['ContactsConfig', 'setName', pubkeyHex, name]) as Promise<
ReturnType<ContactsWrapperActionsCalls['setName']>
>,
setNickname: async (pubkeyHex: string, nickname: string) =>
callLibSessionWorker(['ContactsConfig', 'setNickname', pubkeyHex, nickname]) as Promise<
ReturnType<ContactsWrapperActionsCalls['setNickname']>
>,
setProfilePicture: async (pubkeyHex: string, url: string, key: Uint8Array) =>
callLibSessionWorker(['ContactsConfig', 'setProfilePicture', pubkeyHex, url, key]) as Promise<
ReturnType<ContactsWrapperActionsCalls['setProfilePicture']>
>,
};
const callLibSessionWorker = async (callToMake: LibSessionWorkerFunctions): Promise<unknown> => {
return internalCallLibSessionWorker(callToMake);
};

@ -1,19 +1,22 @@
import _, { isEmpty, isNull } from 'lodash';
import { BaseConfigWrapper, ContactsConfigWrapper, UserConfigWrapper } from 'session_util_wrapper';
import {
BaseConfigWrapper,
BaseConfigWrapperInsideWorker,
ContactsConfigWrapperInsideWorker,
UserConfigWrapperInsideWorker,
} from 'session_util_wrapper';
import { ConfigWrapperObjectTypes } from '../../browser/libsession_worker_functions';
/* eslint-disable no-console */
/* eslint-disable strict */
// we can only have one of those so don't worry about storing them in a map for now
let userProfileWrapper: UserConfigWrapper | undefined;
let contactsConfigWrapper: ContactsConfigWrapper | undefined;
// const configWrappers: Array<EntryUserConfig | EntryContactsConfig> = new Array();
let userProfileWrapper: UserConfigWrapperInsideWorker | undefined;
let contactsConfigWrapper: ContactsConfigWrapperInsideWorker | undefined;
type UserWrapperType = 'UserConfig' | 'ContactsConfig';
function getUserWrapper(type: UserWrapperType): BaseConfigWrapper | undefined {
function getUserWrapper(type: UserWrapperType): BaseConfigWrapperInsideWorker | undefined {
switch (type) {
case 'UserConfig':
return userProfileWrapper;
@ -22,7 +25,9 @@ function getUserWrapper(type: UserWrapperType): BaseConfigWrapper | undefined {
}
}
function getCorrespondingWrapper(wrapperType: ConfigWrapperObjectTypes): BaseConfigWrapper {
function getCorrespondingWrapper(
wrapperType: ConfigWrapperObjectTypes
): BaseConfigWrapperInsideWorker {
switch (wrapperType) {
case 'UserConfig':
case 'ContactsConfig':
@ -68,10 +73,10 @@ function initUserWrapper(options: Array<any>, wrapperType: UserWrapperType): Bas
const userType = assertUserWrapperType(wrapperType);
switch (userType) {
case 'UserConfig':
userProfileWrapper = new UserConfigWrapper(edSecretKey, dump);
userProfileWrapper = new UserConfigWrapperInsideWorker(edSecretKey, dump);
return userProfileWrapper;
case 'ContactsConfig':
contactsConfigWrapper = new ContactsConfigWrapper(edSecretKey, dump);
contactsConfigWrapper = new ContactsConfigWrapperInsideWorker(edSecretKey, dump);
return contactsConfigWrapper;
}
}

Loading…
Cancel
Save