feat: init proj
This commit is contained in:
100
server/src/index.ts
Normal file
100
server/src/index.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import express from 'express';
|
||||
import path from 'path';
|
||||
import './db.js'; // Initialize database
|
||||
import subscriptionsRouter from './routes/subscriptions.js';
|
||||
import nodesRouter from './routes/nodes.js';
|
||||
import rulesRouter from './routes/rules.js';
|
||||
import surgeRouter from './routes/surge.js';
|
||||
import db from './db.js';
|
||||
import { generateSurgeConfig } from './services/generator.js';
|
||||
|
||||
const app = express();
|
||||
const PORT = parseInt(process.env.PORT || '3456', 10);
|
||||
|
||||
app.use(express.json());
|
||||
|
||||
// Surge endpoint (no auth, before everything)
|
||||
app.get('/surge', (req, res) => {
|
||||
const host = req.headers.host || 'localhost:3456';
|
||||
const protocol = req.secure ? 'https' : 'http';
|
||||
const hostUrl = `${protocol}://${host}/surge`;
|
||||
const config = generateSurgeConfig(hostUrl);
|
||||
res.set({
|
||||
'Content-Type': 'text/plain; charset=utf-8',
|
||||
'Content-Disposition': 'attachment; filename=IPLC.MAX.conf',
|
||||
});
|
||||
res.send(config);
|
||||
});
|
||||
|
||||
// Auth routes (no auth required)
|
||||
app.post('/api/auth/login', (req, res) => {
|
||||
const { password } = req.body;
|
||||
const configRow = db.prepare("SELECT value FROM config WHERE key = 'password'").get() as any;
|
||||
|
||||
if (!configRow?.value) {
|
||||
db.prepare("INSERT OR REPLACE INTO config (key, value) VALUES ('password', ?)").run(password);
|
||||
return res.json({ ok: true });
|
||||
}
|
||||
|
||||
if (password === configRow.value) {
|
||||
return res.json({ ok: true });
|
||||
}
|
||||
|
||||
res.status(401).json({ error: 'wrong password' });
|
||||
});
|
||||
|
||||
app.get('/api/auth/status', (_req, res) => {
|
||||
const configRow = db.prepare("SELECT value FROM config WHERE key = 'password'").get() as any;
|
||||
res.json({ hasPassword: !!configRow?.value });
|
||||
});
|
||||
|
||||
// Auth middleware for other /api routes
|
||||
app.use('/api', (req, res, next) => {
|
||||
const configRow = db.prepare("SELECT value FROM config WHERE key = 'password'").get() as any;
|
||||
if (!configRow?.value) return next();
|
||||
|
||||
const authHeader = req.headers.authorization;
|
||||
if (!authHeader || authHeader !== `Bearer ${configRow.value}`) {
|
||||
return res.status(401).json({ error: 'unauthorized' });
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
// API routes
|
||||
app.use('/api/subscriptions', subscriptionsRouter);
|
||||
app.use('/api/nodes', nodesRouter);
|
||||
app.use('/api/rules', rulesRouter);
|
||||
app.use('/api/config', surgeRouter);
|
||||
|
||||
// Stats endpoint
|
||||
app.get('/api/stats', (_req, res) => {
|
||||
const subs = db.prepare('SELECT COUNT(*) as count FROM subscriptions WHERE enabled = 1').get() as any;
|
||||
const fetchedEnabled = db.prepare('SELECT COUNT(*) as count FROM fetched_nodes WHERE enabled = 1').get() as any;
|
||||
const fetchedTotal = db.prepare('SELECT COUNT(*) as count FROM fetched_nodes').get() as any;
|
||||
const staticEnabled = db.prepare('SELECT COUNT(*) as count FROM static_nodes WHERE enabled = 1').get() as any;
|
||||
const staticTotal = db.prepare('SELECT COUNT(*) as count FROM static_nodes').get() as any;
|
||||
const rulesCount = db.prepare('SELECT COUNT(*) as count FROM rules WHERE enabled = 1').get() as any;
|
||||
|
||||
res.json({
|
||||
subscriptions: subs.count,
|
||||
nodes: {
|
||||
fetched: { enabled: fetchedEnabled.count, total: fetchedTotal.count },
|
||||
static: { enabled: staticEnabled.count, total: staticTotal.count },
|
||||
},
|
||||
rules: rulesCount.count,
|
||||
});
|
||||
});
|
||||
|
||||
// Serve static frontend files
|
||||
const webDist = path.join(__dirname, '..', '..', 'web', 'dist');
|
||||
app.use(express.static(webDist));
|
||||
app.get('*', (req, res, next) => {
|
||||
if (req.path.startsWith('/api') || req.path === '/surge') return next();
|
||||
res.sendFile(path.join(webDist, 'index.html'));
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Sub Router running at http://127.0.0.1:${PORT}`);
|
||||
console.log(`Surge subscription: http://127.0.0.1:${PORT}/surge`);
|
||||
console.log(`Admin panel: http://127.0.0.1:${PORT}`);
|
||||
});
|
||||
Reference in New Issue
Block a user