[PR #6596] [MERGED] 🍒 [PM-32802] fix: 400 error when archiving/unarchiving org-owned ciphers #37205

Closed
opened 2026-04-21 04:16:39 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/bitwarden/android/pull/6596
Author: @SaintPatrck
Created: 2/27/2026
Status: Merged
Merged: 2/27/2026
Merged by: @SaintPatrck

Base: release/2026.2-rc47Head: release/2026.2-rc47_cp-pm-32802


📝 Commits (1)

  • 105dd35 🍒 [PM-32802] fix: 400 error when archiving/unarchiving org-owned ciphers

📊 Changes

8 files changed (+256 additions, -231 deletions)

View changed files

📝 app/src/main/kotlin/com/x8bit/bitwarden/data/vault/manager/CipherManagerImpl.kt (+41 -44)
📝 app/src/test/kotlin/com/x8bit/bitwarden/data/vault/manager/CipherManagerTest.kt (+48 -165)
📝 network/src/main/kotlin/com/bitwarden/network/api/CiphersApi.kt (+2 -2)
network/src/main/kotlin/com/bitwarden/network/model/ArchiveCipherResponseJson.kt (+33 -0)
network/src/main/kotlin/com/bitwarden/network/model/UnarchiveCipherResponseJson.kt (+33 -0)
📝 network/src/main/kotlin/com/bitwarden/network/service/CiphersService.kt (+4 -2)
📝 network/src/main/kotlin/com/bitwarden/network/service/CiphersServiceImpl.kt (+30 -6)
📝 network/src/test/kotlin/com/bitwarden/network/service/CiphersServiceTest.kt (+65 -12)

📄 Description

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-32802

🍒Cherry-picked to 2026.2-rc47 from #6592

📔 Objective

Fix a 400 error when users with restricted permissions ("can view, hidden passwords" or "can edit, hidden passwords") attempt to archive or unarchive org-owned ciphers.

Root cause: archiveCipher() and unarchiveCipher() in CipherManagerImpl unnecessarily called encryptCipherAndCheckForMigration() before the archive/unarchive API call. When the SDK generated a new cipher key (migration), this triggered a full PUT /api/ciphers/{id} update that the server rejected with HTTP 400 for users lacking edit permissions — aborting the archive before it was ever attempted.

Fix: Remove the encryption/migration check from archive and unarchive flows entirely. These operations now call the archive/unarchive API directly and upsert the server-returned cipher to disk, following the existing restoreCipher pattern. The server handles all state changes; no client-side encryption is needed.

Changes:

  • CiphersApi — Archive/unarchive return SyncResponseJson.Cipher instead of Unit
  • CiphersService/Impl — Return typed ArchiveCipherResponseJson / UnarchiveCipherResponseJson with 400 error recovery
  • CipherManagerImpl — Remove encryptCipherAndCheckForMigration from archive/unarchive; upsert server response directly
  • Response models — Add ArchiveCipherResponseJson and UnarchiveCipherResponseJson sealed classes
  • Tests — Updated CipherManagerTest and CiphersServiceTest to match new behavior

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/bitwarden/android/pull/6596 **Author:** [@SaintPatrck](https://github.com/SaintPatrck) **Created:** 2/27/2026 **Status:** ✅ Merged **Merged:** 2/27/2026 **Merged by:** [@SaintPatrck](https://github.com/SaintPatrck) **Base:** `release/2026.2-rc47` ← **Head:** `release/2026.2-rc47_cp-pm-32802` --- ### 📝 Commits (1) - [`105dd35`](https://github.com/bitwarden/android/commit/105dd35d7e5940415c515d6b97fa5e7c9cce3b5d) 🍒 [PM-32802] fix: 400 error when archiving/unarchiving org-owned ciphers ### 📊 Changes **8 files changed** (+256 additions, -231 deletions) <details> <summary>View changed files</summary> 📝 `app/src/main/kotlin/com/x8bit/bitwarden/data/vault/manager/CipherManagerImpl.kt` (+41 -44) 📝 `app/src/test/kotlin/com/x8bit/bitwarden/data/vault/manager/CipherManagerTest.kt` (+48 -165) 📝 `network/src/main/kotlin/com/bitwarden/network/api/CiphersApi.kt` (+2 -2) ➕ `network/src/main/kotlin/com/bitwarden/network/model/ArchiveCipherResponseJson.kt` (+33 -0) ➕ `network/src/main/kotlin/com/bitwarden/network/model/UnarchiveCipherResponseJson.kt` (+33 -0) 📝 `network/src/main/kotlin/com/bitwarden/network/service/CiphersService.kt` (+4 -2) 📝 `network/src/main/kotlin/com/bitwarden/network/service/CiphersServiceImpl.kt` (+30 -6) 📝 `network/src/test/kotlin/com/bitwarden/network/service/CiphersServiceTest.kt` (+65 -12) </details> ### 📄 Description ## 🎟️ Tracking https://bitwarden.atlassian.net/browse/PM-32802 🍒Cherry-picked to `2026.2-rc47` from #6592 ## 📔 Objective Fix a 400 error when users with restricted permissions ("can view, hidden passwords" or "can edit, hidden passwords") attempt to archive or unarchive org-owned ciphers. **Root cause:** `archiveCipher()` and `unarchiveCipher()` in `CipherManagerImpl` unnecessarily called `encryptCipherAndCheckForMigration()` before the archive/unarchive API call. When the SDK generated a new cipher key (migration), this triggered a full `PUT /api/ciphers/{id}` update that the server rejected with HTTP 400 for users lacking edit permissions — aborting the archive before it was ever attempted. **Fix:** Remove the encryption/migration check from archive and unarchive flows entirely. These operations now call the archive/unarchive API directly and upsert the server-returned cipher to disk, following the existing `restoreCipher` pattern. The server handles all state changes; no client-side encryption is needed. **Changes:** - **CiphersApi** — Archive/unarchive return `SyncResponseJson.Cipher` instead of `Unit` - **CiphersService/Impl** — Return typed `ArchiveCipherResponseJson` / `UnarchiveCipherResponseJson` with 400 error recovery - **CipherManagerImpl** — Remove `encryptCipherAndCheckForMigration` from archive/unarchive; upsert server response directly - **Response models** — Add `ArchiveCipherResponseJson` and `UnarchiveCipherResponseJson` sealed classes - **Tests** — Updated CipherManagerTest and CiphersServiceTest to match new behavior --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-21 04:16:40 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/android#37205