Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
!.yarn/versions

# testing
/backend/coverage
/coverage
/playwright-report
/test-results

# next.js
/.next/
Expand Down
66 changes: 63 additions & 3 deletions backend/controllers/user.controller.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import User from "../models/User.js"
import { generateToken } from "../lib/utils.js"
import { generateToken, verifyRecaptcha } from "../lib/utils.js"
import bcrypt from "bcryptjs"
import cloudinary from "../lib/cloudinary.js"

export const signup = async (req, res) => {
const { email, password, name, avatarUrl, bio } = req.body // CHANGED: Standardize on avatarUrl instead of profilPic
const { email, password, name, avatarUrl, bio, captchaToken } = req.body // CHANGED: Standardize on avatarUrl instead of profilPic

try {
// Validate input
Expand All @@ -14,6 +14,15 @@ export const signup = async (req, res) => {
.json({ message: "Email, password, and name are required." })
}

if (!captchaToken) {
return res.status(400).json({ message: "CAPTCHA token is required." });
}

const isHuman = await verifyRecaptcha(captchaToken);
if (!isHuman) {
return res.status(403).json({ message: "CAPTCHA verification failed." });
}

// Check if user already exists
const existingUser = await User.findOne({ email })
if (existingUser) {
Expand Down Expand Up @@ -56,7 +65,7 @@ export const signup = async (req, res) => {
}

export const login = async (req, res) => {
const { email, password } = req.body
const { email, password, captchaToken } = req.body

try {
// Validate input
Expand All @@ -66,6 +75,15 @@ export const login = async (req, res) => {
.json({ message: "Email and password are required." })
}

if (!captchaToken) {
return res.status(400).json({ message: "CAPTCHA token is required." });
}

const isHuman = await verifyRecaptcha(captchaToken);
if (!isHuman) {
return res.status(403).json({ message: "CAPTCHA verification failed." });
}

// Find user by email
const user = await User.findOne({ email })
if (!user) {
Expand Down Expand Up @@ -157,3 +175,45 @@ export const updateProfile = async (req, res) => {
res.status(500).json({ message: "Internal server error." })
}
}

export const sendOTP = async (req, res) => {
const { email, captchaToken } = req.body;

try {
if (!email || !captchaToken) {
return res.status(400).json({ message: "Email and CAPTCHA token are required." });
}

const isHuman = await verifyRecaptcha(captchaToken);
if (!isHuman) {
return res.status(403).json({ message: "CAPTCHA verification failed." });
}

// Logic to send OTP via nodemailer
res.status(200).json({ message: "OTP sent successfully." });
} catch (error) {
console.error("Error during sendOTP:", error);
res.status(500).json({ message: "Internal server error." });
}
}

export const forgotPassword = async (req, res) => {
const { email, captchaToken } = req.body;

try {
if (!email || !captchaToken) {
return res.status(400).json({ message: "Email and CAPTCHA token are required." });
}

const isHuman = await verifyRecaptcha(captchaToken);
if (!isHuman) {
return res.status(403).json({ message: "CAPTCHA verification failed." });
}

// Logic to handle forgot password
res.status(200).json({ message: "Password reset link sent." });
} catch (error) {
console.error("Error during forgotPassword:", error);
res.status(500).json({ message: "Internal server error." });
}
}
11 changes: 11 additions & 0 deletions backend/lib/runtime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const isVercel = () => process.env.VERCEL === "1" || process.env.VERCEL === "true";

export const parsePort = (portStr) => {
const port = parseInt(portStr, 10);
return isNaN(port) ? 8080 : port;
};

export const getPlatform = () => {
if (isVercel()) return "vercel";
return process.platform;
};
18 changes: 18 additions & 0 deletions backend/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,21 @@ export function generateToken(userId) {

return token
}

export const verifyRecaptcha = async (captchaToken) => {
if (!captchaToken) return false;
try {
const response = await fetch(`https://www.google.com/recaptcha/api/siteverify`, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: `secret=${process.env.RECAPTCHA_SECRET_KEY}&response=${captchaToken}`,
});
const data = await response.json();
return data.success;
} catch (error) {
console.error("Recaptcha verification error:", error);
return false;
}
};
Loading