Overview
RolesService.updateRole() performs three sequential operations with no transaction: roleRepository.update(id, { name, description }), then a relation .set(permissions) through the query builder, then a findOne to return the result. A failure between the first and second leaves the role renamed but still holding its previous permission set — a security-relevant divergence, since the role's name is what administrators reason about when granting it. Because the relation .set() replaces the entire permission collection, a partially-applied update can also leave the role with no permissions at all if the set operation fails after clearing.
Specifications
Features:
- Role metadata and permission assignment are updated atomically.
- A concurrent update cannot interleave with the permission replacement.
Tasks:
- Wrap all three operations in
dataSource.transaction, using the transactional manager throughout.
- Take a row lock on the role at the start of the transaction so concurrent updates serialize.
- Throw
NotFoundException inside the transaction when the role does not exist, rather than after the writes.
- Invalidate the RBAC permission cache only after the transaction commits.
- Add a test that forces the permission set to fail and asserts the name change is rolled back.
Impacted Files:
src/rbac/roles/roles.service.ts
Acceptance Criteria
- A failure during permission reassignment rolls back the name and description change.
- Concurrent updates to one role do not interleave.
- Cache invalidation happens only after commit.
Overview
RolesService.updateRole()performs three sequential operations with no transaction:roleRepository.update(id, { name, description }), then a relation.set(permissions)through the query builder, then afindOneto return the result. A failure between the first and second leaves the role renamed but still holding its previous permission set — a security-relevant divergence, since the role's name is what administrators reason about when granting it. Because the relation.set()replaces the entire permission collection, a partially-applied update can also leave the role with no permissions at all if the set operation fails after clearing.Specifications
Features:
Tasks:
dataSource.transaction, using the transactional manager throughout.NotFoundExceptioninside the transaction when the role does not exist, rather than after the writes.Impacted Files:
src/rbac/roles/roles.service.tsAcceptance Criteria