Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
36a7749
Connect to database
naikmubashir Jan 13, 2025
9f720eb
Add User.js model
naikmubashir Jan 13, 2025
7a9393f
Add registration route
naikmubashir Jan 13, 2025
9a1265b
Update User model
naikmubashir Jan 13, 2025
7911bc1
Add semester attribute in User model
naikmubashir Jan 13, 2025
2dfe7c1
Add ConfirmationEmail funtionality
naikmubashir Jan 13, 2025
2113999
Fix bugs
naikmubashir Jan 13, 2025
b01f0b6
Add cors middleware
naikmubashir Jan 13, 2025
84a6cac
Add admin route
naikmubashir Jan 14, 2025
7b9374f
Add gender and T&M attribute
naikmubashir Jan 14, 2025
641da76
Fix bugs
naikmubashir Jan 14, 2025
7a63761
Add Subscriber model
naikmubashir Jan 15, 2025
a995f34
Add newsletter route
naikmubashir Jan 15, 2025
e5238b9
Refactor: Extract sendConfirmationEmail function to services/emailSer…
naikmubashir Jan 15, 2025
fd82f6a
Fix bugs
naikmubashir Jan 15, 2025
79e3d66
Update admin route
naikmubashir Jan 16, 2025
e0a7f1d
Remove .gitignore
naikmubashir Jan 16, 2025
3776aaf
Rename backend folder
naikmubashir Jan 16, 2025
a4602ad
Merge pull request #3 from Open-Hub-Community/backend_branch
naikmubashir Jan 16, 2025
077f019
Update package.json
naikmubashir Jan 16, 2025
1d3eead
Update package.json
naikmubashir Jan 16, 2025
d48f8b1
Update package.json
naikmubashir Jan 16, 2025
6c73987
Update package.json
naikmubashir Jan 16, 2025
d3dc65f
Update README.md
Anan328 Jan 16, 2025
692683d
Update README.md
Anan328 Jan 16, 2025
3e25cc6
Merge pull request #4 from Open-Hub-Community/frontend_branch
Anan328 Jan 16, 2025
aaaa1fd
Add allowedDomains.js
naikmubashir Jan 16, 2025
c6bc9f6
Rename folder
naikmubashir Jan 16, 2025
e3c6896
Optimise code by sending mails asynchronously
naikmubashir Jan 16, 2025
25edb02
Refactor database queries to run in parallel using Promise.all
naikmubashir Jan 16, 2025
9f83abe
Remove console.logs
naikmubashir Jan 16, 2025
40f61c4
Update registerController.js
naikmubashir Jan 24, 2025
ea2616b
Update registerController.js
naikmubashir Jan 24, 2025
4b8fc18
Create healthRoute.js
naikmubashir Jan 25, 2025
6d9a772
Create healthController.js
naikmubashir Jan 25, 2025
483d5a8
Update server.js
naikmubashir Jan 25, 2025
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
12 changes: 12 additions & 0 deletions backend/config/DBconn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import mongoose from 'mongoose';


const connectDb=async (url)=>{
try{
await mongoose.connect(url);
}catch(err){
console.log(err,'database not connected')
}
}

export default connectDb;
3 changes: 3 additions & 0 deletions backend/config/allowedDomains.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const allowedDomains = ['mail.com', 'gmail.com', 'yahoo.com', 'outlook.com', 'hotmail.com', 'aol.com', 'icloud.com', 'protonmail.com', 'zoho.com', 'gmx.com'];

export default allowedDomains;
19 changes: 19 additions & 0 deletions backend/controllers/adminController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import User from "../models/User.js";
import Subscriber from "../models/Subscriber.js";

const getAllStudents=async (req,res)=>{
try {
const [users, subscribers] = await Promise.all([
User.find(), // Fetch all registered users
Subscriber.find() // Fetch all subscribers
]);
res.json([users?.length ? users : [], subscribers?.length ? subscribers : []]);
} catch (err) {
res.status(500).json({ message: 'Server error-Couldnt fetch the students', error: err.message });
}
}




export default getAllStudents;
17 changes: 17 additions & 0 deletions backend/controllers/healthController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import mongoose from 'mongoose';

