fix: bound document downloads and cancel stale sessions

This commit is contained in:
2026-09-06 13:56:05 +03:00
parent 34da54a080
commit ae32382ffa
4 changed files with 106 additions and 21 deletions
+40 -17
View File
@@ -1,3 +1,4 @@
import {awaitWithAbort} from './abortable.js';
import { apiKeyRequest } from './apiKeys.js';
import { sessionGuard } from './sessionGuard.js';
/**
@@ -46,25 +47,47 @@ export async function uploadDocument(file, kategori, ikn, ek = {}) {
}
/** Auth başlığı gerektiği için <a href> yerine blob ile indirilir. */
export async function downloadDocument(id, ad) {
export async function downloadDocument(id, ad, {signal,timeoutMs=120000}={}) {
const current = sessionGuard(getToken);
const res = await fetch(`/api/me/documents/download?id=${encodeURIComponent(id)}`, {
headers: { Authorization: `Bearer ${getToken()}` },
});
if (!res.ok) {
const d = await res.json().catch(() => ({}));
throw new Error(d.error || `İndirilemedi (HTTP ${res.status})`);
if (!current()) throw new Error('Belgeyi indirmek için hesabınıza giriş yapın.');
const controller = new AbortController();
const cancel = () => controller.abort(signal.reason);
if (signal?.aborted) cancel(); else signal?.addEventListener('abort',cancel,{once:true});
let timedOut=false;
const timer=setTimeout(()=>{timedOut=true;controller.abort();},timeoutMs);
const assertCurrent=()=>{if(!current())throw new Error('Oturum değişti; belgeyi yeniden açın.');};
try {
controller.signal.throwIfAborted();
const res = await awaitWithAbort(fetch(`/api/me/documents/download?id=${encodeURIComponent(id)}`, {
signal:controller.signal,headers:{Authorization:`Bearer ${getToken()}`},
}),controller.signal);
assertCurrent();
if (!res.ok) {
const data=await awaitWithAbort(res.json().catch(()=>({})),controller.signal);
assertCurrent();
throw new Error(data?.error || `İndirilemedi (HTTP ${res.status})`);
}
const blob=await awaitWithAbort(res.blob(),controller.signal);
assertCurrent();
controller.signal.throwIfAborted();
const url=URL.createObjectURL(blob);
let anchor;
try {
anchor=document.createElement('a');
anchor.href=url;anchor.download=ad || 'belge';
document.body.appendChild(anchor);
anchor.click();
} finally {
anchor?.remove();
setTimeout(()=>URL.revokeObjectURL(url),5000);
}
} catch(error) {
assertCurrent();
if(timedOut)throw new Error('Belge zamanında indirilemedi. Bağlantınızı kontrol edip yeniden deneyin.');
throw error;
} finally {
clearTimeout(timer);signal?.removeEventListener('abort',cancel);
}
const blob = await res.blob();
if (!current()) throw new Error('Oturum değişti; belgeyi yeniden açın.');
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = ad || 'belge';
document.body.appendChild(a);
a.click();
a.remove();
setTimeout(() => URL.revokeObjectURL(url), 5000);
}
export function formatBayt(b) {