@automattic/vip 2.18.0 → 2.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## Changelog
2
2
 
3
+ ### 2.19.0 (23 Sep 2022)
4
+ - #1108 [dev-env] Validate import file and add debug lines
5
+ - #1107 [dev-env] Validate dns lookup
6
+ - #1104 [dev-env] fetch php and wordpress versions for creation wizard
7
+ - #1049 Fix security issues
8
+
3
9
  ### 2.18.0 (15 Sep 2022)
4
10
  - #1103 Force the preference for WebSocket in case we see an error during connection
5
11
  - #1102 Remove http proxy support
@@ -56,7 +56,6 @@ const cmd = (0, _command.default)().option('slug', 'Custom name of the dev envir
56
56
  (0, _devEnvironmentCli.addDevEnvConfigurationOptions)(cmd);
57
57
  cmd.examples(examples);
58
58
  cmd.argv(process.argv, async (arg, opt) => {
59
- await (0, _devEnvironmentCli.validateDependencies)();
60
59
  const environmentNameOptions = {
61
60
  slug: opt.slug,
62
61
  app: opt.app,
@@ -64,6 +63,7 @@ cmd.argv(process.argv, async (arg, opt) => {
64
63
  allowAppEnv: true
65
64
  };
66
65
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(environmentNameOptions);
66
+ await (0, _devEnvironmentCli.validateDependencies)(slug);
67
67
  debug('Args: ', arg, 'Options: ', opt);
68
68
  const trackingInfo = {
69
69
  slug
@@ -38,8 +38,8 @@ const examples = [{
38
38
  description: 'Destroys a local dev environment named foo'
39
39
  }];
40
40
  (0, _command.default)().option('slug', 'Custom name of the dev environment').option('soft', 'Keep config files needed to start an environment intact').examples(examples).argv(process.argv, async (arg, opt) => {
41
- await (0, _devEnvironmentCli.validateDependencies)();
42
41
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
42
+ await (0, _devEnvironmentCli.validateDependencies)(slug);
43
43
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
44
44
  await (0, _tracker.trackEvent)('dev_env_destroy_command_execute', trackingInfo);
45
45
  debug('Args: ', arg, 'Options: ', opt);
@@ -43,8 +43,8 @@ const examples = [{
43
43
 
44
44
  return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase = value.toLowerCase) === null || _value$toLowerCase === void 0 ? void 0 : _value$toLowerCase.call(value));
45
45
  }).examples(examples).argv(process.argv, async (unmatchedArgs, opt) => {
46
- await (0, _devEnvironmentCli.validateDependencies)();
47
46
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
47
+ await (0, _devEnvironmentCli.validateDependencies)(slug);
48
48
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
49
49
  await (0, _tracker.trackEvent)('dev_env_exec_command_execute', trackingInfo);
50
50
 
@@ -36,9 +36,9 @@ const examples = [{
36
36
  (0, _command.default)({
37
37
  requiredArgs: 1
38
38
  }).examples(examples).option('slug', 'Custom name of the dev environment').argv(process.argv, async (unmatchedArgs, opt) => {
39
- await (0, _devEnvironmentCli.validateDependencies)();
40
39
  const [filePath] = unmatchedArgs;
41
40
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
41
+ await (0, _devEnvironmentCli.validateDependencies)(slug);
42
42
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
43
43
  await (0, _tracker.trackEvent)('dev_env_import_media_command_execute', trackingInfo);
44
44
 
@@ -45,13 +45,13 @@ const examples = [{
45
45
  (0, _command.default)({
46
46
  requiredArgs: 1
47
47
  }).option('slug', 'Custom name of the dev environment').option(['r', 'search-replace'], 'Perform Search and Replace on the specified SQL file').option('in-place', 'Search and Replace explicitly on the given input file').option('skip-validate', 'Do not perform file validation.').examples(examples).argv(process.argv, async (unmatchedArgs, opt) => {
48
- await (0, _devEnvironmentCli.validateDependencies)();
49
48
  const [fileName] = unmatchedArgs;
50
49
  const {
51
50
  searchReplace,
52
51
  inPlace
53
52
  } = opt;
54
53
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
54
+ await (0, _devEnvironmentCli.validateDependencies)(slug);
55
55
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
56
56
  await (0, _tracker.trackEvent)('dev_env_import_sql_command_execute', trackingInfo);
57
57
 
@@ -36,8 +36,8 @@ const examples = [{
36
36
  description: 'Return information about a local dev environment named "my_site"'
37
37
  }];
38
38
  (0, _command.default)().option('slug', 'Custom name of the dev environment').option('all', 'Show Info for all local dev environments').option('extended', 'Show extended information about the dev environment').examples(examples).argv(process.argv, async (arg, opt) => {
39
- await (0, _devEnvironmentCli.validateDependencies)();
40
39
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
40
+ await (0, _devEnvironmentCli.validateDependencies)(slug);
41
41
  const trackingInfo = opt.all ? {
42
42
  all: true
43
43
  } : (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
@@ -38,7 +38,7 @@ const examples = [{
38
38
  await (0, _tracker.trackEvent)('dev_env_list_command_execute', trackingInfo);
39
39
 
40
40
  try {
41
- await (0, _devEnvironmentCore.printAllEnvironmentsInfo)();
41
+ await (0, _devEnvironmentCore.printAllEnvironmentsInfo)({});
42
42
  await (0, _tracker.trackEvent)('dev_env_list_command_success', trackingInfo);
43
43
  } catch (error) {
44
44
  (0, _devEnvironmentCli.handleCLIException)(error, 'dev_env_list_command_error', trackingInfo);
@@ -39,9 +39,9 @@ const examples = [{
39
39
  description: 'Starts a local dev environment'
40
40
  }];
41
41
  (0, _command.default)().option('slug', 'Custom name of the dev environment').option('skip-rebuild', 'Only start stopped services').option(['w', 'skip-wp-versions-check'], 'Skip propting for wordpress update if non latest').examples(examples).argv(process.argv, async (arg, opt) => {
42
- await (0, _devEnvironmentCli.validateDependencies)();
43
- const startProcessing = new Date();
44
42
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
43
+ await (0, _devEnvironmentCli.validateDependencies)(slug);
44
+ const startProcessing = new Date();
45
45
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
46
46
  await (0, _tracker.trackEvent)('dev_env_start_command_execute', trackingInfo);
47
47
  debug('Args: ', arg, 'Options: ', opt);
@@ -35,8 +35,8 @@ const examples = [{
35
35
  description: 'Stops a local dev environment'
36
36
  }];
37
37
  (0, _command.default)().option('slug', 'Custom name of the dev environment').examples(examples).argv(process.argv, async (arg, opt) => {
38
- await (0, _devEnvironmentCli.validateDependencies)();
39
38
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
39
+ await (0, _devEnvironmentCli.validateDependencies)(slug);
40
40
  debug('Args: ', arg, 'Options: ', opt);
41
41
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
42
42
  await (0, _tracker.trackEvent)('dev_env_stop_command_execute', trackingInfo);
@@ -38,8 +38,8 @@ const cmd = (0, _command.default)().option('slug', 'Custom name of the dev envir
38
38
  (0, _devEnvironmentCli.addDevEnvConfigurationOptions)(cmd);
39
39
  cmd.examples(examples);
40
40
  cmd.argv(process.argv, async (arg, opt) => {
41
- await (0, _devEnvironmentCli.validateDependencies)();
42
41
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
42
+ await (0, _devEnvironmentCli.validateDependencies)(slug);
43
43
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
44
44
  await (0, _tracker.trackEvent)('dev_env_update_command_execute', trackingInfo);
45
45
 
@@ -71,7 +71,10 @@ const DEFAULT_SLUG = 'vip-local';
71
71
  async function handleCLIException(exception, trackKey, trackBaseInfo = {}) {
72
72
  const errorPrefix = _chalk.default.red('Error:');
73
73
 
74
- if (_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND === exception.message) {
74
+ if (exception instanceof _userError.default) {
75
+ // User errors are handled in global error handler
76
+ throw exception;
77
+ } else if (_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND === exception.message) {
75
78
  const createCommand = _chalk.default.bold(_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND + ' create');
76
79
 
77
80
  const message = `Environment doesn't exist.\n\n\nTo create a new environment run:\n\n${createCommand}\n`;
@@ -104,12 +107,38 @@ async function handleCLIException(exception, trackKey, trackBaseInfo = {}) {
104
107
  }
105
108
  }
106
109
 
107
- const validateDependencies = async () => {
110
+ const verifyDNSResolution = slug => {
111
+ const dns = require('dns');
112
+
113
+ const expectedIP = '127.0.0.1';
114
+ const testDomain = `${slug}.vipdev.lndo.site`;
115
+ const advice = `Please add following line to hosts file on your system:\n${expectedIP} ${testDomain}`;
116
+ debug(`Verifying DNS resolution for ${testDomain}`);
117
+ return new Promise((resolve, reject) => {
118
+ dns.lookup(testDomain, (error, address) => {
119
+ debug(`Got DNS response ${address}`);
120
+
121
+ if (error) {
122
+ reject(new _userError.default(`DNS resolution for ${testDomain} failed. ${advice}`));
123
+ }
124
+
125
+ if (address !== expectedIP) {
126
+ reject(new _userError.default(`DNS resolution for ${testDomain} returned unexpected IP ${address}. Expected value is ${expectedIP}. ${advice}`));
127
+ }
128
+
129
+ resolve();
130
+ });
131
+ });
132
+ };
133
+
134
+ const validateDependencies = async slug => {
108
135
  try {
109
136
  await (0, _devEnvironmentLando.validateDockerInstalled)();
110
137
  } catch (exception) {
111
- exit.withError(exception.message);
138
+ throw new _userError.default(exception.message);
112
139
  }
140
+
141
+ await verifyDNSResolution(slug);
113
142
  };
114
143
 
115
144
  exports.validateDependencies = validateDependencies;
@@ -170,12 +199,14 @@ function processComponentOptionInput(passedParam, allowLocal) {
170
199
  }
171
200
 
172
201
  function getOptionsFromAppInfo(appInfo) {
173
- var _appInfo$environment, _appInfo$environment2, _appInfo$environment3;
202
+ var _appInfo$environment, _appInfo$environment2, _appInfo$environment3, _appInfo$environment4, _appInfo$environment5;
174
203
 
175
204
  return {
176
205
  title: ((_appInfo$environment = appInfo.environment) === null || _appInfo$environment === void 0 ? void 0 : _appInfo$environment.name) || appInfo.name || '',
177
206
  multisite: !!(appInfo !== null && appInfo !== void 0 && (_appInfo$environment2 = appInfo.environment) !== null && _appInfo$environment2 !== void 0 && _appInfo$environment2.isMultisite),
178
- mediaRedirectDomain: (_appInfo$environment3 = appInfo.environment) === null || _appInfo$environment3 === void 0 ? void 0 : _appInfo$environment3.primaryDomain
207
+ mediaRedirectDomain: (_appInfo$environment3 = appInfo.environment) === null || _appInfo$environment3 === void 0 ? void 0 : _appInfo$environment3.primaryDomain,
208
+ php: ((_appInfo$environment4 = appInfo.environment) === null || _appInfo$environment4 === void 0 ? void 0 : _appInfo$environment4.php) || '',
209
+ wordpress: ((_appInfo$environment5 = appInfo.environment) === null || _appInfo$environment5 === void 0 ? void 0 : _appInfo$environment5.wordpress) || ''
179
210
  };
180
211
  }
181
212
  /**
@@ -50,6 +50,10 @@ var _app = _interopRequireDefault(require("../api/app"));
50
50
 
51
51
  var _devEnvironment = require("../constants/dev-environment");
52
52
 
53
+ var _software = require("../config/software");
54
+
55
+ var _userError = _interopRequireDefault(require("../user-error"));
56
+
53
57
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
54
58
 
55
59
  /**
@@ -380,9 +384,17 @@ async function getApplicationInformation(appId, envType) {
380
384
  isMultisite,
381
385
  primaryDomain {
382
386
  name
387
+ },
388
+ softwareSettings {
389
+ php {
390
+ ...Software
391
+ }
392
+ wordpress {
393
+ ...Software
394
+ }
383
395
  }
384
396
  }`;
385
- const queryResult = await (0, _app.default)(appId, fieldsQuery);
397
+ const queryResult = await (0, _app.default)(appId, fieldsQuery, _software.appQueryFragments);
386
398
  const appData = {};
387
399
 
388
400
  if (queryResult) {
@@ -412,14 +424,16 @@ async function getApplicationInformation(appId, envType) {
412
424
  }
413
425
 
414
426
  if (envData) {
415
- var _envData$primaryDomai;
427
+ var _envData$primaryDomai, _envData$softwareSett, _envData$softwareSett2, _envData$softwareSett3, _envData$softwareSett4, _envData$softwareSett5, _envData$softwareSett6;
416
428
 
417
429
  appData.environment = {
418
430
  name: envData.name,
419
431
  branch: envData.branch,
420
432
  type: envData.type,
421
433
  isMultisite: envData.isMultisite,
422
- primaryDomain: ((_envData$primaryDomai = envData.primaryDomain) === null || _envData$primaryDomai === void 0 ? void 0 : _envData$primaryDomai.name) || ''
434
+ primaryDomain: ((_envData$primaryDomai = envData.primaryDomain) === null || _envData$primaryDomai === void 0 ? void 0 : _envData$primaryDomai.name) || '',
435
+ php: ((_envData$softwareSett = envData.softwareSettings) === null || _envData$softwareSett === void 0 ? void 0 : (_envData$softwareSett2 = _envData$softwareSett.php) === null || _envData$softwareSett2 === void 0 ? void 0 : (_envData$softwareSett3 = _envData$softwareSett2.current) === null || _envData$softwareSett3 === void 0 ? void 0 : _envData$softwareSett3.version) || '',
436
+ wordpress: ((_envData$softwareSett4 = envData.softwareSettings) === null || _envData$softwareSett4 === void 0 ? void 0 : (_envData$softwareSett5 = _envData$softwareSett4.wordpress) === null || _envData$softwareSett5 === void 0 ? void 0 : (_envData$softwareSett6 = _envData$softwareSett5.current) === null || _envData$softwareSett6 === void 0 ? void 0 : _envData$softwareSett6.version) || ''
423
437
  };
424
438
  }
425
439
  }
@@ -428,10 +442,16 @@ async function getApplicationInformation(appId, envType) {
428
442
  }
429
443
 
430
444
  async function resolveImportPath(slug, fileName, searchReplace, inPlace) {
445
+ debug(`Will try to resolve path - ${fileName}`);
431
446
  let resolvedPath = (0, _devEnvironmentCli.resolvePath)(fileName);
447
+ debug(`Filename ${fileName} resolved to ${resolvedPath}`);
432
448
 
433
449
  if (!_fs.default.existsSync(resolvedPath)) {
434
- throw new Error('The provided file does not exist or it is not valid (see "--help" for examples)');
450
+ throw new _userError.default(`The provided file ${resolvedPath} does not exist or it is not valid (see "--help" for examples)`);
451
+ }
452
+
453
+ if (_fs.default.lstatSync(resolvedPath).isDirectory()) {
454
+ throw new _userError.default(`The provided file ${resolvedPath} is a directory. Please point to a sql file.`);
435
455
  } // Run Search and Replace if the --search-replace flag was provided
436
456
 
437
457