76 lines
3.2 KiB
JavaScript
76 lines
3.2 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const express_1 = require("express");
|
|
const asyncHandler_1 = require("../utils/asyncHandler");
|
|
const db_1 = require("../db");
|
|
const schema_1 = require("../db/schema");
|
|
const drizzle_orm_1 = require("drizzle-orm");
|
|
const auth_1 = require("../utils/auth");
|
|
const errorHandler_1 = require("../middleware/errorHandler");
|
|
const zod_1 = require("zod");
|
|
const router = (0, express_1.Router)();
|
|
const usernameSchema = zod_1.z
|
|
.string()
|
|
.min(3)
|
|
.max(30)
|
|
.regex(/^[a-zA-Z0-9_.-]+$/, 'Username can only contain letters, numbers, dots, dashes and underscores');
|
|
const registerSchema = zod_1.z.object({
|
|
username: usernameSchema,
|
|
password: zod_1.z.string().min(8),
|
|
});
|
|
const loginSchema = zod_1.z.object({
|
|
username: zod_1.z.string(),
|
|
password: zod_1.z.string(),
|
|
});
|
|
// In production, use bcrypt or argon2 for password hashing
|
|
function hashPassword(password) {
|
|
// Simple hash for demo - replace with bcrypt in production
|
|
return Buffer.from(password).toString('base64');
|
|
}
|
|
function verifyPassword(password, hash) {
|
|
return hashPassword(password) === hash;
|
|
}
|
|
router.post('/register', (0, asyncHandler_1.asyncHandler)(async (req, res) => {
|
|
const data = registerSchema.parse(req.body);
|
|
const existing = await db_1.db.select().from(schema_1.users).where((0, drizzle_orm_1.eq)(schema_1.users.username, data.username)).limit(1);
|
|
if (existing.length > 0) {
|
|
throw new errorHandler_1.AppError('USERNAME_EXISTS', 'Username already registered', 409);
|
|
}
|
|
const userId = (0, auth_1.generateId)('user');
|
|
const now = (0, auth_1.getCurrentTimestamp)();
|
|
await db_1.db.insert(schema_1.users).values({
|
|
id: userId,
|
|
username: data.username,
|
|
passwordHash: hashPassword(data.password),
|
|
createdAt: now,
|
|
});
|
|
const token = (0, auth_1.generateToken)({ userId, username: data.username });
|
|
res.status(201).json({
|
|
user: { id: userId, username: data.username },
|
|
token,
|
|
});
|
|
}));
|
|
router.post('/login', (0, asyncHandler_1.asyncHandler)(async (req, res) => {
|
|
const data = loginSchema.parse(req.body);
|
|
const user = await db_1.db.select().from(schema_1.users).where((0, drizzle_orm_1.eq)(schema_1.users.username, data.username)).limit(1);
|
|
if (user.length === 0 || !verifyPassword(data.password, user[0].passwordHash)) {
|
|
throw new errorHandler_1.AppError('INVALID_CREDENTIALS', 'Invalid username or password', 401);
|
|
}
|
|
const token = (0, auth_1.generateToken)({ userId: user[0].id, username: user[0].username });
|
|
res.json({
|
|
user: { id: user[0].id, username: user[0].username },
|
|
token,
|
|
});
|
|
}));
|
|
router.get('/me', (0, asyncHandler_1.asyncHandler)(async (req, res) => {
|
|
if (!req.user) {
|
|
throw new errorHandler_1.AppError('UNAUTHORIZED', 'Authentication required', 401);
|
|
}
|
|
const user = await db_1.db.select().from(schema_1.users).where((0, drizzle_orm_1.eq)(schema_1.users.id, req.user.userId)).limit(1);
|
|
if (user.length === 0) {
|
|
throw new errorHandler_1.AppError('NOT_FOUND', 'User not found', 404);
|
|
}
|
|
res.json({ id: user[0].id, username: user[0].username });
|
|
}));
|
|
exports.default = router;
|
|
//# sourceMappingURL=auth.js.map
|