Skip to content

Commit

Permalink
Toggle Rule Feature
Browse files Browse the repository at this point in the history
  • Loading branch information
sivm99 committed Oct 1, 2024
1 parent c9118db commit 6693d5c
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 120 deletions.
56 changes: 48 additions & 8 deletions Controller/Mail/mailControllerV2.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import CustomError from "../../utils/CustomError.js";
import createSendResponse from "../../utils/createSendResponse.js";

import { createRuleRequest, d1Query } from "../../utils/prepareRequest.js";
import { createRule, removeRule } from "../../utils/rulesRequest.js";
// import { createRule, removeRule } from "../../utils/rulesRequest.js";
import { sendRule } from "../../utils/safeResponseObject.js";

import { addAlias, updateAlias, removeAlias } from "../User/userAlias.js";

export const createRuleV2 = asyncErrorHandler(async (req, res, next) => {
const createRuleV2 = asyncErrorHandler(async (req, res, next) => {
let { alias, destination } = req.body;
if (!alias || !destination) {
return next(
Expand Down Expand Up @@ -86,7 +86,7 @@ export const createRuleV2 = asyncErrorHandler(async (req, res, next) => {
}
});

export const updateRuleV2 = asyncErrorHandler(async (req, res, next) => {
const updateRuleV2 = asyncErrorHandler(async (req, res, next) => {
const id = req.params.id;
let rule;
try {
Expand Down Expand Up @@ -179,7 +179,49 @@ export const updateRuleV2 = asyncErrorHandler(async (req, res, next) => {
}
});

export const deleteRuleV2 = asyncErrorHandler(async (req, res, next) => {
const toggleRuleV2 = asyncErrorHandler(async (req, res, next) => {
const id = req.params.id;
const rule = await Rule.findById(id);
if (!rule) {
return next(new CustomError("Rule not found", 404));
}
if (rule.username !== req.user.username) {
return next(
new CustomError("You are not authorized to access this rule", 401)
);
}

try {
const response = await createRuleRequest(
"PATCH",
rule.alias,
rule.destination,
rule.username
);
if (response.success === false) {
return next(
new CustomError(`${response.errors[0]} and ${response.message}`, 400)
);
}
rule.enabled = !rule.enabled;
await rule.save({ validateBeforeSave: false });
const updatedUserQuery = await updateAlias(req.user.id, rule.alias, {
aliasEmail: rule.alias,
destinationEmail: rule.destination,
active: rule.enabled,
});
if (!updatedUserQuery[0]) {
throw new CustomError("User not found or update failed", 404);
}
const safeRule = sendRule(rule);
const lid = req.user.id || req.user._id;
createSendResponse(safeRule, 200, res, "rule", lid);
} catch (error) {
return next(new CustomError(`Operation failed: ${error.message}`, 500));
}
});

const deleteRuleV2 = asyncErrorHandler(async (req, res, next) => {
const id = req.params.id;
const rule = await Rule.findById(id);
if (!rule) {
Expand Down Expand Up @@ -212,14 +254,12 @@ export const deleteRuleV2 = asyncErrorHandler(async (req, res, next) => {
if (!updatedUserQuery[0]) {
throw new CustomError("User not found or Deletion failed", 404);
}
if (updatedUser) {
updatedUser.aliasCount = updatedUser.alias.length;
await updatedUser.save({ new: true, validateBeforeSave: false });
}

const lid = req.user.id || req.user._id;
createSendResponse(null, 204, res, "rule", lid);
} catch (error) {
return next(new CustomError(`Operation failed: ${error.message}`, 500));
}
});

export { createRuleV2, updateRuleV2, toggleRuleV2, deleteRuleV2 };
15 changes: 15 additions & 0 deletions Controller/User/userAlias.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ const addAlias = async (userId, newAlias) => {
}
};

/**
* udpates the rule in the user's alias list
*
* @param {string} userId - The ID of the user which is to be updated.
* @param {string} aliasEmail - The current alias email of the rule.
* @param {Object} updatedData - The updated data for the rule.
* @returns {Promise<[boolean, string|Error]>} A promise that resolves to an array where the first element is a boolean indicating success, and the second element is a message or error.
*/
const updateAlias = async (userId, aliasEmail, updatedData) => {
try {
await User.findOneAndUpdate(
Expand All @@ -31,6 +39,13 @@ const updateAlias = async (userId, aliasEmail, updatedData) => {
}
};

/**
* removes the rule in the user's alias list.
*
* @param {string} userId - The ID of the user from whom the alias will be removed.
* @param {string} aliasEmail - The alias email to be removed.
* @returns {Promise<[boolean, string|Error]>} A promise that resolves to an array where the first element is a boolean indicating success, and the second element is a message or error.
*/
const removeAlias = async (userId, aliasEmail) => {
try {
await User.findByIdAndUpdate(
Expand Down
8 changes: 8 additions & 0 deletions routes/mailRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import {
createRuleV2,
deleteRuleV2,
toggleRuleV2,
updateRuleV2,
} from "../Controller/Mail/mailControllerV2.js";

Expand Down Expand Up @@ -52,5 +53,12 @@ router
.patch(protect, updateRuleV2)
.delete(protect, deleteRuleV2);

router
.route("/rule/:id/toggle")
.patch(protect, toggleRuleV2);
router
.route("/rules/:id/toggle")
.patch(protect, toggleRuleV2);


export default router;
11 changes: 11 additions & 0 deletions utils/createSendResponse.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ function signToken(id) {
});
}

/**
* Creates and sends a response with a JWT token and user data.
*
* @param {Object|Array} user - The user object or an array of user objects (Or any Object).
* @param {number} statusCode - The HTTP status code to send.
* @param {Object} res - The Express response object.
* @param {string} responseName - The name of the response data field.
* @param {string} [lid] - Optional ID to use instead of the user's ID.
*
* @returns {void}
*/
export default function createSendResponse(
user,
statusCode,
Expand Down
30 changes: 29 additions & 1 deletion utils/prepareRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ function selectDomain(alias) {
);
}

/**
* Creates a rule request to be sent to the server.
*
* @param {string} method - The HTTP method to use for the request (e.g., "POST", "PATCH").
* @param {string} alias - The alias for the rule.
* @param {string} destination - The destination for the rule.
* @param {string} username - The username of the person creating the rule.
* @returns {Promise} - A promise that resolves to the server response.
* @throws {Error} - Throws an error if the domain is invalid.
*/
export const createRuleRequest = (method, alias, destination, username) => {
const domain = selectDomain(alias);
if (!domain) {
Expand All @@ -33,7 +43,9 @@ export const createRuleRequest = (method, alias, destination, username) => {
const url =
method === "POST"
? ruleUrl
: `${ruleUrl}/${domain}/${alias}`;
: method === "PATCH"
? `${ruleUrl}/${domain}/${alias}/flip`
: `${ruleUrl}/${domain}/${alias}`;

return axios({
method,
Expand All @@ -46,6 +58,13 @@ export const createRuleRequest = (method, alias, destination, username) => {
});
};

/**
* Executes a SQL query on cloudflare D1-database using Axios with the provided SQL statement and parameters.
*
* @param {string} sql - The SQL query to be executed.
* @param {Object} params - The parameters to be used in the SQL query.
* @returns {Promise} - A promise that resolves to the response of the Axios request.
*/
export const d1Query = (sql, params) => {
return axios({
method: "POST",
Expand Down Expand Up @@ -84,6 +103,15 @@ export const routingRulesRequest = (method, alias, destination) => {
});
};

/**
* Sends a request to the specified destination using the provided method and domain.
*
* @param {string} method - The HTTP method to use for the request (e.g., 'GET', 'POST').
* @param {string} domain - The domain to select the destination from.
* @param {string} destination - The email address to be used as the destination.
* @param {string} [cfId] - Optional Cloudflare ID for the specific address.
* @returns {Promise|null} - Returns a promise that resolves to the response of the axios request, or null if email, account, or key is not found.
*/
export const destinationRequest = (method, domain, destination, cfId) => {
const [email, account, key] = selectDestination(domain);
const url = !cfId
Expand Down
111 changes: 0 additions & 111 deletions utils/rulesRequest.js

This file was deleted.

9 changes: 9 additions & 0 deletions utils/sendEmail.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { createTransport } from "nodemailer";
const supportEmail = process.env.SUPPORT_EMAIL;
const companyName = process.env.COMPANY_NAME;
/**
* Sends an email using the provided options.
*
* @param {Object} option - The email options.
* @param {string} option.email - The recipient's email address.
* @param {string} option.subject - The subject of the email.
* @param {string} option.message - The message content of the email.
* @returns {Promise<void>} A promise that resolves when the email is sent.
*/
const sendEmail = async function (option) {
// create a transporter
const transporter = createTransport({
Expand Down

0 comments on commit 6693d5c

Please sign in to comment.