export const checkHealth = (req, res) => {
const dbStatus = mongoose.connection.readyState === 1 ? 'connected' : 'disconnected';
if (dbStatus === 'connected') {
return res.json({
status: 'ok',
database: dbStatus,
});
} else {
return res.status(500).json({
status: 'error',
message: 'Database connection is down',
database: dbStatus,
});
}
};
60 changes: 60 additions & 0 deletions backend/controllers/newsletterController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import Subscribers from "../models/Subscriber.js";
import sendConfirmationEmail from "../services/emailService.js";
import allowedDomains from "../config/allowedDomains.js";
const handleNewSubscriber = async (req, res) => {
const { email } = req.body;
if (!email) {
return res.status(400).json({ message: 'Enter email to subscribe to the newsletter' });
}
// Check if the email domain is allowed
const emailDomain = email.split('@')[1];
if (!allowedDomains.includes(emailDomain)) {
return res.status(400).json({ message: 'Email domain not allowed.' });
}
const duplicateEmail = await Subscribers.findOne({ email });
if (duplicateEmail) {
return res.status(409).json({ message: 'Email already registered.' });
}

// Create a new subscriber
try {
const newSubscriber = await Subscribers.create({ email });
// Send confirmation email
const mailOptions = {
from: '"Open Hub Community" <[email protected]>',
to: email,
subject: 'Welcome to Open Hub Community Newsletter! 🎉',
text: `Hi there! \n\nThank you for subscribing to the Open Hub Community newsletter! 🎉 We're excited to have you onboard and look forward to bringing you the latest updates on open-source projects, tech trends, and collaboration opportunities. 💻✨\n\nAs a subscriber, you'll be the first to know about new initiatives, tutorials, and news from our community. Stay tuned for upcoming newsletters packed with valuable insights and opportunities to engage with like-minded tech enthusiasts! 🚀\n\nFeel free to reach out to us if you have any questions or suggestions. We’d love to hear from you! 💬\n\nIf you’re interested in joining our community and collaborating with us directly, click here to join: https://github.com/Open-Hub-Community/Support/issues/new?assignees=&labels=invite+me+to+the+community&projects=&template=invitation.yml&title=Please+invite+me+to+the+Open+Hub+Community+Organization 🔗\n\nBest regards,\nNaik Mubashir\nFounder, Open Hub Community\n\nFollow us on:\nLinkedIn: https://www.linkedin.com/company/open8hub\nGitHub: https://www.github.com/Open-Hub-Community\nTwitter: https://www.x.com/open8hub\n\n🚀 Let's build something amazing together!`,
html: `
<p>Hi there!</p>
<p>Thank you for subscribing to the <strong>Open Hub Community</strong> newsletter! 🎉 We are thrilled to have you as part of our growing community and are excited to bring you the latest updates on open-source projects, tech trends, and collaboration opportunities. 💻✨</p>
<p>As a subscriber, you'll be the first to know about:</p>
<ul>
<li><strong>Exclusive open-source projects</strong> and collaboration opportunities. 🔧</li>
<li><strong>Helpful resources</strong> and tutorials to enhance your skills. 📚</li>
<li><strong>Latest news and trends</strong> in the world of tech and innovation. 🌐</li>
</ul>
<p>We encourage you to stay engaged and participate in upcoming events. If you ever have any questions, feedback, or suggestions, don’t hesitate to reach out. We’re always happy to hear from you! 💬</p>
<p>If you’re interested in joining our community and collaborating with us directly, <a href="https://github.com/Open-Hub-Community/Support/issues/new?assignees=&labels=invite+me+to+the+community&projects=&template=invitation.yml&title=Please+invite+me+to+the+Open+Hub+Community+Organization">click here to join the Open Hub Community</a> 🔗.</p>
<p>Best regards,</p>
<p><strong>Naik Mubashir</strong><br>Founder, Open Hub Community</p>
<p>Follow us on:</p>
<p>
<a href="https://www.linkedin.com/company/open8hub">LinkedIn</a> |
<a href="https://www.github.com/Open-Hub-Community">GitHub</a> |
<a href="https://www.x.com/open8hub">Twitter</a>
</p>
<p>🚀 Let's build something amazing together!</p>
`
};

sendConfirmationEmail(email,mailOptions);
return res.status(201).json({
message: `New subscriber '${newSubscriber.email}' added successfully.`
});
} catch (error) {
return res.status(500).json({ message: 'Internal server error while handling new subscription' });
}
};

export default handleNewSubscriber;
63 changes: 63 additions & 0 deletions backend/controllers/registerController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import User from "../models/User.js";
import sendConfirmationEmail from "../services/emailService.js";
import allowedDomains from "../config/allowedDomains.js";

