Promote fts5 secure-delete to production
This commit is contained in:
parent
47aff178da
commit
79f7d64fb7
7 changed files with 6 additions and 114 deletions
|
@ -52,7 +52,6 @@ import { senderCertificateService } from './services/senderCertificate';
|
||||||
import { GROUP_CREDENTIALS_KEY } from './services/groupCredentialFetcher';
|
import { GROUP_CREDENTIALS_KEY } from './services/groupCredentialFetcher';
|
||||||
import * as KeyboardLayout from './services/keyboardLayout';
|
import * as KeyboardLayout from './services/keyboardLayout';
|
||||||
import * as StorageService from './services/storage';
|
import * as StorageService from './services/storage';
|
||||||
import { optimizeFTS } from './services/ftsOptimizer';
|
|
||||||
import { RoutineProfileRefresher } from './routineProfileRefresh';
|
import { RoutineProfileRefresher } from './routineProfileRefresh';
|
||||||
import { isOlderThan, toDayMillis } from './util/timestamp';
|
import { isOlderThan, toDayMillis } from './util/timestamp';
|
||||||
import { isValidReactionEmoji } from './reactions/isValidReactionEmoji';
|
import { isValidReactionEmoji } from './reactions/isValidReactionEmoji';
|
||||||
|
@ -982,8 +981,6 @@ export async function startApp(): Promise<void> {
|
||||||
if (newVersion) {
|
if (newVersion) {
|
||||||
await window.Signal.Data.cleanupOrphanedAttachments();
|
await window.Signal.Data.cleanupOrphanedAttachments();
|
||||||
|
|
||||||
optimizeFTS();
|
|
||||||
|
|
||||||
drop(window.Signal.Data.ensureFilePermissions());
|
drop(window.Signal.Data.ensureFilePermissions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,6 @@ import {
|
||||||
notificationService,
|
notificationService,
|
||||||
} from '../services/notifications';
|
} from '../services/notifications';
|
||||||
import { storageServiceUploadJob } from '../services/storage';
|
import { storageServiceUploadJob } from '../services/storage';
|
||||||
import { scheduleOptimizeFTS } from '../services/ftsOptimizer';
|
|
||||||
import { getSendOptions } from '../util/getSendOptions';
|
import { getSendOptions } from '../util/getSendOptions';
|
||||||
import { isConversationAccepted } from '../util/isConversationAccepted';
|
import { isConversationAccepted } from '../util/isConversationAccepted';
|
||||||
import {
|
import {
|
||||||
|
@ -4864,8 +4863,6 @@ export class ConversationModel extends window.Backbone
|
||||||
await window.Signal.Data.removeAllMessagesInConversation(this.id, {
|
await window.Signal.Data.removeAllMessagesInConversation(this.id, {
|
||||||
logId: this.idForLogging(),
|
logId: this.idForLogging(),
|
||||||
});
|
});
|
||||||
|
|
||||||
scheduleOptimizeFTS();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getTitle(options?: { isShort?: boolean }): string {
|
getTitle(options?: { isShort?: boolean }): string {
|
||||||
|
|
|
@ -65,7 +65,6 @@ import { migrateLegacyReadStatus } from '../messages/migrateLegacyReadStatus';
|
||||||
import { migrateLegacySendAttributes } from '../messages/migrateLegacySendAttributes';
|
import { migrateLegacySendAttributes } from '../messages/migrateLegacySendAttributes';
|
||||||
import { getOwn } from '../util/getOwn';
|
import { getOwn } from '../util/getOwn';
|
||||||
import { markRead, markViewed } from '../services/MessageUpdater';
|
import { markRead, markViewed } from '../services/MessageUpdater';
|
||||||
import { scheduleOptimizeFTS } from '../services/ftsOptimizer';
|
|
||||||
import {
|
import {
|
||||||
isDirectConversation,
|
isDirectConversation,
|
||||||
isGroup,
|
isGroup,
|
||||||
|
@ -579,8 +578,6 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
await window.Signal.Data.deleteSentProtoByMessageId(this.id);
|
await window.Signal.Data.deleteSentProtoByMessageId(this.id);
|
||||||
|
|
||||||
scheduleOptimizeFTS();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override isEmpty(): boolean {
|
override isEmpty(): boolean {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
|
||||||
import { sleep } from '../util/sleep';
|
import { sleep } from '../util/sleep';
|
||||||
import { SECOND } from '../util/durations';
|
import { SECOND } from '../util/durations';
|
||||||
import * as Errors from '../types/errors';
|
import * as Errors from '../types/errors';
|
||||||
import { scheduleOptimizeFTS } from './ftsOptimizer';
|
|
||||||
|
|
||||||
class ExpiringMessagesDeletionService {
|
class ExpiringMessagesDeletionService {
|
||||||
public update: typeof this.checkExpiringMessages;
|
public update: typeof this.checkExpiringMessages;
|
||||||
|
@ -56,10 +55,6 @@ class ExpiringMessagesDeletionService {
|
||||||
window.reduxActions.conversations.messageExpired(message.id);
|
window.reduxActions.conversations.messageExpired(message.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (messages.length > 0) {
|
|
||||||
scheduleOptimizeFTS();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.SignalContext.log.error(
|
window.SignalContext.log.error(
|
||||||
'destroyExpiredMessages: Error deleting expired messages',
|
'destroyExpiredMessages: Error deleting expired messages',
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
// Copyright 2023 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
import { debounce } from 'lodash';
|
|
||||||
|
|
||||||
import { SECOND } from '../util/durations';
|
|
||||||
import { sleep } from '../util/sleep';
|
|
||||||
import { drop } from '../util/drop';
|
|
||||||
import { isProduction } from '../util/version';
|
|
||||||
import dataInterface from '../sql/Client';
|
|
||||||
import type { FTSOptimizationStateType } from '../sql/Interface';
|
|
||||||
import * as log from '../logging/log';
|
|
||||||
|
|
||||||
const INTERACTIVITY_DELAY_MS = 50;
|
|
||||||
|
|
||||||
class FTSOptimizer {
|
|
||||||
private isRunning = false;
|
|
||||||
|
|
||||||
public async run(): Promise<void> {
|
|
||||||
if (!isProduction(window.getVersion())) {
|
|
||||||
log.info('ftsOptimizer: not running when not in production');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isRunning) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.isRunning = true;
|
|
||||||
|
|
||||||
log.info('ftsOptimizer: starting');
|
|
||||||
|
|
||||||
let state: FTSOptimizationStateType | undefined;
|
|
||||||
|
|
||||||
const start = Date.now();
|
|
||||||
|
|
||||||
try {
|
|
||||||
do {
|
|
||||||
if (state !== undefined) {
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
|
||||||
await sleep(INTERACTIVITY_DELAY_MS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
|
||||||
state = await dataInterface.optimizeFTS(state);
|
|
||||||
} while (!state?.done);
|
|
||||||
} finally {
|
|
||||||
this.isRunning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const duration = Date.now() - start;
|
|
||||||
|
|
||||||
if (!state) {
|
|
||||||
log.warn('ftsOptimizer: no final state');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info(`ftsOptimizer: took ${duration}ms and ${state.steps} steps`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const optimizer = new FTSOptimizer();
|
|
||||||
|
|
||||||
export const optimizeFTS = (): void => {
|
|
||||||
drop(optimizer.run());
|
|
||||||
};
|
|
||||||
|
|
||||||
export const scheduleOptimizeFTS = debounce(optimizeFTS, SECOND, {
|
|
||||||
maxWait: 5 * SECOND,
|
|
||||||
});
|
|
|
@ -577,7 +577,6 @@ SQL.setLogHandler((code, value) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
async function initialize({
|
async function initialize({
|
||||||
appVersion,
|
|
||||||
configDir,
|
configDir,
|
||||||
key,
|
key,
|
||||||
logger: suppliedLogger,
|
logger: suppliedLogger,
|
||||||
|
@ -619,7 +618,7 @@ async function initialize({
|
||||||
// For profiling use:
|
// For profiling use:
|
||||||
// db.pragma('cipher_profile=\'sqlcipher.log\'');
|
// db.pragma('cipher_profile=\'sqlcipher.log\'');
|
||||||
|
|
||||||
updateSchema(writable, logger, appVersion);
|
updateSchema(writable, logger);
|
||||||
|
|
||||||
readonly = openAndSetUpSQLCipher(databaseFilePath, { key, readonly: true });
|
readonly = openAndSetUpSQLCipher(databaseFilePath, { key, readonly: true });
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { keyBy } from 'lodash';
|
||||||
import { v4 as generateUuid } from 'uuid';
|
import { v4 as generateUuid } from 'uuid';
|
||||||
|
|
||||||
import type { LoggerType } from '../../types/Logging';
|
import type { LoggerType } from '../../types/Logging';
|
||||||
import { isProduction } from '../../util/version';
|
|
||||||
import {
|
import {
|
||||||
getSchemaVersion,
|
getSchemaVersion,
|
||||||
getUserVersion,
|
getUserVersion,
|
||||||
|
@ -2020,11 +2019,7 @@ export class DBVersionFromFutureError extends Error {
|
||||||
override name = 'DBVersionFromFutureError';
|
override name = 'DBVersionFromFutureError';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function lazyFTS5SecureDelete(
|
export function enableFTS5SecureDelete(db: Database, logger: LoggerType): void {
|
||||||
db: Database,
|
|
||||||
logger: LoggerType,
|
|
||||||
enabled: boolean
|
|
||||||
): void {
|
|
||||||
const isEnabled =
|
const isEnabled =
|
||||||
db
|
db
|
||||||
.prepare(
|
.prepare(
|
||||||
|
@ -2035,23 +2030,8 @@ export function lazyFTS5SecureDelete(
|
||||||
.pluck()
|
.pluck()
|
||||||
.get() === 1;
|
.get() === 1;
|
||||||
|
|
||||||
if (isEnabled && !enabled) {
|
if (!isEnabled) {
|
||||||
logger.info('lazyFTS5SecureDelete: disabling, rebuilding fts5 index');
|
logger.info('enableFTS5SecureDelete: enabling');
|
||||||
db.exec(`
|
|
||||||
-- Disable secure-delete
|
|
||||||
INSERT INTO messages_fts
|
|
||||||
(messages_fts, rank)
|
|
||||||
VALUES
|
|
||||||
('secure-delete', 0);
|
|
||||||
|
|
||||||
--- Rebuild the index to fix the corruption
|
|
||||||
INSERT INTO messages_fts
|
|
||||||
(messages_fts)
|
|
||||||
VALUES
|
|
||||||
('rebuild');
|
|
||||||
`);
|
|
||||||
} else if (!isEnabled && enabled) {
|
|
||||||
logger.info('lazyFTS5SecureDelete: enabling');
|
|
||||||
db.exec(`
|
db.exec(`
|
||||||
-- Enable secure-delete
|
-- Enable secure-delete
|
||||||
INSERT INTO messages_fts
|
INSERT INTO messages_fts
|
||||||
|
@ -2062,11 +2042,7 @@ export function lazyFTS5SecureDelete(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateSchema(
|
export function updateSchema(db: Database, logger: LoggerType): void {
|
||||||
db: Database,
|
|
||||||
logger: LoggerType,
|
|
||||||
appVersion: string
|
|
||||||
): void {
|
|
||||||
const sqliteVersion = getSQLiteVersion(db);
|
const sqliteVersion = getSQLiteVersion(db);
|
||||||
const sqlcipherVersion = getSQLCipherVersion(db);
|
const sqlcipherVersion = getSQLCipherVersion(db);
|
||||||
const startingVersion = getUserVersion(db);
|
const startingVersion = getUserVersion(db);
|
||||||
|
@ -2094,7 +2070,7 @@ export function updateSchema(
|
||||||
runSchemaUpdate(startingVersion, db, logger);
|
runSchemaUpdate(startingVersion, db, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
lazyFTS5SecureDelete(db, logger, !isProduction(appVersion));
|
enableFTS5SecureDelete(db, logger);
|
||||||
|
|
||||||
if (startingVersion !== MAX_VERSION) {
|
if (startingVersion !== MAX_VERSION) {
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue