Files
janichat/backend/src/routes/auth.ts

77 lines
2.9 KiB
TypeScript

import { FastifyInstance } from 'fastify';
import bcrypt from 'bcryptjs';
import { pool } from '../db.js';
export default async function authRoutes(app: FastifyInstance) {
app.post('/login', async (req, reply) => {
const { username, password } = req.body as { username: string; password: string };
const { rows: [user] } = await pool.query(
'SELECT * FROM users WHERE username = $1 AND is_active = TRUE', [username]
);
if (!user) return reply.status(401).send({ error: 'Неверный логин или пароль' });
const ok = await bcrypt.compare(password, user.password_hash);
if (!ok) return reply.status(401).send({ error: 'Неверный логин или пароль' });
await pool.query('UPDATE users SET last_seen = NOW() WHERE id = $1', [user.id]);
const token = app.jwt.sign({ id: user.id, isAdmin: user.is_admin }, { expiresIn: '30d' });
return {
token,
user: {
id: user.id,
username: user.username,
displayName: user.display_name,
avatarColor: user.avatar_color,
bio: user.bio,
isAdmin: user.is_admin,
}
};
});
app.get('/me', { preHandler: [app.authenticate] }, async (req) => {
const { id } = req.user as { id: string };
const { rows: [user] } = await pool.query(
'SELECT id, username, display_name, avatar_color, bio, phone, is_admin, last_seen FROM users WHERE id = $1', [id]
);
return {
id: user.id,
username: user.username,
displayName: user.display_name,
avatarColor: user.avatar_color,
bio: user.bio,
phone: user.phone,
isAdmin: user.is_admin,
lastSeen: user.last_seen,
};
});
app.put('/me', { preHandler: [app.authenticate] }, async (req, reply) => {
const { id } = req.user as { id: string };
const { displayName, bio, phone, password, newPassword } = req.body as any;
if (newPassword) {
const { rows: [user] } = await pool.query('SELECT password_hash FROM users WHERE id = $1', [id]);
const ok = await bcrypt.compare(password, user.password_hash);
if (!ok) return reply.status(400).send({ error: 'Неверный текущий пароль' });
const hash = await bcrypt.hash(newPassword, 10);
await pool.query('UPDATE users SET password_hash = $1 WHERE id = $2', [hash, id]);
}
await pool.query(
'UPDATE users SET display_name = COALESCE($1, display_name), bio = COALESCE($2, bio), phone = COALESCE($3, phone) WHERE id = $4',
[displayName, bio, phone, id]
);
const { rows: [user] } = await pool.query(
'SELECT id, username, display_name, avatar_color, bio, phone, is_admin FROM users WHERE id = $1', [id]
);
return {
id: user.id, username: user.username, displayName: user.display_name,
avatarColor: user.avatar_color, bio: user.bio, phone: user.phone, isAdmin: user.is_admin,
};
});
}