mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 21:00:41 +00:00
feat: enhance backup progress handling and improve user status toggling
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { base64ToBytes, decryptBw } from './crypto';
|
||||
import { base64ToBytes, decryptBw, toBufferSource } from './crypto';
|
||||
import type { AdminBackupSettings, BackupSettingsPortablePayload } from './api/backup';
|
||||
import type { Profile, SessionState } from './types';
|
||||
|
||||
@@ -9,7 +9,7 @@ const AES_GCM_ALGORITHM = 'AES-GCM';
|
||||
async function importPortablePrivateKey(pkcs8: Uint8Array): Promise<CryptoKey> {
|
||||
return crypto.subtle.importKey(
|
||||
'pkcs8',
|
||||
pkcs8,
|
||||
toBufferSource(pkcs8),
|
||||
{ name: PORTABLE_ALGORITHM, hash: PORTABLE_HASH },
|
||||
false,
|
||||
['decrypt']
|
||||
@@ -17,7 +17,7 @@ async function importPortablePrivateKey(pkcs8: Uint8Array): Promise<CryptoKey> {
|
||||
}
|
||||
|
||||
async function importPortableAesKey(keyBytes: Uint8Array): Promise<CryptoKey> {
|
||||
return crypto.subtle.importKey('raw', keyBytes, { name: AES_GCM_ALGORITHM }, false, ['decrypt']);
|
||||
return crypto.subtle.importKey('raw', toBufferSource(keyBytes), { name: AES_GCM_ALGORITHM }, false, ['decrypt']);
|
||||
}
|
||||
|
||||
export async function decryptPortableBackupSettings(
|
||||
@@ -50,15 +50,15 @@ export async function decryptPortableBackupSettings(
|
||||
await crypto.subtle.decrypt(
|
||||
{ name: PORTABLE_ALGORITHM },
|
||||
privateKey,
|
||||
base64ToBytes(wrap.wrappedKey)
|
||||
toBufferSource(base64ToBytes(wrap.wrappedKey))
|
||||
)
|
||||
);
|
||||
const aesKey = await importPortableAesKey(portableDek);
|
||||
const plaintext = new Uint8Array(
|
||||
await crypto.subtle.decrypt(
|
||||
{ name: AES_GCM_ALGORITHM, iv: base64ToBytes(portable.iv) },
|
||||
{ name: AES_GCM_ALGORITHM, iv: toBufferSource(base64ToBytes(portable.iv)) },
|
||||
aesKey,
|
||||
base64ToBytes(portable.ciphertext)
|
||||
toBufferSource(base64ToBytes(portable.ciphertext))
|
||||
)
|
||||
);
|
||||
return JSON.parse(new TextDecoder().decode(plaintext)) as AdminBackupSettings;
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
type AuthedFetch,
|
||||
} from './shared';
|
||||
import { readResponseBytesWithProgress } from '../download';
|
||||
import { toBufferSource } from '../crypto';
|
||||
import { unzipSync, zipSync } from 'fflate';
|
||||
|
||||
export type {
|
||||
@@ -367,7 +368,7 @@ export function extractBackupFileChecksumPrefix(fileName: string): string | null
|
||||
}
|
||||
|
||||
async function sha256Hex(bytes: Uint8Array): Promise<string> {
|
||||
const digest = await crypto.subtle.digest('SHA-256', bytes);
|
||||
const digest = await crypto.subtle.digest('SHA-256', toBufferSource(bytes));
|
||||
return Array.from(new Uint8Array(digest)).map((byte) => byte.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
|
||||
|
||||
@@ -152,10 +152,12 @@ export async function createSend(
|
||||
const uploadInfo = await parseJson<{ url?: string; sendResponse?: Send; fileUploadType?: number }>(fileResp);
|
||||
const uploadUrl = uploadInfo?.url;
|
||||
if (!uploadUrl) throw new Error('Create file send failed: missing upload URL');
|
||||
const payload = new ArrayBuffer(encryptedFileBytes.byteLength);
|
||||
new Uint8Array(payload).set(encryptedFileBytes);
|
||||
const uploadResp = await uploadDirectEncryptedPayload({
|
||||
accessToken: session.accessToken,
|
||||
uploadUrl,
|
||||
payload: encryptedFileBytes,
|
||||
payload,
|
||||
fileUploadType: uploadInfo?.fileUploadType,
|
||||
unsupportedMessage: 'Unsupported send upload type',
|
||||
onProgress,
|
||||
|
||||
@@ -63,14 +63,14 @@ interface UploadWithProgressOptions {
|
||||
accessToken?: string;
|
||||
method?: string;
|
||||
headers?: HeadersInit;
|
||||
body?: Document | XMLHttpRequestBodyInit | null;
|
||||
body?: XMLHttpRequestBodyInit | null;
|
||||
onProgress?: (percent: number | null) => void;
|
||||
}
|
||||
|
||||
interface DirectEncryptedUploadOptions {
|
||||
accessToken: string;
|
||||
uploadUrl: string;
|
||||
payload: ArrayBuffer | Uint8Array;
|
||||
payload: XMLHttpRequestBodyInit;
|
||||
fileUploadType: number | null | undefined;
|
||||
unsupportedMessage: string;
|
||||
onProgress?: (percent: number | null) => void;
|
||||
|
||||
@@ -18,7 +18,7 @@ export function concatBytes(a: Uint8Array, b: Uint8Array): Uint8Array {
|
||||
return out;
|
||||
}
|
||||
|
||||
function toBufferSource(bytes: Uint8Array): ArrayBuffer {
|
||||
export function toBufferSource(bytes: Uint8Array): ArrayBuffer {
|
||||
return new Uint8Array(bytes).buffer;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user