Skip to content

Commit

Permalink
chore: user model
Browse files Browse the repository at this point in the history
Signed-off-by: UtkarshAhuja2003 <[email protected]>
  • Loading branch information
UtkarshAhuja2003 committed Oct 16, 2024
1 parent 7225773 commit 9b81bf4
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 5 deletions.
6 changes: 1 addition & 5 deletions users/src/apollo.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
const { ApolloServer } = require("@apollo/server");
const typeDefs = require("./schemas/userSchema");

const typeDefs = `
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => "Hello, world!"
Expand Down
71 changes: 71 additions & 0 deletions users/src/models/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const mongoose = require('mongoose');
const validator = require('validator');
const jwt = require('jsonwebtoken');
const { hashPassword, comparePassword } = require('../utils/password');

const { Schema } = mongoose;

const userSchema = new Schema({
name: {
type: String,
required: [true, "Name is required"],
trim: true,
minLength: [2, "Name should be atleast 2 characters"],
maxLength: [200, "Name should be less than 200 characters"]
},
email: {
type: String,
required: [true, "Email is required"],
unique: true,
trim: true,
lowercase: true,
index: true,
validate: [validator.isEmail, "Invalid Email address"]
},
password: {
type: String,
required: [true, "Password is required"],
minLength: [8, "Minimum length should be 8"],
validate: {
validator: function(value) {
return /[a-z]/.test(value) && /[A-Z]/.test(value) && /\d/.test(value) && /[!@#$%^&*()]/.test(value);
},
message: "Password must contain one lowercase, uppercase, number, special character"
}
},
refreshToken: {
type: String
}
},{
timestamps: true
});

userSchema.pre('save', hashPassword);

userSchema.methods.comparePassword = async function (inputPassword) {
return comparePassword(inputPassword, this.password);
};

userSchema.methods.generateAccessToken = function () {
return jwt.sign(
{
_id: this._id,
email: this.email
},
process.env.ACCESS_TOKEN_SECRET,
{ expiresIn: process.env.ACCESS_TOKEN_EXPIRY }
);
};

userSchema.methods.generateRefreshToken = function () {
return jwt.sign(
{
_id: this._id,
},
process.env.REFRESH_TOKEN_SECRET,
{ expiresIn: process.env.REFRESH_TOKEN_EXPIRY }
);
};

const User = mongoose.model('User', userSchema);
module.exports = User;
19 changes: 19 additions & 0 deletions users/src/schemas/userSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const commonResponseFields = `
success: Boolean!
message: String!
errors: [String]
stack: String
`;

const typeDefs = `
type Response {
${commonResponseFields}
data: String
}
type Query {
hello: Response
}
`;

module.exports = typeDefs;
17 changes: 17 additions & 0 deletions users/src/utils/GraphQLErrorResponse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class GraphQLErrorResponse {
/**
* @param {string} message - An error message.
* @param {any[]} errors - List of detailed error messages (if any).
* @param {string} stack - Stack trace for debugging (optional in production).
*/
constructor(message = "Something went wrong", errors = [], stack = "") {
this.data = null;
this.message = message;
this.success = false;
this.errors = errors;
this.stack = stack || null;
}
}

export { GraphQLErrorResponse };

16 changes: 16 additions & 0 deletions users/src/utils/GraphQLResponse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class GraphQLResponse {
/**
* @param {any} data - The data to be returned in the response.
* @param {string} message - A success message.
*/
constructor(data, message = "Success") {
this.data = data;
this.message = message;
this.success = true;
this.errors = null;
this.stack = null;
}
}

export { GraphQLResponse };

21 changes: 21 additions & 0 deletions users/src/utils/password.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const bcrypt = require('bcryptjs');

const hashPassword = async function (next) {
if (!this.isModified('password')) {
return next();
}

try {
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
next();
} catch (error) {
next(error);
}
}

const comparePassword = async (inputPassword, userPassword) => {
return bcrypt.compare(inputPassword, userPassword);
};

module.exports = { hashPassword, comparePassword };

0 comments on commit 9b81bf4

Please sign in to comment.