Use esbuild
This commit is contained in:
parent
3c1ccce9bd
commit
0174687542
25 changed files with 528 additions and 906 deletions
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// Copyright 2020-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { RequestInit, Response } from 'node-fetch';
|
||||
|
@ -13,6 +13,7 @@ import {
|
|||
IMAGE_WEBP,
|
||||
stringToMIMEType,
|
||||
} from '../types/MIME';
|
||||
import type { LoggerType } from '../types/Logging';
|
||||
import * as log from '../logging/log';
|
||||
|
||||
const USER_AGENT = 'WhatsApp/2';
|
||||
|
@ -76,14 +77,15 @@ type ParsedContentType =
|
|||
async function fetchWithRedirects(
|
||||
fetchFn: FetchFn,
|
||||
href: string,
|
||||
options: RequestInit
|
||||
options: RequestInit,
|
||||
logger: Pick<LoggerType, 'warn'> = log
|
||||
): Promise<Response> {
|
||||
const urlsSeen = new Set<string>();
|
||||
|
||||
let nextHrefToLoad = href;
|
||||
for (let i = 0; i < MAX_REQUEST_COUNT_WITH_REDIRECTS; i += 1) {
|
||||
if (urlsSeen.has(nextHrefToLoad)) {
|
||||
log.warn('fetchWithRedirects: found a redirect loop');
|
||||
logger.warn('fetchWithRedirects: found a redirect loop');
|
||||
throw new Error('redirect loop');
|
||||
}
|
||||
urlsSeen.add(nextHrefToLoad);
|
||||
|
@ -101,7 +103,7 @@ async function fetchWithRedirects(
|
|||
|
||||
const location = response.headers.get('location');
|
||||
if (!location) {
|
||||
log.warn(
|
||||
logger.warn(
|
||||
'fetchWithRedirects: got a redirect status code but no Location header; bailing'
|
||||
);
|
||||
throw new Error('no location with redirect');
|
||||
|
@ -109,7 +111,7 @@ async function fetchWithRedirects(
|
|||
|
||||
const newUrl = maybeParseUrl(location, nextHrefToLoad);
|
||||
if (newUrl?.protocol !== 'https:') {
|
||||
log.warn(
|
||||
logger.warn(
|
||||
'fetchWithRedirects: got a redirect status code and an invalid Location header'
|
||||
);
|
||||
throw new Error('invalid location');
|
||||
|
@ -118,7 +120,7 @@ async function fetchWithRedirects(
|
|||
nextHrefToLoad = newUrl.href;
|
||||
}
|
||||
|
||||
log.warn('fetchWithRedirects: too many redirects');
|
||||
logger.warn('fetchWithRedirects: too many redirects');
|
||||
throw new Error('too many redirects');
|
||||
}
|
||||
|
||||
|
@ -284,7 +286,8 @@ const parseHtmlBytes = (
|
|||
const getHtmlDocument = async (
|
||||
body: AsyncIterable<string | Uint8Array>,
|
||||
httpCharset: string | null,
|
||||
abortSignal: AbortSignal
|
||||
abortSignal: AbortSignal,
|
||||
logger: Pick<LoggerType, 'warn'> = log
|
||||
): Promise<HTMLDocument> => {
|
||||
let result: HTMLDocument = emptyHtmlDocument();
|
||||
|
||||
|
@ -317,7 +320,7 @@ const getHtmlDocument = async (
|
|||
}
|
||||
}
|
||||
} catch (err) {
|
||||
log.warn(
|
||||
logger.warn(
|
||||
'getHtmlDocument: error when reading body; continuing with what we got'
|
||||
);
|
||||
}
|
||||
|
@ -361,12 +364,13 @@ const getLinkHrefAttribute = (
|
|||
|
||||
const parseMetadata = (
|
||||
document: HTMLDocument,
|
||||
href: string
|
||||
href: string,
|
||||
logger: Pick<LoggerType, 'warn'> = log
|
||||
): LinkPreviewMetadata | null => {
|
||||
const title =
|
||||
getOpenGraphContent(document, ['og:title']) || document.title.trim();
|
||||
if (!title) {
|
||||
log.warn("parseMetadata: HTML document doesn't have a title; bailing");
|
||||
logger.warn("parseMetadata: HTML document doesn't have a title; bailing");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -431,40 +435,46 @@ const parseMetadata = (
|
|||
export async function fetchLinkPreviewMetadata(
|
||||
fetchFn: FetchFn,
|
||||
href: string,
|
||||
abortSignal: AbortSignal
|
||||
abortSignal: AbortSignal,
|
||||
logger: Pick<LoggerType, 'warn'> = log
|
||||
): Promise<null | LinkPreviewMetadata> {
|
||||
let response: Response;
|
||||
try {
|
||||
response = await fetchWithRedirects(fetchFn, href, {
|
||||
headers: {
|
||||
Accept: 'text/html,application/xhtml+xml',
|
||||
'User-Agent': USER_AGENT,
|
||||
response = await fetchWithRedirects(
|
||||
fetchFn,
|
||||
href,
|
||||
{
|
||||
headers: {
|
||||
Accept: 'text/html,application/xhtml+xml',
|
||||
'User-Agent': USER_AGENT,
|
||||
},
|
||||
signal: abortSignal as AbortSignalForNodeFetch,
|
||||
},
|
||||
signal: abortSignal as AbortSignalForNodeFetch,
|
||||
});
|
||||
logger
|
||||
);
|
||||
} catch (err) {
|
||||
log.warn(
|
||||
logger.warn(
|
||||
'fetchLinkPreviewMetadata: failed to fetch link preview HTML; bailing'
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
log.warn(
|
||||
logger.warn(
|
||||
`fetchLinkPreviewMetadata: got a ${response.status} status code; bailing`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!response.body) {
|
||||
log.warn('fetchLinkPreviewMetadata: no response body; bailing');
|
||||
logger.warn('fetchLinkPreviewMetadata: no response body; bailing');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
!isInlineContentDisposition(response.headers.get('Content-Disposition'))
|
||||
) {
|
||||
log.warn(
|
||||
logger.warn(
|
||||
'fetchLinkPreviewMetadata: Content-Disposition header is not inline; bailing'
|
||||
);
|
||||
return null;
|
||||
|
@ -478,20 +488,23 @@ export async function fetchLinkPreviewMetadata(
|
|||
response.headers.get('Content-Length')
|
||||
);
|
||||
if (contentLength < MIN_HTML_CONTENT_LENGTH) {
|
||||
log.warn('fetchLinkPreviewMetadata: Content-Length is too short; bailing');
|
||||
logger.warn(
|
||||
'fetchLinkPreviewMetadata: Content-Length is too short; bailing'
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const contentType = parseContentType(response.headers.get('Content-Type'));
|
||||
if (contentType.type !== 'text/html') {
|
||||
log.warn('fetchLinkPreviewMetadata: Content-Type is not HTML; bailing');
|
||||
logger.warn('fetchLinkPreviewMetadata: Content-Type is not HTML; bailing');
|
||||
return null;
|
||||
}
|
||||
|
||||
const document = await getHtmlDocument(
|
||||
response.body,
|
||||
contentType.charset,
|
||||
abortSignal
|
||||
abortSignal,
|
||||
logger
|
||||
);
|
||||
|
||||
// [The Node docs about `ReadableStream.prototype[Symbol.asyncIterator]`][0] say that
|
||||
|
@ -511,7 +524,7 @@ export async function fetchLinkPreviewMetadata(
|
|||
return null;
|
||||
}
|
||||
|
||||
return parseMetadata(document, response.url);
|
||||
return parseMetadata(document, response.url, logger);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -523,19 +536,25 @@ export async function fetchLinkPreviewMetadata(
|
|||
export async function fetchLinkPreviewImage(
|
||||
fetchFn: FetchFn,
|
||||
href: string,
|
||||
abortSignal: AbortSignal
|
||||
abortSignal: AbortSignal,
|
||||
logger: Pick<LoggerType, 'warn'> = log
|
||||
): Promise<null | LinkPreviewImage> {
|
||||
let response: Response;
|
||||
try {
|
||||
response = await fetchWithRedirects(fetchFn, href, {
|
||||
headers: {
|
||||
'User-Agent': USER_AGENT,
|
||||
response = await fetchWithRedirects(
|
||||
fetchFn,
|
||||
href,
|
||||
{
|
||||
headers: {
|
||||
'User-Agent': USER_AGENT,
|
||||
},
|
||||
size: MAX_IMAGE_CONTENT_LENGTH,
|
||||
signal: abortSignal as AbortSignalForNodeFetch,
|
||||
},
|
||||
size: MAX_IMAGE_CONTENT_LENGTH,
|
||||
signal: abortSignal as AbortSignalForNodeFetch,
|
||||
});
|
||||
logger
|
||||
);
|
||||
} catch (err) {
|
||||
log.warn('fetchLinkPreviewImage: failed to fetch image; bailing');
|
||||
logger.warn('fetchLinkPreviewImage: failed to fetch image; bailing');
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -544,7 +563,7 @@ export async function fetchLinkPreviewImage(
|
|||
}
|
||||
|
||||
if (!response.ok) {
|
||||
log.warn(
|
||||
logger.warn(
|
||||
`fetchLinkPreviewImage: got a ${response.status} status code; bailing`
|
||||
);
|
||||
return null;
|
||||
|
@ -554,11 +573,11 @@ export async function fetchLinkPreviewImage(
|
|||
response.headers.get('Content-Length')
|
||||
);
|
||||
if (contentLength < MIN_IMAGE_CONTENT_LENGTH) {
|
||||
log.warn('fetchLinkPreviewImage: Content-Length is too short; bailing');
|
||||
logger.warn('fetchLinkPreviewImage: Content-Length is too short; bailing');
|
||||
return null;
|
||||
}
|
||||
if (contentLength > MAX_IMAGE_CONTENT_LENGTH) {
|
||||
log.warn(
|
||||
logger.warn(
|
||||
'fetchLinkPreviewImage: Content-Length is too large or is unset; bailing'
|
||||
);
|
||||
return null;
|
||||
|
@ -568,7 +587,7 @@ export async function fetchLinkPreviewImage(
|
|||
response.headers.get('Content-Type')
|
||||
);
|
||||
if (!contentType || !VALID_IMAGE_MIME_TYPES.has(contentType)) {
|
||||
log.warn('fetchLinkPreviewImage: Content-Type is not an image; bailing');
|
||||
logger.warn('fetchLinkPreviewImage: Content-Type is not an image; bailing');
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -576,7 +595,7 @@ export async function fetchLinkPreviewImage(
|
|||
try {
|
||||
data = await response.buffer();
|
||||
} catch (err) {
|
||||
log.warn('fetchLinkPreviewImage: failed to read body; bailing');
|
||||
logger.warn('fetchLinkPreviewImage: failed to read body; bailing');
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// Copyright 2021-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { isNil, sortBy } from 'lodash';
|
||||
|
@ -12,8 +12,7 @@ import { take } from './util/iterables';
|
|||
import { isOlderThan } from './util/timestamp';
|
||||
import type { ConversationModel } from './models/conversations';
|
||||
import type { StorageInterface } from './types/Storage.d';
|
||||
// Imported this way so that sinon.sandbox can stub this properly
|
||||
import * as profileGetter from './util/getProfile';
|
||||
import { getProfile } from './util/getProfile';
|
||||
|
||||
const STORAGE_KEY = 'lastAttemptedToRefreshProfilesAt';
|
||||
const MAX_AGE_TO_BE_CONSIDERED_ACTIVE = 30 * 24 * 60 * 60 * 1000;
|
||||
|
@ -25,10 +24,14 @@ export async function routineProfileRefresh({
|
|||
allConversations,
|
||||
ourConversationId,
|
||||
storage,
|
||||
|
||||
// Only for tests
|
||||
getProfileFn = getProfile,
|
||||
}: {
|
||||
allConversations: Array<ConversationModel>;
|
||||
ourConversationId: string;
|
||||
storage: Pick<StorageInterface, 'get' | 'put'>;
|
||||
getProfileFn?: typeof getProfile;
|
||||
}): Promise<void> {
|
||||
log.info('routineProfileRefresh: starting');
|
||||
|
||||
|
@ -59,10 +62,7 @@ export async function routineProfileRefresh({
|
|||
|
||||
totalCount += 1;
|
||||
try {
|
||||
await profileGetter.getProfile(
|
||||
conversation.get('uuid'),
|
||||
conversation.get('e164')
|
||||
);
|
||||
await getProfileFn(conversation.get('uuid'), conversation.get('e164'));
|
||||
log.info(
|
||||
`routineProfileRefresh: refreshed profile for ${conversation.idForLogging()}`
|
||||
);
|
||||
|
|
|
@ -1439,7 +1439,9 @@ function conversationUnloaded(id: string): ConversationUnloadedActionType {
|
|||
};
|
||||
}
|
||||
|
||||
function createGroup(): ThunkAction<
|
||||
function createGroup(
|
||||
createGroupV2 = groups.createGroupV2
|
||||
): ThunkAction<
|
||||
void,
|
||||
RootStateType,
|
||||
unknown,
|
||||
|
@ -1461,7 +1463,7 @@ function createGroup(): ThunkAction<
|
|||
dispatch({ type: 'CREATE_GROUP_PENDING' });
|
||||
|
||||
try {
|
||||
const conversation = await groups.createGroupV2({
|
||||
const conversation = await createGroupV2({
|
||||
name: composer.groupName.trim(),
|
||||
avatar: composer.groupAvatar,
|
||||
avatars: composer.userAvatarData.map(avatarData =>
|
||||
|
|
|
@ -1,34 +1,19 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// Copyright 2021-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import * as sinon from 'sinon';
|
||||
import { times } from 'lodash';
|
||||
import * as remoteConfig from '../../RemoteConfig';
|
||||
import { updateRemoteConfig } from '../helpers/RemoteConfigStub';
|
||||
import { UUID } from '../../types/UUID';
|
||||
|
||||
import { isConversationTooBigToRing } from '../../conversations/isConversationTooBigToRing';
|
||||
|
||||
const CONFIG_KEY = 'global.calling.maxGroupCallRingSize';
|
||||
|
||||
describe('isConversationTooBigToRing', () => {
|
||||
let sinonSandbox: sinon.SinonSandbox;
|
||||
let getMaxGroupCallRingSizeStub: sinon.SinonStub;
|
||||
|
||||
beforeEach(() => {
|
||||
sinonSandbox = sinon.createSandbox();
|
||||
|
||||
const getValueStub = sinonSandbox.stub(remoteConfig, 'getValue');
|
||||
getMaxGroupCallRingSizeStub = getValueStub.withArgs(
|
||||
'global.calling.maxGroupCallRingSize'
|
||||
);
|
||||
});
|
||||
|
||||
const fakeMemberships = (count: number) =>
|
||||
times(count, () => ({ uuid: UUID.generate().toString(), isAdmin: false }));
|
||||
|
||||
afterEach(() => {
|
||||
sinonSandbox.restore();
|
||||
});
|
||||
|
||||
it('returns false if there are no memberships (i.e., for a direct conversation)', () => {
|
||||
assert.isFalse(isConversationTooBigToRing({}));
|
||||
assert.isFalse(isConversationTooBigToRing({ memberships: [] }));
|
||||
|
@ -45,17 +30,20 @@ describe('isConversationTooBigToRing', () => {
|
|||
}
|
||||
};
|
||||
|
||||
it('returns whether there are 16 or more people in the group, if there is nothing in remote config', () => {
|
||||
it('returns whether there are 16 or more people in the group, if there is nothing in remote config', async () => {
|
||||
await updateRemoteConfig([]);
|
||||
textMaximum(16);
|
||||
});
|
||||
|
||||
it('returns whether there are 16 or more people in the group, if the remote config value is bogus', () => {
|
||||
getMaxGroupCallRingSizeStub.returns('uh oh');
|
||||
it('returns whether there are 16 or more people in the group, if the remote config value is bogus', async () => {
|
||||
await updateRemoteConfig([
|
||||
{ name: CONFIG_KEY, value: 'uh oh', enabled: true },
|
||||
]);
|
||||
textMaximum(16);
|
||||
});
|
||||
|
||||
it('returns whether there are 9 or more people in the group, if the remote config value is 9', () => {
|
||||
getMaxGroupCallRingSizeStub.returns('9');
|
||||
it('returns whether there are 9 or more people in the group, if the remote config value is 9', async () => {
|
||||
await updateRemoteConfig([{ name: CONFIG_KEY, value: '9', enabled: true }]);
|
||||
textMaximum(9);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,66 +1,56 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// Copyright 2021-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import * as sinon from 'sinon';
|
||||
import * as remoteConfig from '../../RemoteConfig';
|
||||
import { updateRemoteConfig } from '../helpers/RemoteConfigStub';
|
||||
|
||||
import {
|
||||
getGroupSizeRecommendedLimit,
|
||||
getGroupSizeHardLimit,
|
||||
} from '../../groups/limits';
|
||||
|
||||
const RECOMMENDED_SIZE_KEY = 'global.groupsv2.maxGroupSize';
|
||||
const HARD_LIMIT_KEY = 'global.groupsv2.groupSizeHardLimit';
|
||||
|
||||
describe('group limit utilities', () => {
|
||||
let sinonSandbox: sinon.SinonSandbox;
|
||||
let getRecommendedLimitStub: sinon.SinonStub;
|
||||
let getHardLimitStub: sinon.SinonStub;
|
||||
|
||||
beforeEach(() => {
|
||||
sinonSandbox = sinon.createSandbox();
|
||||
|
||||
const getValueStub = sinonSandbox.stub(remoteConfig, 'getValue');
|
||||
getRecommendedLimitStub = getValueStub.withArgs(
|
||||
'global.groupsv2.maxGroupSize'
|
||||
);
|
||||
getHardLimitStub = getValueStub.withArgs(
|
||||
'global.groupsv2.groupSizeHardLimit'
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinonSandbox.restore();
|
||||
});
|
||||
|
||||
describe('getGroupSizeRecommendedLimit', () => {
|
||||
it('throws if the value in remote config is not defined', () => {
|
||||
getRecommendedLimitStub.returns(undefined);
|
||||
it('throws if the value in remote config is not defined', async () => {
|
||||
await updateRemoteConfig([]);
|
||||
assert.throws(getGroupSizeRecommendedLimit);
|
||||
});
|
||||
|
||||
it('throws if the value in remote config is not a parseable integer', () => {
|
||||
getRecommendedLimitStub.returns('uh oh');
|
||||
it('throws if the value in remote config is not a parseable integer', async () => {
|
||||
await updateRemoteConfig([
|
||||
{ name: RECOMMENDED_SIZE_KEY, value: 'uh oh', enabled: true },
|
||||
]);
|
||||
assert.throws(getGroupSizeRecommendedLimit);
|
||||
});
|
||||
|
||||
it('returns the value in remote config, parsed as an integer', () => {
|
||||
getRecommendedLimitStub.returns('123');
|
||||
it('returns the value in remote config, parsed as an integer', async () => {
|
||||
await updateRemoteConfig([
|
||||
{ name: RECOMMENDED_SIZE_KEY, value: '123', enabled: true },
|
||||
]);
|
||||
assert.strictEqual(getGroupSizeRecommendedLimit(), 123);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getGroupSizeHardLimit', () => {
|
||||
it('throws if the value in remote config is not defined', () => {
|
||||
getHardLimitStub.returns(undefined);
|
||||
it('throws if the value in remote config is not defined', async () => {
|
||||
await updateRemoteConfig([]);
|
||||
assert.throws(getGroupSizeHardLimit);
|
||||
});
|
||||
|
||||
it('throws if the value in remote config is not a parseable integer', () => {
|
||||
getHardLimitStub.returns('uh oh');
|
||||
it('throws if the value in remote config is not a parseable integer', async () => {
|
||||
await updateRemoteConfig([
|
||||
{ name: HARD_LIMIT_KEY, value: 'uh oh', enabled: true },
|
||||
]);
|
||||
assert.throws(getGroupSizeHardLimit);
|
||||
});
|
||||
|
||||
it('returns the value in remote config, parsed as an integer', () => {
|
||||
getHardLimitStub.returns('123');
|
||||
it('returns the value in remote config, parsed as an integer', async () => {
|
||||
await updateRemoteConfig([
|
||||
{ name: HARD_LIMIT_KEY, value: '123', enabled: true },
|
||||
]);
|
||||
assert.strictEqual(getGroupSizeHardLimit(), 123);
|
||||
});
|
||||
});
|
||||
|
|
18
ts/test-both/helpers/RemoteConfigStub.ts
Normal file
18
ts/test-both/helpers/RemoteConfigStub.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { refreshRemoteConfig } from '../../RemoteConfig';
|
||||
import type { WebAPIType } from '../../textsecure/WebAPI';
|
||||
import type { UnwrapPromise } from '../../types/Util';
|
||||
|
||||
export async function updateRemoteConfig(
|
||||
newConfig: UnwrapPromise<ReturnType<WebAPIType['getConfig']>>
|
||||
): Promise<void> {
|
||||
const fakeServer = {
|
||||
async getConfig() {
|
||||
return newConfig;
|
||||
},
|
||||
} as Partial<WebAPIType> as unknown as WebAPIType;
|
||||
|
||||
await refreshRemoteConfig(fakeServer);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// Copyright 2020-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
@ -8,7 +8,7 @@ import * as fs from 'fs';
|
|||
import * as path from 'path';
|
||||
import AbortController from 'abort-controller';
|
||||
import { IMAGE_JPEG, stringToMIMEType } from '../../types/MIME';
|
||||
import * as log from '../../logging/log';
|
||||
import type { LoggerType } from '../../types/Logging';
|
||||
|
||||
import {
|
||||
fetchLinkPreviewImage,
|
||||
|
@ -24,16 +24,12 @@ describe('link preview fetching', () => {
|
|||
return sinon.stub();
|
||||
}
|
||||
|
||||
let sandbox: sinon.SinonSandbox;
|
||||
let warn: sinon.SinonStub;
|
||||
let logger: Pick<LoggerType, 'warn'>;
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.createSandbox();
|
||||
warn = sandbox.stub(log, 'warn');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sandbox.restore();
|
||||
warn = sinon.stub();
|
||||
logger = { warn };
|
||||
});
|
||||
|
||||
describe('fetchLinkPreviewMetadata', () => {
|
||||
|
@ -196,7 +192,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewMetadata(
|
||||
fakeFetch,
|
||||
'https://example.com',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
);
|
||||
|
||||
sinon.assert.notCalled(warn);
|
||||
|
@ -229,7 +226,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewMetadata(
|
||||
fakeFetch,
|
||||
'https://example.com',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -249,7 +247,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewMetadata(
|
||||
fakeFetch,
|
||||
'https://example.com',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -434,7 +433,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewMetadata(
|
||||
fakeFetch,
|
||||
'https://example.com',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -451,7 +451,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewMetadata(
|
||||
fakeFetch,
|
||||
'https://example.com',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -473,7 +474,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewMetadata(
|
||||
fakeFetch,
|
||||
'https://example.com',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -517,7 +519,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewMetadata(
|
||||
fakeFetch,
|
||||
'https://example.com',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -798,7 +801,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewMetadata(
|
||||
fakeFetch,
|
||||
'https://example.com',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
),
|
||||
'title',
|
||||
'foo bar'
|
||||
|
@ -893,7 +897,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewMetadata(
|
||||
fakeFetch,
|
||||
'https://example.com',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -1166,7 +1171,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewImage(
|
||||
fakeFetch,
|
||||
'https://example.com/img',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -1196,7 +1202,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewImage(
|
||||
fakeFetch,
|
||||
'https://example.com/img',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -1264,7 +1271,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewImage(
|
||||
fakeFetch,
|
||||
'https://example.com/img',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -1289,7 +1297,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewImage(
|
||||
fakeFetch,
|
||||
'https://example.com/img',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -1319,7 +1328,8 @@ describe('link preview fetching', () => {
|
|||
await fetchLinkPreviewImage(
|
||||
fakeFetch,
|
||||
'https://example.com/img',
|
||||
new AbortController().signal
|
||||
new AbortController().signal,
|
||||
logger
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// Copyright 2020-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
@ -580,7 +580,12 @@ describe('Message', () => {
|
|||
});
|
||||
|
||||
it("shows a notification's emoji on non-Linux", function test() {
|
||||
this.sandbox.stub(window.Signal.OS, 'isLinux').returns(false);
|
||||
this.sandbox.replace(window.Signal, 'OS', {
|
||||
...window.Signal.OS,
|
||||
isLinux() {
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
createMessage({
|
||||
|
@ -597,7 +602,12 @@ describe('Message', () => {
|
|||
});
|
||||
|
||||
it('hides emoji on Linux', function test() {
|
||||
this.sandbox.stub(window.Signal.OS, 'isLinux').returns(true);
|
||||
this.sandbox.replace(window.Signal, 'OS', {
|
||||
...window.Signal.OS,
|
||||
isLinux() {
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
createMessage({
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// Copyright 2021-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import * as sinon from 'sinon';
|
||||
|
@ -8,14 +8,14 @@ import type { ConversationAttributesType } from '../model-types.d';
|
|||
import { UUID } from '../types/UUID';
|
||||
|
||||
import { routineProfileRefresh } from '../routineProfileRefresh';
|
||||
import * as getProfileStub from '../util/getProfile';
|
||||
|
||||
describe('routineProfileRefresh', () => {
|
||||
let sinonSandbox: sinon.SinonSandbox;
|
||||
let getProfileFn: sinon.SinonStub;
|
||||
|
||||
beforeEach(() => {
|
||||
sinonSandbox = sinon.createSandbox();
|
||||
sinonSandbox.stub(getProfileStub, 'getProfile').resolves(undefined);
|
||||
getProfileFn = sinon.stub();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -87,9 +87,10 @@ describe('routineProfileRefresh', () => {
|
|||
allConversations: [conversation1, conversation2],
|
||||
ourConversationId: UUID.generate().toString(),
|
||||
storage,
|
||||
getProfileFn,
|
||||
});
|
||||
|
||||
sinon.assert.notCalled(getProfileStub.getProfile as sinon.SinonStub);
|
||||
sinon.assert.notCalled(getProfileFn);
|
||||
sinon.assert.notCalled(storage.put);
|
||||
});
|
||||
|
||||
|
@ -101,15 +102,16 @@ describe('routineProfileRefresh', () => {
|
|||
allConversations: [conversation1, conversation2],
|
||||
ourConversationId: UUID.generate().toString(),
|
||||
storage: makeStorage(),
|
||||
getProfileFn,
|
||||
});
|
||||
|
||||
sinon.assert.calledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
conversation1.get('uuid'),
|
||||
conversation1.get('e164')
|
||||
);
|
||||
sinon.assert.calledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
conversation2.get('uuid'),
|
||||
conversation2.get('e164')
|
||||
);
|
||||
|
@ -126,21 +128,22 @@ describe('routineProfileRefresh', () => {
|
|||
allConversations: [recentlyActive, inactive, neverActive],
|
||||
ourConversationId: UUID.generate().toString(),
|
||||
storage: makeStorage(),
|
||||
getProfileFn,
|
||||
});
|
||||
|
||||
sinon.assert.calledOnce(getProfileStub.getProfile as sinon.SinonStub);
|
||||
sinon.assert.calledOnce(getProfileFn);
|
||||
sinon.assert.calledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
recentlyActive.get('uuid'),
|
||||
recentlyActive.get('e164')
|
||||
);
|
||||
sinon.assert.neverCalledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
inactive.get('uuid'),
|
||||
inactive.get('e164')
|
||||
);
|
||||
sinon.assert.neverCalledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
neverActive.get('uuid'),
|
||||
neverActive.get('e164')
|
||||
);
|
||||
|
@ -154,18 +157,11 @@ describe('routineProfileRefresh', () => {
|
|||
allConversations: [notMe, me],
|
||||
ourConversationId: me.id,
|
||||
storage: makeStorage(),
|
||||
getProfileFn,
|
||||
});
|
||||
|
||||
sinon.assert.calledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
notMe.get('uuid'),
|
||||
notMe.get('e164')
|
||||
);
|
||||
sinon.assert.neverCalledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
me.get('uuid'),
|
||||
me.get('e164')
|
||||
);
|
||||
sinon.assert.calledWith(getProfileFn, notMe.get('uuid'), notMe.get('e164'));
|
||||
sinon.assert.neverCalledWith(getProfileFn, me.get('uuid'), me.get('e164'));
|
||||
});
|
||||
|
||||
it('skips conversations that were refreshed in the last hour', async () => {
|
||||
|
@ -178,16 +174,17 @@ describe('routineProfileRefresh', () => {
|
|||
allConversations: [neverRefreshed, recentlyFetched],
|
||||
ourConversationId: UUID.generate().toString(),
|
||||
storage: makeStorage(),
|
||||
getProfileFn,
|
||||
});
|
||||
|
||||
sinon.assert.calledOnce(getProfileStub.getProfile as sinon.SinonStub);
|
||||
sinon.assert.calledOnce(getProfileFn);
|
||||
sinon.assert.calledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
neverRefreshed.get('uuid'),
|
||||
neverRefreshed.get('e164')
|
||||
);
|
||||
sinon.assert.neverCalledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
recentlyFetched.get('uuid'),
|
||||
recentlyFetched.get('e164')
|
||||
);
|
||||
|
@ -220,30 +217,31 @@ describe('routineProfileRefresh', () => {
|
|||
],
|
||||
ourConversationId: UUID.generate().toString(),
|
||||
storage: makeStorage(),
|
||||
getProfileFn,
|
||||
});
|
||||
|
||||
sinon.assert.calledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
privateConversation.get('uuid'),
|
||||
privateConversation.get('e164')
|
||||
);
|
||||
sinon.assert.calledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
recentlyActiveGroupMember.get('uuid'),
|
||||
recentlyActiveGroupMember.get('e164')
|
||||
);
|
||||
sinon.assert.calledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
inactiveGroupMember.get('uuid'),
|
||||
inactiveGroupMember.get('e164')
|
||||
);
|
||||
sinon.assert.neverCalledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
memberWhoHasRecentlyRefreshed.get('uuid'),
|
||||
memberWhoHasRecentlyRefreshed.get('e164')
|
||||
);
|
||||
sinon.assert.neverCalledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
groupConversation.get('uuid'),
|
||||
groupConversation.get('e164')
|
||||
);
|
||||
|
@ -288,11 +286,12 @@ describe('routineProfileRefresh', () => {
|
|||
],
|
||||
ourConversationId: me.id,
|
||||
storage: makeStorage(),
|
||||
getProfileFn,
|
||||
});
|
||||
|
||||
[...activeConversations, ...inactiveGroupMembers].forEach(conversation => {
|
||||
sinon.assert.calledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
conversation.get('uuid'),
|
||||
conversation.get('e164')
|
||||
);
|
||||
|
@ -300,7 +299,7 @@ describe('routineProfileRefresh', () => {
|
|||
|
||||
[me, ...shouldNotBeIncluded].forEach(conversation => {
|
||||
sinon.assert.neverCalledWith(
|
||||
getProfileStub.getProfile as sinon.SinonStub,
|
||||
getProfileFn,
|
||||
conversation.get('uuid'),
|
||||
conversation.get('e164')
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// Copyright 2020-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
@ -31,7 +31,6 @@ import { ReadStatus } from '../../../messages/MessageReadStatus';
|
|||
import { ContactSpoofingType } from '../../../util/contactSpoofing';
|
||||
import { CallMode } from '../../../types/Calling';
|
||||
import { UUID } from '../../../types/UUID';
|
||||
import * as groups from '../../../groups';
|
||||
import {
|
||||
getDefaultConversation,
|
||||
getDefaultConversationWithUuid,
|
||||
|
@ -42,6 +41,7 @@ import {
|
|||
defaultChooseGroupMembersComposerState,
|
||||
defaultSetGroupMetadataComposerState,
|
||||
} from '../../../test-both/helpers/defaultComposerStates';
|
||||
import { updateRemoteConfig } from '../../../test-both/helpers/RemoteConfigStub';
|
||||
|
||||
const {
|
||||
cantAddContactToGroup,
|
||||
|
@ -83,7 +83,7 @@ describe('both/state/ducks/conversations', () => {
|
|||
|
||||
sinonSandbox.stub(window.Whisper.events, 'trigger');
|
||||
|
||||
createGroupStub = sinonSandbox.stub(groups, 'createGroupV2');
|
||||
createGroupStub = sinon.stub();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -686,7 +686,7 @@ describe('both/state/ducks/conversations', () => {
|
|||
});
|
||||
|
||||
it('calls groups.createGroupV2', async () => {
|
||||
await createGroup()(
|
||||
await createGroup(createGroupStub)(
|
||||
sinon.spy(),
|
||||
() => ({
|
||||
...getEmptyRootState(),
|
||||
|
@ -706,7 +706,7 @@ describe('both/state/ducks/conversations', () => {
|
|||
});
|
||||
|
||||
it("trims the group's title before calling groups.createGroupV2", async () => {
|
||||
await createGroup()(
|
||||
await createGroup(createGroupStub)(
|
||||
sinon.spy(),
|
||||
() => ({
|
||||
...getEmptyRootState(),
|
||||
|
@ -732,7 +732,7 @@ describe('both/state/ducks/conversations', () => {
|
|||
|
||||
const dispatch = sinon.spy();
|
||||
|
||||
const createGroupPromise = createGroup()(
|
||||
const createGroupPromise = createGroup(createGroupStub)(
|
||||
dispatch,
|
||||
() => ({
|
||||
...getEmptyRootState(),
|
||||
|
@ -764,7 +764,7 @@ describe('both/state/ducks/conversations', () => {
|
|||
|
||||
const dispatch = sinon.spy();
|
||||
|
||||
const createGroupPromise = createGroup()(
|
||||
const createGroupPromise = createGroup(createGroupStub)(
|
||||
dispatch,
|
||||
() => ({
|
||||
...getEmptyRootState(),
|
||||
|
@ -796,7 +796,7 @@ describe('both/state/ducks/conversations', () => {
|
|||
|
||||
const dispatch = sinon.spy();
|
||||
|
||||
await createGroup()(
|
||||
await createGroup(createGroupStub)(
|
||||
dispatch,
|
||||
() => ({
|
||||
...getEmptyRootState(),
|
||||
|
@ -1572,15 +1572,15 @@ describe('both/state/ducks/conversations', () => {
|
|||
return dispatch.getCall(0).args[0];
|
||||
}
|
||||
|
||||
let remoteConfigGetValueStub: sinon.SinonStub;
|
||||
|
||||
beforeEach(() => {
|
||||
remoteConfigGetValueStub = sinonSandbox
|
||||
.stub(window.Signal.RemoteConfig, 'getValue')
|
||||
.withArgs('global.groupsv2.maxGroupSize')
|
||||
.returns('22')
|
||||
.withArgs('global.groupsv2.groupSizeHardLimit')
|
||||
.returns('33');
|
||||
beforeEach(async () => {
|
||||
await updateRemoteConfig([
|
||||
{ name: 'global.groupsv2.maxGroupSize', value: '22', enabled: true },
|
||||
{
|
||||
name: 'global.groupsv2.groupSizeHardLimit',
|
||||
value: '33',
|
||||
enabled: true,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('adds conversation IDs to the list', () => {
|
||||
|
@ -1657,11 +1657,21 @@ describe('both/state/ducks/conversations', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('defaults the maximum recommended size to 151', () => {
|
||||
[undefined, 'xyz'].forEach(value => {
|
||||
remoteConfigGetValueStub
|
||||
.withArgs('global.groupsv2.maxGroupSize')
|
||||
.returns(value);
|
||||
it('defaults the maximum recommended size to 151', async () => {
|
||||
for (const value of [null, 'xyz']) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await updateRemoteConfig([
|
||||
{
|
||||
name: 'global.groupsv2.maxGroupSize',
|
||||
value,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: 'global.groupsv2.groupSizeHardLimit',
|
||||
value: '33',
|
||||
enabled: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const state = {
|
||||
...getEmptyState(),
|
||||
|
@ -1670,7 +1680,7 @@ describe('both/state/ducks/conversations', () => {
|
|||
const action = getAction(uuid(), state);
|
||||
|
||||
assert.strictEqual(action.payload.maxRecommendedGroupSize, 151);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('shows the maximum group size modal when first reaching the maximum group size', () => {
|
||||
|
@ -1735,13 +1745,17 @@ describe('both/state/ducks/conversations', () => {
|
|||
assert.deepEqual(result, state);
|
||||
});
|
||||
|
||||
it('defaults the maximum group size to 1001 if the recommended maximum is smaller', () => {
|
||||
[undefined, 'xyz'].forEach(value => {
|
||||
remoteConfigGetValueStub
|
||||
.withArgs('global.groupsv2.maxGroupSize')
|
||||
.returns('2')
|
||||
.withArgs('global.groupsv2.groupSizeHardLimit')
|
||||
.returns(value);
|
||||
it('defaults the maximum group size to 1001 if the recommended maximum is smaller', async () => {
|
||||
for (const value of [null, 'xyz']) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await updateRemoteConfig([
|
||||
{ name: 'global.groupsv2.maxGroupSize', value: '2', enabled: true },
|
||||
{
|
||||
name: 'global.groupsv2.groupSizeHardLimit',
|
||||
value,
|
||||
enabled: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const state = {
|
||||
...getEmptyState(),
|
||||
|
@ -1750,15 +1764,22 @@ describe('both/state/ducks/conversations', () => {
|
|||
const action = getAction(uuid(), state);
|
||||
|
||||
assert.strictEqual(action.payload.maxGroupSize, 1001);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('defaults the maximum group size to (recommended maximum + 1) if the recommended maximum is more than 1001', () => {
|
||||
remoteConfigGetValueStub
|
||||
.withArgs('global.groupsv2.maxGroupSize')
|
||||
.returns('1234')
|
||||
.withArgs('global.groupsv2.groupSizeHardLimit')
|
||||
.returns('2');
|
||||
it('defaults the maximum group size to (recommended maximum + 1) if the recommended maximum is more than 1001', async () => {
|
||||
await updateRemoteConfig([
|
||||
{
|
||||
name: 'global.groupsv2.maxGroupSize',
|
||||
value: '1234',
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: 'global.groupsv2.groupSizeHardLimit',
|
||||
value: '2',
|
||||
enabled: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const state = {
|
||||
...getEmptyState(),
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// Copyright 2021-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import * as sinon from 'sinon';
|
||||
import { times } from 'lodash';
|
||||
import { RowType } from '../../../components/ConversationList';
|
||||
import * as remoteConfig from '../../../RemoteConfig';
|
||||
import { ContactCheckboxDisabledReason } from '../../../components/conversationList/ContactCheckbox';
|
||||
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
|
||||
|
||||
import { LeftPaneChooseGroupMembersHelper } from '../../../components/leftPane/LeftPaneChooseGroupMembersHelper';
|
||||
import { updateRemoteConfig } from '../../../test-both/helpers/RemoteConfigStub';
|
||||
|
||||
describe('LeftPaneChooseGroupMembersHelper', () => {
|
||||
const defaults = {
|
||||
|
@ -21,21 +21,15 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
|
|||
selectedContacts: [],
|
||||
};
|
||||
|
||||
let sinonSandbox: sinon.SinonSandbox;
|
||||
|
||||
beforeEach(() => {
|
||||
sinonSandbox = sinon.createSandbox();
|
||||
|
||||
sinonSandbox
|
||||
.stub(remoteConfig, 'getValue')
|
||||
.withArgs('global.groupsv2.maxGroupSize')
|
||||
.returns('22')
|
||||
.withArgs('global.groupsv2.groupSizeHardLimit')
|
||||
.returns('33');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinonSandbox.restore();
|
||||
beforeEach(async () => {
|
||||
await updateRemoteConfig([
|
||||
{ name: 'global.groupsv2.maxGroupSize', value: '22', enabled: true },
|
||||
{
|
||||
name: 'global.groupsv2.groupSizeHardLimit',
|
||||
value: '33',
|
||||
enabled: true,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
describe('getBackAction', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2021 Signal Messenger, LLC
|
||||
// Copyright 2018-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import is from '@sindresorhus/is';
|
||||
|
@ -323,7 +323,7 @@ export function removeSchemaVersion({
|
|||
attachment: AttachmentType;
|
||||
logger: LoggerType;
|
||||
}): AttachmentType {
|
||||
if (!exports.isValid(attachment)) {
|
||||
if (!isValid(attachment)) {
|
||||
logger.error(
|
||||
'Attachment.removeSchemaVersion: Invalid input attachment:',
|
||||
attachment
|
||||
|
|
|
@ -6945,22 +6945,6 @@
|
|||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-07-21T18:34:59.251Z"
|
||||
},
|
||||
{
|
||||
"rule": "DOM-innerHTML",
|
||||
"path": "ts/backbone/views/Lightbox.js",
|
||||
"line": " container.innerHTML = '';",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2018-09-17T20:50:40.689Z",
|
||||
"reasonDetail": "Hard-coded value"
|
||||
},
|
||||
{
|
||||
"rule": "DOM-innerHTML",
|
||||
"path": "ts/backbone/views/Lightbox.js",
|
||||
"line": " container.innerHTML = '';",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2018-09-17T20:50:40.689Z",
|
||||
"reasonDetail": "Hard-coded value"
|
||||
},
|
||||
{
|
||||
"rule": "DOM-innerHTML",
|
||||
"path": "ts/backbone/views/Lightbox.ts",
|
||||
|
@ -6977,14 +6961,6 @@
|
|||
"updated": "2018-09-17T20:50:40.689Z",
|
||||
"reasonDetail": "Hard-coded value"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-html(",
|
||||
"path": "ts/backbone/views/whisper_view.js",
|
||||
"line": " this.$el.html(window.Mustache.render(template, attrs));",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-02-26T18:44:56.450Z",
|
||||
"reasonDetail": "Rendering provided template"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-html(",
|
||||
"path": "ts/backbone/views/whisper_view.ts",
|
||||
|
@ -7001,20 +6977,6 @@
|
|||
"updated": "2021-12-10T23:24:03.829Z",
|
||||
"reasonDetail": "Doesn't touch the DOM."
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/challenge.js",
|
||||
"line": " async load() {",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-05-05T23:11:22.692Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/challenge.js",
|
||||
"line": " // 1. `.load()` when the `window.storage` is ready",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-05-05T23:11:22.692Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/challenge.ts",
|
||||
|
@ -7100,14 +7062,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-12-01T01:31:12.757Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CallingLobby.js",
|
||||
"line": " const localVideoRef = react_1.default.useRef(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Used to get the local video element for rendering."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CallingLobby.tsx",
|
||||
|
@ -7115,22 +7069,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-07-30T16:57:33.618Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CallingPip.js",
|
||||
"line": " const videoContainerRef = react_1.default.useRef(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Element is measured. Its HTML is not used."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CallingPip.js",
|
||||
"line": " const localVideoRef = react_1.default.useRef(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Used to get the local video element for rendering."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CallingPip.tsx",
|
||||
|
@ -7181,61 +7119,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-23T00:07:11.885Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CompositionInput.js",
|
||||
"line": " const emojiCompletionRef = React.useRef();",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Doesn't refer to a DOM element."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CompositionInput.js",
|
||||
"line": " const quillRef = React.useRef();",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Doesn't refer to a DOM element."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CompositionInput.js",
|
||||
"line": " const propsRef = React.useRef(props);",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Doesn't refer to a DOM element."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CompositionInput.js",
|
||||
"line": " const mentionCompletionRef = React.useRef();",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-10-26T23:54:34.273Z",
|
||||
"reasonDetail": "Doesn't refer to a DOM element."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CompositionInput.js",
|
||||
"line": " const memberRepositoryRef = React.useRef(new memberRepository_1.MemberRepository());",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-10-26T23:56:13.482Z",
|
||||
"reasonDetail": "Doesn't refer to a DOM element."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CompositionInput.js",
|
||||
"line": " const scrollerRef = React.useRef(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Used with Quill for scrolling."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CompositionInput.js",
|
||||
"line": " const callbacksRef = React.useRef(unstaleCallbacks);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-04-21T21:35:38.757Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/CompositionInput.tsx",
|
||||
|
@ -7306,13 +7189,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-07-30T16:57:33.618Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/ForwardMessageModal.js",
|
||||
"line": " const inputApiRef = react_1.default.useRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-04-19T18:13:21.664Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/ForwardMessageModal.tsx",
|
||||
|
@ -7414,13 +7290,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-07-30T16:57:33.618Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/components/Intl.js",
|
||||
"line": " const FIND_REPLACEMENTS = /\\$([^$]+)\\$/g;",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-07-21T18:34:59.251Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/components/Intl.tsx",
|
||||
|
@ -7515,14 +7384,6 @@
|
|||
"updated": "2022-01-04T21:43:17.517Z",
|
||||
"reasonDetail": "Used to change the style in non-production builds."
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/SafetyNumberChangeDialog.js",
|
||||
"line": " const cancelButtonRef = React.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-06-23T06:48:06.829Z",
|
||||
"reasonDetail": "Used to focus cancel button when dialog opens"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/Slider.tsx",
|
||||
|
@ -7558,14 +7419,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-11-30T10:15:33.662Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/Tooltip.js",
|
||||
"line": " const wrapperRef = react_1.default.useRef(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-12-04T00:11:08.128Z",
|
||||
"reasonDetail": "Used to add (and remove) event listeners."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/Tooltip.tsx",
|
||||
|
@ -7573,22 +7426,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-07-30T16:57:33.618Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/ConversationHeader.js",
|
||||
"line": " this.menuTriggerRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-08-28T16:12:19.904Z",
|
||||
"reasonDetail": "Used to reference popup menu"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/ConversationHeader.js",
|
||||
"line": " this.headerRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-01-18T22:24:05.937Z",
|
||||
"reasonDetail": "Used to reference popup menu boundaries element"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/ConversationHeader.tsx",
|
||||
|
@ -7627,14 +7464,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-07-30T16:57:33.618Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/InlineNotificationWrapper.js",
|
||||
"line": " this.focusRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2019-11-06T19:56:38.557Z",
|
||||
"reasonDetail": "Used to manage focus"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/InlineNotificationWrapper.tsx",
|
||||
|
@ -7643,30 +7472,6 @@
|
|||
"updated": "2019-11-06T19:56:38.557Z",
|
||||
"reasonDetail": "Used to manage focus"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/Message.js",
|
||||
"line": " this.reactionsContainerRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-08-28T16:12:19.904Z",
|
||||
"reasonDetail": "Used for detecting clicks outside reaction viewer"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/Message.js",
|
||||
"line": " this.focusRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-03-05T20:05:07.474Z",
|
||||
"reasonDetail": "Used for managing focus only"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/Message.js",
|
||||
"line": " this.audioButtonRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-03-05T20:05:07.474Z",
|
||||
"reasonDetail": "Used for propagating click from the Message to MessageAudio's button"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/Message.tsx",
|
||||
|
@ -7698,22 +7503,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-07-30T16:57:33.618Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/MessageDetail.js",
|
||||
"line": " this.focusRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2019-11-01T22:46:33.013Z",
|
||||
"reasonDetail": "Used for setting focus only"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/MessageDetail.js",
|
||||
"line": " this.messageContainerRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-08-20T16:48:00.885Z",
|
||||
"reasonDetail": "Needed to confine Poppers. We don't actually manipulate this DOM reference."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/conversation/Quote.tsx",
|
||||
|
@ -7722,22 +7511,6 @@
|
|||
"updated": "2021-01-20T21:30:08.430Z",
|
||||
"reasonDetail": "Doesn't touch the DOM."
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/Timeline.js",
|
||||
"line": " this.listRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2019-07-31T00:19:18.696Z",
|
||||
"reasonDetail": "Timeline needs to interact with its child List directly"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/Timeline.js",
|
||||
"line": " this.containerRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-08-20T16:48:00.885Z",
|
||||
"reasonDetail": "Needed to confine Poppers. We don't actually manipulate this DOM reference."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/conversation/conversation-details/AddGroupMembersModal/ChooseGroupMembersModal.tsx",
|
||||
|
@ -7766,14 +7539,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-07-30T16:57:33.618Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/media-gallery/MediaGallery.js",
|
||||
"line": " this.focusRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2019-11-01T22:46:33.013Z",
|
||||
"reasonDetail": "Used for setting focus only"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/media-gallery/MediaGallery.tsx",
|
||||
|
@ -7790,14 +7555,6 @@
|
|||
"updated": "2021-12-06T23:07:28.947Z",
|
||||
"reasonDetail": "Doesn't touch the DOM."
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/stickers/StickerManager.js",
|
||||
"line": " const focusRef = React.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2019-11-21T06:13:49.384Z",
|
||||
"reasonDetail": "Used for setting focus only"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useIntersectionObserver.ts",
|
||||
|
@ -7812,35 +7569,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-17T20:16:37.959Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useRestoreFocus.js",
|
||||
"line": " const lastFocusedRef = React.useRef(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-07-30T01:08:01.309Z",
|
||||
"reasonDetail": "Used to store the previous-focused item, again to set focus"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useRestoreFocus.js",
|
||||
"line": " const toFocusRef = React.useRef(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-17T17:37:46.279Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useRestoreFocus.js",
|
||||
"line": " const toFocusRef = React.useRef(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-22T00:52:39.251Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useRestoreFocus.js",
|
||||
"line": " const lastFocusedRef = React.useRef(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-22T00:52:39.251Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useRestoreFocus.ts",
|
||||
|
@ -7869,13 +7597,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-22T00:52:39.251Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/jobs/helpers/syncHelpers.js",
|
||||
"line": " await window.ConversationController.load();",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-12-15T19:58:28.089Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/jobs/helpers/syncHelpers.ts",
|
||||
|
@ -7883,13 +7604,6 @@
|
|||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-11-04T16:14:03.477Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/jobs/normalMessageSendJobQueue.js",
|
||||
"line": " await window.ConversationController.load();",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-11-04T16:14:03.477Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/jobs/normalMessageSendJobQueue.ts",
|
||||
|
@ -7897,13 +7611,6 @@
|
|||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-12-15T19:58:28.089Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/jobs/reactionJobQueue.js",
|
||||
"line": " await window.ConversationController.load();",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-11-04T16:14:03.477Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/jobs/reactionJobQueue.ts",
|
||||
|
@ -7911,34 +7618,6 @@
|
|||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-11-04T16:14:03.477Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "ts/logging/uploadDebugLog.js",
|
||||
"line": " form.append('key', uploadKey);",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-12-17T18:08:07.752Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "ts/logging/uploadDebugLog.js",
|
||||
"line": " form.append(key, value);",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-12-17T18:08:07.752Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "ts/logging/uploadDebugLog.js",
|
||||
"line": " form.append('Content-Type', contentType);",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-12-17T18:08:07.752Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "ts/logging/uploadDebugLog.js",
|
||||
"line": " form.append('file', contentBuffer, {",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-12-17T18:08:07.752Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "ts/logging/uploadDebugLog.ts",
|
||||
|
@ -7967,22 +7646,6 @@
|
|||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-12-17T18:08:07.752Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/manage_full_screen_class.js",
|
||||
"line": "$(document).ready(() => {",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-01-21T23:06:13.270Z",
|
||||
"reasonDetail": "Doesn't manipulate the DOM."
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/manage_full_screen_class.js",
|
||||
"line": " $(document.body).toggleClass('full-screen', isFullScreen);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-01-21T23:06:13.270Z",
|
||||
"reasonDetail": "Manipulates a trusted class."
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/manage_full_screen_class.ts",
|
||||
|
@ -7999,21 +7662,6 @@
|
|||
"updated": "2021-01-21T23:06:13.270Z",
|
||||
"reasonDetail": "Manipulates a trusted class."
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/quill/mentions/completion.js",
|
||||
"line": " this.suggestionListRef = react_1.default.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-10-30T23:03:08.319Z"
|
||||
},
|
||||
{
|
||||
"rule": "DOM-innerHTML",
|
||||
"path": "ts/quill/signal-clipboard/index.js",
|
||||
"line": " return div.innerHTML;",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-11-06T17:43:07.381Z",
|
||||
"reasonDetail": "used for figuring out clipboard contents"
|
||||
},
|
||||
{
|
||||
"rule": "DOM-innerHTML",
|
||||
"path": "ts/quill/signal-clipboard/index.ts",
|
||||
|
@ -8022,22 +7670,6 @@
|
|||
"updated": "2020-11-06T17:43:07.381Z",
|
||||
"reasonDetail": "used for figuring out clipboard contents"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/set_os_class.js",
|
||||
"line": " $(document.body).addClass(className);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-01-21T23:06:13.270Z",
|
||||
"reasonDetail": "Adds a trusted CSS class."
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/set_os_class.js",
|
||||
"line": "$(document).ready(() => {",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-01-21T23:06:13.270Z",
|
||||
"reasonDetail": "Doesn't manipulate the DOM."
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/set_os_class.ts",
|
||||
|
@ -8054,13 +7686,6 @@
|
|||
"updated": "2021-01-21T23:06:13.270Z",
|
||||
"reasonDetail": "Doesn't manipulate the DOM."
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/state/ducks/app.js",
|
||||
"line": " await window.ConversationController.load();",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-11-04T16:14:03.477Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/state/ducks/app.ts",
|
||||
|
@ -8076,13 +7701,6 @@
|
|||
"updated": "2021-12-06T23:07:28.947Z",
|
||||
"reasonDetail": "Doesn't touch the DOM."
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/types/Stickers.js",
|
||||
"line": "async function load() {",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-07-02T02:57:58.052Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/types/Stickers.ts",
|
||||
|
@ -8090,13 +7708,6 @@
|
|||
"reasonCategory": "falseMatch",
|
||||
"updated": "2019-04-26T17:48:30.675Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/util/avatarDataToBytes.js",
|
||||
"line": " await font.load();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-08-03T21:17:38.615Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/util/avatarDataToBytes.ts",
|
||||
|
@ -8104,46 +7715,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-08-03T21:17:38.615Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/util/createIPCEvents.js",
|
||||
"line": " if ($('.dark-overlay').length) {",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-08-18T18:22:55.307Z",
|
||||
"reasonDetail": "Legacy code"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/util/createIPCEvents.js",
|
||||
"line": " $(document.body).prepend('<div class=\"dark-overlay\"></div>');",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-08-18T18:22:55.307Z",
|
||||
"reasonDetail": "Legacy code"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/util/createIPCEvents.js",
|
||||
"line": " $('.dark-overlay').on('click', () => $('.dark-overlay').remove());",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-08-18T18:22:55.307Z",
|
||||
"reasonDetail": "Legacy code"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/util/createIPCEvents.js",
|
||||
"line": " }, removeDarkOverlay: () => $('.dark-overlay').remove(), showKeyboardShortcuts: () => window.showKeyboardShortcuts(), deleteAllData: async () => {",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-08-18T18:22:55.307Z",
|
||||
"reasonDetail": "Legacy code"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-prepend(",
|
||||
"path": "ts/util/createIPCEvents.js",
|
||||
"line": " $(document.body).prepend('<div class=\"dark-overlay\"></div>');",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-08-18T18:22:55.307Z",
|
||||
"reasonDetail": "Legacy code"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/util/createIPCEvents.ts",
|
||||
|
@ -8184,13 +7755,6 @@
|
|||
"updated": "2021-08-18T18:22:55.307Z",
|
||||
"reasonDetail": "Legacy code"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/util/sendReceipts.js",
|
||||
"line": " await window.ConversationController.load();",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-12-15T19:58:28.089Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/util/sendReceipts.ts",
|
||||
|
@ -8198,13 +7762,6 @@
|
|||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-12-15T19:58:28.089Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/util/setupI18n.js",
|
||||
"line": " const FIND_REPLACEMENTS = /\\$([^$]+)\\$/g;",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-09-17T21:51:57.475Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/util/setupI18n.ts",
|
||||
|
@ -8212,90 +7769,6 @@
|
|||
"reasonCategory": "falseMatch",
|
||||
"updated": "2021-09-17T21:51:57.475Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " template: () => $('#app-loading-screen').html(),",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " this.$('.message').text(message);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " template: () => $('#two-column').html(),",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " el: this.$('.conversation-stack'),",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " this.$('.left-pane-placeholder').replaceWith(this.leftPaneView.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-08T17:39:41.541Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " this.$('.no-conversation-open').toggle(!isAnyConversationOpen);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-08T17:40:22.770Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " this.$('.whats-new-placeholder').append(this.whatsNewLink.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-22T20:58:48.103Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " this.$('.whats-new-placeholder').append(this.whatsNewLink.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-22T20:58:48.103Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-appendTo(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " view.$el.appendTo(this.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-20T22:27:31.785Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-html(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " template: () => $('#app-loading-screen').html(),",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-html(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " template: () => $('#two-column').html(),",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-prependTo(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " this.appLoadingScreen.$el.prependTo(this.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.ts",
|
||||
|
@ -8380,13 +7853,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "DOM-innerHTML",
|
||||
"path": "ts/windows/loading/start.js",
|
||||
"line": " message.innerHTML = window.SignalContext.i18n('optimizingApplication');",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-17T21:02:59.414Z"
|
||||
},
|
||||
{
|
||||
"rule": "DOM-innerHTML",
|
||||
"path": "ts/windows/loading/start.ts",
|
||||
|
|
|
@ -31,6 +31,9 @@ const excludedFilesRegexp = RegExp(
|
|||
'.+\\.stories\\.js',
|
||||
'.+\\.stories\\.tsx',
|
||||
|
||||
// Compiled files
|
||||
'^ts/.+\\.js',
|
||||
|
||||
// High-traffic files in our project
|
||||
'^app/.+(ts|js)',
|
||||
'^ts/models/messages.js',
|
||||
|
@ -74,6 +77,7 @@ const excludedFilesRegexp = RegExp(
|
|||
'^.github/.+',
|
||||
|
||||
// Modules we trust
|
||||
'^node_modules/@signalapp/signal-client/.+',
|
||||
'^node_modules/core-js-pure/.+',
|
||||
'^node_modules/core-js/.+',
|
||||
'^node_modules/fbjs/.+',
|
||||
|
@ -104,6 +108,7 @@ const excludedFilesRegexp = RegExp(
|
|||
'^node_modules/react-color/.+/(?:core-js|fbjs|lodash)/.+',
|
||||
|
||||
// Modules used only in test/development scenarios
|
||||
'^node_modules/esbuild/.+',
|
||||
'^node_modules/@babel/.+',
|
||||
'^node_modules/@chanzuckerberg/axe-storybook-testing/.+',
|
||||
'^node_modules/@svgr/.+',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue