Change defaults for conversation title generation
This commit is contained in:
parent
6a165da589
commit
bd922433e3
14 changed files with 142 additions and 24 deletions
2
ts/model-types.d.ts
vendored
2
ts/model-types.d.ts
vendored
|
@ -333,7 +333,7 @@ export type ConversationAttributesType = {
|
||||||
messageRequestResponseType?: number;
|
messageRequestResponseType?: number;
|
||||||
muteExpiresAt?: number;
|
muteExpiresAt?: number;
|
||||||
dontNotifyForMentionsIfMuted?: boolean;
|
dontNotifyForMentionsIfMuted?: boolean;
|
||||||
notSharingPhoneNumber?: boolean;
|
sharingPhoneNumber?: boolean;
|
||||||
profileAvatar?: ContactAvatarType | null;
|
profileAvatar?: ContactAvatarType | null;
|
||||||
profileKeyCredential?: string | null;
|
profileKeyCredential?: string | null;
|
||||||
profileKeyCredentialExpiration?: number | null;
|
profileKeyCredentialExpiration?: number | null;
|
||||||
|
|
|
@ -1859,7 +1859,7 @@ export class ConversationModel extends window.Backbone
|
||||||
this.set('e164', e164 || undefined);
|
this.set('e164', e164 || undefined);
|
||||||
|
|
||||||
// This user changed their phone number
|
// This user changed their phone number
|
||||||
if (oldValue && e164 && !this.get('notSharingPhoneNumber')) {
|
if (oldValue && e164 && this.get('sharingPhoneNumber')) {
|
||||||
void this.addChangeNumberNotification(oldValue, e164);
|
void this.addChangeNumberNotification(oldValue, e164);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -434,15 +434,15 @@ async function doGetProfile(c: ConversationModel): Promise<void> {
|
||||||
decryptionKey
|
decryptionKey
|
||||||
);
|
);
|
||||||
|
|
||||||
// It should be one byte, but be conservative about it and only
|
// It should be one byte, but be conservative about it and
|
||||||
// set `notSharingPhoneNumber` to `true` in all cases except [0x01].
|
// set `sharingPhoneNumber` to `false` in all cases except [0x01].
|
||||||
c.set(
|
c.set(
|
||||||
'notSharingPhoneNumber',
|
'sharingPhoneNumber',
|
||||||
decrypted.length !== 1 || decrypted[0] !== 1
|
decrypted.length === 1 && decrypted[0] === 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.unset('notSharingPhoneNumber');
|
c.unset('sharingPhoneNumber');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile.paymentAddress && isMe(c.attributes)) {
|
if (profile.paymentAddress && isMe(c.attributes)) {
|
||||||
|
|
|
@ -123,7 +123,7 @@ class UsernameIntegrityService {
|
||||||
|
|
||||||
{
|
{
|
||||||
const localValue = isSharingPhoneNumberWithEverybody();
|
const localValue = isSharingPhoneNumberWithEverybody();
|
||||||
const remoteValue = !me.get('notSharingPhoneNumber');
|
const remoteValue = me.get('sharingPhoneNumber') === true;
|
||||||
if (localValue === remoteValue) {
|
if (localValue === remoteValue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ class UsernameIntegrityService {
|
||||||
|
|
||||||
{
|
{
|
||||||
const localValue = isSharingPhoneNumberWithEverybody();
|
const localValue = isSharingPhoneNumberWithEverybody();
|
||||||
const remoteValue = !me.get('notSharingPhoneNumber');
|
const remoteValue = me.get('sharingPhoneNumber') === true;
|
||||||
if (localValue === remoteValue) {
|
if (localValue === remoteValue) {
|
||||||
log.info(
|
log.info(
|
||||||
'usernameIntegrity: phone number sharing mode conflict resolved by ' +
|
'usernameIntegrity: phone number sharing mode conflict resolved by ' +
|
||||||
|
|
45
ts/sql/migrations/990-phone-number-sharing.ts
Normal file
45
ts/sql/migrations/990-phone-number-sharing.ts
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright 2024 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import type { Database } from '@signalapp/better-sqlite3';
|
||||||
|
|
||||||
|
import type { LoggerType } from '../../types/Logging';
|
||||||
|
|
||||||
|
export const version = 990;
|
||||||
|
|
||||||
|
export function updateToSchemaVersion990(
|
||||||
|
currentVersion: number,
|
||||||
|
db: Database,
|
||||||
|
logger: LoggerType
|
||||||
|
): void {
|
||||||
|
if (currentVersion >= 990) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.transaction(() => {
|
||||||
|
db.exec(`
|
||||||
|
UPDATE conversations
|
||||||
|
SET json = json_remove(
|
||||||
|
json_insert(
|
||||||
|
json,
|
||||||
|
'$.sharingPhoneNumber',
|
||||||
|
iif(
|
||||||
|
json ->> '$.notSharingPhoneNumber',
|
||||||
|
-- We flip the value from false to true, and vice versa
|
||||||
|
json('false'),
|
||||||
|
json('true')
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'$.notSharingPhoneNumber'
|
||||||
|
)
|
||||||
|
-- Default value of '$.notSharingPhoneNumber' is true and
|
||||||
|
-- the default value of '$.sharingPhoneNumber' is false so we don't have
|
||||||
|
-- to do anything if the field wasn't present.
|
||||||
|
WHERE json ->> '$.notSharingPhoneNumber' IS NOT NULL;
|
||||||
|
`);
|
||||||
|
})();
|
||||||
|
|
||||||
|
db.pragma('user_version = 990');
|
||||||
|
|
||||||
|
logger.info('updateToSchemaVersion990: success!');
|
||||||
|
}
|
|
@ -73,10 +73,11 @@ import { updateToSchemaVersion940 } from './940-fts5-revert';
|
||||||
import { updateToSchemaVersion950 } from './950-fts5-secure-delete';
|
import { updateToSchemaVersion950 } from './950-fts5-secure-delete';
|
||||||
import { updateToSchemaVersion960 } from './960-untag-pni';
|
import { updateToSchemaVersion960 } from './960-untag-pni';
|
||||||
import { updateToSchemaVersion970 } from './970-fts5-optimize';
|
import { updateToSchemaVersion970 } from './970-fts5-optimize';
|
||||||
|
import { updateToSchemaVersion980 } from './980-reaction-timestamp';
|
||||||
import {
|
import {
|
||||||
version as MAX_VERSION,
|
version as MAX_VERSION,
|
||||||
updateToSchemaVersion980,
|
updateToSchemaVersion990,
|
||||||
} from './980-reaction-timestamp';
|
} from './990-phone-number-sharing';
|
||||||
|
|
||||||
function updateToSchemaVersion1(
|
function updateToSchemaVersion1(
|
||||||
currentVersion: number,
|
currentVersion: number,
|
||||||
|
@ -2017,6 +2018,7 @@ export const SCHEMA_VERSIONS = [
|
||||||
updateToSchemaVersion960,
|
updateToSchemaVersion960,
|
||||||
updateToSchemaVersion970,
|
updateToSchemaVersion970,
|
||||||
updateToSchemaVersion980,
|
updateToSchemaVersion980,
|
||||||
|
updateToSchemaVersion990,
|
||||||
];
|
];
|
||||||
|
|
||||||
export class DBVersionFromFutureError extends Error {
|
export class DBVersionFromFutureError extends Error {
|
||||||
|
|
|
@ -308,7 +308,7 @@ export type ConversationType = ReadonlyDeep<
|
||||||
typingContactIdTimestamps?: Record<string, number>;
|
typingContactIdTimestamps?: Record<string, number>;
|
||||||
recentMediaItems?: ReadonlyArray<MediaItemType>;
|
recentMediaItems?: ReadonlyArray<MediaItemType>;
|
||||||
profileSharing?: boolean;
|
profileSharing?: boolean;
|
||||||
notSharingPhoneNumber?: boolean;
|
sharingPhoneNumber?: boolean;
|
||||||
|
|
||||||
shouldShowDraft?: boolean;
|
shouldShowDraft?: boolean;
|
||||||
// Full information for re-hydrating composition area
|
// Full information for re-hydrating composition area
|
||||||
|
|
|
@ -53,6 +53,7 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) {
|
||||||
{
|
{
|
||||||
identityState: Proto.ContactRecord.IdentityState.DEFAULT,
|
identityState: Proto.ContactRecord.IdentityState.DEFAULT,
|
||||||
whitelisted: true,
|
whitelisted: true,
|
||||||
|
profileKey: undefined,
|
||||||
|
|
||||||
serviceE164: unknownPniContact.device.number,
|
serviceE164: unknownPniContact.device.number,
|
||||||
},
|
},
|
||||||
|
|
69
ts/test-node/sql/migration_990_test.ts
Normal file
69
ts/test-node/sql/migration_990_test.ts
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
// Copyright 2023 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { assert } from 'chai';
|
||||||
|
import type { Database } from '@signalapp/better-sqlite3';
|
||||||
|
import SQL from '@signalapp/better-sqlite3';
|
||||||
|
|
||||||
|
import { updateToVersion, insertData, getTableData } from './helpers';
|
||||||
|
|
||||||
|
describe('SQL/updateToSchemaVersion990', () => {
|
||||||
|
let db: Database;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
db = new SQL(':memory:');
|
||||||
|
updateToVersion(db, 980);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
db.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should migrate conversations', () => {
|
||||||
|
insertData(db, 'conversations', [
|
||||||
|
{
|
||||||
|
id: 'no-prop',
|
||||||
|
json: {
|
||||||
|
keep: 'this',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'false-prop',
|
||||||
|
json: {
|
||||||
|
keep: 'this',
|
||||||
|
notSharingPhoneNumber: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'true-prop',
|
||||||
|
json: {
|
||||||
|
keep: 'this',
|
||||||
|
notSharingPhoneNumber: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
updateToVersion(db, 990);
|
||||||
|
assert.deepStrictEqual(getTableData(db, 'conversations'), [
|
||||||
|
{
|
||||||
|
id: 'no-prop',
|
||||||
|
json: {
|
||||||
|
keep: 'this',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'false-prop',
|
||||||
|
json: {
|
||||||
|
keep: 'this',
|
||||||
|
sharingPhoneNumber: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'true-prop',
|
||||||
|
json: {
|
||||||
|
keep: 'this',
|
||||||
|
sharingPhoneNumber: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
|
@ -247,12 +247,6 @@ export function createIPCEvents(
|
||||||
setPhoneNumberSharingSetting: async (newValue: PhoneNumberSharingMode) => {
|
setPhoneNumberSharingSetting: async (newValue: PhoneNumberSharingMode) => {
|
||||||
const account = window.ConversationController.getOurConversationOrThrow();
|
const account = window.ConversationController.getOurConversationOrThrow();
|
||||||
|
|
||||||
// writeProfile fetches the latest profile first so do it before updating
|
|
||||||
// local data to prevent triggering a conflict.
|
|
||||||
await writeProfile(getConversation(account), {
|
|
||||||
keepAvatar: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const promises = new Array<Promise<void>>();
|
const promises = new Array<Promise<void>>();
|
||||||
promises.push(window.storage.put('phoneNumberSharingMode', newValue));
|
promises.push(window.storage.put('phoneNumberSharingMode', newValue));
|
||||||
if (newValue === PhoneNumberSharingMode.Everybody) {
|
if (newValue === PhoneNumberSharingMode.Everybody) {
|
||||||
|
@ -264,6 +258,12 @@ export function createIPCEvents(
|
||||||
}
|
}
|
||||||
account.captureChange('phoneNumberSharingMode');
|
account.captureChange('phoneNumberSharingMode');
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
|
|
||||||
|
// Write profile after updating storage so that the write has up-to-date
|
||||||
|
// information.
|
||||||
|
await writeProfile(getConversation(account), {
|
||||||
|
keepAvatar: true,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getHasStoriesDisabled: () =>
|
getHasStoriesDisabled: () =>
|
||||||
|
|
|
@ -211,7 +211,7 @@ export function getConversation(model: ConversationModel): ConversationType {
|
||||||
profileName: getProfileName(attributes),
|
profileName: getProfileName(attributes),
|
||||||
profileSharing: attributes.profileSharing,
|
profileSharing: attributes.profileSharing,
|
||||||
profileLastUpdatedAt: attributes.profileLastUpdatedAt,
|
profileLastUpdatedAt: attributes.profileLastUpdatedAt,
|
||||||
notSharingPhoneNumber: attributes.notSharingPhoneNumber,
|
sharingPhoneNumber: attributes.sharingPhoneNumber,
|
||||||
publicParams: attributes.publicParams,
|
publicParams: attributes.publicParams,
|
||||||
secretParams: attributes.secretParams,
|
secretParams: attributes.secretParams,
|
||||||
shouldShowDraft,
|
shouldShowDraft,
|
||||||
|
|
|
@ -13,12 +13,13 @@ export function getE164(
|
||||||
| 'systemGivenName'
|
| 'systemGivenName'
|
||||||
| 'systemFamilyName'
|
| 'systemFamilyName'
|
||||||
| 'e164'
|
| 'e164'
|
||||||
| 'notSharingPhoneNumber'
|
| 'sharingPhoneNumber'
|
||||||
|
| 'profileKey'
|
||||||
>
|
>
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
const { e164, notSharingPhoneNumber = false } = attributes;
|
const { e164, profileKey, sharingPhoneNumber } = attributes;
|
||||||
|
|
||||||
if (notSharingPhoneNumber && !isInSystemContacts(attributes)) {
|
if (!sharingPhoneNumber && profileKey && !isInSystemContacts(attributes)) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ export function getSystemName(
|
||||||
export function getNumber(
|
export function getNumber(
|
||||||
attributes: Pick<
|
attributes: Pick<
|
||||||
ConversationAttributesType,
|
ConversationAttributesType,
|
||||||
'e164' | 'type' | 'notSharingPhoneNumber'
|
'e164' | 'type' | 'sharingPhoneNumber' | 'profileKey'
|
||||||
>
|
>
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
if (!isDirectConversation(attributes)) {
|
if (!isDirectConversation(attributes)) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ export enum PhoneNumberSharingMode {
|
||||||
|
|
||||||
export const parsePhoneNumberSharingMode = makeEnumParser(
|
export const parsePhoneNumberSharingMode = makeEnumParser(
|
||||||
PhoneNumberSharingMode,
|
PhoneNumberSharingMode,
|
||||||
PhoneNumberSharingMode.Everybody
|
PhoneNumberSharingMode.Nobody
|
||||||
);
|
);
|
||||||
|
|
||||||
export const isSharingPhoneNumberWithEverybody = (): boolean => {
|
export const isSharingPhoneNumberWithEverybody = (): boolean => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue