Revert "Clean up unused dependencies."

pull/1051/head
Vince 4 years ago committed by GitHub
parent 6d591d956d
commit 5ff7476359
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -19,6 +19,7 @@ test/test.js
# Third-party files
js/Mp3LameEncoder.min.js
js/WebAudioRecorderMp3.js
js/libphonenumber-util.js
js/libsignal-protocol-worker.js
libtextsecure/libsignal-protocol.js
libtextsecure/test/blanket_mocha.js

@ -1,4 +1,4 @@
const crypto = require('crypto');
const { sha512 } = require('js-sha512');
const ERRORS = {
TYPE: 'Password must be a string',
@ -6,12 +6,6 @@ const ERRORS = {
CHARACTER: 'Password must only contain letters, numbers and symbols',
};
const sha512 = text => {
const hash = crypto.createHash('sha512');
hash.update(text.trim());
return hash.digest('hex');
};
const generateHash = phrase => phrase && sha512(phrase.trim());
const matchesHash = (phrase, hash) =>
phrase && sha512(phrase.trim()) === hash.trim();

@ -454,6 +454,7 @@
<script type='text/javascript' src='js/delivery_receipts.js'></script>
<script type='text/javascript' src='js/read_receipts.js'></script>
<script type='text/javascript' src='js/read_syncs.js'></script>
<script type='text/javascript' src='js/libphonenumber-util.js'></script>
<script type='text/javascript' src='js/models/messages.js'></script>
<script type='text/javascript' src='js/models/conversations.js'></script>
<script type='text/javascript' src='js/models/blockedNumbers.js'></script>
@ -500,6 +501,7 @@
<script type='text/javascript' src='js/views/identicon_svg_view.js'></script>
<script type='text/javascript' src='js/views/install_view.js'></script>
<script type='text/javascript' src='js/views/banner_view.js'></script>
<script type="text/javascript" src="js/views/phone-input-view.js"></script>
<script type='text/javascript' src='js/views/session_registration_view.js'></script>
<script type='text/javascript' src='js/views/app_view.js'></script>
<script type='text/javascript' src='js/views/import_view.js'></script>

@ -454,6 +454,7 @@
<script type='text/javascript' src='js/delivery_receipts.js'></script>
<script type='text/javascript' src='js/read_receipts.js'></script>
<script type='text/javascript' src='js/read_syncs.js'></script>
<script type='text/javascript' src='js/libphonenumber-util.js'></script>
<script type='text/javascript' src='js/models/messages.js'></script>
<script type='text/javascript' src='js/models/conversations.js'></script>
<script type='text/javascript' src='js/models/blockedNumbers.js'></script>
@ -500,6 +501,7 @@
<script type='text/javascript' src='js/views/identicon_svg_view.js'></script>
<script type='text/javascript' src='js/views/install_view.js'></script>
<script type='text/javascript' src='js/views/banner_view.js'></script>
<script type="text/javascript" src="js/views/phone-input-view.js"></script>
<script type='text/javascript' src='js/views/session_registration_view.js'></script>
<script type='text/javascript' src='js/views/app_view.js'></script>
<script type='text/javascript' src='js/views/import_view.js'></script>

@ -56,6 +56,7 @@
"node_modules/backbone/backbone.js",
"components/indexeddb-backbonejs-adapter/**/*.js",
"components/qrcode/**/*.js",
"node_modules/intl-tel-input/build/js/intlTelInput.js",
"components/autosize/**/*.js",
"components/webaudiorecorder/lib/WebAudioRecorder.js",
"components/multibase/dist/index.js"

@ -569,6 +569,12 @@
// listeners
Whisper.RotateSignedPreKeyListener.init(Whisper.events, newVersion);
// window.Signal.RefreshSenderCertificate.initialize({
// events: Whisper.events,
// storage,
// navigator,
// logger: window.log,
// });
connect(true);
});
@ -591,6 +597,12 @@
) {
// listeners
Whisper.RotateSignedPreKeyListener.init(Whisper.events, newVersion);
// window.Signal.RefreshSenderCertificate.initialize({
// events: Whisper.events,
// storage,
// navigator,
// logger: window.log,
// });
connect();
appView.openInbox({
@ -1535,8 +1547,35 @@
textsecure.storage.user.getDeviceId() != '1'
) {
window.getSyncRequest();
try {
const manager = window.getAccountManager();
await Promise.all([
manager.maybeUpdateDeviceName(),
manager.maybeDeleteSignalingKey(),
]);
} catch (e) {
window.log.error(
'Problem with account manager updates after starting new version: ',
e && e.stack ? e.stack : e
);
}
}
// const udSupportKey = 'hasRegisterSupportForUnauthenticatedDelivery';
// if (!storage.get(udSupportKey)) {
// const server = WebAPI.connect({ username: USERNAME, password: PASSWORD });
// try {
// await server.registerSupportForUnauthenticatedDelivery();
// storage.put(udSupportKey, true);
// } catch (error) {
// window.log.error(
// 'Error: Unable to register for unauthenticated delivery support.',
// error && error.stack ? error.stack : error
// );
// }
// }
const deviceId = textsecure.storage.user.getDeviceId();
if (firstRun === true && deviceId !== '1') {
const hasThemeSetting = Boolean(storage.get('theme-setting'));

@ -0,0 +1,295 @@
(function() {
'use strict';
/*
* This file extends the libphonenumber object with a set of phonenumbery
* utility functions. libphonenumber must be included before you call these
* functions, but the order of the files/script-tags doesn't matter.
*/
window.libphonenumber = window.libphonenumber || {};
window.libphonenumber.util = {
getRegionCodeForNumber: function(number) {
try {
var parsedNumber = libphonenumber.parse(number);
return libphonenumber.getRegionCodeForNumber(parsedNumber);
} catch (e) {
return 'ZZ';
}
},
splitCountryCode: function(number) {
var parsedNumber = libphonenumber.parse(number);
return {
country_code: parsedNumber.values_[1],
national_number: parsedNumber.values_[2],
};
},
getCountryCode: function(regionCode) {
var cc = libphonenumber.getCountryCodeForRegion(regionCode);
return cc !== 0 ? cc : '';
},
parseNumber: function(number, defaultRegionCode) {
try {
var parsedNumber = libphonenumber.parse(number, defaultRegionCode);
return {
isValidNumber: libphonenumber.isValidNumber(parsedNumber),
regionCode: libphonenumber.getRegionCodeForNumber(parsedNumber),
countryCode: '' + parsedNumber.getCountryCode(),
nationalNumber: '' + parsedNumber.getNationalNumber(),
e164: libphonenumber.format(
parsedNumber,
libphonenumber.PhoneNumberFormat.E164
),
};
} catch (ex) {
return { error: ex, isValidNumber: false };
}
},
getAllRegionCodes: function() {
return {
AD: 'Andorra',
AE: 'United Arab Emirates',
AF: 'Afghanistan',
AG: 'Antigua and Barbuda',
AI: 'Anguilla',
AL: 'Albania',
AM: 'Armenia',
AO: 'Angola',
AR: 'Argentina',
AS: 'AmericanSamoa',
AT: 'Austria',
AU: 'Australia',
AW: 'Aruba',
AX: 'Åland Islands',
AZ: 'Azerbaijan',
BA: 'Bosnia and Herzegovina',
BB: 'Barbados',
BD: 'Bangladesh',
BE: 'Belgium',
BF: 'Burkina Faso',
BG: 'Bulgaria',
BH: 'Bahrain',
BI: 'Burundi',
BJ: 'Benin',
BL: 'Saint Barthélemy',
BM: 'Bermuda',
BN: 'Brunei Darussalam',
BO: 'Bolivia, Plurinational State of',
BR: 'Brazil',
BS: 'Bahamas',
BT: 'Bhutan',
BW: 'Botswana',
BY: 'Belarus',
BZ: 'Belize',
CA: 'Canada',
CC: 'Cocos (Keeling) Islands',
CD: 'Congo, The Democratic Republic of the',
CF: 'Central African Republic',
CG: 'Congo',
CH: 'Switzerland',
CI: "Cote d'Ivoire",
CK: 'Cook Islands',
CL: 'Chile',
CM: 'Cameroon',
CN: 'China',
CO: 'Colombia',
CR: 'Costa Rica',
CU: 'Cuba',
CV: 'Cape Verde',
CX: 'Christmas Island',
CY: 'Cyprus',
CZ: 'Czech Republic',
DE: 'Germany',
DJ: 'Djibouti',
DK: 'Denmark',
DM: 'Dominica',
DO: 'Dominican Republic',
DZ: 'Algeria',
EC: 'Ecuador',
EE: 'Estonia',
EG: 'Egypt',
ER: 'Eritrea',
ES: 'Spain',
ET: 'Ethiopia',
FI: 'Finland',
FJ: 'Fiji',
FK: 'Falkland Islands (Malvinas)',
FM: 'Micronesia, Federated States of',
FO: 'Faroe Islands',
FR: 'France',
GA: 'Gabon',
GB: 'United Kingdom',
GD: 'Grenada',
GE: 'Georgia',
GF: 'French Guiana',
GG: 'Guernsey',
GH: 'Ghana',
GI: 'Gibraltar',
GL: 'Greenland',
GM: 'Gambia',
GN: 'Guinea',
GP: 'Guadeloupe',
GQ: 'Equatorial Guinea',
GR: 'Ελλάδα',
GT: 'Guatemala',
GU: 'Guam',
GW: 'Guinea-Bissau',
GY: 'Guyana',
HK: 'Hong Kong',
HN: 'Honduras',
HR: 'Croatia',
HT: 'Haiti',
HU: 'Magyarország',
ID: 'Indonesia',
IE: 'Ireland',
IL: 'Israel',
IM: 'Isle of Man',
IN: 'India',
IO: 'British Indian Ocean Territory',
IQ: 'Iraq',
IR: 'Iran, Islamic Republic of',
IS: 'Iceland',
IT: 'Italy',
JE: 'Jersey',
JM: 'Jamaica',
JO: 'Jordan',
JP: 'Japan',
KE: 'Kenya',
KG: 'Kyrgyzstan',
KH: 'Cambodia',
KI: 'Kiribati',
KM: 'Comoros',
KN: 'Saint Kitts and Nevis',
KP: "Korea, Democratic People's Republic of",
KR: 'Korea, Republic of',
KW: 'Kuwait',
KY: 'Cayman Islands',
KZ: 'Kazakhstan',
LA: "Lao People's Democratic Republic",
LB: 'Lebanon',
LC: 'Saint Lucia',
LI: 'Liechtenstein',
LK: 'Sri Lanka',
LR: 'Liberia',
LS: 'Lesotho',
LT: 'Lithuania',
LU: 'Luxembourg',
LV: 'Latvia',
LY: 'Libyan Arab Jamahiriya',
MA: 'Morocco',
MC: 'Monaco',
MD: 'Moldova, Republic of',
ME: 'Црна Гора',
MF: 'Saint Martin',
MG: 'Madagascar',
MH: 'Marshall Islands',
MK: 'Macedonia, The Former Yugoslav Republic of',
ML: 'Mali',
MM: 'Myanmar',
MN: 'Mongolia',
MO: 'Macao',
MP: 'Northern Mariana Islands',
MQ: 'Martinique',
MR: 'Mauritania',
MS: 'Montserrat',
MT: 'Malta',
MU: 'Mauritius',
MV: 'Maldives',
MW: 'Malawi',
MX: 'Mexico',
MY: 'Malaysia',
MZ: 'Mozambique',
NA: 'Namibia',
NC: 'New Caledonia',
NE: 'Niger',
NF: 'Norfolk Island',
NG: 'Nigeria',
NI: 'Nicaragua',
NL: 'Netherlands',
NO: 'Norway',
NP: 'Nepal',
NR: 'Nauru',
NU: 'Niue',
NZ: 'New Zealand',
OM: 'Oman',
PA: 'Panama',
PE: 'Peru',
PF: 'French Polynesia',
PG: 'Papua New Guinea',
PH: 'Philippines',
PK: 'Pakistan',
PL: 'Polska',
PM: 'Saint Pierre and Miquelon',
PR: 'Puerto Rico',
PS: 'Palestinian Territory, Occupied',
PT: 'Portugal',
PW: 'Palau',
PY: 'Paraguay',
QA: 'Qatar',
RE: 'Réunion',
RO: 'Romania',
RS: 'Србија',
RU: 'Russia',
RW: 'Rwanda',
SA: 'Saudi Arabia',
SB: 'Solomon Islands',
SC: 'Seychelles',
SD: 'Sudan',
SE: 'Sweden',
SG: 'Singapore',
SH: 'Saint Helena, Ascension and Tristan Da Cunha',
SI: 'Slovenia',
SJ: 'Svalbard and Jan Mayen',
SK: 'Slovakia',
SL: 'Sierra Leone',
SM: 'San Marino',
SN: 'Senegal',
SO: 'Somalia',
SR: 'Suriname',
ST: 'Sao Tome and Principe',
SV: 'El Salvador',
SY: 'Syrian Arab Republic',
SZ: 'Swaziland',
TC: 'Turks and Caicos Islands',
TD: 'Chad',
TG: 'Togo',
TH: 'Thailand',
TJ: 'Tajikistan',
TK: 'Tokelau',
TL: 'Timor-Leste',
TM: 'Turkmenistan',
TN: 'Tunisia',
TO: 'Tonga',
TR: 'Turkey',
TT: 'Trinidad and Tobago',
TV: 'Tuvalu',
TW: 'Taiwan, Province of China',
TZ: 'Tanzania, United Republic of',
UA: 'Ukraine',
UG: 'Uganda',
US: 'United States',
UY: 'Uruguay',
UZ: 'Uzbekistan',
VA: 'Holy See (Vatican City State)',
VC: 'Saint Vincent and the Grenadines',
VE: 'Venezuela',
VG: 'Virgin Islands, British',
VI: 'Virgin Islands, U.S.',
VN: 'Viet Nam',
VU: 'Vanuatu',
WF: 'Wallis and Futuna',
WS: 'Samoa',
YE: 'Yemen',
YT: 'Mayotte',
ZA: 'South Africa',
ZM: 'Zambia',
ZW: 'Zimbabwe',
};
}, // getAllRegionCodes
}; // libphonenumber.util
})();

@ -2,24 +2,46 @@
/* global window */
const FormData = require('form-data');
const fetch = require('node-fetch');
const got = require('got');
const BASE_URL = 'https://debuglogs.org';
const VERSION = window.getVersion();
const USER_AGENT = `Session ${VERSION}`;
// Workaround: Submitting `FormData` using native `FormData::submit` procedure
// as integration with `got` results in S3 error saying we havent set the
// `Content-Length` header:
// https://github.com/sindresorhus/got/pull/466
const submitFormData = (form, url) =>
new Promise((resolve, reject) => {
form.submit(url, (error, response) => {
if (error) {
return reject(error);
}
const { statusCode } = response;
if (statusCode !== 204) {
return reject(
new Error(`Failed to upload to S3, got status ${statusCode}`)
);
}
return resolve();
});
});
// upload :: String -> Promise URL
exports.upload = async content => {
const signedForm = await fetch(BASE_URL, {
const signedForm = await got.get(BASE_URL, {
json: true,
headers: {
'user-agent': USER_AGENT,
},
});
const json = await signedForm.json();
if (!signedForm.ok || !json) {
if (!signedForm.body) {
throw new Error('Failed to retrieve token');
}
const { fields, url } = json;
const { fields, url } = signedForm.body;
const form = new FormData();
// The API expects `key` to be the first field:
@ -38,15 +60,9 @@ exports.upload = async content => {
filename: `session-desktop-debug-log-${VERSION}.txt`,
});
const result = await fetch(url, {
method: 'POST',
body: form,
});
const { status } = result;
if (status !== 204) {
throw new Error(`Failed to upload to S3, got status ${status}`);
}
// WORKAROUND: See comment on `submitFormData`:
// await got.post(url, { body: form });
await submitFormData(form, url);
return `${BASE_URL}/${fields.key}`;
};

@ -19,7 +19,7 @@ const timeoutDelay = ms => new Promise(resolve => setTimeout(resolve, ms));
class LokiSnodeAPI {
constructor({ serverUrl, localUrl }) {
if (!is.string(serverUrl)) {
throw new Error('LokiSnodeAPI.initialize: Invalid server url');
throw new Error('WebAPI.initialize: Invalid server url');
}
this.serverUrl = serverUrl; // random.snode
this.localUrl = localUrl; // localhost.loki

@ -7,7 +7,7 @@ const { compose } = require('lodash/fp');
const { escapeRegExp } = require('lodash');
const APP_ROOT_PATH = path.join(__dirname, '..', '..', '..');
const SESSION_ID_PATTERN = /\b(05[0-9a-f]{64})\b/gi;
const PHONE_NUMBER_PATTERN = /\+\d{7,12}(\d{3})/g;
const GROUP_ID_PATTERN = /(group\()([^)]+)(\))/g;
const REDACTION_PLACEHOLDER = '[REDACTED]';
@ -55,13 +55,13 @@ exports._pathToRegExp = filePath => {
};
// Public API
// redactSessionID :: String -> String
exports.redactSessionID = text => {
// redactPhoneNumbers :: String -> String
exports.redactPhoneNumbers = text => {
if (!is.string(text)) {
throw new TypeError("'text' must be a string");
}
return text.replace(SESSION_ID_PATTERN, REDACTION_PLACEHOLDER);
return text.replace(PHONE_NUMBER_PATTERN, `+${REDACTION_PLACEHOLDER}$1`);
};
// redactGroupIds :: String -> String
@ -84,7 +84,7 @@ exports.redactSensitivePaths = exports._redactPath(APP_ROOT_PATH);
exports.redactAll = compose(
exports.redactSensitivePaths,
exports.redactGroupIds,
exports.redactSessionID
exports.redactPhoneNumbers
);
const removeNewlines = text => text.replace(/\r?\n|\r/g, '');

@ -0,0 +1,120 @@
/* global window, setTimeout, clearTimeout, textsecure, WebAPI, ConversationController */
module.exports = {
initialize,
};
const ONE_DAY = 24 * 60 * 60 * 1000; // one day
const MINIMUM_TIME_LEFT = 2 * 60 * 60 * 1000; // two hours
let timeout = null;
let scheduledTime = null;
let scheduleNext = null;
// We need to refresh our own profile regularly to account for newly-added devices which
// do not support unidentified delivery.
function refreshOurProfile() {
const ourNumber = textsecure.storage.user.getNumber();
const conversation = ConversationController.getOrCreate(ourNumber, 'private');
conversation.getProfiles();
}
function initialize({ events, storage, navigator, logger }) {
// We don't want to set up all of the below functions, but we do want to ensure that our
// refresh timer is up-to-date.
if (scheduleNext) {
scheduleNext();
return;
}
runWhenOnline();
events.on('timetravel', scheduleNextRotation);
function scheduleNextRotation() {
const now = Date.now();
const certificate = storage.get('senderCertificate');
if (!certificate) {
setTimeoutForNextRun(now);
return;
}
// The useful information in a SenderCertificate is all serialized, so we
// need to do another layer of decoding.
const decoded = textsecure.protobuf.SenderCertificate.Certificate.decode(
certificate.certificate
);
const expires = decoded.expires.toNumber();
const time = Math.min(now + ONE_DAY, expires - MINIMUM_TIME_LEFT);
setTimeoutForNextRun(time);
}
// Keeping this entrypoint around so more inialize() calls just kick the timing
scheduleNext = scheduleNextRotation;
async function run() {
logger.info('refreshSenderCertificate: Getting new certificate...');
try {
const username = storage.get('number_id');
const password = storage.get('password');
const server = WebAPI.connect({ username, password });
const { certificate } = await server.getSenderCertificate();
const arrayBuffer = window.Signal.Crypto.base64ToArrayBuffer(certificate);
const decoded = textsecure.protobuf.SenderCertificate.decode(arrayBuffer);
decoded.certificate = decoded.certificate.toArrayBuffer();
decoded.signature = decoded.signature.toArrayBuffer();
decoded.serialized = arrayBuffer;
storage.put('senderCertificate', decoded);
scheduleNextRotation();
} catch (error) {
logger.error(
'refreshSenderCertificate: Get failed. Trying again in two minutes...',
error && error.stack ? error.stack : error
);
setTimeout(runWhenOnline, 2 * 60 * 1000);
}
refreshOurProfile();
}
function runWhenOnline() {
if (navigator.onLine) {
run();
} else {
logger.info(
'refreshSenderCertificate: Offline. Will update certificate when online...'
);
const listener = () => {
logger.info(
'refreshSenderCertificate: Online. Now updating certificate...'
);
window.removeEventListener('online', listener);
run();
};
window.addEventListener('online', listener);
}
}
function setTimeoutForNextRun(time = Date.now()) {
const now = Date.now();
if (scheduledTime !== time || !timeout) {
logger.info(
'Next sender certificate refresh scheduled for',
new Date(time).toISOString()
);
}
scheduledTime = time;
const waitTime = Math.max(0, time - now);
clearTimeout(timeout);
timeout = setTimeout(runWhenOnline, waitTime);
}
}

@ -13,6 +13,7 @@ const Settings = require('./settings');
const Util = require('../../ts/util');
const { migrateToSQL } = require('./migrate_to_sql');
const Metadata = require('./metadata/SecretSessionCipher');
const RefreshSenderCertificate = require('./refresh_sender_certificate');
const LinkPreviews = require('./link_previews');
const AttachmentDownloads = require('./attachment_downloads');
@ -378,6 +379,7 @@ exports.setup = (options = {}) => {
Migrations,
Notifications,
OS,
RefreshSenderCertificate,
Settings,
State,
Types,

@ -1,7 +1,11 @@
const WebSocket = require('websocket').w3cwebsocket;
const fetch = require('node-fetch');
const ProxyAgent = require('proxy-agent');
const { Agent } = require('https');
const FormData = require('form-data');
const is = require('@sindresorhus/is');
/* global Buffer, setTimeout, log, _, lokiFileServerAPI */
/* eslint-disable more/no-then, no-bitwise, no-nested-ternary */
@ -35,6 +39,89 @@ function _getString(thing) {
return thing;
}
function _b64ToUint6(nChr) {
return nChr > 64 && nChr < 91
? nChr - 65
: nChr > 96 && nChr < 123
? nChr - 71
: nChr > 47 && nChr < 58
? nChr + 4
: nChr === 43
? 62
: nChr === 47
? 63
: 0;
}
function _getStringable(thing) {
return (
typeof thing === 'string' ||
typeof thing === 'number' ||
typeof thing === 'boolean' ||
(thing === Object(thing) &&
(_call(thing) === ArrayBufferToString ||
_call(thing) === Uint8ArrayToString))
);
}
function _ensureStringed(thing) {
if (_getStringable(thing)) {
return _getString(thing);
} else if (thing instanceof Array) {
const res = [];
for (let i = 0; i < thing.length; i += 1) {
res[i] = _ensureStringed(thing[i]);
}
return res;
} else if (thing === Object(thing)) {
const res = {};
// eslint-disable-next-line guard-for-in, no-restricted-syntax
for (const key in thing) {
res[key] = _ensureStringed(thing[key]);
}
return res;
} else if (thing === null) {
return null;
} else if (thing === undefined) {
return undefined;
}
throw new Error(`unsure of how to jsonify object of type ${typeof thing}`);
}
function _jsonThing(thing) {
return JSON.stringify(_ensureStringed(thing));
}
function _base64ToBytes(sBase64, nBlocksSize) {
const sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, '');
const nInLen = sB64Enc.length;
const nOutLen = nBlocksSize
? Math.ceil(((nInLen * 3 + 1) >> 2) / nBlocksSize) * nBlocksSize
: (nInLen * 3 + 1) >> 2;
const aBBytes = new ArrayBuffer(nOutLen);
const taBytes = new Uint8Array(aBBytes);
for (
let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0;
nInIdx < nInLen;
nInIdx += 1
) {
nMod4 = nInIdx & 3;
nUint24 |= _b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (18 - 6 * nMod4);
if (nMod4 === 3 || nInLen - nInIdx === 1) {
for (
nMod3 = 0;
nMod3 < 3 && nOutIdx < nOutLen;
nMod3 += 1, nOutIdx += 1
) {
taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255;
}
nUint24 = 0;
}
}
return aBBytes;
}
function _validateResponse(response, schema) {
try {
// eslint-disable-next-line guard-for-in, no-restricted-syntax
@ -57,6 +144,30 @@ function _validateResponse(response, schema) {
return true;
}
function _createSocket(url, { certificateAuthority, proxyUrl, signature }) {
let requestOptions;
if (proxyUrl) {
requestOptions = {
ca: certificateAuthority,
agent: new ProxyAgent(proxyUrl),
};
} else {
requestOptions = {
ca: certificateAuthority,
};
}
// TODO: sign a timestamp
let headers;
if (signature) {
headers = {
signature,
};
}
// eslint-disable-next-line new-cap
return new WebSocket(url, null, null, headers, requestOptions);
}
const FIVE_MINUTES = 1000 * 60 * 5;
const agents = {
unauth: null,
@ -99,7 +210,9 @@ function _promiseAjax(providedUrl, options) {
log.info(`Cycling agent for type ${cacheKey}`);
}
agents[cacheKey] = {
agent: new Agent({ keepAlive: true }),
agent: proxyUrl
? new ProxyAgent(proxyUrl)
: new Agent({ keepAlive: true }),
timestamp: Date.now(),
};
}
@ -281,12 +394,45 @@ function HTTPError(message, providedCode, response, stack) {
return e;
}
const URL_CALLS = {
accounts: 'v1/accounts',
updateDeviceName: 'v1/accounts/name',
removeSignalingKey: 'v1/accounts/signaling_key',
attachment: 'v1/attachments',
deliveryCert: 'v1/certificate/delivery',
supportUnauthenticatedDelivery: 'v1/devices/unauthenticated_delivery',
devices: 'v1/devices',
keys: 'v2/keys',
messages: 'v1/messages',
profile: 'v1/profile',
signed: 'v2/keys/signed',
};
module.exports = {
initialize,
};
// We first set up the data that won't change during this session of the app
function initialize() {
function initialize({
url,
cdnUrl,
certificateAuthority,
contentProxyUrl,
proxyUrl,
}) {
if (!is.string(url)) {
throw new Error('WebAPI.initialize: Invalid server url');
}
if (!is.string(cdnUrl)) {
throw new Error('WebAPI.initialize: Invalid cdnUrl');
}
if (!is.string(certificateAuthority)) {
throw new Error('WebAPI.initialize: Invalid certificateAuthority');
}
if (!is.string(contentProxyUrl)) {
throw new Error('WebAPI.initialize: Invalid contentProxyUrl');
}
// Thanks to function-hoisting, we can put this return statement before all of the
// below function definitions.
return {
@ -296,19 +442,413 @@ function initialize() {
// Then we connect to the server with user-specific information. This is the only API
// exposed to the browser context, ensuring that it can't connect to arbitrary
// locations.
function connect() {
function connect({ username: initialUsername, password: initialPassword }) {
let username = initialUsername;
let password = initialPassword;
// Thanks, function hoisting!
return {
confirmCode,
getAttachment,
getAvatar,
getDevices,
getKeysForNumber,
getKeysForNumberUnauth,
getMessageSocket,
getMyKeys,
getProfile,
getProfileUnauth,
getProvisioningSocket,
getProxiedSize,
getSenderCertificate,
makeProxiedRequest,
putAttachment,
putAvatar,
registerKeys,
registerSupportForUnauthenticatedDelivery,
removeSignalingKey,
requestVerificationSMS,
requestVerificationVoice,
sendMessages,
sendMessagesUnauth,
setSignedPreKey,
updateDeviceName,
};
function _ajax(param) {
if (!param.urlParameters) {
// eslint-disable-next-line no-param-reassign
param.urlParameters = '';
}
return _outerAjax(null, {
certificateAuthority,
contentType: 'application/json; charset=utf-8',
data: param.jsonData && _jsonThing(param.jsonData),
host: url,
password,
path: URL_CALLS[param.call] + param.urlParameters,
proxyUrl,
responseType: param.responseType,
timeout: param.timeout,
type: param.httpType,
user: username,
validateResponse: param.validateResponse,
unauthenticated: param.unauthenticated,
accessKey: param.accessKey,
}).catch(e => {
const { code } = e;
if (code === 200) {
// happens sometimes when we get no response
// (TODO: Fix server to return 204? instead)
return null;
}
let message;
switch (code) {
case -1:
message =
'Failed to connect to the server, please check your network connection.';
break;
case 413:
message = 'Rate limit exceeded, please try again later.';
break;
case 403:
message = 'Invalid code, please try again.';
break;
case 417:
// TODO: This shouldn't be a thing?, but its in the API doc?
message = 'Number already registered.';
break;
case 401:
message =
'Invalid authentication, most likely someone re-registered and invalidated our registration.';
break;
case 404:
message = 'Number is not registered.';
break;
default:
message =
'The server rejected our query, please file a bug report.';
}
e.message = `${message} (original: ${e.message})`;
throw e;
});
}
function getSenderCertificate() {
return _ajax({
call: 'deliveryCert',
httpType: 'GET',
responseType: 'json',
schema: { certificate: 'string' },
});
}
function registerSupportForUnauthenticatedDelivery() {
return _ajax({
call: 'supportUnauthenticatedDelivery',
httpType: 'PUT',
responseType: 'json',
});
}
function getProfile(number) {
return _ajax({
call: 'profile',
httpType: 'GET',
urlParameters: `/${number}`,
responseType: 'json',
});
}
function getProfileUnauth(number, { accessKey } = {}) {
return _ajax({
call: 'profile',
httpType: 'GET',
urlParameters: `/${number}`,
responseType: 'json',
unauthenticated: true,
accessKey,
});
}
function getAvatar(path) {
// Using _outerAJAX, since it's not hardcoded to the Signal Server. Unlike our
// attachment CDN, it uses our self-signed certificate, so we pass it in.
return _outerAjax(`${cdnUrl}/${path}`, {
certificateAuthority,
contentType: 'application/octet-stream',
proxyUrl,
responseType: 'arraybuffer',
timeout: 0,
type: 'GET',
});
}
function requestVerificationSMS(number) {
return _ajax({
call: 'accounts',
httpType: 'GET',
urlParameters: `/sms/code/${number}`,
});
}
function requestVerificationVoice(number) {
return _ajax({
call: 'accounts',
httpType: 'GET',
urlParameters: `/voice/code/${number}`,
});
}
async function confirmCode(
number,
code,
newPassword,
registrationId,
deviceName,
options = {}
) {
const { accessKey } = options;
const jsonData = {
supportsSms: false,
fetchesMessages: true,
registrationId,
unidentifiedAccessKey: accessKey
? _btoa(_getString(accessKey))
: undefined,
unrestrictedUnidentifiedAccess: false,
};
let call;
let urlPrefix;
let schema;
let responseType;
if (deviceName) {
jsonData.name = deviceName;
call = 'devices';
urlPrefix = '/';
schema = { deviceId: 'number' };
responseType = 'json';
} else {
call = 'accounts';
urlPrefix = '/code/';
}
// We update our saved username and password, since we're creating a new account
username = number;
password = newPassword;
const response = await _ajax({
call,
httpType: 'PUT',
urlParameters: urlPrefix + code,
jsonData,
responseType,
validateResponse: schema,
});
// From here on out, our username will be our phone number combined with device
username = `${number}.${response.deviceId || 1}`;
return response;
}
function updateDeviceName(deviceName) {
return _ajax({
call: 'updateDeviceName',
httpType: 'PUT',
jsonData: {
deviceName,
},
});
}
function removeSignalingKey() {
return _ajax({
call: 'removeSignalingKey',
httpType: 'DELETE',
});
}
function getDevices() {
return _ajax({
call: 'devices',
httpType: 'GET',
});
}
function registerKeys(genKeys) {
const keys = {};
keys.identityKey = _btoa(_getString(genKeys.identityKey));
keys.signedPreKey = {
keyId: genKeys.signedPreKey.keyId,
publicKey: _btoa(_getString(genKeys.signedPreKey.publicKey)),
signature: _btoa(_getString(genKeys.signedPreKey.signature)),
};
keys.preKeys = [];
let j = 0;
// eslint-disable-next-line guard-for-in, no-restricted-syntax
for (const i in genKeys.preKeys) {
keys.preKeys[j] = {
keyId: genKeys.preKeys[i].keyId,
publicKey: _btoa(_getString(genKeys.preKeys[i].publicKey)),
};
j += 1;
}
// This is just to make the server happy
// (v2 clients should choke on publicKey)
keys.lastResortKey = { keyId: 0x7fffffff, publicKey: _btoa('42') };
return _ajax({
call: 'keys',
httpType: 'PUT',
jsonData: keys,
});
}
function setSignedPreKey(signedPreKey) {
return _ajax({
call: 'signed',
httpType: 'PUT',
jsonData: {
keyId: signedPreKey.keyId,
publicKey: _btoa(_getString(signedPreKey.publicKey)),
signature: _btoa(_getString(signedPreKey.signature)),
},
});
}
function getMyKeys() {
return _ajax({
call: 'keys',
httpType: 'GET',
responseType: 'json',
validateResponse: { count: 'number' },
}).then(res => res.count);
}
function handleKeys(res) {
if (!Array.isArray(res.devices)) {
throw new Error('Invalid response');
}
res.identityKey = _base64ToBytes(res.identityKey);
res.devices.forEach(device => {
if (
!_validateResponse(device, { signedPreKey: 'object' }) ||
!_validateResponse(device.signedPreKey, {
publicKey: 'string',
signature: 'string',
})
) {
throw new Error('Invalid signedPreKey');
}
if (device.preKey) {
if (
!_validateResponse(device, { preKey: 'object' }) ||
!_validateResponse(device.preKey, { publicKey: 'string' })
) {
throw new Error('Invalid preKey');
}
// eslint-disable-next-line no-param-reassign
device.preKey.publicKey = _base64ToBytes(device.preKey.publicKey);
}
// eslint-disable-next-line no-param-reassign
device.signedPreKey.publicKey = _base64ToBytes(
device.signedPreKey.publicKey
);
// eslint-disable-next-line no-param-reassign
device.signedPreKey.signature = _base64ToBytes(
device.signedPreKey.signature
);
});
return res;
}
function getKeysForNumber(number, deviceId = '*') {
return _ajax({
call: 'keys',
httpType: 'GET',
urlParameters: `/${number}/${deviceId}`,
responseType: 'json',
validateResponse: { identityKey: 'string', devices: 'object' },
}).then(handleKeys);
}
function getKeysForNumberUnauth(
number,
deviceId = '*',
{ accessKey } = {}
) {
return _ajax({
call: 'keys',
httpType: 'GET',
urlParameters: `/${number}/${deviceId}`,
responseType: 'json',
validateResponse: { identityKey: 'string', devices: 'object' },
unauthenticated: true,
accessKey,
}).then(handleKeys);
}
function sendMessagesUnauth(
destination,
messageArray,
timestamp,
silent,
online,
{ accessKey } = {}
) {
const jsonData = { messages: messageArray, timestamp };
if (silent) {
jsonData.silent = true;
}
if (online) {
jsonData.online = true;
}
return _ajax({
call: 'messages',
httpType: 'PUT',
urlParameters: `/${destination}`,
jsonData,
responseType: 'json',
unauthenticated: true,
accessKey,
});
}
function sendMessages(
destination,
messageArray,
timestamp,
silent,
online
) {
const jsonData = { messages: messageArray, timestamp };
if (silent) {
jsonData.silent = true;
}
if (online) {
jsonData.online = true;
}
return _ajax({
call: 'messages',
httpType: 'PUT',
urlParameters: `/${destination}`,
jsonData,
responseType: 'json',
});
}
function getAttachment(fileUrl) {
return _outerAjax(fileUrl, {
contentType: 'application/octet-stream',
proxyUrl,
responseType: 'arraybuffer',
timeout: 0,
type: 'GET',
@ -344,7 +884,7 @@ function initialize() {
const result = await _outerAjax(url, {
processData: false,
responseType: 'arraybufferwithdetails',
proxyUrl: '',
proxyUrl: contentProxyUrl,
type: 'HEAD',
disableLogs: true,
});
@ -372,12 +912,38 @@ function initialize() {
return _outerAjax(url, {
processData: false,
responseType: returnArrayBuffer ? 'arraybufferwithdetails' : null,
proxyUrl: '',
proxyUrl: contentProxyUrl,
type: 'GET',
redirect: 'follow',
disableLogs: true,
headers,
});
}
function getMessageSocket() {
log.info('opening message socket', url);
const fixedScheme = url
.replace('https://', 'wss://')
.replace('http://', 'ws://');
const login = encodeURIComponent(username);
const pass = encodeURIComponent(password);
return _createSocket(
`${fixedScheme}/v1/websocket/?login=${login}&password=${pass}&agent=OWD`,
{ certificateAuthority, proxyUrl }
);
}
function getProvisioningSocket() {
log.info('opening provisioning socket', url);
const fixedScheme = url
.replace('https://', 'wss://')
.replace('http://', 'ws://');
return _createSocket(
`${fixedScheme}/v1/websocket/provisioning/?agent=OWD`,
{ certificateAuthority, proxyUrl }
);
}
}
}

@ -0,0 +1,39 @@
/* global libphonenumber, Whisper */
// eslint-disable-next-line func-names
(function() {
'use strict';
window.Whisper = window.Whisper || {};
Whisper.PhoneInputView = Whisper.View.extend({
tagName: 'div',
className: 'phone-input',
templateName: 'phone-number',
initialize() {
this.$('input.number').intlTelInput();
},
events: {
change: 'validateNumber',
keyup: 'validateNumber',
},
validateNumber() {
const input = this.$('input.number');
const regionCode = this.$('li.active')
.attr('data-country-code')
.toUpperCase();
const number = input.val();
const parsedNumber = libphonenumber.util.parseNumber(number, regionCode);
if (parsedNumber.isValidNumber) {
this.$('.number-container').removeClass('invalid');
this.$('.number-container').addClass('valid');
} else {
this.$('.number-container').removeClass('valid');
}
input.trigger('validation');
return parsedNumber.e164;
},
});
})();

@ -28,6 +28,7 @@
const ARCHIVE_AGE = 7 * 24 * 60 * 60 * 1000;
function AccountManager(username, password) {
// this.server = window.WebAPI.connect({ username, password });
this.pending = Promise.resolve();
}
@ -47,8 +48,12 @@
AccountManager.prototype = new textsecure.EventTarget();
AccountManager.prototype.extend({
constructor: AccountManager,
requestVoiceVerification(number) {},
requestSMSVerification(number) {},
requestVoiceVerification(number) {
// return this.server.requestVerificationVoice(number);
},
requestSMSVerification(number) {
// return this.server.requestVerificationSMS(number);
},
async encryptDeviceName(name, providedIdentityKey) {
if (!name) {
return null;
@ -93,13 +98,23 @@
return name;
},
async maybeUpdateDeviceName() {
throw new Error('Signal method called: maybeUpdateDeviceName');
const isNameEncrypted = textsecure.storage.user.getDeviceNameEncrypted();
if (isNameEncrypted) {
return;
}
const deviceName = await textsecure.storage.user.getDeviceName();
const base64 = await this.encryptDeviceName(deviceName);
await this.server.updateDeviceName(base64);
},
async deviceNameIsEncrypted() {
await textsecure.storage.user.setDeviceNameEncrypted();
},
async maybeDeleteSignalingKey() {
throw new Error('Signal method called: maybeDeleteSignalingKey');
const key = await textsecure.storage.user.getSignalingKey();
if (key) {
await this.server.removeSignalingKey();
}
},
registerSingleDevice(mnemonic, mnemonicLanguage, profileName) {
const createAccount = this.createAccount.bind(this);
@ -197,7 +212,19 @@
'account_manager: registerSecondDevice has not been implemented!'
);
},
refreshPreKeys() {},
refreshPreKeys() {
// const generateKeys = this.generateKeys.bind(this, 0);
// const registerKeys = this.server.registerKeys.bind(this.server);
// return this.queueTask(() =>
// this.server.getMyKeys().then(preKeyCount => {
// window.log.info(`prekey count ${preKeyCount}`);
// if (preKeyCount < 10) {
// return generateKeys().then(registerKeys);
// }
// return null;
// })
// );
},
rotateSignedPreKey() {
return this.queueTask(() => {
const signedKeyId = textsecure.storage.get('signedKeyId', 1);
@ -485,6 +512,7 @@
keyId: res.keyId,
publicKey: res.keyPair.pubKey,
signature: res.signature,
// server.registerKeys doesn't use keyPair, confirmKeys does
keyPair: res.keyPair,
};
})

@ -11,6 +11,7 @@
/* global HttpResource: false */
/* global ContactBuffer: false */
/* global GroupBuffer: false */
/* global WebSocketResource: false */
/* global lokiPublicChatAPI: false */
/* global lokiMessageAPI: false */
/* global feeds: false */
@ -31,7 +32,14 @@ function MessageReceiver(username, password, signalingKey, options = {}) {
this.signalingKey = signalingKey;
this.username = username;
this.password = password;
this.server = WebAPI.connect();
this.server = WebAPI.connect({ username, password });
if (!options.serverTrustRoot) {
throw new Error('Server trust root is required!');
}
this.serverTrustRoot = window.Signal.Crypto.base64ToArrayBuffer(
options.serverTrustRoot
);
const address = libsignal.SignalProtocolAddress.fromString(username);
this.number = address.getName();
@ -102,6 +110,31 @@ MessageReceiver.prototype.extend({
feed.on('rssMessage', this.handleUnencryptedMessage.bind(this));
});
// TODO: Rework this socket stuff to work with online messaging
const useWebSocket = false;
if (useWebSocket) {
if (this.socket && this.socket.readyState !== WebSocket.CLOSED) {
this.socket.close();
this.wsr.close();
}
// initialize the socket and start listening for messages
this.socket = this.server.getMessageSocket();
this.socket.onclose = this.onclose.bind(this);
this.socket.onerror = this.onerror.bind(this);
this.socket.onopen = this.onopen.bind(this);
this.wsr = new WebSocketResource(this.socket, {
handleRequest: this.handleRequest.bind(this),
keepalive: {
path: '/v1/keepalive',
disconnect: true,
},
});
// Because sometimes the socket doesn't properly emit its close event
this._onClose = this.onclose.bind(this);
this.wsr.addEventListener('close', this._onClose);
}
// Ensures that an immediate 'empty' event from the websocket will fire only after
// all cached envelopes are processed.
this.incoming = [this.pending];
@ -130,11 +163,29 @@ MessageReceiver.prototype.extend({
this.stoppingProcessing = true;
return this.close();
},
shutdown() {},
shutdown() {
if (this.socket) {
this.socket.onclose = null;
this.socket.onerror = null;
this.socket.onopen = null;
this.socket = null;
}
if (this.wsr) {
this.wsr.removeEventListener('close', this._onClose);
this.wsr = null;
}
},
async close() {
window.log.info('MessageReceiver.close()');
this.calledClose = true;
// Our WebSocketResource instance will close the socket and emit a 'close' event
// if the socket doesn't emit one quickly enough.
if (this.wsr) {
this.wsr.close(3000, 'called close');
}
// stop polling all open group rooms
if (lokiPublicChatAPI) {
await lokiPublicChatAPI.close();
@ -169,6 +220,27 @@ MessageReceiver.prototype.extend({
'calledClose:',
this.calledClose
);
// TODO: handle properly
// this.shutdown();
// if (this.calledClose) {
// return Promise.resolve();
// }
// if (ev.code === 3000) {
// return Promise.resolve();
// }
// if (ev.code === 3001) {
// this.onEmpty();
// }
// // possible 403 or network issue. Make an request to confirm
// return this.server
// .getDevices(this.number)
// .then(this.connect.bind(this)) // No HTTP error? Reconnect
// .catch(e => {
// const event = new Event('error');
// event.error = e;
// return this.dispatchAndWait(event);
// });
},
handleRequest(request, options) {
const { onSuccess, onFailure } = options;
@ -565,7 +637,9 @@ MessageReceiver.prototype.extend({
? WebSocket.OPEN
: WebSocket.CLOSED;
}
if (this.hasConnected) {
if (this.socket) {
return this.socket.readyState;
} else if (this.hasConnected) {
return WebSocket.CLOSED;
}
return -1;

@ -178,6 +178,10 @@ OutgoingMessage.prototype = {
return false;
})
);
// TODO: check if still applicable
// if (updateDevices === undefined) {
// return this.server.getKeysForNumber(number, '*').then(handleResult);
// }
let promise = Promise.resolve(true);
updateDevices.forEach(device => {
promise = promise.then(() =>

@ -184,8 +184,8 @@ Message.prototype = {
},
};
function MessageSender() {
this.server = WebAPI.connect();
function MessageSender(username, password) {
this.server = WebAPI.connect({ username, password });
this.pendingMessages = {};
}
@ -595,8 +595,16 @@ MessageSender.prototype = {
);
},
async getProfile() {
throw new Error('Signal code called. This needs to be removed');
async getProfile(number, { accessKey } = {}) {
if (accessKey) {
return this.server.getProfileUnauth(number, { accessKey });
}
return this.server.getProfile(number);
},
getAvatar(path) {
return this.server.getAvatar(path);
},
uploadAvatar(attachment) {
@ -1330,6 +1338,7 @@ textsecure.MessageSender = function MessageSenderWrapper(username, password) {
this.leaveGroup = sender.leaveGroup.bind(sender);
this.sendSyncMessage = sender.sendSyncMessage.bind(sender);
this.getProfile = sender.getProfile.bind(sender);
this.getAvatar = sender.getAvatar.bind(sender);
this.uploadAvatar = sender.uploadAvatar.bind(sender);
this.syncReadMessages = sender.syncReadMessages.bind(sender);
this.syncVerification = sender.syncVerification.bind(sender);

@ -1,11 +1,56 @@
window.setImmediate = window.nodeSetImmediate;
const getKeysForNumberMap = {};
const messagesSentMap = {};
const fakeCall = () => Promise.resolve();
const fakeAPI = {
confirmCode: fakeCall,
getAttachment: fakeCall,
getAvatar: fakeCall,
getDevices: fakeCall,
// getKeysForNumber: fakeCall,
getMessageSocket: fakeCall,
getMyKeys: fakeCall,
getProfile: fakeCall,
getProvisioningSocket: fakeCall,
putAttachment: fakeCall,
putAvatar: fakeCall,
registerKeys: fakeCall,
requestVerificationSMS: fakeCall,
requestVerificationVoice: fakeCall,
// sendMessages: fakeCall,
setSignedPreKey: fakeCall,
getKeysForNumber(number) {
const res = getKeysForNumberMap[number];
if (res !== undefined) {
delete getKeysForNumberMap[number];
return Promise.resolve(res);
}
throw new Error('getKeysForNumber of unknown/used number');
},
sendMessages(destination, messageArray) {
for (let i = 0, max = messageArray.length; i < max; i += 1) {
const msg = messageArray[i];
if (
(msg.type !== 1 && msg.type !== 3) ||
msg.destinationDeviceId === undefined ||
msg.destinationRegistrationId === undefined ||
msg.body === undefined ||
msg.timestamp === undefined ||
msg.relay !== undefined ||
msg.destination !== undefined
) {
throw new Error('Invalid message');
}
messagesSentMap[
`${destination}.${messageArray[i].destinationDeviceId}`
] = msg;
}
},
};
window.WebAPI = {

@ -58,6 +58,8 @@
"dependencies": {
"@journeyapps/sqlcipher": "https://github.com/scottnonnenberg-signal/node-sqlcipher.git#b10f232fac62ba7f8775c9e086bb5558fe7d948b",
"@sindresorhus/is": "0.8.0",
"@types/dompurify": "^2.0.0",
"@types/rc-slider": "^8.6.5",
"backbone": "1.3.3",
"blob-util": "1.3.0",
"blueimp-canvas-to-blob": "3.14.0",
@ -81,8 +83,13 @@
"form-data": "^3.0.0",
"fs-extra": "9.0.0",
"glob": "7.1.2",
"google-libphonenumber": "3.2.2",
"got": "8.2.0",
"he": "1.2.0",
"intl-tel-input": "12.1.15",
"jquery": "3.3.1",
"js-sha512": "0.8.0",
"js-yaml": "3.13.0",
"jsbn": "1.1.0",
"libsodium-wrappers": "^0.7.6",
"linkify-it": "2.0.3",
@ -91,10 +98,12 @@
"moment": "2.21.0",
"mustache": "2.3.0",
"node-fetch": "2.3.0",
"node-gyp": "3.8.0",
"node-sass": "4.9.3",
"os-locale": "2.1.0",
"pify": "3.0.0",
"protobufjs": "6.8.6",
"proxy-agent": "3.0.3",
"rc-slider": "^8.7.1",
"react": "16.8.3",
"react-contextmenu": "2.11.0",
@ -111,28 +120,31 @@
"rimraf": "2.6.2",
"semver": "5.4.1",
"tar": "4.4.8",
"testcheck": "1.0.0-rc.2",
"tmp": "0.0.33",
"to-arraybuffer": "1.0.1",
"underscore": "1.9.0",
"uuid": "3.3.2"
"uuid": "3.3.2",
"websocket": "1.0.28"
},
"devDependencies": {
"@types/chai": "4.1.2",
"@types/classnames": "2.2.3",
"@types/color": "^3.0.0",
"@types/config": "0.0.34",
"@types/dompurify": "^2.0.0",
"@types/electron-is-dev": "^1.1.1",
"@types/filesize": "3.6.0",
"@types/fs-extra": "5.0.5",
"@types/google-libphonenumber": "7.4.14",
"@types/got": "9.4.1",
"@types/jquery": "3.3.29",
"@types/js-yaml": "3.12.0",
"@types/linkify-it": "2.0.3",
"@types/lodash": "4.14.106",
"@types/mkdirp": "0.5.2",
"@types/mocha": "5.0.0",
"@types/pify": "3.0.2",
"@types/qs": "6.5.1",
"@types/rc-slider": "^8.6.5",
"@types/react": "16.8.5",
"@types/react-dom": "16.8.2",
"@types/react-portal": "^4.0.2",
@ -170,7 +182,6 @@
"grunt-sass": "3.0.1",
"mocha": "4.1.0",
"mocha-testcheck": "1.0.0-rc.0",
"node-gyp": "3.8.0",
"node-sass-import-once": "1.2.0",
"nyc": "11.4.1",
"prettier": "1.12.0",

@ -312,7 +312,13 @@ window.nodeSetImmediate = setImmediate;
const { initialize: initializeWebAPI } = require('./js/modules/web_api');
window.WebAPI = initializeWebAPI();
window.WebAPI = initializeWebAPI({
url: config.serverUrl,
cdnUrl: config.cdnUrl,
certificateAuthority: config.certificateAuthority,
contentProxyUrl: config.contentProxyUrl,
proxyUrl: config.proxyUrl,
});
window.seedNodeList = JSON.parse(config.seedNodeList);
const LokiSnodeAPI = require('./js/modules/loki_snode_api');
@ -356,6 +362,8 @@ window.dataURLToBlobSync = require('blueimp-canvas-to-blob');
window.emojiData = require('emoji-datasource');
window.EmojiPanel = require('emoji-panel');
window.filesize = require('filesize');
window.libphonenumber = require('google-libphonenumber').PhoneNumberUtil.getInstance();
window.libphonenumber.PhoneNumberFormat = require('google-libphonenumber').PhoneNumberFormat;
window.loadImage = require('blueimp-load-image');
window.getGuid = require('uuid/v4');
window.profileImages = require('./app/profile_images');

@ -1,2 +1,15 @@
@import 'variables';
@import '../node_modules/intl-tel-input/build/css/intlTelInput.css';
@import 'progress';
.iti-flag {
// override intlTelInput's flags image location
background: url('../node_modules/intl-tel-input/build/img/flags.png');
}
.intl-tel-input .country-list {
text-align: left;
}
.intl-tel-input .country-list .country .country-name {
color: #000;
}

@ -1670,6 +1670,10 @@ body.dark-theme {
// _options
.intl-tel-input .country-list .country .country-name {
color: #000;
}
// _progress
// Not sure we need to change anything there - it's blue

@ -500,6 +500,7 @@
<script type="text/javascript" src="../js/libtextsecure.js" data-cover></script>
<script type="text/javascript" src="../js/libloki.js" data-cover></script>
<script type="text/javascript" src="../js/libphonenumber-util.js"></script>
<script type="text/javascript" src="../js/models/messages.js" data-cover></script>
<script type="text/javascript" src="../js/models/conversations.js" data-cover></script>
<script type="text/javascript" src="../js/models/blockedNumbers.js" data-cover></script>
@ -547,6 +548,7 @@
<script type="text/javascript" src="../js/views/identicon_svg_view.js"></script>
<script type="text/javascript" src="../js/views/install_view.js"></script>
<script type="text/javascript" src="../js/views/banner_view.js"></script>
<script type="text/javascript" src="../js/views/phone-input-view.js"></script>
<script type="text/javascript" src="../js/views/session_registration_view.js"></script>
<script type="text/javascript" src="../js/views/app_view.js"></script>
<script type="text/javascript" src="../js/views/import_view.js"></script>
@ -574,6 +576,7 @@
<script type="text/javascript" src="models/conversations_test.js"></script>
<script type="text/javascript" src="models/messages_test.js"></script>
<script type="text/javascript" src="libphonenumber_util_test.js"></script>
<script type="text/javascript" src="blocked_number_controller_test.js"></script>
<script type="text/javascript" src="conversation_controller_test.js"></script>
<script type="text/javascript" src="storage_test.js"></script>

@ -0,0 +1,26 @@
/* global libphonenumber */
'use strict';
describe('libphonenumber util', () => {
describe('parseNumber', () => {
it('numbers with + are valid without providing regionCode', () => {
const result = libphonenumber.util.parseNumber('+14155555555');
assert.isTrue(result.isValidNumber);
assert.strictEqual(result.nationalNumber, '4155555555');
assert.strictEqual(result.e164, '+14155555555');
assert.strictEqual(result.regionCode, 'US');
assert.strictEqual(result.countryCode, '1');
});
it('variant numbers with the right regionCode are valid', () => {
['4155555555', '14155555555', '+14155555555'].forEach(number => {
const result = libphonenumber.util.parseNumber(number, 'US');
assert.isTrue(result.isValidNumber);
assert.strictEqual(result.nationalNumber, '4155555555');
assert.strictEqual(result.e164, '+14155555555');
assert.strictEqual(result.regionCode, 'US');
assert.strictEqual(result.countryCode, '1');
});
});
});
});

@ -7,27 +7,18 @@ const Privacy = require('../../js/modules/privacy');
const APP_ROOT_PATH = path.join(__dirname, '..', '..', '..');
describe('Privacy', () => {
describe('redactSessionID', () => {
it('should redact all session IDs', () => {
describe('redactPhoneNumbers', () => {
it('should redact all phone numbers', () => {
const text =
'This is a log line with a session ID 0531032fc7415b7cc1b7516480ad121d391eddce3cfb2cee27dd5b215609c32827\n' +
'and another one 05766049a70e725ad02f7fe61b10e461380a4d7433f98096b3cacbf0362d5cab62';
'This is a log line with a phone number +12223334455\n' +
'and another one +13334445566';
const actual = Privacy.redactSessionID(text);
const actual = Privacy.redactPhoneNumbers(text);
const expected =
'This is a log line with a session ID [REDACTED]\n' +
'and another one [REDACTED]';
'This is a log line with a phone number +[REDACTED]455\n' +
'and another one +[REDACTED]566';
assert.equal(actual, expected);
});
it('should not redact non session IDS', () => {
const text =
'This is a log line with a non-session ID sadsad0531032fc7415b7cc1b7516480ad121d391eddce3cfb2cee27dd5b215609c32827888\n' +
'and another one 766049a70e725ad02f7fe61b10e461380a4d7433f98096b3cacbf0362d5cab6234';
const actual = Privacy.redactSessionID(text);
assert.equal(actual, text);
});
});
describe('redactGroupIds', () => {
@ -62,20 +53,20 @@ describe('Privacy', () => {
const text =
'This is a log line with sensitive information:\n' +
`path1 ${APP_ROOT_PATH}/main.js\n` +
'phone1 0531032fc7415b7cc1b7516480ad121d391eddce3cfb2cee27dd5b215609c32827 ipsum\n' +
'phone1 +12223334455 ipsum\n' +
'group1 group(123456789) doloret\n' +
`path2 file:///${encodedAppRootPath}/js/background.js.` +
'phone2 0531033dc7415b7cc1b7516480ad121d391eddce3cfb2cee27dd5b215609c32827 lorem\n' +
'phone2 +13334445566 lorem\n' +
'group2 group(abcdefghij) doloret\n';
const actual = Privacy.redactAll(text);
const expected =
'This is a log line with sensitive information:\n' +
'path1 [REDACTED]/main.js\n' +
'phone1 [REDACTED] ipsum\n' +
'phone1 +[REDACTED]455 ipsum\n' +
'group1 group([REDACTED]789) doloret\n' +
'path2 file:///[REDACTED]/js/background.js.' +
'phone2 [REDACTED] lorem\n' +
'phone2 +[REDACTED]566 lorem\n' +
'group2 group([REDACTED]hij) doloret\n';
assert.equal(actual, expected);
});
@ -87,13 +78,13 @@ describe('Privacy', () => {
const text =
'This is a log line with sensitive information:\n' +
`path1 ${testPath}/main.js\n` +
'phone1 0531032fc7415b7cc1b7516480ad121d391eddce3cfb2cee27dd5b215609c32827 ipsum\n';
'phone1 +12223334455 ipsum\n';
const actual = Privacy._redactPath(testPath)(text);
const expected =
'This is a log line with sensitive information:\n' +
'path1 [REDACTED]/main.js\n' +
'phone1 0531032fc7415b7cc1b7516480ad121d391eddce3cfb2cee27dd5b215609c32827 ipsum\n';
'phone1 +12223334455 ipsum\n';
assert.equal(actual, expected);
});
@ -103,7 +94,7 @@ describe('Privacy', () => {
const text =
'This is a log line with sensitive information:\n' +
`path1 ${testPath}/main.js\n` +
'phone1 0531032fc7415b7cc1b7516480ad121d391eddce3cfb2cee27dd5b215609c32827 ipsum\n' +
'phone1 +12223334455 ipsum\n' +
'group1 group(123456789) doloret\n' +
`path2 file:///${encodedTestPath}/js/background.js.`;
@ -111,7 +102,7 @@ describe('Privacy', () => {
const expected =
'This is a log line with sensitive information:\n' +
'path1 [REDACTED]/main.js\n' +
'phone1 0531032fc7415b7cc1b7516480ad121d391eddce3cfb2cee27dd5b215609c32827 ipsum\n' +
'phone1 +12223334455 ipsum\n' +
'group1 group(123456789) doloret\n' +
'path2 file:///[REDACTED]/js/background.js.';
assert.equal(actual, expected);

@ -0,0 +1,6 @@
import libphonenumber from 'google-libphonenumber';
const instance = libphonenumber.PhoneNumberUtil.getInstance();
const PhoneNumberFormat = libphonenumber.PhoneNumberFormat;
export { instance, PhoneNumberFormat };

@ -122,6 +122,7 @@ const excludedFiles = [
'^node_modules/hpack\\.js/*',
'^node_modules/http-proxy-middlewar/*',
'^node_modules/icss-utils/*',
'^node_modules/intl-tel-input/examples/*',
'^node_modules/istanbul*',
'^node_modules/jimp/*',
'^node_modules/jquery/*',
@ -160,6 +161,7 @@ const excludedFiles = [
'^node_modules/spectron/*',
'^node_modules/style-loader/*',
'^node_modules/svgo/*',
'^node_modules/testcheck/*',
'^node_modules/text-encoding/*',
'^node_modules/tinycolor2/*',
'^node_modules/to-ast/*',

@ -113,6 +113,11 @@
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
"@sindresorhus/is@^0.7.0":
version "0.7.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==
"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.7.0":
version "1.7.1"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.1.tgz#da5fd19a5f71177a53778073978873964f49acf1"
@ -242,6 +247,19 @@
"@types/minimatch" "*"
"@types/node" "*"
"@types/google-libphonenumber@7.4.14":
version "7.4.14"
resolved "https://registry.yarnpkg.com/@types/google-libphonenumber/-/google-libphonenumber-7.4.14.tgz#3625d7aed0c16df920588428c86f0538bd0612ec"
integrity sha512-HGQobTn8CGn0/j7lezIHlGTE1czxQU6NeT7TYtC3OWcbyyUUSfdt4tXSTEGbXmNZlE+xczTDbyR8P6aYGPzG1A==
"@types/got@9.4.1":
version "9.4.1"
resolved "https://registry.yarnpkg.com/@types/got/-/got-9.4.1.tgz#7479a3a321599b5e17647f3bd9d402b8c55bfee1"
integrity sha512-m7Uc07bG/bZ+Dis7yI3mGssYDcAdUvP4irF3ZmBzf0ig7zEd1FyADfnELVGcf+p1Ol/iPCXbZYwcSNOJA2a+Qg==
dependencies:
"@types/node" "*"
"@types/tough-cookie" "*"
"@types/jquery@3.3.29":
version "3.3.29"
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.29.tgz#680a2219ce3c9250483722fccf5570d1e2d08abd"
@ -249,6 +267,11 @@
dependencies:
"@types/sizzle" "*"
"@types/js-yaml@3.12.0":
version "3.12.0"
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.0.tgz#3494ce97358e2675e24e97a747ec23478eeaf8b6"
integrity sha512-UGEe/6RsNAxgWdknhzFZbCxuYc5I7b/YEKlfKbo+76SM8CJzGs7XKCj7zyugXViRbKYpXhSXhCYVQZL5tmDbpQ==
"@types/linkify-it@2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-2.0.3.tgz#5352a2d7a35d7c77b527483cd6e68da9148bd780"
@ -409,6 +432,11 @@
resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47"
integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==
"@types/tough-cookie@*":
version "2.3.6"
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.6.tgz#c880579e087d7a0db13777ff8af689f4ffc7b0d5"
integrity sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ==
"@types/trusted-types@*":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-1.0.4.tgz#922d092c84a776a59acb0bd6785fd82b59b9bad5"
@ -516,6 +544,20 @@ address@^1.0.1:
resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==
agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
dependencies:
es6-promisify "^5.0.0"
agent-base@~4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==
dependencies:
es6-promisify "^5.0.0"
ajv-keywords@^3.0.0, ajv-keywords@^3.1.0:
version "3.4.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da"
@ -886,6 +928,11 @@ ast-types@0.9.11:
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.11.tgz#371177bb59232ff5ceaa1d09ee5cad705b1a5aa9"
integrity sha1-NxF3u1kjL/XOqh0J7lytcFsaWqk=
ast-types@0.x.x:
version "0.13.2"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48"
integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA==
ast-types@^0.7.2:
version "0.7.8"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.7.8.tgz#902d2e0d60d071bdcd46dc115e1809ed11c138a9"
@ -1548,6 +1595,19 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
cacheable-request@^2.1.1:
version "2.1.4"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d"
integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=
dependencies:
clone-response "1.0.2"
get-stream "3.0.0"
http-cache-semantics "3.8.1"
keyv "3.0.0"
lowercase-keys "1.0.0"
normalize-url "2.0.1"
responselike "1.0.2"
cacheable-request@^6.0.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
@ -1859,7 +1919,7 @@ cliui@^6.0.0:
strip-ansi "^6.0.0"
wrap-ansi "^6.2.0"
clone-response@^1.0.2:
clone-response@1.0.2, clone-response@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
@ -2492,6 +2552,11 @@ dashdash@1.14.1, dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
data-uri-to-buffer@1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835"
integrity sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==
dateformat@~1.0.12:
version "1.0.12"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9"
@ -2505,7 +2570,7 @@ debug-log@^1.0.1:
resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f"
integrity sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=
debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9:
debug@2, debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@ -2662,6 +2727,15 @@ defined@^1.0.0:
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=
degenerator@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095"
integrity sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=
dependencies:
ast-types "0.x.x"
escodegen "1.x.x"
esprima "3.x.x"
del@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5"
@ -3169,6 +3243,13 @@ es6-promise@^4.0.3, es6-promise@^4.2.4:
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
es6-promisify@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
dependencies:
es6-promise "^4.0.3"
escape-goat@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
@ -3189,7 +3270,7 @@ escape-string-regexp@^2.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
escodegen@^1.9.1:
escodegen@1.x.x, escodegen@^1.9.1:
version "1.14.1"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457"
integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==
@ -3328,6 +3409,11 @@ espree@^3.5.2:
acorn "^5.5.0"
acorn-jsx "^3.0.0"
esprima@3.x.x:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
esprima@^2.1.0, esprima@^2.6.0:
version "2.7.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
@ -3658,7 +3744,7 @@ file-type@^3.1.0:
resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9"
integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek=
file-uri-to-path@1.0.0:
file-uri-to-path@1, file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
@ -3868,7 +3954,7 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
from2@^2.1.0:
from2@^2.1.0, from2@^2.1.1:
version "2.3.0"
resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=
@ -3979,6 +4065,14 @@ fstream@^1.0.0, fstream@^1.0.12:
mkdirp ">=0.5 0"
rimraf "2"
ftp@~0.3.10:
version "0.3.10"
resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d"
integrity sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=
dependencies:
readable-stream "1.1.x"
xregexp "2.0.0"
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@ -4045,7 +4139,7 @@ get-stdin@^5.0.1:
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
integrity sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=
get-stream@^3.0.0:
get-stream@3.0.0, get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
@ -4064,6 +4158,18 @@ get-stream@^5.1.0:
dependencies:
pump "^3.0.0"
get-uri@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.4.tgz#d4937ab819e218d4cb5ae18e4f5962bef169cc6a"
integrity sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q==
dependencies:
data-uri-to-buffer "1"
debug "2"
extend "~3.0.2"
file-uri-to-path "1"
ftp "~0.3.10"
readable-stream "2"
get-value@^2.0.3, get-value@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
@ -4283,6 +4389,34 @@ glogg@^1.0.1:
dependencies:
sparkles "^1.0.0"
google-libphonenumber@3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/google-libphonenumber/-/google-libphonenumber-3.2.2.tgz#3d9d7ba727e99a50812f21b0ed313723b76c5c54"
integrity sha512-ubjGeosYPeusjYbUHy76lCniGTTI0k1rIFc+uKBX+jHQLDmWOSUtlFUxaeoLJ+Y+PAMM6dWp+C1HjHx5BI8kEw==
got@8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/got/-/got-8.2.0.tgz#0d11a071d05046348a2f5c0a5fa047fb687fdfc6"
integrity sha512-giadqJpXIwjY+ZsuWys8p2yjZGhOHiU4hiJHjS/oeCxw1u8vANQz3zPlrxW2Zw/siCXsSMI3hvzWGcnFyujyAg==
dependencies:
"@sindresorhus/is" "^0.7.0"
cacheable-request "^2.1.1"
decompress-response "^3.3.0"
duplexer3 "^0.1.4"
get-stream "^3.0.0"
into-stream "^3.1.0"
is-retry-allowed "^1.1.0"
isurl "^1.0.0-alpha5"
lowercase-keys "^1.0.0"
mimic-response "^1.0.0"
p-cancelable "^0.3.0"
p-timeout "^2.0.1"
pify "^3.0.0"
safe-buffer "^5.1.1"
timed-out "^4.0.1"
url-parse-lax "^3.0.0"
url-to-options "^1.0.1"
got@^9.6.0:
version "9.6.0"
resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
@ -4499,11 +4633,23 @@ has-flag@^4.0.0:
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
has-symbol-support-x@^1.4.1:
version "1.4.2"
resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455"
integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==
has-symbols@^1.0.0, has-symbols@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
has-to-string-tag-x@^1.2.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d"
integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==
dependencies:
has-symbol-support-x "^1.4.1"
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@ -4651,6 +4797,11 @@ html-entities@^1.2.0:
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=
http-cache-semantics@3.8.1:
version "3.8.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==
http-cache-semantics@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
@ -4672,6 +4823,17 @@ http-errors@1.7.2:
statuses ">= 1.5.0 < 2"
toidentifier "1.0.0"
http-errors@1.7.3, http-errors@~1.7.2:
version "1.7.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
dependencies:
depd "~1.1.2"
inherits "2.0.4"
setprototypeof "1.1.1"
statuses ">= 1.5.0 < 2"
toidentifier "1.0.0"
http-errors@~1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942"
@ -4690,22 +4852,19 @@ http-errors@~1.6.2:
setprototypeof "1.1.0"
statuses ">= 1.4.0 < 2"
http-errors@~1.7.2:
version "1.7.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
dependencies:
depd "~1.1.2"
inherits "2.0.4"
setprototypeof "1.1.1"
statuses ">= 1.5.0 < 2"
toidentifier "1.0.0"
"http-parser-js@>=0.4.0 <0.4.11":
version "0.4.10"
resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4"
integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=
http-proxy-agent@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==
dependencies:
agent-base "4"
debug "3.1.0"
http-proxy-middleware@^0.19.1:
version "0.19.1"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a"
@ -4739,6 +4898,22 @@ https-browserify@^1.0.0:
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
https-proxy-agent@^2.2.1:
version "2.2.4"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
dependencies:
agent-base "^4.3.0"
debug "^3.1.0"
https-proxy-agent@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz#b8c286433e87602311b01c8ea34413d856a4af81"
integrity sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==
dependencies:
agent-base "^4.3.0"
debug "^3.1.0"
hyphenate-style-name@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48"
@ -4903,6 +5078,19 @@ internal-ip@1.2.0:
dependencies:
meow "^3.3.0"
intl-tel-input@12.1.15:
version "12.1.15"
resolved "https://registry.yarnpkg.com/intl-tel-input/-/intl-tel-input-12.1.15.tgz#7393e6b77572731bbc65ca4585782e8ba3d74de4"
integrity sha512-9TN9x6aGdO1eL6iGFpobuLU4UymZqjSnS9UnsOSi//LU3A8nkLOcokSYBYjak18Uu8OM59HsGYDd1jKmwRsskw==
into-stream@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6"
integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=
dependencies:
from2 "^2.1.1"
p-is-promise "^1.1.0"
invariant@^2.2.2, invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
@ -4920,7 +5108,7 @@ ip-regex@^1.0.1:
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd"
integrity sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0=
ip@^1.1.0, ip@^1.1.5:
ip@1.1.5, ip@^1.1.0, ip@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
@ -5187,6 +5375,11 @@ is-obj@^2.0.0:
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982"
integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==
is-object@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA=
is-path-cwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
@ -5255,6 +5448,11 @@ is-resolvable@^1.0.0:
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
is-retry-allowed@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
is-root@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-root/-/is-root-1.0.0.tgz#07b6c233bc394cd9d02ba15c966bd6660d6342d5"
@ -5409,6 +5607,14 @@ istanbul-reports@^1.1.3:
dependencies:
handlebars "^4.0.3"
isurl@^1.0.0-alpha5:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==
dependencies:
has-to-string-tag-x "^1.2.0"
is-object "^1.0.1"
javascript-stringify@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-1.6.0.tgz#142d111f3a6e3dae8f4a9afd77d45855b5a9cce3"
@ -5451,6 +5657,11 @@ js-base64@^2.1.8, js-base64@^2.1.9:
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209"
integrity sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==
js-sha512@0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/js-sha512/-/js-sha512-0.8.0.tgz#dd22db8d02756faccf19f218e3ed61ec8249f7d4"
integrity sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==
"js-tokens@^3.0.0 || ^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@ -5461,6 +5672,14 @@ js-tokens@^3.0.2:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
js-yaml@3.13.0:
version "3.13.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.0.tgz#38ee7178ac0eea2c97ff6d96fff4b18c7d8cf98e"
integrity sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^3.13.1, js-yaml@^3.2.7, js-yaml@^3.7.0, js-yaml@^3.9.1:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
@ -5664,6 +5883,13 @@ keyboardevents-areequal@^0.2.1:
resolved "https://registry.yarnpkg.com/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz#88191ec738ce9f7591c25e9056de928b40277194"
integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==
keyv@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373"
integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==
dependencies:
json-buffer "3.0.0"
keyv@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
@ -5975,6 +6201,11 @@ loud-rejection@^1.0.0:
currently-unhandled "^0.4.1"
signal-exit "^3.0.0"
lowercase-keys@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=
lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
@ -5985,7 +6216,7 @@ lowercase-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
lru-cache@^4.0.1, lru-cache@^4.1.1:
lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2:
version "4.1.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
@ -6478,7 +6709,7 @@ mz@^2.3.1:
object-assign "^4.0.1"
thenify-all "^1.0.0"
nan@^2.10.0, nan@^2.12.1, nan@^2.14.0:
nan@^2.10.0, nan@^2.11.0, nan@^2.12.1, nan@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
@ -6536,6 +6767,11 @@ neo-async@^2.5.0, neo-async@^2.6.0:
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c"
integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==
netmask@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35"
integrity sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=
nise@^1.2.0:
version "1.5.3"
resolved "https://registry.yarnpkg.com/nise/-/nise-1.5.3.tgz#9d2cfe37d44f57317766c6e9408a359c5d3ac1f7"
@ -6708,6 +6944,15 @@ normalize-range@^0.1.2:
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
normalize-url@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6"
integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==
dependencies:
prepend-http "^2.0.0"
query-string "^5.0.1"
sort-keys "^2.0.0"
normalize-url@^1.4.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c"
@ -7034,6 +7279,11 @@ osenv@0, osenv@^0.1.4:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
p-cancelable@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==
p-cancelable@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
@ -7044,6 +7294,11 @@ p-finally@^1.0.0:
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
p-is-promise@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e"
integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=
p-limit@^1.0.0, p-limit@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
@ -7077,6 +7332,13 @@ p-map@^1.1.1:
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==
p-timeout@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038"
integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==
dependencies:
p-finally "^1.0.0"
p-try@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
@ -7087,6 +7349,31 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
pac-proxy-agent@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-3.0.1.tgz#115b1e58f92576cac2eba718593ca7b0e37de2ad"
integrity sha512-44DUg21G/liUZ48dJpUSjZnFfZro/0K5JTyFYLBcmh9+T6Ooi4/i4efwUiEy0+4oQusCBqWdhv16XohIj1GqnQ==
dependencies:
agent-base "^4.2.0"
debug "^4.1.1"
get-uri "^2.0.0"
http-proxy-agent "^2.1.0"
https-proxy-agent "^3.0.0"
pac-resolver "^3.0.0"
raw-body "^2.2.0"
socks-proxy-agent "^4.0.1"
pac-resolver@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-3.0.0.tgz#6aea30787db0a891704deb7800a722a7615a6f26"
integrity sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==
dependencies:
co "^4.6.0"
degenerator "^1.0.4"
ip "^1.1.5"
netmask "^1.0.6"
thunkify "^2.1.2"
package-json@^6.3.0:
version "6.5.0"
resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0"
@ -7801,6 +8088,25 @@ proxy-addr@~2.0.5:
forwarded "~0.1.2"
ipaddr.js "1.9.1"
proxy-agent@3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-3.0.3.tgz#1c1a33db60ef5f2e9e35b876fd63c2bc681c611d"
integrity sha512-PXVVVuH9tiQuxQltFJVSnXWuDtNr+8aNBP6XVDDCDiUuDN8eRCm+ii4/mFWmXWEA0w8jjJSlePa4LXlM4jIzNA==
dependencies:
agent-base "^4.2.0"
debug "^3.1.0"
http-proxy-agent "^2.1.0"
https-proxy-agent "^2.2.1"
lru-cache "^4.1.2"
pac-proxy-agent "^3.0.0"
proxy-from-env "^1.0.0"
socks-proxy-agent "^4.0.1"
proxy-from-env@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
prr@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
@ -7927,6 +8233,15 @@ query-string@^4.1.0:
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
query-string@^5.0.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb"
integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==
dependencies:
decode-uri-component "^0.2.0"
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
querystring-es3@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
@ -7993,6 +8308,16 @@ raw-body@2.4.0:
iconv-lite "0.4.24"
unpipe "1.0.0"
raw-body@^2.2.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c"
integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==
dependencies:
bytes "3.1.0"
http-errors "1.7.3"
iconv-lite "0.4.24"
unpipe "1.0.0"
raw-body@~2.1.5:
version "2.1.7"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774"
@ -8364,7 +8689,7 @@ read-pkg@^2.0.0:
normalize-package-data "^2.3.2"
path-type "^2.0.0"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@ -8377,7 +8702,7 @@ read-pkg@^2.0.0:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^1.1.8, readable-stream@~1.1.9:
readable-stream@1.1.x, readable-stream@^1.1.8, readable-stream@~1.1.9:
version "1.1.14"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
@ -8794,7 +9119,7 @@ resolve@~1.1.0:
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
responselike@^1.0.2:
responselike@1.0.2, responselike@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
@ -9210,6 +9535,11 @@ slide@^1.1.5:
resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=
smart-buffer@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba"
integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@ -9260,6 +9590,22 @@ sockjs@0.3.19:
faye-websocket "^0.10.0"
uuid "^3.0.1"
socks-proxy-agent@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386"
integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==
dependencies:
agent-base "~4.2.1"
socks "~2.3.2"
socks@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3"
integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==
dependencies:
ip "1.1.5"
smart-buffer "^4.1.0"
sort-keys@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad"
@ -9267,6 +9613,13 @@ sort-keys@^1.0.0:
dependencies:
is-plain-obj "^1.0.0"
sort-keys@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128"
integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=
dependencies:
is-plain-obj "^1.0.0"
source-list-map@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
@ -9858,7 +10211,7 @@ test-exclude@^4.1.1:
read-pkg-up "^1.0.1"
require-main-filename "^1.0.1"
testcheck@^1.0.0-rc:
testcheck@1.0.0-rc.2, testcheck@^1.0.0-rc:
version "1.0.0-rc.2"
resolved "https://registry.yarnpkg.com/testcheck/-/testcheck-1.0.0-rc.2.tgz#11356a25b84575efe0b0857451e85b5fa74ee4e4"
integrity sha1-ETVqJbhFde/gsIV0UehbX6dO5OQ=
@ -9913,6 +10266,11 @@ through@2, through@^2.3.6:
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
thunkify@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d"
integrity sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=
thunky@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
@ -9923,6 +10281,11 @@ time-stamp@^2.0.0:
resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.2.0.tgz#917e0a66905688790ec7bbbde04046259af83f57"
integrity sha512-zxke8goJQpBeEgD82CXABeMh0LSJcj7CXEd0OHOg45HgcofF7pxNwZm9+RknpxpDhwN4gFpySkApKfFYfRQnUA==
timed-out@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
timers-browserify@^2.0.4:
version "2.0.11"
resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f"
@ -10477,6 +10840,11 @@ url-regex@^3.0.0:
dependencies:
ip-regex "^1.0.1"
url-to-options@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=
url@^0.11.0, url@~0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@ -10751,6 +11119,16 @@ websocket-extensions@>=0.1.1:
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
websocket@1.0.28:
version "1.0.28"
resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.28.tgz#9e5f6fdc8a3fe01d4422647ef93abdd8d45a78d3"
integrity sha512-00y/20/80P7H4bCYkzuuvvfDvh+dgtXi5kzDf3UcZwN6boTYaKvsrtZ5lIYm1Gsg48siMErd9M4zjSYfYFHTrA==
dependencies:
debug "^2.2.0"
nan "^2.11.0"
typedarray-to-buffer "^3.1.5"
yaeti "^0.0.6"
wgxpath@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/wgxpath/-/wgxpath-1.0.0.tgz#eef8a4b9d558cc495ad3a9a2b751597ecd9af690"
@ -10909,6 +11287,11 @@ xmlbuilder@~11.0.0:
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
xregexp@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943"
integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=
xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
@ -10931,6 +11314,11 @@ y18n@^4.0.0:
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
yaeti@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577"
integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"

Loading…
Cancel
Save