Skip to content

Commit

Permalink
Refactor customer module.
Browse files Browse the repository at this point in the history
  • Loading branch information
HranikBs23 committed Feb 20, 2022
1 parent 50a559c commit 27facbf
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 202 deletions.
3 changes: 2 additions & 1 deletion src/modules/customer/customer-authentication.middleware.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const jwt = require("jsonwebtoken");
const passport = require("passport");

const AuthStrategy = (req, res, next) => {
Expand All @@ -7,13 +6,15 @@ const AuthStrategy = (req, res, next) => {
console.log(err);
return res.status(500).send("Internal server error.");
}

if (!customer) return res.status(401).send("Unauthenticated customer.");

req.logIn(customer, { session: false }, function (error) {
if (error) return next(error);
next();
});
});

auth(req, res, next);
}

Expand Down
172 changes: 24 additions & 148 deletions src/modules/customer/customer.controller.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,19 @@
const path = require("path");
const Customer = require("./customer.model");
const { generateAccessToken } = require("./services/customer.service");
const Customer = require(path.join(process.cwd(), 'src/modules/customer/customer.model'));
const { generateAccessToken } = require(path.join(process.cwd(), 'src/modules/customer/services/customer.service'));
const cloudinary = require(path.join(process.cwd(), 'src/config/lib/cloudinary'));


async function updateAvatar(req, res, next) {
try {
const { id } = req.params;

const customer = await Customer.findOne({
where: {
id,
},
});

if (!customer) return res.status(404).send("Customer not found!");

const file_url = await cloudinary.uploader.upload(req.file.path);

customer.update({ avatar_url: file_url.secure_url });

res.status(201).send({
status: "success",
message: "Customer avatar updated successfully!",
data:
{
customer_id: customer.id,
avatar_url: file_url.secure_url,
}
});


} catch (error) {
console.log(error);
return res.status(500).json({
status: 500,
message: "Internal server error!",
data: error,
});
}
}

