Skip to content

Commit

Permalink
Changed the user model and username validation
Browse files Browse the repository at this point in the history
  • Loading branch information
OomsOoms committed May 24, 2024
1 parent e622179 commit 41f8a13
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 34 deletions.
4 changes: 2 additions & 2 deletions server/src/api/controllers/user.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ const { userService } = require('../services');
async function registerUser(req, res) {
// get the username, email, and password from the request body
const { username, email, password } = req.body;
await userService.registerUser(username, email, password);
res.status(201).json({ message: 'User created successfully' });
const user = await userService.registerUser(username, email, password);
res.status(201).json(user);
}

/**
Expand Down
40 changes: 20 additions & 20 deletions server/src/api/helpers/sendEmail.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
const nodemailer = require('nodemailer');
//const nodemailer = require('nodemailer');

// im getting spammed so much so im just loggin the email
module.exports = function (to, subject, text) {
const transporter = nodemailer.createTransport({
service: 'Gmail',
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
},
});
console.log(process.env.EMAIL_USER, process.env.EMAIL_PASS);
//const transporter = nodemailer.createTransport({
// service: 'Gmail',
// host: 'smtp.gmail.com',
// port: 465,
// secure: true,
// auth: {
// user: process.env.EMAIL_USER,
// pass: process.env.EMAIL_PASS,
// },
//});
const mailOptions = {
//from: "", // If not set, it will be sent from the default email of the gmail account
to: to,
subject: subject,
text: text,
};

transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.error('Error sending email: ', error);
} else {
console.log('Email sent: ', info.response);
}
});
//transporter.sendMail(mailOptions, (error, info) => {
// if (error) {
// console.error('Error sending email: ', error);
// } else {
// console.log('Email sent: ', info.response);
// }
//});
console.log(mailOptions);
};
52 changes: 46 additions & 6 deletions server/src/api/models/user.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,62 @@ const UserSchema = new mongoose.Schema(
type: String,
required: true,
},
passwordChangedAt: {
type: Number,
default: () => Math.floor(Date.now() / 1000),
profile: {
displayName: {
type: String,
default: this.username,
},
bio: {
type: String,
default: 'No bio provided',
},
profilePicture: {
type: String,
default:
'https://i.pinimg.com/736x/c3/57/fa/c357face2de95f03e31c27cecec2ef63.jpg',
},
},
active: {
type: Boolean,
default: false,
settings: {
language: {
type: String,
default: 'en',
},
},
createdAt: {
type: Date,
default: Date.now(),
index: {
expireAfterSeconds: 60,
partialFilterExpression: { active: false },
},
},
updatedAt: {
type: Date,
default: () => Date.now(),
},
roles: {
type: [String],
default: ['user'],
},
active: {
type: Boolean,
default: false,
},
lastLogin: {
type: Date,
default: null,
},
},
{ collection: 'Users' }
);

UserSchema.pre('save', function (next) {
// 'this' refers to the User document.
if (!this.profile.displayName) {
this.profile.displayName = this.username;
}
next();
});
UserSchema.pre('save', async function (next) {
if (!this.isModified('password')) return next();
this.password = await hashPassword(this.password);
Expand Down
25 changes: 20 additions & 5 deletions server/src/api/services/user.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,33 @@ const { User } = require('../models');
const { generateJwt, comparePasswords, sendEmail } = require('../helpers');
const { Error } = require('../helpers');

// if a user hasnt verified their email within a certain time frame, they should be deleted
// jwt token method im using might not be the best for this so i might need to change it
async function registerUser(username, email, password) {
try {
// Few details are needed to create a user, this is to reduce friction in the registration process
const user = new User({ username, email, password });
await user.save();
const token = generateJwt({ id: user._id }, { expiresIn: '10m' });
const verificationLink = `${process.env.DOMAIN}/api/users/verify?token=${token}`;
sendEmail(email, 'Verify your email', verificationLink);

return true;
return {
success: true,
message:
'User created, email verification link sent and will expire in 10 minutes',
user: {
_id: user._id,
username: user.username,
email: user.email,
active: user.active,
profile: {
bio: user.profile.bio,
profilePicture: user.profile.profilePicture,
displayName: user.profile.displayName,
},
settings: {
language: user.settings.language,
},
},
};
} catch (error) {
if (error.code === 11000) {
if (error.keyValue.username) {
Expand All @@ -21,7 +37,6 @@ async function registerUser(username, email, password) {
throw Error.mongoConflictError('Email already exists');
}
}
// Throw an error if its not a duplicate key error
throw error;
}
}
Expand Down
7 changes: 6 additions & 1 deletion server/src/api/validations/user.validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ const registerUser = [
.bail()
.isLength({ min: 3 })
.withMessage('Username must be at least 3 characters long')
.bail()
.matches(/^[a-z0-9_-]+$/)
.withMessage(
'Username can only contain lowercase letters, numbers, underscores, and hyphens'
)
.bail(),
body('email')
.notEmpty()
Expand All @@ -26,7 +31,7 @@ const registerUser = [
.withMessage('Password is required')
.bail()
.isLength({ min: 8 })
.withMessage('Password must be at least 8 characters long')
.withMessage('Password must be at least 8 characters long')
.bail()
.trim()
.escape()
Expand Down

0 comments on commit 41f8a13

Please sign in to comment.