Files
pedwfrontend/pages/api/endpoint/updateaccount_api.js
T

140 lines
4.2 KiB
JavaScript

import { consoleLogger } from "../../../actions/core/logger";
import { respondError, respondSuccess } from "../middleware/apiResponse";
import { updateCrmContact } from "../../../lib/server/updateCrmContact";
import { getServerSession } from "next-auth/next";
import { authOptions } from "../auth/[...nextauth]";
import { getToken } from "../../../actions/core/token";
import { relayGetData } from "../middleware/relayForwarding";
import { azureHeaders } from "../../../actions/core/headers";
import { escapeODataString } from "../../../actions/core/guards";
const GUID_PATTERN =
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
const ALLOWED_ACCOUNT_FIELDS = new Set([
"pinswg_preferredlanguage",
"firstname",
"lastname",
"telephone1",
"pinswg_companyname",
"address1_line1",
"address1_line2",
"address1_city",
"address1_county",
"address1_postalcode"
]);
export default async function ApiProxy(req, res) {
if (req.method !== "POST") {
res.setHeader("Allow", "POST");
return respondError(res, {
status: 405,
code: "METHOD_NOT_ALLOWED",
message: "Method not allowed"
});
}
const session = await getServerSession(req, res, authOptions(req, res));
if (
typeof session?.user?.email !== "string" ||
session.user.email.trim().length === 0
) {
return respondError(res, {
status: 401,
code: "UNAUTHENTICATED",
message: "Authentication required"
});
}
const contactId = req.query.contactId;
if (typeof contactId !== "string" || !GUID_PATTERN.test(contactId.trim())) {
return respondError(res, {
status: 400,
code: "INVALID_CONTACT_ID",
message: "A valid contactId is required"
});
}
if (
!req.body ||
typeof req.body !== "object" ||
Array.isArray(req.body) ||
Object.keys(req.body).length === 0
) {
return respondError(res, {
status: 400,
code: "ACCOUNT_UPDATE_PAYLOAD_REQUIRED",
message: "Account update payload is required"
});
}
try {
const token = await getToken();
const escapedEmail = escapeODataString(session.user.email);
const contactQueryUrl =
"contacts?$filter=emailaddress1 eq '" +
escapedEmail +
"' and statuscode eq 1&$select=contactid";
const contactResponse = await relayGetData({
queryUrl: contactQueryUrl,
accessToken: token.access_token,
requestOptionsBuilder: (accessToken) => azureHeaders(accessToken)
});
const contacts = contactResponse?.data?.value;
if (
!Array.isArray(contacts) ||
contacts.length !== 1 ||
typeof contacts[0]?.contactid !== "string" ||
!GUID_PATTERN.test(contacts[0].contactid.trim())
) {
return respondError(res, {
status: 403,
code: "CONTACT_IDENTITY_NOT_RESOLVED",
message: "Request not permitted"
});
}
if (
contactId.trim().toLowerCase() !==
contacts[0].contactid.trim().toLowerCase()
) {
return respondError(res, {
status: 403,
code: "CONTACT_OWNERSHIP_MISMATCH",
message: "Request not permitted"
});
}
const updatePayload = Object.fromEntries(
Object.entries(req.body).filter(([field]) =>
ALLOWED_ACCOUNT_FIELDS.has(field)
)
);
if (Object.keys(updatePayload).length === 0) {
return respondError(res, {
status: 400,
code: "NO_ALLOWED_ACCOUNT_FIELDS",
message: "No permitted account fields supplied"
});
}
const data = await updateCrmContact(contactId.trim(), updatePayload);
return respondSuccess(res, data);
} catch (error) {
consoleLogger(error);
return respondError(res, {
status: 400,
code: "ACCOUNT_UPDATE_FAILED",
message: "Failed to update account"
});
}
}