1- import { promises as fs , existsSync } from "node:fs" ;
1+ import { constants as fsConstants , promises as fs , existsSync } from "node:fs" ;
22import { randomBytes } from "node:crypto" ;
33import { dirname , join } from "node:path" ;
44import { ACCOUNT_LIMITS } from "./constants.js" ;
@@ -159,12 +159,16 @@ async function renameWithWindowsRetry(sourcePath: string, destinationPath: strin
159159 }
160160}
161161
162- async function copyFileWithWindowsRetry ( sourcePath : string , destinationPath : string ) : Promise < void > {
162+ async function copyFileWithWindowsRetry (
163+ sourcePath : string ,
164+ destinationPath : string ,
165+ mode = 0 ,
166+ ) : Promise < void > {
163167 let lastError : NodeJS . ErrnoException | null = null ;
164168
165169 for ( let attempt = 0 ; attempt < WINDOWS_RENAME_RETRY_ATTEMPTS ; attempt += 1 ) {
166170 try {
167- await fs . copyFile ( sourcePath , destinationPath ) ;
171+ await fs . copyFile ( sourcePath , destinationPath , mode ) ;
168172 return ;
169173 } catch ( error ) {
170174 if ( isWindowsLockError ( error ) ) {
@@ -1136,7 +1140,10 @@ async function loadFlaggedAccountsUnlocked(
11361140}
11371141
11381142export async function loadFlaggedAccounts ( ) : Promise < FlaggedAccountStorageV1 > {
1139- return withStorageLock ( async ( ) => loadFlaggedAccountsUnlocked ( ) ) ;
1143+ return withStorageLock ( async ( ) => {
1144+ const accountsSnapshot = await loadAccountsInternal ( saveAccountsUnlocked ) ;
1145+ return loadFlaggedAccountsUnlocked ( accountsSnapshot ) ;
1146+ } ) ;
11401147}
11411148
11421149/**
@@ -1291,10 +1298,7 @@ function previewImportAccountsAgainstExistingNormalized(
12911298export async function backupRawAccountsFile ( filePath : string , force = true ) : Promise < void > {
12921299 await withStorageLock ( async ( ) => {
12931300 const resolvedPath = resolvePath ( filePath ) ;
1294-
1295- if ( ! force && existsSync ( resolvedPath ) ) {
1296- throw new Error ( `File already exists: ${ resolvedPath } ` ) ;
1297- }
1301+ const copyMode = force ? 0 : fsConstants . COPYFILE_EXCL ;
12981302
12991303 await migrateLegacyProjectStorageIfNeeded ( saveAccountsUnlocked ) ;
13001304 const storagePath = getStoragePath ( ) ;
@@ -1303,7 +1307,14 @@ export async function backupRawAccountsFile(filePath: string, force = true): Pro
13031307 }
13041308
13051309 await fs . mkdir ( dirname ( resolvedPath ) , { recursive : true } ) ;
1306- await copyFileWithWindowsRetry ( storagePath , resolvedPath ) ;
1310+ try {
1311+ await copyFileWithWindowsRetry ( storagePath , resolvedPath , copyMode ) ;
1312+ } catch ( error ) {
1313+ if ( ( error as NodeJS . ErrnoException ) . code === "EEXIST" ) {
1314+ throw new Error ( `File already exists: ${ resolvedPath } ` ) ;
1315+ }
1316+ throw error ;
1317+ }
13071318 await fs . chmod ( resolvedPath , 0o600 ) . catch ( ( chmodErr ) => {
13081319 log . warn ( "Failed to restrict backup file permissions" , {
13091320 path : resolvedPath ,
0 commit comments