Skip to content

Commit abc8f7c

Browse files
authored
Add files via upload
1 parent 4079dc5 commit abc8f7c

File tree

11 files changed

+595
-282
lines changed

11 files changed

+595
-282
lines changed

config.js

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,21 @@
11
require('dotenv').config();
22
const path = require('path');
3-
const fs = require('fs');
4-
5-
const configPath = path.join(__dirname, 'config-data.json');
6-
7-
function loadConfig() {
8-
try {
9-
if (fs.existsSync(configPath)) {
10-
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
11-
}
12-
} catch (e) {}
13-
return {
14-
siteName: 'Bot Panel',
15-
logoUrl: '',
16-
adminUser: process.env.ADMIN_USER || 'admin',
17-
adminPass: process.env.ADMIN_PASS || 'admin123',
18-
};
19-
}
20-
21-
function saveConfig(cfg) {
22-
fs.writeFileSync(configPath, JSON.stringify(cfg, null, 2));
23-
}
3+
const db = require('./database');
244

255
module.exports = {
266
port: process.env.PORT || 3000,
277
sessionSecret: process.env.SESSION_SECRET || 'changeme_super_secret_key',
288
serversDir: path.join(__dirname, 'servers'),
29-
dataFile: path.join(__dirname, 'panel-data.json'),
30-
loadConfig,
31-
saveConfig,
9+
// Load dynamic config from DB
10+
loadConfig() {
11+
const s = db.getAllSettings();
12+
return {
13+
siteName: s.site_name || 'Bot Panel',
14+
logoUrl: s.logo_url || '',
15+
};
16+
},
17+
saveConfig(cfg) {
18+
if (cfg.siteName !== undefined) db.setSetting('site_name', cfg.siteName);
19+
if (cfg.logoUrl !== undefined) db.setSetting('logo_url', cfg.logoUrl);
20+
},
3221
};

