Enforce API key quota within the database transaction

This commit is contained in:
2026-09-06 10:40:45 +03:00
parent 1c0b48655e
commit 1a62a876e6
5 changed files with 63 additions and 11 deletions
+17
View File
@@ -155,3 +155,20 @@ test('HTTP API key creation, private listing, MCP use and revocation form a comp
assert.deepEqual(revoked.data.anahtarlar,[]);
assert.equal((await request('/mcp','POST',rpc,anahtar)).status,401);
});
test('concurrent API key requests never exceed quota and malformed input creates nothing',async()=>{
const auth=signToken({email:'quota-http@example.test',name:'Quota QA',isAdmin:true});
const pending=Array.from({length:16},(_,i)=>request('/api/me/apikeys','POST',{ad:`QA ${i}`},auth));
const results=await Promise.all(pending);
assert.equal(results.filter(r=>r.status===200).length,10);
assert.equal(results.filter(r=>r.status===402&&r.data.kod==='KOTA_ASILDI').length,6);
const keys=await request('/api/me/apikeys','GET',null,auth);
assert.equal(keys.data.anahtarlar.length,10);
await request('/api/me/apikeys?id='+keys.data.anahtarlar[0].id,'DELETE',null,auth);
const invalid=await fetch(base+'/api/me/apikeys',{method:'POST',headers:{Authorization:'Bearer '+auth,'Content-Type':'application/json'},body:'{broken'});
assert.equal(invalid.status,400);
assert.equal((await request('/api/me/apikeys','POST',{ad:{}},auth)).status,400);
assert.equal((await request('/api/me/apikeys','GET',null,auth)).data.anahtarlar.length,9);
assert.equal((await request('/api/me/apikeys','POST',{ad:'replacement'},auth)).status,200);
assert.equal((await request('/api/me/apikeys','PUT',{},auth)).status,405);
});
+13
View File
@@ -56,3 +56,16 @@ test('per-tender versions prevent stale updates; five tasks persist', () => {
assert.equal(Object.keys(store.getTenderStates('c@example.test')).length,5);
assert.deepEqual(store.getTenderStates('d@example.test'),{});
});
test('API key quota is transactional and revoked slots can be reused', () => {
const email='quota@example.test';
const key=store.createApiKey(email,' ERP ',{limit:1});
assert.equal(key.ad,'ERP');
assert.throws(()=>store.createApiKey(email,'excess',{limit:1}), {kod:'KOTA_ASILDI'});
assert.equal(store.listApiKeys(email).length,1);
assert.equal(store.revokeApiKey(email,key.id),true);
assert.ok(store.createApiKey(email,'replacement',{limit:1}).id);
assert.equal(store.listApiKeys(email).length,1);
for(const ad of [{},[],42,'x'.repeat(121)])assert.throws(()=>store.createApiKey('invalid-name@example.test',ad));
assert.deepEqual(store.listApiKeys('invalid-name@example.test'),[]);
});