From bfbdc2bf478b8a196bc481e045c16708ff82707e Mon Sep 17 00:00:00 2001 From: Andrew Foote Date: Fri, 22 May 2026 11:58:05 -0400 Subject: [PATCH 1/2] Properly handling read-after-writes in registry user controller --- .../registry-user.controller.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/controller/registry-user.controller/registry-user.controller.js b/src/controller/registry-user.controller/registry-user.controller.js index 63445c2e0..65647ae08 100644 --- a/src/controller/registry-user.controller/registry-user.controller.js +++ b/src/controller/registry-user.controller/registry-user.controller.js @@ -387,9 +387,10 @@ async function updateUser (req, res, next) { } } - // UUID of the user will not change, lets get it before we write to avoid read after write issues. + // Move lookups of immutable properties BEFORE the transaction mutation writes to completely bypass read-after-write anomalies const requestingUserUUID = await userRepo.getUserUUID(req.ctx.user, req.ctx.org, { session }) - updatedUserUUID = await userRepo.getUserUUID(req.ctx.user, org.UUID) + updatedUserUUID = await userRepo.getUserUUID(req.ctx.user, org.UUID, { session }) + updatedUser = await userRepo.updateUserFull(userToEdit.UUID, body, { session }, true, requestingUserUUID) await session.commitTransaction() } catch (error) { @@ -456,7 +457,8 @@ async function deleteUser (req, res, next) { } async function grantRole (req, res, next) { - const session = await mongoose.startSession() + // Explicitly configuring causalConsistency flag for clear DocumentDB context documentation + const session = await mongoose.startSession({ causalConsistency: false }) try { const orgShortName = req.ctx.params.shortname const username = req.ctx.params.username @@ -519,7 +521,8 @@ async function grantRole (req, res, next) { } async function revokeRole (req, res, next) { - const session = await mongoose.startSession() + // Explicitly configuring causalConsistency flag for clear DocumentDB context documentation + const session = await mongoose.startSession({ causalConsistency: false }) try { const orgShortName = req.ctx.params.shortname const username = req.ctx.params.username @@ -595,4 +598,4 @@ module.exports = { DELETE_USER: deleteUser, GRANT_ROLE: grantRole, REVOKE_ROLE: revokeRole -} +} \ No newline at end of file From d67ce80e9f20cd4ce789c448e31531ae6f27ca57 Mon Sep 17 00:00:00 2001 From: Andrew Foote Date: Fri, 22 May 2026 12:04:27 -0400 Subject: [PATCH 2/2] Fixing linting issues from last commit --- .../registry-user.controller/registry-user.controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controller/registry-user.controller/registry-user.controller.js b/src/controller/registry-user.controller/registry-user.controller.js index 65647ae08..922bae908 100644 --- a/src/controller/registry-user.controller/registry-user.controller.js +++ b/src/controller/registry-user.controller/registry-user.controller.js @@ -390,7 +390,7 @@ async function updateUser (req, res, next) { // Move lookups of immutable properties BEFORE the transaction mutation writes to completely bypass read-after-write anomalies const requestingUserUUID = await userRepo.getUserUUID(req.ctx.user, req.ctx.org, { session }) updatedUserUUID = await userRepo.getUserUUID(req.ctx.user, org.UUID, { session }) - + updatedUser = await userRepo.updateUserFull(userToEdit.UUID, body, { session }, true, requestingUserUUID) await session.commitTransaction() } catch (error) { @@ -598,4 +598,4 @@ module.exports = { DELETE_USER: deleteUser, GRANT_ROLE: grantRole, REVOKE_ROLE: revokeRole -} \ No newline at end of file +}