UNPKG

wanbotz-security

Version:

Protect Your Script Using WanBotz Security

315 lines (254 loc) • 9.75 kB
const fs = require("fs"); const chalk = require("chalk"); const readlineSync = require("readline-sync"); const passwordPrompt = require("password-prompt"); const { Pool } = require("pg"); const bcrypt = require("bcryptjs"); const jwt = require("jsonwebtoken"); const readline = require("readline"); function question(query) { const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); return new Promise((resolve) => rl.question(query, (answer) => { rl.close(); resolve(answer); })); } const pool = new Pool({ connectionString: "postgresql://WanDB_owner:npg_4bOotp5KADWQ@ep-lively-tooth-a8czukgu-pooler.eastus2.azure.neon.tech/WanDB?sslmode=require", ssl: { rejectUnauthorized: false } }); const SECRET_KEY = "WanzzDevsJaya2025"; const path = require("path"); const SESSION_DIR = "./session"; const SESSION_FILE = path.join(SESSION_DIR, "authed.json"); if (!fs.existsSync(SESSION_DIR)) { fs.mkdirSync(SESSION_DIR, { recursive: true }); } if (!fs.existsSync(SESSION_FILE)) { fs.writeFileSync(SESSION_FILE, "{}"); } async function getPassword(promptText) { return await passwordPrompt(promptText, { method: "hide" }); } async function register() { console.log(chalk.green("\n====== REGISTER ======")); const username = readlineSync.question("Username: "); const number = readlineSync.question("Nomor HP (628xxx): "); const password = await getPassword("Password: "); if (!username || !number || !password) { console.log(chalk.red("Harap isi semua pertanyaan!")); return; } try { const hashedPassword = await bcrypt.hash(password, 10); const token = jwt.sign({ username }, SECRET_KEY, { expiresIn: "7d" }); await pool.query("INSERT INTO users (username, password, number, token) VALUES ($1, $2, $3, $4)", [username, hashedPassword, number, token]); console.log(chalk.green("Registerasi BerhasilšŸš€!")); } catch (err) { console.log(chalk.red("Gagal register, mungkin username atau nomor telah terpakai.")); } } async function login() { console.log(chalk.blue("\n====== LOGIN ======")); const username = await question("Username: "); try { const result = await pool.query("SELECT * FROM users WHERE username = $1", [username]); if (result.rows.length === 0) { console.log(chalk.red("User tidak ditemukan!")); return; } const user = result.rows[0]; let sessions = {}; if (fs.existsSync(SESSION_FILE)) { sessions = JSON.parse(fs.readFileSync(SESSION_FILE)); } if (sessions[username] === user.token) { console.log(chalk.green("Login sukses!")); return; } const password = await getPassword("Password: "); const validPassword = await bcrypt.compare(password, user.password); if (!validPassword) { console.log(chalk.red("Password salah!")); return; } sessions[username] = user.token; fs.writeFileSync(SESSION_FILE, JSON.stringify(sessions, null, 2)); console.log(chalk.green("Login sukses!")); } catch (err) { console.log(chalk.red("Terjadi kesalahan saat login!")); } } async function deleteUser() { console.log(chalk.red("\n====== DELETE USERS ======")); const username = readlineSync.question("Masukkan username: "); try { const result = await pool.query("SELECT * FROM users WHERE username = $1", [username]); if (result.rows.length === 0) { console.log(chalk.red("User tidak ditemukan!")); return; } const konfirmasi = readlineSync.question(`Apakah anda yakin ingin menghapus "${username}"? (y/n): `); if (konfirmasi.toLowerCase() !== "y") { console.log(chalk.blue("Penghapusan dibatalkan")); return; } await pool.query("DELETE FROM users WHERE username = $1", [username]); if (fs.existsSync(SESSION_FILE)) { let sessions = JSON.parse(fs.readFileSync(SESSION_FILE)); delete sessions[username]; fs.writeFileSync(SESSION_FILE, JSON.stringify(sessions, null, 2)); } console.log(chalk.green(`User "${username}" berhasil dihapus!`)); } catch (err) { console.log(chalk.red("Terjadi kesalahan saat menghapus user!")); } } async function resetPassword() { console.log(chalk.cyan("\n====== RESET PASSWORD ======")); const username = readlineSync.question("Username: "); try { const result = await pool.query("SELECT * FROM users WHERE username = $1", [username]); if (result.rows.length === 0) { console.log(chalk.red("User tidak ditemukan!")); return; } const user = result.rows[0]; const oldPassword = await getPassword("Password lama: "); const validPassword = await bcrypt.compare(oldPassword, user.password); if (!validPassword) { console.log(chalk.red("Password lama salah!!")); return; } const newPassword = await getPassword("Password baru: "); if (!newPassword) { console.log(chalk.red("Password tidak boleh kosong!")); return; } const hashedNewPassword = await bcrypt.hash(newPassword, 10); await pool.query("UPDATE users SET password = $1 WHERE username = $2", [hashedNewPassword, username]); console.log(chalk.green("Password berhasil diganti!!")); } catch (err) { console.log(chalk.red("Terjadi kesalahan saat mereset password!!")); } } async function renameUser() { console.log(chalk.yellow("\n====== RENAME USER ======")); const oldUsername = readlineSync.question("Username lama: "); try { const result = await pool.query("SELECT * FROM users WHERE username = $1", [oldUsername]); if (result.rows.length === 0) { console.log(chalk.red("User tidak ditemukan!")); return; } const user = result.rows[0]; const password = await getPassword("Password: "); const validPassword = await bcrypt.compare(password, user.password); if (!validPassword) { console.log(chalk.red("Password salah!")); return; } const newUsername = readlineSync.question("Username baru: "); if (!newUsername) { console.log(chalk.red("Username baru tidak boleh kosong!")); return; } const checkUser = await pool.query("SELECT * FROM users WHERE username = $1", [newUsername]); if (checkUser.rows.length > 0) { console.log(chalk.red("Username sudah digunakan!")); return; } await pool.query("UPDATE users SET username = $1 WHERE username = $2", [newUsername, oldUsername]); if (fs.existsSync(SESSION_FILE)) { let sessions = JSON.parse(fs.readFileSync(SESSION_FILE)); if (sessions[oldUsername]) { sessions[newUsername] = sessions[oldUsername]; delete sessions[oldUsername]; fs.writeFileSync(SESSION_FILE, JSON.stringify(sessions, null, 2)); } } console.log(chalk.green(`Username berhasil diubah dari "${oldUsername}" ke "${newUsername}"!`)); } catch (err) { console.log(chalk.red("Terjadi kesalahan saat rename username!")); } } async function resetNumber() { console.log(chalk.magenta("\n====== RESET NUMBER ======")); const username = readlineSync.question("Username: "); try { const result = await pool.query("SELECT * FROM users WHERE username = $1", [username]); if (result.rows.length === 0) { console.log(chalk.red("User tidak ditemukan!")); return; } const user = result.rows[0]; const password = await getPassword("Password: "); const validPassword = await bcrypt.compare(password, user.password); if (!validPassword) { console.log(chalk.red("Password salah!")); return; } const newNumber = readlineSync.question("Nomor HP baru (628xxx): "); if (!/^628\d+$/.test(newNumber)) { console.log(chalk.red("Format nomor HP tidak valid! Harus dimulai dengan 628.")); return; } await pool.query("UPDATE users SET number = $1 WHERE username = $2", [newNumber, username]); console.log(chalk.green("Nomor HP berhasil diperbarui!")); } catch (err) { console.log(chalk.red("Terjadi kesalahan saat reset nomor HP!")); } } async function listUsers() { console.log(chalk.cyan("\n====== LIST USER ======")); try { const result = await pool.query("SELECT id, username, number FROM users ORDER BY id ASC"); if (result.rows.length === 0) { console.log(chalk.red("Tidak ada user terdaftar.")); return; } console.log(chalk.yellow("\nID | Username | Nomor HP")); console.log(chalk.yellow("--------------------------------")); result.rows.forEach(user => { console.log(`${user.id.toString().padEnd(4)} | ${user.username.padEnd(12)} | ${user.number}`); }); } catch (err) { console.log(chalk.red("Terjadi kesalahan saat mengambil data user!")); } } async function main() { console.log(chalk.yellow("\n====== Wan Database ======")); console.log("1. Register"); console.log("2. Login"); console.log("3. Hapus User"); console.log("4. Reset Password"); console.log("5. Rename User"); console.log("6. Reset Number"); console.log("7. List User"); console.log("8. Exit"); const pilihan = readlineSync.question("Pilih menu: "); if (pilihan === "1") { await register(); } else if (pilihan === "2") { await login(); } else if (pilihan === "3") { await deleteUser(); } else if (pilihan === "4") { await resetPassword(); } else if (pilihan === "5") { await renameUser(); } else if (pilihan === "6") { await resetNumber(); } else if (pilihan === "7") { await listUsers(); } else if (pilihan === "0") { console.log(chalk.blue("Exit...")); process.exit(); } main(); } module.exports = { register, login, deleteUser, resetPassword, renameUser, resetNumber, listUsers, SESSION_DIR, SESSION_FILE }