diff --git a/Jenkinsfile b/Jenkinsfile
index b3c044e277709d224670dd322fc4d6eb05ec2d72..8cfdb418e18aebe4766b8aec7ee513c711056d9c 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,7 +1,7 @@
 pipeline {
     agent {
         node {
-            label 'jenkins-build-agent-nodejs-16'
+            label 'jenkins-build-agent-nodejs-18'
         }
     }
 
@@ -50,6 +50,7 @@ pipeline {
                     FAILED_STAGE=env.STAGE_NAME
 
                     sh 'npm --version'
+                    sh 'node --version'
                     dir('goofy-client') {
                         sh 'echo "registry=https://nexus.ozg-sh.de/repository/npm-proxy" >> ~/.npmrc'
                         sh 'echo "//nexus.ozg-sh.de/:_auth=amVua2luczprTSFnNVUhMVQzNDZxWQ==" >> ~/.npmrc'
diff --git a/goofy-client/.nvmrc b/goofy-client/.nvmrc
index 5397c87fabfd3917dad11ea66b889b1efa087548..87ec8842b158d213e0477ba0129281a484b9d47d 100644
--- a/goofy-client/.nvmrc
+++ b/goofy-client/.nvmrc
@@ -1 +1 @@
-16.18.1
+18.18.2
diff --git a/goofy-client/apps/goofy-e2e/Jenkinsfile b/goofy-client/apps/goofy-e2e/Jenkinsfile
index 6cf3ad53c272f1997b0095b7e3124851f4cc5d2f..af39449c370c6f429bebd41b81fc0c411067e7bc 100644
--- a/goofy-client/apps/goofy-e2e/Jenkinsfile
+++ b/goofy-client/apps/goofy-e2e/Jenkinsfile
@@ -5,7 +5,7 @@ def SKIP_RUN = false
 pipeline {
     agent {
         node {
-            label 'jenkins-build-agent-nodejs-16'
+            label 'jenkins-build-agent-nodejs-18'
         }
     }
 
diff --git a/goofy-client/apps/goofy-e2e/src/components/postfach/postfach-mail.e2e.component.ts b/goofy-client/apps/goofy-e2e/src/components/postfach/postfach-mail.e2e.component.ts
index a8a9aa827e200e30feae06db4ba17a8e55c93029..6aff70a2ee14d5a996e56e9c07c11ef568b81828 100644
--- a/goofy-client/apps/goofy-e2e/src/components/postfach/postfach-mail.e2e.component.ts
+++ b/goofy-client/apps/goofy-e2e/src/components/postfach/postfach-mail.e2e.component.ts
@@ -27,11 +27,13 @@ import { UserProfileE2EComponent } from '../user-profile/user-profile.component.
 
 export class PostfachMailE2EComponent {
 
-	private readonly locatorCreateMailButtonWithText: string = 'create-mail-button-with-text';
-	private readonly locatorCreateMailButtonWithoutText: string = 'create-mail-button-without-text';
-	private readonly locatorList: string = 'postfach-mail-list';
-	private readonly locatorNoPostfachText: string = 'no-postfach-text';
-	private readonly locatorAttachments: string = 'postfach-nachricht-attachments-container';
+	private readonly createMailButtonWithText: string = 'create-mail-button-with-text';
+	private readonly createMailButtonWithoutText: string = 'create-mail-button-without-text';
+	private readonly list: string = 'postfach-mail-list';
+	private readonly noPostfachText: string = 'no-postfach-text';
+	private readonly attachments: string = 'postfach-nachricht-attachments-container';
+	private readonly downloadButtonWithIcon: string = 'postfach-pdf-export-button';
+	private readonly downloadButtonWithLabel: string = 'postfach-pdf-export-label-button';
 
 	private readonly locatorRoot: string = 'postfach-nachrichten-container-in-vorgang';
 
@@ -40,19 +42,19 @@ export class PostfachMailE2EComponent {
 	}
 
 	public getCreateButtonWithText() {
-		return cy.getTestElement(this.locatorCreateMailButtonWithText);
+		return cy.getTestElement(this.createMailButtonWithText);
 	}
 
 	public getCreateButtonWithoutText() {
-		return cy.getTestElement(this.locatorCreateMailButtonWithoutText);
+		return cy.getTestElement(this.createMailButtonWithoutText);
 	}
 
 	public getList() {
-		return cy.getTestElement(this.locatorList);
+		return cy.getTestElement(this.list);
 	}
 
 	public getNoPostfachText() {
-		return cy.getTestElement(this.locatorNoPostfachText);
+		return cy.getTestElement(this.noPostfachText);
 	}
 
 	public getListItem(subject: string): PostfachMailListItem {
@@ -60,7 +62,15 @@ export class PostfachMailE2EComponent {
 	}
 
 	public getAttachments() {
-		return cy.getTestElement(this.locatorAttachments);
+		return cy.getTestElement(this.attachments);
+	}
+
+	public getDownloadButtonWithIcon() {
+		return cy.getTestElement(this.downloadButtonWithIcon);
+	}
+
+	public getDownloadButtonWithLabel() {
+		return cy.getTestElement(this.downloadButtonWithLabel);
 	}
 }
 
diff --git a/goofy-client/apps/goofy-e2e/src/e2e/main-tests/postfach-mail/postfach-nachrichten.cy.ts b/goofy-client/apps/goofy-e2e/src/e2e/main-tests/postfach-mail/postfach-nachrichten.cy.ts
index a21f78ed8c51b085fa05ae9b5a43aa3cb964bd17..5fda81fdc8f441ae009fffce67b3ced35b825cba 100644
--- a/goofy-client/apps/goofy-e2e/src/e2e/main-tests/postfach-mail/postfach-nachrichten.cy.ts
+++ b/goofy-client/apps/goofy-e2e/src/e2e/main-tests/postfach-mail/postfach-nachrichten.cy.ts
@@ -27,21 +27,33 @@ import { HttpMethodE2E } from '../../../model/util';
 import { VorgangE2E } from '../../../model/vorgang';
 import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po';
 import { VorgangPage } from '../../../page-objects/vorgang.po';
-import { dropCollections, interceptWithResponse } from '../../../support/cypress-helper';
+import { dropCollections, countDownloadFiles, deleteDownloadFolder, interceptWithResponse } from '../../../support/cypress-helper';
 import { exist, notExist } from '../../../support/cypress.util';
 import { LinkRelE2E } from '../../../support/linkrels';
 import { removeLinkFromResource } from '../../../support/tech.util';
 import { loginAsSabine } from '../../../support/user-util';
-import { createVorgang, initVorgang } from '../../../support/vorgang-util';
+import { buildVorgang, createVorgang, initVorgaenge, objectIds } from '../../../support/vorgang-util';
+import { PostfachMailItemE2E, VorgangAttachedItemE2E } from '../../../model/vorgang-attached-item';
+import { createPostfachNachrichtAttachedItem, createPostfachNachrichtReplyItem, initVorgangAttachedItem } from 'apps/goofy-e2e/src/support/vorgang-attached-item-util';
+import { PostfachMailE2EComponent} from 'apps/goofy-e2e/src/components/postfach/postfach-mail.e2e.component';
+import { PostfachMailPage } from 'apps/goofy-e2e/src/page-objects/postfach-mail.component.po';
+
 
 describe('Postfach Nachrichten', () => {
 	const vorgangList: VorgangListE2EComponent = new MainPage().getVorgangList();
 	const vorgangPage: VorgangPage = new VorgangPage();
+	const postfachMailContainer: PostfachMailE2EComponent = vorgangPage.getPostfachMailcontainer();
+	const postfachMailPage: PostfachMailPage = new PostfachMailPage();
 
 	const vorgang: VorgangE2E = createVorgang();
+	const vorgangWithReply: VorgangE2E = { ...buildVorgang(objectIds[0], 'VorgangWithReply') };
+
+	const postfachMailReply: PostfachMailItemE2E = createPostfachNachrichtReplyItem();
+	const postfachNachrichtAttachedItem: VorgangAttachedItemE2E = { ...createPostfachNachrichtAttachedItem(objectIds[1], objectIds[0]), item: postfachMailReply };
 
 	before(() => {
-		initVorgang(vorgang);
+		initVorgaenge([vorgang, vorgangWithReply]);
+		initVorgangAttachedItem([postfachNachrichtAttachedItem]);
 
 		loginAsSabine();
 
@@ -53,7 +65,7 @@ describe('Postfach Nachrichten', () => {
 		dropCollections();
 	})
 
-	describe('navigate to vorganDetail', () => {
+	describe('navigate to vorgangDetail', () => {
 
 		beforeEach(() => {
 			interceptWithResponse(HttpMethodE2E.GET, '*/vorgangs/*', (req) => modifyResponse(req));
@@ -74,4 +86,53 @@ describe('Postfach Nachrichten', () => {
 			notExist(vorgangPage.getPostfachMailcontainer().getRoot());
 		})
 	})
+
+	describe('download nachrichten as pdf', () => {
+
+		describe('by download button on vorgang main page', () => {
+
+			it('should be visible as icon button', () => {
+				vorgangPage.getSubnavigation().getBackButton().click();
+				vorgangList.getListItem(vorgangWithReply.name).getRoot().click();
+				waitForSpinnerToDisappear();
+
+				exist(postfachMailContainer.getDownloadButtonWithLabel());
+			})
+
+			it('should have 1 file in download folder after click on download', () => {
+				postfachMailContainer.getDownloadButtonWithLabel().click();
+				waitForSpinnerToDisappear();
+
+				countDownloadFiles().then((count) => {
+					expect(count).to.eq(1);
+					deleteDownloadFolder();
+				});
+			})
+		})
+
+		describe('by download button on nachrichten details page', () => {
+
+			it ('should show an overview of all nachrichten after clicking on nachricht', () => {
+				postfachMailContainer.getList().click();
+				waitForSpinnerToDisappear();
+
+				exist(postfachMailPage.getRoot());
+			})
+
+			it ('should exist a pdf download button', () => {
+				exist(postfachMailPage.getDownloadButton());
+			})
+
+			it('should have 1 file in download folder after click on download', () => {
+				postfachMailPage.getDownloadButton().click();
+				waitForSpinnerToDisappear();
+
+				countDownloadFiles().then((count) => {
+					expect(count).to.eq(1);
+					deleteDownloadFolder();
+				});
+			})
+		})
+
+	})
 })
\ No newline at end of file
diff --git a/goofy-client/apps/goofy-e2e/src/page-objects/postfach-mail.component.po.ts b/goofy-client/apps/goofy-e2e/src/page-objects/postfach-mail.component.po.ts
index 713082709338690a9594492a2b4cb125d1981078..a7d10ebb4e964c7385f8371e1f0ee99f62890ff9 100644
--- a/goofy-client/apps/goofy-e2e/src/page-objects/postfach-mail.component.po.ts
+++ b/goofy-client/apps/goofy-e2e/src/page-objects/postfach-mail.component.po.ts
@@ -27,13 +27,14 @@ import { PostfachMailListItem } from '../components/postfach/postfach-mail.e2e.c
 
 export class PostfachMailPage {
 
-	private readonly locatorBreadcrump: string = 'postfach-breadcrump';
-	private readonly locatorRoot: string = 'postfach-mail-list';
+	private readonly breadcrump: string = 'postfach-breadcrump';
+	private readonly root: string = 'postfach-mail-list';
+	private readonly downloadButton: string = 'postfach-pdf-export-button';
 
 	private readonly subnavigation: PostfachMailSubnavigation = new PostfachMailSubnavigation();
 
 	getRoot() {
-		return cy.getTestElement(this.locatorRoot);
+		return cy.getTestElement(this.root);
 	}
 
 	getSubnavigation(): PostfachMailSubnavigation {
@@ -41,10 +42,14 @@ export class PostfachMailPage {
 	}
 
 	getBreadcrump() {
-		return cy.getTestElement(this.locatorBreadcrump);
+		return cy.getTestElement(this.breadcrump);
 	}
 
 	getListItem(subject: string): PostfachMailListItem {
 		return new PostfachMailListItem(subject);
 	}
+
+	getDownloadButton() {
+		return cy.getTestElement(this.downloadButton);
+	}
 }
\ No newline at end of file
diff --git a/goofy-client/apps/goofy-e2e/src/support/cypress-tasks.ts b/goofy-client/apps/goofy-e2e/src/support/cypress-tasks.ts
index d92b9e80d3c05c57f3e62671449e84d4ecd40f5b..b8a1bac27dbf39c722b3c2e268d4ef58780c6e54 100644
--- a/goofy-client/apps/goofy-e2e/src/support/cypress-tasks.ts
+++ b/goofy-client/apps/goofy-e2e/src/support/cypress-tasks.ts
@@ -1,5 +1,6 @@
 import { rmdir } from 'fs';
 import { Long, MongoClient, ObjectId } from 'mongodb';
+const fs = require('fs');
 
 const Binary = require('mongodb').Binary;
 
diff --git a/goofy-client/libs/navigation/src/lib/build-info/build-info.component.spec.ts b/goofy-client/libs/navigation/src/lib/build-info/build-info.component.spec.ts
index 80d2be5aa5f629e837d83c542dedef3fdd6419a9..762767d8f4356c2c5d55ab36d9379acef80b0706 100644
--- a/goofy-client/libs/navigation/src/lib/build-info/build-info.component.spec.ts
+++ b/goofy-client/libs/navigation/src/lib/build-info/build-info.component.spec.ts
@@ -39,6 +39,15 @@ jest.mock('@goofy-client/tech-shared', () => {
 
 registerLocaleData(localeDe);
 
+jest.mock('@goofy-client/tech-shared', () => mockAsEsModule('@goofy-client/tech-shared'));
+
+function mockAsEsModule(module: string) {
+	return {
+		__esModule: true,
+		...jest.requireActual(module)
+	};
+}
+
 describe('BuildInfoComponent', () => {
 	let component: BuildInfoComponent;
 	let fixture: ComponentFixture<BuildInfoComponent>;
diff --git a/goofy-client/libs/tech-shared/src/lib/date.util.spec.ts b/goofy-client/libs/tech-shared/src/lib/date.util.spec.ts
index 9e9dc97579f2bded5ac64df66c4fe41c3290039a..4a3d206c39280b9e7b755a1d8c97a434651e85b4 100644
--- a/goofy-client/libs/tech-shared/src/lib/date.util.spec.ts
+++ b/goofy-client/libs/tech-shared/src/lib/date.util.spec.ts
@@ -28,14 +28,16 @@ import { formatDateWithoutYearWithTime, formatForDatabase, formatFullDate, forma
 import faker from '@faker-js/faker';
 import * as dateFns from 'date-fns';
 
-jest.mock('date-fns', () => {
+jest.mock('date-fns', () => mockAsEsModule('date-fns'));
+
+registerLocaleData(localeDe);
+
+function mockAsEsModule(module: string) {
 	return {
 		__esModule: true,
-		...jest.requireActual('date-fns')
+		...jest.requireActual(module)
 	};
-});
-
-registerLocaleData(localeDe);
+}
 
 describe('Date Util', () => {
 
diff --git a/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts b/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts
index 7ac729f843e3c9dd202281dd3742eb4cc8baf5f2..d73dd18fd51493f8598dfca7e2704b1ee57d31a9 100644
--- a/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts
+++ b/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts
@@ -52,12 +52,15 @@ import * as NavigationActions from '@goofy-client/navigation-shared';
 import * as VorgangActions from './vorgang.actions';
 import * as Reducer from './vorgang.reducer';
 
-jest.mock('@goofy-client/app-shared', () => {
+jest.mock('@goofy-client/app-shared', () => mockAsEsModule('@goofy-client/app-shared'));
+
+
+function mockAsEsModule(module: string) {
 	return {
 		__esModule: true,
-		...jest.requireActual('@goofy-client/app-shared')
+		...jest.requireActual(module)
 	};
-});
+}
 
 describe('Vorgang Reducer', () => {
 
diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts
index 9aa3d5bb973a3bdc7e300dc2e2d1befc09a46c9c..59a3d8da2f981ab399f2ca39a4ecea4c9a0916cf 100644
--- a/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts
+++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts
@@ -34,12 +34,14 @@ import { VorgangFilter, VorgangView } from './vorgang.model';
 import * as Storage from '@goofy-client/app-shared';
 import * as VorgangNavigationUtil from './vorgang-navigation.util';
 
-jest.mock('@goofy-client/app-shared', () => {
+jest.mock('@goofy-client/app-shared', () => mockAsEsModule('@goofy-client/app-shared'));
+
+function mockAsEsModule(module: string) {
 	return {
 		__esModule: true,
-		...jest.requireActual('@goofy-client/app-shared')
+		...jest.requireActual(module)
 	};
-});
+}
 
 describe('Vorgang Navigation Util', () => {
 
diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-filter-view.guard.spec.ts b/goofy-client/libs/vorgang/src/lib/vorgang-filter-view.guard.spec.ts
index b789904d1844e5bd2c909d3727207c35bbccc72b..6054a3bfeb759b8002220f09c0ace9654373f675 100644
--- a/goofy-client/libs/vorgang/src/lib/vorgang-filter-view.guard.spec.ts
+++ b/goofy-client/libs/vorgang/src/lib/vorgang-filter-view.guard.spec.ts
@@ -8,16 +8,19 @@ import { Observable, of } from 'rxjs';
 import * as RouterHelper from '@angular/router';
 import * as Guard from './vorgang-filter-view.guard';
 
-jest.mock('@angular/router', () => {
-	return {
-		__esModule: true,
-		...jest.requireActual('@angular/router')
-	};
-});
+jest.mock('@angular/router', () => mockAsEsModule('@angular/router'));
 
 const next: ActivatedRouteSnapshot = {} as unknown as ActivatedRouteSnapshot;
 const state: RouterStateSnapshot = { root: { url: [<UrlSegment>{}] } } as unknown as RouterStateSnapshot;
 
+
+function mockAsEsModule(module: string) {
+	return {
+		__esModule: true,
+		...jest.requireActual(module)
+	};
+}
+
 describe('vorgangFilterViewGuard', () => {
 	const vorgangService = mock(VorgangService);
 	const authService = mock(AuthService);
diff --git a/goofy-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts b/goofy-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts
index 39e5d935dc8c5ab1f6083ff00033d0bd21344e7a..636389e3abc17ce538d651a919a44c5c8ebc579c 100644
--- a/goofy-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts
+++ b/goofy-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts
@@ -44,12 +44,14 @@ import { WiedervorlageService } from './wiedervorlage.service';
 
 import * as TechShared from '@goofy-client/tech-shared';
 
-jest.mock('@goofy-client/tech-shared', () => {
+jest.mock('@goofy-client/tech-shared', () => mockAsEsModule('@goofy-client/tech-shared'));
+
+function mockAsEsModule(module: string) {
 	return {
 		__esModule: true,
-		...jest.requireActual('@goofy-client/tech-shared')
+		...jest.requireActual(module)
 	};
-});
+}
 
 describe('WiedervorlageService', () => {
 	let service: WiedervorlageService;