Feature/511 Remove sensitivity and channel from legacy third party functionality - #691
Conversation
📝 WalkthroughWalkthroughThis pull request removes the ChangesThird-party subscription field removal
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🎭 Playwright E2E Test Results84 tests 52 ✅ 6m 1s ⏱️ Results for commit c895039. ♻️ This comment has been updated with latest results. |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
libs/subscriptions/src/repository/service.test.ts (1)
21-24: 💤 Low valueRemove unused
getLocationByIdfrom mock factory.The mock defines
getLocationByIdbut it's no longer imported (line 26) or used anywhere in this test file. Consider removing it for cleanliness.♻️ Proposed cleanup
vi.mock("`@hmcts/location`", () => ({ - getLocationById: vi.fn(), getLocationsByIds: vi.fn() }));libs/system-admin-pages/src/third-party-user/queries.test.ts (1)
128-144: ⚡ Quick winStrengthen transaction assertions for subscription updates.
These tests only check that
$transactionwas called, so they can miss regressions indeleteMany/createManypayloads (especially the removed fields contract). Assert the inner calls and exactcreateMany.datashape.Suggested test tightening
it("should delete existing subscriptions and create new ones", async () => { + const deleteMany = vi.fn(); + const createMany = vi.fn(); const mockTransaction = vi.fn(async (callback) => { return callback({ legacyThirdPartySubscription: { - deleteMany: vi.fn(), - createMany: vi.fn() + deleteMany, + createMany } }); }); vi.mocked(prisma.$transaction).mockImplementation(mockTransaction); const subscriptions = [{ listTypeId: 1 }, { listTypeId: 2 }]; await updateThirdPartySubscriptions("user-1", subscriptions); expect(prisma.$transaction).toHaveBeenCalled(); + expect(deleteMany).toHaveBeenCalledWith({ where: { userId: "user-1" } }); + expect(createMany).toHaveBeenCalledWith({ + data: [{ userId: "user-1", listTypeId: 1 }, { userId: "user-1", listTypeId: 2 }] + }); });Also applies to: 146-160
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0d96fe09-e472-4f52-95cc-1cee0514b5fe
📒 Files selected for processing (26)
apps/postgres/prisma/migrations/20260608155746_remove_channel_sensitivity_from_legacy_third_party_subscription/migration.sqllibs/legacy-third-party-fulfilment/src/queries.test.tslibs/legacy-third-party-fulfilment/src/queries.tslibs/legacy-third-party-fulfilment/src/service.tslibs/postgres-prisma/prisma/schema/base.prismalibs/subscriptions/src/repository/service.test.tslibs/system-admin-pages/src/pages/manage-third-party-subscriptions/cy.tslibs/system-admin-pages/src/pages/manage-third-party-subscriptions/en.tslibs/system-admin-pages/src/pages/manage-third-party-subscriptions/index.njklibs/system-admin-pages/src/pages/manage-third-party-subscriptions/index.test.tslibs/system-admin-pages/src/pages/manage-third-party-subscriptions/index.tslibs/system-admin-pages/src/pages/manage-third-party-user/cy.tslibs/system-admin-pages/src/pages/manage-third-party-user/en.tslibs/system-admin-pages/src/pages/manage-third-party-user/index.njklibs/system-admin-pages/src/pages/manage-third-party-user/index.test.tslibs/system-admin-pages/src/pages/manage-third-party-user/index.tslibs/system-admin-pages/src/pages/manage-third-party-users/cy.tslibs/system-admin-pages/src/pages/manage-third-party-users/en.tslibs/system-admin-pages/src/pages/manage-third-party-users/index.njklibs/system-admin-pages/src/pages/manage-third-party-users/index.test.tslibs/system-admin-pages/src/pages/manage-third-party-users/index.tslibs/system-admin-pages/src/third-party-user/queries.test.tslibs/system-admin-pages/src/third-party-user/queries.tslibs/system-admin-pages/src/third-party-user/validation.test.tslibs/system-admin-pages/src/third-party-user/validation.tslibs/system-admin-pages/src/user-management/validation.ts
💤 Files with no reviewable changes (7)
- libs/system-admin-pages/src/pages/manage-third-party-subscriptions/en.ts
- libs/system-admin-pages/src/user-management/validation.ts
- libs/system-admin-pages/src/third-party-user/validation.ts
- libs/system-admin-pages/src/pages/manage-third-party-users/index.njk
- libs/system-admin-pages/src/pages/manage-third-party-subscriptions/index.njk
- libs/postgres-prisma/prisma/schema/base.prisma
- libs/system-admin-pages/src/pages/manage-third-party-subscriptions/cy.ts
| const listTypeIds = Array.isArray(req.body.listTypes) ? req.body.listTypes.map(Number) : req.body.listTypes ? [Number(req.body.listTypes)] : []; | ||
| const listTypes = await findAllListTypes(); | ||
|
|
||
| const validationError = validateSensitivity(sensitivity); | ||
| if (validationError) { | ||
| return res.render("manage-third-party-subscriptions/index", { | ||
| ...content, | ||
| listTypes, | ||
| currentChannel: channel || "API", | ||
| currentSensitivity: sensitivity || "", | ||
| currentListTypeIds: listTypeIds, | ||
| errors: [{ ...validationError, text: content.sensitivityRequired }] | ||
| }); | ||
| } | ||
|
|
||
| const subscriptions = listTypeIds.map((listTypeId: number) => ({ | ||
| listTypeId, | ||
| channel: channel || "API", | ||
| sensitivity: sensitivity! | ||
| })); | ||
| const subscriptions = listTypeIds.map((listTypeId: number) => ({ listTypeId })); | ||
|
|
||
| await updateThirdPartySubscriptions(session.manageThirdPartyUser.userId, subscriptions); |
There was a problem hiding this comment.
Reject invalid listTypes values before DB update.
Number(...) can produce NaN (or out-of-domain IDs), and those values are sent straight to updateThirdPartySubscriptions, which can fail at persistence time and surface as a server error.
Suggested hardening
- const listTypeIds = Array.isArray(req.body.listTypes) ? req.body.listTypes.map(Number) : req.body.listTypes ? [Number(req.body.listTypes)] : [];
- const listTypes = await findAllListTypes();
+ const rawListTypeIds = Array.isArray(req.body.listTypes) ? req.body.listTypes : req.body.listTypes ? [req.body.listTypes] : [];
+ const parsedListTypeIds = rawListTypeIds.map((value: string) => Number(value));
+ const listTypes = await findAllListTypes();
+ const allowedListTypeIds = new Set(listTypes.map((listType) => listType.id));
+ const hasInvalidListType = parsedListTypeIds.some((id) => !Number.isInteger(id) || !allowedListTypeIds.has(id));
+ if (hasInvalidListType) {
+ return res.status(400).render("manage-third-party-subscriptions/index", {
+ ...(language === "cy" ? cy : en),
+ listTypes,
+ currentListTypeIds: session.manageThirdPartyUser.originalSubscriptions,
+ errors: [{ text: "Invalid list type selection" }]
+ });
+ }
+ const listTypeIds = parsedListTypeIds;As per coding guidelines: “All API endpoints must include input validation.”
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const listTypeIds = Array.isArray(req.body.listTypes) ? req.body.listTypes.map(Number) : req.body.listTypes ? [Number(req.body.listTypes)] : []; | |
| const listTypes = await findAllListTypes(); | |
| const validationError = validateSensitivity(sensitivity); | |
| if (validationError) { | |
| return res.render("manage-third-party-subscriptions/index", { | |
| ...content, | |
| listTypes, | |
| currentChannel: channel || "API", | |
| currentSensitivity: sensitivity || "", | |
| currentListTypeIds: listTypeIds, | |
| errors: [{ ...validationError, text: content.sensitivityRequired }] | |
| }); | |
| } | |
| const subscriptions = listTypeIds.map((listTypeId: number) => ({ | |
| listTypeId, | |
| channel: channel || "API", | |
| sensitivity: sensitivity! | |
| })); | |
| const subscriptions = listTypeIds.map((listTypeId: number) => ({ listTypeId })); | |
| await updateThirdPartySubscriptions(session.manageThirdPartyUser.userId, subscriptions); | |
| const rawListTypeIds = Array.isArray(req.body.listTypes) ? req.body.listTypes : req.body.listTypes ? [req.body.listTypes] : []; | |
| const parsedListTypeIds = rawListTypeIds.map((value: string) => Number(value)); | |
| const listTypes = await findAllListTypes(); | |
| const allowedListTypeIds = new Set(listTypes.map((listType) => listType.id)); | |
| const hasInvalidListType = parsedListTypeIds.some((id) => !Number.isInteger(id) || !allowedListTypeIds.has(id)); | |
| if (hasInvalidListType) { | |
| return res.status(400).render("manage-third-party-subscriptions/index", { | |
| ...(language === "cy" ? cy : en), | |
| listTypes, | |
| currentListTypeIds: session.manageThirdPartyUser.originalSubscriptions, | |
| errors: [{ text: "Invalid list type selection" }] | |
| }); | |
| } | |
| const listTypeIds = parsedListTypeIds; | |
| const subscriptions = listTypeIds.map((listTypeId: number) => ({ listTypeId })); | |
| await updateThirdPartySubscriptions(session.manageThirdPartyUser.userId, subscriptions); |
Source: Coding guidelines
| req.auditMetadata = { | ||
| shouldLog: true, | ||
| action: AuditLogAction.UPDATE_THIRD_PARTY_SUBSCRIPTIONS, | ||
| entityInfo: `ID: ${session.manageThirdPartyUser.userId}, Name: ${session.manageThirdPartyUser.userName}, Sensitivity: ${sensitivity}, Previous List Types: [${previousListTypes}], Current List Types: [${currentListTypes}]` | ||
| entityInfo: `ID: ${session.manageThirdPartyUser.userId}, Name: ${session.manageThirdPartyUser.userName}, Previous List Types: [${previousListTypes}], Current List Types: [${currentListTypes}]` | ||
| }; |
There was a problem hiding this comment.
Avoid logging user names in audit metadata.
entityInfo currently includes userName, which is personal data and should be excluded from logs.
Suggested change
- entityInfo: `ID: ${session.manageThirdPartyUser.userId}, Name: ${session.manageThirdPartyUser.userName}, Previous List Types: [${previousListTypes}], Current List Types: [${currentListTypes}]`
+ entityInfo: `ID: ${session.manageThirdPartyUser.userId}, Previous List Types: [${previousListTypes}], Current List Types: [${currentListTypes}]`As per coding guidelines: “Never include sensitive data in logs.”
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| req.auditMetadata = { | |
| shouldLog: true, | |
| action: AuditLogAction.UPDATE_THIRD_PARTY_SUBSCRIPTIONS, | |
| entityInfo: `ID: ${session.manageThirdPartyUser.userId}, Name: ${session.manageThirdPartyUser.userName}, Sensitivity: ${sensitivity}, Previous List Types: [${previousListTypes}], Current List Types: [${currentListTypes}]` | |
| entityInfo: `ID: ${session.manageThirdPartyUser.userId}, Name: ${session.manageThirdPartyUser.userName}, Previous List Types: [${previousListTypes}], Current List Types: [${currentListTypes}]` | |
| }; | |
| req.auditMetadata = { | |
| shouldLog: true, | |
| action: AuditLogAction.UPDATE_THIRD_PARTY_SUBSCRIPTIONS, | |
| entityInfo: `ID: ${session.manageThirdPartyUser.userId}, Previous List Types: [${previousListTypes}], Current List Types: [${currentListTypes}]` | |
| }; |
Source: Coding guidelines
Preview Deployment Successful 🚀Your preview environment is ready:
The environment will be automatically cleaned up when this PR is closed. |
…sensitivity-from-legacy-third-party # Conflicts: # apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.test.ts # apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.ts # apps/web/src/pages/(system-admin)/manage-third-party-user/index.test.ts # apps/web/src/pages/(system-admin)/manage-third-party-user/index.ts # apps/web/src/pages/(system-admin)/manage-third-party-users/index.test.ts # apps/web/src/pages/(system-admin)/manage-third-party-users/index.ts # libs/system-admin-pages/src/user-management/validation.ts
Preview Deployment Successful 🚀Your preview environment is ready:
The environment will be automatically cleaned up when this PR is closed. |
|
Preview Deployment Successful 🚀Your preview environment is ready:
The environment will be automatically cleaned up when this PR is closed. |
Resolved conflicts by taking master's removal of channel/sensitivity from legacy third-party subscriptions (PR #691) and adopting the `t` variable naming convention and `{% block content %}` template pattern. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>



Jira link
#511
Change description
Remove sensitivity and channel from legacy third party functionality
Testing done
Security Vulnerability Assessment
CVE Suppression: Are there any CVEs present in the codebase (either newly introduced or pre-existing) that are being intentionally suppressed or ignored by this commit?
Checklist
Summary by CodeRabbit