mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-04-17 07:13:24 +01:00
Update libsignal to 0.90.0
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
This commit is contained in:
@@ -129,7 +129,7 @@
|
||||
"@react-aria/utils": "3.33.1",
|
||||
"@react-spring/web": "10.0.3",
|
||||
"@react-types/shared": "3.33.1",
|
||||
"@signalapp/libsignal-client": "0.89.2",
|
||||
"@signalapp/libsignal-client": "0.90.0",
|
||||
"@signalapp/minimask": "1.0.1",
|
||||
"@signalapp/mute-state-change": "workspace:1.0.0",
|
||||
"@signalapp/quill-cjs": "2.1.2",
|
||||
|
||||
13
pnpm-lock.yaml
generated
13
pnpm-lock.yaml
generated
@@ -126,8 +126,8 @@ importers:
|
||||
specifier: 3.33.1
|
||||
version: 3.33.1(react@19.2.4)
|
||||
'@signalapp/libsignal-client':
|
||||
specifier: 0.89.2
|
||||
version: 0.89.2
|
||||
specifier: 0.90.0
|
||||
version: 0.90.0
|
||||
'@signalapp/minimask':
|
||||
specifier: 1.0.1
|
||||
version: 1.0.1
|
||||
@@ -3425,6 +3425,9 @@ packages:
|
||||
'@signalapp/libsignal-client@0.89.2':
|
||||
resolution: {integrity: sha512-LGvE50XxiCB7vXHtx/TElPXl8sFr6kLO6CkZVh33pc5FME3j/PMtdTZnUE7bFDV15yxW//pCntFrpV0XzV5lSA==}
|
||||
|
||||
'@signalapp/libsignal-client@0.90.0':
|
||||
resolution: {integrity: sha512-jNS5Xy7043QKXlcFYHA5HnxhrVvYHI+zaWgpeRLTKAdJLycYV6OesG6Y1lqxhkOWQcXjiOg/cDWt8ZOGl5pVYw==}
|
||||
|
||||
'@signalapp/minimask@1.0.1':
|
||||
resolution: {integrity: sha512-QAwo0joA60urTNbW9RIz6vLKQjy+jdVtH7cvY0wD9PVooD46MAjE40MLssp4xUJrph91n2XvtJ3pbEUDrmT2AA==}
|
||||
|
||||
@@ -14070,6 +14073,12 @@ snapshots:
|
||||
type-fest: 4.26.1
|
||||
uuid: 11.0.2
|
||||
|
||||
'@signalapp/libsignal-client@0.90.0':
|
||||
dependencies:
|
||||
node-gyp-build: 4.8.4
|
||||
type-fest: 4.26.1
|
||||
uuid: 11.0.2
|
||||
|
||||
'@signalapp/minimask@1.0.1': {}
|
||||
|
||||
'@signalapp/mock-server@18.3.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)':
|
||||
|
||||
@@ -11,6 +11,7 @@ import { Preferences } from './Preferences.dom.js';
|
||||
import { DEFAULT_CONVERSATION_COLOR } from '../types/Colors.std.js';
|
||||
import { PhoneNumberSharingMode } from '../types/PhoneNumberSharingMode.std.js';
|
||||
import { PhoneNumberDiscoverability } from '../util/phoneNumberDiscoverability.std.js';
|
||||
import { sleep } from '../util/sleep.std.js';
|
||||
import { EmojiSkinTone } from './fun/data/emojis.std.js';
|
||||
import {
|
||||
DAY,
|
||||
@@ -659,6 +660,10 @@ export default {
|
||||
setIsGroupVp9Enabled: action('setIsDirectVp9Enabled'),
|
||||
sfuUrl: 'https://sfu.voip.signal.org',
|
||||
setSfuUrl: action('setSfuUrl'),
|
||||
forceKeyTransparencyCheck: async () => {
|
||||
await sleep(1000);
|
||||
},
|
||||
keyTransparencySelfHealth: 'ok',
|
||||
} satisfies PropsType,
|
||||
} satisfies Meta<PropsType>;
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ import type {
|
||||
NotificationSettingType,
|
||||
SentMediaQualitySettingType,
|
||||
ZoomFactorType,
|
||||
StorageAccessType,
|
||||
} from '../types/StorageKeys.std.js';
|
||||
import type { ThemeSettingType } from '../util/theme.std.js';
|
||||
import type { AnyToast } from '../types/Toast.dom.js';
|
||||
@@ -359,6 +360,8 @@ type PropsFunctionType = {
|
||||
setIsGroupVp9Enabled: (value: boolean | undefined) => void;
|
||||
setGroupMaxBitrate: (value: number | undefined) => void;
|
||||
setSfuUrl: (value: string | undefined) => void;
|
||||
forceKeyTransparencyCheck: () => Promise<void>;
|
||||
keyTransparencySelfHealth: StorageAccessType['keyTransparencySelfHealth'];
|
||||
|
||||
// Localization
|
||||
i18n: LocalizerType;
|
||||
@@ -580,6 +583,8 @@ export function Preferences({
|
||||
groupMaxBitrate,
|
||||
setSfuUrl,
|
||||
sfuUrl,
|
||||
forceKeyTransparencyCheck,
|
||||
keyTransparencySelfHealth,
|
||||
}: PropsType): React.JSX.Element {
|
||||
const storiesId = useId();
|
||||
const themeSelectId = useId();
|
||||
@@ -2371,6 +2376,8 @@ export function Preferences({
|
||||
groupMaxBitrate={groupMaxBitrate}
|
||||
sfuUrl={sfuUrl}
|
||||
setSfuUrl={setSfuUrl}
|
||||
forceKeyTransparencyCheck={forceKeyTransparencyCheck}
|
||||
keyTransparencySelfHealth={keyTransparencySelfHealth}
|
||||
/>
|
||||
}
|
||||
contentsRef={settingsPaneRef}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { SettingsRow, FlowingSettingsControl } from './PreferencesUtil.dom.js';
|
||||
import type { MessageCountBySchemaVersionType } from '../sql/Interface.std.js';
|
||||
import type { MessageAttributesType } from '../model-types.d.ts';
|
||||
import type { DonationReceipt } from '../types/Donations.std.js';
|
||||
import type { StorageAccessType } from '../types/StorageKeys.std.js';
|
||||
import { createLogger } from '../logging/log.std.js';
|
||||
import { isStagingServer } from '../util/isStagingServer.dom.js';
|
||||
import { getHumanDonationAmount } from '../util/currency.dom.js';
|
||||
@@ -53,6 +54,8 @@ export function PreferencesInternal({
|
||||
setGroupMaxBitrate,
|
||||
sfuUrl,
|
||||
setSfuUrl,
|
||||
forceKeyTransparencyCheck,
|
||||
keyTransparencySelfHealth,
|
||||
}: {
|
||||
i18n: LocalizerType;
|
||||
validateBackup: () => Promise<BackupValidationResultType>;
|
||||
@@ -90,6 +93,8 @@ export function PreferencesInternal({
|
||||
setGroupMaxBitrate: (value: number | undefined) => void;
|
||||
sfuUrl: string | undefined;
|
||||
setSfuUrl: (value: string | undefined) => void;
|
||||
forceKeyTransparencyCheck: () => Promise<void>;
|
||||
keyTransparencySelfHealth: StorageAccessType['keyTransparencySelfHealth'];
|
||||
}): React.JSX.Element {
|
||||
const [messageCountBySchemaVersion, setMessageCountBySchemaVersion] =
|
||||
useState<MessageCountBySchemaVersionType>();
|
||||
@@ -276,6 +281,31 @@ export function PreferencesInternal({
|
||||
[]
|
||||
);
|
||||
|
||||
// Key Transparancy
|
||||
|
||||
const [isKeyTransparencyRunning, setIsKeyTransparencyRunning] =
|
||||
useState(false);
|
||||
|
||||
const handleKeyTransparencyCheck = useCallback(async () => {
|
||||
setIsKeyTransparencyRunning(true);
|
||||
try {
|
||||
await forceKeyTransparencyCheck();
|
||||
} finally {
|
||||
setIsKeyTransparencyRunning(false);
|
||||
}
|
||||
}, [forceKeyTransparencyCheck]);
|
||||
|
||||
let keyTransparencySymbol: undefined | 'check-circle-fill' | 'error-fill';
|
||||
if (keyTransparencySelfHealth == null) {
|
||||
keyTransparencySymbol = undefined;
|
||||
} else if (keyTransparencySelfHealth === 'ok') {
|
||||
keyTransparencySymbol = 'check-circle-fill';
|
||||
} else if (keyTransparencySelfHealth === 'fail') {
|
||||
keyTransparencySymbol = 'error-fill';
|
||||
} else if (keyTransparencySelfHealth === 'intermittent') {
|
||||
keyTransparencySymbol = 'error-fill';
|
||||
}
|
||||
|
||||
const prevAbortControlerRef = useRef<AbortController | null>(null);
|
||||
|
||||
const handleReadOnlySqlInputSubmit = useCallback(async () => {
|
||||
@@ -723,6 +753,26 @@ export function PreferencesInternal({
|
||||
</div>
|
||||
</FlowingSettingsControl>
|
||||
</SettingsRow>
|
||||
<SettingsRow title="Key Transparency">
|
||||
<FlowingSettingsControl>
|
||||
<div className="Preferences__two-thirds-flow">Force Self Check</div>
|
||||
<div className="Preferences__one-third-flow Preferences__one-third-flow--justify-end">
|
||||
<AxoButton.Root
|
||||
symbol={keyTransparencySymbol}
|
||||
variant="secondary"
|
||||
size="lg"
|
||||
onClick={handleKeyTransparencyCheck}
|
||||
experimentalSpinner={
|
||||
isKeyTransparencyRunning
|
||||
? { 'aria-label': i18n('icu:loading') }
|
||||
: null
|
||||
}
|
||||
>
|
||||
Check
|
||||
</AxoButton.Root>
|
||||
</div>
|
||||
</FlowingSettingsControl>
|
||||
</SettingsRow>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,16 +11,11 @@ import type {
|
||||
Request,
|
||||
E164Info,
|
||||
} from '@signalapp/libsignal-client/dist/net/KeyTransparency.js';
|
||||
import { MonitorMode } from '@signalapp/libsignal-client/dist/net/KeyTransparency.js';
|
||||
import pTimeout from 'p-timeout';
|
||||
|
||||
import {
|
||||
keyTransparencySearch,
|
||||
keyTransparencyMonitor,
|
||||
} from '../textsecure/WebAPI.preload.js';
|
||||
import { keyTransparencyCheck } from '../textsecure/WebAPI.preload.js';
|
||||
import { signalProtocolStore } from '../SignalProtocolStore.preload.js';
|
||||
import { itemStorage } from '../textsecure/Storage.preload.js';
|
||||
import { fromAciObject } from '../types/ServiceId.std.js';
|
||||
import { toLogFormat } from '../types/errors.std.js';
|
||||
import { toAciObject } from '../util/ServiceId.node.js';
|
||||
import { TaskDeduplicator } from '../util/TaskDeduplicator.std.js';
|
||||
@@ -142,8 +137,9 @@ export class KeyTransparency {
|
||||
};
|
||||
}
|
||||
|
||||
await this.#verify(
|
||||
await this.#check(
|
||||
{
|
||||
mode: 'contact',
|
||||
aciInfo: {
|
||||
aci: toAciObject(aci),
|
||||
identityKey: PublicKey.deserialize(identityKey),
|
||||
@@ -195,23 +191,16 @@ export class KeyTransparency {
|
||||
|
||||
const me = window.ConversationController.getOurConversationOrThrow();
|
||||
|
||||
let e164Info: E164Info | undefined;
|
||||
if (
|
||||
const isE164Discoverable =
|
||||
itemStorage.get('phoneNumberDiscoverability') ===
|
||||
PhoneNumberDiscoverability.Discoverable
|
||||
) {
|
||||
const ourE164 = itemStorage.user.getNumber();
|
||||
strictAssert(ourE164 != null, 'missing our e164');
|
||||
PhoneNumberDiscoverability.Discoverable;
|
||||
|
||||
me.deriveAccessKeyIfNeeded();
|
||||
const ourAccessKey = me.get('accessKey');
|
||||
strictAssert(ourAccessKey != null, 'missing our access key');
|
||||
const ourE164 = itemStorage.user.getNumber();
|
||||
strictAssert(ourE164 != null, 'missing our e164');
|
||||
|
||||
e164Info = {
|
||||
e164: ourE164,
|
||||
unidentifiedAccessKey: Bytes.fromBase64(ourAccessKey),
|
||||
};
|
||||
}
|
||||
me.deriveAccessKeyIfNeeded();
|
||||
const ourAccessKey = me.get('accessKey');
|
||||
strictAssert(ourAccessKey != null, 'missing our access key');
|
||||
|
||||
let usernameHash: Uint8Array<ArrayBuffer> | undefined;
|
||||
|
||||
@@ -235,13 +224,18 @@ export class KeyTransparency {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.#verify(
|
||||
await this.#check(
|
||||
{
|
||||
mode: 'self',
|
||||
isE164Discoverable,
|
||||
aciInfo: {
|
||||
aci: toAciObject(ourAci),
|
||||
identityKey: keyPair.publicKey,
|
||||
},
|
||||
e164Info,
|
||||
e164Info: {
|
||||
e164: ourE164,
|
||||
unidentifiedAccessKey: Bytes.fromBase64(ourAccessKey),
|
||||
},
|
||||
usernameHash,
|
||||
},
|
||||
abortSignal
|
||||
@@ -312,29 +306,16 @@ export class KeyTransparency {
|
||||
}
|
||||
}
|
||||
|
||||
async #verify(
|
||||
async #check(
|
||||
request: Request,
|
||||
abortSignal?: AbortSignal,
|
||||
backOff = new BackOff(KEY_TRANSPARENCY_TIMEOUTS)
|
||||
): Promise<void> {
|
||||
try {
|
||||
const existing = await signalProtocolStore.getKTAccountData(
|
||||
request.aciInfo.aci
|
||||
);
|
||||
if (abortSignal?.aborted) {
|
||||
throw new Error('Aborted');
|
||||
}
|
||||
const aciString = fromAciObject(request.aciInfo.aci);
|
||||
if (existing == null) {
|
||||
log.info('search', aciString);
|
||||
await keyTransparencySearch(request, abortSignal);
|
||||
} else {
|
||||
const mode = itemStorage.user.isOurServiceId(aciString)
|
||||
? MonitorMode.Self
|
||||
: MonitorMode.Other;
|
||||
log.info('monitor', aciString);
|
||||
await keyTransparencyMonitor(request, mode, abortSignal);
|
||||
}
|
||||
await keyTransparencyCheck(request, abortSignal);
|
||||
} catch (error) {
|
||||
if (abortSignal?.aborted) {
|
||||
throw new Error('Aborted');
|
||||
@@ -368,7 +349,7 @@ export class KeyTransparency {
|
||||
throw new Error('Aborted');
|
||||
}
|
||||
|
||||
return this.#verify(request, abortSignal, backOff);
|
||||
return this.#check(request, abortSignal, backOff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +204,10 @@ function getSystemTraySettingValues(
|
||||
};
|
||||
}
|
||||
|
||||
async function forceKeyTransparencyCheck(): Promise<void> {
|
||||
await keyTransparency.selfCheck();
|
||||
}
|
||||
|
||||
export function SmartPreferences(): React.JSX.Element | null {
|
||||
const {
|
||||
addCustomColor,
|
||||
@@ -1025,6 +1029,8 @@ export function SmartPreferences(): React.JSX.Element | null {
|
||||
groupMaxBitrate={items.groupMaxBitrate}
|
||||
sfuUrl={items.sfuUrl}
|
||||
setSfuUrl={setSfuUrl}
|
||||
forceKeyTransparencyCheck={forceKeyTransparencyCheck}
|
||||
keyTransparencySelfHealth={items.keyTransparencySelfHealth}
|
||||
/>
|
||||
</AxoProvider>
|
||||
</StrictMode>
|
||||
|
||||
@@ -30,10 +30,7 @@ import type {
|
||||
ProvisioningConnectionListener,
|
||||
} from '@signalapp/libsignal-client/dist/net.js';
|
||||
import { GroupSendFullToken } from '@signalapp/libsignal-client/zkgroup.js';
|
||||
import type {
|
||||
Request as KTRequest,
|
||||
MonitorMode as KTMonitorMode,
|
||||
} from '@signalapp/libsignal-client/dist/net/KeyTransparency.js';
|
||||
import type { Request as KTRequest } from '@signalapp/libsignal-client/dist/net/KeyTransparency.js';
|
||||
|
||||
import { assertDev, strictAssert } from '../util/assert.std.js';
|
||||
import * as durations from '../util/durations/index.std.js';
|
||||
@@ -2492,7 +2489,7 @@ export async function getAccountForUsername({
|
||||
return aci ? fromAciObject(aci) : null;
|
||||
}
|
||||
|
||||
export async function keyTransparencySearch(
|
||||
export async function keyTransparencyCheck(
|
||||
request: KTRequest,
|
||||
abortSignal?: AbortSignal
|
||||
): Promise<void> {
|
||||
@@ -2503,30 +2500,7 @@ export async function keyTransparencySearch(
|
||||
}
|
||||
const kt = chat.keyTransparencyClient();
|
||||
const store = new KeyTransparencyStore(signalProtocolStore);
|
||||
return kt.search(request, store, { abortSignal });
|
||||
});
|
||||
}
|
||||
|
||||
export async function keyTransparencyMonitor(
|
||||
request: KTRequest,
|
||||
mode: KTMonitorMode,
|
||||
abortSignal?: AbortSignal
|
||||
): Promise<void> {
|
||||
return _retry(async () => {
|
||||
const chat = await socketManager.getUnauthenticatedApi();
|
||||
if (abortSignal?.aborted) {
|
||||
throw new Error('Aborted');
|
||||
}
|
||||
const kt = chat.keyTransparencyClient();
|
||||
const store = new KeyTransparencyStore(signalProtocolStore);
|
||||
return kt.monitor(
|
||||
{
|
||||
...request,
|
||||
mode,
|
||||
},
|
||||
store,
|
||||
{ abortSignal }
|
||||
);
|
||||
return kt.check(request, store, { abortSignal });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user