Skip to content

Commit

Permalink
feat: Use hookable for login and logout functions
Browse files Browse the repository at this point in the history
  • Loading branch information
treoden committed Jan 3, 2025
1 parent 0b0946a commit e7bf8ab
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 56 deletions.
2 changes: 1 addition & 1 deletion packages/evershop/src/lib/util/hookable.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function hookBefore(funcName, callback, priority = 10) {

function hookable(originalFunction, context) {
// Make sure the original function is a named function
const funcName = originalFunction.name;
const funcName = originalFunction.name.replace('bound ', '');
if (!funcName) {
throw new Error('The original function must be a named function');
}
Expand Down
37 changes: 7 additions & 30 deletions packages/evershop/src/modules/auth/bootstrap.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,16 @@
const { request } = require('express');
const { select } = require('@evershop/postgres-query-builder');
const { pool } = require('../../lib/postgres/connection');
const { comparePassword } = require('../../lib/util/passwordHelper');
const { hookable } = require('../../lib/util/hookable');
const loginUserWithEmail = require('./services/loginUserWithEmail');
const logoutUser = require('./services/logoutUser');

module.exports = () => {
request.loginUserWithEmail = async function loginUserWithEmail(
email,
password,
callback
) {
// Escape the email to prevent SQL injection
const userEmail = email.replace(/%/g, '\\%');
const user = await select()
.from('admin_user')
.where('email', 'ILIKE', userEmail)
.and('status', '=', 1)
.load(pool);
const result = comparePassword(password, user ? user.password : '');
if (!user || !result) {
throw new Error('Invalid email or password');
}
this.session.userID = user.admin_user_id;
// Delete the password field
delete user.password;

// Save the user in the request
this.locals.user = user;

request.loginUserWithEmail = async function login(email, password, callback) {
await hookable(loginUserWithEmail.bind(this))(email, password);
this.session.save(callback);
};

request.logoutUser = function logoutUser(callback) {
this.session.userID = undefined;
this.locals.user = undefined;

request.logoutUser = function logout(callback) {
hookable(logoutUser.bind(this))();
this.session.save(callback);
};

Expand Down
31 changes: 31 additions & 0 deletions packages/evershop/src/modules/auth/services/loginUserWithEmail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const { pool } = require('@evershop/evershop/src/lib/postgres/connection');
const {
comparePassword
} = require('@evershop/evershop/src/lib/util/passwordHelper');
const { select } = require('@evershop/postgres-query-builder');

/**
* This function will login the admin user with email and password. This function must be accessed from the request object (request.loginUserWithEmail(email, password, callback))
* @param {string} email
* @param {string} password
*/
async function loginUserWithEmail(email, password) {
// Escape the email to prevent SQL injection
const userEmail = email.replace(/%/g, '\\%');
const user = await select()
.from('admin_user')
.where('email', 'ILIKE', userEmail)
.and('status', '=', 1)
.load(pool);
const result = comparePassword(password, user ? user.password : '');
if (!user || !result) {
throw new Error('Invalid email or password');
}
this.session.userID = user.admin_user_id;
// Delete the password field
delete user.password;
// Save the user in the request
this.locals.user = user;
}

module.exports = loginUserWithEmail;
9 changes: 9 additions & 0 deletions packages/evershop/src/modules/auth/services/logoutUser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Logout a current user. This function must be accessed from the request object (request.logoutUser(callback))
*/
function logoutUser() {
this.session.userID = undefined;
this.locals.user = undefined;
}

module.exports = logoutUser;
31 changes: 7 additions & 24 deletions packages/evershop/src/modules/customer/bootstrap.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
const { request } = require('express');
const config = require('config');
const { pool } = require('@evershop/evershop/src/lib/postgres/connection');
const { select } = require('@evershop/postgres-query-builder');
const { merge } = require('@evershop/evershop/src/lib/util/merge');
const { comparePassword } = require('../../lib/util/passwordHelper');
const { translate } = require('../../lib/locale/translate/translate');
const { addProcessor } = require('../../lib/util/registry');
const registerDefaultCustomerCollectionFilters = require('./services/registerDefaultCustomerCollectionFilters');
const {
defaultPaginationFilters
} = require('../../lib/util/defaultPaginationFilters');
const registerDefaultCustomerGroupCollectionFilters = require('./services/registerDefaultCustomerGroupCollectionFilters');
const { hookable } = require('../../lib/util/hookable');
const loginCustomerWithEmail = require('./services/customer/loginCustomerWithEmail');
const logoutCustomer = require('./services/customer/logoutCustomer');

module.exports = () => {
addProcessor('cartFields', (fields) => {
Expand Down Expand Up @@ -71,34 +71,17 @@ module.exports = () => {
* @param {*} password
* @param {*} callback
*/
request.loginCustomerWithEmail = async function loginCustomerWithEmail(
request.loginCustomerWithEmail = async function login(
email,
password,
callback
) {
// Escape the email to prevent SQL injection
const customerEmail = email.replace(/%/g, '\\%');
const customer = await select()
.from('customer')
.where('email', 'ILIKE', customerEmail)
.and('status', '=', 1)
.load(pool);

const result = comparePassword(password, customer ? customer.password : '');
if (!customer || !result) {
throw new Error(translate('Invalid email or password'));
}
this.session.customerID = customer.customer_id;
// Delete the password field
delete customer.password;
// Save the customer in the request
this.locals.customer = customer;
await hookable(loginCustomerWithEmail.bind(this))(email, password);
this.session.save(callback);
};

request.logoutCustomer = function logoutCustomer(callback) {
this.session.customerID = undefined;
this.locals.customer = undefined;
request.logoutCustomer = function logout(callback) {
hookable(logoutCustomer.bind(this))();
this.session.save(callback);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module.exports = async (request, response, delegate, next) => {
response.json({
error: {
status: INVALID_PAYLOAD,
message
message: error.message
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const {
translate
} = require('@evershop/evershop/src/lib/locale/translate/translate');
const { pool } = require('@evershop/evershop/src/lib/postgres/connection');
const {
comparePassword
} = require('@evershop/evershop/src/lib/util/passwordHelper');
const { select } = require('@evershop/postgres-query-builder');
/**
* Login a customer with email and password. This function must be accessed from the request object (request.loginCustomerWithEmail(email, password, callback))
* @param {string} email
* @param {string} password
*/
async function loginCustomerWithEmail(email, password) {
// Escape the email to prevent SQL injection
const customerEmail = email.replace(/%/g, '\\%');
const customer = await select()
.from('customer')
.where('email', 'ILIKE', customerEmail)
.and('status', '=', 1)
.load(pool);
const result = comparePassword(password, customer ? customer.password : '');
if (!customer || !result) {
throw new Error(translate('Invalid email or password'));
}
this.session.customerID = customer.customer_id;
// Delete the password field
delete customer.password;
// Save the customer in the request
this.locals.customer = customer;
}

module.exports = loginCustomerWithEmail;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Logout the current customer. This function must be accessed from the request object (request.logoutCustomer(callback))
*/
function logoutCustomer() {
this.session.customerID = undefined;
this.locals.customer = undefined;
}

module.exports = logoutCustomer;

0 comments on commit e7bf8ab

Please sign in to comment.