216 lines
6.4 KiB
JavaScript
216 lines
6.4 KiB
JavaScript
const {
|
|
SET_PHONE_NUMBER_CONSENT,
|
|
BULK_SET_PHONE_NUMBER_CONSENT,
|
|
INSERT_PHONE_NUMBER_CONSENT_HISTORY
|
|
} = require("../graphql-client/queries");
|
|
const { phone } = require("phone");
|
|
const gqlClient = require("../graphql-client/graphql-client").client;
|
|
|
|
/**
|
|
* Set SMS consent for a phone number
|
|
* @param req
|
|
* @param res
|
|
* @returns {Promise<*>}
|
|
*/
|
|
const setConsent = async (req, res) => {
|
|
const { bodyshopid, phone_number, consent_status, reason, changed_by } = req.body;
|
|
const {
|
|
logger,
|
|
ioRedis,
|
|
ioHelpers: { getBodyshopRoom },
|
|
sessionUtils: { getBodyshopFromRedis }
|
|
} = req;
|
|
|
|
if (!bodyshopid || !phone_number || consent_status === undefined || !reason || !changed_by) {
|
|
logger.log("set-consent-error", "ERROR", req.user.email, null, {
|
|
type: "missing-parameters",
|
|
bodyshopid,
|
|
phone_number,
|
|
consent_status,
|
|
reason,
|
|
changed_by
|
|
});
|
|
return res.status(400).json({ success: false, message: "Missing required parameter(s)." });
|
|
}
|
|
|
|
try {
|
|
// Check enforce_sms_consent
|
|
const bodyShopData = await getBodyshopFromRedis(bodyshopid);
|
|
const enforceConsent = bodyShopData?.enforce_sms_consent ?? false;
|
|
|
|
if (!enforceConsent) {
|
|
logger.log("set-consent-error", "ERROR", req.user.email, null, {
|
|
type: "consent-not-enforced",
|
|
bodyshopid
|
|
});
|
|
return res.status(403).json({ success: false, message: "SMS consent enforcement is not enabled." });
|
|
}
|
|
|
|
const normalizedPhone = phone(phone_number, "CA").phoneNumber.replace(/^\+1/, "");
|
|
const consentResponse = await gqlClient.request(SET_PHONE_NUMBER_CONSENT, {
|
|
bodyshopid,
|
|
phone_number: normalizedPhone,
|
|
consent_status
|
|
});
|
|
|
|
const consent = consentResponse.insert_phone_number_consent_one;
|
|
|
|
// Log audit history
|
|
const historyResponse = await gqlClient.request(INSERT_PHONE_NUMBER_CONSENT_HISTORY, {
|
|
objects: [
|
|
{
|
|
phone_number_consent_id: consent.id,
|
|
old_value: null, // Not tracking old value
|
|
new_value: consent_status,
|
|
reason,
|
|
changed_by,
|
|
changed_at: "now()"
|
|
}
|
|
]
|
|
});
|
|
|
|
const history = historyResponse.insert_phone_number_consent_history.returning[0];
|
|
|
|
// Emit WebSocket event
|
|
const broadcastRoom = getBodyshopRoom(bodyshopid);
|
|
ioRedis.to(broadcastRoom).emit("consent-changed", {
|
|
bodyshopId: bodyshopid,
|
|
phone_number: normalizedPhone,
|
|
consent_status,
|
|
reason
|
|
});
|
|
|
|
logger.log("set-consent-success", "DEBUG", req.user.email, null, {
|
|
bodyshopid,
|
|
phone_number: normalizedPhone,
|
|
consent_status
|
|
});
|
|
|
|
// Return both consent and history
|
|
res.status(200).json({
|
|
success: true,
|
|
consent: {
|
|
...consent,
|
|
phone_number_consent_history: [history]
|
|
}
|
|
});
|
|
} catch (error) {
|
|
logger.log("set-consent-error", "ERROR", req.user.email, null, {
|
|
bodyshopid,
|
|
phone_number,
|
|
error: error.message,
|
|
stack: error.stack
|
|
});
|
|
res.status(500).json({ success: false, message: "Failed to update consent status." });
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Bulk set SMS consent for multiple phone numbers
|
|
* @param req
|
|
* @param res
|
|
* @returns {Promise<*>}
|
|
*/
|
|
const bulkSetConsent = async (req, res) => {
|
|
const { bodyshopid, consents } = req.body; // consents: [{ phone_number, consent_status }]
|
|
const {
|
|
logger,
|
|
ioRedis,
|
|
ioHelpers: { getBodyshopRoom },
|
|
sessionUtils: { getBodyshopFromRedis }
|
|
} = req;
|
|
|
|
if (!bodyshopid || !Array.isArray(consents) || consents.length === 0) {
|
|
logger.log("bulk-set-consent-error", "ERROR", req.user.email, null, {
|
|
type: "missing-parameters",
|
|
bodyshopid,
|
|
consents
|
|
});
|
|
return res.status(400).json({ success: false, message: "Missing or invalid parameters." });
|
|
}
|
|
|
|
try {
|
|
// Check enforce_sms_consent
|
|
const bodyShopData = await getBodyshopFromRedis(bodyshopid);
|
|
const enforceConsent = bodyShopData?.enforce_sms_consent ?? false;
|
|
|
|
if (!enforceConsent) {
|
|
logger.log("bulk-set-consent-error", "ERROR", req.user.email, null, {
|
|
type: "consent-not-enforced",
|
|
bodyshopid
|
|
});
|
|
return res.status(403).json({ success: false, message: "SMS consent enforcement is not enabled." });
|
|
}
|
|
|
|
const objects = consents.map(({ phone_number, consent_status }) => ({
|
|
bodyshopid,
|
|
phone_number: phone(phone_number, "CA").phoneNumber.replace(/^\+1/, ""),
|
|
consent_status,
|
|
consent_updated_at: "now()"
|
|
}));
|
|
|
|
// Insert or update phone_number_consent records
|
|
const consentResponse = await gqlClient.request(BULK_SET_PHONE_NUMBER_CONSENT, {
|
|
objects
|
|
});
|
|
|
|
const updatedConsents = consentResponse.insert_phone_number_consent.returning;
|
|
|
|
// Log audit history
|
|
const historyObjects = updatedConsents.map((consent) => ({
|
|
phone_number_consent_id: consent.id,
|
|
old_value: null, // Not tracking old value for bulk updates
|
|
new_value: consent.consent_status,
|
|
reason: "System update via bulk upload",
|
|
changed_by: "system",
|
|
changed_at: "now()"
|
|
}));
|
|
|
|
const historyResponse = await gqlClient.request(INSERT_PHONE_NUMBER_CONSENT_HISTORY, {
|
|
objects: historyObjects
|
|
});
|
|
|
|
const history = historyResponse.insert_phone_number_consent_history.returning;
|
|
|
|
// Combine consents with their history
|
|
const consentsWithhistory = updatedConsents.map((consent, index) => ({
|
|
...consent,
|
|
phone_number_consent_history: [history[index]]
|
|
}));
|
|
|
|
// Emit WebSocket events for each consent change
|
|
const broadcastRoom = getBodyshopRoom(bodyshopid);
|
|
updatedConsents.forEach((consent) => {
|
|
ioRedis.to(broadcastRoom).emit("consent-changed", {
|
|
bodyshopId: bodyshopid,
|
|
phone_number: consent.phone_number,
|
|
consent_status: consent.consent_status,
|
|
reason: "System update via bulk upload"
|
|
});
|
|
});
|
|
|
|
logger.log("bulk-set-consent-success", "DEBUG", req.user.email, null, {
|
|
bodyshopid,
|
|
updatedCount: updatedConsents.length
|
|
});
|
|
|
|
res.status(200).json({
|
|
success: true,
|
|
updatedCount: updatedConsents.length,
|
|
consents: consentsWithhistory
|
|
});
|
|
} catch (error) {
|
|
logger.log("bulk-set-consent-error", "ERROR", req.user.email, null, {
|
|
bodyshopid,
|
|
error: error.message,
|
|
stack: error.stack
|
|
});
|
|
res.status(500).json({ success: false, message: "Failed to update consents." });
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
setConsent,
|
|
bulkSetConsent
|
|
};
|