Backups: update to latest integration tests
This commit is contained in:
parent
c7dc4279a1
commit
6f7faf4be8
12 changed files with 239 additions and 88 deletions
|
@ -139,6 +139,7 @@ import { getRoomIdFromRootKey } from '../../util/callLinksRingrtc';
|
|||
import { SeenStatus } from '../../MessageSeenStatus';
|
||||
import { migrateAllMessages } from '../../messages/migrateMessageData';
|
||||
import { trimBody } from '../../util/longAttachment';
|
||||
import { generateBackupsSubscriberData } from '../../util/backupSubscriptionData';
|
||||
|
||||
const MAX_CONCURRENCY = 10;
|
||||
|
||||
|
@ -258,6 +259,8 @@ export class BackupExportStream extends Readable {
|
|||
version: Long.fromNumber(BACKUP_VERSION),
|
||||
backupTimeMs: this.backupTimeMs,
|
||||
mediaRootBackupKey: getBackupMediaRootKey().serialize(),
|
||||
firstAppVersion: window.storage.get('restoredBackupFirstAppVersion'),
|
||||
currentAppVersion: `Desktop ${window.getVersion()}`,
|
||||
}).finish()
|
||||
);
|
||||
|
||||
|
@ -660,7 +663,8 @@ export class BackupExportStream extends Readable {
|
|||
const usernameLink = storage.get('usernameLink');
|
||||
|
||||
const subscriberId = storage.get('subscriberId');
|
||||
const backupsSubscriberId = storage.get('backupsSubscriberId');
|
||||
|
||||
const backupsSubscriberData = generateBackupsSubscriberData();
|
||||
|
||||
return {
|
||||
profileKey: storage.get('profileKey'),
|
||||
|
@ -676,16 +680,7 @@ export class BackupExportStream extends Readable {
|
|||
givenName: me.get('profileName'),
|
||||
familyName: me.get('profileFamilyName'),
|
||||
avatarUrlPath: storage.get('avatarUrl'),
|
||||
backupsSubscriberData: Bytes.isNotEmpty(backupsSubscriberId)
|
||||
? {
|
||||
subscriberId: backupsSubscriberId,
|
||||
currencyCode: storage.get('backupsSubscriberCurrencyCode'),
|
||||
manuallyCancelled: storage.get(
|
||||
'backupsSubscriptionManuallyCancelled',
|
||||
false
|
||||
),
|
||||
}
|
||||
: null,
|
||||
backupsSubscriberData,
|
||||
donationSubscriberData: Bytes.isNotEmpty(subscriberId)
|
||||
? {
|
||||
subscriberId,
|
||||
|
|
|
@ -122,6 +122,7 @@ import { hasAttachmentDownloads } from '../../util/hasAttachmentDownloads';
|
|||
import { isNightly } from '../../util/version';
|
||||
import { ToastType } from '../../types/Toast';
|
||||
import { isConversationAccepted } from '../../util/isConversationAccepted';
|
||||
import { saveBackupsSubscriberData } from '../../util/backupSubscriptionData';
|
||||
|
||||
const MAX_CONCURRENCY = 10;
|
||||
|
||||
|
@ -262,6 +263,11 @@ export class BackupImportStream extends Writable {
|
|||
throw new Error('Missing mediaRootBackupKey');
|
||||
}
|
||||
|
||||
await window.storage.put(
|
||||
'restoredBackupFirstAppVersion',
|
||||
info.firstAppVersion
|
||||
);
|
||||
|
||||
const theirKey = info.mediaRootBackupKey;
|
||||
const ourKey = getBackupMediaRootKey().serialize();
|
||||
if (!constantTimeEqual(theirKey, ourKey)) {
|
||||
|
@ -658,22 +664,8 @@ export class BackupImportStream extends Writable {
|
|||
);
|
||||
}
|
||||
}
|
||||
if (backupsSubscriberData != null) {
|
||||
const { subscriberId, currencyCode, manuallyCancelled } =
|
||||
backupsSubscriberData;
|
||||
if (Bytes.isNotEmpty(subscriberId)) {
|
||||
await storage.put('backupsSubscriberId', subscriberId);
|
||||
}
|
||||
if (currencyCode != null) {
|
||||
await storage.put('backupsSubscriberCurrencyCode', currencyCode);
|
||||
}
|
||||
if (manuallyCancelled != null) {
|
||||
await storage.put(
|
||||
'backupsSubscriptionManuallyCancelled',
|
||||
manuallyCancelled
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await saveBackupsSubscriberData(backupsSubscriberData);
|
||||
|
||||
await storage.put(
|
||||
'read-receipt-setting',
|
||||
|
@ -1213,6 +1205,7 @@ export class BackupImportStream extends Writable {
|
|||
if (conversation.active_at == null) {
|
||||
conversation.active_at = Math.max(chat.id.toNumber(), 1);
|
||||
}
|
||||
|
||||
conversation.isArchived = chat.archived === true;
|
||||
conversation.isPinned = (chat.pinnedOrder || 0) !== 0;
|
||||
|
||||
|
|
|
@ -80,6 +80,10 @@ import { fromAdminKeyBytes, toAdminKeyBytes } from '../util/callLinks';
|
|||
import { isOlderThan } from '../util/timestamp';
|
||||
import { getMessageQueueTime } from '../util/getMessageQueueTime';
|
||||
import { callLinkRefreshJobQueue } from '../jobs/callLinkRefreshJobQueue';
|
||||
import {
|
||||
generateBackupsSubscriberData,
|
||||
saveBackupsSubscriberData,
|
||||
} from '../util/backupSubscriptionData';
|
||||
|
||||
const MY_STORY_BYTES = uuidToBytes(MY_STORY_ID);
|
||||
|
||||
|
@ -406,9 +410,7 @@ export function toAccountRecord(
|
|||
if (Bytes.isNotEmpty(subscriberId)) {
|
||||
accountRecord.subscriberId = subscriberId;
|
||||
}
|
||||
const subscriberCurrencyCode = window.storage.get(
|
||||
'backupsSubscriberCurrencyCode'
|
||||
);
|
||||
const subscriberCurrencyCode = window.storage.get('subscriberCurrencyCode');
|
||||
if (typeof subscriberCurrencyCode === 'string') {
|
||||
accountRecord.subscriberCurrencyCode = subscriberCurrencyCode;
|
||||
}
|
||||
|
@ -419,23 +421,9 @@ export function toAccountRecord(
|
|||
accountRecord.donorSubscriptionManuallyCancelled =
|
||||
donorSubscriptionManuallyCancelled;
|
||||
}
|
||||
const backupsSubscriberId = window.storage.get('backupsSubscriberId');
|
||||
if (Bytes.isNotEmpty(backupsSubscriberId)) {
|
||||
accountRecord.backupsSubscriberId = backupsSubscriberId;
|
||||
}
|
||||
const backupsSubscriberCurrencyCode = window.storage.get(
|
||||
'backupsSubscriberCurrencyCode'
|
||||
);
|
||||
if (typeof backupsSubscriberCurrencyCode === 'string') {
|
||||
accountRecord.backupsSubscriberCurrencyCode = backupsSubscriberCurrencyCode;
|
||||
}
|
||||
const backupsSubscriptionManuallyCancelled = window.storage.get(
|
||||
'backupsSubscriptionManuallyCancelled'
|
||||
);
|
||||
if (typeof backupsSubscriptionManuallyCancelled === 'boolean') {
|
||||
accountRecord.backupsSubscriptionManuallyCancelled =
|
||||
backupsSubscriptionManuallyCancelled;
|
||||
}
|
||||
|
||||
accountRecord.backupSubscriberData = generateBackupsSubscriberData();
|
||||
|
||||
const displayBadgesOnProfile = window.storage.get('displayBadgesOnProfile');
|
||||
if (displayBadgesOnProfile !== undefined) {
|
||||
accountRecord.displayBadgesOnProfile = displayBadgesOnProfile;
|
||||
|
@ -1327,9 +1315,7 @@ export async function mergeAccountRecord(
|
|||
subscriberId,
|
||||
subscriberCurrencyCode,
|
||||
donorSubscriptionManuallyCancelled,
|
||||
backupsSubscriberId,
|
||||
backupsSubscriberCurrencyCode,
|
||||
backupsSubscriptionManuallyCancelled,
|
||||
backupSubscriberData,
|
||||
displayBadgesOnProfile,
|
||||
keepMutedChatsArchived,
|
||||
hasCompletedUsernameOnboarding,
|
||||
|
@ -1548,21 +1534,9 @@ export async function mergeAccountRecord(
|
|||
donorSubscriptionManuallyCancelled
|
||||
);
|
||||
}
|
||||
if (Bytes.isNotEmpty(backupsSubscriberId)) {
|
||||
await window.storage.put('backupsSubscriberId', backupsSubscriberId);
|
||||
}
|
||||
if (typeof backupsSubscriberCurrencyCode === 'string') {
|
||||
await window.storage.put(
|
||||
'backupsSubscriberCurrencyCode',
|
||||
backupsSubscriberCurrencyCode
|
||||
);
|
||||
}
|
||||
if (backupsSubscriptionManuallyCancelled != null) {
|
||||
await window.storage.put(
|
||||
'backupsSubscriptionManuallyCancelled',
|
||||
backupsSubscriptionManuallyCancelled
|
||||
);
|
||||
}
|
||||
|
||||
await saveBackupsSubscriberData(backupSubscriberData);
|
||||
|
||||
await window.storage.put(
|
||||
'displayBadgesOnProfile',
|
||||
Boolean(displayBadgesOnProfile)
|
||||
|
|
|
@ -60,6 +60,12 @@ describe('backup/integration', () => {
|
|||
|
||||
const files = readdirSync(BACKUP_INTEGRATION_DIR)
|
||||
.filter(file => file.endsWith('.binproto'))
|
||||
.filter(
|
||||
file =>
|
||||
// TODO (DESKTOP-8025)
|
||||
!file.startsWith('chat_folder_') &&
|
||||
!file.startsWith('notification_profile_')
|
||||
)
|
||||
.map(file => join(BACKUP_INTEGRATION_DIR, file));
|
||||
|
||||
if (files.length === 0) {
|
||||
|
|
7
ts/types/Storage.d.ts
vendored
7
ts/types/Storage.d.ts
vendored
|
@ -175,8 +175,8 @@ export type StorageAccessType = {
|
|||
subscriberCurrencyCode: string;
|
||||
donorSubscriptionManuallyCancelled: boolean;
|
||||
backupsSubscriberId: Uint8Array;
|
||||
backupsSubscriberCurrencyCode: string;
|
||||
backupsSubscriptionManuallyCancelled: boolean;
|
||||
backupsSubscriberPurchaseToken: string;
|
||||
backupsSubscriberOriginalTransactionId: string;
|
||||
displayBadgesOnProfile: boolean;
|
||||
keepMutedChatsArchived: boolean;
|
||||
usernameLastIntegrityCheck: number;
|
||||
|
@ -209,6 +209,9 @@ export type StorageAccessType = {
|
|||
// If true Desktop message history was restored from backup
|
||||
isRestoredFromBackup: boolean;
|
||||
|
||||
// The `firstAppVersion` present on an BackupInfo from an imported backup.
|
||||
restoredBackupFirstAppVersion: string;
|
||||
|
||||
// Deprecated
|
||||
'challenge:retry-message-ids': never;
|
||||
nextSignedKeyRotationTime: number;
|
||||
|
|
75
ts/util/backupSubscriptionData.ts
Normal file
75
ts/util/backupSubscriptionData.ts
Normal file
|
@ -0,0 +1,75 @@
|
|||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import Long from 'long';
|
||||
import type { Backups, SignalService } from '../protobuf';
|
||||
import * as Bytes from '../Bytes';
|
||||
|
||||
// These two proto messages (Backups.AccountData.IIAPSubscriberData &&
|
||||
// SignalService.AccountRecord.IIAPSubscriberData) should remain in sync. If they drift,
|
||||
// we'll need separate logic for each
|
||||
export async function saveBackupsSubscriberData(
|
||||
backupsSubscriberData:
|
||||
| Backups.AccountData.IIAPSubscriberData
|
||||
| SignalService.AccountRecord.IIAPSubscriberData
|
||||
| null
|
||||
| undefined
|
||||
): Promise<void> {
|
||||
if (backupsSubscriberData == null) {
|
||||
await window.storage.remove('backupsSubscriberId');
|
||||
await window.storage.remove('backupsSubscriberPurchaseToken');
|
||||
await window.storage.remove('backupsSubscriberOriginalTransactionId');
|
||||
return;
|
||||
}
|
||||
|
||||
const { subscriberId, purchaseToken, originalTransactionId } =
|
||||
backupsSubscriberData;
|
||||
|
||||
if (Bytes.isNotEmpty(subscriberId)) {
|
||||
await window.storage.put('backupsSubscriberId', subscriberId);
|
||||
} else {
|
||||
await window.storage.remove('backupsSubscriberId');
|
||||
}
|
||||
|
||||
if (purchaseToken) {
|
||||
await window.storage.put('backupsSubscriberPurchaseToken', purchaseToken);
|
||||
} else {
|
||||
await window.storage.remove('backupsSubscriberPurchaseToken');
|
||||
}
|
||||
|
||||
if (originalTransactionId) {
|
||||
await window.storage.put(
|
||||
'backupsSubscriberOriginalTransactionId',
|
||||
originalTransactionId.toString()
|
||||
);
|
||||
} else {
|
||||
await window.storage.remove('backupsSubscriberOriginalTransactionId');
|
||||
}
|
||||
}
|
||||
|
||||
export function generateBackupsSubscriberData(): Backups.AccountData.IIAPSubscriberData | null {
|
||||
const backupsSubscriberId = window.storage.get('backupsSubscriberId');
|
||||
|
||||
if (Bytes.isEmpty(backupsSubscriberId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const backupsSubscriberData: Backups.AccountData.IIAPSubscriberData = {
|
||||
subscriberId: backupsSubscriberId,
|
||||
};
|
||||
const purchaseToken = window.storage.get('backupsSubscriberPurchaseToken');
|
||||
if (purchaseToken) {
|
||||
backupsSubscriberData.purchaseToken = purchaseToken;
|
||||
} else {
|
||||
const originalTransactionId = window.storage.get(
|
||||
'backupsSubscriberOriginalTransactionId'
|
||||
);
|
||||
if (originalTransactionId) {
|
||||
backupsSubscriberData.originalTransactionId = Long.fromString(
|
||||
originalTransactionId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return backupsSubscriberData;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue