fix(domains): Neuabruf ?refresh=1 nur fuer Verwalter (WR-06)

Jeder Neuabruf sind bis zu 20 Aufrufe auf dem geteilten AutoDNS-Takt; Benutzer
ohne Freigabestufe Verwalten koennten damit Bestellung und Abgleich verdraengen.
Der ModuleGuard legt die wirksame Stufe auf den Request, das Flag wird fuer
Nicht-Verwalter ignoriert (Zwischenspeicher bleibt).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-10-08 11:27:51 +02:00
parent 268d6d55a4
commit 9eada2e082
5 changed files with 51 additions and 12 deletions
@@ -7,6 +7,9 @@ import { DomainsController } from './domains.controller';
const proto = DomainsController.prototype as any;
const req = (tenantId?: string) => ({ tenantId }) as any;
/** Aufrufer mit der Freigabestufe Verwalten (setzt sonst der ModuleGuard). */
const managerReq = (tenantId?: string) => ({ tenantId, moduleAccessLevel: 'MANAGE' }) as any;
const userReq = (tenantId?: string) => ({ tenantId, moduleAccessLevel: 'USE' }) as any;
const MANAGE_HANDLERS = [
'getSettings',
@@ -160,13 +163,13 @@ describe('DomainsController — Verhalten', () => {
await c.createCustomer(req('t1'), { name: 'A' } as any);
await c.updateCustomer(req('t1'), id, { name: 'B' } as any);
await c.deleteCustomer(req('t1'), id);
await c.listContacts(req('t1'), '1');
await c.listContacts(req('t1'), 'true');
await c.listContacts(req('t1'), undefined);
await c.listContacts(req('t1'), '0');
await c.listContacts(managerReq('t1'), '1');
await c.listContacts(managerReq('t1'), 'true');
await c.listContacts(managerReq('t1'), undefined);
await c.listContacts(managerReq('t1'), '0');
await c.createContact(req('t1'), { type: 'PERSON' } as any);
await c.assignContacts(req('t1'), { contactIds: [1], customerId: null });
await c.listDomains(req('t1'), 'true');
await c.listDomains(managerReq('t1'), 'true');
expect(directory.listCustomers).toHaveBeenCalledWith('t1');
expect(directory.createCustomer).toHaveBeenCalledWith('t1', { name: 'A' });
expect(directory.updateCustomer).toHaveBeenCalledWith('t1', id, { name: 'B' });
@@ -185,6 +188,23 @@ describe('DomainsController — Verhalten', () => {
expect(directory.listDomains).toHaveBeenCalledWith('t1', { refresh: true });
});
it('refresh=1 wird ohne Freigabestufe Verwalten ignoriert (kein Neuabruf bei AutoDNS)', async () => {
const directory = makeDirectory();
const c = new DomainsController(makeSettings() as any, directory as any, makeOrders() as any);
await c.listContacts(userReq('t1'), '1');
await c.listContacts(req('t1'), 'true');
await c.listDomains(userReq('t1'), '1');
await c.listDomains(req('t1'), 'true');
expect(directory.listContacts.mock.calls.map((x) => x[1])).toEqual([
{ refresh: false },
{ refresh: false },
]);
expect(directory.listDomains.mock.calls.map((x) => x[1])).toEqual([
{ refresh: false },
{ refresh: false },
]);
});
it('ohne Mandantenkontext 403', async () => {
const c = new DomainsController(
makeSettings() as any,
@@ -222,8 +242,6 @@ describe('DomainsController — Auftraege: Verhalten', () => {
makeDirectory() as any,
makeOrders() as any,
);
await expect(c.submitOrder(req(undefined), user, id)).rejects.toBeInstanceOf(
ForbiddenException,
);
await expect(c.submitOrder(req(undefined), user, id)).rejects.toBeInstanceOf(ForbiddenException);
});
});