mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-09-19 11:10:12 +00:00
fix(webapp): resolve three errors in the webapp typecheck (#356)
`npx tsc -p webapp/tsconfig.json --noEmit`, one of the checks recommended in CONTRIBUTING.md, currently fails on main with three errors. All three are declaration defects with correct runtime behavior; none changes observable behavior. - api/backup.ts: downloadAdminBackupAttachmentBlob declared a bare Uint8Array return. Since TypeScript made typed arrays generic, that widens to Uint8Array<ArrayBufferLike> and no longer satisfies fflate's Uint8Array<ArrayBuffer>. The body already returns an ArrayBuffer-backed value, so this only annotates what it produces. - backup-center.ts: invalidateRemoteBrowserCacheForDestination declared a full PersistedRemoteBrowserState but builds four of its five fields. The sole caller reads .cache only, so the return type is narrowed to match what the function actually returns. - password-security-cache.ts: getPasswordSecurityState declared the public PasswordSecurityState, but startPasswordSecurityScan needs `controller`, which lives on InternalPasswordSecurityState. An internal accessor keeps `controller` off the exported type rather than widening the public API. No change to backup payload shape, archive/import whitelists, or any persisted format. Verified with tsc 5.9.3, 6.0.3, and 7.0.2 (all exit 0 for both webapp/tsconfig.json and tsconfig.json), plus npm run build and npm run i18n:validate.
This commit is contained in:
@@ -197,7 +197,7 @@ export async function downloadAdminBackupAttachmentBlob(
|
|||||||
authedFetch: AuthedFetch,
|
authedFetch: AuthedFetch,
|
||||||
blobName: string,
|
blobName: string,
|
||||||
masterPasswordHash: string
|
masterPasswordHash: string
|
||||||
): Promise<Uint8Array> {
|
): Promise<Uint8Array<ArrayBuffer>> {
|
||||||
const resp = await authedFetch('/api/admin/backup/blob', {
|
const resp = await authedFetch('/api/admin/backup/blob', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ export function invalidateRemoteBrowserCacheForDestination(
|
|||||||
cache: Record<string, RemoteBackupBrowserResponse>,
|
cache: Record<string, RemoteBackupBrowserResponse>,
|
||||||
pathByDestination: Record<string, string>,
|
pathByDestination: Record<string, string>,
|
||||||
pageByKey: Record<string, number>
|
pageByKey: Record<string, number>
|
||||||
): PersistedRemoteBrowserState {
|
): Omit<PersistedRemoteBrowserState, 'refreshedAt'> {
|
||||||
return {
|
return {
|
||||||
cache: Object.fromEntries(Object.entries(cache).filter(([key]) => !key.startsWith(`${destinationId}:`))),
|
cache: Object.fromEntries(Object.entries(cache).filter(([key]) => !key.startsWith(`${destinationId}:`))),
|
||||||
pathByDestination: Object.fromEntries(Object.entries(pathByDestination).filter(([key]) => key !== destinationId)),
|
pathByDestination: Object.fromEntries(Object.entries(pathByDestination).filter(([key]) => key !== destinationId)),
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function createState(fingerprint: string): InternalPasswordSecurityState {
|
|||||||
return { fingerprint, report: null, scannedAt: null, scanning: false, progress: { checked: 0, total: 0 }, scanError: false, controller: null };
|
return { fingerprint, report: null, scannedAt: null, scanning: false, progress: { checked: 0, total: 0 }, scanError: false, controller: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPasswordSecurityState(fingerprint: string): PasswordSecurityState {
|
function ensurePasswordSecurityState(fingerprint: string): InternalPasswordSecurityState {
|
||||||
if (state?.fingerprint !== fingerprint) {
|
if (state?.fingerprint !== fingerprint) {
|
||||||
state?.controller?.abort();
|
state?.controller?.abort();
|
||||||
state = createState(fingerprint);
|
state = createState(fingerprint);
|
||||||
@@ -31,6 +31,10 @@ export function getPasswordSecurityState(fingerprint: string): PasswordSecurityS
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getPasswordSecurityState(fingerprint: string): PasswordSecurityState {
|
||||||
|
return ensurePasswordSecurityState(fingerprint);
|
||||||
|
}
|
||||||
|
|
||||||
export function readPasswordSecurityState(fingerprint: string): PasswordSecurityState | null {
|
export function readPasswordSecurityState(fingerprint: string): PasswordSecurityState | null {
|
||||||
return state?.fingerprint === fingerprint ? state : null;
|
return state?.fingerprint === fingerprint ? state : null;
|
||||||
}
|
}
|
||||||
@@ -41,7 +45,7 @@ export function subscribePasswordSecurityState(listener: () => void): () => void
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function startPasswordSecurityScan(fingerprint: string, ciphers: Cipher[]): void {
|
export function startPasswordSecurityScan(fingerprint: string, ciphers: Cipher[]): void {
|
||||||
const current = getPasswordSecurityState(fingerprint);
|
const current = ensurePasswordSecurityState(fingerprint);
|
||||||
current.controller?.abort();
|
current.controller?.abort();
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const total = ciphers.filter((cipher) => Number(cipher.type) === 1 && !cipher.deletedDate && !(cipher as { deletedAt?: string | null }).deletedAt && !!cipher.login?.decPassword).length;
|
const total = ciphers.filter((cipher) => Number(cipher.type) === 1 && !cipher.deletedDate && !(cipher as { deletedAt?: string | null }).deletedAt && !!cipher.login?.decPassword).length;
|
||||||
|
|||||||
Reference in New Issue
Block a user