fix: Berechtigungen der Tagesübersicht, WebDAV-Ausbau, Tests instand gesetzt
Build and Push Multi-Platform Images / build-and-push (push) Successful in 55s
Build and Push Multi-Platform Images / build-and-push (push) Successful in 55s
Die tägliche E-Mail-Zusammenfassung zeigte Nutzern Bereiche, für die sie
keine Berechtigung haben. Zwei unabhängige Ursachen:
- Das Backend prüfte weiterhin die Altgruppe PM_Belege. Die Umbenennung
zu PM_Buchhaltung (ca1d371) war nur im Frontend angekommen, weshalb
der Digest "Manuell bearbeiten" und "In Agrarmonitor" anbot, während
die Oberfläche beide Bereiche sperrte.
- Der Cron-Versand wertet die Gruppen aus user_settings aus. Diese Spalte
wurde nur beim Aufruf der Benutzereinstellungen gefüllt; entzogene
Berechtigungen erreichten den Digest daher unter Umständen nie.
Behoben durch Angleichen des Gruppen-Mappings und den neuen
UserIdentitySyncService, der E-Mail, Benutzername und Gruppen bei jedem
authentifizierten Request aus dem Token spiegelt – ohne den Request zu
blockieren und ohne DB-Zugriff, solange sich das Token nicht ändert. Die
doppelte Identitätspflege im UserSettingsService entfällt.
WebDAV wird nicht eingesetzt und ist entfernt; Export-Ziele bieten nur
noch FTP. Damit verschwindet das ESM-Paket webdav, an dem zwei
Jest-Suites bereits beim Parsen scheiterten.
Veraltete Tests instand gesetzt: email.controller und settings.controller
mockten weniger Abhängigkeiten, als die Klassen inzwischen haben;
postprocessing.service.spec beschrieb noch das alte Regelmodell mit
Einzelfeldern statt FilterJson und ist gegen die heutige Filter-Engine
neu geschrieben (AND/OR, verschachtelte Gruppen, Fehlerprotokollierung).
Enthält außerdem den Arbeitsstand der E-Rechnungs-Mandantenzuordnung, da
sich beide Änderungen dieselben Dateien teilen (SettingsPage, package.json).
98 Tests in 12 Suites grün, Backend- und Frontend-Build sauber.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
32ba772e4e
commit
b7b65c64ae
41 files changed
+2462
-443
No files matched your search
@@ -0,0 +1,51 @@
|
||||
import { PDFDocument } from 'pdf-lib';
|
||||
import { extrahiereEingebetteteDateien } from './pdf-attachment.util';
|
||||
|
||||
const XML = '<?xml version="1.0"?><rsm:CrossIndustryInvoice/>';
|
||||
|
||||
async function pdfMitAnhang(
|
||||
...anhaenge: { name: string; inhalt: string }[]
|
||||
): Promise<Buffer> {
|
||||
const doc = await PDFDocument.create();
|
||||
doc.addPage();
|
||||
for (const a of anhaenge) {
|
||||
await doc.attach(Buffer.from(a.inhalt, 'utf8'), a.name, {
|
||||
mimeType: 'text/xml',
|
||||
});
|
||||
}
|
||||
return Buffer.from(await doc.save());
|
||||
}
|
||||
|
||||
describe('extrahiereEingebetteteDateien', () => {
|
||||
it('liest einen eingebetteten ZUGFeRD-Anhang aus', async () => {
|
||||
const pdf = await pdfMitAnhang({ name: 'factur-x.xml', inhalt: XML });
|
||||
|
||||
const dateien = await extrahiereEingebetteteDateien(pdf);
|
||||
|
||||
expect(dateien).toHaveLength(1);
|
||||
expect(dateien[0].name).toBe('factur-x.xml');
|
||||
expect(dateien[0].inhalt.toString('utf8')).toBe(XML);
|
||||
});
|
||||
|
||||
it('liefert jeden Anhang nur einmal, obwohl er in /Names und /AF steht', async () => {
|
||||
const pdf = await pdfMitAnhang(
|
||||
{ name: 'xrechnung.xml', inhalt: XML },
|
||||
{ name: 'anhang.txt', inhalt: 'Lieferschein' },
|
||||
);
|
||||
|
||||
const dateien = await extrahiereEingebetteteDateien(pdf);
|
||||
|
||||
expect(dateien.map((d) => d.name).sort()).toEqual([
|
||||
'anhang.txt',
|
||||
'xrechnung.xml',
|
||||
]);
|
||||
});
|
||||
|
||||
it('liefert eine leere Liste für ein PDF ohne Anhänge', async () => {
|
||||
const doc = await PDFDocument.create();
|
||||
doc.addPage();
|
||||
const pdf = Buffer.from(await doc.save());
|
||||
|
||||
expect(await extrahiereEingebetteteDateien(pdf)).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user