Remove safetyNumberAci remote configuration

This commit is contained in:
Fedor Indutny 2023-11-01 21:35:55 +01:00 committed by GitHub
parent ab0c12847d
commit aa03ac36bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 50 additions and 171 deletions

View file

@ -724,7 +724,7 @@
}, },
"icu:SafetyNumberViewer__hint--normal": { "icu:SafetyNumberViewer__hint--normal": {
"messageformat": "To verify end-to-end encryption with {name}, compare the numbers above with their device. They can also scan your code with their device.", "messageformat": "To verify end-to-end encryption with {name}, compare the numbers above with their device. They can also scan your code with their device.",
"description": "Safety number viewer, text of the hint after migration period" "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period"
}, },
"icu:SafetyNumberOnboarding__title": { "icu:SafetyNumberOnboarding__title": {
"messageformat": "Changes to safety numbers", "messageformat": "Changes to safety numbers",

View file

@ -31,8 +31,6 @@ export type ConfigKeyType =
| 'desktop.pnp' | 'desktop.pnp'
| 'desktop.pnp.accountE164Deprecation' | 'desktop.pnp.accountE164Deprecation'
| 'desktop.retryRespondMaxAge' | 'desktop.retryRespondMaxAge'
| 'desktop.safetyNumberAci'
| 'desktop.safetyNumberAci.beta'
| 'desktop.senderKey.retry' | 'desktop.senderKey.retry'
| 'desktop.senderKey.send' | 'desktop.senderKey.send'
| 'desktop.senderKeyMaxAge' | 'desktop.senderKeyMaxAge'
@ -50,8 +48,7 @@ export type ConfigKeyType =
| 'global.groupsv2.groupSizeHardLimit' | 'global.groupsv2.groupSizeHardLimit'
| 'global.groupsv2.maxGroupSize' | 'global.groupsv2.maxGroupSize'
| 'global.nicknames.max' | 'global.nicknames.max'
| 'global.nicknames.min' | 'global.nicknames.min';
| 'global.safetyNumberAci';
type ConfigValueType = { type ConfigValueType = {
name: ConfigKeyType; name: ConfigKeyType;

View file

@ -3,7 +3,6 @@
import React, { useState, useCallback } from 'react'; import React, { useState, useCallback } from 'react';
import { SafetyNumberMode } from '../types/safetyNumber';
import { isSafetyNumberNotAvailable } from '../util/isSafetyNumberNotAvailable'; import { isSafetyNumberNotAvailable } from '../util/isSafetyNumberNotAvailable';
import { Modal } from './Modal'; import { Modal } from './Modal';
import type { PropsType as SafetyNumberViewerPropsType } from './SafetyNumberViewer'; import type { PropsType as SafetyNumberViewerPropsType } from './SafetyNumberViewer';
@ -24,11 +23,10 @@ export function SafetyNumberModal({
markHasCompletedSafetyNumberOnboarding, markHasCompletedSafetyNumberOnboarding,
...safetyNumberViewerProps ...safetyNumberViewerProps
}: PropsType): JSX.Element | null { }: PropsType): JSX.Element | null {
const { contact, safetyNumberMode } = safetyNumberViewerProps; const { contact } = safetyNumberViewerProps;
const [isOnboarding, setIsOnboarding] = useState( const [isOnboarding, setIsOnboarding] = useState(
safetyNumberMode !== SafetyNumberMode.JustE164 && !hasCompletedSafetyNumberOnboarding
!hasCompletedSafetyNumberOnboarding
); );
const showOnboarding = useCallback(() => { const showOnboarding = useCallback(() => {
@ -40,14 +38,10 @@ export function SafetyNumberModal({
markHasCompletedSafetyNumberOnboarding(); markHasCompletedSafetyNumberOnboarding();
}, [setIsOnboarding, markHasCompletedSafetyNumberOnboarding]); }, [setIsOnboarding, markHasCompletedSafetyNumberOnboarding]);
const missingRequiredE164 =
safetyNumberMode !== SafetyNumberMode.DefaultACIAndMaybeE164 &&
!contact.e164;
let title: string | undefined; let title: string | undefined;
let content: JSX.Element; let content: JSX.Element;
let hasXButton = true; let hasXButton = true;
if (missingRequiredE164 || isSafetyNumberNotAvailable(contact)) { if (isSafetyNumberNotAvailable(contact)) {
content = ( content = (
<SafetyNumberNotReady <SafetyNumberNotReady
i18n={i18n} i18n={i18n}

View file

@ -7,10 +7,7 @@ import type { Meta } from '@storybook/react';
import type { PropsType } from './SafetyNumberViewer'; import type { PropsType } from './SafetyNumberViewer';
import { SafetyNumberViewer } from './SafetyNumberViewer'; import { SafetyNumberViewer } from './SafetyNumberViewer';
import { setupI18n } from '../util/setupI18n'; import { setupI18n } from '../util/setupI18n';
import { import { SafetyNumberIdentifierType } from '../types/safetyNumber';
SafetyNumberIdentifierType,
SafetyNumberMode,
} from '../types/safetyNumber';
import enMessages from '../../_locales/en/messages.json'; import enMessages from '../../_locales/en/messages.json';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation'; import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
@ -72,8 +69,6 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
contact: overrideProps.contact || contactWithAllData, contact: overrideProps.contact || contactWithAllData,
generateSafetyNumber: action('generate-safety-number'), generateSafetyNumber: action('generate-safety-number'),
i18n, i18n,
safetyNumberMode:
overrideProps.safetyNumberMode ?? SafetyNumberMode.DefaultE164AndThenACI,
safetyNumbers: overrideProps.safetyNumbers ?? [ safetyNumbers: overrideProps.safetyNumbers ?? [
{ {
identifierType: SafetyNumberIdentifierType.ACIIdentifier, identifierType: SafetyNumberIdentifierType.ACIIdentifier,
@ -97,28 +92,10 @@ export function SafetyNumber(): JSX.Element {
return <SafetyNumberViewer {...createProps({})} />; return <SafetyNumberViewer {...createProps({})} />;
} }
export function SafetyNumberBeforeE164Transition(): JSX.Element {
return (
<SafetyNumberViewer
{...createProps({
safetyNumberMode: SafetyNumberMode.JustE164,
safetyNumbers: [
{
identifierType: SafetyNumberIdentifierType.E164Identifier,
numberBlocks: generateNumberBlocks(),
qrData: generateQRData(),
},
],
})}
/>
);
}
export function SafetyNumberE164Transition(): JSX.Element { export function SafetyNumberE164Transition(): JSX.Element {
return ( return (
<SafetyNumberViewer <SafetyNumberViewer
{...createProps({ {...createProps({
safetyNumberMode: SafetyNumberMode.DefaultE164AndThenACI,
safetyNumbers: [ safetyNumbers: [
{ {
identifierType: SafetyNumberIdentifierType.E164Identifier, identifierType: SafetyNumberIdentifierType.E164Identifier,

View file

@ -12,10 +12,7 @@ import { Emojify } from './conversation/Emojify';
import type { LocalizerType } from '../types/Util'; import type { LocalizerType } from '../types/Util';
import type { SafetyNumberType } from '../types/safetyNumber'; import type { SafetyNumberType } from '../types/safetyNumber';
import { SAFETY_NUMBER_MIGRATION_URL } from '../types/support'; import { SAFETY_NUMBER_MIGRATION_URL } from '../types/support';
import { import { SafetyNumberIdentifierType } from '../types/safetyNumber';
SafetyNumberIdentifierType,
SafetyNumberMode,
} from '../types/safetyNumber';
import { arrow } from '../util/keyboard'; import { arrow } from '../util/keyboard';
export type PropsType = { export type PropsType = {
@ -23,7 +20,6 @@ export type PropsType = {
generateSafetyNumber: (contact: ConversationType) => void; generateSafetyNumber: (contact: ConversationType) => void;
i18n: LocalizerType; i18n: LocalizerType;
onClose: () => void; onClose: () => void;
safetyNumberMode: SafetyNumberMode;
safetyNumbers?: ReadonlyArray<SafetyNumberType>; safetyNumbers?: ReadonlyArray<SafetyNumberType>;
toggleVerified: (contact: ConversationType) => void; toggleVerified: (contact: ConversationType) => void;
showOnboarding?: () => void; showOnboarding?: () => void;
@ -35,7 +31,6 @@ export function SafetyNumberViewer({
generateSafetyNumber, generateSafetyNumber,
i18n, i18n,
onClose, onClose,
safetyNumberMode,
safetyNumbers, safetyNumbers,
toggleVerified, toggleVerified,
showOnboarding, showOnboarding,
@ -115,8 +110,6 @@ export function SafetyNumberViewer({
? i18n('icu:SafetyNumberViewer__clearVerification') ? i18n('icu:SafetyNumberViewer__clearVerification')
: i18n('icu:SafetyNumberViewer__markAsVerified'); : i18n('icu:SafetyNumberViewer__markAsVerified');
const isMigrationVisible = safetyNumberMode !== SafetyNumberMode.JustE164;
const visibleSafetyNumber = safetyNumbers.at(selectedIndex); const visibleSafetyNumber = safetyNumbers.at(selectedIndex);
if (!visibleSafetyNumber) { if (!visibleSafetyNumber) {
return null; return null;
@ -188,54 +181,44 @@ export function SafetyNumberViewer({
return ( return (
<div className="module-SafetyNumberViewer"> <div className="module-SafetyNumberViewer">
{isMigrationVisible && ( <div className="module-SafetyNumberViewer__migration">
<div className="module-SafetyNumberViewer__migration"> <div className="module-SafetyNumberViewer__migration__icon" />
<div className="module-SafetyNumberViewer__migration__icon" />
<div className="module-SafetyNumberViewer__migration__text"> <div className="module-SafetyNumberViewer__migration__text">
<p> <p>
<Intl i18n={i18n} id="icu:SafetyNumberViewer__migration__text" /> <Intl i18n={i18n} id="icu:SafetyNumberViewer__migration__text" />
</p> </p>
<p> <p>
<a <a
href={SAFETY_NUMBER_MIGRATION_URL} href={SAFETY_NUMBER_MIGRATION_URL}
rel="noreferrer" rel="noreferrer"
target="_blank" target="_blank"
onClick={e => { onClick={e => {
if (showOnboarding) { if (showOnboarding) {
e.preventDefault(); e.preventDefault();
showOnboarding(); showOnboarding();
} }
}} }}
> >
<Intl <Intl
i18n={i18n} i18n={i18n}
id="icu:SafetyNumberViewer__migration__learn_more" id="icu:SafetyNumberViewer__migration__learn_more"
/> />
</a> </a>
</p> </p>
</div>
</div> </div>
)} </div>
{safetyNumberCard} {safetyNumberCard}
{safetyNumbers.length > 1 && carousel} {safetyNumbers.length > 1 && carousel}
<div className="module-SafetyNumberViewer__help"> <div className="module-SafetyNumberViewer__help">
{isMigrationVisible ? ( <Intl
<Intl i18n={i18n}
i18n={i18n} id="icu:SafetyNumberViewer__hint--migration"
id="icu:SafetyNumberViewer__hint--migration" components={{ name: boldName }}
components={{ name: boldName }} />
/>
) : (
<Intl
i18n={i18n}
id="icu:SafetyNumberViewer__hint--normal"
components={{ name: boldName }}
/>
)}
<br /> <br />
<a href={SAFETY_NUMBER_MIGRATION_URL} rel="noreferrer" target="_blank"> <a href={SAFETY_NUMBER_MIGRATION_URL} rel="noreferrer" target="_blank">
<Intl <Intl

View file

@ -15,7 +15,6 @@ import {
import * as log from '../../logging/log'; import * as log from '../../logging/log';
import * as Errors from '../../types/errors'; import * as Errors from '../../types/errors';
import type { StateType as RootStateType } from '../reducer'; import type { StateType as RootStateType } from '../reducer';
import { getSafetyNumberMode } from '../selectors/items';
export type SafetyNumberContactType = ReadonlyDeep<{ export type SafetyNumberContactType = ReadonlyDeep<{
safetyNumbers: ReadonlyArray<SafetyNumberType>; safetyNumbers: ReadonlyArray<SafetyNumberType>;
@ -82,12 +81,9 @@ function clearSafetyNumber(contactId: string): ClearSafetyNumberActionType {
function generate( function generate(
contact: ConversationType contact: ConversationType
): ThunkAction<void, RootStateType, unknown, GenerateFulfilledActionType> { ): ThunkAction<void, RootStateType, unknown, GenerateFulfilledActionType> {
return async (dispatch, getState) => { return async dispatch => {
try { try {
const safetyNumbers = await generateSafetyNumbers( const safetyNumbers = await generateSafetyNumbers(contact);
contact,
getSafetyNumberMode(getState(), { now: Date.now() })
);
dispatch({ dispatch({
type: GENERATE_FULFILLED, type: GENERATE_FULFILLED,
payload: { payload: {
@ -112,7 +108,7 @@ function toggleVerified(
unknown, unknown,
ToggleVerifiedPendingActionType | ToggleVerifiedFulfilledActionType ToggleVerifiedPendingActionType | ToggleVerifiedFulfilledActionType
> { > {
return async (dispatch, getState) => { return async dispatch => {
dispatch({ dispatch({
type: TOGGLE_VERIFIED_PENDING, type: TOGGLE_VERIFIED_PENDING,
payload: { payload: {
@ -132,10 +128,7 @@ function toggleVerified(
} catch (err) { } catch (err) {
if (err.name === 'OutgoingIdentityKeyError') { if (err.name === 'OutgoingIdentityKeyError') {
await reloadProfiles(contact.id); await reloadProfiles(contact.id);
const safetyNumbers = await generateSafetyNumbers( const safetyNumbers = await generateSafetyNumbers(contact);
contact,
getSafetyNumberMode(getState(), { now: Date.now() })
);
dispatch({ dispatch({
type: TOGGLE_VERIFIED_FULFILLED, type: TOGGLE_VERIFIED_FULFILLED,

View file

@ -5,7 +5,6 @@ import { createSelector } from 'reselect';
import { isInteger } from 'lodash'; import { isInteger } from 'lodash';
import { ITEM_NAME as UNIVERSAL_EXPIRE_TIMER_ITEM } from '../../util/universalExpireTimer'; import { ITEM_NAME as UNIVERSAL_EXPIRE_TIMER_ITEM } from '../../util/universalExpireTimer';
import { SafetyNumberMode } from '../../types/safetyNumber';
import { innerIsBucketValueEnabled } from '../../RemoteConfig'; import { innerIsBucketValueEnabled } from '../../RemoteConfig';
import type { ConfigKeyType, ConfigMapType } from '../../RemoteConfig'; import type { ConfigKeyType, ConfigMapType } from '../../RemoteConfig';
import type { StateType } from '../reducer'; import type { StateType } from '../reducer';
@ -18,7 +17,7 @@ import type { AciString } from '../../types/ServiceId';
import { DEFAULT_CONVERSATION_COLOR } from '../../types/Colors'; import { DEFAULT_CONVERSATION_COLOR } from '../../types/Colors';
import { getPreferredReactionEmoji as getPreferredReactionEmojiFromStoredValue } from '../../reactions/preferredReactionEmoji'; import { getPreferredReactionEmoji as getPreferredReactionEmojiFromStoredValue } from '../../reactions/preferredReactionEmoji';
import { isBeta } from '../../util/version'; import { isBeta } from '../../util/version';
import { DurationInSeconds, SECOND } from '../../util/durations'; import { DurationInSeconds } from '../../util/durations';
import { generateUsernameLink } from '../../util/sgnlHref'; import { generateUsernameLink } from '../../util/sgnlHref';
import * as Bytes from '../../Bytes'; import * as Bytes from '../../Bytes';
import { getUserNumber, getUserACI } from './user'; import { getUserNumber, getUserACI } from './user';
@ -167,40 +166,6 @@ export const getStoriesEnabled = createSelector(
} }
); );
export const getSafetyNumberMode = createSelector(
getRemoteConfig,
getServerTimeSkew,
(_state: StateType, { now }: { now: number }) => now,
(
remoteConfig: ConfigMapType,
serverTimeSkew: number,
now: number
): SafetyNumberMode => {
if (
!isRemoteConfigFlagEnabled(remoteConfig, 'desktop.safetyNumberAci') &&
!(
isRemoteConfigFlagEnabled(
remoteConfig,
'desktop.safetyNumberAci.beta'
) && isBeta(window.getVersion())
)
) {
return SafetyNumberMode.JustE164;
}
const timestampInSeconds = remoteConfig['global.safetyNumberAci']?.value;
if (typeof timestampInSeconds !== 'number') {
return SafetyNumberMode.DefaultE164AndThenACI;
}
// Note: serverTimeSkew is a difference between server time and local time,
// so we have to add local time to it to correct it for a skew.
return now + serverTimeSkew >= timestampInSeconds * SECOND
? SafetyNumberMode.DefaultACIAndMaybeE164
: SafetyNumberMode.DefaultE164AndThenACI;
}
);
export const getDefaultConversationColor = createSelector( export const getDefaultConversationColor = createSelector(
getItems, getItems,
( (

View file

@ -7,10 +7,7 @@ import { SafetyNumberModal } from '../../components/SafetyNumberModal';
import type { StateType } from '../reducer'; import type { StateType } from '../reducer';
import { getContactSafetyNumber } from '../selectors/safetyNumber'; import { getContactSafetyNumber } from '../selectors/safetyNumber';
import { getConversationSelector } from '../selectors/conversations'; import { getConversationSelector } from '../selectors/conversations';
import { import { getHasCompletedSafetyNumberOnboarding } from '../selectors/items';
getSafetyNumberMode,
getHasCompletedSafetyNumberOnboarding,
} from '../selectors/items';
import { getIntl } from '../selectors/user'; import { getIntl } from '../selectors/user';
export type Props = { export type Props = {
@ -22,7 +19,6 @@ const mapStateToProps = (state: StateType, props: Props) => {
...props, ...props,
...getContactSafetyNumber(state, props), ...getContactSafetyNumber(state, props),
contact: getConversationSelector(state)(props.contactID), contact: getConversationSelector(state)(props.contactID),
safetyNumberMode: getSafetyNumberMode(state, { now: Date.now() }),
hasCompletedSafetyNumberOnboarding: hasCompletedSafetyNumberOnboarding:
getHasCompletedSafetyNumberOnboarding(state), getHasCompletedSafetyNumberOnboarding(state),
i18n: getIntl(state), i18n: getIntl(state),

View file

@ -8,7 +8,6 @@ import type { StateType } from '../reducer';
import type { SafetyNumberProps } from '../../components/SafetyNumberChangeDialog'; import type { SafetyNumberProps } from '../../components/SafetyNumberChangeDialog';
import { getContactSafetyNumber } from '../selectors/safetyNumber'; import { getContactSafetyNumber } from '../selectors/safetyNumber';
import { getConversationSelector } from '../selectors/conversations'; import { getConversationSelector } from '../selectors/conversations';
import { getSafetyNumberMode } from '../selectors/items';
import { getIntl } from '../selectors/user'; import { getIntl } from '../selectors/user';
const mapStateToProps = (state: StateType, props: SafetyNumberProps) => { const mapStateToProps = (state: StateType, props: SafetyNumberProps) => {
@ -16,7 +15,6 @@ const mapStateToProps = (state: StateType, props: SafetyNumberProps) => {
...props, ...props,
...getContactSafetyNumber(state, props), ...getContactSafetyNumber(state, props),
contact: getConversationSelector(state)(props.contactID), contact: getConversationSelector(state)(props.contactID),
safetyNumberMode: getSafetyNumberMode(state, { now: Date.now() }),
i18n: getIntl(state), i18n: getIntl(state),
}; };
}; };

View file

@ -1,12 +1,6 @@
// Copyright 2023 Signal Messenger, LLC // Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
export enum SafetyNumberMode {
JustE164 = 'JustE164',
DefaultE164AndThenACI = 'DefaultE164AndThenACI',
DefaultACIAndMaybeE164 = 'DefaultACIAndMaybeE164',
}
export enum SafetyNumberIdentifierType { export enum SafetyNumberIdentifierType {
ACIIdentifier = 'ACIIdentifier', ACIIdentifier = 'ACIIdentifier',
E164Identifier = 'E164Identifier', E164Identifier = 'E164Identifier',

View file

@ -11,10 +11,7 @@ import { uuidToBytes } from './uuidToBytes';
import * as log from '../logging/log'; import * as log from '../logging/log';
import * as Bytes from '../Bytes'; import * as Bytes from '../Bytes';
import type { SafetyNumberType } from '../types/safetyNumber'; import type { SafetyNumberType } from '../types/safetyNumber';
import { import { SafetyNumberIdentifierType } from '../types/safetyNumber';
SafetyNumberIdentifierType,
SafetyNumberMode,
} from '../types/safetyNumber';
import { isAciString } from './isAciString'; import { isAciString } from './isAciString';
const ITERATION_COUNT = 5200; const ITERATION_COUNT = 5200;
@ -25,10 +22,9 @@ const SERVICE_ID_VERSION = 2;
const BLOCK_SIZE = 5; const BLOCK_SIZE = 5;
export async function generateSafetyNumbers( export async function generateSafetyNumbers(
contact: ConversationType, contact: ConversationType
mode: SafetyNumberMode
): Promise<ReadonlyArray<SafetyNumberType>> { ): Promise<ReadonlyArray<SafetyNumberType>> {
const logId = `generateSafetyNumbers(${contact.id}, ${mode})`; const logId = `generateSafetyNumbers(${contact.id})`;
log.info(`${logId}: starting`); log.info(`${logId}: starting`);
const { storage } = window.textsecure; const { storage } = window.textsecure;
@ -57,24 +53,10 @@ export async function generateSafetyNumbers(
const ourKey = PublicKey.deserialize(Buffer.from(ourKeyBuffer)); const ourKey = PublicKey.deserialize(Buffer.from(ourKeyBuffer));
const theirKey = PublicKey.deserialize(Buffer.from(theirKeyBuffer)); const theirKey = PublicKey.deserialize(Buffer.from(theirKeyBuffer));
let identifierTypes: ReadonlyArray<SafetyNumberIdentifierType>; const identifierTypes = [
if (mode === SafetyNumberMode.DefaultE164AndThenACI) { SafetyNumberIdentifierType.ACIIdentifier,
// Important: order matters, legacy safety number should be displayed first. SafetyNumberIdentifierType.E164Identifier,
identifierTypes = [ ];
SafetyNumberIdentifierType.E164Identifier,
SafetyNumberIdentifierType.ACIIdentifier,
];
// Controlled by 'desktop.safetyNumberAci'
} else if (mode === SafetyNumberMode.JustE164) {
identifierTypes = [SafetyNumberIdentifierType.E164Identifier];
} else if (mode === SafetyNumberMode.DefaultACIAndMaybeE164) {
identifierTypes = [
SafetyNumberIdentifierType.ACIIdentifier,
SafetyNumberIdentifierType.E164Identifier,
];
} else {
throw missingCaseError(mode);
}
return identifierTypes return identifierTypes
.map(identifierType => { .map(identifierType => {