mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 21:00:41 +00:00
feat: add archiving functionality for ciphers
- Introduced `archive` and `unarchive` endpoints in the API for ciphers. - Implemented bulk archiving and unarchiving of ciphers in the vault. - Updated the storage schema to include `archived_at` timestamps for ciphers. - Enhanced user interface to support archiving actions in the vault. - Added necessary translations for archive-related actions. - Updated user and device models to accommodate new fields related to archiving.
This commit is contained in:
@@ -582,6 +582,20 @@ export async function deleteCipher(authedFetch: AuthedFetch, cipherId: string):
|
||||
if (!resp.ok) throw new Error('Delete item failed');
|
||||
}
|
||||
|
||||
export async function archiveCipher(authedFetch: AuthedFetch, cipherId: string): Promise<void> {
|
||||
const id = String(cipherId || '').trim();
|
||||
if (!id) throw new Error('Cipher id is required');
|
||||
const resp = await authedFetch(`/api/ciphers/${encodeURIComponent(id)}/archive`, { method: 'PUT' });
|
||||
if (!resp.ok) throw new Error('Archive item failed');
|
||||
}
|
||||
|
||||
export async function unarchiveCipher(authedFetch: AuthedFetch, cipherId: string): Promise<void> {
|
||||
const id = String(cipherId || '').trim();
|
||||
if (!id) throw new Error('Cipher id is required');
|
||||
const resp = await authedFetch(`/api/ciphers/${encodeURIComponent(id)}/unarchive`, { method: 'PUT' });
|
||||
if (!resp.ok) throw new Error('Unarchive item failed');
|
||||
}
|
||||
|
||||
export async function bulkDeleteCiphers(authedFetch: AuthedFetch, ids: string[]): Promise<void> {
|
||||
const uniqueIds = Array.from(new Set(ids.map((id) => String(id || '').trim()).filter(Boolean)));
|
||||
for (const chunk of chunkArray(uniqueIds, BULK_API_CHUNK_SIZE)) {
|
||||
@@ -594,6 +608,18 @@ export async function bulkDeleteCiphers(authedFetch: AuthedFetch, ids: string[])
|
||||
}
|
||||
}
|
||||
|
||||
export async function bulkArchiveCiphers(authedFetch: AuthedFetch, ids: string[]): Promise<void> {
|
||||
const uniqueIds = Array.from(new Set(ids.map((id) => String(id || '').trim()).filter(Boolean)));
|
||||
for (const chunk of chunkArray(uniqueIds, BULK_API_CHUNK_SIZE)) {
|
||||
const resp = await authedFetch('/api/ciphers/archive', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ ids: chunk }),
|
||||
});
|
||||
if (!resp.ok) throw new Error('Bulk archive failed');
|
||||
}
|
||||
}
|
||||
|
||||
export async function bulkPermanentDeleteCiphers(authedFetch: AuthedFetch, ids: string[]): Promise<void> {
|
||||
const uniqueIds = Array.from(new Set(ids.map((id) => String(id || '').trim()).filter(Boolean)));
|
||||
for (const chunk of chunkArray(uniqueIds, BULK_API_CHUNK_SIZE)) {
|
||||
@@ -618,6 +644,18 @@ export async function bulkRestoreCiphers(authedFetch: AuthedFetch, ids: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export async function bulkUnarchiveCiphers(authedFetch: AuthedFetch, ids: string[]): Promise<void> {
|
||||
const uniqueIds = Array.from(new Set(ids.map((id) => String(id || '').trim()).filter(Boolean)));
|
||||
for (const chunk of chunkArray(uniqueIds, BULK_API_CHUNK_SIZE)) {
|
||||
const resp = await authedFetch('/api/ciphers/unarchive', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ ids: chunk }),
|
||||
});
|
||||
if (!resp.ok) throw new Error('Bulk unarchive failed');
|
||||
}
|
||||
}
|
||||
|
||||
export async function bulkMoveCiphers(
|
||||
authedFetch: AuthedFetch,
|
||||
ids: string[],
|
||||
|
||||
@@ -280,6 +280,18 @@ const messages: Record<Locale, Record<string, string>> = {
|
||||
txt_delete_item: "Delete Item",
|
||||
txt_delete_item_failed: "Delete item failed",
|
||||
txt_delete_permanently: "Delete Permanently",
|
||||
txt_archive: "Archive",
|
||||
txt_archived: "Archived",
|
||||
txt_archive_selected: "Archive",
|
||||
txt_item_archived: "Item archived",
|
||||
txt_item_unarchived: "Item unarchived",
|
||||
txt_archived_selected_items: "Archived selected items",
|
||||
txt_unarchived_selected_items: "Unarchived selected items",
|
||||
txt_archive_item_failed: "Archive item failed",
|
||||
txt_unarchive_item_failed: "Unarchive item failed",
|
||||
txt_bulk_archive_failed: "Bulk archive failed",
|
||||
txt_bulk_unarchive_failed: "Bulk unarchive failed",
|
||||
txt_unarchive: "Unarchive",
|
||||
txt_delete_selected: "Delete Selected",
|
||||
txt_delete_selected_items: "Delete Selected Items",
|
||||
txt_delete_selected_items_permanently: "Delete Selected Items Permanently",
|
||||
@@ -1363,6 +1375,18 @@ zhCNOverrides.txt_import_encrypted_zip_message = '该 ZIP 压缩包已加密,
|
||||
zhCNOverrides.txt_import_export_title = '导入导出';
|
||||
zhCNOverrides.txt_new_type_header = '新建{type}';
|
||||
zhCNOverrides.txt_edit_type_header = '编辑{type}';
|
||||
zhCNOverrides.txt_archive = '归档';
|
||||
zhCNOverrides.txt_archived = '已归档';
|
||||
zhCNOverrides.txt_archive_selected = '归档';
|
||||
zhCNOverrides.txt_item_archived = '项目已归档';
|
||||
zhCNOverrides.txt_item_unarchived = '项目已取消归档';
|
||||
zhCNOverrides.txt_archived_selected_items = '已归档所选项目';
|
||||
zhCNOverrides.txt_unarchived_selected_items = '已取消归档所选项目';
|
||||
zhCNOverrides.txt_archive_item_failed = '归档项目失败';
|
||||
zhCNOverrides.txt_unarchive_item_failed = '取消归档项目失败';
|
||||
zhCNOverrides.txt_bulk_archive_failed = '批量归档失败';
|
||||
zhCNOverrides.txt_bulk_unarchive_failed = '批量取消归档失败';
|
||||
zhCNOverrides.txt_unarchive = '取消归档';
|
||||
zhCNOverrides.txt_delete_folder = '删除文件夹';
|
||||
zhCNOverrides.txt_delete_folder_message = '删除文件夹「{name}」?其中的项目将移至无文件夹。';
|
||||
zhCNOverrides.txt_delete_all_folders = '删除全部文件夹';
|
||||
|
||||
@@ -143,6 +143,7 @@ export interface Cipher {
|
||||
creationDate?: string;
|
||||
revisionDate?: string;
|
||||
deletedDate?: string | null;
|
||||
archivedDate?: string | null;
|
||||
attachments?: CipherAttachment[] | null;
|
||||
login?: CipherLogin | null;
|
||||
card?: CipherCard | null;
|
||||
|
||||
Reference in New Issue
Block a user