mirror of
https://github.com/AikidoSec/safe-chain.git
synced 2026-05-26 12:10:49 +00:00
Add ultimate installer for Windows
This commit is contained in:
parent
b1fa9f5492
commit
dba101daa7
2 changed files with 121 additions and 12 deletions
|
|
@ -16,6 +16,7 @@ import path from "path";
|
|||
import { fileURLToPath } from "url";
|
||||
import fs from "fs";
|
||||
import { knownAikidoTools } from "../src/shell-integration/helpers.js";
|
||||
import { installUltimate } from "../src/installation/installUltimate.js";
|
||||
|
||||
/** @type {string} */
|
||||
// This checks the current file's dirname in a way that's compatible with:
|
||||
|
|
@ -62,6 +63,8 @@ if (tool) {
|
|||
process.exit(0);
|
||||
} else if (command === "setup") {
|
||||
setup();
|
||||
} else if (command === "--ultimate") {
|
||||
installUltimate();
|
||||
} else if (command === "teardown") {
|
||||
teardownDirectories();
|
||||
teardown();
|
||||
|
|
@ -82,36 +85,41 @@ if (tool) {
|
|||
|
||||
function writeHelp() {
|
||||
ui.writeInformation(
|
||||
chalk.bold("Usage: ") + chalk.cyan("safe-chain <command>")
|
||||
chalk.bold("Usage: ") + chalk.cyan("safe-chain <command>"),
|
||||
);
|
||||
ui.emptyLine();
|
||||
ui.writeInformation(
|
||||
`Available commands: ${chalk.cyan("setup")}, ${chalk.cyan(
|
||||
"teardown"
|
||||
"teardown",
|
||||
)}, ${chalk.cyan("setup-ci")}, ${chalk.cyan("help")}, ${chalk.cyan(
|
||||
"--version"
|
||||
)}`
|
||||
"--version",
|
||||
)}`,
|
||||
);
|
||||
ui.emptyLine();
|
||||
ui.writeInformation(
|
||||
`- ${chalk.cyan(
|
||||
"safe-chain setup"
|
||||
)}: This will setup your shell to wrap safe-chain around npm, npx, yarn, pnpm, pnpx, bun, bunx, pip and pip3.`
|
||||
"safe-chain setup",
|
||||
)}: This will setup your shell to wrap safe-chain around npm, npx, yarn, pnpm, pnpx, bun, bunx, pip and pip3.`,
|
||||
);
|
||||
ui.writeInformation(
|
||||
`- ${chalk.cyan(
|
||||
"safe-chain teardown"
|
||||
)}: This will remove safe-chain aliases from your shell configuration.`
|
||||
"safe-chain --ultimate",
|
||||
)}: This installs the ultimate version of safe-chain, enabling protection for more eco-systems (vscode).`,
|
||||
);
|
||||
ui.writeInformation(
|
||||
`- ${chalk.cyan(
|
||||
"safe-chain setup-ci"
|
||||
)}: This will setup safe-chain for CI environments by creating shims and modifying the PATH.`
|
||||
"safe-chain teardown",
|
||||
)}: This will remove safe-chain aliases from your shell configuration.`,
|
||||
);
|
||||
ui.writeInformation(
|
||||
`- ${chalk.cyan(
|
||||
"safe-chain setup-ci",
|
||||
)}: This will setup safe-chain for CI environments by creating shims and modifying the PATH.`,
|
||||
);
|
||||
ui.writeInformation(
|
||||
`- ${chalk.cyan("safe-chain --version")} (or ${chalk.cyan(
|
||||
"-v"
|
||||
)}): Display the current version of safe-chain.`
|
||||
"-v",
|
||||
)}): Display the current version of safe-chain.`,
|
||||
);
|
||||
ui.emptyLine();
|
||||
}
|
||||
|
|
|
|||
101
packages/safe-chain/src/installation/installUltimate.js
Normal file
101
packages/safe-chain/src/installation/installUltimate.js
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
import { platform, arch, tmpdir } from "os";
|
||||
import { createWriteStream, unlinkSync } from "fs";
|
||||
import { join } from "path";
|
||||
import { execSync } from "child_process";
|
||||
import { pipeline } from "stream/promises";
|
||||
import fetch from "make-fetch-happen";
|
||||
import { ui } from "../environment/userInteraction.js";
|
||||
|
||||
const ULTIMATE_VERSION = "v0.2.0";
|
||||
|
||||
export function installUltimate() {
|
||||
const operatingSystem = platform();
|
||||
|
||||
if (operatingSystem === "win32") {
|
||||
installOnWindows();
|
||||
} else {
|
||||
ui.writeInformation(
|
||||
`${operatingSystem} is not supported yet by safe-chain's ultimate version.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function installOnWindows() {
|
||||
if (!isRunningAsAdmin()) {
|
||||
ui.writeError("Administrator privileges required.");
|
||||
ui.writeInformation(
|
||||
"Please run this command in an elevated terminal (Run as Administrator)."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const architecture = getWindowsArchitecture();
|
||||
const downloadUrl = buildDownloadUrl(architecture);
|
||||
const msiPath = join(tmpdir(), `SafeChainAgent-${Date.now()}.msi`);
|
||||
|
||||
ui.writeInformation(`Downloading SafeChain Agent ${ULTIMATE_VERSION} for ${architecture}...`);
|
||||
ui.writeVerbose(`Download URL: ${downloadUrl}`);
|
||||
ui.writeVerbose(`Destination: ${msiPath}`);
|
||||
await downloadFile(downloadUrl, msiPath);
|
||||
|
||||
ui.writeInformation("Installing SafeChain Agent...");
|
||||
ui.writeVerbose(`Running: msiexec /i "${msiPath}" /qn`);
|
||||
runMsiInstaller(msiPath);
|
||||
|
||||
ui.writeVerbose(`Cleaning up temporary file: ${msiPath}`);
|
||||
cleanup(msiPath);
|
||||
ui.writeInformation("SafeChain Agent installed successfully!");
|
||||
}
|
||||
|
||||
function isRunningAsAdmin() {
|
||||
try {
|
||||
execSync("net session", { stdio: "ignore" });
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getWindowsArchitecture() {
|
||||
const nodeArch = arch();
|
||||
if (nodeArch === "x64") return "amd64";
|
||||
if (nodeArch === "arm64") return "arm64";
|
||||
throw new Error(`Unsupported architecture: ${nodeArch}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} architecture
|
||||
*/
|
||||
function buildDownloadUrl(architecture) {
|
||||
return `https://github.com/AikidoSec/safechain-internals/releases/download/${ULTIMATE_VERSION}/SafeChainAgent-windows-${architecture}.msi`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {string} destPath
|
||||
*/
|
||||
async function downloadFile(url, destPath) {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Download failed: ${response.statusText}`);
|
||||
}
|
||||
await pipeline(response.body, createWriteStream(destPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} msiPath
|
||||
*/
|
||||
function runMsiInstaller(msiPath) {
|
||||
execSync(`msiexec /i "${msiPath}" /qn`, { stdio: "inherit" });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} msiPath
|
||||
*/
|
||||
function cleanup(msiPath) {
|
||||
try {
|
||||
unlinkSync(msiPath);
|
||||
} catch {
|
||||
// Ignore cleanup errors
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue