Skip to content

Check seat count when unarchiving a vault#432

Open
tobihagemann wants to merge 14 commits intodevelopfrom
feature/check-seats-on-unarchive
Open

Check seat count when unarchiving a vault#432
tobihagemann wants to merge 14 commits intodevelopfrom
feature/check-seats-on-unarchive

Conversation

@tobihagemann
Copy link
Copy Markdown
Member

@tobihagemann tobihagemann commented Mar 27, 2026

When unarchiving a vault, the seat count was not validated against the license limit. Unarchiving restores access for all vault members, which can push the effective seat count beyond the licensed limit.

This adds a seat check on the archive-to-active transition in setArchived (PUT /vaults/{vaultId}/archived). The check reuses the existing usersSeatedOnOtherVaults pattern from setDirectMembers to project the seat count after unarchive. If the limit would be exceeded, PaymentRequiredException (402) is thrown before any mutation.

createOrUpdate (PUT /vaults/{vaultId}) no longer handles the archived field at all. Archive state is exclusively managed through the dedicated endpoint.

All seat-limit checks across VaultResource now use a shared ensureSeatsNotExceeded helper.

Frontend: ReactivateVaultDialog has been removed. The reactivation action is now inlined directly in VaultDetails, with a 402-specific error message shown inline when the seat limit would be exceeded.

Closes #431.

@tobihagemann tobihagemann assigned SailReal and unassigned SailReal Mar 27, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

Warning

Rate limit exceeded

@tobihagemann has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 48 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 16 minutes and 48 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9ed1d9fc-c1a2-482d-aee2-0f409fb48039

📥 Commits

Reviewing files that changed from the base of the PR and between 28fa136 and a63d0e4.

📒 Files selected for processing (1)
  • frontend/src/components/VaultDetails.vue

Walkthrough

A new private helper ensureSeatsNotExceeded(long occupiedSeats) centralizes seat-limit checks in VaultResource. Unarchiving via setArchived now projects effective occupied seats (including resolved group members and users seated elsewhere) and returns HTTP 402 if the licensed seat limit would be exceeded. createOrUpdate ignores the archived field in DTOs. Several access flows (addUser, addGroup, grantAccess, unlock, legacyUnlock, setDirectMembers) were updated to call the helper. Frontend, tests, and i18n were updated to handle 402 and the ReactivateVaultDialog component was removed.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • SailReal
  • overheadhunter
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: enforcing seat count validation when unarchiving a vault, which is the core objective of the PR.
Description check ✅ Passed The description clearly explains the problem, the solution, and the scope of changes across backend and frontend components, all directly related to the changeset.
Linked Issues check ✅ Passed All acceptance criteria from #431 are met: seat validation on unarchive via setArchived endpoint is implemented, 402 is thrown when limit exceeded, and no check on archiving is enforced.
Out of Scope Changes check ✅ Passed All changes are directly scoped to #431: backend seat validation, frontend dialog removal, and related refactoring. The consolidation of seat checks via ensureSeatsNotExceeded helper is a reasonable supporting change.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/check-seats-on-unarchive

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/src/main/java/org/cryptomator/hub/api/VaultResource.java`:
- Around line 529-537: Add the same unarchive seat-check used in the PATCH
handler into createOrUpdate(): extract the logic in VaultResource that checks if
(wasArchived && !archived) and counts occupied seats via
effectiveVaultAccessRepo.countSeatOccupyingUsers(), throwing
PaymentRequiredException when occupiedSeats > license.getEntitlements().seats(),
into a helper (e.g., ensureSeatLimitAfterUnarchive) and invoke it in
createOrUpdate() immediately after vaultRepo.persistAndFlush(vault) for
existing-vault updates so unarchiving via PUT /vaults/{vaultId} enforces the
same seat validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9790dfd3-51f7-442d-b649-aab1238f111d

📥 Commits

Reviewing files that changed from the base of the PR and between 445fb27 and 7f8a573.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • backend/src/main/java/org/cryptomator/hub/api/VaultResource.java
  • backend/src/test/java/org/cryptomator/hub/api/ExceedingLicenseLimitsIT.java
  • frontend/src/common/backend.ts
  • frontend/src/components/ReactivateVaultDialog.vue
  • frontend/src/i18n/en-US.json

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
backend/src/main/java/org/cryptomator/hub/api/VaultResource.java (1)

562-567: ⚠️ Potential issue | 🟠 Major

createOrUpdate still has an unarchive bypass without seat validation.

Line 562 can unarchive an existing vault via PUT /vaults/{vaultId}, but there is no post-flush wasArchived && !archived check here. This bypasses the new 402 enforcement in setArchived.

🔧 Suggested fix
 public Response createOrUpdate(`@PathParam`("vaultId") UUID vaultId, `@Valid` `@NotNull` VaultDto vaultDto) {
 	User currentUser = userRepo.findById(jwt.getSubject());
 	Optional<Vault> existingVault = vaultRepo.findByIdOptional(vaultId);
 	final Vault vault;
+	final boolean wasArchived;
 	if (existingVault.isPresent()) {
 		// load existing vault:
 		vault = existingVault.get();
+		wasArchived = vault.isArchived();
 	} else {
 		//if license is exceeded block vault creation, independent if the user is already sitting
 		ensureSeatsNotExceeded(effectiveVaultAccessRepo.countSeatOccupyingUsers());
 		// create new vault:
 		vault = new Vault();
 		vault.setId(vaultDto.id);
 		vault.setCreationTime(Instant.now().truncatedTo(ChronoUnit.MILLIS));
+		wasArchived = false;
 	}
 	// set regardless of whether vault is new or existing:
 	vault.setName(vaultDto.name);
 	vault.setDescription(vaultDto.description);
 	vault.setArchived(existingVault.isEmpty() ? false : vaultDto.archived);
 	var oldEmergencyKeyShares = vault.getEmergencyKeyShares().values();
 	vault.setRequiredEmergencyKeyShares(vaultDto.requiredEmergencyKeyShares);
 	vault.setEmergencyKeyShares(vaultDto.emergencyKeyShares);

 	vaultRepo.persistAndFlush(vault); // trigger PersistenceException before we continue with
+	if (existingVault.isPresent() && wasArchived && !vault.isArchived()) {
+		ensureSeatsNotExceeded(effectiveVaultAccessRepo.countSeatOccupyingUsers());
+	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/main/java/org/cryptomator/hub/api/VaultResource.java` around
lines 562 - 567, The createOrUpdate flow in VaultResource currently calls
vault.setArchived(...) and then vaultRepo.persistAndFlush(vault) without
enforcing the post-flush check that prevents unarchiving without seat
validation; update the createOrUpdate method to detect an unarchive transition
(capture prior wasArchived from existingVault and new archived flag) after
persisting and, if wasArchived && !archived, invoke the same enforcement path
used elsewhere (e.g., call the existing setArchived validation or the
402/seat-validation logic) to reject or handle the unarchive accordingly before
returning; reference createOrUpdate, vault.setArchived(...),
vaultRepo.persistAndFlush(vault) and the wasArchived && !archived check when
making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@backend/src/main/java/org/cryptomator/hub/api/VaultResource.java`:
- Around line 562-567: The createOrUpdate flow in VaultResource currently calls
vault.setArchived(...) and then vaultRepo.persistAndFlush(vault) without
enforcing the post-flush check that prevents unarchiving without seat
validation; update the createOrUpdate method to detect an unarchive transition
(capture prior wasArchived from existingVault and new archived flag) after
persisting and, if wasArchived && !archived, invoke the same enforcement path
used elsewhere (e.g., call the existing setArchived validation or the
402/seat-validation logic) to reject or handle the unarchive accordingly before
returning; reference createOrUpdate, vault.setArchived(...),
vaultRepo.persistAndFlush(vault) and the wasArchived && !archived check when
making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d280d0c1-1e8c-40a0-ac20-054a61effa5c

📥 Commits

Reviewing files that changed from the base of the PR and between 7f8a573 and b878a2b.

📒 Files selected for processing (1)
  • backend/src/main/java/org/cryptomator/hub/api/VaultResource.java

@tobihagemann tobihagemann requested a review from SailReal March 27, 2026 13:48
Comment on lines +569 to +572
// flush first so countSeatOccupyingUsers sees the unarchived vault; @Transactional rolls back on exception
if (wasArchived && !vaultDto.archived) {
ensureSeatsNotExceeded(effectiveVaultAccessRepo.countSeatOccupyingUsers());
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a different query that simulates seat count instead of looking at the status quo. Need to look it up when I am back on my computer. Just fyi that the "change, check, rollback" approach isn't necessary.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 0cf8232. Added a countSeatOccupyingUsersIfVaultUnarchived query that uses (NOT v.archived OR v.id = :vaultId) to simulate the seat count before any mutation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the check I was talking about:

// resolve group members and simulate new seat count:
var effectiveUsers = new HashSet<User>();
effectiveUsers.addAll(userRepo.getEffectiveGroupUsers(memberRoles.keySet()));
effectiveUsers.addAll(userRepo.findByIds(memberRoles.keySet()).toList());
var newSeatOccupyingUsers = new HashSet<>(effectiveVaultAccessRepo.usersSeatedOnOtherVaults(vaultId).toList()); // initialize with users already having access to other vaults
newSeatOccupyingUsers.addAll(effectiveUsers.stream().map(User::getId).toList()); // add all users that will have access to this vault after the operation (avoid double counting by using a set)
if (newSeatOccupyingUsers.size() > license.getEntitlements().seats()) {
throw new PaymentRequiredException("License seats exceeded. Cannot add more users.");
}

The approach here is "get seat count in other vaults + check overlap with this vault". The difference of both sets is the number of additional seats required.

Always try reusing existing queries, only add new queries (or logic in general), if efficiency gains are significant. Otherwise, favour code reuse (or even deduplication) for improved maintainability. When in doubt, ask a human 😉

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Damn. I can't read minds after all.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5708a66. Replaced countSeatOccupyingUsersIfVaultUnarchived with the usersSeatedOnOtherVaults pattern and removed the custom query. Also made createOrUpdate ignore the archived flag entirely, so unarchiving is only possible through the dedicated endpoint.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/src/main/java/org/cryptomator/hub/api/VaultResource.java`:
- Around line 274-276: The code currently enforces seat limits even for archived
vaults by unconditionally adding +1 in the branch using
effectiveVaultAccessRepo.isUserOccupyingSeat and ensureSeatsNotExceeded; change
the conditional to skip the ensureSeatsNotExceeded call for archived vaults by
guarding it with !vault.isArchived() so that
ensureSeatsNotExceeded(effectiveVaultAccessRepo.countSeatOccupyingUsers() + 1)
only runs when the vault is not archived (use vault.isArchived() together with
effectiveVaultAccessRepo.isUserOccupyingSeat to decide).
- Around line 547-548: The preflight license check uses
effectiveVaultAccessRepo.countSeatOccupyingUsers() but omits the creator being
added as OWNER, so a creation can exceed the license; before calling
ensureSeatsNotExceeded, account for the creator's seat by incrementing the
counted seats when the creator is not already a seat-occupying user (or call
ensureSeatsNotExceeded with an extraSeatsNeeded=1); locate the branch that adds
OWNER access for currentUser (the code around where OWNER access is added, e.g.,
the method adding OWNER for currentUser) and change the preflight to include
that extra seat when the creator would become a new seat-occupying user.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7788046a-a3d5-4e0a-a2ed-1bb5d4535fa2

📥 Commits

Reviewing files that changed from the base of the PR and between 0cf8232 and e2c54bc.

📒 Files selected for processing (1)
  • backend/src/main/java/org/cryptomator/hub/api/VaultResource.java

Archived vaults don't contribute to seat counts (HQL queries filter
NOT v.archived), so enforcing seat limits on addUser, addGroup,
setDirectMembers, and grantAccess for archived vaults can produce
false 402 rejections when the license is at capacity.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
backend/src/main/java/org/cryptomator/hub/api/VaultResource.java (2)

241-241: ⚠️ Potential issue | 🟠 Major

Skip seat checks while the vault is archived.

These branches still return 402 on archived vaults once the license is full, which blocks preparing members or tokens before reactivation and moves enforcement away from setArchived().

💡 Suggested direction
-		ensureSeatsNotExceeded(newSeatOccupyingUsers.size());
+		if (!vault.isArchived()) {
+			ensureSeatsNotExceeded(newSeatOccupyingUsers.size());
+		}

-		if (!effectiveVaultAccessRepo.isUserOccupyingSeat(userId)) {
+		if (!vault.isArchived() && !effectiveVaultAccessRepo.isUserOccupyingSeat(userId)) {
 			ensureSeatsNotExceeded(effectiveVaultAccessRepo.countSeatOccupyingUsers() + 1);
 		}

-		ensureSeatsNotExceeded(userRepo.countEffectiveGroupUsers(groupId) - effectiveVaultAccessRepo.countSeatOccupyingUsersOfGroup(groupId) + effectiveVaultAccessRepo.countSeatOccupyingUsers());
+		if (!vault.isArchived()) {
+			ensureSeatsNotExceeded(userRepo.countEffectiveGroupUsers(groupId) - effectiveVaultAccessRepo.countSeatOccupyingUsersOfGroup(groupId) + effectiveVaultAccessRepo.countSeatOccupyingUsers());
+		}

-		ensureSeatsNotExceeded(occupiedSeats + usersWithoutSeat);
+		if (!vault.isArchived()) {
+			ensureSeatsNotExceeded(occupiedSeats + usersWithoutSeat);
+		}

Also applies to: 274-276, 299-299, 475-475

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/main/java/org/cryptomator/hub/api/VaultResource.java` at line
241, Skip calling ensureSeatsNotExceeded when the vault is archived: wrap the
ensureSeatsNotExceeded(newSeatOccupyingUsers.size()) call in a guard that checks
vault.isArchived() (e.g. if (!vault.isArchived()) ensureSeatsNotExceeded(...)),
and apply the same archival guard around the other ensureSeatsNotExceeded
invocations referenced (the occurrences around the 274-276, 299, and 475 spots)
so seat enforcement is bypassed for archived vaults and remains enforced only
for active ones.

559-559: ⚠️ Potential issue | 🟠 Major

Count the creator's seat before allowing vault creation.

If the installation is exactly at the seat cap and currentUser is not already seated, this preflight passes and the OWNER access added later pushes the system one seat over the license.

💡 Suggested fix
-			ensureSeatsNotExceeded(effectiveVaultAccessRepo.countSeatOccupyingUsers());
+			long projectedSeats = effectiveVaultAccessRepo.countSeatOccupyingUsers()
+					+ (effectiveVaultAccessRepo.isUserOccupyingSeat(currentUser.getId()) ? 0 : 1);
+			ensureSeatsNotExceeded(projectedSeats);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/main/java/org/cryptomator/hub/api/VaultResource.java` at line
559, The preflight seat check calls
ensureSeatsNotExceeded(effectiveVaultAccessRepo.countSeatOccupyingUsers()) but
fails to account for the creator becoming an OWNER; modify the creation
preflight to include the creator's seat if they are not already counted:
determine whether currentUser is already a seat-occupying user (e.g., via
effectiveVaultAccessRepo.isSeatOccupier(currentUser) or equivalent) and if not,
add 1 to effectiveVaultAccessRepo.countSeatOccupyingUsers() before calling
ensureSeatsNotExceeded so the OWNER added later cannot push the system over the
license.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@backend/src/main/java/org/cryptomator/hub/api/VaultResource.java`:
- Line 241: Skip calling ensureSeatsNotExceeded when the vault is archived: wrap
the ensureSeatsNotExceeded(newSeatOccupyingUsers.size()) call in a guard that
checks vault.isArchived() (e.g. if (!vault.isArchived())
ensureSeatsNotExceeded(...)), and apply the same archival guard around the other
ensureSeatsNotExceeded invocations referenced (the occurrences around the
274-276, 299, and 475 spots) so seat enforcement is bypassed for archived vaults
and remains enforced only for active ones.
- Line 559: The preflight seat check calls
ensureSeatsNotExceeded(effectiveVaultAccessRepo.countSeatOccupyingUsers()) but
fails to account for the creator becoming an OWNER; modify the creation
preflight to include the creator's seat if they are not already counted:
determine whether currentUser is already a seat-occupying user (e.g., via
effectiveVaultAccessRepo.isSeatOccupier(currentUser) or equivalent) and if not,
add 1 to effectiveVaultAccessRepo.countSeatOccupyingUsers() before calling
ensureSeatsNotExceeded so the OWNER added later cannot push the system over the
license.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 06c34074-f439-4e57-b3e0-41957ec301ca

📥 Commits

Reviewing files that changed from the base of the PR and between 24bcf70 and 18399ef.

📒 Files selected for processing (4)
  • backend/src/main/java/org/cryptomator/hub/api/VaultResource.java
  • backend/src/test/java/org/cryptomator/hub/api/ExceedingLicenseLimitsIT.java
  • backend/src/test/java/org/cryptomator/hub/api/VaultResourceIT.java
  • frontend/src/i18n/en-US.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/i18n/en-US.json
  • backend/src/test/java/org/cryptomator/hub/api/ExceedingLicenseLimitsIT.java

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/VaultDetails.vue`:
- Around line 509-520: The post-success call to refreshLicense() in
reactivateVault can throw unhandled rejections; wrap refreshLicense() in its own
try/catch (or include it in the existing try) so any failure after successful
backend.vaults.setArchived and refreshVault is caught and handled: catch the
error, console.error it, and set onReactivateError.value appropriately (similar
to the existing catch) to surface the error to the UI; ensure references to
reactivateVault, onReactivateError, backend.vaults.setArchived, refreshVault,
and refreshLicense are used so the change is made in the correct function.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6928cfa2-dfe1-4f41-ab47-97180cd2e5e2

📥 Commits

Reviewing files that changed from the base of the PR and between 18399ef and 572158a.

📒 Files selected for processing (3)
  • frontend/src/components/ReactivateVaultDialog.vue
  • frontend/src/components/VaultDetails.vue
  • frontend/src/i18n/en-US.json
💤 Files with no reviewable changes (1)
  • frontend/src/components/ReactivateVaultDialog.vue
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/i18n/en-US.json

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/VaultDetails.vue`:
- Around line 225-232: The template introduces a new i18n key
t('vaultDetails.error.reactivateFailed') which may be missing in non-en locales;
either add the key to all locale files or replace the new key with an existing
translated key to avoid raw keys showing. Locate VaultDetails.vue where
t('vaultDetails.error.reactivateFailed') is used (the onReactivateError
conditional alongside PaymentRequiredError) and either (A) add the key
"vaultDetails.error.reactivateFailed" with appropriate translations to each
locale file, or (B) change the call to reuse an existing key (for example an
existing vault/error or common key used for similar messages) so all locales
already cover it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5a40b147-155c-496c-8b62-abf57567da77

📥 Commits

Reviewing files that changed from the base of the PR and between 572158a and 28fa136.

📒 Files selected for processing (1)
  • frontend/src/components/VaultDetails.vue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Check seat count when unarchiving a vault

3 participants