Update message reporting to use sender ACI instead of E164
This commit is contained in:
parent
8f630a52b5
commit
2f5e4f1b98
7 changed files with 129 additions and 13 deletions
|
@ -22,10 +22,10 @@ export async function addReportSpamJob({
|
||||||
'addReportSpamJob: cannot report spam for non-direct conversations'
|
'addReportSpamJob: cannot report spam for non-direct conversations'
|
||||||
);
|
);
|
||||||
|
|
||||||
const { e164 } = conversation;
|
const { uuid } = conversation;
|
||||||
if (!e164) {
|
if (!uuid) {
|
||||||
log.info(
|
log.info(
|
||||||
'addReportSpamJob got a conversation with no E164, which the server does not support. Doing nothing'
|
'addReportSpamJob got a conversation with no UUID, which the server does not support. Doing nothing'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -41,5 +41,5 @@ export async function addReportSpamJob({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await jobQueue.add({ e164, serverGuids });
|
await jobQueue.add({ uuid, serverGuids });
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ const isRetriable4xxStatus = (code: number): boolean =>
|
||||||
RETRYABLE_4XX_FAILURE_STATUSES.has(code);
|
RETRYABLE_4XX_FAILURE_STATUSES.has(code);
|
||||||
|
|
||||||
const reportSpamJobDataSchema = z.object({
|
const reportSpamJobDataSchema = z.object({
|
||||||
e164: z.string().min(1),
|
uuid: z.string().min(1),
|
||||||
serverGuids: z.string().array().min(1).max(1000),
|
serverGuids: z.string().array().min(1).max(1000),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ export class ReportSpamJobQueue extends JobQueue<ReportSpamJobData> {
|
||||||
{ data }: Readonly<{ data: ReportSpamJobData }>,
|
{ data }: Readonly<{ data: ReportSpamJobData }>,
|
||||||
{ log }: Readonly<{ log: LoggerType }>
|
{ log }: Readonly<{ log: LoggerType }>
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { e164, serverGuids } = data;
|
const { uuid, serverGuids } = data;
|
||||||
|
|
||||||
await new Promise<void>(resolve => {
|
await new Promise<void>(resolve => {
|
||||||
window.storage.onready(resolve);
|
window.storage.onready(resolve);
|
||||||
|
@ -66,7 +66,7 @@ export class ReportSpamJobQueue extends JobQueue<ReportSpamJobData> {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
map(serverGuids, serverGuid => server.reportMessage(e164, serverGuid))
|
map(serverGuids, serverGuid => server.reportMessage(uuid, serverGuid))
|
||||||
);
|
);
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (!(err instanceof HTTPError)) {
|
if (!(err instanceof HTTPError)) {
|
||||||
|
|
68
ts/sql/migrations/55-report-message-aci.ts
Normal file
68
ts/sql/migrations/55-report-message-aci.ts
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright 2022 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import type { Database } from 'better-sqlite3';
|
||||||
|
import type { LoggerType } from '../../types/Logging';
|
||||||
|
import { getJobsInQueueSync, insertJobSync } from '../Server';
|
||||||
|
import { isRecord } from '../../util/isRecord';
|
||||||
|
import { isIterable } from '../../util/iterables';
|
||||||
|
|
||||||
|
export default function updateToSchemaVersion55(
|
||||||
|
currentVersion: number,
|
||||||
|
db: Database,
|
||||||
|
logger: LoggerType
|
||||||
|
): void {
|
||||||
|
if (currentVersion >= 55) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.transaction(() => {
|
||||||
|
const deleteJobsInQueue = db.prepare(
|
||||||
|
'DELETE FROM jobs WHERE queueType = $queueType'
|
||||||
|
);
|
||||||
|
|
||||||
|
// First, make sure that report spam job data has e164 and serverGuids
|
||||||
|
const reportSpamJobs = getJobsInQueueSync(db, 'report spam');
|
||||||
|
deleteJobsInQueue.run({ queueType: 'report spam' });
|
||||||
|
|
||||||
|
reportSpamJobs.forEach(job => {
|
||||||
|
const { data, id } = job;
|
||||||
|
|
||||||
|
if (!isRecord(data)) {
|
||||||
|
logger.warn(
|
||||||
|
`updateToSchemaVersion55: report spam queue job ${id} was missing valid data`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { e164, serverGuids } = data;
|
||||||
|
if (typeof e164 !== 'string') {
|
||||||
|
logger.warn(
|
||||||
|
`updateToSchemaVersion55: report spam queue job ${id} had a non-string e164`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isIterable(serverGuids)) {
|
||||||
|
logger.warn(
|
||||||
|
`updateToSchemaVersion55: report spam queue job ${id} had a non-iterable serverGuids`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newJob = {
|
||||||
|
...job,
|
||||||
|
queueType: 'report spam',
|
||||||
|
data: {
|
||||||
|
uuid: e164, // this looks odd, but they are both strings and interchangeable in the server API
|
||||||
|
serverGuids,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
insertJobSync(db, newJob);
|
||||||
|
});
|
||||||
|
|
||||||
|
db.pragma('user_version = 55');
|
||||||
|
})();
|
||||||
|
logger.info('updateToSchemaVersion55: success!');
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ import updateToSchemaVersion51 from './51-centralize-conversation-jobs';
|
||||||
import updateToSchemaVersion52 from './52-optimize-stories';
|
import updateToSchemaVersion52 from './52-optimize-stories';
|
||||||
import updateToSchemaVersion53 from './53-gv2-banned-members';
|
import updateToSchemaVersion53 from './53-gv2-banned-members';
|
||||||
import updateToSchemaVersion54 from './54-unprocessed-received-at-counter';
|
import updateToSchemaVersion54 from './54-unprocessed-received-at-counter';
|
||||||
|
import updateToSchemaVersion55 from './55-report-message-aci';
|
||||||
|
|
||||||
function updateToSchemaVersion1(
|
function updateToSchemaVersion1(
|
||||||
currentVersion: number,
|
currentVersion: number,
|
||||||
|
@ -1923,6 +1924,7 @@ export const SCHEMA_VERSIONS = [
|
||||||
updateToSchemaVersion52,
|
updateToSchemaVersion52,
|
||||||
updateToSchemaVersion53,
|
updateToSchemaVersion53,
|
||||||
updateToSchemaVersion54,
|
updateToSchemaVersion54,
|
||||||
|
updateToSchemaVersion55,
|
||||||
];
|
];
|
||||||
|
|
||||||
export function updateSchema(db: Database, logger: LoggerType): void {
|
export function updateSchema(db: Database, logger: LoggerType): void {
|
||||||
|
|
|
@ -29,9 +29,9 @@ describe('addReportSpamJob', () => {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does nothing if the conversation lacks an E164', async () => {
|
it('does nothing if the conversation lacks a UUID', async () => {
|
||||||
await addReportSpamJob({
|
await addReportSpamJob({
|
||||||
conversation: getDefaultConversation({ e164: undefined }),
|
conversation: getDefaultConversation({ uuid: undefined }),
|
||||||
getMessageServerGuidsForSpam,
|
getMessageServerGuidsForSpam,
|
||||||
jobQueue,
|
jobQueue,
|
||||||
});
|
});
|
||||||
|
@ -66,7 +66,7 @@ describe('addReportSpamJob', () => {
|
||||||
|
|
||||||
sinon.assert.calledOnce(jobQueue.add);
|
sinon.assert.calledOnce(jobQueue.add);
|
||||||
sinon.assert.calledWith(jobQueue.add, {
|
sinon.assert.calledWith(jobQueue.add, {
|
||||||
e164: conversation.e164,
|
uuid: conversation.uuid,
|
||||||
serverGuids: ['abc', 'xyz'],
|
serverGuids: ['abc', 'xyz'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1726,4 +1726,50 @@ describe('SQL migrations test', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('updateToSchemaVersion55', () => {
|
||||||
|
it('moves existing report spam jobs to new schema', () => {
|
||||||
|
updateToVersion(54);
|
||||||
|
|
||||||
|
const E164_1 = '+12125550155';
|
||||||
|
const MESSAGE_ID_1 = generateGuid();
|
||||||
|
|
||||||
|
db.exec(
|
||||||
|
`
|
||||||
|
INSERT INTO jobs
|
||||||
|
(id, timestamp, queueType, data)
|
||||||
|
VALUES
|
||||||
|
('id-1', 1, 'random job', '{}'),
|
||||||
|
('id-2', 2, 'report spam', '{"serverGuids": ["${MESSAGE_ID_1}"], "e164": "${E164_1}"}');
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
const totalJobs = db.prepare('SELECT COUNT(*) FROM jobs;').pluck();
|
||||||
|
const reportSpamJobs = db
|
||||||
|
.prepare("SELECT COUNT(*) FROM jobs WHERE queueType = 'report spam';")
|
||||||
|
.pluck();
|
||||||
|
|
||||||
|
assert.strictEqual(totalJobs.get(), 2, 'before total');
|
||||||
|
assert.strictEqual(reportSpamJobs.get(), 1, 'before report spam');
|
||||||
|
|
||||||
|
updateToVersion(55);
|
||||||
|
|
||||||
|
assert.strictEqual(totalJobs.get(), 2, 'after total');
|
||||||
|
assert.strictEqual(reportSpamJobs.get(), 1, 'after report spam');
|
||||||
|
|
||||||
|
const jobs = getJobsInQueueSync(db, 'report spam');
|
||||||
|
|
||||||
|
assert.deepEqual(jobs, [
|
||||||
|
{
|
||||||
|
id: 'id-2',
|
||||||
|
queueType: 'report spam',
|
||||||
|
timestamp: 2,
|
||||||
|
data: {
|
||||||
|
serverGuids: [`${MESSAGE_ID_1}`],
|
||||||
|
uuid: `${E164_1}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -918,7 +918,7 @@ export type WebAPIType = {
|
||||||
registerCapabilities: (capabilities: CapabilitiesUploadType) => Promise<void>;
|
registerCapabilities: (capabilities: CapabilitiesUploadType) => Promise<void>;
|
||||||
registerKeys: (genKeys: KeysType, uuidKind: UUIDKind) => Promise<void>;
|
registerKeys: (genKeys: KeysType, uuidKind: UUIDKind) => Promise<void>;
|
||||||
registerSupportForUnauthenticatedDelivery: () => Promise<void>;
|
registerSupportForUnauthenticatedDelivery: () => Promise<void>;
|
||||||
reportMessage: (senderE164: string, serverGuid: string) => Promise<void>;
|
reportMessage: (senderUuid: string, serverGuid: string) => Promise<void>;
|
||||||
requestVerificationSMS: (number: string, token: string) => Promise<void>;
|
requestVerificationSMS: (number: string, token: string) => Promise<void>;
|
||||||
requestVerificationVoice: (number: string, token: string) => Promise<void>;
|
requestVerificationVoice: (number: string, token: string) => Promise<void>;
|
||||||
checkAccountExistence: (uuid: UUID) => Promise<boolean>;
|
checkAccountExistence: (uuid: UUID) => Promise<boolean>;
|
||||||
|
@ -1663,13 +1663,13 @@ export function initialize({
|
||||||
}
|
}
|
||||||
|
|
||||||
async function reportMessage(
|
async function reportMessage(
|
||||||
senderE164: string,
|
senderUuid: string,
|
||||||
serverGuid: string
|
serverGuid: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await _ajax({
|
await _ajax({
|
||||||
call: 'reportMessage',
|
call: 'reportMessage',
|
||||||
httpType: 'POST',
|
httpType: 'POST',
|
||||||
urlParameters: `/${senderE164}/${serverGuid}`,
|
urlParameters: `/${senderUuid}/${serverGuid}`,
|
||||||
responseType: 'bytes',
|
responseType: 'bytes',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue