const { execSync } = require("child_process"); const fs = require("fs"); const readline = require("readline"); const username = "user"; const password = "root"; /* ---------------- RUN COMMAND ---------------- */ function run(cmd) { console.log(`Running: ${cmd}`); try { execSync(cmd, { stdio: "inherit" }); } catch (err) { console.error(`Error: ${cmd}`); } } /* ---------------- FILES ---------------- */ const PIN_FILE = "pin.lock"; const ATTEMPT_FILE = "attempts.lock"; const MAX_ATTEMPTS = 3; const LOCK_TIME = 5 * 60 * 1000; /* ---------------- READLINE ---------------- */ const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); function ask(q) { return new Promise(resolve => rl.question(q, ans => resolve(ans.trim()))); } /* ---------------- PIN SYSTEM ---------------- */ function generatePIN() { return Math.floor(1000 + Math.random() * 9000).toString(); } function loadPIN() { if (!fs.existsSync(PIN_FILE)) { const pin = generatePIN(); fs.writeFileSync(PIN_FILE, JSON.stringify({ pin }, null, 2)); console.log("New PIN created:", pin); return pin; } return JSON.parse(fs.readFileSync(PIN_FILE)).pin; } function loadAttempts() { if (!fs.existsSync(ATTEMPT_FILE)) { return { attempts: 0, lockUntil: 0 }; } return JSON.parse(fs.readFileSync(ATTEMPT_FILE)); } function saveAttempts(data) { fs.writeFileSync(ATTEMPT_FILE, JSON.stringify(data, null, 2)); } function timeLeft(ms) { const sec = Math.max(0, Math.floor(ms / 1000)); return { min: Math.floor(sec / 60), sec: sec % 60 }; } /* ---------------- INSTALLER ---------------- */ function install() { console.log("\nStarting installation...\n"); run("sudo apt update -y"); run("wget -q --show-progress https://dl.google.com/linux/direct/chrome-remote-desktop_current_amd64.deb"); run("sudo dpkg --install chrome-remote-desktop_current_amd64.deb"); run("sudo apt-get install --fix-broken -y"); run("sudo systemctl disable lightdm.service"); run("sudo DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes -y xfce4 desktop-base dbus-x11 xscreensaver"); run(`sudo bash -c 'echo "exec /etc/X11/Xsession /usr/bin/xfce4-session" > /etc/chrome-remote-desktop-session'`); run(`sudo useradd -m ${username}`); run(`echo "${username}:${password}" | sudo chpasswd`); run(`sudo sed -i 's#/bin/sh#/bin/bash#g' /etc/passwd`); run("sudo add-apt-repository ppa:mozillateam/ppa -y"); run("sudo apt update -y"); run("sudo apt install firefox-esr -y"); console.log("\nInstallation completed successfully"); } /* ---------------- LOGIN ---------------- */ async function loginFlow() { const pin = loadPIN(); const state = loadAttempts(); if (state.lockUntil && Date.now() < state.lockUntil) { const t = timeLeft(state.lockUntil - Date.now()); console.log(`Too many failed attempts.`); console.log(`Try again in ${t.min} min ${t.sec} sec`); process.exit(1); } let inputPin = await ask("Enter PIN: "); if (inputPin === pin) { console.log("PIN correct. Access granted."); saveAttempts({ attempts: 0, lockUntil: 0 }); rl.close(); // START INSTALL AFTER LOGIN install(); return; } state.attempts += 1; console.log(`Wrong PIN (${state.attempts}/${MAX_ATTEMPTS})`); if (state.attempts >= MAX_ATTEMPTS) { state.lockUntil = Date.now() + LOCK_TIME; state.attempts = 0; const t = timeLeft(LOCK_TIME); console.log(`Locked for ${t.min} min ${t.sec} sec`); saveAttempts(state); rl.close(); process.exit(1); } saveAttempts(state); rl.close(); process.exit(1); } /* ---------------- INIT PIN SETUP ---------------- */ async function setupPINIfNeeded() { if (fs.existsSync(PIN_FILE)) return; console.log("First time setup: Create PIN"); let pin1 = await ask("Enter new 4-digit PIN: "); let pin2 = await ask("Confirm PIN: "); if (pin1 !== pin2) { console.log("PIN mismatch. Try again."); rl.close(); process.exit(1); } fs.writeFileSync(PIN_FILE, JSON.stringify({ pin: pin1 }, null, 2)); fs.writeFileSync(ATTEMPT_FILE, JSON.stringify({ attempts: 0, lockUntil: 0 }, null, 2)); console.log("PIN created successfully."); } /* ---------------- MAIN ---------------- */ (async () => { await setupPINIfNeeded(); await loginFlow(); })();