Bugfixes for v1.29

* If focus was set to document.body during archive, focus left pane
* Shortcut Guide: Add space between text and shortcut highlight
* Ensure that draft attachment can be closed with click on X button
* Move to keyDown event for user idle checking
* Additional resiliency around avatars; check for them on on-disk
* Increase timeouts to preserve websocket connection
* On startup, be resilient to malformed JSON in log files
* Don't crash if shell.openExternal returns an error
* Whenever we request a contact/group sync, also request block list
* Avatar popup: Ensure styling is mouse- and keyboard-appropriate
* MainHeader: Create popperRoot on demand, not on mount
* CompositionInput: Disable default Ctrl-/ shortcut
* Update libphonenumber
This commit is contained in:
Scott Nonnenberg 2019-12-03 12:02:50 -08:00 committed by Ken Powers
parent ee9e86ab7a
commit e9f08c3da9
19 changed files with 300 additions and 128 deletions

View File

@ -105,6 +105,30 @@ exports.createReader = root => {
}; };
}; };
exports.createDoesExist = root => {
if (!isString(root)) {
throw new TypeError("'root' must be a path");
}
return async relativePath => {
if (!isString(relativePath)) {
throw new TypeError("'relativePath' must be a string");
}
const absolutePath = path.join(root, relativePath);
const normalized = path.normalize(absolutePath);
if (!normalized.startsWith(root)) {
throw new Error('Invalid relative path');
}
try {
await fse.access(normalized, fse.constants.F_OK);
return true;
} catch (error) {
return false;
}
};
};
exports.copyIntoAttachmentsDirectory = root => { exports.copyIntoAttachmentsDirectory = root => {
if (!isString(root)) { if (!isString(root)) {
throw new TypeError("'root' must be a path"); throw new TypeError("'root' must be a path");

View File

@ -31,7 +31,7 @@ module.exports = {
fetch, fetch,
}; };
function initialize() { async function initialize() {
if (logger) { if (logger) {
throw new Error('Already called initialize!'); throw new Error('Already called initialize!');
} }
@ -40,66 +40,81 @@ function initialize() {
const logPath = path.join(basePath, 'logs'); const logPath = path.join(basePath, 'logs');
mkdirp.sync(logPath); mkdirp.sync(logPath);
return cleanupLogs(logPath).then(() => { try {
const logFile = path.join(logPath, 'log.log'); await cleanupLogs(logPath);
const loggerOptions = { } catch (error) {
name: 'log', const errorString = `Failed to clean logs; deleting all. Error: ${
streams: [ error.stack
}`;
console.error(errorString);
await deleteAllLogs(logPath);
mkdirp.sync(logPath);
// If we want this log entry to persist on disk, we need to wait until we've
// set up our logging infrastructure.
setTimeout(() => {
console.error(errorString);
}, 500);
}
const logFile = path.join(logPath, 'log.log');
const loggerOptions = {
name: 'log',
streams: [
{
type: 'rotating-file',
path: logFile,
period: '1d',
count: 3,
},
],
};
if (isRunningFromConsole) {
loggerOptions.streams.push({
level: 'debug',
stream: process.stdout,
});
}
logger = bunyan.createLogger(loggerOptions);
LEVELS.forEach(level => {
ipc.on(`log-${level}`, (first, ...rest) => {
logger[level](...rest);
});
});
ipc.on('batch-log', (first, batch) => {
batch.forEach(item => {
logger[item.level](
{ {
type: 'rotating-file', time: new Date(item.timestamp),
path: logFile,
period: '1d',
count: 3,
}, },
], item.logText
};
if (isRunningFromConsole) {
loggerOptions.streams.push({
level: 'debug',
stream: process.stdout,
});
}
logger = bunyan.createLogger(loggerOptions);
LEVELS.forEach(level => {
ipc.on(`log-${level}`, (first, ...rest) => {
logger[level](...rest);
});
});
ipc.on('batch-log', (first, batch) => {
batch.forEach(item => {
logger[item.level](
{
time: new Date(item.timestamp),
},
item.logText
);
});
});
ipc.on('fetch-log', event => {
fetch(logPath).then(
data => {
event.sender.send('fetched-log', data);
},
error => {
logger.error(`Problem loading log from disk: ${error.stack}`);
}
); );
}); });
});
ipc.on('delete-all-logs', async event => { ipc.on('fetch-log', event => {
try { fetch(logPath).then(
await deleteAllLogs(logPath); data => {
} catch (error) { event.sender.send('fetched-log', data);
logger.error(`Problem deleting all logs: ${error.stack}`); },
error => {
logger.error(`Problem loading log from disk: ${error.stack}`);
} }
);
});
event.sender.send('delete-all-logs-complete'); ipc.on('delete-all-logs', async event => {
}); try {
await deleteAllLogs(logPath);
} catch (error) {
logger.error(`Problem deleting all logs: ${error.stack}`);
}
event.sender.send('delete-all-logs-complete');
}); });
} }

View File

@ -76,7 +76,7 @@
const ACTIVE_TIMEOUT = 15 * 1000; const ACTIVE_TIMEOUT = 15 * 1000;
const ACTIVE_EVENTS = [ const ACTIVE_EVENTS = [
'click', 'click',
'keypress', 'keydown',
'mousedown', 'mousedown',
'mousemove', 'mousemove',
// 'scroll', // this is triggered by Timeline re-renders, can't use // 'scroll', // this is triggered by Timeline re-renders, can't use
@ -193,6 +193,7 @@
upgradeMessageSchema, upgradeMessageSchema,
writeNewAttachmentData, writeNewAttachmentData,
deleteAttachmentData, deleteAttachmentData,
doesAttachmentExist,
} = window.Signal.Migrations; } = window.Signal.Migrations;
const { Views } = window.Signal; const { Views } = window.Signal;
@ -1049,6 +1050,23 @@
document.body document.body
); );
// It's very likely that the act of archiving a conversation will set focus to
// 'none,' or the top-level body element. This resets it to the left pane,
// whether in the normal conversation list or search results.
if (document.activeElement === document.body) {
const leftPaneEl = document.querySelector('.module-left-pane__list');
if (leftPaneEl) {
leftPaneEl.focus();
}
const searchResultsEl = document.querySelector(
'.module-search-results'
);
if (searchResultsEl) {
searchResultsEl.focus();
}
}
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
return; return;
@ -1852,12 +1870,14 @@
{ {
writeNewAttachmentData, writeNewAttachmentData,
deleteAttachmentData, deleteAttachmentData,
doesAttachmentExist,
} }
); );
conversation.set(newAttributes); conversation.set(newAttributes);
} }
window.Signal.Data.updateConversation(id, conversation.attributes); window.Signal.Data.updateConversation(id, conversation.attributes);
const { expireTimer } = details; const { expireTimer } = details;
const isValidExpireTimer = typeof expireTimer === 'number'; const isValidExpireTimer = typeof expireTimer === 'number';
if (isValidExpireTimer) { if (isValidExpireTimer) {
@ -1934,6 +1954,7 @@
{ {
writeNewAttachmentData, writeNewAttachmentData,
deleteAttachmentData, deleteAttachmentData,
doesAttachmentExist,
} }
); );
conversation.set(newAttributes); conversation.set(newAttributes);

