Files
api_builder/backend/src/controllers/authController.ts
eshmeshek 8632e651bf Add Gitea integration + ESLint setup
Phase 3: Gitea Integration
- Migration 012: app_settings table + gitea_commit_sha on endpoint_versions
- SettingsService: encrypted token storage (AES-256-GCM from JWT_SECRET)
- GiteaService: full REST API client — repo management, file CRUD,
  branches, commit history, diff/compare, pull requests, sync all
- giteaController + routes: 15 API endpoints for settings, branches,
  commits, PRs, endpoint info, sync
- VersionService hooks: auto-sync to Gitea on publish/draft (non-blocking)
- Frontend: Gitea tab in Settings (connection, sync status, branch mgmt),
  Gitea panel in EndpointEditor (file link, last commit SHA)
- docker-compose.gitea.yml: optional companion Gitea container
- Cache fix: index.html served with no-cache for instant deploys

ESLint Setup
- Backend: eslint 8 + @typescript-eslint configured
- Frontend: eslint 8 + @typescript-eslint + react-hooks + react-refresh
- Fixed 15 lint issues: unused imports, require statements, escapes,
  Function type, empty catch blocks
- Added npm run lint / lint:fix scripts

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 22:45:45 +03:00

73 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Request, Response } from 'express';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import { mainPool } from '../config/database';
import { config } from '../config/environment';
export const login = async (req: Request, res: Response) => {
try {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).json({ error: 'Не заполнены обязательные поля' });
}
// Find user
const result = await mainPool.query(
'SELECT id, username, password_hash, role, is_superadmin FROM users WHERE username = $1',
[username]
);
if (result.rows.length === 0) {
return res.status(401).json({ error: 'Неверные учетные данные' });
}
const user = result.rows[0];
// Verify password
const isValidPassword = await bcrypt.compare(password, user.password_hash);
if (!isValidPassword) {
return res.status(401).json({ error: 'Неверные учетные данные' });
}
// Generate token
const token = jwt.sign(
{ userId: user.id },
config.jwt.secret,
{ expiresIn: config.jwt.expiresIn as any }
);
res.json({
user: {
id: user.id,
username: user.username,
role: user.role,
is_superadmin: user.is_superadmin,
},
token,
});
} catch (error) {
console.error('Login error:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
};
export const getMe = async (req: any, res: Response) => {
try {
const result = await mainPool.query(
'SELECT id, username, role, is_superadmin, created_at FROM users WHERE id = $1',
[req.user.id]
);
if (result.rows.length === 0) {
return res.status(404).json({ error: 'Пользователь не найден' });
}
res.json(result.rows[0]);
} catch (error) {
console.error('Get me error:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
};