const handleNewRegistration = async (req, res) => {
const { name, email, phoneNumber, college, semester,gender, agree } = req.body;
// Validate required fields
if (!name || !email || !phoneNumber || !college || !semester, !gender, !agree) {
return res.status(400).json({ message: 'All fields are required.' });
}
// Check for duplicate email and phone number in parallel
const [duplicateEmail, duplicatePhoneNo] = await Promise.all([
User.findOne({ email }),
User.findOne({ phoneNumber })
]);
// Check if the email domain is allowed
const emailDomain = email.split('@')[1];
if (!allowedDomains.includes(emailDomain)) {
return res.status(400).json({ message: 'Email domain not allowed.' });
}
if (duplicateEmail && duplicatePhoneNo) {
return res.status(409).json({ message: 'Email and Phone Number already registered.' });
}
else if (duplicateEmail) {
console.log('Duplicate email found:', duplicateEmail);
return res.status(409).json({ message: 'Email already registered.' });
}
else if (duplicatePhoneNo) {
console.log('Duplicate phone number found:', duplicatePhoneNo);
return res.status(409).json({ message: 'Phone number already registered.' });
}

try {
// Create a new user
const newUser = await User.create({ name, email, phoneNumber, college, semester, gender, agree });
const mailOptions={
from:'"Hack-This-Spring Team" [email protected]',
to: email,
subject: 'Registration Confirmation for Hack This Spring',
text:`Dear ${name},\n\nThank you for registering for HackThisSpring! We are excited to have you onboard for this prestigious hackathon organized by the OpenHub Community.\n\nIn the coming days, we will be hosting a team-building meet where you will have the opportunity to connect with other developers, discuss ideas, and form your teams for the event. We encourage you to participate actively and collaborate with fellow developers.\n\nWe look forward to seeing you at HackThisSpring and wish you the best of luck!\n\nBest regards,\nThe HackThisSpring Team`,
html:`
<p>Dear <strong>${name}</strong>,</p>
<p>Thank you for registering for <strong>HackThisSpring</strong>! We are thrilled to have you onboard for this exciting hackathon, organized by the <strong>OpenHub Community</strong>.</p>
<p>In the coming days, we will be hosting a <strong>team-building meet</strong> where you will have the opportunity to connect with other developers, exchange ideas, and form your teams for the event. We encourage you to actively participate and collaborate with your fellow developers.</p>
<p>We are excited about your participation in <strong>HackThisSpring</strong> and wish you the best of luck as you prepare for the hackathon.</p>
<p>Best regards,</p>
<p>The HackThisSpring Team</p>
`
};
// Send confirmation email
sendConfirmationEmail( email, mailOptions);
return res.status(201).json({
message: `New user '${newUser.name}' created successfully.`//, user: newUser, // Include the created user details if needed
});
} catch (error) {
return res.status(500).json({ message: error.message });
}
};




export default handleNewRegistration
18 changes: 18 additions & 0 deletions backend/middlewares/verifyAdmin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@


const verifyAdmin=(req, res, next)=>{
const ADMIN_USERNAME = process.env.ADMIN_USERNAME ;
const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD;

const {adminId,password} = req.body;
if(!adminId || !password ) return res.status(400).json({'message':'adminId and password are required...'});

if (adminId === ADMIN_USERNAME && password===ADMIN_PASSWORD) {
return next();
} else {
return res.status(401).send('Unauthorized: Invalid credentials.');
}


}
export default verifyAdmin;
13 changes: 13 additions & 0 deletions backend/models/Subscriber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import mongoose from "mongoose";

const SubscriberSchema= new mongoose.Schema({
email: {
type: String,
required: true,
unique: true,
trim: true,
lowercase: true,
match: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
}
});
export default mongoose.model('Subscriber',SubscriberSchema);
49 changes: 49 additions & 0 deletions backend/models/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import mongoose from "mongoose";

const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
minlength: 2,
maxlength: 50
},
email: {
type: String,
required: true,
unique: true,
trim: true,
lowercase: true,
match: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
},
phoneNumber: {
type: String,
required: true,
unique: true,
match: /^\d{10}$/
},
college: {
type: String,
required: true,
trim: true,
minlength: 2,
maxlength: 100
},
semester: {
type: String,
required: true,
trim: true,
minlength: 1,
maxlength: 20
},
gender: {
type: String,
required: true,
},
agree: {
type: Boolean,
required: true
}
}, { timestamps: true });

export default mongoose.model('User', UserSchema);
Loading