diff --git a/backend/middleware/validation.js b/backend/middleware/validation.js index ebf3ab9..6e5530c 100644 --- a/backend/middleware/validation.js +++ b/backend/middleware/validation.js @@ -110,16 +110,6 @@ const validateRegistration = [ "Last name can only contain letters, spaces, hyphens, and apostrophes" ), - body("username") - .optional() - .trim() - .isLength({ min: 3, max: 30 }) - .withMessage("Username must be between 3 and 30 characters") - .matches(/^[a-zA-Z0-9_-]+$/) - .withMessage( - "Username can only contain letters, numbers, underscores, and hyphens" - ), - body("phone") .optional() .isMobilePhone() diff --git a/backend/models/User.js b/backend/models/User.js index 01c4113..ab86ddf 100644 --- a/backend/models/User.js +++ b/backend/models/User.js @@ -10,15 +10,10 @@ const User = sequelize.define( defaultValue: DataTypes.UUIDV4, primaryKey: true, }, - username: { - type: DataTypes.STRING, - unique: true, - allowNull: true, - }, email: { type: DataTypes.STRING, unique: true, - allowNull: true, + allowNull: false, validate: { isEmail: true, }, diff --git a/backend/routes/auth.js b/backend/routes/auth.js index 90c016b..a66edf6 100644 --- a/backend/routes/auth.js +++ b/backend/routes/auth.js @@ -43,13 +43,11 @@ router.post( validateRegistration, async (req, res) => { try { - const { username, email, password, firstName, lastName, phone } = + const { email, password, firstName, lastName, phone } = req.body; const existingUser = await User.findOne({ - where: { - [require("sequelize").Op.or]: [{ email }, { username }], - }, + where: { email }, }); if (existingUser) { @@ -96,7 +94,6 @@ router.post( } const user = await User.create({ - username, email, password, firstName, @@ -161,14 +158,12 @@ router.post( const reqLogger = logger.withRequestId(req.id); reqLogger.info("User registration successful", { userId: user.id, - username: user.username, email: user.email, }); res.status(201).json({ user: { id: user.id, - username: user.username, email: user.email, firstName: user.firstName, lastName: user.lastName, @@ -184,7 +179,6 @@ router.post( error: error.message, stack: error.stack, email: req.body.email, - username: req.body.username, }); res.status(500).json({ error: "Registration failed. Please try again." }); } @@ -265,7 +259,6 @@ router.post( res.json({ user: { id: user.id, - username: user.username, email: user.email, firstName: user.firstName, lastName: user.lastName, @@ -326,9 +319,9 @@ router.post( } = payload; if (!email) { - return res - .status(400) - .json({ error: "Email not provided by Google" }); + return res.status(400).json({ + error: "Email permission is required to continue. Please grant email access when signing in with Google and try again." + }); } // Handle cases where Google doesn't provide name fields @@ -375,7 +368,6 @@ router.post( authProvider: "google", providerId: googleId, profileImage: picture, - username: email.split("@")[0] + "_" + googleId.slice(-6), // Generate unique username isVerified: true, verifiedAt: new Date(), }); @@ -439,7 +431,6 @@ router.post( res.json({ user: { id: user.id, - username: user.username, email: user.email, firstName: user.firstName, lastName: user.lastName, @@ -677,7 +668,6 @@ router.post("/refresh", async (req, res) => { res.json({ user: { id: user.id, - username: user.username, email: user.email, firstName: user.firstName, lastName: user.lastName, diff --git a/backend/routes/forum.js b/backend/routes/forum.js index f77f198..bae134d 100644 --- a/backend/routes/forum.js +++ b/backend/routes/forum.js @@ -95,7 +95,7 @@ router.get('/posts', optionalAuth, async (req, res) => { { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName'] + attributes: ['id', 'firstName', 'lastName'] }, { model: PostTag, @@ -170,12 +170,12 @@ router.get('/posts/:id', optionalAuth, async (req, res) => { { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName', 'role'] + attributes: ['id', 'firstName', 'lastName', 'role'] }, { model: User, as: 'closer', - attributes: ['id', 'username', 'firstName', 'lastName', 'role'], + attributes: ['id', 'firstName', 'lastName', 'role'], required: false }, { @@ -191,7 +191,7 @@ router.get('/posts/:id', optionalAuth, async (req, res) => { { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName', 'role'] + attributes: ['id', 'firstName', 'lastName', 'role'] } ] } @@ -335,7 +335,7 @@ router.post('/posts', authenticateToken, uploadForumPostImages, async (req, res) { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName'] + attributes: ['id', 'firstName', 'lastName'] }, { model: PostTag, @@ -524,7 +524,7 @@ router.put('/posts/:id', authenticateToken, async (req, res) => { { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName'] + attributes: ['id', 'firstName', 'lastName'] }, { model: PostTag, @@ -622,7 +622,7 @@ router.patch('/posts/:id/status', authenticateToken, async (req, res) => { (async () => { try { const closerUser = await User.findByPk(req.user.id, { - attributes: ['id', 'username', 'firstName', 'lastName', 'email'] + attributes: ['id', 'firstName', 'lastName', 'email'] }); const postWithAuthor = await ForumPost.findByPk(post.id, { @@ -630,7 +630,7 @@ router.patch('/posts/:id/status', authenticateToken, async (req, res) => { { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName', 'email'] + attributes: ['id', 'firstName', 'lastName', 'email'] } ] }); @@ -702,12 +702,12 @@ router.patch('/posts/:id/status', authenticateToken, async (req, res) => { { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName'] + attributes: ['id', 'firstName', 'lastName'] }, { model: User, as: 'closer', - attributes: ['id', 'username', 'firstName', 'lastName'], + attributes: ['id', 'firstName', 'lastName'], required: false }, { @@ -790,13 +790,13 @@ router.patch('/posts/:id/accept-answer', authenticateToken, async (req, res) => { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName', 'email'] + attributes: ['id', 'firstName', 'lastName', 'email'] } ] }); const postAuthor = await User.findByPk(req.user.id, { - attributes: ['id', 'username', 'firstName', 'lastName', 'email'] + attributes: ['id', 'firstName', 'lastName', 'email'] }); const postWithAuthor = await ForumPost.findByPk(post.id, { @@ -804,7 +804,7 @@ router.patch('/posts/:id/accept-answer', authenticateToken, async (req, res) => { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName', 'email'] + attributes: ['id', 'firstName', 'lastName', 'email'] } ] }); @@ -882,7 +882,7 @@ router.patch('/posts/:id/accept-answer', authenticateToken, async (req, res) => { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName'] + attributes: ['id', 'firstName', 'lastName'] }, { model: PostTag, @@ -972,7 +972,7 @@ router.post('/posts/:id/comments', authenticateToken, uploadForumCommentImages, { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName', 'email'] + attributes: ['id', 'firstName', 'lastName', 'email'] } ] }); @@ -984,7 +984,7 @@ router.post('/posts/:id/comments', authenticateToken, uploadForumCommentImages, { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName', 'email'] + attributes: ['id', 'firstName', 'lastName', 'email'] } ] }); @@ -1027,7 +1027,7 @@ router.post('/posts/:id/comments', authenticateToken, uploadForumCommentImages, { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName', 'email'] + attributes: ['id', 'firstName', 'lastName', 'email'] } ], group: ['ForumComment.authorId', 'author.id'] @@ -1102,7 +1102,7 @@ router.put('/comments/:id', authenticateToken, async (req, res) => { { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName'] + attributes: ['id', 'firstName', 'lastName'] } ] }); @@ -1177,7 +1177,7 @@ router.get('/my-posts', authenticateToken, async (req, res) => { { model: User, as: 'author', - attributes: ['id', 'username', 'firstName', 'lastName'] + attributes: ['id', 'firstName', 'lastName'] }, { model: PostTag, @@ -1294,7 +1294,7 @@ router.delete('/admin/posts/:id', authenticateToken, requireAdmin, async (req, r (async () => { try { const admin = await User.findByPk(req.user.id, { - attributes: ['id', 'username', 'firstName', 'lastName'] + attributes: ['id', 'firstName', 'lastName'] }); if (post.author && admin) { @@ -1422,7 +1422,7 @@ router.delete('/admin/comments/:id', authenticateToken, requireAdmin, async (req (async () => { try { const admin = await User.findByPk(req.user.id, { - attributes: ['id', 'username', 'firstName', 'lastName'] + attributes: ['id', 'firstName', 'lastName'] }); if (comment.author && admin && post) { diff --git a/backend/routes/items.js b/backend/routes/items.js index 32f2a98..8157d0b 100644 --- a/backend/routes/items.js +++ b/backend/routes/items.js @@ -43,7 +43,7 @@ router.get("/", async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], limit: parseInt(limit), @@ -180,12 +180,12 @@ router.get("/:id", optionalAuth, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "deleter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], }); @@ -242,7 +242,7 @@ router.post("/", authenticateToken, requireVerifiedEmail, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName", "email", "stripeConnectedAccountId"], + attributes: ["id", "firstName", "lastName", "email", "stripeConnectedAccountId"], }, ], }); @@ -307,7 +307,7 @@ router.put("/:id", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], }); @@ -378,7 +378,7 @@ router.delete("/admin/:id", authenticateToken, requireAdmin, async (req, res) => { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName", "email"], + attributes: ["id", "firstName", "lastName", "email"], }, ], }); @@ -422,12 +422,12 @@ router.delete("/admin/:id", authenticateToken, requireAdmin, async (req, res) => { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "deleter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], } ], }); @@ -492,7 +492,7 @@ router.patch("/admin/:id/restore", authenticateToken, requireAdmin, async (req, { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], } ], }); diff --git a/backend/routes/rentals.js b/backend/routes/rentals.js index fa96e4b..e9988bb 100644 --- a/backend/routes/rentals.js +++ b/backend/routes/rentals.js @@ -64,7 +64,7 @@ router.get("/renting", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], order: [["createdAt", "DESC"]], @@ -92,7 +92,7 @@ router.get("/owning", authenticateToken, async (req, res) => { { model: User, as: "renter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], order: [["createdAt", "DESC"]], @@ -141,12 +141,12 @@ router.get("/:id", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "renter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], }); @@ -290,12 +290,12 @@ router.post("/", authenticateToken, requireVerifiedEmail, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "renter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], }); @@ -351,14 +351,13 @@ router.put("/:id/status", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "renter", attributes: [ "id", - "username", "firstName", "lastName", "stripeCustomerId", @@ -431,12 +430,12 @@ router.put("/:id/status", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "renter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], }); @@ -523,12 +522,12 @@ router.put("/:id/status", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "renter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], }); @@ -600,12 +599,12 @@ router.put("/:id/status", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "renter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], }); @@ -634,12 +633,12 @@ router.put("/:id/decline", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "renter", - attributes: ["id", "username", "firstName", "lastName", "email"], + attributes: ["id", "firstName", "lastName", "email"], }, ], }); @@ -674,12 +673,12 @@ router.put("/:id/decline", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "renter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], }); @@ -832,12 +831,12 @@ router.post("/:id/mark-completed", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "renter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], }); @@ -1048,12 +1047,12 @@ router.post("/:id/cancel", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "renter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], }); @@ -1143,12 +1142,12 @@ router.post("/:id/mark-return", authenticateToken, async (req, res) => { { model: User, as: "owner", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, { model: User, as: "renter", - attributes: ["id", "username", "firstName", "lastName"], + attributes: ["id", "firstName", "lastName"], }, ], });