easy-devops 0.1.3 → 0.1.4

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.
@@ -268,7 +268,7 @@ async function installNginx() {
268
268
  let nginxVersion = FALLBACK_VERSION;
269
269
 
270
270
  const fetchVersionResult = await run(
271
- `try { $p=(Invoke-WebRequest -Uri 'https://nginx.org/en/download.html' -UseBasicParsing -TimeoutSec 15).Content; if($p -match 'nginx-(\\d+\\.\\d+\\.\\d+)\\.zip'){$Matches[1]}else{''} } catch { '' }`,
271
+ `[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; try { $p=(Invoke-WebRequest -Uri 'https://nginx.org/en/download.html' -UseBasicParsing -TimeoutSec 15).Content; if($p -match 'nginx-(\\d+\\.\\d+\\.\\d+)\\.zip'){$Matches[1]}else{''} } catch { '' }`,
272
272
  { timeout: 20000 },
273
273
  );
274
274
  const fetched = (fetchVersionResult.stdout || '').trim();
@@ -276,15 +276,30 @@ async function installNginx() {
276
276
 
277
277
  const { nginxDir } = loadConfig();
278
278
  const zipUrl = `https://nginx.org/download/nginx-${nginxVersion}.zip`;
279
+ const zipDest = `$env:TEMP\\nginx-${nginxVersion}.zip`;
279
280
 
280
281
  spinner.text = `Downloading nginx ${nginxVersion}…`;
281
282
 
282
- const downloadResult = await run(
283
- `$ProgressPreference='SilentlyContinue'; Invoke-WebRequest -Uri '${zipUrl}' -OutFile "$env:TEMP\\nginx-${nginxVersion}.zip" -UseBasicParsing -TimeoutSec 120`,
283
+ // Try Invoke-WebRequest with TLS 1.2 forced, fall back to curl.exe
284
+ let downloadOk = false;
285
+ let downloadResult = await run(
286
+ `[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $ProgressPreference='SilentlyContinue'; Invoke-WebRequest -Uri '${zipUrl}' -OutFile "${zipDest}" -UseBasicParsing -TimeoutSec 120`,
284
287
  { timeout: 130000 },
285
288
  );
289
+ if (downloadResult.success) {
290
+ downloadOk = true;
291
+ } else {
292
+ const hasCurl = (await run('where.exe curl.exe 2>$null')).success;
293
+ if (hasCurl) {
294
+ downloadResult = await run(
295
+ `curl.exe -L --silent --show-error --max-time 120 -o "${zipDest}" "${zipUrl}"`,
296
+ { timeout: 130000 },
297
+ );
298
+ if (downloadResult.success) downloadOk = true;
299
+ }
300
+ }
286
301
 
287
- if (!downloadResult.success) {
302
+ if (!downloadOk) {
288
303
  spinner.fail('Download failed');
289
304
  console.log(chalk.red(downloadResult.stderr || downloadResult.stdout));
290
305
  console.log(chalk.gray(`\n Download nginx manually from: https://nginx.org/en/download.html\n`));
@@ -276,29 +276,41 @@ async function installCertbot() {
276
276
  console.log(chalk.yellow(' Chocolatey failed, trying direct download...\n'));
277
277
  }
278
278
 
279
- // 3. Direct download — try multiple sources in order
279
+ // 3. Direct download — try multiple sources × multiple download methods
280
+ // PowerShell 5.1 on Windows Server defaults to TLS 1.0; GitHub requires TLS 1.2+.
281
+ // Force TLS 1.2 before every Invoke-WebRequest call.
282
+ // Also try curl.exe (built into Windows Server 2019+) as a second method.
280
283
  const INSTALLER_FILENAME = 'certbot-beta-installer-win_amd64_signed.exe';
284
+ const INSTALLER_DEST = '$env:TEMP\\certbot-installer.exe';
281
285
  const downloadSources = [
282
286
  `https://github.com/certbot/certbot/releases/latest/download/${INSTALLER_FILENAME}`,
283
287
  `https://dl.eff.org/${INSTALLER_FILENAME}`,
284
288
  ];
285
289
 
290
+ const hasCurl = (await run('where.exe curl.exe 2>$null')).success;
291
+
286
292
  let downloaded = false;
287
293
  for (const url of downloadSources) {
288
294
  const label = new URL(url).hostname;
289
295
  console.log(chalk.gray(`\n Downloading certbot installer from ${label} ...\n`));
290
296
 
291
- const downloadResult = await run(
292
- `$ProgressPreference='SilentlyContinue'; Invoke-WebRequest -Uri '${url}' -OutFile "$env:TEMP\\certbot-installer.exe" -UseBasicParsing -TimeoutSec 120`,
297
+ // Method A: Invoke-WebRequest with TLS 1.2 forced
298
+ const iwr = await run(
299
+ `[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $ProgressPreference='SilentlyContinue'; Invoke-WebRequest -Uri '${url}' -OutFile "${INSTALLER_DEST}" -UseBasicParsing -TimeoutSec 120`,
293
300
  { timeout: 130000 },
294
301
  );
302
+ if (iwr.success) { downloaded = true; break; }
295
303
 
296
- if (downloadResult.success) {
297
- downloaded = true;
298
- break;
304
+ // Method B: curl.exe (handles TLS independently of PowerShell/.NET settings)
305
+ if (hasCurl) {
306
+ const curlResult = await run(
307
+ `curl.exe -L --silent --show-error --max-time 120 -o "${INSTALLER_DEST}" "${url}"`,
308
+ { timeout: 130000 },
309
+ );
310
+ if (curlResult.success) { downloaded = true; break; }
299
311
  }
300
312
 
301
- console.log(chalk.yellow(` Failed from ${label}: ${(downloadResult.stderr || downloadResult.stdout).split('\n')[0].trim()}`));
313
+ console.log(chalk.yellow(` Failed from ${label}`));
302
314
  }
303
315
 
304
316
  if (!downloaded) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "easy-devops",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "A unified DevOps management tool with CLI and web dashboard for managing Nginx, SSL certificates, and Node.js on Linux and Windows servers.",
5
5
  "keywords": [
6
6
  "devops",