TASK22269: delegate fileClient signed get/post to signedRequestClient
This commit is contained in:
@@ -1,17 +1,12 @@
|
|||||||
import { getJson, requestJson } from "./endpointClient";
|
import { getJson, requestJson } from "./endpointClient";
|
||||||
import { buildHashedQueryUrl } from "./relayClient";
|
import { getSignedJson, postSignedJson } from "./signedRequestClient";
|
||||||
|
|
||||||
export const getFileJson = (url) => {
|
export const getFileJson = (url) => {
|
||||||
return getJson(url);
|
return getJson(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSignedFileJson = async (queryUrl) => {
|
export const getSignedFileJson = async (queryUrl) => {
|
||||||
const signedUrl = await buildHashedQueryUrl(queryUrl);
|
return getSignedJson(queryUrl);
|
||||||
|
|
||||||
return requestJson({
|
|
||||||
method: "get",
|
|
||||||
url: signedUrl
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const downloadFileBlob = (url) => {
|
export const downloadFileBlob = (url) => {
|
||||||
@@ -23,12 +18,5 @@ export const downloadFileBlob = (url) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const postSignedFileJson = async (queryUrl, data, config = {}) => {
|
export const postSignedFileJson = async (queryUrl, data, config = {}) => {
|
||||||
const signedUrl = await buildHashedQueryUrl(queryUrl);
|
return postSignedJson(queryUrl, data, config);
|
||||||
|
|
||||||
return requestJson({
|
|
||||||
method: "post",
|
|
||||||
url: signedUrl,
|
|
||||||
data,
|
|
||||||
...config
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2801,3 +2801,34 @@ Validation:
|
|||||||
Follow-ups:
|
Follow-ups:
|
||||||
|
|
||||||
- Next bounded signed GET candidate in portal service is `sendRepCompleteMessage` (single signed URL + GET request path).
|
- Next bounded signed GET candidate in portal service is `sendRepCompleteMessage` (single signed URL + GET request path).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### CL-078: TASK22269 Slice B1.3 — fileClient signed helper delegation bundle
|
||||||
|
|
||||||
|
date: 2026-03-25
|
||||||
|
author: Cline
|
||||||
|
scope: `actions/clients/fileClient.js`, `tests/phase22/file-client-behaviour.test.cjs`
|
||||||
|
type: change
|
||||||
|
rationale: Continue grouped signed-request consolidation by reducing duplicate signing logic in `fileClient` and delegating signed GET/POST operations to shared `signedRequestClient` helpers.
|
||||||
|
impact: Centralizes signed method execution behavior in one helper layer and lowers drift risk across file-service call paths.
|
||||||
|
status: completed
|
||||||
|
|
||||||
|
Summary:
|
||||||
|
|
||||||
|
- Updated `actions/clients/fileClient.js`:
|
||||||
|
- replaced direct `buildHashedQueryUrl + requestJson` logic in:
|
||||||
|
- `getSignedFileJson` -> now delegates to `getSignedJson`
|
||||||
|
- `postSignedFileJson` -> now delegates to `postSignedJson`
|
||||||
|
- retained `downloadFileBlob` and `getFileJson` behavior unchanged.
|
||||||
|
- Updated `tests/phase22/file-client-behaviour.test.cjs` to assert delegation contracts for `getSignedJson` and `postSignedJson` rather than direct signing internals.
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
|
||||||
|
- `npm run lint` -> pass with warnings only (pre-existing `react-hooks/exhaustive-deps`; no new lint errors)
|
||||||
|
- `node tests/phase22/index.test.cjs` -> pass
|
||||||
|
- `node tests/phase7/service-behaviour.test.cjs` -> pass (13/13)
|
||||||
|
|
||||||
|
Follow-ups:
|
||||||
|
|
||||||
|
- Candidate map now indicates remaining explicit signed request composition is primarily in account/portal signed GET edge paths (`getPortalLogin`, `sendRepCompleteMessage`, and signed suffix append flow in `sendCaseCompleteMessage`) for future bounded slices.
|
||||||
|
|||||||
@@ -24,8 +24,11 @@ const loadFileClientModule = (injected = {}) => {
|
|||||||
requestJson: async () => {
|
requestJson: async () => {
|
||||||
throw new Error("requestJson not injected");
|
throw new Error("requestJson not injected");
|
||||||
},
|
},
|
||||||
buildHashedQueryUrl: async () => {
|
getSignedJson: async () => {
|
||||||
throw new Error("buildHashedQueryUrl not injected");
|
throw new Error("getSignedJson not injected");
|
||||||
|
},
|
||||||
|
postSignedJson: async () => {
|
||||||
|
throw new Error("postSignedJson not injected");
|
||||||
},
|
},
|
||||||
...injected
|
...injected
|
||||||
};
|
};
|
||||||
@@ -56,15 +59,10 @@ test("clients/fileClient getFileJson delegates to getJson", async () => {
|
|||||||
|
|
||||||
test("clients/fileClient getSignedFileJson signs url and requests json", async () => {
|
test("clients/fileClient getSignedFileJson signs url and requests json", async () => {
|
||||||
const signedCalls = [];
|
const signedCalls = [];
|
||||||
const requestCalls = [];
|
|
||||||
|
|
||||||
const mod = loadFileClientModule({
|
const mod = loadFileClientModule({
|
||||||
buildHashedQueryUrl: async (queryUrl) => {
|
getSignedJson: async (queryUrl) => {
|
||||||
signedCalls.push(queryUrl);
|
signedCalls.push(queryUrl);
|
||||||
return queryUrl + "&hash=signed";
|
|
||||||
},
|
|
||||||
requestJson: async (config) => {
|
|
||||||
requestCalls.push(config);
|
|
||||||
return { deleted: true };
|
return { deleted: true };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -77,11 +75,9 @@ test("clients/fileClient getSignedFileJson signs url and requests json", async (
|
|||||||
deleted: true
|
deleted: true
|
||||||
});
|
});
|
||||||
assert.strictEqual(signedCalls.length, 1);
|
assert.strictEqual(signedCalls.length, 1);
|
||||||
assert.strictEqual(requestCalls.length, 1);
|
|
||||||
assert.strictEqual(requestCalls[0].method, "get");
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
requestCalls[0].url,
|
signedCalls[0],
|
||||||
"/api/file/deleteblobcase?container=a&casefolderID=b&hash=signed"
|
"/api/file/deleteblobcase?container=a&casefolderID=b"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -106,15 +102,12 @@ test("clients/fileClient downloadFileBlob requests blob response", async () => {
|
|||||||
|
|
||||||
test("clients/fileClient postSignedFileJson signs url and posts payload", async () => {
|
test("clients/fileClient postSignedFileJson signs url and posts payload", async () => {
|
||||||
const signedCalls = [];
|
const signedCalls = [];
|
||||||
const requestCalls = [];
|
const postedCalls = [];
|
||||||
|
|
||||||
const mod = loadFileClientModule({
|
const mod = loadFileClientModule({
|
||||||
buildHashedQueryUrl: async (queryUrl) => {
|
postSignedJson: async (queryUrl, data, config) => {
|
||||||
signedCalls.push(queryUrl);
|
signedCalls.push(queryUrl);
|
||||||
return queryUrl + "&hash=signed-post";
|
postedCalls.push({ data, config });
|
||||||
},
|
|
||||||
requestJson: async (config) => {
|
|
||||||
requestCalls.push(config);
|
|
||||||
return { uploaded: true };
|
return { uploaded: true };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -132,18 +125,14 @@ test("clients/fileClient postSignedFileJson signs url and posts payload", async
|
|||||||
uploaded: true
|
uploaded: true
|
||||||
});
|
});
|
||||||
assert.strictEqual(signedCalls.length, 1);
|
assert.strictEqual(signedCalls.length, 1);
|
||||||
assert.strictEqual(requestCalls.length, 1);
|
assert.strictEqual(postedCalls.length, 1);
|
||||||
assert.strictEqual(requestCalls[0].method, "post");
|
assert.strictEqual(signedCalls[0], "/api/file/uploadsinglefile");
|
||||||
assert.strictEqual(
|
|
||||||
requestCalls[0].url,
|
|
||||||
"/api/file/uploadsinglefile&hash=signed-post"
|
|
||||||
);
|
|
||||||
assert.deepStrictEqual(
|
assert.deepStrictEqual(
|
||||||
JSON.parse(JSON.stringify(requestCalls[0].data)),
|
JSON.parse(JSON.stringify(postedCalls[0].data)),
|
||||||
payload
|
payload
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
requestCalls[0].headers["content-type"],
|
postedCalls[0].config.headers["content-type"],
|
||||||
"multipart/form-data"
|
"multipart/form-data"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user