other
This commit is contained in:
158
backend/routes/auth.routes.js
Normal file
158
backend/routes/auth.routes.js
Normal file
@@ -0,0 +1,158 @@
|
||||
import express from "express";
|
||||
import bcrypt from "bcryptjs";
|
||||
import jwt from "jsonwebtoken";
|
||||
import Vendor from "../models/Vendor.model.js";
|
||||
import Store from "../models/Store.model.js";
|
||||
import Invitation from "../models/Invitation.model.js";
|
||||
import { protectVendor } from "../middleware/vendorAuthMiddleware.js";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
* Register a New Vendor (and create a corresponding Store)
|
||||
* @route POST /api/auth/register
|
||||
*/
|
||||
router.post("/register", async (req, res) => {
|
||||
const { username, password, invitationCode } = req.body;
|
||||
|
||||
try {
|
||||
if (!username || !password || !invitationCode) {
|
||||
return res.status(400).json({ error: "All fields are required." });
|
||||
}
|
||||
|
||||
// Verify invitation code
|
||||
const invitation = await Invitation.findOne({
|
||||
code: invitationCode,
|
||||
isUsed: false,
|
||||
});
|
||||
|
||||
console.log(`Invitation: ${invitation}`);
|
||||
|
||||
if (!invitation) {
|
||||
return res.status(400).json({ error: "Invalid or used invitation code." });
|
||||
}
|
||||
|
||||
// Check if vendor already exists
|
||||
const existingVendor = await Vendor.findOne({ username });
|
||||
if (existingVendor) {
|
||||
return res.status(400).json({ error: "Vendor already exists." });
|
||||
}
|
||||
|
||||
// Hash the password
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
|
||||
// Create the vendor
|
||||
const vendor = new Vendor({
|
||||
username,
|
||||
passwordHash: hashedPassword,
|
||||
});
|
||||
await vendor.save();
|
||||
|
||||
// Create a store for this vendor
|
||||
const store = new Store({
|
||||
vendorId: vendor._id,
|
||||
storeName: `${username}'s Store`,
|
||||
welcomeMessage: "Welcome to my store!",
|
||||
categories: [],
|
||||
});
|
||||
await store.save();
|
||||
|
||||
// Attach `storeId` to vendor
|
||||
vendor.storeId = store._id;
|
||||
await vendor.save();
|
||||
|
||||
// Mark invitation as used
|
||||
invitation.isUsed = true;
|
||||
invitation.usedBy = vendor._id;
|
||||
invitation.usedAt = new Date();
|
||||
await invitation.save();
|
||||
|
||||
return res
|
||||
.status(201)
|
||||
.json({ message: "Vendor registered successfully", store });
|
||||
} catch (error) {
|
||||
console.error("Error registering vendor:", error);
|
||||
return res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Vendor Login
|
||||
* @route POST /api/auth/login
|
||||
*/
|
||||
router.post("/login", async (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
|
||||
try {
|
||||
if (!username || !password) {
|
||||
return res.status(400).json({ error: "Username and password are required." });
|
||||
}
|
||||
|
||||
const vendor = await Vendor.findOne({ username });
|
||||
if (!vendor) {
|
||||
return res.status(401).json({ error: "Invalid credentials." });
|
||||
}
|
||||
|
||||
const isMatch = await bcrypt.compare(password, vendor.passwordHash);
|
||||
if (!isMatch) {
|
||||
return res.status(401).json({ error: "Invalid credentials." });
|
||||
}
|
||||
|
||||
// Generate a JWT
|
||||
const token = jwt.sign(
|
||||
{ id: vendor._id, role: "vendor" },
|
||||
process.env.JWT_SECRET,
|
||||
{ expiresIn: "7d" }
|
||||
);
|
||||
|
||||
// Store the token in the DB to identify the current session
|
||||
vendor.currentToken = token;
|
||||
await vendor.save();
|
||||
|
||||
return res.json({ token, role: "vendor" });
|
||||
} catch (error) {
|
||||
console.error("Error logging in vendor:", error);
|
||||
return res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Vendor Logout
|
||||
* @route POST /api/auth/logout
|
||||
* @access Private (Vendors only)
|
||||
*/
|
||||
router.post("/logout", protectVendor, async (req, res) => {
|
||||
try {
|
||||
await Vendor.findByIdAndUpdate(req.user._id, { currentToken: null });
|
||||
return res.json({ message: "Successfully logged out." });
|
||||
} catch (error) {
|
||||
console.error("Error logging out vendor:", error);
|
||||
return res.status(500).json({ error: "Failed to log out." });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get Vendor Info
|
||||
* @route GET /api/auth/me
|
||||
* @access Private (Vendors only)
|
||||
*/
|
||||
router.get("/me", protectVendor, async (req, res) => {
|
||||
try {
|
||||
const vendor = await Vendor.findById(req.user._id).select("-passwordHash -currentToken");
|
||||
|
||||
if (!vendor) {
|
||||
return res.status(404).json({ error: "Vendor not found." });
|
||||
}
|
||||
|
||||
vendor.lastOnline = new Date();
|
||||
await vendor.save();
|
||||
|
||||
const store = await Store.findOne({ vendorId: vendor._id });
|
||||
return res.json({ vendor, store });
|
||||
} catch (error) {
|
||||
console.error("Error fetching vendor info:", error);
|
||||
return res.status(500).json({ error: "Failed to fetch vendor data." });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user