async function login(req, res) {
try {
const { email, password } = req.body;

const customer = await Customer.findOne({
where: {
email,
},
});
const customer = await Customer.findOne({ where: { email }});

if (!customer || !customer.password || !customer.validPassword(password))
return res.status(400).send("Invalid email or password!");
if (!customer || !customer.password || !customer.validPassword(password)) return res.status(400).send("Invalid email or password!");

res.cookie("access_token", generateAccessToken(customer), { httpOnly: true, sameSite: true, signed: true });

res.status(201).send({
status: "success",
message: "Customer logged in successfully!",
data:
{
email: customer.email,
loggedInTime: new Date(),
}
});
res.status(200).send(customer);
} catch (err) {
console.log(err);
res.status(500).json("Internal server error!");
Expand All @@ -73,39 +22,9 @@ async function login(req, res) {

async function logout(req, res) {
res.clearCookie("access_token");
res.clearCookie("refresh_token").redirect("/");
res.send('Ok');
}

const getCustomers = async (req, res) => {
try {
const customers = await Customer.findAll();

res.status(200).send(customers);
} catch (err) {
console.error(err);
res.status(500).send("Internal server error!");
}
};

const getCustomer = async (req, res) => {
try {
const { id } = req.params;

const customer = await Customer.findOne({
where: {
id,
},
});

if (!customer) return res.status(404).send("Customer not found!");

res.status(200).send(customer);
} catch (err) {
console.error(err);
res.status(500).send("Internal server error!");
}
};

const registerCustomer = async (req, res) => {
try {
const { username, email, password } = req.body;
Expand All @@ -128,86 +47,43 @@ const registerCustomer = async (req, res) => {
}
};

const updateCustomer = async (req, res) => {
async function getSignedInCustomerProfile (req, res) {
try {
const { id } = req.params;
const { firstName, lastName, username, email } = req.body;

const customer = await Customer.update(
{
first_name: firstName,
last_name: lastName,
username,
email,
},
{
where: {
id,
},
}
);
const customer = await Customer.findOne({ where: { id: req.user.id }});

if (!customer) return res.status(404).send("Customer not found!");

res.status(201).send(customer);
} catch (err) {
console.log(err);
res.status(500).send("Internal server error!");
}
};

const updateCustomerDetails = async (req, res) => {
try {
const { id } = req.params;
const { firstName, lastName, username, email } = req.body;

const customer = await Customer.findOne({
where: {
id,
},
});

if (!customer) return res.status(404).send("Customer not found!");

if (firstName) customer.update({ first_name: firstName });
if (lastName) customer.update({ first_name: lastName });
if (username) customer.update({ username });
if (email) customer.update({ email });

res.status(201).send(customer);
res.status(200).send(customer);
} catch (err) {
console.log(err);
console.error(err);
res.status(500).send("Internal server error!");
}
};
}

const deleteCustomer = async (req, res) => {
async function updateSignedInCustomerProfile (req, res) {
try {
const { id } = req.params;
const { first_name, last_name, username, email, phone } = req.body;

const customer = await Customer.findOne({
where: {
id,
},
});
const customer = await Customer.findOne({ where: { id: req.user.id }});

if (!customer) return res.status(404).send("Customer not found!");

customer.update({ first_name, last_name, username, email, phone });

await customer.destroy();
if(req.file?.path) {
const file_url = await cloudinary.uploader.upload(req.file.path);
customer.update({ avatar_url: file_url.secure_url });
}

res.sendStatus(200).send(customer);
res.send(customer);
} catch (err) {
console.log(err);
res.status(500).send("Internal server error!");
}
};
}

module.exports.updateAvatar = updateAvatar;
module.exports.login = login;
module.exports.logout = logout;
module.exports.getCustomers = getCustomers;
module.exports.getCustomer = getCustomer;
module.exports.registerCustomer = registerCustomer;
module.exports.updateCustomer = updateCustomer;
module.exports.updateCustomerDetails = updateCustomerDetails;
module.exports.deleteCustomer = deleteCustomer;
module.exports.getSignedInCustomerProfile = getSignedInCustomerProfile;
module.exports.updateSignedInCustomerProfile = updateSignedInCustomerProfile;
11 changes: 3 additions & 8 deletions src/modules/customer/customer.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@ module.exports = (app) => {
app.route('/api/customers')
.post(validate(customerRegisterSchema), controller.registerCustomer);

app.route('/api/customers/:id')
.get(AuthStrategy, controller.getCustomer)
.put(AuthStrategy, validate(customerUpdateSchema), controller.updateCustomer)
.patch(AuthStrategy, validate(customerUpdateSchema), controller.updateCustomerDetails)
.delete(AuthStrategy, controller.deleteCustomer);

app.route('/api/customers/updateAvatar/:id')
.put(AuthStrategy, multer.single('image'), controller.updateAvatar);
app.route('/api/customers/profile')
.get(AuthStrategy, controller.getSignedInCustomerProfile)
.put(AuthStrategy, validate(customerUpdateSchema), multer.single('image'), controller.updateSignedInCustomerProfile);
};

57 changes: 33 additions & 24 deletions src/modules/customer/customer.schema.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,51 @@
const { object, string, ref } = require('yup');
const { object, string, ref } = require("yup");

const isEmailLengthValid = email => {
const isEmailLengthValid = (email) => {
if (!email) return false;
const part = email.split('@');
const part = email.split("@");
const emailParts = part[0];
return emailParts.length <= 64;
}
};

const customerRegisterSchema = object().shape({
username: string()
.min(3, 'Username must be at least 3 characters.')
.max(50, 'Username must be at most 50 character long.')
.required('Username is required.'),
.min(3, "Username must be at least 3 characters.")
.max(50, "Username must be at most 50 character long.")
.required("Username is required."),
email: string()
.email('This field should be a valid email address.')
.max(100, 'Email must be at most 100 characters long.')
.required('Email is required.')
.test('is-valid-email-length', 'The part before @ of the email can be maximum 64 characters.',
email => isEmailLengthValid(email)),
.email("This field should be a valid email address.")
.max(100, "Email must be at most 100 characters long.")
.required("Email is required.")
.test(
"is-valid-email-length",
"The part before @ of the email can be maximum 64 characters.",
(email) => isEmailLengthValid(email)
),
password: string()
.min(8, 'The password must be at least 8 characters long.')
.max(50, 'The password must be at most 50 characters long.')
.required('Password is required.'),
.min(8, "The password must be at least 8 characters long.")
.max(50, "The password must be at most 50 characters long.")
.required("Password is required."),
confirm_password: string()
.required('Confirm Password is required')
.oneOf([ref('password'), null], 'Password and Confirm Password must should be matched')
.required("Confirm Password is required")
.oneOf(
[ref("password"), null],
"Password and Confirm Password must should be matched"
),
});

const customerUpdateSchema = object().shape({
username: string()
.min(3, 'Username must be at least 3 characters.')
.max(50, 'Username must be at most 50 characters long.'),
.min(3, "Username must be at least 3 characters.")
.max(50, "Username must be at most 50 characters long."),
email: string()
.email('This field should be a valid email address.')
.max(100, 'Email must be at most 100 characters long.')
.test('is-valid-email-length', 'The part before @ of the email can be maximum 64 characters.',
email => isEmailLengthValid(email))
.email("This field should be a valid email address.")
.max(100, "Email must be at most 100 characters long.")
.test(
"is-valid-email-length",
"The part before @ of the email can be maximum 64 characters.",
(email) => isEmailLengthValid(email)
),
});

module.exports.customerRegisterSchema = customerRegisterSchema;
module.exports.customerUpdateSchema = customerUpdateSchema;
module.exports.customerUpdateSchema = customerUpdateSchema;
45 changes: 24 additions & 21 deletions src/modules/customer/customer.strategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,29 @@ const { Strategy } = require("passport-jwt");
const Customer = require("./customer.model");

module.exports = function () {
function cookieExtractor(req) {
let token = null;
if (req && req.signedCookies) token = req.signedCookies["access_token"];
return token;
}
function cookieExtractor(req) {
let token = null;
if (req && req.signedCookies) token = req.signedCookies["access_token"];
return token;
}

passport.use(
"customer-jwt",
new Strategy(
{ secretOrKey: process.env.TOKEN_SECRET, jwtFromRequest: cookieExtractor },
function (payload, done) {
Customer.findOne({
where: {
id: payload.id,
},
}).then((customer) => {
if (customer) return done(null, customer);
return done(null, false);
});
}
)
);
passport.use(
"customer-jwt",
new Strategy(
{
secretOrKey: process.env.TOKEN_SECRET,
jwtFromRequest: cookieExtractor,
},
function (payload, done) {
Customer.findOne({
where: {
id: payload.id,
},
}).then((customer) => {
if (customer) return done(null, customer);
return done(null, false);
});
}
)
);
};

0 comments on commit 27facbf

Please sign in to comment.