/** * @swagger * /api/endpoint/deleteamywatchedcases_api: * delete: * tags: [Portal,Case] * summary: Phase 2 * description: Delete my watched cases * responses: * 200: * description: Success */ import axios from "axios"; import { getServerSession } from "next-auth/next"; import { azureHeaders } from "../../../actions/core/headers"; import { escapeODataString } from "../../../actions/core/guards"; import { consoleLogger } from "../../../actions/core/logger"; import { getToken } from "../../../actions/core/token"; import { hashAPIPath } from "../../../actions/core/hash"; import { authOptions } from "../auth/[...nextauth]"; import { respondError, respondSuccess } from "../middleware/apiResponse"; import { relayGetData } from "../middleware/relayForwarding"; const WEBAPI_URL = process.env.RELAY_ROOT || "https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/"; 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 normaliseGuid = (value) => value.trim().toLowerCase(); export default async function ApiProxy(req, res) { const watchedCaseID = req.query.watchedCaseID; if ( typeof watchedCaseID !== "string" || !GUID_PATTERN.test(watchedCaseID) ) { return respondError(res, { status: 400, code: "INVALID_WATCHED_CASE_ID", message: "watchedCaseID must be a valid GUID" }); } if (req.method !== "DELETE") { return respondError(res, { status: 405, code: "METHOD_NOT_ALLOWED", message: "Only DELETE is supported" }); } const session = await getServerSession(req, res, authOptions(req, res)); const authenticatedEmail = session?.user?.email; if ( typeof authenticatedEmail !== "string" || authenticatedEmail.trim().length === 0 ) { return respondError(res, { status: 401, code: "UNAUTHENTICATED", message: "Authentication required" }); } try { const token = await getToken(); const requestOptionsBuilder = (accessToken) => azureHeaders(accessToken); const escapedEmail = escapeODataString(authenticatedEmail); const contactQueryUrl = "contacts?$filter=emailaddress1 eq '" + escapedEmail + "' and statuscode eq 1&$select=contactid"; const contactResponse = await relayGetData({ queryUrl: contactQueryUrl, accessToken: token.access_token, requestOptionsBuilder }); const contacts = contactResponse?.data?.value; if (!Array.isArray(contacts)) { return respondError(res, { status: 500, code: "CONTACT_LOOKUP_FAILED", message: "Unable to verify portal contact" }); } if ( 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" }); } const normalisedWatchedCaseID = normaliseGuid(watchedCaseID); const watchlistQueryUrl = "pinswg_watchlists(" + normalisedWatchedCaseID + ")?$select=pinswg_watchlistid,_pinswg_contact_value"; let watchlistResponse; try { watchlistResponse = await relayGetData({ queryUrl: watchlistQueryUrl, accessToken: token.access_token, requestOptionsBuilder }); } catch (error) { if (error?.response?.status === 404) { return respondError(res, { status: 404, code: "WATCHED_CASE_NOT_FOUND", message: "Watched case not found" }); } throw error; } const watchlist = watchlistResponse?.data; const watchlistContactID = watchlist?._pinswg_contact_value; const watchlistRecordID = watchlist?.pinswg_watchlistid; if ( typeof watchlistRecordID !== "string" || !GUID_PATTERN.test(watchlistRecordID.trim()) || normaliseGuid(watchlistRecordID) !== normalisedWatchedCaseID || typeof watchlistContactID !== "string" || !GUID_PATTERN.test(watchlistContactID.trim()) || normaliseGuid(watchlistContactID) !== normaliseGuid(contacts[0].contactid) ) { return respondError(res, { status: 404, code: "WATCHED_CASE_NOT_FOUND", message: "Watched case not found" }); } const queryUrl = "pinswg_watchlists(" + normalisedWatchedCaseID + ")"; const config = { method: "delete", 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" } }; const { data } = await axios(config); return respondSuccess(res, data); } catch (error) { consoleLogger(error); return respondError(res, { status: 500, code: "WATCHED_CASE_DELETE_FAILED", message: "Failed to delete watched case" }); } }