View File

@ -30,6 +30,7 @@
const { Conversation, Contact, Message, PhoneNumber } = window.Signal.Types; const { Conversation, Contact, Message, PhoneNumber } = window.Signal.Types;
const { const {
deleteAttachmentData, deleteAttachmentData,
doesAttachmentExist,
getAbsoluteAttachmentPath, getAbsoluteAttachmentPath,
loadAttachmentData, loadAttachmentData,
readStickerData, readStickerData,
@ -1746,7 +1747,6 @@
error && error.stack ? error.stack : error error && error.stack ? error.stack : error
); );
await c.dropProfileKey(); await c.dropProfileKey();
return;
} }
try { try {
@ -1814,6 +1814,7 @@
{ {
writeNewAttachmentData, writeNewAttachmentData,
deleteAttachmentData, deleteAttachmentData,
doesAttachmentExist,
} }
); );
this.set(newAttributes); this.set(newAttributes);

View File

@ -114,6 +114,7 @@ function initializeMigrations({
createReader, createReader,
createWriterForExisting, createWriterForExisting,
createWriterForNew, createWriterForNew,
createDoesExist,
getDraftPath, getDraftPath,
getPath, getPath,
getStickersPath, getStickersPath,
@ -139,6 +140,7 @@ function initializeMigrations({
const copyIntoAttachmentsDirectory = Attachments.copyIntoAttachmentsDirectory( const copyIntoAttachmentsDirectory = Attachments.copyIntoAttachmentsDirectory(
attachmentsPath attachmentsPath
); );
const doesAttachmentExist = createDoesExist(attachmentsPath);
const stickersPath = getStickersPath(userDataPath); const stickersPath = getStickersPath(userDataPath);
const writeNewStickerData = createWriterForNew(stickersPath); const writeNewStickerData = createWriterForNew(stickersPath);
@ -173,6 +175,7 @@ function initializeMigrations({
}), }),
deleteSticker, deleteSticker,
deleteTempFile, deleteTempFile,
doesAttachmentExist,
getAbsoluteAttachmentPath, getAbsoluteAttachmentPath,
getAbsoluteDraftPath, getAbsoluteDraftPath,
getAbsoluteStickerPath, getAbsoluteStickerPath,

View File

@ -1,4 +1,4 @@
/* global crypto */ /* global crypto, window */
const { isFunction, isNumber } = require('lodash'); const { isFunction, isNumber } = require('lodash');
const { createLastMessageUpdate } = require('../../../ts/types/Conversation'); const { createLastMessageUpdate } = require('../../../ts/types/Conversation');
@ -16,17 +16,26 @@ function buildAvatarUpdater({ field }) {
} }
const avatar = conversation[field]; const avatar = conversation[field];
const { writeNewAttachmentData, deleteAttachmentData } = options; const {
if (!isFunction(writeNewAttachmentData)) { deleteAttachmentData,
throw new Error( doesAttachmentExist,
'Conversation.buildAvatarUpdater: writeNewAttachmentData must be a function' writeNewAttachmentData,
); } = options;
}
if (!isFunction(deleteAttachmentData)) { if (!isFunction(deleteAttachmentData)) {
throw new Error( throw new Error(
'Conversation.buildAvatarUpdater: deleteAttachmentData must be a function' 'Conversation.buildAvatarUpdater: deleteAttachmentData must be a function'
); );
} }
if (!isFunction(doesAttachmentExist)) {
throw new Error(
'Conversation.buildAvatarUpdater: deleteAttachmentData must be a function'
);
}
if (!isFunction(writeNewAttachmentData)) {
throw new Error(
'Conversation.buildAvatarUpdater: writeNewAttachmentData must be a function'
);
}
const newHash = await computeHash(data); const newHash = await computeHash(data);
@ -41,8 +50,14 @@ function buildAvatarUpdater({ field }) {
} }
const { hash, path } = avatar; const { hash, path } = avatar;
const exists = await doesAttachmentExist(path);
if (!exists) {
window.log.warn(
`Conversation.buildAvatarUpdater: attachment ${path} did not exist`
);
}
if (hash === newHash) { if (exists && hash === newHash) {
return conversation; return conversation;
} }

