140 lines
4.2 KiB
JavaScript
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"
|
|
});
|
|
}
|
|
}
|