mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 21:00:41 +00:00
Merge branch 'main' of https://github.com/shuaiplus/nodewarden
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { base64ToBytes, bytesToBase64, decryptBw, decryptBwFileData, decryptStr, encryptBw, encryptBwFileData, hkdf, pbkdf2 } from '../crypto';
|
||||
import type { Send, SendDraft, SessionState } from '../types';
|
||||
import { chunkArray, createApiError, parseErrorMessage, parseJson, uploadDirectEncryptedPayload, type AuthedFetch } from './shared';
|
||||
import { loadVaultSyncSnapshot } from './vault-sync';
|
||||
|
||||
function toIsoDateFromDays(value: string, required: boolean): string | null {
|
||||
const raw = String(value || '').trim();
|
||||
@@ -61,10 +62,8 @@ function parseMaxAccessCountRaw(value: string): number | null {
|
||||
}
|
||||
|
||||
export async function getSends(authedFetch: AuthedFetch): Promise<Send[]> {
|
||||
const resp = await authedFetch('/api/sends');
|
||||
if (!resp.ok) throw new Error('Failed to load sends');
|
||||
const body = await parseJson<{ object: 'list'; data: Send[] }>(resp);
|
||||
return body?.data || [];
|
||||
const body = await loadVaultSyncSnapshot(authedFetch);
|
||||
return body.sends || [];
|
||||
}
|
||||
|
||||
export async function createSend(
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { Cipher, Folder, Send } from '../types';
|
||||
import { parseJson, type AuthedFetch } from './shared';
|
||||
|
||||
interface VaultSyncResponse {
|
||||
ciphers?: Cipher[];
|
||||
folders?: Folder[];
|
||||
sends?: Send[];
|
||||
}
|
||||
|
||||
const pendingSyncRequests = new WeakMap<AuthedFetch, Promise<VaultSyncResponse>>();
|
||||
|
||||
export async function loadVaultSyncSnapshot(authedFetch: AuthedFetch): Promise<VaultSyncResponse> {
|
||||
const existing = pendingSyncRequests.get(authedFetch);
|
||||
if (existing) return existing;
|
||||
|
||||
const request = (async () => {
|
||||
const resp = await authedFetch('/api/sync');
|
||||
if (!resp.ok) throw new Error('Failed to load vault');
|
||||
const body = await parseJson<VaultSyncResponse>(resp);
|
||||
return body || {};
|
||||
})();
|
||||
|
||||
pendingSyncRequests.set(authedFetch, request);
|
||||
try {
|
||||
return await request;
|
||||
} finally {
|
||||
if (pendingSyncRequests.get(authedFetch) === request) {
|
||||
pendingSyncRequests.delete(authedFetch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ import { base64ToBytes, decryptBw, decryptBwFileData, decryptStr, encryptBw, enc
|
||||
import type {
|
||||
Cipher,
|
||||
Folder,
|
||||
ListResponse,
|
||||
SessionState,
|
||||
VaultDraft,
|
||||
VaultDraftField,
|
||||
@@ -16,12 +15,11 @@ import {
|
||||
type AuthedFetch,
|
||||
} from './shared';
|
||||
import { readResponseBytesWithProgress } from '../download';
|
||||
import { loadVaultSyncSnapshot } from './vault-sync';
|
||||
|
||||
export async function getFolders(authedFetch: AuthedFetch): Promise<Folder[]> {
|
||||
const resp = await authedFetch('/api/folders');
|
||||
if (!resp.ok) throw new Error('Failed to load folders');
|
||||
const body = await parseJson<ListResponse<Folder>>(resp);
|
||||
return body?.data || [];
|
||||
const body = await loadVaultSyncSnapshot(authedFetch);
|
||||
return body.folders || [];
|
||||
}
|
||||
|
||||
export async function createFolder(
|
||||
@@ -93,10 +91,8 @@ export async function updateFolder(
|
||||
}
|
||||
|
||||
export async function getCiphers(authedFetch: AuthedFetch): Promise<Cipher[]> {
|
||||
const resp = await authedFetch('/api/ciphers?deleted=true');
|
||||
if (!resp.ok) throw new Error('Failed to load ciphers');
|
||||
const body = await parseJson<ListResponse<Cipher>>(resp);
|
||||
return body?.data || [];
|
||||
const body = await loadVaultSyncSnapshot(authedFetch);
|
||||
return body.ciphers || [];
|
||||
}
|
||||
|
||||
export interface CiphersImportPayload {
|
||||
|
||||
Reference in New Issue
Block a user