fix: reject stale company profile and filter updates
This commit is contained in:
+7
-4
@@ -1194,7 +1194,7 @@ const server = http.createServer(async (req, res) => {
|
||||
|
||||
if (req.method === 'GET') {
|
||||
if (anahtar) return json(res, 200, { success: true, anahtar, deger: store.getData(user.email, anahtar) });
|
||||
return json(res, 200, { success: true, veri: store.getAllData(user.email) });
|
||||
return json(res, 200, { success: true, ...store.getDataSnapshot(user.email) });
|
||||
}
|
||||
if (req.method === 'PUT' || req.method === 'POST') {
|
||||
try {
|
||||
@@ -1205,10 +1205,13 @@ const server = http.createServer(async (req, res) => {
|
||||
if (k === 'ekip' && Array.isArray(body.deger)) {
|
||||
kotaKontrol(user.email, 'ekip', 0, body.deger.length, { isAdmin: user.isAdmin });
|
||||
}
|
||||
store.setData(user.email, k, body.deger);
|
||||
return json(res, 200, { success: true });
|
||||
const protectedKey=['firma_profil','saved_filters'].includes(k);
|
||||
if(protectedKey && (!Object.hasOwn(body,'revision') || (body.revision!==null && (typeof body.revision!=='string' || !/^[a-f0-9]{64}$/.test(body.revision)))))
|
||||
return json(res,428,{success:false,kod:'VERSION_REQUIRED',error:'Güncel kayıt sürümü gerekli. Sayfayı yenileyip tekrar deneyin.'});
|
||||
const revision=store.setData(user.email, k, body.deger, protectedKey ? body.revision : undefined);
|
||||
return json(res, 200, { success: true, ...(protectedKey ? {revision} : {}) });
|
||||
} catch (e) {
|
||||
return json(res, e.kod === 'KOTA_ASILDI' ? 402 : 400, { success: false, error: e.message, kod: e.kod || null });
|
||||
return json(res, e.kod === 'KOTA_ASILDI' ? 402 : e.kod === 'VERSION_CONFLICT' ? 409 : 400, { success: false, error: e.message, kod: e.kod || null });
|
||||
}
|
||||
}
|
||||
return json(res, 405, { success: false, error: 'desteklenmeyen metot' });
|
||||
|
||||
+26
-13
@@ -202,24 +202,37 @@ export function getData(email, anahtar) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getAllData(email) {
|
||||
return withDb((db) => {
|
||||
const rows = db.prepare('SELECT anahtar, deger FROM kullanici_verisi WHERE email=?').all(email);
|
||||
const out = {};
|
||||
for (const r of rows) {
|
||||
try { out[r.anahtar] = JSON.parse(r.deger); } catch { /* bozuk kayıt atlanır */ }
|
||||
const dataRevision = raw => raw == null ? null : crypto.createHash('sha256').update(raw).digest('hex');
|
||||
export function getDataSnapshot(email) {
|
||||
return withDb(db=>{
|
||||
const rows=db.prepare('SELECT anahtar,deger FROM kullanici_verisi WHERE email=?').all(email);
|
||||
const veri={},revisions={};
|
||||
for(const row of rows){
|
||||
revisions[row.anahtar]=dataRevision(row.deger);
|
||||
try{veri[row.anahtar]=JSON.parse(row.deger);}catch{/* invalid data remains absent */}
|
||||
}
|
||||
return out;
|
||||
}, {});
|
||||
return {veri,revisions};
|
||||
},{veri:{},revisions:{}});
|
||||
}
|
||||
export function getAllData(email) { return getDataSnapshot(email).veri; }
|
||||
|
||||
export function setData(email, anahtar, deger) {
|
||||
export function setData(email, anahtar, deger, expectedRevision=undefined) {
|
||||
if (!IZINLI_ANAHTARLAR.has(anahtar)) throw new Error(`Bilinmeyen veri anahtarı: ${anahtar}`);
|
||||
return withDb((db) => {
|
||||
db.prepare(`INSERT INTO kullanici_verisi (email, anahtar, deger, guncelleme) VALUES (?,?,?,?)
|
||||
ON CONFLICT(email, anahtar) DO UPDATE SET deger=excluded.deger, guncelleme=excluded.guncelleme`)
|
||||
.run(email, anahtar, JSON.stringify(deger ?? null), now());
|
||||
return true;
|
||||
db.exec('BEGIN IMMEDIATE');
|
||||
try {
|
||||
const old=db.prepare('SELECT deger FROM kullanici_verisi WHERE email=? AND anahtar=?').get(email,anahtar);
|
||||
if(expectedRevision!==undefined && expectedRevision!==dataRevision(old?.deger)) {
|
||||
const error=new Error('Bu kayıt başka bir sekmede veya cihazda değişti. Değişikliklerinizi bir yere kopyalayıp sayfayı yenileyin; güncel kayıt üzerinde tekrar düzenleyin.');
|
||||
error.kod='VERSION_CONFLICT';throw error;
|
||||
}
|
||||
const raw=JSON.stringify(deger ?? null);
|
||||
db.prepare(`INSERT INTO kullanici_verisi (email, anahtar, deger, guncelleme) VALUES (?,?,?,?)
|
||||
ON CONFLICT(email, anahtar) DO UPDATE SET deger=excluded.deger, guncelleme=excluded.guncelleme`)
|
||||
.run(email, anahtar, raw, now());
|
||||
db.exec('COMMIT');
|
||||
return expectedRevision===undefined ? true : dataRevision(raw);
|
||||
} catch(error) {db.exec('ROLLBACK');throw error;}
|
||||
}, false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user