Initial commit — Умный Байт landing

This commit is contained in:
2026-05-13 09:32:45 +03:00
commit 9e21350def
37 changed files with 1950 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt';
import type { Request, Response, NextFunction } from 'express';
const JWT_SECRET = process.env.JWT_SECRET || 'change-me-please';
const COOKIE_NAME = 'umbyte_session';
const TOKEN_TTL_SEC = 60 * 60 * 24 * 7;
export interface AdminPayload {
id: number;
login: string;
}
declare global {
namespace Express {
interface Request {
admin?: AdminPayload;
}
}
}
export function signToken(payload: AdminPayload): string {
return jwt.sign(payload, JWT_SECRET, { expiresIn: TOKEN_TTL_SEC });
}
export function setAuthCookie(res: Response, token: string): void {
res.cookie(COOKIE_NAME, token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: TOKEN_TTL_SEC * 1000,
path: '/',
});
}
export function clearAuthCookie(res: Response): void {
res.clearCookie(COOKIE_NAME, { path: '/' });
}
export function requireAdmin(
req: Request,
res: Response,
next: NextFunction
): void {
const token = req.cookies?.[COOKIE_NAME];
if (!token) {
res.status(401).json({ error: 'unauthorized' });
return;
}
try {
const payload = jwt.verify(token, JWT_SECRET) as AdminPayload;
req.admin = payload;
next();
} catch {
res.status(401).json({ error: 'unauthorized' });
}
}
export async function hashPassword(plain: string): Promise<string> {
return bcrypt.hash(plain, 12);
}
export async function verifyPassword(
plain: string,
hash: string
): Promise<boolean> {
return bcrypt.compare(plain, hash);
}