class Router {
constructor() {
this.routes = {
GET: {},
POST: {},
PUT: {},
DELETE: {}
};
this.middlewares = [];
}
// Register a route
register(method, path, handler, middlewares = []) {
// Convert path parameters to regex pattern
const paramNames = [];
let pattern = path.replace(/:([^/]+)/g, (match, paramName) => {
paramNames.push(paramName);
return '([^/]+)';
});
pattern = '^' + pattern + '$';
this.routes[method][path] = {
pattern: new RegExp(pattern),
paramNames,
handler,
middlewares
};
}
// Shorthand methods
get(path, handler, middlewares) {
this.register('GET', path, handler, middlewares);
}
post(path, handler, middlewares) {
this.register('POST', path, handler, middlewares);
}
put(path, handler, middlewares) {
this.register('PUT', path, handler, middlewares);
}
delete(path, handler, middlewares) {
this.register('DELETE', path, handler, middlewares);
}
// Add global middleware
use(middleware) {
this.middlewares.push(middleware);
}
// Match request to route
match(method, url) {
const routes = this.routes[method];
if (!routes) return null;
for (const path in routes) {
const route = routes[path];
const match = url.match(route.pattern);
if (match) {
const params = {};
route.paramNames.forEach((name, index) => {
params[name] = match[index + 1];
});
return { route, params };
}
}
return null;
}
// Handle incoming request
async handle(req, res) {
const { method, url } = req;
const parsedUrl = new URL(url, `http://${req.headers.host}`);
const pathname = parsedUrl.pathname;
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (method === 'OPTIONS') {
res.writeHead(200);
res.end();
return;
}
// Parse query parameters
req.query = Object.fromEntries(parsedUrl.searchParams);
// Set JSON response helper
res.json = (data, statusCode = 200) => {
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(data));
};
// Set error response helper
res.error = (message, statusCode = 400) => {
res.json({ success: false, error: message }, statusCode);
};
// Find matching route
const matched = this.match(method, pathname);
if (!matched) {
res.error('Route not found', 404);
return;
}
const { route, params } = matched;
req.params = params;
// Parse body for POST/PUT requests
if (method === 'POST' || method === 'PUT') {
await this.parseBody(req);
}
try {
// Execute route handler
await route.handler(req, res);
} catch (error) {
console.error('Route handler error:', error);
res.error('Internal server error', 500);
}
}
// Parse request body
parseBody(req) {
return new Promise((resolve, reject) => {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
try {
const contentType = req.headers['content-type'] || '';
if (contentType.includes('application/json')) {
req.body = JSON.parse(body || '{}');
} else {
req.body = body;
}
resolve();
} catch (e) {
req.body = {};
resolve();
}
});
req.on('error', reject);
});
}
}
module.exports = Router;
const bcrypt = require('bcryptjs');
const { getDb } = require('../config/database');
const { generateToken } = require('../middleware/auth');
class AuthController {
// Register new user
async register(req, res) {
const { username, email, password, first_name, last_name } = req.body;
if (!username || !email || !password) {
return res.error('Username, email and password are required');
}
if (password.length < 6) {
return res.error('Password must be at least 6 characters');
}
const db = getDb();
try {
// Check if user exists
const existingUser = await new Promise((resolve, reject) => {
db.get('SELECT id FROM users WHERE username = ? OR email = ?', [username, email], (err, row) => {
if (err) reject(err);
else resolve(row);
});
});
if (existingUser) {
return res.error('Username or email already exists');
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 10);
// Create user
const result = await new Promise((resolve, reject) => {
db.run(
'INSERT INTO users (username, email, password, first_name, last_name) VALUES (?, ?, ?, ?, ?)',
[username, email, hashedPassword, first_name || '', last_name || ''],
function(err) {
if (err) reject(err);
else resolve({ id: this.lastID });
}
);
});
const token = generateToken(result.id);
res.json({
success: true,
data: {
token,
user: {
id: result.id,
username,
email,
first_name: first_name || '',
last_name: last_name || ''
}
}
});
} catch (error) {
console.error('Register error:', error);
res.error('Registration failed', 500);
} finally {
db.close();
}
}
// Login user
async login(req, res) {
const { username, password } = req.body;
if (!username || !password) {
return res.error('Username and password are required');
}
const db = getDb();
try {
const user = await new Promise((resolve, reject) => {
db.get('SELECT * FROM users WHERE username = ? OR email = ?', [username, username], (err, row) => {
if (err) reject(err);
else resolve(row);
});
});
if (!user) {
return res.error('Invalid username or password', 401);
}
const validPassword = await bcrypt.compare(password, user.password);
if (!validPassword) {
return res.error('Invalid username or password', 401);
}
// Update online status
await new Promise((resolve, reject) => {
db.run('UPDATE users SET online = 1, last_seen = CURRENT_TIMESTAMP WHERE id = ?', [user.id], (err) => {
if (err) reject(err);
else resolve();
});
});
const token = generateToken(user.id);
res.json({
success: true,
data: {
token,
user: {
id: user.id,
username: user.username,
email: user.email,
first_name: user.first_name,
last_name: user.last_name,
avatar: user.avatar,
status: user.status,
online: 1
}
}
});
} catch (error) {
console.error('Login error:', error);
res.error('Login failed', 500);
} finally {
db.close();
}
}
// Get current user
async me(req, res) {
const db = getDb();
try {
const user = await new Promise((resolve, reject) => {
db.get(
'SELECT id, username, email, first_name, last_name, avatar, status, city, birthdate, about, online, last_seen, created_at FROM users WHERE id = ?',
[req.userId],
(err, row) => {
if (err) reject(err);
else resolve(row);
}
);
});
if (!user) {
return res.error('User not found', 404);
}
res.json({
success: true,
data: { user }
});
} catch (error) {
console.error('Me error:', error);
res.error('Failed to get user', 500);
} finally {
db.close();
}
}
// Logout user
async logout(req, res) {
const db = getDb();
try {
await new Promise((resolve, reject) => {
db.run('UPDATE users SET online = 0, last_seen = CURRENT_TIMESTAMP WHERE id = ?', [req.userId], (err) => {
if (err) reject(err);
else resolve();
});
});
res.json({ success: true, data: { message: 'Logged out successfully' } });
} catch (error) {
console.error('Logout error:', error);
res.error('Logout failed', 500);
} finally {
db.close();
}
}
}
module.exports = new AuthController();
Warning: Cannot modify header information - headers already sent by (output started at /var/www/www-root/data/www/chatabbkk.ru/backend/controllers/AuthController.js:1) in /var/www/www-root/data/www/chatabbkk.ru/public/index.php on line 10
Warning: Cannot modify header information - headers already sent by (output started at /var/www/www-root/data/www/chatabbkk.ru/backend/controllers/AuthController.js:1) in /var/www/www-root/data/www/chatabbkk.ru/public/index.php on line 11
Warning: Cannot modify header information - headers already sent by (output started at /var/www/www-root/data/www/chatabbkk.ru/backend/controllers/AuthController.js:1) in /var/www/www-root/data/www/chatabbkk.ru/public/index.php on line 12
Warning: Cannot modify header information - headers already sent by (output started at /var/www/www-root/data/www/chatabbkk.ru/backend/controllers/AuthController.js:1) in /var/www/www-root/data/www/chatabbkk.ru/public/index.php on line 13
Fatal error: Uncaught Error: Class "Router" not found in /var/www/www-root/data/www/chatabbkk.ru/public/index.php:26
Stack trace:
#0 {main}
thrown in /var/www/www-root/data/www/chatabbkk.ru/public/index.php on line 26