remove primary and secondary device separate status

pull/1445/head
Audric Ackermann 4 years ago
parent 135fc3b366
commit a0703bc2f9
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -72,7 +72,6 @@ module.exports = {
removeContactSignedPreKeyByIdentityKey,
removeAllContactSignedPreKeys,
createOrUpdateItem,
getItemById,
getAllItems,
@ -906,7 +905,6 @@ async function updateToLokiSchemaVersion3(currentVersion, instance) {
const SENDER_KEYS_TABLE = 'senderKeys';
async function removeAllClosedGroupRatchets(groupId) {
await db.run(`DELETE FROM ${SENDER_KEYS_TABLE} WHERE groupId = $groupId;`, {
$groupId: groupId,
@ -1550,7 +1548,6 @@ async function removeAllSignedPreKeys() {
return removeAllFromTable(SIGNED_PRE_KEYS_TABLE);
}
const GUARD_NODE_TABLE = 'guardNodes';
async function getGuardNodes() {

@ -2,7 +2,6 @@
$,
_,
Backbone,
getAccountManager,
Signal,
storage,
textsecure,
@ -481,9 +480,7 @@
if (Whisper.Import.isIncomplete()) {
window.log.info('Import was interrupted, showing import error screen');
appView.openImporter();
} else if (
Whisper.Registration.isDone()
) {
} else if (Whisper.Registration.isDone()) {
connect();
appView.openInbox({
initialLoadComplete,

@ -34,17 +34,20 @@
return null;
}
const message = messages.find(
item => !item.isIncoming() && originalSource === item.get('conversationId')
item =>
!item.isIncoming() && originalSource === item.get('conversationId')
);
if (message) {
return message;
}
const groups = await window.Signal.Data.getAllGroupsInvolvingId(originalSource, {
ConversationCollection: Whisper.ConversationCollection,
});
const groups = await window.Signal.Data.getAllGroupsInvolvingId(
originalSource,
{
ConversationCollection: Whisper.ConversationCollection,
}
);
const ids = groups.pluck('id');
ids.push(originalSource);

@ -921,8 +921,6 @@
}
},
async updateExpirationTimer(
providedExpireTimer,
providedSource,

@ -990,7 +990,7 @@
// Special-case the self-send case - we send only a sync message
if (recipients.length === 1) {
const isOurDevice = await libsession.Utils.UserUtil.isUs(
const isOurDevice = await libsession.Utils.UserUtils.isUs(
recipients[0]
);
if (isOurDevice) {
@ -1102,7 +1102,7 @@
async handleMessageSentSuccess(sentMessage, wrappedEnvelope) {
let sentTo = this.get('sent_to') || [];
const isOurDevice = await window.libsession.Utils.UserUtil.isUs(
const isOurDevice = await window.libsession.Utils.UserUtils.isUs(
sentMessage.device
);
// FIXME this is not correct and will cause issues with syncing
@ -1201,7 +1201,7 @@
await c.getProfiles();
}
}
const isOurDevice = await window.libsession.Utils.UserUtil.isUs(
const isOurDevice = await window.libsession.Utils.UserUtils.isUs(
sentMessage.device
);
const expirationStartTimestamp = Date.now();
@ -1366,12 +1366,14 @@
await this.sendSyncMessage(data);
},
async sendSyncMessage(dataMessage) {
async sendSyncMessage(/* dataMessage */) {
if (this.get('synced') || this.get('sentSync')) {
return;
}
window.log.error('sendSyncMessage to upgrade to multi device protocol v2')
window.log.error(
'sendSyncMessage to upgrade to multi device protocol v2'
);
// const data =
// dataMessage instanceof libsession.Messages.Outgoing.DataMessage

@ -1,4 +1,4 @@
/* global window, setTimeout, clearTimeout, IDBKeyRange, dcodeIO */
/* global window, setTimeout, clearTimeout, IDBKeyRange */
const electron = require('electron');
const { ipcRenderer } = electron;
@ -598,7 +598,6 @@ async function removeAllContactSignedPreKeys() {
await channels.removeAllContactSignedPreKeys();
}
function getGuardNodes() {
return channels.getGuardNodes();
}

@ -1862,137 +1862,11 @@ class LokiPublicChannelAPI {
return;
}
// slave to primary map for this group of messages
let slavePrimaryMap = {};
// reduce list of servers into verified maps and keys
const verifiedPrimaryPKs = await Object.keys(homeServerPubKeys).reduce(
async (curVal, serverUrl) => {
// get an API to this server
const serverAPI = await window.lokiFileServerAPIFactory.establishConnection(
serverUrl
);
// get list of verified primary PKs
const result = await serverAPI.verifyPrimaryPubKeys(
homeServerPubKeys[serverUrl]
);
// merged these device mappings into our slavePrimaryMap
// should not be any collisions, since each pubKey can only have one home server
slavePrimaryMap = { ...slavePrimaryMap, ...result.slaveMap };
// copy verified pub keys into result
return curVal.concat(result.verifiedPrimaryPKs);
},
[]
);
// filter out invalid messages
pendingMessages = pendingMessages.filter(messageData => !!messageData);
// separate messages coming from primary and secondary devices
let [primaryMessages, slaveMessages] = _.partition(
pendingMessages,
message => !(message.source in slavePrimaryMap)
);
// get minimum ID for primaryMessages and slaveMessages
const firstPrimaryId = _.min(primaryMessages.map(msg => msg.serverId));
const firstSlaveId = _.min(slaveMessages.map(msg => msg.serverId));
if (firstPrimaryId < firstSlaveId) {
// early send
// split off count from pendingMessages
let sendNow = [];
[sendNow, pendingMessages] = _.partition(
pendingMessages,
message => message.serverId < firstSlaveId
);
sendNow.forEach(message => {
// send them out now
log.info(
'emitting primary message',
message.serverId,
'on',
this.channelId,
'at',
this.serverAPI.baseServerUrl
);
this.chatAPI.emit('publicMessage', {
message,
});
});
sendNow = false;
}
primaryMessages = false; // free memory
// get actual chat server data (mainly the name rn) of primary device
const verifiedDeviceResults = await this.serverAPI.getUsers(
verifiedPrimaryPKs
);
// build map of userProfileName to primaryKeys
/* eslint-disable no-param-reassign */
this.primaryUserProfileName = verifiedDeviceResults.reduce(
(mapOut, user) => {
let avatar = null;
let profileKey = null;
const avatarNote = user.annotations.find(
note => note.type === AVATAR_USER_ANNOTATION_TYPE
);
if (avatarNote) {
({ profileKey, url: avatar } = avatarNote.value);
}
mapOut[user.username] = {
name: user.name,
avatar,
profileKey,
};
return mapOut;
},
{}
);
/* eslint-enable no-param-reassign */
// process remaining messages
/* eslint-disable no-param-reassign */
slaveMessages.forEach(messageData => {
const slaveKey = messageData.source;
// prevent our own device sent messages from coming back in
if (slaveKey === ourNumberDevice) {
// we originally sent these
return;
}
// look up primary device once
const primaryPubKey = slavePrimaryMap[slaveKey];
// send out remaining messages for this merged identity
/* eslint-disable no-param-reassign */
if (slavePrimaryMap[slaveKey]) {
// rewrite source, profile
messageData.source = primaryPubKey;
const primaryProfile = this.primaryUserProfileName[primaryPubKey];
if (primaryProfile) {
const { name, avatar, profileKey } = primaryProfile;
messageData.message.profile.displayName = name;
messageData.message.profile.avatar = avatar;
messageData.message.profileKey = profileKey;
}
}
});
slaveMessages = false; // free memory
// process all messages in the order received
pendingMessages.forEach(message => {
// if slave device
if (message.source in slavePrimaryMap) {
// prevent our own device sent messages from coming back in
if (message.source === ourNumberDevice) {
// we originally sent these
return;
}
}
if (this.running) {
log.info(
'emitting pending message',

@ -1,9 +1,8 @@
/* global log, libloki, window */
/* global log, window */
/* global log: false */
const LokiAppDotNetAPI = require('./loki_app_dot_net_api');
// can have multiple of these instances as each user can have a
// different home server
class LokiFileServerInstance {

@ -2,16 +2,12 @@
window,
textsecure,
libsignal,
libloki,
libsession,
lokiFileServerAPI,
mnemonic,
btoa,
getString,
Event,
dcodeIO,
StringView,
log,
Event,
Whisper
*/
@ -146,7 +142,6 @@
store.clearPreKeyStore(),
store.clearSignedPreKeysStore(),
]);
},
async generateMnemonic(language = 'english') {
// Note: 4 bytes are converted into 3 seed words, so length 12 seed words
@ -166,7 +161,7 @@
window.log.info('registration done');
textsecure.storage.put('primaryDevicePubKey', number);
// Ensure that we always have a conversation for ourself
const conversation = await window
.getConversationController()

@ -469,6 +469,12 @@ $session-compose-margin: 20px;
.left-pane-setting {
&-bottom-buttons {
@include bottom-buttons();
.session-button {
vertical-align: middle;
white-space: normal;
text-align: center;
}
}
&-content,

@ -2,9 +2,10 @@ import React from 'react';
import { RenderTextCallbackType } from '../../types/Util';
import classNames from 'classnames';
import { FindMember, UserUtil } from '../../util';
import { FindMember } from '../../util';
import { useInterval } from '../../hooks/useInterval';
import { ConversationModel } from '../../../js/models/conversations';
import { isUs } from '../../session/utils/User';
interface MentionProps {
key: string;
@ -24,7 +25,7 @@ const Mention = (props: MentionProps) => {
);
if (foundMember) {
const itsUs = await UserUtil.isUs(foundMember.id);
const itsUs = await isUs(foundMember.id);
setUs(itsUs);
setFound(foundMember);
// FIXME stop this interval once we found it.

@ -10,11 +10,11 @@ import { ConversationType } from '../../state/ducks/conversations';
import { noop } from 'lodash';
import { DefaultTheme } from 'styled-components';
import { StateType } from '../../state/reducer';
import { UserUtil } from '../../util';
import { ConversationController } from '../../session/conversations';
import { getFocusedSection } from '../../state/selectors/section';
import { getTheme } from '../../state/selectors/theme';
import { getOurNumber } from '../../state/selectors/user';
import { UserUtils } from '../../session/utils';
// tslint:disable-next-line: no-import-side-effect no-submodule-imports
export enum SectionType {
@ -197,7 +197,7 @@ class ActionsPanelPrivate extends React.Component<Props> {
};
private async showResetSessionIDDialogIfNeeded() {
const userED25519KeyPairHex = await UserUtil.getUserED25519KeyPair();
const userED25519KeyPairHex = await UserUtils.getUserED25519KeyPair();
if (userED25519KeyPairHex) {
return;
}

@ -140,7 +140,6 @@ export class LeftPaneSettingSection extends React.Component<Props, State> {
}
public renderBottomButtons(): JSX.Element | undefined {
const dangerButtonText = window.i18n('clearAllData');
const showRecoveryPhrase = window.i18n('showRecoveryPhrase');
@ -152,7 +151,7 @@ export class LeftPaneSettingSection extends React.Component<Props, State> {
buttonColor={SessionButtonColor.Danger}
onClick={this.onDeleteAccount}
/>
<SessionButton
text={showRecoveryPhrase}
buttonType={SessionButtonType.SquareOutline}
@ -164,7 +163,6 @@ export class LeftPaneSettingSection extends React.Component<Props, State> {
}
public onDeleteAccount() {
const title = window.i18n('clearAllData');
const message = window.i18n('unpairDeviceWarning');

@ -410,7 +410,7 @@ export class RegistrationTabs extends React.Component<any, State> {
</div>
);
}
if (signUpMode === SignUpMode.EnterDetails) {
return (
<div className={classNames('session-registration__entry-fields')}>

@ -102,11 +102,7 @@ export class SessionInboxView extends React.Component<Props, State> {
const category =
this.state.settingsCategory || SessionSettingCategory.Appearance;
return (
<FilteredSettingsView
category={category}
/>
);
return <FilteredSettingsView category={category} />;
}
private renderSessionConversation() {

@ -11,7 +11,7 @@ import {
import { Constants } from '../../../session';
import _ from 'lodash';
import { AttachmentUtil, GoogleChrome, UserUtil } from '../../../util';
import { AttachmentUtil, GoogleChrome } from '../../../util';
import { ConversationHeaderWithDetails } from '../../conversation/ConversationHeader';
import { SessionRightPanelWithDetails } from './SessionRightPanel';
import { SessionTheme } from '../../../state/ducks/SessionTheme';
@ -21,7 +21,7 @@ import { LightboxGallery, MediaItemType } from '../../LightboxGallery';
import { Message } from '../../conversation/media-gallery/types/Message';
import { AttachmentType, save } from '../../../types/Attachment';
import { ToastUtils } from '../../../session/utils';
import { ToastUtils, UserUtils } from '../../../session/utils';
import * as MIME from '../../../types/MIME';
import { SessionFileDropzone } from './SessionFileDropzone';
import { ConversationType } from '../../../state/ducks/conversations';
@ -682,14 +682,15 @@ export class SessionConversation extends React.Component<Props, State> {
if (selectedConversation.isPublic) {
// Get our Moderator status
const ourDevicePubkey = await UserUtil.getCurrentDevicePubKey();
const ourDevicePubkey = await UserUtils.getCurrentDevicePubKey();
if (!ourDevicePubkey) {
return;
}
const isAdmin = conversationModel.isAdmin(ourDevicePubkey);
const isAllOurs = selectedMessages.every(message =>
ourDevicePubkey === message.attributes.source);
const isAllOurs = selectedMessages.every(
message => ourDevicePubkey === message.attributes.source
);
if (!isAllOurs && !isAdmin) {
ToastUtils.pushMessageDeleteForbidden();

@ -7,11 +7,9 @@ import {
SessionButtonColor,
SessionButtonType,
} from '../SessionButton';
import { BlockedNumberController, UserUtil } from '../../../util';
import { BlockedNumberController } from '../../../util';
import { ToastUtils } from '../../../session/utils';
import {
ConversationLookupType,
} from '../../../state/ducks/conversations';
import { ConversationLookupType } from '../../../state/ducks/conversations';
import { StateType } from '../../../state/reducer';
import { ConversationController } from '../../../session/conversations';
import {
@ -102,7 +100,7 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
const { category } = this.props;
let settings: Array<LocalSettingType>;
if (category === SessionSettingCategory.Blocked) {
// special case for blocked user
settings = this.getBlockedUserSettings();
@ -633,7 +631,6 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
return results;
}
private async onKeyUp(event: any) {
const lockPasswordFocussed = ($('#password-lock-input') as any).is(
':focus'

@ -3,7 +3,9 @@ import { SettingsViewProps } from './SessionSettings';
import { DefaultTheme, withTheme } from 'styled-components';
interface Props extends SettingsViewProps {
// tslint:disable-next-line: react-unused-props-and-state
categoryTitle: string;
// tslint:disable-next-line: react-unused-props-and-state
theme: DefaultTheme;
}
@ -14,6 +16,6 @@ const SettingsHeaderInner = (props: Props) => {
<div className="session-settings-header-title">{categoryTitle}</div>
</div>
);
}
};
export const SettingsHeader = withTheme(SettingsHeaderInner);

@ -1,5 +1,4 @@
import { GroupUtils } from '../../session/utils';
import { UserUtil } from '../../util';
import { GroupUtils, UserUtils } from '../../session/utils';
import { PubKey } from '../../session/types';
import React from 'react';
import * as _ from 'lodash';
@ -56,7 +55,9 @@ export function usingClosedConversationDetails(WrappedComponent: any) {
(conversationType === 'group' || type === 'group' || isGroup)
) {
const groupId = id || phoneNumber;
const ourPrimary = PubKey.cast(await UserUtil.getCurrentDevicePubKey());
const ourPrimary = PubKey.cast(
await UserUtils.getCurrentDevicePubKey()
);
let members = await GroupUtils.getGroupMembers(PubKey.cast(groupId));
const ourself = members.find(m => m.key !== ourPrimary.key);

@ -2,10 +2,10 @@ import { SignalService } from '../protobuf';
import { removeFromCache } from './cache';
import { EnvelopePlus } from './types';
import { PubKey } from '../session/types';
import { fromHexToArray, toHex } from '../session/utils/String';
import { toHex } from '../session/utils/String';
import { ConversationController } from '../session/conversations';
import * as ClosedGroupV2 from '../session/groupv2';
import { BlockedNumberController, UserUtil } from '../util';
import { BlockedNumberController } from '../util';
import {
generateClosedGroupV2PublicKey,
generateCurve25519KeyPairWithoutPrefix,
@ -18,55 +18,9 @@ import {
ClosedGroupV2NewMessageParams,
} from '../session/messages/outgoing/content/data/groupv2/ClosedGroupV2NewMessage';
import { KeyPair } from '../../libtextsecure/libsignal-protocol';
import { getOurNumber } from '../util/user';
export type HexKeyPair = {
publicHex: string;
privateHex: string;
};
export class ECKeyPair {
public readonly publicKeyData: Uint8Array;
public readonly privateKeyData: Uint8Array;
constructor(publicKeyData: Uint8Array, privateKeyData: Uint8Array) {
this.publicKeyData = publicKeyData;
this.privateKeyData = privateKeyData;
}
public static fromArrayBuffer(pub: ArrayBuffer, priv: ArrayBuffer) {
return new ECKeyPair(new Uint8Array(pub), new Uint8Array(priv));
}
public static fromKeyPair(pair: KeyPair) {
return new ECKeyPair(
new Uint8Array(pair.pubKey),
new Uint8Array(pair.privKey)
);
}
public static fromHexKeyPair(pair: HexKeyPair) {
return new ECKeyPair(
fromHexToArray(pair.publicHex),
fromHexToArray(pair.privateHex)
);
}
public toString() {
const hexKeypair = this.toHexKeyPair();
return `ECKeyPair: ${hexKeypair.publicHex} ${hexKeypair.privateHex}`;
}
public toHexKeyPair(): HexKeyPair {
const publicHex = toHex(this.publicKeyData);
const privateHex = toHex(this.privateKeyData);
return {
publicHex,
privateHex,
};
}
}
import { ECKeyPair } from './keypairs';
import { getOurNumber } from '../session/utils/User';
import { UserUtils } from '../session/utils';
export async function handleClosedGroupV2(
envelope: EnvelopePlus,
@ -161,7 +115,9 @@ async function handleNewClosedGroupV2(
) {
const { log } = window;
if (groupUpdate.type !== SignalService.DataMessage.ClosedGroupUpdateV2.Type.NEW) {
if (
groupUpdate.type !== SignalService.DataMessage.ClosedGroupUpdateV2.Type.NEW
) {
return;
}
if (!sanityCheckNewGroupV2(groupUpdate)) {
@ -182,7 +138,7 @@ async function handleNewClosedGroupV2(
const members = membersAsData.map(toHex);
const admins = adminsAsData.map(toHex);
const ourPrimary = await UserUtil.getOurNumber();
const ourPrimary = await UserUtils.getOurNumber();
if (!members.includes(ourPrimary.key)) {
log.info(
'Got a new group message but apparently we are not a member of it. Dropping it.'
@ -263,7 +219,10 @@ async function handleUpdateClosedGroupV2(
envelope: EnvelopePlus,
groupUpdate: SignalService.DataMessage.ClosedGroupUpdateV2
) {
if (groupUpdate.type !== SignalService.DataMessage.ClosedGroupUpdateV2.Type.UPDATE) {
if (
groupUpdate.type !==
SignalService.DataMessage.ClosedGroupUpdateV2.Type.UPDATE
) {
return;
}
const { name, members: membersBinary } = groupUpdate;
@ -317,7 +276,7 @@ async function handleUpdateClosedGroupV2(
const diff = ClosedGroupV2.buildGroupDiff(convo, { name, members });
// Check whether we are still in the group
const ourNumber = await UserUtil.getOurNumber();
const ourNumber = await UserUtils.getOurNumber();
const wasCurrentUserRemoved = !members.includes(ourNumber.key);
const isCurrentUserAdmin = curAdmins?.includes(ourNumber.key);
@ -391,9 +350,9 @@ async function handleKeyPairClosedGroupV2(
) {
return;
}
const ourNumber = await UserUtil.getOurNumber();
const ourNumber = await UserUtils.getOurNumber();
const groupPublicKey = envelope.source;
const ourKeyPair = await UserUtil.getIdentityKeyPair();
const ourKeyPair = await UserUtils.getIdentityKeyPair();
if (!ourKeyPair) {
window.log.warn("Couldn't find user X25519 key pair.");
@ -455,7 +414,9 @@ async function handleKeyPairClosedGroupV2(
// Parse it
let proto: SignalService.DataMessage.ClosedGroupUpdateV2.KeyPair;
try {
proto = SignalService.DataMessage.ClosedGroupUpdateV2.KeyPair.decode(plaintext);
proto = SignalService.DataMessage.ClosedGroupUpdateV2.KeyPair.decode(
plaintext
);
if (
!proto ||
proto.privateKey.length === 0 ||

@ -3,9 +3,9 @@ import { EnvelopePlus } from './types';
export function getEnvelopeId(envelope: EnvelopePlus) {
if (envelope.source) {
return `${envelope.source} ${toNumber(
envelope.timestamp
)} (${envelope.id})`;
return `${envelope.source} ${toNumber(envelope.timestamp)} (${
envelope.id
})`;
}
return envelope.id;

@ -8,13 +8,12 @@ import * as Lodash from 'lodash';
import { PubKey } from '../session/types';
import { BlockedNumberController } from '../util/blockedNumberController';
import { GroupUtils } from '../session/utils';
import { UserUtil } from '../util';
import { GroupUtils, UserUtils } from '../session/utils';
import { fromHexToArray, toHex } from '../session/utils/String';
import { concatUInt8Array, getSodium } from '../session/crypto';
import { ConversationController } from '../session/conversations';
import * as Data from '../../js/modules/data';
import { ECKeyPair } from './closedGroupsV2';
import { ECKeyPair } from './keypairs';
export async function handleContentMessage(envelope: EnvelopePlus) {
try {
@ -91,7 +90,7 @@ async function decryptForClosedGroupV2(
);
}
window.log.info('ClosedGroupV2 Message decrypted successfully.');
const ourDevicePubKey = await UserUtil.getCurrentDevicePubKey();
const ourDevicePubKey = await UserUtils.getCurrentDevicePubKey();
if (
envelope.senderIdentity &&
@ -221,7 +220,7 @@ async function decryptUnidentifiedSender(
): Promise<ArrayBuffer | null> {
window.log.info('received unidentified sender message');
try {
const userX25519KeyPair = await UserUtil.getIdentityKeyPair();
const userX25519KeyPair = await UserUtils.getIdentityKeyPair();
if (!userX25519KeyPair) {
throw new Error('Failed to find User x25519 keypair from stage'); // noUserX25519KeyPair
}

@ -8,12 +8,12 @@ import { PubKey } from '../session/types';
import { handleMessageJob } from './queuedJob';
import { downloadAttachment } from './attachments';
import _ from 'lodash';
import { StringUtils } from '../session/utils';
import { StringUtils, UserUtils } from '../session/utils';
import { DeliveryReceiptMessage } from '../session/messages/outgoing';
import { getMessageQueue } from '../session';
import { ConversationController } from '../session/conversations';
import { handleClosedGroupV2 } from './closedGroupsV2';
import { UserUtil } from '../util';
import { isUs } from '../session/utils/User';
export async function updateProfile(
conversation: any,
@ -30,7 +30,8 @@ export async function updateProfile(
// TODO: may need to allow users to reset their avatars to null
if (profile.profilePicture) {
const prevPointer = conversation.get('avatarPointer');
const needsUpdate = !prevPointer || !_.isEqual(prevPointer, profile.profilePicture);
const needsUpdate =
!prevPointer || !_.isEqual(prevPointer, profile.profilePicture);
if (needsUpdate) {
conversation.set('avatarPointer', profile.profilePicture);
@ -276,7 +277,7 @@ export async function handleDataMessage(
}
const source = envelope.senderIdentity || senderPubKey;
const ownDevice = await UserUtil.isUs(source);
const ownDevice = await isUs(source);
const ownMessage = conversation?.isMediumGroup() && ownDevice;
@ -563,8 +564,6 @@ export async function handleMessageEvent(event: MessageEvent): Promise<void> {
type,
isIncoming
);
confirm();
return;
}
const msg = createMessage(data, isIncoming);
@ -578,7 +577,7 @@ export async function handleMessageEvent(event: MessageEvent): Promise<void> {
}
// TODO: this shouldn't be called when source is not a pubkey!!!
const isOurDevice = await UserUtil.isUs(source);
const isOurDevice = await UserUtils.isUs(source);
const shouldSendReceipt =
isIncoming &&
@ -628,7 +627,7 @@ export async function handleMessageEvent(event: MessageEvent): Promise<void> {
message,
ourNumber,
confirm,
source,
source
).ignore();
});
}

@ -0,0 +1,49 @@
import { KeyPair } from '../../libtextsecure/libsignal-protocol';
import { fromHexToArray, toHex } from '../session/utils/String';
export type HexKeyPair = {
publicHex: string;
privateHex: string;
};
export class ECKeyPair {
public readonly publicKeyData: Uint8Array;
public readonly privateKeyData: Uint8Array;
constructor(publicKeyData: Uint8Array, privateKeyData: Uint8Array) {
this.publicKeyData = publicKeyData;
this.privateKeyData = privateKeyData;
}
public static fromArrayBuffer(pub: ArrayBuffer, priv: ArrayBuffer) {
return new ECKeyPair(new Uint8Array(pub), new Uint8Array(priv));
}
public static fromKeyPair(pair: KeyPair) {
return new ECKeyPair(
new Uint8Array(pair.pubKey),
new Uint8Array(pair.privKey)
);
}
public static fromHexKeyPair(pair: HexKeyPair) {
return new ECKeyPair(
fromHexToArray(pair.publicHex),
fromHexToArray(pair.privateHex)
);
}
public toString() {
const hexKeypair = this.toHexKeyPair();
return `ECKeyPair: ${hexKeypair.publicHex} ${hexKeypair.privateHex}`;
}
public toHexKeyPair(): HexKeyPair {
const publicHex = toHex(this.publicKeyData);
const privateHex = toHex(this.privateKeyData);
return {
publicHex,
privateHex,
};
}
}

@ -6,9 +6,8 @@ import { MessageModel } from '../../js/models/messages';
import { PubKey } from '../session/types';
import _ from 'lodash';
import { SignalService } from '../protobuf';
import { StringUtils } from '../session/utils';
import { StringUtils, UserUtils } from '../session/utils';
import { ConversationController } from '../session/conversations';
import { UserUtil } from '../util';
async function handleGroups(
conversation: ConversationModel,
@ -54,9 +53,7 @@ async function handleGroups(
// Check if anyone got kicked:
const removedMembers = _.difference(oldMembers, attributes.members);
const isOurDeviceMap = await Promise.all(
removedMembers.map(async member =>
UserUtil.isUs(member)
)
removedMembers.map(async member => UserUtils.isUs(member))
);
const ourDeviceWasRemoved = isOurDeviceMap.includes(true);
@ -67,7 +64,7 @@ async function handleGroups(
groupUpdate.kicked = removedMembers;
}
} else if (group.type === GROUP_TYPES.QUIT) {
if (await UserUtil.isUs(source)) {
if (await UserUtils.isUs(source)) {
attributes.left = true;
groupUpdate = { left: 'You' };
} else {
@ -356,7 +353,7 @@ async function handleRegularMessage(
message: MessageModel,
initialMessage: any,
source: string,
ourNumber: string,
ourNumber: string
) {
const { upgradeMessageSchema } = window.Signal.Migrations;
@ -413,7 +410,7 @@ async function handleRegularMessage(
conversation
);
const ourPubKey = PubKey.cast(ourNumber)
const ourPubKey = PubKey.cast(ourNumber);
handleMentions(message, conversation, ourPubKey);
@ -453,7 +450,7 @@ async function handleRegularMessage(
// we just received a message from that user so we reset the typing indicator for this convo
conversation.notifyTyping({
isTyping: false,
sender: ourPubKey.key,
sender: source,
});
}
@ -495,7 +492,7 @@ export async function handleMessageJob(
initialMessage: any,
ourNumber: string,
confirm: () => void,
source: string,
source: string
) {
window.log.info(
`Starting handleDataMessage for message ${message.idForLogging()} in conversation ${conversation.idForLogging()}`
@ -527,7 +524,7 @@ export async function handleMessageJob(
message,
initialMessage,
source,
ourNumber,
ourNumber
);
}

@ -19,10 +19,9 @@ export { processMessage };
import { handleMessageEvent, updateProfile } from './dataMessage';
import { getEnvelopeId } from './common';
import { StringUtils } from '../session/utils';
import { StringUtils, UserUtils } from '../session/utils';
import { SignalService } from '../protobuf';
import { ConversationController } from '../session/conversations';
import { UserUtil } from '../util';
// TODO: check if some of these exports no longer needed
@ -286,7 +285,7 @@ export async function handleUnencryptedMessage({ message: outerMessage }: any) {
await updateProfile(conversation, profile, profileKey);
}
const isOurDevice = await UserUtil.isUs(source);
const isOurDevice = await UserUtils.isUs(source);
const isPublicChatMessage =
group && group.id && !!group.id.match(/^publicChat:/);

@ -1,13 +1,11 @@
import { EncryptionType } from '../types/EncryptionType';
import { SignalService } from '../../protobuf';
import { UserUtil } from '../../util';
import { CipherTextObject } from '../../../libtextsecure/libsignal-protocol';
import { PubKey } from '../types';
import { concatUInt8Array, getSodium } from '.';
import { fromHexToArray } from '../utils/String';
import { ECKeyPair } from '../../receiver/closedGroupsV2';
export { concatUInt8Array, getSodium };
import { getLatestClosedGroupEncryptionKeyPair } from '../../../js/modules/data';
import { UserUtils } from '../utils';
/**
* Add padding to a message buffer
@ -104,7 +102,7 @@ export async function encryptUsingSessionProtocol(
recipientHexEncodedX25519PublicKey: PubKey,
plaintext: Uint8Array
): Promise<Uint8Array> {
const userED25519KeyPairHex = await UserUtil.getUserED25519KeyPair();
const userED25519KeyPairHex = await UserUtils.getUserED25519KeyPair();
if (
!userED25519KeyPairHex ||
!userED25519KeyPairHex.pubKey?.length ||

@ -5,9 +5,8 @@ export { MessageEncrypter };
// libsodium-wrappers requires the `require` call to work
// tslint:disable-next-line: no-require-imports
import libsodiumwrappers = require('libsodium-wrappers');
import { fromHex } from 'bytebuffer';
import { toHex } from '../utils/String';
import { ECKeyPair } from '../../receiver/closedGroupsV2';
import { ECKeyPair } from '../../receiver/keypairs';
export async function getSodium(): Promise<typeof libsodiumwrappers> {
await libsodiumwrappers.ready;

@ -3,24 +3,24 @@ import * as Data from '../../../js/modules/data';
import _ from 'lodash';
import { fromHex, fromHexToArray, toHex } from '../utils/String';
import { UserUtil } from '../../util';
import { MessageModel, MessageModelType } from '../../../js/models/messages';
import { ConversationModel } from '../../../js/models/conversations';
import { BlockedNumberController } from '../../util/blockedNumberController';
import { ConversationController } from '../conversations';
import { updateOpenGroup } from '../../receiver/openGroups';
import { ECKeyPair } from '../../receiver/closedGroupsV2';
import { getMessageQueue } from '../instance';
import {
ClosedGroupV2EncryptionPairMessage,
ClosedGroupV2NewMessage,
ClosedGroupV2UpdateMessage,
ExpirationTimerUpdateMessage,
} from '../messages/outgoing';
} from '../messages/outgoing/';
import uuid from 'uuid';
import { SignalService } from '../../protobuf';
import { generateCurve25519KeyPairWithoutPrefix } from '../crypto';
import { encryptUsingSessionProtocol } from '../crypto/MessageEncrypter';
import { ECKeyPair } from '../../receiver/keypairs';
import { UserUtils } from '../utils';
export interface GroupInfo {
id: string;
@ -255,7 +255,7 @@ export async function updateOrCreateClosedGroupV2(details: GroupInfo) {
if (expireTimer === undefined || typeof expireTimer !== 'number') {
return;
}
const source = await UserUtil.getCurrentDevicePubKey();
const source = await UserUtils.getCurrentDevicePubKey();
await conversation.updateExpirationTimer(expireTimer, source, Date.now(), {
fromSync: true,
});
@ -270,7 +270,7 @@ export async function leaveClosedGroupV2(groupId: string) {
window.log.error('Cannot leave non-existing v2 group');
return;
}
const ourNumber = await UserUtil.getOurNumber();
const ourNumber = await UserUtils.getOurNumber();
const isCurrentUserAdmin = convo.get('groupAdmins')?.includes(ourNumber.key);
const now = Date.now();
@ -320,7 +320,7 @@ export async function sendGroupUpdateForClosedV2(
messageId: string
) {
const { id: groupId, members, name: groupName, expireTimer } = groupUpdate;
const ourNumber = await UserUtil.getOurNumber();
const ourNumber = await UserUtils.getOurNumber();
const removedMembers = diff.leavingMembers || [];
const newMembers = diff.joiningMembers || []; // joining members
@ -461,7 +461,7 @@ export async function generateAndSendNewEncryptionKeyPair(
return;
}
const ourNumber = await UserUtil.getOurNumber();
const ourNumber = await UserUtils.getOurNumber();
if (!groupConvo.get('groupAdmins')?.includes(ourNumber.key)) {
window.log.warn(
'generateAndSendNewEncryptionKeyPair: cannot send it as a non admin'

@ -7,7 +7,9 @@ import {
interface ClosedGroupV2EncryptionPairMessageParams
extends ClosedGroupV2MessageParams {
encryptedKeyPairs: Array<SignalService.DataMessage.ClosedGroupUpdateV2.KeyPairWrapper>;
encryptedKeyPairs: Array<
SignalService.DataMessage.ClosedGroupUpdateV2.KeyPairWrapper
>;
}
export class ClosedGroupV2EncryptionPairMessage extends ClosedGroupV2Message {

@ -1,7 +1,7 @@
import { DataMessage } from '../DataMessage';
import { MessageParams } from '../../../Message';
import { PubKey } from '../../../../../types';
import { SignalService } from '../../../../../../protobuf';
import { PubKey } from '../../../../../types/PubKey';
export interface ClosedGroupV2MessageParams extends MessageParams {
groupId: string | PubKey;

@ -4,7 +4,7 @@ import {
ClosedGroupV2MessageParams,
} from './ClosedGroupV2Message';
import { fromHexToArray } from '../../../../../utils/String';
import { ECKeyPair } from '../../../../../../receiver/closedGroupsV2';
import { ECKeyPair } from '../../../../../../receiver/keypairs';
export interface ClosedGroupV2NewMessageParams
extends ClosedGroupV2MessageParams {

@ -1,5 +1,4 @@
export * from './ClosedGroupV2ChatMessage';
export * from './ClosedGroupV2EncryptionPairMessage';
export * from './ClosedGroupV2Message';
export * from './ClosedGroupV2NewMessage';
export * from './ClosedGroupV2UpdateMessage';

@ -1,5 +1,10 @@
export * from './DataMessage';
export * from './GroupInvitationMessage';
export * from './ChatMessage';
export * from './groupv2';
export * from './groupv2/ClosedGroupV2Message';
export * from './groupv2/ClosedGroupV2ChatMessage';
export * from './groupv2/ClosedGroupV2EncryptionPairMessage';
export * from './groupv2/ClosedGroupV2NewMessage';
export * from './groupv2/ClosedGroupV2UpdateMessage';
export * from './groupv2/ClosedGroupV2Message';
export * from './ExpirationTimerUpdateMessage';

@ -5,16 +5,15 @@ import {
MessageQueueInterfaceEvents,
} from './MessageQueueInterface';
import {
ClosedGroupV2Message,
ContentMessage,
ExpirationTimerUpdateMessage,
OpenGroupMessage,
} from '../messages/outgoing';
import { PendingMessageCache } from './PendingMessageCache';
import { JobQueue, TypedEventEmitter } from '../utils';
import { JobQueue, TypedEventEmitter, UserUtils } from '../utils';
import { PubKey, RawMessage } from '../types';
import { MessageSender } from '.';
import { UserUtil } from '../../util';
import { ClosedGroupV2Message } from '../messages/outgoing/content/data/groupv2/ClosedGroupV2Message';
export class MessageQueue implements MessageQueueInterface {
public readonly events: TypedEventEmitter<MessageQueueInterfaceEvents>;
@ -115,13 +114,13 @@ export class MessageQueue implements MessageQueueInterface {
return;
}
const ourPubKey = await UserUtil.getCurrentDevicePubKey();
const ourPubKey = await UserUtils.getCurrentDevicePubKey();
if(!ourPubKey) {
throw new Error('ourNumber is not set')
if (!ourPubKey) {
throw new Error('ourNumber is not set');
}
window.log.warn('sendSyncMessage TODO with syncTarget')
window.log.warn('sendSyncMessage TODO with syncTarget');
await this.sendMessageToDevices([PubKey.cast(ourPubKey)], message, sentCb);
}
@ -183,7 +182,7 @@ export class MessageQueue implements MessageQueueInterface {
sentCb?: (message: RawMessage) => Promise<void>
): Promise<void> {
// Don't send to ourselves
const currentDevice = await UserUtil.getCurrentDevicePubKey();
const currentDevice = await UserUtils.getCurrentDevicePubKey();
if (currentDevice && device.isEqual(currentDevice)) {
return;
}

@ -1,7 +1,4 @@
import {
ContentMessage,
OpenGroupMessage,
} from '../messages/outgoing';
import { ContentMessage, OpenGroupMessage } from '../messages/outgoing';
import { RawMessage } from '../types/RawMessage';
import { TypedEventEmitter } from '../utils';
import { PubKey } from '../types';

@ -3,10 +3,10 @@
import { RawMessage } from '../types/RawMessage';
import { OpenGroupMessage } from '../messages/outgoing';
import { SignalService } from '../../protobuf';
import { UserUtil } from '../../util';
import { MessageEncrypter } from '../crypto';
import pRetry from 'p-retry';
import { PubKey } from '../types';
import { UserUtils } from '../utils';
// ================ Regular ================
@ -70,10 +70,9 @@ async function buildEnvelope(
if (type === SignalService.Envelope.Type.CLOSED_GROUP_CIPHERTEXT) {
source = sskSource;
} else if (type !== SignalService.Envelope.Type.UNIDENTIFIED_SENDER) {
source = await UserUtil.getCurrentDevicePubKey();
}
return SignalService.Envelope.create({
type,
source,

@ -48,7 +48,7 @@ export class PubKey {
* @param value The value to cast.
*/
public static cast(value?: string | PubKey): PubKey {
if(!value) {
if (!value) {
throw new Error(`Invalid pubkey string passed: ${value}`);
}
return typeof value === 'string' ? new PubKey(value) : value;
@ -135,4 +135,4 @@ export class PubKey {
public withoutPrefixToArray(): Uint8Array {
return fromHexToArray(PubKey.remove05PrefixIfNeeded(this.key));
}
}
}

@ -3,9 +3,7 @@ import { PubKey } from '../types';
import { ConversationController } from '../conversations';
import { fromHexToArray } from './String';
export async function getGroupMembers(
groupId: PubKey
): Promise<Array<PubKey>> {
export async function getGroupMembers(groupId: PubKey): Promise<Array<PubKey>> {
const groupConversation = ConversationController.getInstance().get(
groupId.key
);

@ -20,7 +20,8 @@ export function getEncryptionTypeFromMessageType(
// 2. if TypingMessage or ExpirationTimer and groupId is set => must be encoded with ClosedGroup too
if (
message instanceof ClosedGroupV2Message ||
(message instanceof ExpirationTimerUpdateMessage && message.groupId)) {
(message instanceof ExpirationTimerUpdateMessage && message.groupId)
) {
return EncryptionType.ClosedGroup;
} else {
return EncryptionType.Fallback;
@ -33,7 +34,7 @@ export async function toRawMessage(
): Promise<RawMessage> {
const timestamp = message.timestamp;
const ttl = message.ttl();
window?.log?.debug('toRawMessage proto:', message.contentProto());
// window?.log?.debug('toRawMessage proto:', message.contentProto());
const plainTextBuffer = message.plainTextBuffer();
const encryption = getEncryptionTypeFromMessageType(message);

@ -1,9 +1,23 @@
import { getItemById } from '../../js/modules/data';
import { KeyPair } from '../../libtextsecure/libsignal-protocol';
import { StringUtils } from '../session/utils';
import _ from 'lodash';
import { PubKey } from '../session/types';
import { UserUtil } from '.';
import { UserUtils } from '.';
import { getItemById } from '../../../js/modules/data';
import { KeyPair } from '../../../libtextsecure/libsignal-protocol';
import { PubKey } from '../types';
import { toHex } from './String';
export async function isUs(
pubKey: string | PubKey | undefined
): Promise<boolean> {
if (!pubKey) {
throw new Error('pubKey is not set');
}
const ourNumber = await UserUtils.getCurrentDevicePubKey();
if (!ourNumber) {
throw new Error('ourNumber is not set');
}
const pubKeyStr = pubKey instanceof PubKey ? pubKey.key : pubKey;
return pubKeyStr === ourNumber;
}
export type HexKeyPair = {
pubKey: string;
@ -23,25 +37,13 @@ export async function getCurrentDevicePubKey(): Promise<string | undefined> {
}
export async function getOurNumber(): Promise<PubKey> {
const ourNumber = await UserUtil.getCurrentDevicePubKey();
if(!ourNumber) {
const ourNumber = await UserUtils.getCurrentDevicePubKey();
if (!ourNumber) {
throw new Error('ourNumber is not set');
}
return PubKey.cast(ourNumber);
}
export async function isUs(pubKey: string | PubKey | undefined): Promise<boolean> {
if(!pubKey) {
throw new Error('pubKey is not set');
}
const ourNumber = await UserUtil.getCurrentDevicePubKey();
if(!ourNumber) {
throw new Error('ourNumber is not set');
}
const pubKeyStr = pubKey instanceof PubKey ? pubKey.key : pubKey;
return pubKeyStr === ourNumber;
}
/**
* This return the stored x25519 identity keypair for the current logged in user
*/
@ -60,8 +62,8 @@ export async function getUserED25519KeyPair(): Promise<HexKeyPair | undefined> {
const pubKeyAsArray = _.map(ed25519KeyPair.publicKey, a => a);
const privKeyAsArray = _.map(ed25519KeyPair.privateKey, a => a);
return {
pubKey: StringUtils.toHex(new Uint8Array(pubKeyAsArray)),
privKey: StringUtils.toHex(new Uint8Array(privKeyAsArray)),
pubKey: toHex(new Uint8Array(pubKeyAsArray)),
privKey: toHex(new Uint8Array(privKeyAsArray)),
};
}
return undefined;

@ -6,6 +6,7 @@ import * as PromiseUtils from './Promise';
import * as ProtobufUtils from './Protobuf';
import * as MenuUtils from '../../components/session/menu/Menu';
import * as ToastUtils from './Toast';
import * as UserUtils from './User';
export * from './Attachments';
export * from './TypedEmitter';
@ -20,4 +21,5 @@ export {
ProtobufUtils,
MenuUtils,
ToastUtils,
UserUtils,
};

@ -578,9 +578,7 @@ export function reducer(
if (action.type === 'CONVERSATION_CHANGED') {
const { payload } = action;
const { id, data } = payload;
const { conversationLookup } = state;
let selectedConversation = state.selectedConversation;
const { conversationLookup, selectedConversation } = state;
const existing = conversationLookup[id];
// In the change case we only modify the lookup if we already had that conversation

@ -260,7 +260,6 @@ async function queryConversationsAndContacts(
query
);
// Split into two groups - active conversations and items just from address book
let conversations: Array<string> = [];
let contacts: Array<string> = [];

@ -10,8 +10,7 @@ import {
MessageTypeInConvo,
} from '../ducks/conversations';
import { getIntl, getRegionCode, getOurNumber } from './user';
import { ConversationListItemProps } from '../../components/ConversationListItem';
import { getIntl, getOurNumber, getRegionCode } from './user';
import { BlockedNumberController } from '../../util';
export const getConversations = (state: StateType): ConversationsStateType =>

@ -3,11 +3,7 @@ import { LeftPane } from '../../components/LeftPane';
import { StateType } from '../reducer';
import { getQuery, getSearchResults, isSearching } from '../selectors/search';
import {
getIntl,
getRegionCode,
getOurNumber,
} from '../selectors/user';
import { getIntl, getOurNumber, getRegionCode } from '../selectors/user';
import {
getLeftPaneLists,
getOurPrimaryConversation,
@ -17,7 +13,7 @@ import { getFocusedSection } from '../selectors/section';
import { getTheme } from '../selectors/theme';
// Workaround: A react component's required properties are filtering up through connect()
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31363
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/3136k3
const mapStateToProps = (state: StateType) => {
const showSearch = isSearching(state);

@ -326,9 +326,7 @@ export class Common {
return [app1, app2];
}
public static async addFriendToNewClosedGroup(
members: Array<Application>,
) {
public static async addFriendToNewClosedGroup(members: Array<Application>) {
const [app, ...others] = members;
await app.client

@ -55,7 +55,6 @@ async function makeFriendsPlusMessage(
async function testTwoMembers() {
const [app, app2] = await Common.startAppsAsFriends();
// create group and add new friend
await Common.addFriendToNewClosedGroup([app, app2]);

@ -8,10 +8,9 @@ import {
} from '../../../../session/crypto';
import { EncryptionType } from '../../../../session/types/EncryptionType';
import { Stubs, TestUtils } from '../../../test-utils';
import { UserUtil } from '../../../../util';
import { SignalService } from '../../../../protobuf';
import { StringUtils } from '../../../../session/utils';
import { StringUtils, UserUtils } from '../../../../session/utils';
import chaiBytes from 'chai-bytes';
import { PubKey } from '../../../../session/types';
@ -118,9 +117,9 @@ describe('MessageEncrypter', () => {
} as any,
});
sandbox.stub(UserUtil, 'getCurrentDevicePubKey').resolves(ourNumber);
sandbox.stub(UserUtils, 'getCurrentDevicePubKey').resolves(ourNumber);
sandbox
.stub(UserUtil, 'getUserED25519KeyPair')
.stub(UserUtils, 'getUserED25519KeyPair')
.resolves(ourUserEd25516Keypair);
});
@ -187,7 +186,7 @@ describe('MessageEncrypter', () => {
sandboxSessionProtocol = sinon.createSandbox();
sandboxSessionProtocol
.stub(UserUtil, 'getIdentityKeyPair')
.stub(UserUtils, 'getIdentityKeyPair')
.resolves(ourIdentityKeypair);
});
@ -211,7 +210,7 @@ describe('MessageEncrypter', () => {
});
it('should pass the correct data for sodium crypto_sign', async () => {
const keypair = await UserUtil.getUserED25519KeyPair();
const keypair = await UserUtils.getUserED25519KeyPair();
const recipient = TestUtils.generateFakePubKey();
const sodium = await getSodium();
const cryptoSignDetachedSpy = sandboxSessionProtocol.spy(
@ -266,8 +265,8 @@ describe('MessageEncrypter', () => {
it('should return valid decodable ciphertext', async () => {
// for testing, we encode a message to ourself
const userX25519KeyPair = await UserUtil.getIdentityKeyPair();
const userEd25519KeyPair = await UserUtil.getUserED25519KeyPair();
const userX25519KeyPair = await UserUtils.getIdentityKeyPair();
const userEd25519KeyPair = await UserUtils.getUserED25519KeyPair();
const plainTextBytes = new Uint8Array(
StringUtils.encode('123456789', 'utf8')

@ -63,7 +63,7 @@ describe('ChatMessage', () => {
.to.have.deep.property('displayName', 'displayName');
expect(decoded.dataMessage)
.to.have.property('profile')
.to.have.deep.property('avatar', 'avatarPointer');
.to.have.deep.property('profilePicture', 'avatarPointer');
expect(decoded.dataMessage).to.have.deep.property('profileKey', profileKey);
});

@ -3,18 +3,17 @@ import * as sinon from 'sinon';
import _ from 'lodash';
import { describe } from 'mocha';
import { GroupUtils, PromiseUtils } from '../../../../session/utils';
import { TestUtils } from '../../../../test/test-utils';
import { GroupUtils, PromiseUtils, UserUtils } from '../../../../session/utils';
import { TestUtils } from '../../../../test/test-utils';
import { MessageQueue } from '../../../../session/sending/MessageQueue';
import {
ContentMessage,
OpenGroupMessage,
} from '../../../../session/messages/outgoing';
import {PubKey, RawMessage } from '../../../../session/types';
import { UserUtil } from '../../../../util';
import { PubKey, RawMessage } from '../../../../session/types';
import { MessageSender } from '../../../../session/sending';
import { PendingMessageCacheStub } from '../../../test-utils/stubs';
import { ClosedGroupV2Message } from '../../../../session/messages/outgoing/content/data/groupv2';
import { ClosedGroupV2Message } from '../../../../session/messages/outgoing/content/data/groupv2/ClosedGroupV2Message';
// tslint:disable-next-line: no-require-imports no-var-requires
const chaiAsPromised = require('chai-as-promised');
@ -38,7 +37,7 @@ describe('MessageQueue', () => {
beforeEach(async () => {
// Utils Stubs
sandbox.stub(UserUtil, 'getCurrentDevicePubKey').resolves(ourNumber);
sandbox.stub(UserUtils, 'getCurrentDevicePubKey').resolves(ourNumber);
TestUtils.stubWindow('libsignal', {
SignalProtocolAddress: sandbox.stub(),
@ -213,7 +212,10 @@ describe('MessageQueue', () => {
});
it('should emit a success event when send was successful', async () => {
sendToOpenGroupStub.resolves({ serverId: 5125, serverTimestamp: 5125 });
sendToOpenGroupStub.resolves({
serverId: 5125,
serverTimestamp: 5125,
});
const message = TestUtils.generateOpenGroupMessage();
const eventPromise = PromiseUtils.waitForTask(complete => {
@ -237,4 +239,4 @@ describe('MessageQueue', () => {
});
});
});
});
});

@ -5,12 +5,12 @@ import { toNumber } from 'lodash';
import { MessageSender } from '../../../../session/sending';
import LokiMessageAPI from '../../../../../js/modules/loki_message_api';
import { TestUtils } from '../../../test-utils';
import { UserUtil } from '../../../../util';
import { MessageEncrypter } from '../../../../session/crypto';
import { SignalService } from '../../../../protobuf';
import { OpenGroupMessage } from '../../../../session/messages/outgoing';
import { EncryptionType } from '../../../../session/types/EncryptionType';
import { PubKey } from '../../../../session/types';
import { UserUtils } from '../../../../session/utils';
describe('MessageSender', () => {
const sandbox = sinon.createSandbox();
@ -35,6 +35,7 @@ describe('MessageSender', () => {
});
});
// tslint:disable-next-line: max-func-body-length
describe('send', () => {
const ourNumber = '0123456789abcdef';
let lokiMessageAPISendStub: sinon.SinonStub<
@ -58,7 +59,7 @@ describe('MessageSender', () => {
cipherText: crypto.randomBytes(10),
});
sandbox.stub(UserUtil, 'getCurrentDevicePubKey').resolves(ourNumber);
sandbox.stub(UserUtils, 'getCurrentDevicePubKey').resolves(ourNumber);
});
describe('retry', () => {
@ -161,8 +162,10 @@ describe('MessageSender', () => {
const envelope = SignalService.Envelope.decode(
webSocketMessage.request?.body as Uint8Array
);
expect(envelope.type).to.equal(SignalService.Envelope.Type.UNIDENTIFIED_SENDER);
expect(envelope.source).to.equal(ourNumber);
expect(envelope.type).to.equal(
SignalService.Envelope.Type.UNIDENTIFIED_SENDER
);
expect(envelope.source).to.equal('');
expect(toNumber(envelope.timestamp)).to.equal(timestamp);
expect(envelope.content).to.deep.equal(plainTextBuffer);
});

@ -1,7 +1,6 @@
import * as crypto from 'crypto';
import { ECKeyPair } from '../../../receiver/closedGroupsV2';
import { ECKeyPair } from '../../../receiver/keypairs';
import { PubKey } from '../../../session/types';
import { fromHexToArray } from '../../../session/utils/String';
export function generateFakePubKey(): PubKey {
// Generates a mock pubkey for testing

@ -3,8 +3,9 @@ import * as sinon from 'sinon';
import { BlockedNumberController } from '../../util/blockedNumberController';
import { TestUtils } from '../test-utils';
import { PubKey } from '../../session/types';
import { UserUtil } from '../../util';
import { UserUtils } from '../../session/utils';
// tslint:disable-next-line: max-func-body-length
describe('BlockedNumberController', () => {
const sandbox = sinon.createSandbox();
let memoryDB: { [key: string]: any };
@ -78,10 +79,9 @@ describe('BlockedNumberController', () => {
describe('unblock', async () => {
it('should unblock the user', async () => {
const primary = TestUtils.generateFakePubKey();
const secondary = TestUtils.generateFakePubKey();
memoryDB.blocked = [primary.key];
await BlockedNumberController.unblock(secondary);
await BlockedNumberController.unblock(primary);
const blockedNumbers = BlockedNumberController.getBlockedNumbers();
expect(blockedNumbers).to.be.empty;
@ -166,14 +166,11 @@ describe('BlockedNumberController', () => {
let ourDevice: PubKey;
beforeEach(() => {
ourDevice = TestUtils.generateFakePubKey();
sandbox.stub(UserUtil, 'getCurrentDevicePubKey').resolves(ourDevice.key);
sandbox.stub(UserUtils, 'getCurrentDevicePubKey').resolves(ourDevice.key);
});
it('should return false for our device', async () => {
const isBlocked = await BlockedNumberController.isBlockedAsync(ourDevice);
expect(isBlocked).to.equal(
false,
'Expected our device to return false'
);
expect(isBlocked).to.equal(false, 'Expected our device to return false');
});
it('should return true if the device is blocked', async () => {

@ -1,6 +1,6 @@
import { UserUtil } from '.';
import { createOrUpdateItem, getItemById } from '../../js/modules/data';
import { PubKey } from '../session/types';
import { UserUtils } from '../session/utils';
const BLOCKED_NUMBERS_ID = 'blocked';
const BLOCKED_GROUPS_ID = 'blocked-groups';
@ -18,7 +18,7 @@ export class BlockedNumberController {
*/
public static async isBlockedAsync(user: string | PubKey): Promise<boolean> {
await this.load();
const isOurDevice = await UserUtil.isUs(user);
const isOurDevice = await UserUtils.isUs(user);
if (isOurDevice) {
return false;
}

@ -5,7 +5,6 @@ import { missingCaseError } from './missingCaseError';
import { migrateColor } from './migrateColor';
import { makeLookup } from './makeLookup';
import { FindMember } from './findMember';
import * as UserUtil from './user';
import * as PasswordUtil from './passwordUtils';
import * as AttachmentUtil from './attachmentsUtil';
import * as LinkPreviewUtil from './linkPreviewFetch';
@ -19,7 +18,6 @@ export {
makeLookup,
migrateColor,
missingCaseError,
UserUtil,
PasswordUtil,
FindMember,
AttachmentUtil,

Loading…
Cancel
Save