View File

@ -556,6 +556,30 @@ MessageSender.prototype = {
return this.server.getStickerPackManifest(packId); return this.server.getStickerPackManifest(packId);
}, },
sendRequestBlockSyncMessage(options) {
const myNumber = textsecure.storage.user.getNumber();
const myDevice = textsecure.storage.user.getDeviceId();
if (myDevice !== 1 && myDevice !== '1') {
const request = new textsecure.protobuf.SyncMessage.Request();
request.type = textsecure.protobuf.SyncMessage.Request.Type.BLOCKED;
const syncMessage = this.createSyncMessage();
syncMessage.request = request;
const contentMessage = new textsecure.protobuf.Content();
contentMessage.syncMessage = syncMessage;
const silent = true;
return this.sendIndividualProto(
myNumber,
contentMessage,
Date.now(),
silent,
options
);
}
return Promise.resolve();
},
sendRequestConfigurationSyncMessage(options) { sendRequestConfigurationSyncMessage(options) {
const myNumber = textsecure.storage.user.getNumber(); const myNumber = textsecure.storage.user.getNumber();
const myDevice = textsecure.storage.user.getDeviceId(); const myDevice = textsecure.storage.user.getDeviceId();
@ -1236,6 +1260,10 @@ textsecure.MessageSender = function MessageSenderWrapper(username, password) {
this.sendRequestConfigurationSyncMessage = sender.sendRequestConfigurationSyncMessage.bind( this.sendRequestConfigurationSyncMessage = sender.sendRequestConfigurationSyncMessage.bind(
sender sender
); );
this.sendRequestBlockSyncMessage = sender.sendRequestBlockSyncMessage.bind(
sender
);
this.sendMessageToNumber = sender.sendMessageToNumber.bind(sender); this.sendMessageToNumber = sender.sendMessageToNumber.bind(sender);
this.sendMessage = sender.sendMessage.bind(sender); this.sendMessage = sender.sendMessage.bind(sender);
this.resetSession = sender.resetSession.bind(sender); this.resetSession = sender.resetSession.bind(sender);

View File

@ -32,6 +32,9 @@
window.log.info('SyncRequest created. Sending config sync request...'); window.log.info('SyncRequest created. Sending config sync request...');
wrap(sender.sendRequestConfigurationSyncMessage(sendOptions)); wrap(sender.sendRequestConfigurationSyncMessage(sendOptions));
window.log.info('SyncRequest now sending block sync request...');
wrap(sender.sendRequestBlockSyncMessage(sendOptions));
window.log.info('SyncRequest now sending contact sync message...'); window.log.info('SyncRequest now sending contact sync message...');
wrap(sender.sendRequestContactSyncMessage(sendOptions)) wrap(sender.sendRequestContactSyncMessage(sendOptions))
.then(() => { .then(() => {

View File

@ -191,7 +191,7 @@
ev.code = code; ev.code = code;
ev.reason = reason; ev.reason = reason;
this.dispatchEvent(ev); this.dispatchEvent(ev);
}, 1000); }, 5000);
}; };
}; };
window.WebSocketResource.prototype = new textsecure.EventTarget(); window.WebSocketResource.prototype = new textsecure.EventTarget();
@ -227,7 +227,7 @@
this.disconnectTimer = setTimeout(() => { this.disconnectTimer = setTimeout(() => {
clearTimeout(this.keepAliveTimer); clearTimeout(this.keepAliveTimer);
this.wsr.close(3001, 'No response to keepalive request'); this.wsr.close(3001, 'No response to keepalive request');
}, 1000); }, 10000);
} else { } else {
this.reset(); this.reset();
} }

