Spaces:
Runtime error
Runtime error
| import express from "express"; | |
| import bcrypt from "bcrypt"; | |
| import jwt from "jsonwebtoken"; | |
| import { AppDataSource } from "../utils/dataSource"; | |
| import { User } from "../entity/User"; | |
| import { readyPlayerMeClient } from "../utils/readyPlayerMe"; | |
| import dotenv from "dotenv"; | |
| dotenv.config(); | |
| const router = express.Router(); | |
| /** | |
| * @openapi | |
| * /api/auth/register: | |
| * post: | |
| * summary: Register a new user | |
| * tags: [Authentication] | |
| * requestBody: | |
| * required: true | |
| * content: | |
| * application/json: | |
| * schema: | |
| * $ref: "#/components/schemas/RegisterRequest" | |
| * responses: | |
| * 201: | |
| * description: User registered successfully | |
| * content: | |
| * application/json: | |
| * schema: | |
| * $ref: "#/components/schemas/AuthResponse" | |
| * 400: | |
| * description: Bad request (missing fields, email exists, or weak password) | |
| * 500: | |
| * description: Server error | |
| */ | |
| router.post("/register", async (req, res) => { | |
| try { | |
| const { name, email, password } = req.body; | |
| if (!name || !email || !password) { | |
| return res.status(400).json({ | |
| success: false, | |
| error: "Name, email, and password are required", | |
| }); | |
| } | |
| if (password.length < 6) { | |
| return res.status(400).json({ | |
| success: false, | |
| error: "Password must be at least 6 characters", | |
| }); | |
| } | |
| const userRepo = AppDataSource.getRepository(User); | |
| const existingUser = await userRepo.findOne({ where: { email } }); | |
| if (existingUser) { | |
| return res.status(400).json({ | |
| success: false, | |
| error: "Email already registered", | |
| }); | |
| } | |
| const hashedPassword = await bcrypt.hash(password, 10); | |
| const newUser = userRepo.create({ | |
| name, | |
| email, | |
| password: hashedPassword, | |
| }); | |
| await userRepo.save(newUser); | |
| const applicationId = process.env.READY_PLAYER_ME_APPLICATION_ID; | |
| if (applicationId) { | |
| try { | |
| const rpmUser = await readyPlayerMeClient.createGuestUser(applicationId); | |
| if (rpmUser) { | |
| newUser.readyPlayerMeUserId = rpmUser.id; | |
| await userRepo.save(newUser); | |
| console.log(`Created Ready Player Me guest user: ${rpmUser.id} for user ${newUser.id}`); | |
| } | |
| } catch (rpmError: any) { | |
| console.warn("Failed to create Ready Player Me guest user:", rpmError.message); | |
| } | |
| } | |
| const jwtSecret = process.env.JWT_SECRET || ""; | |
| const token = jwt.sign( | |
| { userId: newUser.id, email: newUser.email }, | |
| jwtSecret, | |
| { expiresIn: "7d" } | |
| ); | |
| res.status(201).json({ | |
| success: true, | |
| user: { | |
| id: newUser.id, | |
| name: newUser.name, | |
| email: newUser.email, | |
| }, | |
| token, | |
| }); | |
| } catch (error: any) { | |
| console.error("Registration error:", error); | |
| res.status(500).json({ | |
| success: false, | |
| error: error.message || "Registration failed", | |
| }); | |
| } | |
| }); | |
| /** | |
| * @openapi | |
| * /api/auth/login: | |
| * post: | |
| * summary: Login user | |
| * tags: [Authentication] | |
| * requestBody: | |
| * required: true | |
| * content: | |
| * application/json: | |
| * schema: | |
| * $ref: "#/components/schemas/LoginRequest" | |
| * responses: | |
| * 200: | |
| * description: Login successful | |
| * content: | |
| * application/json: | |
| * schema: | |
| * $ref: "#/components/schemas/AuthResponse" | |
| * 401: | |
| * description: Invalid credentials | |
| * 500: | |
| * description: Server error | |
| */ | |
| router.post("/login", async (req, res) => { | |
| try { | |
| const { email, password } = req.body; | |
| if (!email || !password) { | |
| return res.status(400).json({ | |
| success: false, | |
| error: "Email and password are required", | |
| }); | |
| } | |
| const userRepo = AppDataSource.getRepository(User); | |
| const user = await userRepo.findOne({ where: { email } }); | |
| if (!user) { | |
| return res.status(401).json({ | |
| success: false, | |
| error: "Invalid email or password", | |
| }); | |
| } | |
| const isPasswordValid = await bcrypt.compare(password, user.password); | |
| if (!isPasswordValid) { | |
| return res.status(401).json({ | |
| success: false, | |
| error: "Invalid email or password", | |
| }); | |
| } | |
| const jwtSecret = process.env.JWT_SECRET || ""; | |
| const token = jwt.sign( | |
| { userId: user.id, email: user.email }, | |
| jwtSecret, | |
| { expiresIn: "7d" } | |
| ); | |
| res.json({ | |
| success: true, | |
| user: { | |
| id: user.id, | |
| name: user.name, | |
| email: user.email, | |
| }, | |
| token, | |
| }); | |
| } catch (error: any) { | |
| console.error("Login error:", error); | |
| res.status(500).json({ | |
| success: false, | |
| error: error.message || "Login failed", | |
| }); | |
| } | |
| }); | |
| export default router; | |