Merge pull request #3119 from oxen-io/clearnet

Session 1.12.4
pull/3124/head v1.12.4
Audric Ackermann 10 months ago committed by GitHub
commit ab86cafb68
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

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

@ -5,6 +5,8 @@
<!-- Mac distribution --> <!-- Mac distribution -->
<key>com.apple.security.cs.allow-unsigned-executable-memory</key> <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/> <true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key> <key>com.apple.security.cs.disable-library-validation</key>
<true/> <true/>
<key>com.apple.security.device.audio-input</key> <key>com.apple.security.device.audio-input</key>

@ -5,6 +5,10 @@
<!-- Mac app store --> <!-- Mac app store -->
<key>com.apple.security.app-sandbox</key> <key>com.apple.security.app-sandbox</key>
<true/> <true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.network.client</key> <key>com.apple.security.network.client</key>
<true/> <true/>
<key>com.apple.security.files.user-selected.read-only</key> <key>com.apple.security.files.user-selected.read-only</key>

@ -29,7 +29,7 @@ exports.default = async function notarizing(context) {
} }
const options = { const options = {
appBundleId: 'org.getsession.desktop', appBundleId: 'com.loki-project.messenger-desktop',
appPath: `${appOutDir}/${appName}.app`, appPath: `${appOutDir}/${appName}.app`,
appleId: SIGNING_APPLE_ID, appleId: SIGNING_APPLE_ID,
appleIdPassword: SIGNING_APP_PASSWORD, appleIdPassword: SIGNING_APP_PASSWORD,

@ -2,7 +2,7 @@
"name": "session-desktop", "name": "session-desktop",
"productName": "Session", "productName": "Session",
"description": "Private messaging from your desktop", "description": "Private messaging from your desktop",
"version": "1.12.3", "version": "1.12.4",
"license": "GPL-3.0", "license": "GPL-3.0",
"author": { "author": {
"name": "Oxen Labs", "name": "Oxen Labs",
@ -95,7 +95,7 @@
"fs-extra": "9.0.0", "fs-extra": "9.0.0",
"glob": "7.1.2", "glob": "7.1.2",
"image-type": "^4.1.0", "image-type": "^4.1.0",
"libsession_util_nodejs": "https://github.com/oxen-io/libsession-util-nodejs/releases/download/v0.3.1/libsession_util_nodejs-v0.3.1.tar.gz", "libsession_util_nodejs": "https://github.com/oxen-io/libsession-util-nodejs/releases/download/v0.3.19/libsession_util_nodejs-v0.3.19.tar.gz",
"libsodium-wrappers-sumo": "^0.7.9", "libsodium-wrappers-sumo": "^0.7.9",
"linkify-it": "^4.0.1", "linkify-it": "^4.0.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",

@ -20,11 +20,6 @@
.module-contact-name__profile-number.italic { .module-contact-name__profile-number.italic {
font-style: italic; font-style: italic;
} }
.module-contact-name.compact {
display: block;
}
// Module: Message // Module: Message
.module-message__error-container { .module-message__error-container {

@ -13,12 +13,11 @@ type Props = {
profileName?: string | null; profileName?: string | null;
module?: string; module?: string;
boldProfileName?: boolean; boldProfileName?: boolean;
compact?: boolean;
shouldShowPubkey: boolean; shouldShowPubkey: boolean;
}; };
export const ContactName = (props: Props) => { export const ContactName = (props: Props) => {
const { pubkey, name, profileName, module, boldProfileName, compact, shouldShowPubkey } = props; const { pubkey, name, profileName, module, boldProfileName, shouldShowPubkey } = props;
const prefix = module || 'module-contact-name'; const prefix = module || 'module-contact-name';
const convoName = useNicknameOrProfileNameOrShortenedPubkey(pubkey); const convoName = useNicknameOrProfileNameOrShortenedPubkey(pubkey);
@ -43,7 +42,7 @@ export const ContactName = (props: Props) => {
return ( return (
<span <span
className={classNames(prefix, compact && 'compact')} className={classNames(prefix)}
dir="auto" dir="auto"
data-testid={`${prefix}__profile-name`} data-testid={`${prefix}__profile-name`}
style={{ style={{

@ -1,6 +1,6 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React, { useState } from 'react';
import { noop } from 'lodash'; import { noop } from 'lodash';
import React, { useState } from 'react';
import * as MIME from '../../../../types/MIME'; import * as MIME from '../../../../types/MIME';
import * as GoogleChrome from '../../../../util/GoogleChrome'; import * as GoogleChrome from '../../../../util/GoogleChrome';
@ -291,7 +291,6 @@ const QuoteAuthor = (props: QuoteAuthorProps) => {
pubkey={PubKey.shorten(author)} pubkey={PubKey.shorten(author)}
name={authorName} name={authorName}
profileName={authorProfileName} profileName={authorProfileName}
compact={true}
shouldShowPubkey={Boolean(props.showPubkeyForAuthor)} shouldShowPubkey={Boolean(props.showPubkeyForAuthor)}
/> />
)} )}

@ -41,7 +41,6 @@ export const QuoteAuthor = (props: QuoteAuthorProps) => {
<ContactName <ContactName
pubkey={PubKey.shorten(author)} pubkey={PubKey.shorten(author)}
name={authorName} name={authorName}
compact={true}
shouldShowPubkey={Boolean(authorName && !isMe && isPublic)} shouldShowPubkey={Boolean(authorName && !isMe && isPublic)}
/> />
</StyledQuoteAuthor> </StyledQuoteAuthor>

@ -14,6 +14,7 @@ import {
} from '../../state/ducks/modalDialog'; } from '../../state/ducks/modalDialog';
import { import {
useSelectedIsPublic, useSelectedIsPublic,
useSelectedWeAreAdmin,
useSelectedWeAreModerator, useSelectedWeAreModerator,
} from '../../state/selectors/selectedConversation'; } from '../../state/selectors/selectedConversation';
import { SortedReactionList } from '../../types/Reaction'; import { SortedReactionList } from '../../types/Reaction';
@ -50,6 +51,11 @@ const StyledSendersContainer = styled(Flex)`
padding: 0 16px 16px; padding: 0 16px 16px;
`; `;
const StyledContactContainer = styled.span`
text-overflow: ellipsis;
overflow: hidden;
`;
const StyledReactionBar = styled(Flex)` const StyledReactionBar = styled(Flex)`
width: 100%; width: 100%;
margin: 12px 0 20px 4px; margin: 12px 0 20px 4px;
@ -132,7 +138,7 @@ const ReactionSenders = (props: ReactionSendersProps) => {
justifyContent={'space-between'} justifyContent={'space-between'}
alignItems={'center'} alignItems={'center'}
> >
<Flex container={true} alignItems={'center'}> <Flex container={true} alignItems={'center'} style={{ overflow: 'hidden' }}>
<Avatar <Avatar
size={AvatarSize.XS} size={AvatarSize.XS}
pubkey={sender} pubkey={sender}
@ -143,11 +149,13 @@ const ReactionSenders = (props: ReactionSendersProps) => {
{sender === me ? ( {sender === me ? (
window.i18n('you') window.i18n('you')
) : ( ) : (
<ContactName <StyledContactContainer>
pubkey={sender} <ContactName
module="module-conversation__user" pubkey={sender}
shouldShowPubkey={false} module="module-conversation__user"
/> shouldShowPubkey={false}
/>
</StyledContactContainer>
)} )}
</Flex> </Flex>
{sender === me && ( {sender === me && (
@ -231,6 +239,7 @@ export const ReactListModal = (props: Props) => {
const msgProps = useMessageReactsPropsById(messageId); const msgProps = useMessageReactsPropsById(messageId);
const isPublic = useSelectedIsPublic(); const isPublic = useSelectedIsPublic();
const weAreAdmin = useSelectedWeAreAdmin();
const weAreModerator = useSelectedWeAreModerator(); const weAreModerator = useSelectedWeAreModerator();
const me = UserUtils.getOurPubKeyStrFromCache(); const me = UserUtils.getOurPubKeyStrFromCache();
@ -362,7 +371,7 @@ export const ReactListModal = (props: Props) => {
</> </>
)} )}
</p> </p>
{isPublic && weAreModerator && ( {isPublic && (weAreAdmin || weAreModerator) && (
<SessionButton <SessionButton
text={window.i18n('clearAll')} text={window.i18n('clearAll')}
buttonColor={SessionButtonColor.Danger} buttonColor={SessionButtonColor.Danger}

@ -88,7 +88,19 @@ export type SessionIconType =
export type SessionIconSize = 'tiny' | 'small' | 'medium' | 'large' | 'huge' | 'huge2' | 'max'; export type SessionIconSize = 'tiny' | 'small' | 'medium' | 'large' | 'huge' | 'huge2' | 'max';
export const icons: Record<string, { path: string; viewBox: string; ratio: number }> = { export type ClipRule = 'nonzero' | 'evenodd' | 'inherit';
export type FillRule = 'nonzero' | 'evenodd';
type IconProps = {
path: string;
viewBox: string;
ratio: number;
fill?: string;
clipRule?: ClipRule;
fillRule?: FillRule;
};
export const icons: Record<SessionIconType, IconProps> = {
addUser: { addUser: {
path: 'M8.85,2.17c-1.73,0-3.12,1.4-3.12,3.12s1.4,3.12,3.12,3.12c1.73,0,3.13-1.4,3.13-3.12S10.58,2.17,8.85,2.17z M8.85,0.08c2.88,0,5.21,2.33,5.21,5.21s-2.33,5.21-5.21,5.21s-5.2-2.33-5.2-5.21C3.65,2.42,5.98,0.08,8.85,0.08z M20.83,5.29 c0.54,0,0.98,0.41,1.04,0.93l0.01,0.11v2.08h2.08c0.54,0,0.98,0.41,1.04,0.93v0.12c0,0.54-0.41,0.98-0.93,1.04l-0.11,0.01h-2.08 v2.08c0,0.58-0.47,1.04-1.04,1.04c-0.54,0-0.98-0.41-1.04-0.93l-0.01-0.11v-2.08h-2.08c-0.54,0-0.98-0.41-1.04-0.93l-0.01-0.11 c0-0.54,0.41-0.98,0.93-1.04l0.11-0.01h2.08V6.34C19.79,5.76,20.26,5.29,20.83,5.29z M12.5,12.58c2.8,0,5.09,2.21,5.2,4.99v0.22 v2.08c0,0.58-0.47,1.04-1.04,1.04c-0.54,0-0.98-0.41-1.04-0.93l-0.01-0.11v-2.08c0-1.67-1.3-3.03-2.95-3.12h-0.18H5.21 c-1.67,0-3.03,1.3-3.12,2.95v0.18v2.08c0,0.58-0.47,1.04-1.04,1.04c-0.54,0-0.98-0.41-1.04-0.93L0,19.88V17.8 c0-2.8,2.21-5.09,4.99-5.2h0.22h7.29V12.58z', path: 'M8.85,2.17c-1.73,0-3.12,1.4-3.12,3.12s1.4,3.12,3.12,3.12c1.73,0,3.13-1.4,3.13-3.12S10.58,2.17,8.85,2.17z M8.85,0.08c2.88,0,5.21,2.33,5.21,5.21s-2.33,5.21-5.21,5.21s-5.2-2.33-5.2-5.21C3.65,2.42,5.98,0.08,8.85,0.08z M20.83,5.29 c0.54,0,0.98,0.41,1.04,0.93l0.01,0.11v2.08h2.08c0.54,0,0.98,0.41,1.04,0.93v0.12c0,0.54-0.41,0.98-0.93,1.04l-0.11,0.01h-2.08 v2.08c0,0.58-0.47,1.04-1.04,1.04c-0.54,0-0.98-0.41-1.04-0.93l-0.01-0.11v-2.08h-2.08c-0.54,0-0.98-0.41-1.04-0.93l-0.01-0.11 c0-0.54,0.41-0.98,0.93-1.04l0.11-0.01h2.08V6.34C19.79,5.76,20.26,5.29,20.83,5.29z M12.5,12.58c2.8,0,5.09,2.21,5.2,4.99v0.22 v2.08c0,0.58-0.47,1.04-1.04,1.04c-0.54,0-0.98-0.41-1.04-0.93l-0.01-0.11v-2.08c0-1.67-1.3-3.03-2.95-3.12h-0.18H5.21 c-1.67,0-3.03,1.3-3.12,2.95v0.18v2.08c0,0.58-0.47,1.04-1.04,1.04c-0.54,0-0.98-0.41-1.04-0.93L0,19.88V17.8 c0-2.8,2.21-5.09,4.99-5.2h0.22h7.29V12.58z',
viewBox: '0 0 25 21', viewBox: '0 0 25 21',

@ -1,7 +1,8 @@
import React from 'react'; import React, { memo } from 'react';
import styled, { css, keyframes } from 'styled-components'; import styled, { css, CSSProperties, keyframes } from 'styled-components';
import { icons, SessionIconSize, SessionIconType } from '.'; import { icons, SessionIconSize, SessionIconType } from '.';
import { ClipRule, FillRule } from './Icons';
export type SessionIconProps = { export type SessionIconProps = {
iconType: SessionIconType; iconType: SessionIconType;
@ -15,6 +16,7 @@ export type SessionIconProps = {
glowStartDelay?: number; glowStartDelay?: number;
noScale?: boolean; noScale?: boolean;
backgroundColor?: string; backgroundColor?: string;
style?: CSSProperties;
dataTestId?: string; dataTestId?: string;
unreadCount?: number; unreadCount?: number;
}; };
@ -55,6 +57,9 @@ type StyledSvgProps = {
noScale?: boolean; noScale?: boolean;
iconColor?: string; iconColor?: string;
backgroundColor?: string; backgroundColor?: string;
fill?: string;
clipRule?: ClipRule;
filleRule?: FillRule;
}; };
const rotate = keyframes` const rotate = keyframes`
@ -119,37 +124,28 @@ const animation = (props: {
return undefined; return undefined;
}; };
const Svg = React.memo(styled.svg<StyledSvgProps>` const Svg = memo(styled.svg<StyledSvgProps>`
width: ${props => props.width}; width: ${props => props.width};
transform: ${props => `rotate(${props.iconRotation}deg)`}; transform: ${props => `rotate(${props.iconRotation}deg)`};
${props => animation(props)}; ${props => animation(props)};
border-radius: ${props => props.borderRadius}; border-radius: ${props => props.borderRadius};
background-color: ${props => background-color: ${props =>
props.backgroundColor ? props.backgroundColor : '--button-icon-background-color'}; props.backgroundColor ? props.backgroundColor : 'var(--button-icon-background-color)'};
border-radius: ${props => (props.borderRadius ? props.borderRadius : '')};
filter: ${props => (props.noScale ? `drop-shadow(0px 0px 4px ${props.iconColor})` : '')}; filter: ${props => (props.noScale ? `drop-shadow(0px 0px 4px ${props.iconColor})` : '')};
fill: ${props => (props.iconColor ? props.iconColor : '--button-icon-stroke-color')}; fill: ${props => (props.iconColor ? props.iconColor : 'var(--button-icon-stroke-color)')};
padding: ${props => (props.iconPadding ? props.iconPadding : '')}; padding: ${props => (props.iconPadding ? props.iconPadding : '')};
transition: inherit; transition: inherit;
`); `);
const SessionSvg = (props: { const SessionSvg = (
viewBox: string; props: StyledSvgProps & {
path: string | Array<string>; viewBox: string;
width: string | number; path: string | Array<string>;
height: string | number; style?: CSSProperties;
iconRotation: number; dataTestId?: string;
iconColor?: string; }
rotateDuration?: number; ) => {
glowDuration?: number; const colorSvg = props.iconColor ? props.iconColor : 'var(--button-icon-stroke-color)';
glowStartDelay?: number;
noScale?: boolean;
borderRadius?: string;
backgroundColor?: string;
iconPadding?: string;
dataTestId?: string;
}) => {
const colorSvg = props.iconColor ? props.iconColor : '--button-icon-stroke-color';
const pathArray = props.path instanceof Array ? props.path : [props.path]; const pathArray = props.path instanceof Array ? props.path : [props.path];
const propsToPick = { const propsToPick = {
width: props.width, width: props.width,
@ -164,6 +160,10 @@ const SessionSvg = (props: {
backgroundColor: props.backgroundColor, backgroundColor: props.backgroundColor,
borderRadius: props.borderRadius, borderRadius: props.borderRadius,
iconPadding: props.iconPadding, iconPadding: props.iconPadding,
fill: props.fill,
clipRule: props.clipRule,
fillRule: props.filleRule,
style: props.style,
dataTestId: props.dataTestId, dataTestId: props.dataTestId,
}; };
@ -187,6 +187,7 @@ export const SessionIcon = (props: SessionIconProps) => {
noScale, noScale,
backgroundColor, backgroundColor,
iconPadding, iconPadding,
style,
dataTestId, dataTestId,
} = props; } = props;
let { iconSize, iconRotation } = props; let { iconSize, iconRotation } = props;
@ -196,6 +197,9 @@ export const SessionIcon = (props: SessionIconProps) => {
const iconDimensions = getIconDimensionFromIconSize(iconSize); const iconDimensions = getIconDimensionFromIconSize(iconSize);
const iconDef = icons[iconType]; const iconDef = icons[iconType];
const ratio = iconDef?.ratio || 1; const ratio = iconDef?.ratio || 1;
const fill = iconDef?.fill || undefined;
const clipRule = iconDef?.clipRule || 'nonzero';
const fillRule = iconDef?.fillRule || 'nonzero';
return ( return (
<SessionSvg <SessionSvg
@ -212,6 +216,10 @@ export const SessionIcon = (props: SessionIconProps) => {
iconColor={iconColor} iconColor={iconColor}
backgroundColor={backgroundColor} backgroundColor={backgroundColor}
iconPadding={iconPadding} iconPadding={iconPadding}
fill={fill}
clipRule={clipRule}
filleRule={fillRule}
style={style}
dataTestId={dataTestId} dataTestId={dataTestId}
/> />
); );

@ -68,13 +68,21 @@ function IconMessageStatus({ status }: { status: LastMessageStatusType }) {
const nonErrorIconColor = 'var(--text-secondary-color'; const nonErrorIconColor = 'var(--text-secondary-color';
switch (status) { switch (status) {
case 'error': case 'error':
return <SessionIcon iconColor={'var(--danger-color'} iconType="error" iconSize="tiny" />; return (
<SessionIcon
iconColor={'var(--danger-color'}
iconType="error"
iconSize="tiny"
style={{ flexShrink: 0 }}
/>
);
case 'read': case 'read':
return ( return (
<SessionIcon <SessionIcon
iconColor={nonErrorIconColor} iconColor={nonErrorIconColor}
iconType="doubleCheckCircleFilled" iconType="doubleCheckCircleFilled"
iconSize="tiny" iconSize="tiny"
style={{ flexShrink: 0 }}
/> />
); );
case 'sending': case 'sending':
@ -84,10 +92,18 @@ function IconMessageStatus({ status }: { status: LastMessageStatusType }) {
iconColor={nonErrorIconColor} iconColor={nonErrorIconColor}
iconType="sending" iconType="sending"
iconSize="tiny" iconSize="tiny"
style={{ flexShrink: 0 }}
/> />
); );
case 'sent': case 'sent':
return <SessionIcon iconColor={nonErrorIconColor} iconType="circleCheck" iconSize="tiny" />; return (
<SessionIcon
iconColor={nonErrorIconColor}
iconType="circleCheck"
iconSize="tiny"
style={{ flexShrink: 0 }}
/>
);
case undefined: case undefined:
return null; return null;
default: default:

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

@ -251,7 +251,9 @@ export async function handleSwarmDataMessage({
} }
let msgModel = let msgModel =
isSyncedMessage || (envelope.senderIdentity && isUsFromCache(envelope.senderIdentity)) isSyncedMessage ||
(envelope.senderIdentity && isUsFromCache(envelope.senderIdentity)) ||
(envelope.source && isUsFromCache(envelope.source))
? createSwarmMessageSentFromUs({ ? createSwarmMessageSentFromUs({
conversationId: convoIdToAddTheMessageTo, conversationId: convoIdToAddTheMessageTo,
messageHash, messageHash,

@ -1,7 +1,7 @@
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
/* eslint-disable more/no-then */ /* eslint-disable more/no-then */
/* eslint-disable @typescript-eslint/no-misused-promises */ /* eslint-disable @typescript-eslint/no-misused-promises */
import { compact, concat, flatten, last, sample, toNumber, uniqBy } from 'lodash'; import { compact, concat, flatten, last, sample, uniqBy } from 'lodash';
import { Data, Snode } from '../../../data/data'; import { Data, Snode } from '../../../data/data';
import { SignalService } from '../../../protobuf'; import { SignalService } from '../../../protobuf';
import * as Receiver from '../../../receiver/receiver'; import * as Receiver from '../../../receiver/receiver';
@ -11,8 +11,6 @@ import * as snodePool from './snodePool';
import { ConversationModel } from '../../../models/conversation'; import { ConversationModel } from '../../../models/conversation';
import { ConfigMessageHandler } from '../../../receiver/configMessage'; import { ConfigMessageHandler } from '../../../receiver/configMessage';
import { decryptEnvelopeWithOurKey } from '../../../receiver/contentMessage';
import { EnvelopePlus } from '../../../receiver/types';
import { updateIsOnline } from '../../../state/ducks/onion'; import { updateIsOnline } from '../../../state/ducks/onion';
import { ReleasedFeatures } from '../../../util/releaseFeature'; import { ReleasedFeatures } from '../../../util/releaseFeature';
import { import {
@ -21,15 +19,18 @@ import {
} from '../../../webworker/workers/browser/libsession_worker_interface'; } from '../../../webworker/workers/browser/libsession_worker_interface';
import { DURATION, SWARM_POLLING_TIMEOUT } from '../../constants'; import { DURATION, SWARM_POLLING_TIMEOUT } from '../../constants';
import { getConversationController } from '../../conversations'; import { getConversationController } from '../../conversations';
import { IncomingMessage } from '../../messages/incoming/IncomingMessage';
import { StringUtils, UserUtils } from '../../utils'; import { StringUtils, UserUtils } from '../../utils';
import { ed25519Str } from '../../utils/String';
import { LibSessionUtil } from '../../utils/libsession/libsession_utils'; import { LibSessionUtil } from '../../utils/libsession/libsession_utils';
import { SnodeNamespace, SnodeNamespaces } from './namespaces'; import { SnodeNamespace, SnodeNamespaces } from './namespaces';
import { SnodeAPIRetrieve } from './retrieveRequest'; import { SnodeAPIRetrieve } from './retrieveRequest';
import { RetrieveMessageItem, RetrieveMessagesResultsBatched } from './types'; import {
import { ed25519Str } from '../../utils/String'; RetrieveMessageItem,
RetrieveMessageItemWithNamespace,
RetrieveMessagesResultsBatched,
} from './types';
export function extractWebSocketContent( function extractWebSocketContent(
message: string, message: string,
messageHash: string messageHash: string
): null | { ): null | {
@ -265,9 +266,16 @@ export class SwarmPolling {
// check if we just fetched the details from the config namespaces. // check if we just fetched the details from the config namespaces.
// If yes, merge them together and exclude them from the rest of the messages. // If yes, merge them together and exclude them from the rest of the messages.
if (userConfigLibsession && resultsFromAllNamespaces) { if (userConfigLibsession && resultsFromAllNamespaces) {
const userConfigMessages = resultsFromAllNamespaces const userConfigMessages = resultsFromAllNamespaces.filter(m =>
.filter(m => SnodeNamespace.isUserConfigNamespace(m.namespace)) SnodeNamespace.isUserConfigNamespace(m.namespace)
.map(r => r.messages.messages); );
const userConfigMessagesWithNamespace: Array<Array<RetrieveMessageItemWithNamespace>> =
userConfigMessages.map(r => {
return (r.messages.messages || []).map(m => {
return { ...m, namespace: r.namespace };
});
});
allNamespacesWithoutUserConfigIfNeeded = flatten( allNamespacesWithoutUserConfigIfNeeded = flatten(
compact( compact(
@ -283,7 +291,7 @@ export class SwarmPolling {
`received userConfigMessages count: ${userConfigMessagesMerged.length} for key ${pubkey.key}` `received userConfigMessages count: ${userConfigMessagesMerged.length} for key ${pubkey.key}`
); );
try { try {
await this.handleSharedConfigMessages(userConfigMessagesMerged); await this.handleSharedConfigMessages(flatten(userConfigMessagesWithNamespace));
} catch (e) { } catch (e) {
window.log.warn( window.log.warn(
`handleSharedConfigMessages of ${userConfigMessagesMerged.length} failed with ${e.message}` `handleSharedConfigMessages of ${userConfigMessagesMerged.length} failed with ${e.message}`
@ -365,58 +373,22 @@ export class SwarmPolling {
} }
} }
private async handleSharedConfigMessages(userConfigMessagesMerged: Array<RetrieveMessageItem>) { private async handleSharedConfigMessages(
const extractedUserConfigMessage = compact( userConfigMessagesMerged: Array<RetrieveMessageItemWithNamespace>
userConfigMessagesMerged.map((m: RetrieveMessageItem) => { ) {
return extractWebSocketContent(m.data, m.hash); if (!userConfigMessagesMerged.length) {
}) return;
);
const allDecryptedConfigMessages: Array<IncomingMessage<SignalService.ISharedConfigMessage>> =
[];
for (let index = 0; index < extractedUserConfigMessage.length; index++) {
const userConfigMessage = extractedUserConfigMessage[index];
try {
const envelope: EnvelopePlus = SignalService.Envelope.decode(userConfigMessage.body) as any;
const decryptedEnvelope = await decryptEnvelopeWithOurKey(envelope);
if (!decryptedEnvelope?.byteLength) {
continue;
}
const content = SignalService.Content.decode(new Uint8Array(decryptedEnvelope));
if (content.sharedConfigMessage) {
const asIncomingMsg: IncomingMessage<SignalService.ISharedConfigMessage> = {
envelopeTimestamp: toNumber(envelope.timestamp),
message: content.sharedConfigMessage,
messageHash: userConfigMessage.messageHash,
authorOrGroupPubkey: envelope.source,
authorInGroup: envelope.senderIdentity,
};
allDecryptedConfigMessages.push(asIncomingMsg);
} else {
throw new Error(
'received a message from the namespace reserved for user config but it did not contain a sharedConfigMessage'
);
}
} catch (e) {
window.log.warn(
`failed to decrypt message with hash "${userConfigMessage.messageHash}": ${e.message}`
);
}
} }
if (allDecryptedConfigMessages.length) { try {
try { window.log.info(
window.log.info( `handleConfigMessagesViaLibSession of "${userConfigMessagesMerged.length}" messages with libsession`
`handleConfigMessagesViaLibSession of "${allDecryptedConfigMessages.length}" messages with libsession` );
); await ConfigMessageHandler.handleConfigMessagesViaLibSession(userConfigMessagesMerged);
await ConfigMessageHandler.handleConfigMessagesViaLibSession(allDecryptedConfigMessages); } catch (e) {
} catch (e) { const allMessagesHashes = userConfigMessagesMerged.map(m => m.hash).join(',');
const allMessageHases = allDecryptedConfigMessages.map(m => m.messageHash).join(','); window.log.warn(
window.log.warn( `failed to handle messages hashes "${allMessagesHashes}" with libsession. Error: "${e.message}"`
`failed to handle messages hashes "${allMessageHases}" with libsession. Error: "${e.message}"` );
);
}
} }
} }

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

@ -17,6 +17,15 @@ export const DURATION = {
WEEKS: days * 7, WEEKS: days * 7,
}; };
export const FILESIZE = {
/** 1KB */
KB: 1024,
/** 1MB */
MB: 1024 * 1024,
/** 1GB */
GB: 1024 * 1024 * 1024,
};
export const TTL_DEFAULT = { export const TTL_DEFAULT = {
/** 20 seconds */ /** 20 seconds */
TYPING_MESSAGE: 20 * DURATION.SECONDS, TYPING_MESSAGE: 20 * DURATION.SECONDS,

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

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

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

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

@ -3,6 +3,7 @@ import imageType from 'image-type';
import { arrayBufferToBlob } from 'blob-util'; import { arrayBufferToBlob } from 'blob-util';
import loadImage from 'blueimp-load-image'; import loadImage from 'blueimp-load-image';
import fileSize from 'filesize';
import { StagedAttachmentType } from '../components/conversation/composition/CompositionBox'; import { StagedAttachmentType } from '../components/conversation/composition/CompositionBox';
import { SignalService } from '../protobuf'; import { SignalService } from '../protobuf';
import { getDecryptedMediaUrl } from '../session/crypto/DecryptedAttachmentsManager'; import { getDecryptedMediaUrl } from '../session/crypto/DecryptedAttachmentsManager';
@ -12,7 +13,7 @@ import { IMAGE_GIF, IMAGE_JPEG, IMAGE_PNG, IMAGE_TIFF, IMAGE_UNKNOWN } from '../
import { getAbsoluteAttachmentPath, processNewAttachment } from '../types/MessageAttachment'; import { getAbsoluteAttachmentPath, processNewAttachment } from '../types/MessageAttachment';
import { THUMBNAIL_SIDE } from '../types/attachments/VisualAttachment'; import { THUMBNAIL_SIDE } from '../types/attachments/VisualAttachment';
import { MAX_ATTACHMENT_FILESIZE_BYTES } from '../session/constants'; import { FILESIZE, MAX_ATTACHMENT_FILESIZE_BYTES } from '../session/constants';
import { perfEnd, perfStart } from '../session/utils/Performance'; import { perfEnd, perfStart } from '../session/utils/Performance';
/** /**
@ -53,7 +54,7 @@ export async function autoScaleForAvatar<T extends { contentType: string; blob:
) { ) {
const maxMeasurements = { const maxMeasurements = {
maxSide: AVATAR_MAX_SIDE, maxSide: AVATAR_MAX_SIDE,
maxSize: 1000 * 1024, maxSize: 5 * FILESIZE.MB,
}; };
// we can only upload jpeg, gif, or png as avatar/opengroup // we can only upload jpeg, gif, or png as avatar/opengroup
@ -79,7 +80,7 @@ export async function autoScaleForAvatar<T extends { contentType: string; blob:
export async function autoScaleForIncomingAvatar(incomingAvatar: ArrayBuffer) { export async function autoScaleForIncomingAvatar(incomingAvatar: ArrayBuffer) {
const maxMeasurements = { const maxMeasurements = {
maxSide: AVATAR_MAX_SIDE, maxSide: AVATAR_MAX_SIDE,
maxSize: 1000 * 1024, maxSize: 5 * FILESIZE.MB,
}; };
// the avatar url send in a message does not contain anything related to the avatar MIME type, so // the avatar url send in a message does not contain anything related to the avatar MIME type, so
@ -186,7 +187,7 @@ export async function autoScale<T extends { contentType: string; blob: Blob }>(
} }
if (blob.type === IMAGE_GIF && blob.size > maxSize) { if (blob.type === IMAGE_GIF && blob.size > maxSize) {
throw new Error(`GIF is too large, required size is ${maxSize}`); throw new Error(`GIF is too large. Max size: ${fileSize(maxSize, { base: 10, round: 0 })}`);
} }
perfStart(`loadimage-*${blob.size}`); perfStart(`loadimage-*${blob.size}`);

@ -46,6 +46,11 @@ export const GenericWrapperActions = {
) => ) =>
/** base wrapper generic actions */ /** base wrapper generic actions */
callLibSessionWorker([wrapperId, 'init', ed25519Key, dump]) as Promise<void>, callLibSessionWorker([wrapperId, 'init', ed25519Key, dump]) as Promise<void>,
/** This function is used to free wrappers from memory only.
*
* See freeUserWrapper() in libsession.worker.ts */
free: async (wrapperId: ConfigWrapperObjectTypes) =>
callLibSessionWorker([wrapperId, 'free']) as Promise<void>,
confirmPushed: async (wrapperId: ConfigWrapperObjectTypes, seqno: number, hash: string) => confirmPushed: async (wrapperId: ConfigWrapperObjectTypes, seqno: number, hash: string) =>
callLibSessionWorker([wrapperId, 'confirmPushed', seqno, hash]) as ReturnType< callLibSessionWorker([wrapperId, 'confirmPushed', seqno, hash]) as ReturnType<
BaseWrapperActionsCalls['confirmPushed'] BaseWrapperActionsCalls['confirmPushed']
@ -87,6 +92,7 @@ export const UserConfigWrapperActions: UserConfigWrapperActionsCalls = {
/* Reuse the GenericWrapperActions with the UserConfig argument */ /* Reuse the GenericWrapperActions with the UserConfig argument */
init: async (ed25519Key: Uint8Array, dump: Uint8Array | null) => init: async (ed25519Key: Uint8Array, dump: Uint8Array | null) =>
GenericWrapperActions.init('UserConfig', ed25519Key, dump), GenericWrapperActions.init('UserConfig', ed25519Key, dump),
free: async () => GenericWrapperActions.free('UserConfig'),
confirmPushed: async (seqno: number, hash: string) => confirmPushed: async (seqno: number, hash: string) =>
GenericWrapperActions.confirmPushed('UserConfig', seqno, hash), GenericWrapperActions.confirmPushed('UserConfig', seqno, hash),
dump: async () => GenericWrapperActions.dump('UserConfig'), dump: async () => GenericWrapperActions.dump('UserConfig'),
@ -135,6 +141,7 @@ export const ContactsWrapperActions: ContactsWrapperActionsCalls = {
/* Reuse the GenericWrapperActions with the ContactConfig argument */ /* Reuse the GenericWrapperActions with the ContactConfig argument */
init: async (ed25519Key: Uint8Array, dump: Uint8Array | null) => init: async (ed25519Key: Uint8Array, dump: Uint8Array | null) =>
GenericWrapperActions.init('ContactsConfig', ed25519Key, dump), GenericWrapperActions.init('ContactsConfig', ed25519Key, dump),
free: async () => GenericWrapperActions.free('ContactsConfig'),
confirmPushed: async (seqno: number, hash: string) => confirmPushed: async (seqno: number, hash: string) =>
GenericWrapperActions.confirmPushed('ContactsConfig', seqno, hash), GenericWrapperActions.confirmPushed('ContactsConfig', seqno, hash),
dump: async () => GenericWrapperActions.dump('ContactsConfig'), dump: async () => GenericWrapperActions.dump('ContactsConfig'),
@ -171,6 +178,7 @@ export const UserGroupsWrapperActions: UserGroupsWrapperActionsCalls = {
/* Reuse the GenericWrapperActions with the ContactConfig argument */ /* Reuse the GenericWrapperActions with the ContactConfig argument */
init: async (ed25519Key: Uint8Array, dump: Uint8Array | null) => init: async (ed25519Key: Uint8Array, dump: Uint8Array | null) =>
GenericWrapperActions.init('UserGroupsConfig', ed25519Key, dump), GenericWrapperActions.init('UserGroupsConfig', ed25519Key, dump),
free: async () => GenericWrapperActions.free('UserGroupsConfig'),
confirmPushed: async (seqno: number, hash: string) => confirmPushed: async (seqno: number, hash: string) =>
GenericWrapperActions.confirmPushed('UserGroupsConfig', seqno, hash), GenericWrapperActions.confirmPushed('UserGroupsConfig', seqno, hash),
dump: async () => GenericWrapperActions.dump('UserGroupsConfig'), dump: async () => GenericWrapperActions.dump('UserGroupsConfig'),
@ -244,6 +252,7 @@ export const ConvoInfoVolatileWrapperActions: ConvoInfoVolatileWrapperActionsCal
/* Reuse the GenericWrapperActions with the ContactConfig argument */ /* Reuse the GenericWrapperActions with the ContactConfig argument */
init: async (ed25519Key: Uint8Array, dump: Uint8Array | null) => init: async (ed25519Key: Uint8Array, dump: Uint8Array | null) =>
GenericWrapperActions.init('ConvoInfoVolatileConfig', ed25519Key, dump), GenericWrapperActions.init('ConvoInfoVolatileConfig', ed25519Key, dump),
free: async () => GenericWrapperActions.free('ConvoInfoVolatileConfig'),
confirmPushed: async (seqno: number, hash: string) => confirmPushed: async (seqno: number, hash: string) =>
GenericWrapperActions.confirmPushed('ConvoInfoVolatileConfig', seqno, hash), GenericWrapperActions.confirmPushed('ConvoInfoVolatileConfig', seqno, hash),
dump: async () => GenericWrapperActions.dump('ConvoInfoVolatileConfig'), dump: async () => GenericWrapperActions.dump('ConvoInfoVolatileConfig'),

@ -2877,12 +2877,12 @@ available-typed-arrays@^1.0.5, available-typed-arrays@^1.0.6:
dependencies: dependencies:
possible-typed-array-names "^1.0.0" possible-typed-array-names "^1.0.0"
axios@^1.3.2: axios@^1.6.5:
version "1.6.2" version "1.7.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.2.tgz#b625db8a7051fbea61c35a3cbb3a1daa7b9c7621"
integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== integrity sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==
dependencies: dependencies:
follow-redirects "^1.15.0" follow-redirects "^1.15.6"
form-data "^4.0.0" form-data "^4.0.0"
proxy-from-env "^1.1.0" proxy-from-env "^1.1.0"
@ -3494,23 +3494,23 @@ clsx@^1.0.4, clsx@^1.1.1, clsx@^1.2.1:
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
cmake-js@^7.2.1: cmake-js@^7.2.1:
version "7.2.1" version "7.3.0"
resolved "https://registry.yarnpkg.com/cmake-js/-/cmake-js-7.2.1.tgz#757c0d39994121b084bab96290baf115ee7712cd" resolved "https://registry.yarnpkg.com/cmake-js/-/cmake-js-7.3.0.tgz#6fd6234b7aeec4545c1c806f9e3f7ffacd9798b2"
integrity sha512-AdPSz9cSIJWdKvm0aJgVu3X8i0U3mNTswJkSHzZISqmYVjZk7Td4oDFg0mCBA383wO+9pG5Ix7pEP1CZH9x2BA== integrity sha512-dXs2zq9WxrV87bpJ+WbnGKv8WUBXDw8blNiwNHoRe/it+ptscxhQHKB1SJXa1w+kocLMeP28Tk4/eTCezg4o+w==
dependencies: dependencies:
axios "^1.3.2" axios "^1.6.5"
debug "^4" debug "^4"
fs-extra "^10.1.0" fs-extra "^11.2.0"
lodash.isplainobject "^4.0.6" lodash.isplainobject "^4.0.6"
memory-stream "^1.0.0" memory-stream "^1.0.0"
node-api-headers "^0.0.2" node-api-headers "^1.1.0"
npmlog "^6.0.2" npmlog "^6.0.2"
rc "^1.2.7" rc "^1.2.7"
semver "^7.3.8" semver "^7.5.4"
tar "^6.1.11" tar "^6.2.0"
url-join "^4.0.1" url-join "^4.0.1"
which "^2.0.2" which "^2.0.2"
yargs "^17.6.0" yargs "^17.7.2"
color-convert@^1.9.0: color-convert@^1.9.0:
version "1.9.3" version "1.9.3"
@ -3905,7 +3905,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.6.8, debug@^2.6.9:
dependencies: dependencies:
ms "2.0.0" ms "2.0.0"
debug@4, debug@4.3.4, debug@^4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4" version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@ -3919,6 +3919,13 @@ debug@^3.2.7:
dependencies: dependencies:
ms "^2.1.1" ms "^2.1.1"
debug@^4:
version "4.3.5"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e"
integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==
dependencies:
ms "2.1.2"
decamelize-keys@^1.1.0: decamelize-keys@^1.1.0:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8"
@ -5067,10 +5074,10 @@ focus-trap@^7.5.4:
dependencies: dependencies:
tabbable "^6.2.0" tabbable "^6.2.0"
follow-redirects@^1.15.0: follow-redirects@^1.15.6:
version "1.15.3" version "1.15.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
for-each@^0.3.3: for-each@^0.3.3:
version "0.3.3" version "0.3.3"
@ -5130,6 +5137,15 @@ fs-extra@^11.0.0:
jsonfile "^6.0.1" jsonfile "^6.0.1"
universalify "^2.0.0" universalify "^2.0.0"
fs-extra@^11.2.0:
version "11.2.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b"
integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
universalify "^2.0.0"
fs-extra@^8.1.0: fs-extra@^8.1.0:
version "8.1.0" version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
@ -6526,9 +6542,9 @@ levn@~0.3.0:
prelude-ls "~1.1.2" prelude-ls "~1.1.2"
type-check "~0.3.2" type-check "~0.3.2"
"libsession_util_nodejs@https://github.com/oxen-io/libsession-util-nodejs/releases/download/v0.3.1/libsession_util_nodejs-v0.3.1.tar.gz": "libsession_util_nodejs@https://github.com/oxen-io/libsession-util-nodejs/releases/download/v0.3.19/libsession_util_nodejs-v0.3.19.tar.gz":
version "0.3.1" version "0.3.19"
resolved "https://github.com/oxen-io/libsession-util-nodejs/releases/download/v0.3.1/libsession_util_nodejs-v0.3.1.tar.gz#d2c94bfaae6e3ef594609abb08cf8be485fa5d39" resolved "https://github.com/oxen-io/libsession-util-nodejs/releases/download/v0.3.19/libsession_util_nodejs-v0.3.19.tar.gz#221c1fc34fcc18601aea4ce1b733ebfa55af66ea"
dependencies: dependencies:
cmake-js "^7.2.1" cmake-js "^7.2.1"
node-addon-api "^6.1.0" node-addon-api "^6.1.0"
@ -7393,10 +7409,10 @@ node-addon-api@^6.1.0:
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76"
integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==
node-api-headers@^0.0.2: node-api-headers@^1.1.0:
version "0.0.2" version "1.1.0"
resolved "https://registry.yarnpkg.com/node-api-headers/-/node-api-headers-0.0.2.tgz#31f4c6c2750b63e598128e76a60aefca6d76ac5d" resolved "https://registry.yarnpkg.com/node-api-headers/-/node-api-headers-1.1.0.tgz#3f9dd7bb10b29e1c3e3db675979605a308b2373c"
integrity sha512-YsjmaKGPDkmhoNKIpkChtCsPVaRE0a274IdERKnuc/E8K1UJdBZ4/mvI006OijlQZHCfpRNOH3dfHQs92se8gg== integrity sha512-ucQW+SbYCUPfprvmzBsnjT034IGRB2XK8rRc78BgjNKhTdFKgAwAmgW704bKIBmcYW48it0Gkjpkd39Azrwquw==
node-dir@^0.1.17: node-dir@^0.1.17:
version "0.1.17" version "0.1.17"
@ -9584,6 +9600,18 @@ tar@^6.1.0, tar@^6.1.11:
mkdirp "^1.0.3" mkdirp "^1.0.3"
yallist "^4.0.0" yallist "^4.0.0"
tar@^6.2.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a"
integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==
dependencies:
chownr "^2.0.0"
fs-minipass "^2.0.0"
minipass "^5.0.0"
minizlib "^2.1.1"
mkdirp "^1.0.3"
yallist "^4.0.0"
temp-dir@^2.0.0: temp-dir@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e"
@ -10536,7 +10564,7 @@ yargs@^15.1.0:
y18n "^4.0.0" y18n "^4.0.0"
yargs-parser "^18.1.2" yargs-parser "^18.1.2"
yargs@^17.0.0, yargs@^17.0.1, yargs@^17.6.0, yargs@^17.6.2: yargs@^17.0.0, yargs@^17.0.1, yargs@^17.6.2, yargs@^17.7.2:
version "17.7.2" version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==

Loading…
Cancel
Save