fix(settings): защищать восстановление базы от повторов и смены контекста
This commit is contained in:
1 parent
92b65a30ce
commit
57293479d1
13 files changed
+148
-188
No files matched your search
@@ -38,3 +38,12 @@ test("backup warning header is strict and malformed metadata preserves valid arc
|
||||
}
|
||||
}finally{globalThis.fetch=original}
|
||||
})
|
||||
|
||||
test("restore dispatch checkpoint runs only after local validation and immediately before POST",async()=>{
|
||||
const original=globalThis.fetch;const calls:string[]=[];try{
|
||||
globalThis.fetch=async()=>{calls.push("POST");return Response.json({ok:true})}
|
||||
const options={onDispatch:()=>calls.push("checkpoint")}
|
||||
await assert.rejects(restoreSystemDatabaseBackup("https://backend.test",new File(["wrong"],"wrong.dump"),options));assert.deepEqual(calls,[])
|
||||
await restoreSystemDatabaseBackup("https://backend.test",dump,options);assert.deepEqual(calls,["checkpoint","POST"])
|
||||
}finally{globalThis.fetch=original}
|
||||
})
|
||||
@@ -6,7 +6,7 @@ const receiptSchema=z.object({ok:z.literal(true),eventError:z.string().min(1).op
|
||||
export type SystemDatabaseRestoreReceipt=z.output<typeof receiptSchema>
|
||||
const warningSchema=receiptSchema.omit({ok:true})
|
||||
export type SystemDatabaseWarnings=z.output<typeof warningSchema>
|
||||
type Options={signal?:AbortSignal}
|
||||
type Options={signal?:AbortSignal;onDispatch?:()=>void}
|
||||
const signal=(options?:Options)=>options?.signal?AbortSignal.any([options.signal,AbortSignal.timeout(600_000)]):AbortSignal.timeout(600_000)
|
||||
function parseFilename(value:string|null):string{
|
||||
let name="mikrotik-manager.dump"
|
||||
@@ -39,6 +39,7 @@ export async function restoreSystemDatabaseBackup(baseUrl:string,file:File,optio
|
||||
if(file.size>MAX_RESTORE_BYTES)throw new ApiClientError("Файл больше 512 МБ — уменьшите бэкап или обратитесь к администратору",413)
|
||||
const activeSignal=signal(options);activeSignal.throwIfAborted()
|
||||
await confirmDump(file);activeSignal.throwIfAborted()
|
||||
options?.onDispatch?.()
|
||||
const raw=await requestJson<unknown>(baseUrl,"/api/system/database/restore",{method:"POST",headers:{"Content-Type":"application/octet-stream"},body:file,signal:activeSignal})
|
||||
const receipt=receiptSchema.safeParse(raw)
|
||||
if(!receipt.success)throw new Error("Восстановление базы не подтверждено сервером")
|
||||
|
||||
Reference in new issue
Block a user