1
0
mirror of https://github.com/bitwarden/server synced 2026-01-16 23:43:22 +00:00
Files
server/src/Core/Vault/Commands/UnarchiveCiphersCommand.cs
Jordan Aasen 02c03f4493 [PM-27884][PM-27886][PM-27885] - Add Cipher Archives (#6578)
* add Archives column to ciphers table

* add archives column

* update cipher archive/unarchive and cipher deatils query

* add migrations

* add missing migrations

* fixes

* update tests. cleanup

* syntax fix

* fix sql syntax

* fix sql

* fix CreateWithCollections

* fix sql

* fix migration file

* fix migration

* add go

* add missing go

* fix migrations

* add missing proc

* fix migrations

* implement claude suggestions

* fix test

* update cipher service and tests

* updates to soft delete

* update UserCipherDetailsQuery and migration

* update migration

* update archive ciphers command to allow org ciphers to be archived

* updates to archivedDate

* revert change to UserCipherDetails

* updates to migration and procs

* remove archivedDate from Cipher_CreateWithCollections

* remove trailing comma

* fix syntax errors

* fix migration

* add double quotes around datetime

* fix syntax error

* remove archivedDate from cipher entity

* re-add ArchivedDate into cipher

* fix migration

* do not set Cipher.ArchivedDate in CipherRepository

* re-add ArchivedDate until removed from the db

* set defaults

* change to CREATE OR ALTER

* fix migration

* fix migration file

* quote datetime

* fix existing archiveAsync test. add additional test

* quote datetime

* update migration

* do not wrap datetime in quotes

* do not wrap datetime in quotes

* fix migration

* clean up archives and archivedDate from procs

* fix UserCipherDetailsQuery

* fix setting date in JSON_MODIFY

* prefer cast over convert

* fix cipher response model

* re-add ArchivedDate

* add new keyword

* remove ArchivedDate from entity

* use custom parameters for CipherDetails_CreateWithCollections

* remove reference to archivedDate

* add missing param

* add missing param

* fix params

* fix cipher repository

* fix migration file

* update request/response models

* update migration

* remove Archives from Cipher_CreateWithCollections

* revert last change

* clean up

* remove comment

* remove column in migration

* change language in drop

* wrap in brackets

* put drop column in separate migration

* remove archivedDate column

* re-add archivedDate

* add refresh module

* bump migration name

* fix proc and migration

* do not require edit permission for archiving ciphers

* do not require edit permission for unarchiving ciphers
2026-01-07 09:29:10 -08:00

61 lines
2.1 KiB
C#

using Bit.Core.Exceptions;
using Bit.Core.Platform.Push;
using Bit.Core.Vault.Commands.Interfaces;
using Bit.Core.Vault.Models.Data;
using Bit.Core.Vault.Repositories;
namespace Bit.Core.Vault.Commands;
public class UnarchiveCiphersCommand : IUnarchiveCiphersCommand
{
private readonly ICipherRepository _cipherRepository;
private readonly IPushNotificationService _pushService;
public UnarchiveCiphersCommand(
ICipherRepository cipherRepository,
IPushNotificationService pushService
)
{
_cipherRepository = cipherRepository;
_pushService = pushService;
}
public async Task<ICollection<CipherDetails>> UnarchiveManyAsync(IEnumerable<Guid> cipherIds,
Guid unarchivingUserId)
{
var cipherIdEnumerable = cipherIds as Guid[] ?? cipherIds.ToArray();
if (cipherIds == null || cipherIdEnumerable.Length == 0)
throw new BadRequestException("No cipher ids provided.");
var cipherIdsSet = new HashSet<Guid>(cipherIdEnumerable);
var ciphers = await _cipherRepository.GetManyByUserIdAsync(unarchivingUserId);
if (ciphers == null || ciphers.Count == 0)
{
return [];
}
var unarchivingCiphers = ciphers
.Where(c => cipherIdsSet.Contains(c.Id) && c is { ArchivedDate: not null })
.ToList();
var revisionDate =
await _cipherRepository.UnarchiveAsync(unarchivingCiphers.Select(c => c.Id), unarchivingUserId);
// Adding specifyKind because revisionDate is currently coming back as Unspecified from the database
revisionDate = DateTime.SpecifyKind(revisionDate, DateTimeKind.Utc);
unarchivingCiphers.ForEach(c =>
{
c.RevisionDate = revisionDate;
c.ArchivedDate = null;
});
// Will not log an event because the archive feature is limited to individual ciphers, and event logs only apply to organization ciphers.
// Add event logging here if this is expanded to organization ciphers in the future.
await _pushService.PushSyncCiphersAsync(unarchivingUserId);
return unarchivingCiphers;
}
}