View File

@ -166,11 +166,15 @@ function prepareURL(pathSegments, moreKeys) {
}); });
} }
function handleUrl(event, target) { async function handleUrl(event, target) {
event.preventDefault(); event.preventDefault();
const { protocol } = url.parse(target); const { protocol } = url.parse(target);
if (protocol === 'http:' || protocol === 'https:') { if (protocol === 'http:' || protocol === 'https:') {
shell.openExternal(target); try {
await shell.openExternal(target);
} catch (error) {
console.log(`Failed to open url: ${error.stack}`);
}
} }
} }

View File

@ -70,7 +70,7 @@
"fs-extra": "5.0.0", "fs-extra": "5.0.0",
"fuse.js": "3.4.4", "fuse.js": "3.4.4",
"glob": "7.1.2", "glob": "7.1.2",
"google-libphonenumber": "3.2.2", "google-libphonenumber": "3.2.6",
"got": "8.2.0", "got": "8.2.0",
"he": "1.2.0", "he": "1.2.0",
"intl-tel-input": "12.1.15", "intl-tel-input": "12.1.15",

View File

@ -6831,13 +6831,27 @@ button.module-image__border-overlay:focus {
padding: 6px; padding: 6px;
@include light-theme { @include light-theme {
&:hover, &:hover {
background-color: $color-gray-05;
}
}
@include keyboard-mode {
&:hover {
background-color: inherit;
}
&:focus { &:focus {
background-color: $color-gray-05; background-color: $color-gray-05;
} }
} }
@include dark-theme { @include dark-theme {
&:hover, &:hover {
background-color: $color-gray-60;
}
}
@include dark-keyboard-mode {
&:hover {
background-color: inherit;
}
&:focus { &:focus {
background-color: $color-gray-60; background-color: $color-gray-60;
} }
@ -7009,6 +7023,7 @@ button.module-image__border-overlay:focus {
align-items: center; align-items: center;
break-inside: avoid; break-inside: avoid;
padding-left: 4px;
min-height: 40px; min-height: 40px;
outline: none; outline: none;

View File

@ -24,6 +24,7 @@ export interface Props {
interface State { interface State {
imageBroken: boolean; imageBroken: boolean;
lastAvatarPath?: string;
} }
export class Avatar extends React.Component<Props, State> { export class Avatar extends React.Component<Props, State> {
@ -35,10 +36,23 @@ export class Avatar extends React.Component<Props, State> {
this.handleImageErrorBound = this.handleImageError.bind(this); this.handleImageErrorBound = this.handleImageError.bind(this);
this.state = { this.state = {
lastAvatarPath: props.avatarPath,
imageBroken: false, imageBroken: false,
}; };
} }
public static getDerivedStateFromProps(props: Props, state: State): State {
if (props.avatarPath !== state.lastAvatarPath) {
return {
...state,
lastAvatarPath: props.avatarPath,
imageBroken: false,
};
}
return state;
}
public handleImageError() { public handleImageError() {
// tslint:disable-next-line no-console // tslint:disable-next-line no-console
console.log('Avatar: Image failed to load; failing over to placeholder'); console.log('Avatar: Image failed to load; failing over to placeholder');

View File

@ -700,6 +700,13 @@ export const CompositionInput = ({
return null; return null;
} }
// Get rid of Ctrl-/, which on GNOME is bound to 'select all'
if (e.key === '/' && !e.shiftKey && e.ctrlKey) {
e.preventDefault();
return null;
}
return getDefaultKeyBinding(e); return getDefaultKeyBinding(e);
}, },
[emojiResults, large] [emojiResults, large]

View File

@ -70,15 +70,6 @@ export class MainHeader extends React.Component<PropsType, StateType> {
}; };
} }
public componentDidMount() {
const popperRoot = document.createElement('div');
document.body.appendChild(popperRoot);
this.setState({
popperRoot,
});
}
public componentDidUpdate(prevProps: PropsType) { public componentDidUpdate(prevProps: PropsType) {
const { searchConversationId, startSearchCounter } = this.props; const { searchConversationId, startSearchCounter } = this.props;
@ -114,28 +105,41 @@ export class MainHeader extends React.Component<PropsType, StateType> {
}; };
public showAvatarPopup = () => { public showAvatarPopup = () => {
const popperRoot = document.createElement('div');
document.body.appendChild(popperRoot);
this.setState({ this.setState({
showingAvatarPopup: true, showingAvatarPopup: true,
popperRoot,
}); });
document.addEventListener('click', this.handleOutsideClick); document.addEventListener('click', this.handleOutsideClick);
document.addEventListener('keydown', this.handleOutsideKeyDown); document.addEventListener('keydown', this.handleOutsideKeyDown);
}; };
public hideAvatarPopup = () => { public hideAvatarPopup = () => {
const { popperRoot } = this.state;
document.removeEventListener('click', this.handleOutsideClick); document.removeEventListener('click', this.handleOutsideClick);
document.removeEventListener('keydown', this.handleOutsideKeyDown); document.removeEventListener('keydown', this.handleOutsideKeyDown);
this.setState({ this.setState({
showingAvatarPopup: false, showingAvatarPopup: false,
popperRoot: null,
}); });
if (popperRoot) {
document.body.removeChild(popperRoot);
}
}; };
public componentWillUnmount() { public componentWillUnmount() {
const { popperRoot } = this.state; const { popperRoot } = this.state;
document.removeEventListener('click', this.handleOutsideClick);
document.removeEventListener('keydown', this.handleOutsideKeyDown);
if (popperRoot) { if (popperRoot) {
document.body.removeChild(popperRoot); document.body.removeChild(popperRoot);
document.removeEventListener('click', this.handleOutsideClick);
document.removeEventListener('keydown', this.handleOutsideKeyDown);
} }
} }

View File

@ -162,20 +162,6 @@ export class Image extends React.Component<Props> {
alt={i18n('imageCaptionIconAlt')} alt={i18n('imageCaptionIconAlt')}
/> />
) : null} ) : null}
{closeButton ? (
<button
onClick={(e: React.MouseEvent<{}>) => {
e.preventDefault();
e.stopPropagation();
if (onClickClose) {
onClickClose(attachment);
}
}}
className="module-image__close-button"
title={i18n('remove-attachment')}
/>
) : null}
{bottomOverlay ? ( {bottomOverlay ? (
<div <div
className={classNames( className={classNames(
@ -199,6 +185,20 @@ export class Image extends React.Component<Props> {
</div> </div>
) : null} ) : null}
{overlay} {overlay}
{closeButton ? (
<button
onClick={(e: React.MouseEvent<{}>) => {
e.preventDefault();
e.stopPropagation();
if (onClickClose) {
onClickClose(attachment);
}
}}
className="module-image__close-button"
title={i18n('remove-attachment')}
/>
) : null}
</div> </div>
); );
} }

View File

@ -33,6 +33,7 @@ export const actions = {
}; };
function userChanged(attributes: { function userChanged(attributes: {
interactionMode?: 'mouse' | 'keyboard';
ourNumber: string; ourNumber: string;
regionCode: string; regionCode: string;
}): UserChangedActionType { }): UserChangedActionType {

View File

@ -1292,18 +1292,26 @@
{ {
"rule": "jQuery-wrap(", "rule": "jQuery-wrap(",
"path": "libtextsecure/sync_request.js", "path": "libtextsecure/sync_request.js",
"line": " wrap(sender.sendRequestContactSyncMessage(sendOptions))", "line": " wrap(sender.sendRequestBlockSyncMessage(sendOptions));",
"lineNumber": 36, "lineNumber": 36,
"reasonCategory": "falseMatch", "reasonCategory": "falseMatch",
"updated": "2018-10-05T23:12:28.961Z" "updated": "2019-12-03T00:28:08.683Z"
},
{
"rule": "jQuery-wrap(",
"path": "libtextsecure/sync_request.js",
"line": " wrap(sender.sendRequestContactSyncMessage(sendOptions))",
"lineNumber": 39,
"reasonCategory": "falseMatch",
"updated": "2019-12-03T00:28:08.683Z"
}, },
{ {
"rule": "jQuery-wrap(", "rule": "jQuery-wrap(",
"path": "libtextsecure/sync_request.js", "path": "libtextsecure/sync_request.js",
"line": " return wrap(sender.sendRequestGroupSyncMessage(sendOptions));", "line": " return wrap(sender.sendRequestGroupSyncMessage(sendOptions));",
"lineNumber": 39, "lineNumber": 42,
"reasonCategory": "falseMatch", "reasonCategory": "falseMatch",
"updated": "2018-10-05T23:12:28.961Z" "updated": "2019-12-03T00:28:08.683Z"
}, },
{ {
"rule": "jQuery-wrap(", "rule": "jQuery-wrap(",
@ -3673,7 +3681,7 @@
"rule": "eval", "rule": "eval",
"path": "node_modules/google-libphonenumber/dist/libphonenumber.js", "path": "node_modules/google-libphonenumber/dist/libphonenumber.js",
"line": " var a = !eval('\"use strict\";let x = 1; function f() { return typeof x; };f() == \"number\";');", "line": " var a = !eval('\"use strict\";let x = 1; function f() { return typeof x; };f() == \"number\";');",
"lineNumber": 232, "lineNumber": 233,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2018-11-27T01:31:13.384Z", "updated": "2018-11-27T01:31:13.384Z",
"reasonDetail": "Hard-coded string used for testing capabilities." "reasonDetail": "Hard-coded string used for testing capabilities."
@ -3682,25 +3690,16 @@
"rule": "eval", "rule": "eval",
"path": "node_modules/google-libphonenumber/dist/libphonenumber.js", "path": "node_modules/google-libphonenumber/dist/libphonenumber.js",
"line": " eval(a);", "line": " eval(a);",
"lineNumber": 267, "lineNumber": 268,
"reasonCategory": "notExercisedByOurApp", "reasonCategory": "notExercisedByOurApp",
"updated": "2018-11-27T01:31:13.384Z", "updated": "2018-11-27T01:31:13.384Z",
"reasonDetail": "Used to load dependencies; parent function loadModuleFromSource_ is used in one place only." "reasonDetail": "Used to load dependencies; parent function loadModuleFromSource_ is used in one place only."
}, },
{
"rule": "eval",
"path": "node_modules/google-libphonenumber/dist/libphonenumber.js",
"line": " eval(g + \"\\n//# sourceURL=\" + f);",
"lineNumber": 298,
"reasonCategory": "notExercisedByOurApp",
"updated": "2019-04-12T00:50:12.124Z",
"reasonDetail": "Used for google closure compiler transpilation scenarios"
},
{ {
"rule": "eval", "rule": "eval",
"path": "node_modules/google-libphonenumber/dist/libphonenumber.js", "path": "node_modules/google-libphonenumber/dist/libphonenumber.js",
"line": " goog.global.eval(\"var _evalTest_ = 1;\");", "line": " goog.global.eval(\"var _evalTest_ = 1;\");",
"lineNumber": 444, "lineNumber": 445,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-04-12T00:50:12.124Z", "updated": "2019-04-12T00:50:12.124Z",
"reasonDetail": "Hard-coded string used for testing capabilities" "reasonDetail": "Hard-coded string used for testing capabilities"
@ -3709,7 +3708,7 @@
"rule": "eval", "rule": "eval",
"path": "node_modules/google-libphonenumber/dist/libphonenumber.js", "path": "node_modules/google-libphonenumber/dist/libphonenumber.js",
"line": " goog.global.eval(a);", "line": " goog.global.eval(a);",
"lineNumber": 458, "lineNumber": 459,
"reasonCategory": "notExercisedByOurApp", "reasonCategory": "notExercisedByOurApp",
"updated": "2018-11-27T01:31:13.384Z", "updated": "2018-11-27T01:31:13.384Z",
"reasonDetail": "More transpilation logic" "reasonDetail": "More transpilation logic"
@ -3717,16 +3716,16 @@
{ {
"rule": "jQuery-$(", "rule": "jQuery-$(",
"path": "node_modules/google-libphonenumber/dist/libphonenumber.js", "path": "node_modules/google-libphonenumber/dist/libphonenumber.js",
"line": " b && (a = a.replace(/\\{\\$([^}]+)}/g, function(a, d) {", "line": " b && (a = a.replace(/\\{\\$([^}]+)}/g, function(a, c) {",
"lineNumber": 498, "lineNumber": 500,
"reasonCategory": "falseMatch", "reasonCategory": "falseMatch",
"updated": "2018-11-27T01:31:13.384Z" "updated": "2019-12-03T19:24:21.611Z"
}, },
{ {
"rule": "eval", "rule": "eval",
"path": "node_modules/google-libphonenumber/dist/libphonenumber.js", "path": "node_modules/google-libphonenumber/dist/libphonenumber.js",
"line": " return !!eval(a);", "line": " return !!eval(a);",
"lineNumber": 640, "lineNumber": 642,
"reasonCategory": "notExercisedByOurApp", "reasonCategory": "notExercisedByOurApp",
"updated": "2018-11-27T01:31:13.384Z", "updated": "2018-11-27T01:31:13.384Z",
"reasonDetail": "More transpilation logic" "reasonDetail": "More transpilation logic"
@ -3735,7 +3734,7 @@
"rule": "jQuery-load(", "rule": "jQuery-load(",
"path": "node_modules/google-libphonenumber/dist/libphonenumber.js", "path": "node_modules/google-libphonenumber/dist/libphonenumber.js",
"line": " d.load(f);", "line": " d.load(f);",
"lineNumber": 796, "lineNumber": 794,
"reasonCategory": "notExercisedByOurApp", "reasonCategory": "notExercisedByOurApp",
"updated": "2019-04-12T00:50:12.124Z", "updated": "2019-04-12T00:50:12.124Z",
"reasonDetail": "Part of their google closure 'debug loader'" "reasonDetail": "Part of their google closure 'debug loader'"
@ -3752,11 +3751,29 @@
{ {
"rule": "DOM-innerHTML", "rule": "DOM-innerHTML",
"path": "node_modules/google-libphonenumber/dist/libphonenumber.js", "path": "node_modules/google-libphonenumber/dist/libphonenumber.js",
"line": " e || (d.innerHTML = a + \" \", e = d.firstChild.nodeValue.slice(0, -1));", "line": " a.innerHTML = goog.html.SafeHtml.unwrapTrustedHTML(goog.html.SafeHtml.EMPTY);",
"lineNumber": 2045, "lineNumber": 3448,
"reasonCategory": "notExercisedByOurApp", "reasonCategory": "usageTrusted",
"updated": "2018-11-27T01:31:13.384Z", "updated": "2019-12-03T19:24:21.611Z",
"reasonDetail": "An odd technique of unescaping content by putting it into the dom" "reasonDetail": "HTML is escaped"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/google-libphonenumber/dist/libphonenumber.js",
"line": " a.innerHTML = goog.html.SafeHtml.unwrapTrustedHTML(b);",
"lineNumber": 3457,
"reasonCategory": "usageTrusted",
"updated": "2019-12-03T19:24:21.611Z",
"reasonDetail": "HTML is escaped"
},
{
"rule": "DOM-outerHTML",
"path": "node_modules/google-libphonenumber/dist/libphonenumber.js",
"line": " a.outerHTML = goog.html.SafeHtml.unwrapTrustedHTML(b);",
"lineNumber": 3469,
"reasonCategory": "usageTrusted",
"updated": "2019-12-03T19:24:21.611Z",
"reasonDetail": "HTML is escaped"
}, },
{ {
"rule": "DOM-innerHTML", "rule": "DOM-innerHTML",
@ -7560,7 +7577,7 @@
"rule": "React-createRef", "rule": "React-createRef",
"path": "ts/components/MainHeader.js", "path": "ts/components/MainHeader.js",
"line": " this.inputRef = react_1.default.createRef();", "line": " this.inputRef = react_1.default.createRef();",
"lineNumber": 134, "lineNumber": 142,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-08-09T21:17:57.798Z", "updated": "2019-08-09T21:17:57.798Z",
"reasonDetail": "Used only to set focus" "reasonDetail": "Used only to set focus"

View File

@ -4242,10 +4242,10 @@ glogg@^1.0.1:
dependencies: dependencies:
sparkles "^1.0.0" sparkles "^1.0.0"
google-libphonenumber@3.2.2: google-libphonenumber@3.2.6:
version "3.2.2" version "3.2.6"
resolved "https://registry.yarnpkg.com/google-libphonenumber/-/google-libphonenumber-3.2.2.tgz#3d9d7ba727e99a50812f21b0ed313723b76c5c54" resolved "https://registry.yarnpkg.com/google-libphonenumber/-/google-libphonenumber-3.2.6.tgz#3d725b48ff44706b80246e77f95f2c2fdc6fd729"
integrity sha512-ubjGeosYPeusjYbUHy76lCniGTTI0k1rIFc+uKBX+jHQLDmWOSUtlFUxaeoLJ+Y+PAMM6dWp+C1HjHx5BI8kEw== integrity sha512-6QCQAaKJlSd/1dUqvdQf7zzfb3uiZHsG8yhCfOdCVRfMuPZ/VDIEB47y5SYwjPQJPs7ebfW5jj6PeobB9JJ4JA==
got@8.2.0: got@8.2.0:
version "8.2.0" version "8.2.0"