fix(security): retire legacy direct CRM case creation endpoint
This commit is contained in:
@@ -76,35 +76,6 @@ export const getAppealID = (
|
||||
});
|
||||
};
|
||||
|
||||
export const createNewCase = (
|
||||
appealTypeId,
|
||||
lpaID,
|
||||
contactid,
|
||||
createBody,
|
||||
containerName
|
||||
) => {
|
||||
appealTypeId = parseInt(appealTypeId);
|
||||
|
||||
var data = createBody;
|
||||
|
||||
var queryUrl = buildFileQuery("/api/endpoint/createcase_api", {
|
||||
appealTypeId,
|
||||
lpaID,
|
||||
contactid,
|
||||
containername: containerName
|
||||
});
|
||||
|
||||
var config = {
|
||||
method: "post",
|
||||
url: withBaseUrl(BASE_URL, queryUrl),
|
||||
data: data
|
||||
};
|
||||
|
||||
return requestJson(config).catch((error) => {
|
||||
consoleLogger(error);
|
||||
});
|
||||
};
|
||||
|
||||
export const createNewCaseBlob = (
|
||||
appealTypeId,
|
||||
lpaID,
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
getSIPSEvents,
|
||||
getSIPSMedia,
|
||||
getAppealID,
|
||||
createNewCase,
|
||||
createNewCaseBlob,
|
||||
updateCase,
|
||||
updateCaseBlob,
|
||||
@@ -26,7 +25,6 @@ export {
|
||||
getSIPSEvents,
|
||||
getSIPSMedia,
|
||||
getAppealID,
|
||||
createNewCase,
|
||||
createNewCaseBlob,
|
||||
updateCase,
|
||||
updateCaseBlob,
|
||||
|
||||
@@ -393,13 +393,6 @@ let CreateCase = (props) => {
|
||||
|
||||
delete values.confirmHASCAS;
|
||||
|
||||
// createNewCase(
|
||||
// appTypeCollection.appealTypeID,
|
||||
// values.lpaTypes,
|
||||
// props.loggedInUser,
|
||||
// values,
|
||||
// props.containerID
|
||||
// )
|
||||
const selectedLpaName = props.LPAData.LPAData.value.filter((obj) => {
|
||||
return obj.accountid === values.lpaTypes;
|
||||
})[0].name;
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
/**
|
||||
* @swagger
|
||||
* /api/endpoint/createcase_api:
|
||||
* post:
|
||||
* tags: [Case]
|
||||
* description: Create case
|
||||
* summary: Phase 2
|
||||
* parameters:
|
||||
* - name: body
|
||||
* in: requestbody
|
||||
* required: true
|
||||
* example: {}
|
||||
* schema:
|
||||
* type: object
|
||||
* - name: contactid
|
||||
* in: query
|
||||
* required: true
|
||||
* example: pinswg_planningappeals78s
|
||||
* schema:
|
||||
* type: string
|
||||
* - name: appealTypeId
|
||||
* in: query
|
||||
* required: true
|
||||
* example: pinswg_planningappeals78id
|
||||
* schema:
|
||||
* type: string
|
||||
* - name: containername
|
||||
* in: query
|
||||
* required: true
|
||||
* example: pinswg_planningappeals78id
|
||||
* schema:
|
||||
* type: string
|
||||
* - name: lpaID
|
||||
* in: query
|
||||
* required: true
|
||||
* example: pinswg_planningappeals78id
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Success
|
||||
*/
|
||||
|
||||
import axios from "axios";
|
||||
import { consoleLogger } from "../../../actions/core/logger";
|
||||
import { getToken } from "../../../actions/core/token";
|
||||
import { getCaseBlob } from "../../../actions/azurestorage";
|
||||
import { hashAPIPath } from "../../../actions/core/hash";
|
||||
import { respondError, respondSuccess } from "../middleware/apiResponse";
|
||||
|
||||
const WEBAPI_URL =
|
||||
process.env.RELAY_ROOT ||
|
||||
"https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/";
|
||||
|
||||
export default async function ApiProxy(req, res) {
|
||||
const createCaseBody = req.body;
|
||||
const contactid = req.query.contactid;
|
||||
const appealTypeId = req.query.appealTypeId;
|
||||
const containerName = req.query.containername;
|
||||
const lpaID = req.query.lpaID;
|
||||
const queryUrl = "incidents";
|
||||
|
||||
if (!createCaseBody || typeof createCaseBody !== "object") {
|
||||
return respondError(res, {
|
||||
status: 400,
|
||||
code: "CASE_PAYLOAD_REQUIRED",
|
||||
message: "Case payload is required"
|
||||
});
|
||||
}
|
||||
if (typeof contactid !== "string" || contactid.trim().length === 0) {
|
||||
return respondError(res, {
|
||||
status: 400,
|
||||
code: "CONTACT_ID_REQUIRED",
|
||||
message: "contactid is required"
|
||||
});
|
||||
}
|
||||
if (typeof appealTypeId !== "string" || appealTypeId.trim().length === 0) {
|
||||
return respondError(res, {
|
||||
status: 400,
|
||||
code: "APPEAL_TYPE_ID_REQUIRED",
|
||||
message: "appealTypeId is required"
|
||||
});
|
||||
}
|
||||
if (
|
||||
typeof containerName !== "string" ||
|
||||
containerName.trim().length === 0
|
||||
) {
|
||||
return respondError(res, {
|
||||
status: 400,
|
||||
code: "CONTAINER_NAME_REQUIRED",
|
||||
message: "containername is required"
|
||||
});
|
||||
}
|
||||
if (typeof lpaID !== "string" || lpaID.trim().length === 0) {
|
||||
return respondError(res, {
|
||||
status: 400,
|
||||
code: "LPA_ID_REQUIRED",
|
||||
message: "lpaID is required"
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const token = await getToken();
|
||||
|
||||
const data = {
|
||||
"title": "insertion test case",
|
||||
"caseorigincode": 3,
|
||||
"servicestage": 1,
|
||||
"customerid_contact@odata.bind": "/contacts(" + contactid + ")",
|
||||
"pinswg_appealcasetype": appealTypeId,
|
||||
"pinswg_AssociatedLPA@odata.bind": "/accounts(" + lpaID + ")"
|
||||
};
|
||||
const newData = Object.assign(data, createCaseBody);
|
||||
|
||||
delete newData.lpaTypes;
|
||||
delete newData.appealTypes;
|
||||
|
||||
console.log("/////Create Case:\n", newData, "\n//////////////");
|
||||
|
||||
const config = {
|
||||
method: "post",
|
||||
url: WEBAPI_URL + queryUrl + hashAPIPath(queryUrl),
|
||||
headers: {
|
||||
"OData-MaxVersion": "4.0",
|
||||
"OData-Version": "4.0",
|
||||
"Accept": "application/json",
|
||||
"Prefer": 'odata.include-annotations="*",return=representation',
|
||||
"Authorization": "Bearer " + token.access_token,
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
data: JSON.stringify(newData)
|
||||
};
|
||||
|
||||
const { data: responseData } = await axios(config);
|
||||
await getCaseBlob(
|
||||
containerName,
|
||||
responseData.ticketnumber,
|
||||
createCaseBody
|
||||
);
|
||||
|
||||
return respondSuccess(res, responseData);
|
||||
} catch (error) {
|
||||
consoleLogger(error);
|
||||
return respondError(res, {
|
||||
status: 400,
|
||||
code: "CASE_CREATE_FAILED",
|
||||
message: "Failed to create case"
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,46 +1,3 @@
|
||||
/**
|
||||
* @swagger
|
||||
* /api/endpoint/createcase_api:
|
||||
* post:
|
||||
* tags: [Case]
|
||||
* description: Create case
|
||||
* summary: Phase 2
|
||||
* parameters:
|
||||
* - name: body
|
||||
* in: requestbody
|
||||
* required: true
|
||||
* example: {}
|
||||
* schema:
|
||||
* type: object
|
||||
* - name: contactid
|
||||
* in: query
|
||||
* required: true
|
||||
* example: pinswg_planningappeals78s
|
||||
* schema:
|
||||
* type: string
|
||||
* - name: appealTypeId
|
||||
* in: query
|
||||
* required: true
|
||||
* example: pinswg_planningappeals78id
|
||||
* schema:
|
||||
* type: string
|
||||
* - name: containername
|
||||
* in: query
|
||||
* required: true
|
||||
* example: pinswg_planningappeals78id
|
||||
* schema:
|
||||
* type: string
|
||||
* - name: lpaID
|
||||
* in: query
|
||||
* required: true
|
||||
* example: pinswg_planningappeals78id
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Success
|
||||
*/
|
||||
|
||||
import axios from "axios";
|
||||
import { isNonEmptyString, sanitizeString } from "../../../actions/core/guards";
|
||||
import { consoleLogger } from "../../../actions/core/logger";
|
||||
|
||||
@@ -4624,76 +4624,6 @@ test("getappealpdfdocuments catch path returns APPEAL_PDF_DOCUMENTS_FETCH_FAILED
|
||||
);
|
||||
});
|
||||
|
||||
test("createcase returns CASE_PAYLOAD_REQUIRED when body missing", async () => {
|
||||
const mod = loadModule("pages/api/endpoint/createcase_api.js", {
|
||||
respondError: respondErrorMock,
|
||||
respondSuccess: respondSuccessMock,
|
||||
getToken: async () => ({ access_token: "token" }),
|
||||
getCaseBlob: async () => {},
|
||||
hashAPIPath: () => "&hash=expected",
|
||||
axios: async () => ({ data: { ticketnumber: "CAS-1" } }),
|
||||
consoleLogger: () => {}
|
||||
});
|
||||
|
||||
const req = { query: {}, body: undefined };
|
||||
const res = createRes();
|
||||
await mod.default(req, res);
|
||||
|
||||
assert.strictEqual(res.state.statusCode, 400);
|
||||
assert.strictEqual(res.state.jsonBody.error.code, "CASE_PAYLOAD_REQUIRED");
|
||||
});
|
||||
|
||||
test("createcase returns CONTACT_ID_REQUIRED when contactid missing", async () => {
|
||||
const mod = loadModule("pages/api/endpoint/createcase_api.js", {
|
||||
respondError: respondErrorMock,
|
||||
respondSuccess: respondSuccessMock,
|
||||
getToken: async () => ({ access_token: "token" }),
|
||||
getCaseBlob: async () => {},
|
||||
hashAPIPath: () => "&hash=expected",
|
||||
axios: async () => ({ data: { ticketnumber: "CAS-1" } }),
|
||||
consoleLogger: () => {}
|
||||
});
|
||||
|
||||
const req = {
|
||||
query: { appealTypeId: "a1", containername: "c1", lpaID: "l1" },
|
||||
body: { title: "x" }
|
||||
};
|
||||
const res = createRes();
|
||||
await mod.default(req, res);
|
||||
|
||||
assert.strictEqual(res.state.statusCode, 400);
|
||||
assert.strictEqual(res.state.jsonBody.error.code, "CONTACT_ID_REQUIRED");
|
||||
});
|
||||
|
||||
test("createcase catch path returns CASE_CREATE_FAILED", async () => {
|
||||
const mod = loadModule("pages/api/endpoint/createcase_api.js", {
|
||||
respondError: respondErrorMock,
|
||||
respondSuccess: respondSuccessMock,
|
||||
getToken: async () => ({ access_token: "token" }),
|
||||
getCaseBlob: async () => {},
|
||||
hashAPIPath: () => "&hash=expected",
|
||||
axios: async () => {
|
||||
throw new Error("create failed");
|
||||
},
|
||||
consoleLogger: () => {}
|
||||
});
|
||||
|
||||
const req = {
|
||||
query: {
|
||||
contactid: "c1",
|
||||
appealTypeId: "a1",
|
||||
containername: "container",
|
||||
lpaID: "l1"
|
||||
},
|
||||
body: { title: "x" }
|
||||
};
|
||||
const res = createRes();
|
||||
await mod.default(req, res);
|
||||
|
||||
assert.strictEqual(res.state.statusCode, 400);
|
||||
assert.strictEqual(res.state.jsonBody.error.code, "CASE_CREATE_FAILED");
|
||||
});
|
||||
|
||||
test("updatecase returns CASE_UPDATE_PAYLOAD_REQUIRED when body missing", async () => {
|
||||
const mod = loadModule("pages/api/endpoint/updatecase_api.js", {
|
||||
respondError: respondErrorMock,
|
||||
@@ -4836,7 +4766,8 @@ test("gethash returns UNAUTHENTICATED when session missing", async () => {
|
||||
respondError: respondErrorMock,
|
||||
respondSuccess: respondSuccessMock,
|
||||
hashAPIPath: () => "&hash=expected",
|
||||
getSession: async () => null,
|
||||
getServerSession: async () => null,
|
||||
authOptions: () => ({}),
|
||||
nextConnect: () => {
|
||||
const handler = { registeredGet: null };
|
||||
handler.get = (cb) => {
|
||||
@@ -4860,7 +4791,10 @@ test("gethash returns INVALID_HASH_PATH when path is invalid", async () => {
|
||||
respondError: respondErrorMock,
|
||||
respondSuccess: respondSuccessMock,
|
||||
hashAPIPath: () => "&hash=expected",
|
||||
getSession: async () => ({ user: { email: "user@test.local" } }),
|
||||
getServerSession: async () => ({
|
||||
user: { email: "user@test.local" }
|
||||
}),
|
||||
authOptions: () => ({}),
|
||||
nextConnect: () => {
|
||||
const handler = { registeredGet: null };
|
||||
handler.get = (cb) => {
|
||||
|
||||
Reference in New Issue
Block a user