fix: validate document uploads and allow clearing expiry dates
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
export function decodeDocumentUpload(value) {
|
||||
if (typeof value !== 'string' || !value.length || value.length % 4 !== 0 ||
|
||||
!/^[A-Za-z0-9+/]*={0,2}$/.test(value))
|
||||
throw new Error('Dosya içeriği geçersiz; dosyayı yeniden seçin.');
|
||||
const bytes = Buffer.from(value, 'base64');
|
||||
if (!bytes.length || bytes.toString('base64') !== value) throw new Error('Dosya içeriği boş veya bozuk.');
|
||||
if (bytes.length > 10 * 1024 * 1024) throw new Error('Dosya en fazla 10 MB olabilir.');
|
||||
return bytes;
|
||||
}
|
||||
|
||||
export function documentMetadataPatch(body) {
|
||||
const patch = {};
|
||||
if (Object.hasOwn(body, 'sonKullanma')) {
|
||||
const value = body.sonKullanma;
|
||||
if (value !== null && value !== '') {
|
||||
if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}$/.test(value))
|
||||
throw new Error('Son kullanma tarihi YYYY-AA-GG biçiminde olmalı.');
|
||||
const date = new Date(value + 'T00:00:00Z');
|
||||
if (!Number.isFinite(date.getTime()) || date.toISOString().slice(0,10) !== value)
|
||||
throw new Error('Son kullanma tarihi geçerli bir takvim günü olmalı.');
|
||||
}
|
||||
patch.sonKullanma = value || null;
|
||||
}
|
||||
if (Object.hasOwn(body, 'kategori')) {
|
||||
if (body.kategori !== null && typeof body.kategori !== 'string') throw new Error('Belge kategorisi metin olmalı.');
|
||||
patch.kategori = body.kategori?.trim().slice(0,60) || null;
|
||||
}
|
||||
return patch;
|
||||
}
|
||||
+6
-6
@@ -1,3 +1,4 @@
|
||||
import { documentMetadataPatch, decodeDocumentUpload } from './document-metadata.mjs';
|
||||
import { deadlineInfo } from '../src/services/tenderCalendar.js';
|
||||
import { exchangeRates } from './exchange-rates.mjs';
|
||||
import { uniqueTenders, announcementFields } from './tender-quality.mjs';
|
||||
@@ -953,7 +954,8 @@ const server = http.createServer(async (req, res) => {
|
||||
if (!body.ad || !body.icerikBase64) {
|
||||
return json(res, 400, { success: false, error: 'ad ve icerikBase64 gerekli' });
|
||||
}
|
||||
const buf = Buffer.from(body.icerikBase64, 'base64');
|
||||
const metadata = documentMetadataPatch(body);
|
||||
const buf = decodeDocumentUpload(body.icerikBase64);
|
||||
const kullanimDurumu = store.documentUsage(user.email);
|
||||
kotaKontrol(user.email, 'belgeAdet', kullanimDurumu.adet, 1, opts);
|
||||
kotaKontrol(user.email, 'belgeBayt', kullanimDurumu.bayt, buf.length, opts);
|
||||
@@ -971,11 +973,11 @@ const server = http.createServer(async (req, res) => {
|
||||
fs.writeFileSync(path.join(store.BELGE_DIR, dosyaAdi), buf);
|
||||
const id = store.addDocument(user.email, {
|
||||
ad: String(body.ad).slice(0, 200),
|
||||
kategori: body.kategori || null,
|
||||
kategori: metadata.kategori || null,
|
||||
boyut: buf.length, // GERÇEK bayt — rastgele değil
|
||||
mime: body.mime || null,
|
||||
dosya: dosyaAdi,
|
||||
sonKullanma: body.sonKullanma || null,
|
||||
sonKullanma: metadata.sonKullanma || null,
|
||||
ikn, // ihaleye bağlı belge
|
||||
});
|
||||
// Yükleme anında otomatik kalem çıkarımı — AI kullanmaz, kullanıcıdan
|
||||
@@ -1037,9 +1039,7 @@ const server = http.createServer(async (req, res) => {
|
||||
try {
|
||||
const body = await readBody(req);
|
||||
if (!body.id) return json(res, 400, { success: false, error: 'id gerekli' });
|
||||
const sonKullanma = body.sonKullanma ? String(body.sonKullanma).slice(0, 10) : null;
|
||||
if (sonKullanma && !/^\d{4}-\d{2}-\d{2}$/.test(sonKullanma)) return json(res, 400, { success: false, error: 'tarih YYYY-AA-GG olmalı' });
|
||||
const ok = store.updateDocument(user.email, String(body.id), { sonKullanma, kategori: body.kategori ? String(body.kategori).slice(0, 60) : null });
|
||||
const ok = store.updateDocument(user.email, String(body.id), documentMetadataPatch(body));
|
||||
if (!ok) return json(res, 404, { success: false, error: 'belge bulunamadı' });
|
||||
return json(res, 200, { success: true, belgeler: store.listDocuments(user.email) });
|
||||
} catch (e) { return json(res, 400, { success: false, error: e.message }); }
|
||||
|
||||
@@ -262,12 +262,14 @@ export function getDocument(email, id) {
|
||||
}
|
||||
|
||||
/** Belge üst verisi: son kullanma / kategori (süre takibi için). */
|
||||
export function updateDocument(email, id, { sonKullanma, kategori } = {}) {
|
||||
export function updateDocument(email, id, patch = {}) {
|
||||
return withDb((db) => {
|
||||
const hasDate = Object.hasOwn(patch,'sonKullanma');
|
||||
const hasCategory = Object.hasOwn(patch,'kategori');
|
||||
const r = db.prepare(`UPDATE belgeler SET
|
||||
son_kullanma = COALESCE(?, son_kullanma),
|
||||
kategori = COALESCE(?, kategori)
|
||||
WHERE id=? AND email=?`).run(sonKullanma ?? null, kategori ?? null, id, email);
|
||||
son_kullanma = CASE WHEN ? THEN ? ELSE son_kullanma END,
|
||||
kategori = CASE WHEN ? THEN ? ELSE kategori END
|
||||
WHERE id=? AND email=?`).run(Number(hasDate), patch.sonKullanma ?? null, Number(hasCategory), patch.kategori ?? null, id, email);
|
||||
return r.changes > 0;
|
||||
}, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user