158 lines
4.3 KiB
JavaScript
158 lines
4.3 KiB
JavaScript
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; |