feat: Security CSRF Fix, Logout optimierung, Footer Anpassung, Rechtstexteanpassung
Docker Image bauen und veroeffentlichen / build-and-push (push) Failing after 1m33s

This commit is contained in:
Nick Szaunig committed 2026-09-03 13:51:50 +02:00
1 parent 0753a3bc8a
commit 4d3100e9ba
28 files changed
+802 -121

No files matched your search

+120 -20
View File
@@ -32,12 +32,11 @@ export const de: Dictionary = {
columnShopping: "Einkaufen",
columnLegal: "Rechtliches",
aboutUs: "Über uns",
shipping: "Versand",
pickup: "Abholung",
businessCustomers: "Geschäftskunden",
trackOrder: "Bestellung verfolgen",
tagline: "Honig aus den Westlichen Wäldern.",
bottomLine: "Geerntet · abgefüllt · versendet aus eigener Imkerei in Altenmünster",
socialAriaLabel: (platform) => `Wabenhain bei ${platform}`,
},
legalTitles: {
impressum: "Impressum",
@@ -168,11 +167,41 @@ export const de: Dictionary = {
sections: [
{
heading: "Angaben gemäß § 5 TMG",
paragraphs: ["[PLATZHALTER] Inhaber: Vor- und Nachname"],
paragraphs: [
"[PLATZHALTER — Name der Inhaberin/des Inhabers bzw. der Geschäftsführung eintragen]",
"[PLATZHALTER — Rechtsform eintragen, z.B. Einzelunternehmen/e.K./GmbH. Sofern im Handelsregister eingetragen: Registergericht und Handelsregisternummer ergänzen.]",
],
},
{
heading: "Umsatzsteuer-ID",
paragraphs: ["[PLATZHALTER] Umsatzsteuer-Identifikationsnummer gemäß §27a Umsatzsteuergesetz."],
paragraphs: [
"[PLATZHALTER] Umsatzsteuer-Identifikationsnummer gemäß § 27a Umsatzsteuergesetz.",
"Sofern stattdessen die Kleinunternehmerregelung nach § 19 UStG angewendet wird, entfällt eine Umsatzsteuer-ID — dies ist an dieser Stelle entsprechend zu vermerken (z.B. \"Gemäß § 19 UStG wird keine Umsatzsteuer berechnet.\").",
],
},
{
heading: "Redaktionell verantwortlich",
paragraphs: [
"Verantwortlich für den redaktionellen Inhalt gemäß § 18 Abs. 2 MStV (u.a. die Beiträge im Bereich \"Honigwissen\"): [Name wie oben].",
],
},
{
heading: "Haftung für Inhalte",
paragraphs: [
"Als Diensteanbieter sind wir gemäß § 7 Abs. 1 TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden entsprechender Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.",
],
},
{
heading: "Haftung für Links",
paragraphs: [
"Unser Angebot enthält Links zu externen Websites Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zu diesem Zeitpunkt nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.",
],
},
{
heading: "Urheberrecht",
paragraphs: [
"Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechts bedürfen der schriftlichen Zustimmung des jeweiligen Erstellers. Downloads und Kopien dieser Seite sind nur für den privaten, nicht kommerziellen Gebrauch gestattet.",
],
},
{
heading: "Streitschlichtung",
@@ -187,53 +216,61 @@ export const de: Dictionary = {
sections: [
{
heading: "1. Verantwortlicher",
paragraphs: ["[PLATZHALTER] Datenschutzbeauftragte/r (falls gesetzlich erforderlich): Name, Kontaktdaten."],
paragraphs: [
"Sofern gesetzlich erforderlich (z.B. bei umfangreicher Verarbeitung besonderer Datenkategorien oder mehr als 20 Personen, die ständig mit der automatisierten Verarbeitung personenbezogener Daten befasst sind, § 38 BDSG), benennen wir hier eine/n Datenschutzbeauftragte/n: [PLATZHALTER — Name und Kontaktdaten eintragen, falls zutreffend].",
],
},
{
heading: "2. Server-Logfiles beim Besuch der Website",
heading: "2. Hosting",
paragraphs: [
"Unsere Website wird bei einem externen Hosting-Anbieter gehostet: [PLATZHALTER — Name und Anschrift des Hosting-Anbieters eintragen]. Mit diesem Anbieter besteht ein Auftragsverarbeitungsvertrag gemäß Art. 28 DSGVO. Der Hosting-Anbieter verarbeitet in unserem Auftrag insbesondere die in den Server-Logfiles (siehe Punkt 3) anfallenden Daten sowie sämtliche über diese Website eingegebenen Daten.",
],
},
{
heading: "3. Server-Logfiles beim Besuch der Website",
paragraphs: [
"Beim Aufruf unserer Website erhebt unser Hosting-Anbieter automatisch technische Zugriffsdaten (z.B. IP-Adresse, Datum und Uhrzeit des Zugriffs, aufgerufene Seite, Browsertyp, Referrer-URL) in sogenannten Server-Logfiles. Diese Verarbeitung ist zur Bereitstellung der Website technisch erforderlich (Art. 6 Abs. 1 lit. f DSGVO) und wird nach kurzer Zeit automatisch gelöscht.",
],
},
{
heading: "3. Bestellung und Vertragsabwicklung",
heading: "4. Bestellung und Vertragsabwicklung",
paragraphs: [
"Bei einer Bestellung erheben wir die für die Vertrags-, Zahlungs- und Versandabwicklung notwendigen Daten (Name, Adresse, E-Mail, ggf. Telefonnummer sowie die bestellten Artikel). Rechtsgrundlage ist Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung).",
"Zahlungen werden über unseren Zahlungsdienstleister Stripe Payments Europe, Ltd. abgewickelt. Dabei werden die für die Zahlungsabwicklung notwendigen Daten an Stripe übermittelt. Es gelten zusätzlich die Datenschutzhinweise von Stripe (stripe.com/de/privacy).",
"Zahlungen werden über unseren Zahlungsdienstleister Stripe Payments Europe, Ltd. abgewickelt. Dabei werden die für die Zahlungsabwicklung notwendigen Daten an Stripe übermittelt. Es gelten zusätzlich die Datenschutzhinweise von Stripe (stripe.com/de/privacy). Soweit dabei Daten an mit Stripe verbundene Unternehmen außerhalb der EU/des EWR (insbesondere Stripe, Inc. in den USA) übermittelt werden, erfolgt dies auf Grundlage von EU-Standardvertragsklauseln gemäß Art. 46 DSGVO.",
"Bestell- und Rechnungsdaten werden aufgrund handels- und steuerrechtlicher Aufbewahrungspflichten (§ 257 HGB, § 147 AO) für die gesetzlich vorgeschriebene Dauer gespeichert.",
],
},
{
heading: "4. Kundenkonto",
heading: "5. Kundenkonto",
paragraphs: [
"Legst du ein Kundenkonto an, speichern wir die von dir angegebenen Daten (Name, E-Mail, Passwort verschlüsselt als Hash) sowie optional hinterlegte Lieferadressen, um dir Bestellhistorie, Rechnungseinsicht und eine schnellere Kasse zu ermöglichen. Rechtsgrundlage ist Art. 6 Abs. 1 lit. b DSGVO. Du kannst dein Konto und die zugehörigen Daten jederzeit über eine formlose Anfrage an uns löschen lassen.",
"Zur Anmeldung wird ein technisch notwendiges Cookie gesetzt, siehe unsere Cookie-Richtlinie.",
],
},
{
heading: "5. Newsletter (Erntepost)",
heading: "6. Newsletter (Erntepost)",
paragraphs: [
"Meldest du dich zu unserer Erntepost an, verwenden wir deine E-Mail-Adresse ausschließlich zum Versand von Informationen über neue Ernten. Rechtsgrundlage ist deine Einwilligung (Art. 6 Abs. 1 lit. a DSGVO). Eine Abmeldung ist jederzeit über den Link in jeder E-Mail oder im Kundenkonto möglich.",
],
},
{
heading: "6. Kontakt- und Firmenkundenformular",
heading: "7. Kontakt- und Firmenkundenformular",
paragraphs: [
"Nimmst du über ein Formular Kontakt zu uns auf (z.B. Firmenkunden-Anfrage), verarbeiten wir die von dir mitgeteilten Daten zur Bearbeitung deiner Anfrage. Rechtsgrundlage ist Art. 6 Abs. 1 lit. b bzw. f DSGVO.",
],
},
{
heading: "7. Google-Rezensionen",
heading: "8. Google-Rezensionen",
paragraphs: [
"Auf unserer Startseite zeigen wir Bewertungen von unserem Google-Unternehmensprofil an. Die Rezensionstexte werden dafür serverseitig über die Google Places API abgerufen; dein Browser baut dabei keine eigene Verbindung zu Google auf. Anbieter: Google Ireland Limited. Es gelten die Datenschutzhinweise von Google (policies.google.com/privacy).",
"Auf unserer Startseite zeigen wir Bewertungen von unserem Google-Unternehmensprofil an. Die Rezensionstexte werden dafür serverseitig über die Google Places API abgerufen; dein Browser baut dabei keine eigene Verbindung zu Google auf. Anbieter: Google Ireland Limited, wobei eine Übermittlung an die Google LLC (USA) nicht ausgeschlossen werden kann. Es gelten die Datenschutzhinweise von Google (policies.google.com/privacy).",
],
},
{
heading: "8. Cookies",
heading: "9. Cookies",
paragraphs: ["Details zu den auf dieser Website eingesetzten Cookies findest du in unserer Cookie-Richtlinie."],
},
{
heading: "9. Deine Rechte",
heading: "10. Deine Rechte",
paragraphs: [
"Du hast das Recht auf Auskunft (Art. 15 DSGVO), Berichtigung (Art. 16 DSGVO), Löschung (Art. 17 DSGVO), Einschränkung der Verarbeitung (Art. 18 DSGVO), Datenübertragbarkeit (Art. 20 DSGVO) sowie Widerspruch gegen die Verarbeitung (Art. 21 DSGVO) deiner personenbezogenen Daten.",
"Zudem steht dir ein Beschwerderecht bei einer Datenschutz-Aufsichtsbehörde zu, z.B. dem Bayerischen Landesamt für Datenschutzaufsicht.",
@@ -246,22 +283,61 @@ export const de: Dictionary = {
sections: [
{
heading: "1. Geltungsbereich",
paragraphs: ["Diese AGB gelten für alle Bestellungen über wabenhain.com zwischen Wabenhain und ihren Kund:innen."],
paragraphs: [
"Diese Allgemeinen Geschäftsbedingungen (AGB) gelten für alle Bestellungen über wabenhain.com zwischen Wabenhain und ihren Kund:innen, sowohl Verbraucher:innen im Sinne des § 13 BGB als auch Unternehmer:innen im Sinne des § 14 BGB.",
],
},
{
heading: "2. Vertragsschluss",
paragraphs: [
"Die Darstellung der Produkte im Shop stellt kein bindendes Angebot dar. Mit Abschluss der Bestellung gibst du ein verbindliches Angebot zum Kauf ab, das wir durch eine Bestätigung annehmen.",
"Die Darstellung der Produkte im Shop stellt kein bindendes Angebot dar, sondern eine unverbindliche Aufforderung, eine Bestellung aufzugeben. Mit Abschluss der Bestellung gibst du ein verbindliches Angebot zum Kauf ab, das wir durch eine Bestätigung per E-Mail oder durch Lieferung der Ware annehmen.",
],
},
{
heading: "3. Preise und Versandkosten",
paragraphs: ["Alle Preise verstehen sich inklusive der gesetzlichen Umsatzsteuer. Versandkosten werden im Checkout transparent ausgewiesen."],
paragraphs: ["Alle Preise verstehen sich inklusive der gesetzlichen Umsatzsteuer. Versandkosten werden im Checkout transparent ausgewiesen, siehe auch unsere Seite \"Versand und Zahlung\"."],
},
{
heading: "4. Lieferung und Abholung",
heading: "4. Zahlungsarten",
paragraphs: [
"Wir bieten PayPal, Kreditkarte, Apple Pay und Google Pay über unseren Zahlungsdienstleister Stripe an. Eine Zahlung per Überweisung ist auf Anfrage möglich. Details siehe unsere Seite \"Versand und Zahlung\" sowie unsere Datenschutzerklärung zu Stripe.",
"Die Kaufpreiszahlung ist grundsätzlich sofort mit Bestellung fällig (Vorkasse über den gewählten Zahlungsdienst), sofern nichts anderes vereinbart wurde.",
],
},
{
heading: "5. Lieferung und Abholung",
paragraphs: ["Wir liefern innerhalb Deutschlands. Alternativ kann die Ware nach Absprache direkt bei uns in Altenmünster abgeholt werden."],
},
{
heading: "6. Widerrufsrecht",
paragraphs: [
"Verbraucher:innen steht grundsätzlich ein gesetzliches Widerrufsrecht zu. Einzelheiten, insbesondere zu Ausnahmen bei schnell verderblichen Waren wie Honig, entnimmst du unserer separaten Widerrufsbelehrung.",
],
},
{
heading: "7. Gewährleistung",
paragraphs: [
"Es gelten die gesetzlichen Gewährleistungsrechte (§§ 434 ff. BGB). Bei Verbraucher:innen beträgt die Verjährungsfrist für Mängelansprüche zwei Jahre ab Ablieferung der Ware.",
"Bei Lebensmitteln wie Honig weist das aufgedruckte Mindesthaltbarkeitsdatum (MHD) darauf hin, bis wann das Produkt bei sachgerechter Lagerung mindestens seine spezifischen Eigenschaften behält — es handelt sich nicht um ein Verfallsdatum und begründet für sich genommen keinen Mangel.",
],
},
{
heading: "8. Eigentumsvorbehalt",
paragraphs: ["Die gelieferte Ware bleibt bis zur vollständigen Bezahlung unser Eigentum."],
},
{
heading: "9. Streitschlichtung",
paragraphs: [
"Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit: https://ec.europa.eu/consumers/odr. Wir sind nicht verpflichtet und nicht bereit, an einem Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.",
],
},
{
heading: "10. Schlussbestimmungen",
paragraphs: [
"Es gilt das Recht der Bundesrepublik Deutschland unter Ausschluss des UN-Kaufrechts. Bei Verbraucher:innen gilt dies nur, soweit hierdurch der durch zwingende Bestimmungen des Rechts des gewöhnlichen Aufenthaltslandes gewährte Schutz nicht entzogen wird.",
"Sollte eine Bestimmung dieser AGB unwirksam sein oder werden, bleibt die Wirksamkeit der übrigen Bestimmungen hiervon unberührt.",
],
},
],
},
widerrufPage: {
@@ -790,6 +866,11 @@ export const de: Dictionary = {
colLocation: "Standort",
colBatches: "Chargen",
colProducts: "Produkte",
colStatus: "Status",
statusPublished: "Veröffentlicht",
statusDraft: "Entwurf",
publish: "Veröffentlichen",
unpublish: "Verbergen",
edit: "Bearbeiten",
noHarvestsYet: "Noch keine Ernten angelegt.",
newHarvestHeading: "Neue Ernte anlegen",
@@ -798,7 +879,15 @@ export const de: Dictionary = {
harvestDateLabel: "Erntedatum",
locationLabel: "Standort",
descriptionLabel: "Beschreibung",
isPublishedLabel: "Sofort veröffentlichen",
create: "Anlegen",
syncHeading: "ApiCore-Synchronisierung",
syncIntro:
"Importiert Ernten aus ApiCore als Entwürfe (nicht öffentlich sichtbar). Bereits veröffentlichte, zuvor synchronisierte Ernten werden dabei nicht verändert — nur neue oder noch unveröffentlichte Entwürfe werden aktualisiert.",
syncButton: "Jetzt synchronisieren",
syncResult: (created, updated, skipped, failed) =>
`Synchronisierung abgeschlossen: ${created} neu angelegt, ${updated} aktualisiert, ${skipped} übersprungen (bereits veröffentlicht)${failed > 0 ? `, ${failed} fehlgeschlagen` : ""}.`,
syncError: "Synchronisierung mit ApiCore fehlgeschlagen.",
},
adminHarvestEditPage: {
backToHarvests: "Zurück zu Ernten",
@@ -808,6 +897,10 @@ export const de: Dictionary = {
harvestDateLabel: "Erntedatum",
locationLabel: "Standort",
descriptionLabel: "Beschreibung",
isPublishedLabel: "Öffentlich sichtbar",
isPublishedHint: "Steuert, ob diese Ernte auf der Website (Shop, /ernten) sichtbar ist.",
draftNotice: "Diese Ernte ist aktuell nur im Admin-Bereich sichtbar (z.B. aus ApiCore importiert). Bitte Angaben prüfen und danach veröffentlichen.",
publishNow: "Jetzt veröffentlichen",
save: "Speichern",
},
adminProductsPage: {
@@ -945,6 +1038,10 @@ export const de: Dictionary = {
carrierPlaceholder: "z.B. DHL, DPD, Hermes",
trackingNumberLabel: "Sendungsnummer",
saveTracking: "Speichern",
dhlHeading: "DHL-Versandmarke",
dhlCreateButton: "Versandmarke erstellen",
dhlAlreadyCreated: (trackingNumber) => `DHL-Versandmarke bereits erstellt — Sendungsnummer ${trackingNumber}`,
dhlNotConfigured: "DHL ist noch nicht konfiguriert, siehe .env (DHL_API_KEY, DHL_API_SECRET, DHL_GKP_USERNAME, DHL_GKP_PASSWORD, DHL_ACCOUNT_NUMBER).",
},
adminOrdersPage: {
backToDashboard: "Zurück zum Dashboard",
@@ -998,6 +1095,7 @@ export const de: Dictionary = {
groupCompany: "Firmendaten",
groupHome: "Homepage",
groupLegal: "Rechtstexte",
groupSocial: "Social Media",
deLabel: "Deutsch",
enLabel: "Englisch",
save: "Speichern",
@@ -1071,6 +1169,8 @@ export const de: Dictionary = {
firstNameLabel: "Vorname",
lastNameLabel: "Nachname",
forgotPassword: "Passwort vergessen?",
ssoDivider: "oder",
ssoButton: "Mit Microsoft anmelden",
greeting: (name) => `Hallo, ${name}`,
verifyEmailPrompt: "Bitte bestätige deine E-Mail-Adresse — ohne Bestätigung kannst du mit diesem Konto nicht bestellen.",
resendVerification: "Link erneut senden",
@@ -1090,7 +1190,7 @@ export const de: Dictionary = {
subscribe: "Anmelden",
unsubscribe: "Abmelden",
logoutAllDevicesHeading: "Alle Geräte abmelden",
logoutAllDevicesDescription: "Beendet alle aktiven Sitzungen auf anderen Geräten.",
logoutAllDevicesDescription: "Beendet alle aktiven Sitzungen, auch dieses Gerät. Du musst dich danach neu anmelden.",
logout: "Abmelden",
privacy: {
heading: "Datenschutz",