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

Closed
opened 2026-04-11 03:52:17 -05:00 by GiteaMirror · 0 comments
Owner

Original Pull Request: https://github.com/bitwarden/android/pull/6596

State: closed
Merged: Yes


🎟️ 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
**Original Pull Request:** https://github.com/bitwarden/android/pull/6596 **State:** closed **Merged:** Yes --- ## 🎟️ 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
GiteaMirror added the pull-request label 2026-04-11 03:52:17 -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#12848