database.js

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
const Database = require('better-sqlite3');
2+
const path = require('path');
3+
const bcrypt = require('bcryptjs');
4+
5+
const DB_PATH = path.join(__dirname, 'panel.db');
6+
7+
let db;
8+
9+
function getDb() {
10+
if (!db) {
11+
db = new Database(DB_PATH);
12+
db.pragma('journal_mode = WAL');
13+
initSchema();
14+
}
15+
return db;
16+
}
17+
18+
function initSchema() {
19+
db.exec(`
20+
CREATE TABLE IF NOT EXISTS settings (
21+
key TEXT PRIMARY KEY,
22+
value TEXT NOT NULL
23+
);
24+
25+
CREATE TABLE IF NOT EXISTS users (
26+
id INTEGER PRIMARY KEY AUTOINCREMENT,
27+
username TEXT UNIQUE NOT NULL,
28+
password TEXT NOT NULL,
29+
role TEXT NOT NULL DEFAULT 'user',
30+
max_servers INTEGER NOT NULL DEFAULT 3,
31+
max_ram INTEGER NOT NULL DEFAULT 512,
32+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
33+
);
34+
35+
CREATE TABLE IF NOT EXISTS servers (
36+
id TEXT PRIMARY KEY,
37+
name TEXT NOT NULL,
38+
entry_point TEXT NOT NULL DEFAULT 'index.js',
39+
ram_limit INTEGER NOT NULL DEFAULT 512,
40+
cpu_limit INTEGER NOT NULL DEFAULT 100,
41+
owner TEXT,
42+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
43+
);
44+
`);
45+
46+
// Insert default settings if not exist
47+
const insertSetting = db.prepare(`INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)`);
48+
insertSetting.run('site_name', 'Bot Panel');
49+
insertSetting.run('logo_url', '');
50+
insertSetting.run('default_ram', '512');
51+
insertSetting.run('default_cpu', '100');
52+
insertSetting.run('max_servers_per_user', '5');
53+
54+
// Create default admin if no admin exists
55+
const adminCount = db.prepare(`SELECT COUNT(*) as cnt FROM users WHERE role = 'admin'`).get();
56+
if (adminCount.cnt === 0) {
57+
const hash = bcrypt.hashSync(process.env.ADMIN_PASS || 'admin123', 10);
58+
db.prepare(`INSERT OR IGNORE INTO users (username, password, role, max_servers, max_ram) VALUES (?, ?, 'admin', 999, 8192)`)
59+
.run(process.env.ADMIN_USER || 'admin', hash);
60+
}
61+
}
62+
63+
// ── Settings ──────────────────────────────────────────────
64+
function getSetting(key) {
65+
const row = getDb().prepare('SELECT value FROM settings WHERE key = ?').get(key);
66+
return row ? row.value : null;
67+
}
68+
69+
function setSetting(key, value) {
70+
getDb().prepare('INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)').run(key, String(value));
71+
}
72+
73+
function getAllSettings() {
74+
const rows = getDb().prepare('SELECT key, value FROM settings').all();
75+
const obj = {};
76+
rows.forEach(r => obj[r.key] = r.value);
77+
return obj;
78+
}
79+
80+
// ── Users ──────────────────────────────────────────────────
81+
function getUserByUsername(username) {
82+
return getDb().prepare('SELECT * FROM users WHERE username = ?').get(username);
83+
}
84+
85+
function getAllUsers() {
86+
return getDb().prepare("SELECT id, username, role, max_servers, max_ram, created_at FROM users WHERE role != 'admin'").all();
87+
}
88+
89+
function createUser(username, password, maxServers, maxRam) {
90+
const hash = bcrypt.hashSync(password, 10);
91+
try {
92+
getDb().prepare('INSERT INTO users (username, password, role, max_servers, max_ram) VALUES (?, ?, ?, ?, ?)')
93+
.run(username, hash, 'user', maxServers, maxRam);
94+
return { success: true };
95+
} catch (e) {
96+
return { success: false, message: 'Username already exists' };
97+
}
98+
}
99+
100+
function deleteUser(username) {
101+
getDb().prepare("DELETE FROM users WHERE username = ? AND role != 'admin'").run(username);
102+
}
103+
104+
function updateAdminCredentials(newUsername, newPassword) {
105+
const db = getDb();
106+
if (newPassword) {
107+
const hash = bcrypt.hashSync(newPassword, 10);
108+
db.prepare("UPDATE users SET password = ? WHERE role = 'admin'").run(hash);
109+
}
110+
if (newUsername) {
111+
db.prepare("UPDATE users SET username = ? WHERE role = 'admin'").run(newUsername);
112+
}
113+
}
114+
115+
function verifyPassword(username, password) {
116+
const user = getUserByUsername(username);
117+
if (!user) return false;
118+
return bcrypt.compareSync(password, user.password);
119+
}
120+
121+
// ── Servers (metadata) ─────────────────────────────────────
122+
function getServerMeta(id) {
123+
const row = getDb().prepare('SELECT * FROM servers WHERE id = ?').get(id);
124+
if (!row) return { entryPoint: 'index.js', name: id, ramLimit: 512, cpuLimit: 100 };
125+
return {
126+
name: row.name,
127+
entryPoint: row.entry_point,
128+
ramLimit: row.ram_limit,
129+
cpuLimit: row.cpu_limit,
130+
owner: row.owner,
131+
};
132+
}
133+
134+
function saveServerMeta(id, meta) {
135+
const db = getDb();
136+
const existing = db.prepare('SELECT id FROM servers WHERE id = ?').get(id);
137+
if (existing) {
138+
db.prepare('UPDATE servers SET name=?, entry_point=?, ram_limit=?, cpu_limit=?, owner=? WHERE id=?')
139+
.run(meta.name || id, meta.entryPoint || 'index.js', meta.ramLimit || 512, meta.cpuLimit || 100, meta.owner || null, id);
140+
} else {
141+
db.prepare('INSERT INTO servers (id, name, entry_point, ram_limit, cpu_limit, owner) VALUES (?,?,?,?,?,?)')
142+
.run(id, meta.name || id, meta.entryPoint || 'index.js', meta.ramLimit || 512, meta.cpuLimit || 100, meta.owner || null);
143+
}
144+
}
145+
146+
function deleteServerMeta(id) {
147+
getDb().prepare('DELETE FROM servers WHERE id = ?').run(id);
148+
}
149+
150+
function getAllServerMetas() {
151+
return getDb().prepare('SELECT * FROM servers').all().map(row => ({
152+
id: row.id,
153+
name: row.name,
154+
entryPoint: row.entry_point,
155+
ramLimit: row.ram_limit,
156+
cpuLimit: row.cpu_limit,
157+
owner: row.owner,
158+
createdAt: row.created_at,
159+
}));
160+
}
161+
162+
module.exports = {
163+
getDb,
164+
getSetting,
165+
setSetting,
166+
getAllSettings,
167+
getUserByUsername,
168+
getAllUsers,
169+
createUser,
170+
deleteUser,
171+
updateAdminCredentials,
172+
verifyPassword,
173+
getServerMeta,
174+
saveServerMeta,
175+
deleteServerMeta,
176+
getAllServerMetas,
177+
};

0 commit comments

Comments
 (0)