diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 2ef7e3d..b549fd8 100644 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -10,7 +10,10 @@ STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM) FAIL=0 # Allow legitimate locations (Impressum, privacy, terms, COMMERCIAL-LICENSE, gdpr-design, self-hosting). -ALLOW_RE='^(app/templates/(impressum|privacy|terms)\.html|COMMERCIAL-LICENSE\.md|docs/gdpr-account-deletion-design\.md|docs/api-usage-guide\.md|docs/self-hosting\.md|docs-internal/.*|\.githooks/.*|\.github/workflows/scope-guard\.yml|CHANGELOG\.md)$' +# locale/ catalogs are mechanically extracted from the impressum/privacy/terms templates above — +# they cannot avoid carrying the same address/email strings. Treating them as public is consistent +# with the source templates being public. +ALLOW_RE='^(app/templates/(impressum|privacy|terms)\.html|COMMERCIAL-LICENSE\.md|docs/gdpr-account-deletion-design\.md|docs/api-usage-guide\.md|docs/self-hosting\.md|docs-internal/.*|\.githooks/.*|\.github/workflows/scope-guard\.yml|CHANGELOG\.md|locale/.*\.(po|pot|mo))$' # Personal/operational identifiers that should never land in public code. PATTERNS='lennart\.seidel@icloud\.com|lennart@filemorph\.io|Reetwerder|21029 Hamburg' diff --git a/.githooks/pre-push b/.githooks/pre-push index a013e39..9583fe8 100644 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -15,7 +15,7 @@ set -e ZERO=0000000000000000000000000000000000000000 # Same patterns as pre-commit — keep in sync. -ALLOW_RE='^(app/templates/(impressum|privacy|terms)\.html|COMMERCIAL-LICENSE\.md|docs/gdpr-account-deletion-design\.md|docs/api-usage-guide\.md|docs/self-hosting\.md|docs-internal/.*|\.githooks/.*|\.github/workflows/scope-guard\.yml|CHANGELOG\.md)$' +ALLOW_RE='^(app/templates/(impressum|privacy|terms)\.html|COMMERCIAL-LICENSE\.md|docs/gdpr-account-deletion-design\.md|docs/api-usage-guide\.md|docs/self-hosting\.md|docs-internal/.*|\.githooks/.*|\.github/workflows/scope-guard\.yml|CHANGELOG\.md|locale/.*\.(po|pot|mo))$' PATTERNS='lennart\.seidel@icloud\.com|lennart@filemorph\.io|Reetwerder|21029 Hamburg' OPS_PATTERNS='/opt/filemorph(/|$|[[:space:]])|/var/log/filemorph|/home/deploy([[:space:]]|/)|Hetzner CX|HETZNER_HOST|HETZNER_SSH_USER|HETZNER_SSH_KEY|OPS_REPO_DISPATCH_PAT|GHCR_PAT|appleboy/ssh-action' SECRET_ASSIGN='(JWT_SECRET|SMTP_PASSWORD|STRIPE_SECRET_KEY|STRIPE_WEBHOOK_SECRET|DATABASE_URL|API_KEY|POSTGRES_PASSWORD|GHCR_PAT|OPS_REPO_DISPATCH_PAT|HETZNER_SSH_KEY)[[:space:]]*=[[:space:]]*[^[:space:]$]' diff --git a/README.md b/README.md index 99af800..e44fc30 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ FileMorph runs in three editions, all built from this repository: |---|---|---| | **Community** | Self-hosted (Docker, source) | File conversion + compression, REST API, single-user API-key auth | | **Cloud SaaS** | [filemorph.io](https://filemorph.io) | Community features + user accounts (JWT), tier quotas, Stripe billing, admin cockpit | -| **Compliance** | Self-hosted with commercial licence | Cloud-Edition features + tamper-evident audit log (SHA-256 hash chain), `X-Output-SHA256` integrity header, PDF/A-2b output (veraPDF-validated), default-on EXIF/XMP/IPTC strip, `X-Data-Classification` header, self-service account deletion, signed images (cosign) + signed releases (GPG). For DACH Behörden, Krankenhäuser, and Anwaltskanzleien. | +| **Compliance** | Self-hosted with commercial licence | Cloud-Edition features + tamper-evident audit log (SHA-256 hash chain), `X-Output-SHA256` integrity header, PDF/A-2b output (CI gate validated against veraPDF for a worst-case fixture), default-on EXIF/XMP/IPTC strip, `X-Data-Classification` header, self-service account deletion, signed images (cosign) + cryptographically signed releases. For DACH Behörden, Krankenhäuser, and Anwaltskanzleien. | The README and `docs/` are written for the **Community** edition. The Cloud-Edition features (account registration, Stripe checkout, admin diff --git a/app/api/routes/billing.py b/app/api/routes/billing.py index 467e051..d4a4524 100644 --- a/app/api/routes/billing.py +++ b/app/api/routes/billing.py @@ -8,9 +8,11 @@ from sqlalchemy.ext.asyncio import AsyncSession from app.api.routes.auth import get_current_user +from app.core.audit import record_event from app.core.config import settings from app.db.base import get_db from app.db.models import TierEnum, User +from app.models.schemas import CheckoutRequest logger = logging.getLogger(__name__) @@ -34,14 +36,27 @@ def _stripe_enabled() -> None: @router.post("/checkout/{tier}") async def create_checkout_session( tier: str, + body: CheckoutRequest, + request: Request, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): - """Create a Stripe Checkout session for the given tier (pro | business).""" + """Create a Stripe Checkout session for the given tier (pro | business). + + Requires `withdrawal_waiver_acknowledged: true` in the request body so the + user has explicitly waived their 14-day §312g BGB / §356 (5) BGB right of + withdrawal — the consent is recorded as a SHA-256 hash-chained audit event + so it can be reproduced at dispute time. + """ _stripe_enabled() price_id = _TIER_TO_PRICE.get(tier, "") if not price_id: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid tier.") + if not body.withdrawal_waiver_acknowledged: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="withdrawal_waiver_required", + ) stripe.api_key = settings.stripe_secret_key @@ -55,6 +70,15 @@ async def create_checkout_session( await db.commit() customer_id = customer.id + actor_ip = request.client.host if request.client else None + await record_event( + event_type="billing.checkout.withdrawal_waiver_recorded", + actor_user_id=user.id, + actor_ip=actor_ip, + payload={"tier": tier}, + db=db, + ) + session = stripe.checkout.Session.create( customer=customer_id, payment_method_types=["card"], diff --git a/app/core/jsonld.py b/app/core/jsonld.py index 8d5172d..e1b5b86 100644 --- a/app/core/jsonld.py +++ b/app/core/jsonld.py @@ -49,7 +49,7 @@ def build_site_jsonld(app_base_url: str) -> tuple[str, str]: "operatingSystem": "Any", "offers": {"@type": "Offer", "price": "0", "priceCurrency": "EUR"}, "description": ( - "Privacy-first file converter & compressor — open-source and self-hostable." + "Privacy-respecting file converter & compressor — open-source and self-hostable." ), }, { diff --git a/app/models/schemas.py b/app/models/schemas.py index 1ce93e9..5f43f74 100644 --- a/app/models/schemas.py +++ b/app/models/schemas.py @@ -19,3 +19,16 @@ class FormatsResponse(BaseModel): class ErrorResponse(BaseModel): detail: str + + +class CheckoutRequest(BaseModel): + """Body schema for POST /billing/checkout/{tier}. + + The user must explicitly waive their 14-day right of withdrawal under + §312g BGB / §356(5) BGB before paid-tier API access can be activated + immediately on Stripe checkout completion. Without this acknowledgement + the request is rejected with HTTP 400 — the standard 14-day withdrawal + protection then applies and immediate activation is deferred. + """ + + withdrawal_waiver_acknowledged: bool = False diff --git a/app/static/js/pricing.js b/app/static/js/pricing.js index fd5e179..3d9ffe0 100644 --- a/app/static/js/pricing.js +++ b/app/static/js/pricing.js @@ -1,5 +1,18 @@ // SPDX-License-Identifier: AGPL-3.0-or-later document.addEventListener('DOMContentLoaded', () => { + // Wire withdrawal-waiver checkboxes to enable/disable their target buttons. + // The checkbox + button pair represents an explicit two-step §356 (5) BGB + // consent: the button stays disabled until the user actively ticks the + // waiver box. The `data-target` attribute names the button id. + document.querySelectorAll('.withdrawal-waiver').forEach((cb) => { + const targetId = cb.dataset.target; + const btn = document.getElementById(targetId); + if (!btn) return; + cb.addEventListener('change', () => { + btn.disabled = !cb.checked; + }); + }); + const proBtn = document.getElementById('pro-btn'); const bizBtn = document.getElementById('business-btn'); if (proBtn) proBtn.addEventListener('click', () => upgrade('pro')); @@ -12,18 +25,28 @@ async function upgrade(tier) { window.location.href = '/register?next=pricing'; return; } - var btn = document.getElementById(tier + '-btn'); + const waiver = document.getElementById(tier + '-waiver'); + if (!waiver || !waiver.checked) { + // The button shouldn't be clickable without the checkbox, but guard + // anyway in case the markup or DOM is altered. + return; + } + const btn = document.getElementById(tier + '-btn'); btn.disabled = true; - btn.textContent = 'Redirecting\u2026'; + btn.textContent = 'Redirecting…'; try { - var res = await window.FM.authFetch('/api/v1/billing/checkout/' + tier, { method: 'POST' }); + const res = await window.FM.authFetch('/api/v1/billing/checkout/' + tier, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ withdrawal_waiver_acknowledged: true }), + }); if (res.status === 503) { btn.disabled = false; btn.textContent = tier === 'pro' ? 'Upgrade to Pro' : 'Upgrade to Business'; alert('Payments are not yet active. Please check back soon.'); return; } - var data = await res.json(); + const data = await res.json(); if (data.url) window.location.href = data.url; } catch (e) { btn.disabled = false; diff --git a/app/templates/base.html b/app/templates/base.html index d49c248..bb23c71 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -12,7 +12,7 @@ - + {% call uc.card() %} @@ -13,10 +13,10 @@

Dashboard

?
-

Loading…

+

{{ _('Loading…') }}

-

Member since

+

{{ _('Member since') }}

{% endcall %} @@ -26,28 +26,28 @@

Dashboard

-

API Keys

-

Use these to authenticate programmatic API requests.

+

{{ _('API Keys') }}

+

{{ _('Use these to authenticate programmatic API requests.') }}

- {{ ub.button('+ New Key', id='create-key-btn', size='sm') }} + {{ ub.button(_('+ New Key'), id='create-key-btn', size='sm') }}
-

Loading…

+

{{ _('Loading…') }}

{% endcall %} diff --git a/app/templates/enterprise.html b/app/templates/enterprise.html index f0e9760..f16aaf9 100644 --- a/app/templates/enterprise.html +++ b/app/templates/enterprise.html @@ -1,347 +1,336 @@ {% extends "base.html" %} -{% block title %}Compliance Edition — FileMorph{% endblock %} +{% block title %}{{ _('Compliance Edition') }} — FileMorph{% endblock %} {% block content %}
+ {% if locale == 'en' %} +
+

{{ _('FileMorph operates under German law (Hamburg).') }}

+

{{ _('Compliance assertions on this page cite German statutes (HGB §257, AO §147, DSGVO Art 17). This English translation is provided for accessibility — the German version is the authoritative legal text in case of conflict.') }}

+
+ {% endif %} +
-

FileMorph Compliance Edition

+

{{ _('FileMorph Compliance Edition') }}

- DSGVO-konforme File-Engine für die regulierte Verwaltung. + {{ _('GDPR-aligned file engine for regulated administration.') }}

- Self-hosted hinter Ihrer Firewall. AGPLv3 + kommerzielle Lizenz. - EU-Vendor mit deutschem Impressum, Auftragsverarbeitungs-Vorlage, - und SBOM in jedem Release. + {{ _('Self-hosted behind your firewall. AGPLv3 + commercial license. EU vendor with German imprint, individually drafted DPA template in pilot conversation, and SBOM in every release.') }}

-

Engineering-Beweis vor dem Vertrag

+

{{ _('Engineering proof before contract') }}

-

SHA-256-Audit-Log

-

Jede Operation in einer fortlaufenden Hash-Chain. Manipulation an einer alten Zeile bricht die nachfolgende Kette.

+

{{ _('SHA-256 audit log') }}

+

{{ _('Every operation in a continuous hash chain. Tampering with an old row breaks every following one.') }}

-

Signiertes Image + SBOM

-

cosign-keyless-OIDC, GPG-signierte Git-Tags, CycloneDX-JSON-SBOM in jedem GitHub-Release.

+

{{ _('Signed image + SBOM') }}

+

{{ _('cosign keyless OIDC, cryptographically signed git tags, CycloneDX-JSON SBOM in every GitHub release.') }}

-

PDF/A-2b veraPDF-validiert

-

Konformitäts-Gate läuft als CI-Workflow. Kein Release ohne grünes veraPDF gegen einen Worst-Case-Source-PDF.

+

{{ _('PDF/A-2b veraPDF-validated') }}

+

{{ _('Conformance gate runs as CI workflow. No release without green veraPDF against a worst-case source PDF.') }}

- +
-

Tier-Übersicht

-

Server-Volumen-basiert, nicht per User-Seat. Verbindliche Konditionen folgen dem persönlichen Gespräch.

+

{{ _('Tier overview') }}

+

{{ _('Server-volume-based, not per user seat. Binding terms follow the personal conversation.') }}

- - - + + + - - - + + + - - - + + + - - - + + +
TierUmfangPreis / Jahr{{ _('Tier') }}{{ _('Scope') }}{{ _('Price / year') }}
Compliance Starter1 Server, ≤ 50 Mitarbeitende€ 1.490{{ _('Compliance Starter') }}{{ _('1 server, ≤ 50 employees') }}€ 1,490
Compliance Standard3 Server, ≤ 2.000 Mitarbeitende€ 7.490{{ _('Compliance Standard') }}{{ _('3 servers, ≤ 2,000 employees') }}€ 7,490
Compliance Enterpriseunbegrenzte Server, dediziertes Onboarding, Custom-SLAab € 24.900{{ _('Compliance Enterprise') }}{{ _('unlimited servers, dedicated onboarding, custom SLA') }}{{ _('from € 24,900') }}

- KRITIS- und Air-Gap-Varianten auf Anfrage. Alle Tiers enthalten kommerzielle Lizenz, AVV-Vorlage, signiertes Docker-Image und Support-SLA. + {{ _('KRITIS and air-gap variants on request. All tiers include commercial license, DPA template, signed Docker image and support SLA.') }}

-

Warum eine Compliance-Edition?

+

{{ _('Why a Compliance Edition?') }}

- Behörden, Krankenhäuser und Kanzleien dürfen Bürger- und Mandantendaten - in vielen Fällen nicht durch öffentliche Cloud-Konvertierungs-Dienste - verarbeiten — die DSGVO-Datenkette und das EVB-IT-Vertragswerk setzen - hier enge Grenzen. Gleichzeitig fehlt der typischen IT-Abteilung die - Bandbreite, ein Konvertierungs-Backend selbst zu pflegen. + {{ _('Public authorities, hospitals and law firms often may not process citizen and client data through public cloud conversion services — the GDPR data chain and the EVB-IT contract framework set tight limits here. At the same time, the typical IT department lacks the bandwidth to maintain a conversion backend on its own.') }}

- FileMorph schließt diese Lücke: Die Open-Source-Engine deckt 16+ - Format-Paare ab und läuft auf Ihrer eigenen Hetzner / On-Premise / - Air-Gap-Infrastruktur. Die Compliance-Edition liefert zusätzlich die - Verträge, die SLAs und die Roadmap-Garantien, die ein - EVB-IT-konformer Einkauf voraussetzt. + {{ _('FileMorph closes this gap: the open-source engine covers 16+ format pairs and runs on your own Hetzner / on-premises / air-gap infrastructure. The Compliance Edition additionally provides the contracts, SLAs and roadmap guarantees that an EVB-IT-compliant procurement requires.') }}

-

Inhalt der Compliance-Edition

+

{{ _('What\'s in the Compliance Edition') }}

-

Kommerzielle Lizenz

-

Hebt die AGPLv3-Veröffentlichungspflicht für interne Eigenentwicklungen + öffentliche Bürgerportal-Integrationen auf.

+

{{ _('Commercial license') }}

+

{{ _('Lifts the AGPLv3 publication obligation for internal in-house developments + public citizen-portal integrations.') }}

-

Auftragsverarbeitungs-Vertrag (AVV)

-

DSGVO Art. 28-konforme Vorlage, an Ihre Behörden- oder Klinik-Spezifika angepasst.

+

{{ _('Data Processing Agreement (DPA)') }}

+

{{ _('GDPR Art. 28-compliant DPA — drafted jointly in the pilot conversation and adapted to your authority or clinic specifics.') }}

-

Audit-Log mit Hash-Chain

-

SHA-256-verkettetes Operations-Log, ISO 27001 A.12.4.1 / BORA §50 / BeurkG §39a.

+

{{ _('Audit log with hash chain') }}

+

{{ _('SHA-256-chained operations log, ISO 27001 A.12.4.1 / BORA §50 / BeurkG §39a.') }}

-

PDF/A-2b-Output

-

Validiert nach veraPDF — für beA-Anhänge, Bürgerantrags-Archivierung, BSI TR-RESISCAN.

+

{{ _('PDF/A-2b output') }}

+

{{ _('Conformance secured by veraPDF CI gate against a worst-case source PDF — for beA attachments, citizen-application archiving, BSI TR-RESISCAN.') }}

-

Signierte Releases + SBOM

-

cosign-signiertes Docker-Image, GPG-signierte Git-Tags, CycloneDX-JSON-SBOM in jedem Release. Auf die EVB-IT-Cloud-Klausel (März 2026) ausgerichtet.

+

{{ _('Signed releases + SBOM') }}

+

{{ _('cosign-signed Docker image, cryptographically signed git tags, CycloneDX-JSON SBOM in every release. Aligned with the EVB-IT cloud clause (March 2026).') }}

-

Support-SLA

-

Reaktionszeit nach Schweregrad — kritisch 4 h, hoch 24 h, mittel/niedrig im nächsten regulären Release.

+

{{ _('Support SLA') }}

+

{{ _('Response-time targets by severity — critical 4 h, high 24 h, medium/low in the next regular release. Targets apply Mon–Fri 09:00–18:00 CET, excluding German public holidays.') }}

- +
-

Design-Partner-Programm

+

{{ _('Design Partner Programme') }}

- Drei Plätze. Sechs Monate kostenfrei. Direkter Einfluss auf die - Roadmap der Compliance-Edition. + {{ _('Three spots. Six months free. Direct influence on the Compliance Edition roadmap.') }}

-

Was Sie geben

-

Logo-Nennung als Pilotkunde (optional). Roadmap-Feedback alle vier Wochen. Bereitschaft, Feature-Tickets zu priorisieren.

+

{{ _('What you give') }}

+

{{ _('Logo mention as pilot customer (optional). Roadmap feedback every four weeks. Willingness to prioritize feature tickets.') }}

-

Was Sie bekommen

-

Vollständige Compliance-Edition. Onboarding gemeinsam mit dem Maintainer. Bug-Hotfix mit Priorität.

+

{{ _('What you get') }}

+

{{ _('Full Compliance Edition. Onboarding together with the maintainer. Priority bug hotfixes.') }}

-

Wer passt

-

Behörde, Klinik-IT, Anwaltskanzlei mit konkretem DSGVO-Konvertierungs-Use-Case. Wir filtern auf Pilotreife — nicht jeder Interessent passt.

+

{{ _('Who\'s a fit') }}

+

{{ _('Public authority, clinic IT, law firm with a concrete GDPR conversion use case. We filter for pilot readiness — not every applicant fits.') }}

- +
-

Was wir gegenüber typischen Alternativen liefern

-

Eine Orientierung über die in DACH-RFPs gängigen Anbieter-Kategorien. Im Einzelfall kann ein konkretes Produkt mehr leisten — bitte individuell prüfen.

+

{{ _('What we deliver compared to typical alternatives') }}

+

{{ _('An orientation about the provider categories common in DACH RFPs. In individual cases, a specific product may do more — please check individually.') }}

- - - - + + + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + +
KriteriumFileMorph
Compliance
Typische Open-Source-KonvertiererTypische SaaS-Konvertierer{{ _('Criterion') }}FileMorph
{{ _('Compliance') }}
{{ _('Typical open-source converters') }}{{ _('Typical SaaS converters') }}
Self-Hosted (Daten bleiben im Haus){{ _('Self-hosted (data stays in-house)') }} häufig ✓selten{{ _('often ✓') }}{{ _('rare') }}
DSGVO-AVV-Vorlage in deutscher Form{{ _('GDPR DPA template in German form') }} seltenvariabel{{ _('rare') }}{{ _('varies') }}
Audit-Log mit Hash-Chain{{ _('Audit log with hash chain') }} variabelvariabel{{ _('varies') }}{{ _('varies') }}
PDF/A-2b veraPDF-validiert{{ _('PDF/A-2b veraPDF-validated') }} variabelvariabel{{ _('varies') }}{{ _('varies') }}
Multi-Format (Bild + Audio + Video + Sheet){{ _('Multi-format (image + audio + video + sheet)') }} häufig auf einen Bereich beschränkthäufig ✓{{ _('often limited to one area') }}{{ _('often ✓') }}
EU-Vendor mit deutschem Impressum{{ _('EU vendor with German imprint') }} variabelvariabel{{ _('varies') }}{{ _('varies') }}
Kommerzielle Lizenz auf AGPL-Code{{ _('Commercial license on AGPL code') }} seltennicht zutreffend{{ _('rare') }}{{ _('not applicable') }}

- Die Tabelle beschreibt typische Eigenschaften der genannten Anbieter-Kategorien und ist kein abschließender Vergleich konkreter Produkte. Einzelne Anbieter können mehr oder weniger leisten — bitte das jeweils aktuelle Angebot direkt beim Hersteller prüfen. + {{ _('The table describes typical characteristics of the named provider categories and is not a definitive comparison of specific products. Individual providers may do more or less — please check the current offer directly with the manufacturer.') }}

- +
-

Vertrauensbasis vor dem Vertrag

-

Sie können FileMorph vor dem ersten Gespräch vollständig prüfen. Alle relevanten Sicherheits- und Architektur-Dokumente sind frei zugänglich:

+

{{ _('Trust basis before contract') }}

+

{{ _('You can fully audit FileMorph before the first conversation. All relevant security and architecture documents are freely accessible:') }}

-

Häufige Fragen

+

{{ _('Frequently asked questions') }}

-

Hosten Sie auch, wenn wir nicht selbst betreiben können?

-

Compliance-Edition ist self-hosted. Wenn Sie keine eigene Infrastruktur betreiben können, ist filemorph.io (Cloud-Edition) der richtige Pfad — andere Datenklasse, andere Verträge, kein EVB-IT-Anker.

+

{{ _('Do you also host if we can\'t operate ourselves?') }}

+

{{ _('The Compliance Edition is self-hosted. If you can\'t operate your own infrastructure, filemorph.io (Cloud Edition) is the right path — different data class, different contracts, no EVB-IT anchor.') }}

-

Was passiert, wenn wir kündigen?

-

Sie behalten den Code (AGPLv3 bleibt). Sie verlieren die kommerzielle Lizenz, das aktualisierte AVV, neue Releases mit Compliance-Features, und den Support-SLA. Bestehende Installationen laufen weiter — kein Lock-in über Zwangs-Updates.

+

{{ _('What happens if we cancel?') }}

+

{{ _('You keep the code (AGPLv3 stays). You lose the commercial license, the updated DPA, new releases with compliance features, and the support SLA. Existing installations continue running — no lock-in via forced updates.') }}

-

Wie verhält sich AGPLv3 bei Bürgerportal-Integrationen?

-

Bei einer öffentlich erreichbaren Service-Integration greift die AGPL-Veröffentlichungspflicht. Die kommerzielle Lizenz hebt sie auf — Sie können FileMorph in einem Bürgerportal einbinden, ohne den Quellcode Ihres Portals offenzulegen. Detail in docs/agpl-fuer-behoerden.md ↗.

+

{{ _('How does AGPLv3 behave with citizen-portal integrations?') }}

+

{{ _('For a publicly accessible service integration, the AGPL publication obligation applies. The commercial license lifts it — you can integrate FileMorph into a citizen portal without disclosing your portal\'s source code. Detail in') }} docs/agpl-fuer-behoerden.md ↗.

-

Brauche ich für KRITIS die Enterprise-Stufe?

-

Standard-Tier reicht für die meisten KRITIS-Voraussetzungen (Self-Hosting, Audit-Log, signierte Artefakte). Enterprise wird relevant, sobald Air-Gap-Update-Mechanismus, Reproducible-Builds oder dedizierter Support-SLA gefordert sind. Wir klären das in 15 Minuten am Telefon.

+

{{ _('Do I need the Enterprise tier for KRITIS?') }}

+

{{ _('Standard tier is enough for most KRITIS requirements (self-hosting, audit log, signed artefacts). Enterprise becomes relevant once air-gap update mechanism, reproducible builds or dedicated support SLA are required. We clarify this in 15 minutes by phone.') }}

-

Wie sieht der Datenexport aus, wenn wir migrieren?

-

FileMorph ist stateless für Konvertierungen — es gibt nichts zu exportieren außer dem Audit-Log (Postgres, SQL-Dump-fähig) und Konfiguration (env-Vars). Migration zu einem Nachfolger ist eine SQL-Dump + Container-Image-Frage, kein Vendor-Lock-in.

+

{{ _('What does the data export look like if we migrate?') }}

+

{{ _('FileMorph is stateless for conversions — there is nothing to export apart from the audit log (Postgres, SQL-dumpable) and configuration (env vars). Migration to a successor is a SQL-dump + container-image question, not a vendor lock-in.') }}

- +
-

Worüber wir transparent sind

+

{{ _('What we\'re transparent about') }}

    -
  • Externe ISO 27001-Zertifizierung und externer Pen-Test sind als - Year-2-Roadmap-Items eingeplant — beide werden umgesetzt, sobald der - erste zahlende Pilot den Aufwand betriebswirtschaftlich rechtfertigt.
  • -
  • Reproducible-Builds und Air-Gap-Update-Mechanismus sind ebenfalls - Year-2 (für die KRITIS-Variante erforderlich, im Standard-Tier nicht - kritisch).
  • -
  • Wir benennen das, weil ein RFP-Reviewer es ohnehin bemerken würde — - und weil wir die Roadmap lieber transparent statt geschönt halten.
  • +
  • {{ _('External ISO 27001 certification and external pen test are planned as Year-2 roadmap items — both will be implemented as soon as the first paying pilot economically justifies the effort.') }}
  • +
  • {{ _('Reproducible builds and air-gap update mechanism are also Year-2 (required for the KRITIS variant, not critical in the standard tier).') }}
  • +
  • {{ _('We name it because an RFP reviewer would notice anyway — and because we prefer to keep the roadmap transparent rather than embellished.') }}
- +
-

Bereit für ein 15-Minuten-Pilotgespräch?

+

{{ _('Ready for a 15-minute pilot call?') }}

- Sie evaluieren Konvertierungs-Software für eine Behörde, ein Krankenhaus - oder eine Kanzlei? Schreiben Sie uns mit Ihrem Use-Case — wir antworten - innerhalb eines Werktages. + {{ _('You\'re evaluating conversion software for a public authority, hospital or law firm? Write to us with your use case — we respond within one business day.') }}

- Vertrauliche Anfragen über + {{ _('Confidential inquiries via') }} security.txt - werden mit demselben Schlüssel verschlüsselt. + {{ _('are encrypted with the same key.') }}

diff --git a/app/templates/impressum.html b/app/templates/impressum.html index a09b1c7..4521191 100644 --- a/app/templates/impressum.html +++ b/app/templates/impressum.html @@ -3,8 +3,15 @@ {% block content %}
+ {% if locale == 'en' %} +
+

{{ _('Imprint per German Telemediengesetz §5 (TMG).') }}

+

{{ _('The legal information below is provided in German as required by German law.') }}

+
+ {% endif %} +
- ← Back + {{ _('← Back') }}

Impressum

Angaben gemäß § 5 TMG

@@ -32,6 +39,15 @@

Inhaltl

Gemäß § 18 Abs. 2 MStV: Lennart Seidel, Reetwerder 25b, 21029 Hamburg

+
+

Verbraucherstreitbeilegung

+

Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen (§ 36 VSBG).

+

Online-Streitbeilegung der EU-Kommission: + ec.europa.eu/consumers/odr +

+
+

Hinweis

diff --git a/app/templates/pricing.html b/app/templates/pricing.html index 3e0ad52..bb175d4 100644 --- a/app/templates/pricing.html +++ b/app/templates/pricing.html @@ -107,8 +107,13 @@

{{ _('Simple, transparent pricing') }}

{% if stripe_enabled %} - {% else %} @@ -155,8 +160,13 @@

{{ _('Simple, transparent pricing') }}

{% if stripe_enabled %} - {% else %} diff --git a/app/templates/privacy.html b/app/templates/privacy.html index cfba2c0..3033380 100644 --- a/app/templates/privacy.html +++ b/app/templates/privacy.html @@ -1,82 +1,86 @@ {% extends "base.html" %} -{% block title %}Privacy Policy — FileMorph{% endblock %} +{% block title %}{{ _('Privacy Policy') }} — FileMorph{% endblock %} {% block content %}
- ← Back -

Privacy Policy

-

Last updated: 2026-04-23 · Community + Cloud Edition

+ {{ _('← Back') }} +

{{ _('Privacy Policy') }}

+

{{ _('Last updated: 2026-04-23 · Community + Cloud Edition') }}

-

1. Who is responsible?

+

{{ _('1. Who is responsible?') }}

- FileMorph is operated by Lennart Seidel, Reetwerder 25b, 21029 Hamburg, Germany. - Contact: privacy@filemorph.io. - See Impressum for full contact details. + {{ _('FileMorph is operated by Lennart Seidel, Reetwerder 25b, 21029 Hamburg, Germany.') }} + {{ _('Contact:') }} privacy@filemorph.io. + {{ _('See') }} Impressum {{ _('for full contact details.') }}

-

2. What data we process

-

2a. Uploaded files: Files you upload for conversion or compression are processed entirely server-side and deleted immediately after the converted output is returned to you. No file content is stored, logged, or retained in any form.

-

2b. User accounts (Cloud Edition): If you register an account, we store your email address, a bcrypt hash of your password (never the plaintext), your subscription tier, your account creation timestamp, and — once you upgrade to a paid tier — the Stripe customer identifier that links your account to Stripe. Account data is persisted in our PostgreSQL database for the lifetime of your account and erased on deletion request (Art. 17 GDPR).

-

2c. Transactional emails: When you request a password reset, we generate a single-use token (valid for 30 minutes) and send it to your registered email address as a reset link. The outgoing message is delivered from no-reply@filemorph.io via our email provider (see § 3a). We do not send marketing emails.

-

2d. Server logs: Our web server automatically records standard access log data for each request: IP address, request timestamp, HTTP method, URL path, response status code, and response size. Application-level events (logins, password-reset requests, subscription changes) are logged as structured JSON without plaintext email addresses — only the email domain is kept for debug purposes. Logs are rotated by the hosting infrastructure under standard operational policies (typically up to 30 days) and accessed only for security, abuse-detection, and debugging.

-

2e. API keys: If you generate an API key (via the dashboard or command-line tool), only the SHA-256 hash of your key is stored. The plaintext key is shown to you exactly once at creation time and is never persisted on our servers.

+

{{ _('2. What data we process') }}

+

{{ _('2a. Uploaded files:') }} {{ _('Files you upload for conversion or compression are processed entirely server-side and deleted immediately after the converted output is returned to you. No file content is stored, logged, or retained in any form.') }}

+

{{ _('2b. User accounts (Cloud Edition):') }} {{ _('If you register an account, we store your email address, a bcrypt hash of your password (never the plaintext), your subscription tier, your account creation timestamp, and — once you upgrade to a paid tier — the Stripe customer identifier that links your account to Stripe. Account data is persisted in our PostgreSQL database for the lifetime of your account and erased on deletion request (Art. 17 GDPR).') }}

+

{{ _('2c. Transactional emails:') }} {{ _('When you request a password reset, we generate a single-use token (valid for 30 minutes) and send it to your registered email address as a reset link. The outgoing message is delivered from') }} no-reply@filemorph.io {{ _('via our email provider (see § 3a). We do not send marketing emails.') }}

+

{{ _('2d. Server logs:') }} {{ _('Our web server automatically records standard access log data for each request: IP address, request timestamp, HTTP method, URL path, response status code, and response size. Application-level events (logins, password-reset requests, subscription changes) are logged as structured JSON without plaintext email addresses — only the email domain is kept for debug purposes. Logs are rotated by the hosting infrastructure under standard operational policies (typically up to 30 days) and accessed only for security, abuse-detection, and debugging.') }}

+

{{ _('2e. API keys:') }} {{ _('If you generate an API key (via the dashboard or command-line tool), only the SHA-256 hash of your key is stored. The plaintext key is shown to you exactly once at creation time and is never persisted on our servers.') }}

-

3. Legal basis (GDPR Art. 6)

-

Account creation, paid subscriptions, and transactional emails are processed on the basis of Art. 6(1)(b) GDPR (performance of a contract). Server-log processing, rate-limiting, and abuse prevention are based on our legitimate interest (Art. 6(1)(f) GDPR) in operating a secure and reliable service.

+

{{ _('3. Legal basis (GDPR Art. 6)') }}

+

{{ _('Account creation, paid subscriptions, and transactional emails are processed on the basis of Art. 6(1)(b) GDPR (performance of a contract). Server-log processing, rate-limiting, and abuse prevention are based on our legitimate interest (Art. 6(1)(f) GDPR) in operating a secure and reliable service.') }}

-

3a. External services (Sub-Processors)

-

To operate FileMorph we rely on the following sub-processors. Each one receives only the minimum data needed for its task:

-

Stripe (payments): When you upgrade to a paid tier, we create a Stripe customer record containing your email address and an internal user identifier, then redirect you to checkout.stripe.com to complete payment. Stripe handles all card details directly — FileMorph never sees or stores your card data. After checkout, Stripe returns a customer identifier which we store to manage your subscription. Stripe is a US-based company; the transfer is covered by the EU Standard Contractual Clauses under Stripe's Data Processing Agreement. Legal basis: Art. 6(1)(b) GDPR. See Stripe's privacy policy.

-

Zoho Mail (transactional email): Password-reset and other account-related emails are delivered through Zoho Mail (smtp.zoho.eu, hosted in Frankfurt, EU). Zoho receives the recipient address and the email contents (including the reset link). Legal basis: Art. 6(1)(b) GDPR. See Zoho's privacy policy.

+

{{ _('3a. External services (Sub-Processors)') }}

+

{{ _('To operate FileMorph we rely on the following sub-processors. Each one receives only the minimum data needed for its task:') }}

+

{{ _('Stripe (payments):') }} {{ _('When you upgrade to a paid tier, we create a Stripe customer record containing your email address and an internal user identifier, then redirect you to') }} checkout.stripe.com {{ _('to complete payment. Stripe handles all card details directly — FileMorph never sees or stores your card data. After checkout, Stripe returns a customer identifier which we store to manage your subscription. Stripe is a US-based company; the transfer is covered by the EU Standard Contractual Clauses under Stripe\'s Data Processing Agreement. Legal basis: Art. 6(1)(b) GDPR. See') }} {{ _('Stripe\'s privacy policy') }}.

+

{{ _('Zoho Mail (transactional email):') }} {{ _('Password-reset and other account-related emails are delivered through Zoho Mail (') }}smtp.zoho.eu{{ _(', hosted in Frankfurt, EU). Zoho receives the recipient address and the email contents (including the reset link). Legal basis: Art. 6(1)(b) GDPR. See') }} {{ _('Zoho\'s privacy policy') }}.

-

4. Hosting

-

This service is hosted by Hetzner Online GmbH, Germany (Frankfurt data centre). Your requests are routed through Cloudflare's network for DDoS protection and performance. See Hetzner's privacy policy and Cloudflare's privacy policy for their data processing terms.

+

{{ _('4. Hosting') }}

+

{{ _('This service is hosted by Hetzner Online GmbH, Germany (Frankfurt data centre). Your requests are routed through Cloudflare\'s network for DDoS protection and performance. See') }} {{ _('Hetzner\'s privacy policy') }} {{ _('and') }} {{ _('Cloudflare\'s privacy policy') }} {{ _('for their data processing terms.') }}

-

5. Your rights (GDPR)

-

You have the right to access, rectify, erase, and restrict processing of your personal data (Art. 15–21 GDPR). To exercise these rights, contact us at privacy@filemorph.io. You also have the right to lodge a complaint with your local data protection authority.

-

Account deletion: Free accounts can be deleted from the API at DELETE /api/v1/auth/account after a three-field re-confirmation (your password, your email, and the literal word DELETE). The cascade removes your login credentials and API keys; conversion-job and usage-record entries are anonymised (your account ID is nulled, the rows are kept as anonymous aggregate data under DSGVO Art. 4(1)). A confirmation email is sent after the row is gone.

-

Accounts that have ever been linked to Stripe cannot use the self-service path yet — German commercial law (HGB §257, AO §147) requires a 10-year retention of tax-relevant records under Art. 17(3)(b) GDPR. For these accounts, contact privacy@filemorph.io. Stripe may retain records of past transactions independently of our deletion, to comply with its own legal and tax obligations.

+

{{ _('5. Your rights (GDPR)') }}

+

{{ _('You have the right to access, rectify, erase, and restrict processing of your personal data (Art. 15–21 GDPR). To exercise these rights, contact us at') }} privacy@filemorph.io. {{ _('You also have the right to lodge a complaint with your local data protection authority.') }}

+

{{ _('Account deletion:') }} {{ _('Free accounts can be deleted from the API at') }} DELETE /api/v1/auth/account {{ _('after a three-field re-confirmation (your password, your email, and the literal word') }} DELETE{{ _('). The cascade removes your login credentials and API keys; conversion-job and usage-record entries are anonymised (your account ID is nulled, the rows are kept as anonymous aggregate data under DSGVO Art. 4(1)). A confirmation email is sent after the row is gone.') }}

+

{{ _('Accounts that have ever been linked to Stripe cannot use the self-service path yet — German commercial law (HGB §257, AO §147) requires a 10-year retention of tax-relevant records under Art. 17(3)(b) GDPR. For these accounts, contact') }} privacy@filemorph.io. {{ _('Stripe may retain records of past transactions independently of our deletion, to comply with its own legal and tax obligations.') }}

-

6. No cookies, no tracking

-

FileMorph sets no cookies on its own domain and runs no tracking or analytics scripts. A small number of keys are written to your browser's localStorage only while you are signed in:

+

{{ _('6. No cookies, no tracking') }}

+

{{ _('FileMorph sets') }} {{ _('no cookies') }} {{ _('on its own domain and runs no tracking or analytics scripts. A small number of keys are written to your browser\'s') }} localStorage {{ _('only while you are signed in:') }}

    -
  • fm_access_token / fm_refresh_token — your JWT session tokens; strictly necessary to keep you signed in.
  • -
  • filemorph_api_key — optional; remembers the API key shown in your dashboard across reloads so you don't need to paste it again. Cleared on logout.
  • +
  • fm_access_token / fm_refresh_token — {{ _('your JWT session tokens; strictly necessary to keep you signed in.') }}
  • +
  • filemorph_api_key — {{ _('optional; remembers the API key shown in your dashboard across reloads so you don\'t need to paste it again. Cleared on logout.') }}
-

These entries fall under the "strictly necessary" exemption of Art. 5(3) ePrivacy Directive / § 25 Abs. 2 Nr. 2 TTDSG and therefore do not require a consent banner. For anonymous usage, nothing is stored in your browser at all.

-

When you start a paid-tier upgrade, you are redirected to Stripe Checkout on the stripe.com domain, which sets its own cookies. That is outside FileMorph's control and is governed by Stripe's privacy policy.

-

Our pages load no external resources. All CSS (including Tailwind), JavaScript, fonts, and images are served from the FileMorph domain; your browser never contacts a third-party CDN to render the site.

+

{{ _('These entries fall under the "strictly necessary" exemption of Art. 5(3) ePrivacy Directive / § 25 Abs. 2 Nr. 2 TTDSG and therefore do not require a consent banner. For anonymous usage, nothing is stored in your browser at all.') }}

+

{{ _('When you start a paid-tier upgrade, you are redirected to Stripe Checkout on the') }} stripe.com {{ _('domain, which sets its own cookies. That is outside FileMorph\'s control and is governed by') }} {{ _('Stripe\'s privacy policy') }}.

+

{{ _('Our pages load') }} {{ _('no external resources') }}. {{ _('All CSS (including Tailwind), JavaScript, fonts, and images are served from the FileMorph domain; your browser never contacts a third-party CDN to render the site.') }}

-

7. Rate limiting & abuse prevention

-

We apply a temporary in-memory rate limit (max. 10 requests per minute per IP address) to protect the service from abuse. IP addresses used by the rate limiter are processed transiently in memory only and are never written to disk or logs. Legal basis: Art. 6(1)(f) GDPR — legitimate interest in service stability and security.

+

{{ _('7. Rate limiting & abuse prevention') }}

+

{{ _('We apply a temporary in-memory rate limit (max. 10 requests per minute per IP address) to protect the service from abuse. IP addresses used by the rate limiter are processed transiently in memory only and are never written to disk or logs. Legal basis: Art. 6(1)(f) GDPR — legitimate interest in service stability and security.') }}

-

8. Changes to this policy

-

We may update this policy when the service changes. Accounts and billing are live as of April 2026; persistent file history (Cloud Edition Phase 2) is planned but not yet implemented. The date at the top indicates the current version.

+

{{ _('8. Changes to this policy') }}

+

{{ _('We may update this policy when the service changes. Accounts and billing are live as of April 2026; persistent file history (Cloud Edition Phase 2) is planned but not yet implemented. The date at the top indicates the current version.') }}

-

9. Admin access (transparency)

-

Operator staff with the admin role can access an internal cockpit that lists registered email addresses in plaintext, along with subscription tier, account creation date, and Stripe subscription status — strictly for service operation, abuse response, and support. Admin actions (tier changes, role changes, deactivations) are recorded with the admin's user identifier, the target user's identifier, and the change performed, to enable internal auditing. Legal basis: Art. 6(1)(f) GDPR.

+

{{ _('9. Admin access (transparency)') }}

+

{{ _('Operator staff with the') }} admin {{ _('role can access an internal cockpit that lists registered email addresses in plaintext, along with subscription tier, account creation date, and Stripe subscription status — strictly for service operation, abuse response, and support. Admin actions (tier changes, role changes, deactivations) are recorded with the admin\'s user identifier, the target user\'s identifier, and the change performed, to enable internal auditing. Legal basis: Art. 6(1)(f) GDPR.') }}

+

+ {{ _('This English translation is provided for accessibility. The German version is the authoritative legal text in case of conflict.') }} +

+
{% endblock %} diff --git a/app/templates/register.html b/app/templates/register.html index 8e2a9f7..3eeeac7 100644 --- a/app/templates/register.html +++ b/app/templates/register.html @@ -9,7 +9,7 @@

{{ _('Create Account') }}

-

{{ _('Free forever — no credit card required') }}

+

{{ _('Free tier forever — upgrade only when you need more') }}

{% call uc.card() %} diff --git a/app/templates/terms.html b/app/templates/terms.html index 552b7e9..32b36ba 100644 --- a/app/templates/terms.html +++ b/app/templates/terms.html @@ -1,59 +1,77 @@ {% extends "base.html" %} -{% block title %}Terms of Use — FileMorph{% endblock %} +{% block title %}{{ _('Terms of Use') }} — FileMorph{% endblock %} {% block content %}
- ← Back -

Terms of Use

-

Last updated: 2026-04-21 · Community Edition

+ {{ _('← Back') }} +

{{ _('Terms of Use') }}

+

{{ _('Last updated: 2026-05-08 · Community + Cloud Edition') }}

-

1. Acceptance

-

By using FileMorph (the "Service"), you agree to these Terms of Use. If you do not agree, do not use the Service.

+

{{ _('1. Acceptance') }}

+

{{ _('By using FileMorph (the "Service"), you agree to these Terms of Use. If you do not agree, do not use the Service.') }}

-

2. Description of Service

-

FileMorph is a file conversion and compression service. The Community Edition is provided free of charge, without warranty, and without SLA commitments.

+

{{ _('2. Description of Service') }}

+

{{ _('FileMorph is a file conversion and compression service. The Community Edition is provided free of charge, without warranty, and without SLA commitments.') }}

-

3. Acceptable Use

-

You may not use the Service to:

+

{{ _('3. Acceptable Use') }}

+

{{ _('You may not use the Service to:') }}

    -
  • Upload files that contain malware, exploits, or illegal content
  • -
  • Attempt to circumvent rate limits or security controls
  • -
  • Use the Service for automated large-scale processing without prior agreement
  • -
  • Infringe third-party intellectual property rights through the files you process
  • +
  • {{ _('Upload files that contain malware, exploits, or illegal content') }}
  • +
  • {{ _('Attempt to circumvent rate limits or security controls') }}
  • +
  • {{ _('Use the Service for automated large-scale processing without prior agreement') }}
  • +
  • {{ _('Infringe third-party intellectual property rights through the files you process') }}
-

4. Disclaimer of Warranties

-

The Service is provided "as is" without warranty of any kind, express or implied. We do not guarantee uptime, accuracy of conversion results, or fitness for a particular purpose.

+

{{ _('4. Disclaimer of Warranties') }}

+

{{ _('The Service is provided "as is" without warranty of any kind, express or implied. We do not guarantee uptime, accuracy of conversion results, or fitness for a particular purpose.') }}

-

5. Limitation of Liability

-

To the extent permitted by applicable law, the operator of FileMorph shall not be liable for any direct, indirect, incidental, or consequential damages arising from your use of the Service.

+

{{ _('5. Limitation of Liability') }}

+

{{ _('To the extent permitted by applicable law, the operator of FileMorph shall not be liable for any direct, indirect, incidental, or consequential damages arising from your use of the Service.') }}

-

6. Open Source License

-

FileMorph is open source software licensed under the GNU Affero General Public License v3.0 (AGPLv3). The source code is available at github.com/MrChengLen/FileMorph.

+

{{ _('6. Open Source License') }}

+

{{ _('FileMorph is open source software licensed under the GNU Affero General Public License v3.0 (AGPLv3). The source code is available at') }} github.com/MrChengLen/FileMorph.

-

7. Governing Law

-

These Terms are governed by the laws of the Federal Republic of Germany. Place of jurisdiction is Hamburg, Germany.

+

{{ _('7. Governing Law') }}

+

{{ _('These Terms are governed by the laws of the Federal Republic of Germany. Place of jurisdiction is Hamburg, Germany.') }}

-

8. Contact

-

For questions about these Terms, contact: legal@filemorph.io.

+

{{ _('8. Subscriptions (Cloud Edition)') }}

+

{{ _('Paid plans (Pro €7/month, Business €19/month) are billed monthly via Stripe and renew automatically until cancelled. You may cancel at any time through the Stripe customer portal linked from your account dashboard; cancellation takes effect at the end of the current billing period and you retain access for the remainder of that period.') }}

+

{{ _('Refunds are not issued for partial billing periods. In the event of a documented service outage exceeding 24 hours within a single billing period, you may request a discretionary credit by contacting:') }} legal@filemorph.io.

+

{{ _("Payment processing is handled by Stripe Payments Europe Ltd.; Stripe's terms apply to the processing of your payment details.") }}

+
+

{{ _('9. Right of Withdrawal (Consumers)') }}

+

{{ _('If you are a consumer (a natural person entering a contract for purposes outside your trade, business or profession) and reside in the European Union, you have the statutory right to withdraw from a paid subscription within fourteen (14) days of contract conclusion — the date your first Stripe payment is confirmed — without giving any reason.') }}

+

{{ _('To exercise the right of withdrawal, send an unambiguous statement to:') }} legal@filemorph.io{{ _(' — for example: "I hereby withdraw from the contract concluded on [date] for the FileMorph [Pro / Business] subscription." Including your registered email address speeds up identification of your account.') }}

+

{{ _('Early expiration of the right of withdrawal:') }} {{ _('Pursuant to § 356 (5) BGB, the right of withdrawal expires when we begin executing the contract — i.e. when paid-tier API access becomes available — provided you (a) expressly consented to this and (b) acknowledged that you lose your right of withdrawal upon full performance. By ticking the dedicated waiver checkbox on the pricing page before being redirected to Stripe checkout, you give such consent. Without this acknowledgement, the standard 14-day withdrawal protection applies. The Community Edition (free of charge) is not subject to a right of withdrawal because no contract for paid services is concluded.') }}

+
+ +
+

{{ _('10. Contact') }}

+

{{ _('For questions about these Terms, contact:') }} legal@filemorph.io.

+
+ +

+ {{ _('This English translation is provided for accessibility. The German version is the authoritative legal text in case of conflict.') }} +

+
{% endblock %} diff --git a/locale/de/LC_MESSAGES/messages.mo b/locale/de/LC_MESSAGES/messages.mo index f078e24..a60a64e 100644 Binary files a/locale/de/LC_MESSAGES/messages.mo and b/locale/de/LC_MESSAGES/messages.mo differ diff --git a/locale/de/LC_MESSAGES/messages.po b/locale/de/LC_MESSAGES/messages.po index 1e060b4..823c51d 100644 --- a/locale/de/LC_MESSAGES/messages.po +++ b/locale/de/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: FileMorph VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2026-05-08 15:52+0200\n" +"POT-Creation-Date: 2026-05-08 14:43+0200\n" "PO-Revision-Date: 2026-05-08 11:00+0200\n" "Last-Translator: FileMorph \n" "Language: de\n" @@ -18,9 +18,33 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.18.0\n" +msgid "" +" — for example: \"I hereby withdraw from the contract concluded on [date]" +" for the FileMorph [Pro / Business] subscription.\" Including your " +"registered email address speeds up identification of your account." +msgstr "" +" — zum Beispiel: „Hiermit widerrufe ich den am [Datum] geschlossenen " +"Vertrag über das FileMorph-[Pro-/Business-]Abonnement.“ Die Angabe deiner" +" registrierten E-Mail-Adresse beschleunigt die Zuordnung zu deinem Konto." + msgid "(vs. 20 MB anonymous)" msgstr "(vs. 20 MB anonym)" +msgid "" +"). The cascade removes your login credentials and API keys; conversion-" +"job and usage-record entries are anonymised (your account ID is nulled, " +"the rows are kept as anonymous aggregate data under DSGVO Art. 4(1)). A " +"confirmation email is sent after the row is gone." +msgstr "" +"). Die Kaskade entfernt deine Login-Credentials und API-Keys; " +"Konvertierungs-Job- und Usage-Record-Einträge werden anonymisiert (deine " +"Konto-ID wird genullt, die Zeilen werden als anonyme Aggregat-Daten unter" +" DSGVO Art. 4(1) behalten). Eine Bestätigungs-E-Mail wird nach der " +"Löschung gesendet." + +msgid "+ New Key" +msgstr "+ Neuer Key" + msgid ", 1 concurrent, 10 req/min" msgstr ", 1 gleichzeitig, 10 Anfr./min" @@ -30,12 +54,33 @@ msgstr ", 2 gleichzeitig, 10 Anfr./min" msgid ", 5 concurrent, 10 req/min" msgstr ", 5 gleichzeitig, 10 Anfr./min" +msgid "" +", hosted in Frankfurt, EU). Zoho receives the recipient address and the " +"email contents (including the reset link). Legal basis: Art. 6(1)(b) " +"GDPR. See" +msgstr "" +", gehostet in Frankfurt, EU). Zoho erhält die Empfänger-Adresse und die E" +"-Mail-Inhalte (einschließlich des Reset-Links). Rechtsgrundlage: Art. " +"6(1)(b) DSGVO. Siehe" + msgid "/mo" msgstr "/Monat" +msgid "1 server, ≤ 50 employees" +msgstr "1 Server, ≤ 50 Mitarbeitende" + +msgid "1. Acceptance" +msgstr "1. Annahme" + +msgid "1. Who is responsible?" +msgstr "1. Wer ist verantwortlich?" + msgid "10,000 API calls / month" msgstr "10.000 API-Aufrufe / Monat" +msgid "10. Contact" +msgstr "10. Kontakt" + msgid "100 MB · 10k API" msgstr "100 MB · 10k API" @@ -45,21 +90,66 @@ msgstr "100 Dateien" msgid "100,000 API calls / month" msgstr "100.000 API-Aufrufe / Monat" +msgid "2. Description of Service" +msgstr "2. Beschreibung des Dienstes" + +msgid "2. What data we process" +msgstr "2. Welche Daten wir verarbeiten" + msgid "25 files" msgstr "25 Dateien" +msgid "2a. Uploaded files:" +msgstr "2a. Hochgeladene Dateien:" + +msgid "2b. User accounts (Cloud Edition):" +msgstr "2b. Nutzerkonten (Cloud Edition):" + +msgid "2c. Transactional emails:" +msgstr "2c. Transaktions-E-Mails:" + +msgid "2d. Server logs:" +msgstr "2d. Server-Logs:" + +msgid "2e. API keys:" +msgstr "2e. API-Keys:" + +msgid "3 servers, ≤ 2,000 employees" +msgstr "3 Server, ≤ 2.000 Mitarbeitende" + +msgid "3. Acceptable Use" +msgstr "3. Akzeptable Nutzung" + +msgid "3. Legal basis (GDPR Art. 6)" +msgstr "3. Rechtsgrundlage (DSGVO Art. 6)" + msgid "30+ formats (images, docs, audio, video)" msgstr "30+ Formate (Bilder, Dokumente, Audio, Video)" msgid "30+ formats incl. video" msgstr "30+ Formate inkl. Video" +msgid "3a. External services (Sub-Processors)" +msgstr "3a. Externe Dienste (Sub-Processors)" + +msgid "4. Disclaimer of Warranties" +msgstr "4. Gewährleistungsausschluss" + +msgid "4. Hosting" +msgstr "4. Hosting" + msgid "404 – Not Found" msgstr "404 – Nicht gefunden" msgid "5 files" msgstr "5 Dateien" +msgid "5. Limitation of Liability" +msgstr "5. Haftungsbeschränkung" + +msgid "5. Your rights (GDPR)" +msgstr "5. Deine Rechte (DSGVO)" + msgid "50 MB · API key" msgstr "50 MB · API-Key" @@ -72,38 +162,125 @@ msgstr "500 Aufrufe / Monat" msgid "500 – Server Error" msgstr "500 – Serverfehler" +msgid "6. No cookies, no tracking" +msgstr "6. Keine Cookies, kein Tracking" + +msgid "6. Open Source License" +msgstr "6. Open-Source-Lizenz" + +msgid "7. Governing Law" +msgstr "7. Anwendbares Recht" + +msgid "7. Rate limiting & abuse prevention" +msgstr "7. Rate-Limiting & Missbrauchsprävention" + +msgid "8. Changes to this policy" +msgstr "8. Änderungen dieser Richtlinie" + +msgid "8. Subscriptions (Cloud Edition)" +msgstr "8. Abonnements (Cloud Edition)" + +msgid "9. Admin access (transparency)" +msgstr "9. Admin-Zugriff (Transparenz)" + +msgid "9. Right of Withdrawal (Consumers)" +msgstr "9. Widerrufsrecht (Verbraucher)" + msgid "A description of the vulnerability and its potential impact." msgstr "" "Eine Beschreibung der Sicherheitslücke und ihrer potenziellen " "Auswirkungen." +msgid "AGPLv3 for public authorities" +msgstr "AGPLv3 für Behörden" + msgid "API Docs" msgstr "API-Doku" msgid "API Docs ↗" msgstr "API-Doku ↗" +msgid "API Keys" +msgstr "API-Schlüssel" + msgid "API key management" msgstr "API-Key-Verwaltung" msgid "API key — " msgstr "API-Key — " +msgid "" +"Account creation, paid subscriptions, and transactional emails are " +"processed on the basis of Art. 6(1)(b) GDPR (performance of a contract). " +"Server-log processing, rate-limiting, and abuse prevention are based on " +"our legitimate interest (Art. 6(1)(f) GDPR) in operating a secure and " +"reliable service." +msgstr "" +"Konto-Erstellung, bezahlte Abonnements und Transaktions-E-Mails werden " +"auf Grundlage von Art. 6(1)(b) DSGVO (Vertragserfüllung) verarbeitet. " +"Server-Log-Verarbeitung, Rate-Limiting und Missbrauchsprävention basieren" +" auf unserem berechtigten Interesse (Art. 6(1)(f) DSGVO) am Betrieb eines" +" sicheren und zuverlässigen Dienstes." + +msgid "Account deletion:" +msgstr "Konto-Löschung:" + +msgid "" +"Accounts that have ever been linked to Stripe cannot use the self-service" +" path yet — German commercial law (HGB §257, AO §147) requires a 10-year " +"retention of tax-relevant records under Art. 17(3)(b) GDPR. For these " +"accounts, contact" +msgstr "" +"Konten, die jemals mit Stripe verknüpft waren, können den Self-Service-" +"Pfad noch nicht nutzen — das deutsche Handelsrecht (HGB §257, AO §147) " +"verlangt eine 10-Jahres-Aufbewahrung steuerrelevanter Aufzeichnungen " +"unter Art. 17(3)(b) DSGVO. Für diese Konten kontaktiere" + msgid "Acknowledgement:" msgstr "Bestätigung:" msgid "Affected version (commit hash or release tag if known)." msgstr "Betroffene Version (Commit-Hash oder Release-Tag, falls bekannt)." +msgid "" +"All CSS (including Tailwind), JavaScript, fonts, and images are served " +"from the FileMorph domain; your browser never contacts a third-party CDN " +"to render the site." +msgstr "" +"Alle CSS-Dateien (inklusive Tailwind), JavaScript, Fonts und Bilder " +"werden von der FileMorph-Domain ausgeliefert; dein Browser kontaktiert " +"niemals ein Drittanbieter-CDN zum Rendern der Site." + msgid "All prices excl. VAT where applicable. Payments processed by Stripe." msgstr "Alle Preise zzgl. ggf. anfallender USt. Zahlungen via Stripe." msgid "Already have an account?" msgstr "Hast du schon ein Konto?" +msgid "" +"An orientation about the provider categories common in DACH RFPs. In " +"individual cases, a specific product may do more — please check " +"individually." +msgstr "" +"Eine Orientierung über die in DACH-RFPs gängigen Anbieter-Kategorien. Im " +"Einzelfall kann ein konkretes Produkt mehr leisten — bitte individuell " +"prüfen." + +msgid "Apply as design partner" +msgstr "Als Design-Partner bewerben" + +msgid "Architecture overview" +msgstr "Architektur-Übersicht" + msgid "At least 8 characters" msgstr "Mindestens 8 Zeichen" +msgid "Attempt to circumvent rate limits or security controls" +msgstr "Versuche zu unternehmen, Rate-Limits oder Sicherheitskontrollen zu umgehen" + +msgid "Audit log with hash chain" +msgstr "Audit-Log mit Hash-Chain" + msgid "Back to Home" msgstr "Zurück zur Startseite" @@ -131,24 +308,69 @@ msgstr "Nach Qualität %" msgid "By target size" msgstr "Nach Zielgröße" +msgid "" +"By using FileMorph (the \"Service\"), you agree to these Terms of Use. If" +" you do not agree, do not use the Service." +msgstr "" +"Mit der Nutzung von FileMorph (dem „Dienst“) stimmst du diesen " +"Nutzungsbedingungen zu. Falls du nicht zustimmst, nutze den Dienst nicht." + msgid "Choose a password you haven't used before" msgstr "Wähle ein Passwort, das du vorher noch nicht verwendet hast" msgid "Clear all" msgstr "Alle entfernen" +msgid "Cloudflare's privacy policy" +msgstr "Cloudflares Datenschutzerklärung" + msgid "Coming soon" msgstr "Demnächst verfügbar" +msgid "Commercial license" +msgstr "Kommerzielle Lizenz" + +msgid "Commercial license on AGPL code" +msgstr "Kommerzielle Lizenz auf AGPL-Code" + +msgid "Compliance" +msgstr "Compliance" + +msgid "Compliance Edition" +msgstr "Compliance Edition" + msgid "Compliance Edition →" msgstr "Compliance Edition →" +msgid "Compliance Enterprise" +msgstr "Compliance Enterprise" + +msgid "Compliance Standard" +msgstr "Compliance Standard" + +msgid "Compliance Starter" +msgstr "Compliance Starter" + +msgid "" +"Compliance assertions on this page cite German statutes (HGB §257, AO " +"§147, DSGVO Art 17). This English translation is provided for " +"accessibility — the German version is the authoritative legal text in " +"case of conflict." +msgstr "" +"Compliance-Aussagen auf dieser Seite zitieren deutsche Rechtsnormen (HGB " +"§257, AO §147, DSGVO Art 17). Diese englische Übersetzung dient der " +"Barrierefreiheit — die deutsche Version ist im Konfliktfall der rechtlich" +" verbindliche Text." + msgid "Compress" msgstr "Komprimieren" msgid "Compression mode" msgstr "Kompressions-Modus" +msgid "Confidential inquiries via" +msgstr "Vertrauliche Anfragen über" + msgid "Confirm Password" msgstr "Passwort bestätigen" @@ -164,6 +386,23 @@ msgstr "E-Mail wird bestätigt" msgid "Confirming your email…" msgstr "Deine E-Mail-Adresse wird bestätigt…" +msgid "" +"Conformance gate runs as CI workflow. No release without green veraPDF " +"against a worst-case source PDF." +msgstr "" +"Konformitäts-Gate läuft als CI-Workflow. Kein Release ohne grünes veraPDF" +" gegen einen Worst-Case-Source-PDF." + +msgid "" +"Conformance secured by veraPDF CI gate against a worst-case source PDF — " +"for beA attachments, citizen-application archiving, BSI TR-RESISCAN." +msgstr "" +"Konformität abgesichert durch veraPDF-CI-Gate gegen ein Worst-Case-Quell-" +"PDF — für beA-Anhänge, Bürgerantrags-Archivierung, BSI TR-RESISCAN." + +msgid "Contact:" +msgstr "Kontakt:" + msgid "Convert" msgstr "Konvertieren" @@ -173,12 +412,21 @@ msgstr "Dateien konvertieren & komprimieren" msgid "Coordinated disclosure:" msgstr "Koordinierte Offenlegung:" +msgid "Copy" +msgstr "Kopieren" + +msgid "Copy this key now — it will not be shown again." +msgstr "Kopiere diesen Key jetzt — er wird nicht erneut angezeigt." + msgid "Create Account" msgstr "Konto erstellen" msgid "Create one" msgstr "Jetzt erstellen" +msgid "Criterion" +msgstr "Kriterium" + msgid "" "Custom volume, batch uploads up to 250 files, SLA, on-premise deployment," " dedicated support & contract. For DACH Behörden, hospitals, law firms " @@ -191,9 +439,24 @@ msgstr "" msgid "DOCX · PDF · TXT · MD · XLSX · CSV · JSON" msgstr "DOCX · PDF · TXT · MD · XLSX · CSV · JSON" +msgid "Dashboard" +msgstr "Dashboard" + +msgid "Data Processing Agreement (DPA)" +msgstr "Auftragsverarbeitungs-Vertrag (AVV)" + msgid "Dedicated onboarding" msgstr "Dediziertes Onboarding" +msgid "Design Partner Programme" +msgstr "Design-Partner-Programm" + +msgid "Do I need the Enterprise tier for KRITIS?" +msgstr "Brauche ich für KRITIS die Enterprise-Stufe?" + +msgid "Do you also host if we can't operate ourselves?" +msgstr "Hosten Sie auch, wenn wir nicht selbst betreiben können?" + msgid "Documented API endpoints and the web UI." msgstr "Dokumentierte API-Endpunkte und die Web-UI." @@ -209,9 +472,18 @@ msgstr "Dateien hier ablegen oder klicken zum Auswählen" msgid "E-mail support" msgstr "E-Mail-Support" +msgid "EU vendor with German imprint" +msgstr "EU-Vendor mit deutschem Impressum" + +msgid "Early expiration of the right of withdrawal:" +msgstr "Vorzeitiges Erlöschen des Widerrufsrechts:" + msgid "Email" msgstr "E-Mail" +msgid "Engineering proof before contract" +msgstr "Engineering-Beweis vor dem Vertrag" + msgid "Enter your email to receive a reset link" msgstr "Gib deine E-Mail-Adresse ein, um einen Zurücksetzungs-Link zu erhalten" @@ -224,6 +496,22 @@ msgstr "Enterprise & Self-Hosted:" msgid "Enterprise / Compliance" msgstr "Enterprise / Compliance" +msgid "" +"Every operation in a continuous hash chain. Tampering with an old row " +"breaks every following one." +msgstr "" +"Jede Operation in einer fortlaufenden Hash-Chain. Manipulation an einer " +"alten Zeile bricht die nachfolgende Kette." + +msgid "" +"External ISO 27001 certification and external pen test are planned as " +"Year-2 roadmap items — both will be implemented as soon as the first " +"paying pilot economically justifies the effort." +msgstr "" +"Externe ISO 27001-Zertifizierung und externer Pen-Test sind als Year-2" +"-Roadmap-Items eingeplant — beide werden umgesetzt, sobald der erste " +"zahlende Pilot den Aufwand betriebswirtschaftlich rechtfertigt." + msgid "File Converter & Compressor" msgstr "Datei-Konverter & -Kompressor" @@ -236,28 +524,107 @@ msgstr "Datei-Konvertierung und -Kompression — Open Source, selbst hostbar." msgid "File conversion mode" msgstr "Datei-Konvertierungs-Modus" +msgid "FileMorph Compliance Edition" +msgstr "FileMorph Compliance Edition" + +msgid "" +"FileMorph closes this gap: the open-source engine covers 16+ format pairs" +" and runs on your own Hetzner / on-premises / air-gap infrastructure. The" +" Compliance Edition additionally provides the contracts, SLAs and roadmap" +" guarantees that an EVB-IT-compliant procurement requires." +msgstr "" +"FileMorph schließt diese Lücke: Die Open-Source-Engine deckt 16+ Format-" +"Paare ab und läuft auf Ihrer eigenen Hetzner / On-Premise / Air-Gap-" +"Infrastruktur. Die Compliance-Edition liefert zusätzlich die Verträge, " +"die SLAs und die Roadmap-Garantien, die ein EVB-IT-konformer Einkauf " +"voraussetzt." + +msgid "" +"FileMorph is a file conversion and compression service. The Community " +"Edition is provided free of charge, without warranty, and without SLA " +"commitments." +msgstr "" +"FileMorph ist ein Datei-Konvertierungs- und Kompressions-Dienst. Die " +"Community Edition wird kostenfrei, ohne Garantie und ohne SLA-" +"Verpflichtungen bereitgestellt." + +msgid "" +"FileMorph is open source software licensed under the GNU Affero General " +"Public License v3.0 (AGPLv3). The source code is available at" +msgstr "" +"FileMorph ist Open-Source-Software unter der GNU Affero General Public " +"License v3.0 (AGPLv3). Der Quellcode ist verfügbar unter" + +msgid "" +"FileMorph is operated by Lennart Seidel, Reetwerder 25b, 21029 Hamburg, " +"Germany." +msgstr "" +"FileMorph wird betrieben von Lennart Seidel, Reetwerder 25b, 21029 " +"Hamburg, Deutschland." + +msgid "" +"FileMorph is stateless for conversions — there is nothing to export apart" +" from the audit log (Postgres, SQL-dumpable) and configuration (env " +"vars). Migration to a successor is a SQL-dump + container-image question," +" not a vendor lock-in." +msgstr "" +"FileMorph ist stateless für Konvertierungen — es gibt nichts zu " +"exportieren außer dem Audit-Log (Postgres, SQL-Dump-fähig) und " +"Konfiguration (env-Vars). Migration zu einem Nachfolger ist eine SQL-Dump" +" + Container-Image-Frage, kein Vendor-Lock-in." + +msgid "FileMorph operates under German law (Hamburg)." +msgstr "FileMorph unterliegt deutschem Recht (Hamburg)." + +msgid "FileMorph sets" +msgstr "FileMorph setzt" + msgid "" "FileMorph — Free online file converter & compressor. Convert images, " -"documents, audio and video. Fast, private, no account required." +"documents, audio and video. Privacy-respecting, no account required." msgstr "" -"FileMorph — Kostenloser Online-Datei-Konverter & -Kompressor. Bilder, " -"Dokumente, Audio und Video konvertieren. Schnell, privat, kein Konto " -"erforderlich." +"FileMorph — Kostenloser Online-Datei-Konverter & -Kompressor. Konvertiere" +" Bilder, Dokumente, Audio und Video. Datenschutzfreundlich, ohne Account." msgid "Files are processed server-side and deleted immediately after conversion." msgstr "" "Dateien werden serverseitig verarbeitet und sofort nach der Konvertierung" " gelöscht." +msgid "" +"Files you upload for conversion or compression are processed entirely " +"server-side and deleted immediately after the converted output is " +"returned to you. No file content is stored, logged, or retained in any " +"form." +msgstr "" +"Dateien, die du zur Konvertierung oder Kompression hochlädst, werden " +"ausschließlich serverseitig verarbeitet und sofort nach Rücksendung des " +"konvertierten Outputs gelöscht. Keine Datei-Inhalte werden in irgendeiner" +" Form gespeichert, geloggt oder aufbewahrt." + msgid "Fix timeline:" msgstr "Behebungs-Zeitplan:" msgid "For Developers" msgstr "Für Entwickler" +msgid "" +"For a publicly accessible service integration, the AGPL publication " +"obligation applies. The commercial license lifts it — you can integrate " +"FileMorph into a citizen portal without disclosing your portal's source " +"code. Detail in" +msgstr "" +"Bei einer öffentlich erreichbaren Service-Integration greift die AGPL-" +"Veröffentlichungspflicht. Die kommerzielle Lizenz hebt sie auf — Sie " +"können FileMorph in einem Bürgerportal einbinden, ohne den Quellcode " +"Ihres Portals offenzulegen. Detail in" + msgid "For issues in the open-source codebase itself, you may alternatively use" msgstr "Für Probleme im Open-Source-Codebase selbst kannst du alternativ" +msgid "For questions about these Terms, contact:" +msgstr "Bei Fragen zu diesen Bedingungen, kontaktiere:" + msgid "Forgot Password" msgstr "Passwort vergessen" @@ -267,8 +634,11 @@ msgstr "Passwort vergessen?" msgid "Free" msgstr "Kostenlos" -msgid "Free forever — no credit card required" -msgstr "Für immer kostenlos — keine Kreditkarte erforderlich" +msgid "Free accounts can be deleted from the API at" +msgstr "Free-Konten können über die API gelöscht werden unter" + +msgid "Free tier forever — upgrade only when you need more" +msgstr "Kostenlos für immer — Upgrade nur, wenn du mehr brauchst" msgid "" "Free tier is live today. Pro & Business launch shortly — paid checkouts " @@ -277,6 +647,32 @@ msgstr "" "Free-Tier ist seit heute live. Pro & Business folgen in Kürze — bezahlte " "Checkouts gehen live, sobald die Zahlungsabwicklung eingerichtet ist." +msgid "Frequently asked questions" +msgstr "Häufige Fragen" + +msgid "" +"Full Compliance Edition. Onboarding together with the maintainer. " +"Priority bug hotfixes." +msgstr "" +"Vollständige Compliance-Edition. Onboarding gemeinsam mit dem Maintainer." +" Bug-Hotfix mit Priorität." + +msgid "GDPR Art. 28 annex ↗" +msgstr "DSGVO Art. 28-Anhang ↗" + +msgid "" +"GDPR Art. 28-compliant DPA — drafted jointly in the pilot conversation " +"and adapted to your authority or clinic specifics." +msgstr "" +"DSGVO-Art.-28-konformer AVV — gemeinsam im Pilotgespräch erarbeitet und " +"auf die Spezifika deiner Behörde oder Klinik angepasst." + +msgid "GDPR DPA template in German form" +msgstr "DSGVO-AVV-Vorlage in deutscher Form" + +msgid "GDPR-aligned file engine for regulated administration." +msgstr "DSGVO-konforme File-Engine für regulierte Verwaltung." + msgid "Get API Key →" msgstr "API-Key holen →" @@ -300,11 +696,46 @@ msgstr "" "Datenschutzverletzungen, Service-Unterbrechungen und Datenzerstörung; " "teste wenn möglich gegen deine eigene selbst gehostete Instanz." +msgid "Hetzner's privacy policy" +msgstr "Hetzners Datenschutzerklärung" + +msgid "How does AGPLv3 behave with citizen-portal integrations?" +msgstr "Wie verhält sich AGPLv3 bei Bürgerportal-Integrationen?" + +msgid "" +"I waive my 14-day right of withdrawal and consent to immediate contract " +"execution pursuant to §356 (5) BGB." +msgstr "" + msgid "If this email exists, you'll receive a reset link shortly." msgstr "" "Falls diese E-Mail-Adresse existiert, erhältst du in Kürze einen " "Zurücksetzungs-Link." +msgid "" +"If you are a consumer (a natural person entering a contract for purposes " +"outside your trade, business or profession) and reside in the European " +"Union, you have the statutory right to withdraw from a paid subscription " +"within fourteen (14) days of contract conclusion — the date your first " +"Stripe payment is confirmed — without giving any reason." +msgstr "" +"Wenn du Verbraucher bist (eine natürliche Person, die einen Vertrag zu " +"Zwecken außerhalb deiner gewerblichen oder selbstständigen Tätigkeit " +"abschließt) und in der Europäischen Union wohnst, hast du das gesetzliche" +" Recht, ein bezahltes Abonnement innerhalb von vierzehn (14) Tagen ab " +"Vertragsschluss — dem Tag der Bestätigung deiner ersten Stripe-Zahlung — " +"ohne Angabe von Gründen zu widerrufen." + +msgid "" +"If you generate an API key (via the dashboard or command-line tool), only" +" the SHA-256 hash of your key is stored. The plaintext key is shown to " +"you exactly once at creation time and is never persisted on our servers." +msgstr "" +"Wenn du einen API-Key erzeugst (über das Dashboard oder das Command-Line-" +"Tool), wird nur der SHA-256-Hash deines Keys gespeichert. Der Klartext-" +"Key wird dir genau einmal bei der Erzeugung angezeigt und niemals auf " +"unseren Servern persistiert." + msgid "" "If you have discovered a security issue in FileMorph or in this " "deployment, please email" @@ -312,15 +743,44 @@ msgstr "" "Wenn du eine Sicherheitslücke in FileMorph oder in diesem Deployment " "entdeckt hast, schicke bitte eine E-Mail an" +msgid "" +"If you register an account, we store your email address, a bcrypt hash of" +" your password (never the plaintext), your subscription tier, your " +"account creation timestamp, and — once you upgrade to a paid tier — the " +"Stripe customer identifier that links your account to Stripe. Account " +"data is persisted in our PostgreSQL database for the lifetime of your " +"account and erased on deletion request (Art. 17 GDPR)." +msgstr "" +"Wenn du ein Konto registrierst, speichern wir deine E-Mail-Adresse, einen" +" bcrypt-Hash deines Passworts (niemals den Klartext), deinen Abonnement-" +"Tier, deinen Konto-Erstellungs-Zeitstempel und — sobald du auf einen " +"bezahlten Tier upgradest — den Stripe-Customer-Identifier, der dein Konto" +" mit Stripe verknüpft. Konto-Daten werden in unserer PostgreSQL-Datenbank" +" für die Lebensdauer deines Kontos persistiert und auf Löschanfrage " +"entfernt (Art. 17 DSGVO)." + msgid "Images · Documents · Audio · Video · Spreadsheets" msgstr "Bilder · Dokumente · Audio · Video · Tabellen" msgid "Impressum" msgstr "Impressum" +msgid "Imprint per German Telemediengesetz §5 (TMG)." +msgstr "Impressum gemäß § 5 Telemediengesetz (TMG)." + msgid "In scope:" msgstr "Im Geltungsbereich:" +msgid "Incident response plan" +msgstr "Incident-Response-Plan" + +msgid "" +"Infringe third-party intellectual property rights through the files you " +"process" +msgstr "" +"Geistige Eigentumsrechte Dritter durch die verarbeiteten Dateien zu " +"verletzen" + msgid "Initial triage:" msgstr "Erste Prüfung:" @@ -344,15 +804,52 @@ msgstr "" msgid "JPEG / WebP only." msgstr "Nur JPEG / WebP." +msgid "" +"KRITIS and air-gap variants on request. All tiers include commercial " +"license, DPA template, signed Docker image and support SLA." +msgstr "" +"KRITIS- und Air-Gap-Varianten auf Anfrage. Alle Tiers enthalten " +"kommerzielle Lizenz, AVV-Vorlage, signiertes Docker-Image und Support-" +"SLA." + msgid "Language" msgstr "Sprache" +msgid "Last updated: 2026-04-23 · Community + Cloud Edition" +msgstr "Zuletzt aktualisiert: 2026-04-23 · Community + Cloud Edition" + +msgid "Last updated: 2026-05-08 · Community + Cloud Edition" +msgstr "Stand: 08.05.2026 · Community + Cloud Edition" + +msgid "" +"Lifts the AGPLv3 publication obligation for internal in-house " +"developments + public citizen-portal integrations." +msgstr "" +"Hebt die AGPLv3-Veröffentlichungspflicht für interne Eigenentwicklungen +" +" öffentliche Bürgerportal-Integrationen auf." + +msgid "Loading…" +msgstr "Wird geladen…" + +msgid "" +"Logo mention as pilot customer (optional). Roadmap feedback every four " +"weeks. Willingness to prioritize feature tickets." +msgstr "" +"Logo-Nennung als Pilotkunde (optional). Roadmap-Feedback alle vier " +"Wochen. Bereitschaft, Feature-Tickets zu priorisieren." + msgid "MP4 · MOV · AVI · MKV · WebM" msgstr "MP4 · MOV · AVI · MKV · WebM" msgid "MP4 · MOV · AVI · MKV · WebM · MP3 · WAV · FLAC · OGG · M4A" msgstr "MP4 · MOV · AVI · MKV · WebM · MP3 · WAV · FLAC · OGG · M4A" +msgid "Member since" +msgstr "Mitglied seit" + +msgid "Mermaid diagram and request lifecycle ↗" +msgstr "Mermaid-Diagramm und Request-Lifecycle ↗" + msgid "Min. 8 characters." msgstr "Min. 8 Zeichen." @@ -369,6 +866,9 @@ msgstr "" msgid "Most popular" msgstr "Am beliebtesten" +msgid "Multi-format (image + audio + video + sheet)" +msgstr "Multi-Format (Bild + Audio + Video + Sheet)" + msgid "New password" msgstr "Neues Passwort" @@ -384,24 +884,89 @@ msgstr "Ein Klick und du bist fertig" msgid "Open dashboard" msgstr "Dashboard öffnen" +msgid "Operator staff with the" +msgstr "Betreiber-Mitarbeiter mit der" + +msgid "Our pages load" +msgstr "Unsere Seiten laden" + msgid "Our response" msgstr "Unsere Reaktion" +msgid "" +"Our web server automatically records standard access log data for each " +"request: IP address, request timestamp, HTTP method, URL path, response " +"status code, and response size. Application-level events (logins, " +"password-reset requests, subscription changes) are logged as structured " +"JSON without plaintext email addresses — only the email domain is kept " +"for debug purposes. Logs are rotated by the hosting infrastructure under " +"standard operational policies (typically up to 30 days) and accessed only" +" for security, abuse-detection, and debugging." +msgstr "" +"Unser Webserver zeichnet für jede Anfrage automatisch Standard-Access-" +"Log-Daten auf: IP-Adresse, Anfrage-Zeitstempel, HTTP-Methode, URL-Pfad, " +"Response-Status-Code und Response-Größe. Anwendungsebene-Events (Logins, " +"Passwort-Reset-Anfragen, Abonnement-Änderungen) werden als strukturiertes" +" JSON ohne Klartext-E-Mail-Adressen geloggt — nur die E-Mail-Domain wird " +"zu Debug-Zwecken behalten. Logs werden von der Hosting-Infrastruktur " +"unter Standard-Operations-Policies rotiert (typisch bis zu 30 Tage) und " +"nur für Security, Missbrauchs-Erkennung und Debugging zugegriffen." + msgid "Out of scope:" msgstr "Nicht im Geltungsbereich:" +msgid "PDF/A-2b output" +msgstr "PDF/A-2b-Output" + +msgid "PDF/A-2b veraPDF-validated" +msgstr "PDF/A-2b veraPDF-validiert" + msgid "Page not found" msgstr "Seite nicht gefunden" +msgid "" +"Paid plans (Pro €7/month, Business €19/month) are billed monthly via " +"Stripe and renew automatically until cancelled. You may cancel at any " +"time through the Stripe customer portal linked from your account " +"dashboard; cancellation takes effect at the end of the current billing " +"period and you retain access for the remainder of that period." +msgstr "" +"Bezahlte Pläne (Pro 7 €/Monat, Business 19 €/Monat) werden monatlich über" +" Stripe abgerechnet und verlängern sich automatisch bis zur Kündigung. Du" +" kannst jederzeit über das im Account-Dashboard verlinkte Stripe-" +"Kundenportal kündigen; die Kündigung wird zum Ende des laufenden " +"Abrechnungszeitraums wirksam, und der Zugang bleibt bis zum Periodenende " +"erhalten." + msgid "Paid tiers — coming soon" msgstr "Bezahlte Tarife — demnächst verfügbar" msgid "Password" msgstr "Passwort" +msgid "" +"Password-reset and other account-related emails are delivered through " +"Zoho Mail (" +msgstr "" +"Passwort-Reset- und andere konto-bezogene E-Mails werden über Zoho Mail " +"zugestellt (" + +msgid "Patch policy" +msgstr "Patch-Policy" + +msgid "" +"Payment processing is handled by Stripe Payments Europe Ltd.; Stripe's " +"terms apply to the processing of your payment details." +msgstr "" +"Die Zahlungsabwicklung erfolgt durch Stripe Payments Europe Ltd.; die AGB" +" von Stripe gelten für die Verarbeitung deiner Zahlungsdaten." + msgid "Plans" msgstr "Tarife" +msgid "Price / year" +msgstr "Preis / Jahr" + msgid "Pricing" msgstr "Preise" @@ -423,12 +988,70 @@ msgstr "Pro · 7 €/Monat" msgid "Processing…" msgstr "Verarbeitung…" +msgid "" +"Public authorities, hospitals and law firms often may not process citizen" +" and client data through public cloud conversion services — the GDPR data" +" chain and the EVB-IT contract framework set tight limits here. At the " +"same time, the typical IT department lacks the bandwidth to maintain a " +"conversion backend on its own." +msgstr "" +"Behörden, Krankenhäuser und Kanzleien dürfen Bürger- und Mandantendaten " +"in vielen Fällen nicht durch öffentliche Cloud-Konvertierungs-Dienste " +"verarbeiten — die DSGVO-Datenkette und das EVB-IT-Vertragswerk setzen " +"hier enge Grenzen. Gleichzeitig fehlt der typischen IT-Abteilung die " +"Bandbreite, ein Konvertierungs-Backend selbst zu pflegen." + +msgid "" +"Public authority, clinic IT, law firm with a concrete GDPR conversion use" +" case. We filter for pilot readiness — not every applicant fits." +msgstr "" +"Behörde, Klinik-IT, Anwaltskanzlei mit konkretem DSGVO-Konvertierungs-" +"Use-Case. Wir filtern auf Pilotreife — nicht jeder Interessent passt." + +msgid "" +"Pursuant to § 356 (5) BGB, the right of withdrawal expires when we begin " +"executing the contract — i.e. when paid-tier API access becomes available" +" — provided you (a) expressly consented to this and (b) acknowledged that" +" you lose your right of withdrawal upon full performance. By ticking the " +"dedicated waiver checkbox on the pricing page before being redirected to " +"Stripe checkout, you give such consent. Without this acknowledgement, the" +" standard 14-day withdrawal protection applies. The Community Edition " +"(free of charge) is not subject to a right of withdrawal because no " +"contract for paid services is concluded." +msgstr "" +"Gemäß § 356 Abs. 5 BGB erlischt das Widerrufsrecht, sobald wir mit der " +"Ausführung des Vertrags beginnen — d. h. sobald der API-Zugang der " +"bezahlten Stufe verfügbar wird — vorausgesetzt, du hast (a) ausdrücklich " +"zugestimmt und (b) zur Kenntnis genommen, dass du dein Widerrufsrecht bei" +" vollständiger Vertragserfüllung verlierst. Mit dem Setzen des speziellen" +" Verzichts-Häkchens auf der Preisseite vor der Weiterleitung zum Stripe-" +"Checkout erteilst du diese Zustimmung. Ohne diese Bestätigung gilt der " +"Standardschutz von 14 Tagen. Die Community Edition (kostenfrei) " +"unterliegt keinem Widerrufsrecht, da kein Vertrag über kostenpflichtige " +"Leistungen abgeschlossen wird." + msgid "Quality" msgstr "Qualität" msgid "RFC 9116 · referenced from" msgstr "RFC 9116 · referenziert von" +msgid "RFC 9116, with response times and scope" +msgstr "RFC 9116, mit Reaktionszeiten und Scope" + +msgid "Ready for a 15-minute pilot call?" +msgstr "Bereit für ein 15-Minuten-Pilotgespräch?" + +msgid "" +"Refunds are not issued for partial billing periods. In the event of a " +"documented service outage exceeding 24 hours within a single billing " +"period, you may request a discretionary credit by contacting:" +msgstr "" +"Eine anteilige Erstattung für nicht genutzte Abrechnungszeiträume erfolgt" +" nicht. Bei einem dokumentierten Service-Ausfall von mehr als 24 Stunden " +"innerhalb eines Abrechnungszeitraums kannst du auf Kulanzbasis eine " +"Gutschrift anfragen unter:" + msgid "Register" msgstr "Registrieren" @@ -445,9 +1068,44 @@ msgstr "" "Berichte, die ausschließlich von automatisierten Scannern ohne " "funktionierenden Proof-of-Concept erstellt wurden." +msgid "" +"Reproducible builds and air-gap update mechanism are also Year-2 " +"(required for the KRITIS variant, not critical in the standard tier)." +msgstr "" +"Reproducible-Builds und Air-Gap-Update-Mechanismus sind ebenfalls Year-2 " +"(für die KRITIS-Variante erforderlich, im Standard-Tier nicht kritisch)." + +msgid "Request pilot call" +msgstr "Pilotgespräch anfragen" + +msgid "Request pilot call by email" +msgstr "Pilotgespräch per E-Mail anfragen" + msgid "Reset Password" msgstr "Passwort zurücksetzen" +msgid "" +"Response-time targets by severity — critical 4 h, high 24 h, medium/low " +"in the next regular release. Targets apply Mon–Fri 09:00–18:00 CET, " +"excluding German public holidays." +msgstr "" +"Reaktionszeiten nach Schweregrad — kritisch 4 h, hoch 24 h, " +"mittel/niedrig im nächsten regulären Release. Die Zielwerte gelten Mo–Fr " +"09:00–18:00 MEZ, ausgenommen gesetzliche Feiertage in Deutschland." + +msgid "SHA-256 audit log" +msgstr "SHA-256-Audit-Log" + +msgid "" +"SHA-256-chained operations log, ISO 27001 A.12.4.1 / BORA §50 / BeurkG " +"§39a." +msgstr "" +"SHA-256-verkettetes Operations-Log, ISO 27001 A.12.4.1 / BORA §50 / " +"BeurkG §39a." + +msgid "STRIDE threat model" +msgstr "STRIDE-Threat-Model" + msgid "Safe-harbour" msgstr "Safe-Harbour" @@ -457,15 +1115,33 @@ msgstr "Gespeicherte API-Keys & Dashboard" msgid "Scope" msgstr "Geltungsbereich" +msgid "Security Disclosure Policy" +msgstr "Security-Disclosure-Policy" + msgid "Security disclosure policy" msgstr "Sicherheits-Offenlegungsrichtlinie" +msgid "See" +msgstr "Siehe" + msgid "See all plans →" msgstr "Alle Tarife anzeigen →" msgid "Select one or more files to convert or compress" msgstr "Wähle eine oder mehrere Dateien zum Konvertieren oder Komprimieren" +msgid "Self-hosted (data stays in-house)" +msgstr "Self-Hosted (Daten bleiben im Haus)" + +msgid "" +"Self-hosted behind your firewall. AGPLv3 + commercial license. EU vendor " +"with German imprint, individually drafted DPA template in pilot " +"conversation, and SBOM in every release." +msgstr "" +"Self-hosted hinter deiner Firewall. AGPLv3 + kommerzielle Lizenz. EU-" +"Anbieter mit deutschem Impressum, individuell ausgearbeitete AVV-Vorlage " +"im Pilotgespräch und SBOM in jedem Release." + msgid "" "Self-hoster-specific deployment misconfiguration that is not caused by " "our defaults or documentation." @@ -476,6 +1152,13 @@ msgstr "" msgid "Send Reset Link" msgstr "Link senden" +msgid "" +"Server-volume-based, not per user seat. Binding terms follow the personal" +" conversation." +msgstr "" +"Server-Volumen-basiert, nicht per User-Seat. Verbindliche Konditionen " +"folgen dem persönlichen Gespräch." + msgid "Set a new password" msgstr "Neues Passwort festlegen" @@ -485,6 +1168,12 @@ msgstr "Anmelden" msgid "Sign in" msgstr "Anmelden" +msgid "Signed image + SBOM" +msgstr "Signiertes Image + SBOM" + +msgid "Signed releases + SBOM" +msgstr "Signierte Releases + SBOM" + msgid "Simple, transparent pricing" msgstr "Einfache, transparente Preise" @@ -496,6 +1185,20 @@ msgstr "" "Auf unserer Seite ist etwas schiefgelaufen. Bitte versuche es gleich noch" " einmal." +msgid "Source code" +msgstr "Quellcode" + +msgid "" +"Standard tier is enough for most KRITIS requirements (self-hosting, audit" +" log, signed artefacts). Enterprise becomes relevant once air-gap update " +"mechanism, reproducible builds or dedicated support SLA are required. We " +"clarify this in 15 minutes by phone." +msgstr "" +"Standard-Tier reicht für die meisten KRITIS-Voraussetzungen (Self-" +"Hosting, Audit-Log, signierte Artefakte). Enterprise wird relevant, " +"sobald Air-Gap-Update-Mechanismus, Reproducible-Builds oder dedizierter " +"Support-SLA gefordert sind. Wir klären das in 15 Minuten am Telefon." + msgid "Start free. Upgrade when you need more. No hidden fees." msgstr "Kostenlos starten. Upgraden bei Bedarf. Keine versteckten Gebühren." @@ -504,6 +1207,26 @@ msgstr "" "Schritte zur Reproduktion, einschließlich erforderlicher Konfiguration " "oder Input-Dateien." +msgid "Stripe (payments):" +msgstr "Stripe (Zahlungen):" + +msgid "" +"Stripe may retain records of past transactions independently of our " +"deletion, to comply with its own legal and tax obligations." +msgstr "" +"Stripe kann Aufzeichnungen vergangener Transaktionen unabhängig von " +"unserer Löschung aufbewahren, um eigenen rechtlichen und steuerlichen " +"Verpflichtungen nachzukommen." + +msgid "Stripe's privacy policy" +msgstr "Stripes Datenschutzerklärung" + +msgid "Sub-processor list" +msgstr "Sub-Processor-Liste" + +msgid "Support SLA" +msgstr "Support-SLA" + msgid "Supported: HEIC · JPG · PNG · WebP · BMP · TIFF · GIF" msgstr "Unterstützt: HEIC · JPG · PNG · WebP · BMP · TIFF · GIF" @@ -534,15 +1257,70 @@ msgstr "" "Instanz betreffen, da die Repository-Maintainer eine CVE koordinieren und" " eine gepatchte Version zentral veröffentlichen können." +msgid "" +"The Compliance Edition is self-hosted. If you can't operate your own " +"infrastructure, filemorph.io (Cloud Edition) is the right path — " +"different data class, different contracts, no EVB-IT anchor." +msgstr "" +"Compliance-Edition ist self-hosted. Wenn Sie keine eigene Infrastruktur " +"betreiben können, ist filemorph.io (Cloud-Edition) der richtige Pfad — " +"andere Datenklasse, andere Verträge, kein EVB-IT-Anker." + msgid "The FileMorph application source code (this repository)." msgstr "Der FileMorph-Anwendungs-Quellcode (dieses Repository)." +msgid "" +"The Service is provided \"as is\" without warranty of any kind, express " +"or implied. We do not guarantee uptime, accuracy of conversion results, " +"or fitness for a particular purpose." +msgstr "" +"Der Dienst wird „wie besehen“ ohne ausdrückliche oder stillschweigende " +"Gewährleistung bereitgestellt. Wir garantieren keine Verfügbarkeit, " +"Konvertierungs-Ergebnis-Genauigkeit oder Eignung für einen bestimmten " +"Zweck." + +msgid "" +"The legal information below is provided in German as required by German " +"law." +msgstr "" +"Die nachfolgenden rechtlichen Angaben sind aus rechtlichen Gründen auf " +"Deutsch verfasst." + msgid "The official Docker images and release artifacts." msgstr "Die offiziellen Docker-Images und Release-Artefakte." msgid "The page you are looking for does not exist or has been moved." msgstr "Die gesuchte Seite existiert nicht oder wurde verschoben." +msgid "" +"The table describes typical characteristics of the named provider " +"categories and is not a definitive comparison of specific products. " +"Individual providers may do more or less — please check the current offer" +" directly with the manufacturer." +msgstr "" +"Die Tabelle beschreibt typische Eigenschaften der genannten Anbieter-" +"Kategorien und ist kein abschließender Vergleich konkreter Produkte. " +"Einzelne Anbieter können mehr oder weniger leisten — bitte das jeweils " +"aktuelle Angebot direkt beim Hersteller prüfen." + +msgid "" +"These Terms are governed by the laws of the Federal Republic of Germany. " +"Place of jurisdiction is Hamburg, Germany." +msgstr "" +"Diese Bedingungen unterliegen dem Recht der Bundesrepublik Deutschland. " +"Gerichtsstand ist Hamburg, Deutschland." + +msgid "" +"These entries fall under the \"strictly necessary\" exemption of Art. " +"5(3) ePrivacy Directive / § 25 Abs. 2 Nr. 2 TTDSG and therefore do not " +"require a consent banner. For anonymous usage, nothing is stored in your " +"browser at all." +msgstr "" +"Diese Einträge fallen unter die „strikt notwendig“-Ausnahme von Art. 5(3)" +" ePrivacy-Richtlinie / § 25 Abs. 2 Nr. 2 TTDSG und erfordern daher kein " +"Consent-Banner. Bei anonymer Nutzung wird überhaupt nichts in deinem " +"Browser gespeichert." + msgid "" "Third-party services we depend on (Stripe, Zoho, Cloudflare, Hetzner) — " "please report to those vendors directly." @@ -550,6 +1328,13 @@ msgstr "" "Drittanbieter-Dienste, von denen wir abhängen (Stripe, Zoho, Cloudflare, " "Hetzner) — bitte direkt an die jeweiligen Anbieter melden." +msgid "" +"This English translation is provided for accessibility. The German " +"version is the authoritative legal text in case of conflict." +msgstr "" +"Diese deutsche Fassung ist die rechtlich verbindliche Version. Die " +"englische Übersetzung dient nur der Barrierefreiheit." + msgid "This link is missing a reset token. Request a new one from" msgstr "Diesem Link fehlt ein Zurücksetzungs-Token. Fordere einen neuen an unter" @@ -560,12 +1345,62 @@ msgstr "" "Diesem Link fehlt ein Bestätigungs-Token. Melde dich an und fordere eine " "neue Bestätigungs-E-Mail vom Dashboard an." +msgid "" +"This service is hosted by Hetzner Online GmbH, Germany (Frankfurt data " +"centre). Your requests are routed through Cloudflare's network for DDoS " +"protection and performance. See" +msgstr "" +"Dieser Dienst wird gehostet von Hetzner Online GmbH, Deutschland " +"(Rechenzentrum Frankfurt). Deine Anfragen werden über Cloudflares " +"Netzwerk für DDoS-Schutz und Performance geroutet. Siehe" + +msgid "" +"Three spots. Six months free. Direct influence on the Compliance Edition " +"roadmap." +msgstr "" +"Drei Plätze. Sechs Monate kostenfrei. Direkter Einfluss auf die Roadmap " +"der Compliance-Edition." + +msgid "Tier" +msgstr "Tier" + +msgid "Tier overview" +msgstr "Tier-Übersicht" + +msgid "To exercise the right of withdrawal, send an unambiguous statement to:" +msgstr "Um das Widerrufsrecht auszuüben, sende eine eindeutige Erklärung an:" + +msgid "" +"To operate FileMorph we rely on the following sub-processors. Each one " +"receives only the minimum data needed for its task:" +msgstr "" +"Zum Betrieb von FileMorph verlassen wir uns auf folgende Sub-Processors. " +"Jeder erhält nur die minimal für seine Aufgabe notwendigen Daten:" + +msgid "" +"To the extent permitted by applicable law, the operator of FileMorph " +"shall not be liable for any direct, indirect, incidental, or " +"consequential damages arising from your use of the Service." +msgstr "" +"Soweit nach geltendem Recht zulässig, haftet der Betreiber von FileMorph " +"nicht für direkte, indirekte, beiläufige oder Folgeschäden, die aus " +"deiner Nutzung des Dienstes entstehen." + msgid "Toggle menu" msgstr "Menü umschalten" +msgid "Trust basis before contract" +msgstr "Vertrauensbasis vor dem Vertrag" + msgid "Type it again" msgstr "Erneut eingeben" +msgid "Typical SaaS converters" +msgstr "Typische SaaS-Konvertierer" + +msgid "Typical open-source converters" +msgstr "Typische Open-Source-Konvertierer" + msgid "Up to 100 MB per file" msgstr "Bis zu 100 MB pro Datei" @@ -584,6 +1419,19 @@ msgstr "Auf Business upgraden" msgid "Upgrade to Pro" msgstr "Auf Pro upgraden" +msgid "Upload files that contain malware, exploits, or illegal content" +msgstr "Dateien hochzuladen, die Malware, Exploits oder illegale Inhalte enthalten" + +msgid "" +"Use the Service for automated large-scale processing without prior " +"agreement" +msgstr "" +"Den Dienst für automatisierte Large-Scale-Verarbeitung ohne vorherige " +"Vereinbarung zu nutzen" + +msgid "Use these to authenticate programmatic API requests." +msgstr "Verwende diese zur Authentifizierung programmatischer API-Anfragen." + msgid "Using anonymously: up to 20 MB per file." msgstr "Anonyme Nutzung: bis zu 20 MB pro Datei." @@ -594,21 +1442,188 @@ msgstr "" "Ohne Konto verwenden: bis zu 20 MB pro Datei · einzelne Dateien · 10 " "Anfragen/Minute · kein API-Zugriff" +msgid "" +"We apply a temporary in-memory rate limit (max. 10 requests per minute " +"per IP address) to protect the service from abuse. IP addresses used by " +"the rate limiter are processed transiently in memory only and are never " +"written to disk or logs. Legal basis: Art. 6(1)(f) GDPR — legitimate " +"interest in service stability and security." +msgstr "" +"Wir wenden ein temporäres In-Memory-Rate-Limit (max. 10 Anfragen pro " +"Minute pro IP-Adresse) an, um den Dienst vor Missbrauch zu schützen. Vom " +"Rate-Limiter verwendete IP-Adressen werden nur transient im Speicher " +"verarbeitet und niemals auf Disk oder in Logs geschrieben. " +"Rechtsgrundlage: Art. 6(1)(f) DSGVO — berechtigtes Interesse an Dienst-" +"Stabilität und Sicherheit." + +msgid "" +"We may update this policy when the service changes. Accounts and billing " +"are live as of April 2026; persistent file history (Cloud Edition Phase " +"2) is planned but not yet implemented. The date at the top indicates the " +"current version." +msgstr "" +"Wir können diese Richtlinie aktualisieren, wenn sich der Dienst ändert. " +"Accounts und Billing sind seit April 2026 live; persistente Datei-" +"Historie (Cloud Edition Phase 2) ist geplant aber noch nicht " +"implementiert. Das Datum oben zeigt die aktuelle Version an." + +msgid "" +"We name it because an RFP reviewer would notice anyway — and because we " +"prefer to keep the roadmap transparent rather than embellished." +msgstr "" +"Wir benennen das, weil ein RFP-Reviewer es ohnehin bemerken würde — und " +"weil wir die Roadmap lieber transparent statt geschönt halten." + msgid "Welcome back to FileMorph" msgstr "Willkommen zurück bei FileMorph" +msgid "What does the Edition cost?" +msgstr "Was kostet die Edition?" + +msgid "What does the data export look like if we migrate?" +msgstr "Wie sieht der Datenexport aus, wenn wir migrieren?" + +msgid "What happens if we cancel?" +msgstr "Was passiert, wenn wir kündigen?" + msgid "What to include in a report" msgstr "Was ein Bericht enthalten sollte" +msgid "What we deliver compared to typical alternatives" +msgstr "Was wir gegenüber typischen Alternativen liefern" + +msgid "What we're transparent about" +msgstr "Worüber wir transparent sind" + +msgid "What you get" +msgstr "Was Sie bekommen" + +msgid "What you give" +msgstr "Was Sie geben" + +msgid "What's in the Compliance Edition" +msgstr "Inhalt der Compliance-Edition" + +msgid "" +"When you request a password reset, we generate a single-use token (valid " +"for 30 minutes) and send it to your registered email address as a reset " +"link. The outgoing message is delivered from" +msgstr "" +"Wenn du ein Passwort-Reset anforderst, generieren wir einen Einmal-Token " +"(gültig für 30 Minuten) und senden ihn als Reset-Link an deine " +"registrierte E-Mail-Adresse. Die ausgehende Nachricht wird verschickt von" + +msgid "" +"When you start a paid-tier upgrade, you are redirected to Stripe Checkout" +" on the" +msgstr "" +"Wenn du ein Paid-Tier-Upgrade startest, wirst du zum Stripe-Checkout auf " +"der" + +msgid "" +"When you upgrade to a paid tier, we create a Stripe customer record " +"containing your email address and an internal user identifier, then " +"redirect you to" +msgstr "" +"Wenn du auf einen bezahlten Tier upgradest, erzeugen wir einen Stripe-" +"Customer-Record mit deiner E-Mail-Adresse und einem internen User-" +"Identifier, und leiten dich dann weiter zu" + msgid "Whether the issue has been disclosed publicly elsewhere." msgstr "Ob das Problem bereits anderswo öffentlich offengelegt wurde." +msgid "Who's a fit" +msgstr "Wer passt" + +msgid "Why a Compliance Edition?" +msgstr "Warum eine Compliance-Edition?" + +msgid "" +"You also have the right to lodge a complaint with your local data " +"protection authority." +msgstr "" +"Du hast außerdem das Recht, Beschwerde bei deiner lokalen " +"Datenschutzbehörde einzureichen." + +msgid "" +"You can fully audit FileMorph before the first conversation. All relevant" +" security and architecture documents are freely accessible:" +msgstr "" +"Sie können FileMorph vor dem ersten Gespräch vollständig prüfen. Alle " +"relevanten Sicherheits- und Architektur-Dokumente sind frei zugänglich:" + +msgid "" +"You have the right to access, rectify, erase, and restrict processing of " +"your personal data (Art. 15–21 GDPR). To exercise these rights, contact " +"us at" +msgstr "" +"Du hast das Recht auf Auskunft, Berichtigung, Löschung und Einschränkung " +"der Verarbeitung deiner personenbezogenen Daten (Art. 15–21 DSGVO). Um " +"diese Rechte auszuüben, kontaktiere uns unter" + +msgid "" +"You keep the code (AGPLv3 stays). You lose the commercial license, the " +"updated DPA, new releases with compliance features, and the support SLA. " +"Existing installations continue running — no lock-in via forced updates." +msgstr "" +"Sie behalten den Code (AGPLv3 bleibt). Sie verlieren die kommerzielle " +"Lizenz, das aktualisierte AVV, neue Releases mit Compliance-Features, und" +" den Support-SLA. Bestehende Installationen laufen weiter — kein Lock-in " +"über Zwangs-Updates." + +msgid "You may not use the Service to:" +msgstr "Du darfst den Dienst nicht nutzen, um:" + +msgid "" +"You're evaluating conversion software for a public authority, hospital or" +" law firm? Write to us with your use case — we respond within one " +"business day." +msgstr "" +"Sie evaluieren Konvertierungs-Software für eine Behörde, ein Krankenhaus " +"oder eine Kanzlei? Schreiben Sie uns mit Ihrem Use-Case — wir antworten " +"innerhalb eines Werktages." + msgid "Your email is now verified." msgstr "Deine E-Mail-Adresse ist jetzt bestätigt." msgid "Your password has been updated." msgstr "Dein Passwort wurde aktualisiert." +msgid "Zoho Mail (transactional email):" +msgstr "Zoho Mail (Transaktions-E-Mail):" + +msgid "Zoho's privacy policy" +msgstr "Zohos Datenschutzerklärung" + +msgid "" +"after a three-field re-confirmation (your password, your email, and the " +"literal word" +msgstr "" +"nach einer Drei-Felder-Re-Bestätigung (dein Passwort, deine E-Mail-" +"Adresse und das wörtliche Wort" + +msgid "and" +msgstr "und" + +msgid "are encrypted with the same key." +msgstr "werden mit demselben Schlüssel verschlüsselt." + +msgid "" +"cosign keyless OIDC, cryptographically signed git tags, CycloneDX-JSON " +"SBOM in every GitHub release." +msgstr "" +"cosign keyless OIDC, kryptographisch signierte Git-Tags, CycloneDX-JSON-" +"SBOM in jedem GitHub-Release." + +msgid "" +"cosign-signed Docker image, cryptographically signed git tags, CycloneDX-" +"JSON SBOM in every release. Aligned with the EVB-IT cloud clause (March " +"2026)." +msgstr "" +"Cosign-signiertes Docker-Image, kryptographisch signierte Git-Tags, " +"CycloneDX-JSON-SBOM in jedem Release. Abgestimmt auf die EVB-IT-Cloud-" +"Klausel (März 2026)." + msgid "" "critical issues within 7 days, high severity within 30 days, medium/low " "within the next regular release." @@ -616,6 +1631,28 @@ msgstr "" "kritische Probleme innerhalb von 7 Tagen, hohe Schwere innerhalb von 30 " "Tagen, mittel/niedrig im nächsten regulären Release." +msgid "" +"domain, which sets its own cookies. That is outside FileMorph's control " +"and is governed by" +msgstr "" +"-Domain umgeleitet, die eigene Cookies setzt. Das liegt außerhalb der " +"Kontrolle von FileMorph und unterliegt" + +msgid "escalation, post-mortem template ↗" +msgstr "Eskalation, Post-Mortem-Vorlage ↗" + +msgid "for full contact details." +msgstr "für vollständige Kontaktdaten." + +msgid "for their data processing terms." +msgstr "für deren Datenverarbeitungs-Bedingungen." + +msgid "from € 24,900" +msgstr "ab € 24.900" + +msgid "full GitHub repository ↗" +msgstr "vollständiges GitHub-Repository ↗" + msgid "hint. Large batches are processed sequentially inside the request." msgstr "" "Hinweis. Große Batches werden sequentiell innerhalb der Anfrage " @@ -624,12 +1661,102 @@ msgstr "" msgid "min 0.05 MB" msgstr "min. 0,05 MB" +msgid "no cookies" +msgstr "keine Cookies" + +msgid "no external resources" +msgstr "keine externen Ressourcen" + +msgid "not applicable" +msgstr "nicht zutreffend" + +msgid "often limited to one area" +msgstr "häufig auf einen Bereich beschränkt" + +msgid "often ✓" +msgstr "häufig ✓" + +msgid "" +"on its own domain and runs no tracking or analytics scripts. A small " +"number of keys are written to your browser's" +msgstr "" +"auf der eigenen Domain und betreibt keine Tracking- oder Analytics-" +"Skripte. Eine kleine Anzahl Keys wird im" + +msgid "only while you are signed in:" +msgstr "deines Browsers gespeichert, während du angemeldet bist:" + +msgid "" +"optional; remembers the API key shown in your dashboard across reloads so" +" you don't need to paste it again. Cleared on logout." +msgstr "" +"optional; merkt sich den im Dashboard angezeigten API-Key über Reloads " +"hinweg, damit du ihn nicht erneut einfügen musst. Wird beim Logout " +"gelöscht." + +msgid "or apply directly as design partner →" +msgstr "oder direkt als Design-Partner bewerben →" + msgid "or click to browse (multi-file supported)" msgstr "oder klicken zum Auswählen (Mehrfach-Dateien möglich)" msgid "per request" msgstr "pro Anfrage" +msgid "rare" +msgstr "selten" + +msgid "" +"role can access an internal cockpit that lists registered email addresses" +" in plaintext, along with subscription tier, account creation date, and " +"Stripe subscription status — strictly for service operation, abuse " +"response, and support. Admin actions (tier changes, role changes, " +"deactivations) are recorded with the admin's user identifier, the target " +"user's identifier, and the change performed, to enable internal auditing." +" Legal basis: Art. 6(1)(f) GDPR." +msgstr "" +"-Rolle können auf ein internes Cockpit zugreifen, das registrierte E" +"-Mail-Adressen im Klartext auflistet, zusammen mit Abonnement-Tier, " +"Konto-Erstellungs-Datum und Stripe-Abonnement-Status — strikt zum Betrieb" +" des Dienstes, zur Missbrauchs-Reaktion und zum Support. Admin-Aktionen " +"(Tier-Wechsel, Rollen-Änderungen, Deaktivierungen) werden mit dem User-" +"Identifier des Admins, dem User-Identifier des Ziel-Users und der " +"durchgeführten Änderung aufgezeichnet, um interne Auditierung zu " +"ermöglichen. Rechtsgrundlage: Art. 6(1)(f) DSGVO." + +msgid "threat-mitigation anchors per category ↗" +msgstr "Bedrohung-Mitigation-Anker pro Kategorie ↗" + +msgid "" +"to complete payment. Stripe handles all card details directly — FileMorph" +" never sees or stores your card data. After checkout, Stripe returns a " +"customer identifier which we store to manage your subscription. Stripe is" +" a US-based company; the transfer is covered by the EU Standard " +"Contractual Clauses under Stripe's Data Processing Agreement. Legal " +"basis: Art. 6(1)(b) GDPR. See" +msgstr "" +"zum Abschluss der Zahlung. Stripe verarbeitet alle Kartendaten direkt — " +"FileMorph sieht oder speichert deine Kartendaten niemals. Nach dem " +"Checkout gibt Stripe einen Customer-Identifier zurück, den wir zur " +"Verwaltung deines Abonnements speichern. Stripe ist ein US-basiertes " +"Unternehmen; der Transfer ist durch die EU-Standardvertragsklauseln unter" +" Stripes Auftragsverarbeitungsvertrag gedeckt. Rechtsgrundlage: Art. " +"6(1)(b) DSGVO. Siehe" + +msgid "unlimited servers, dedicated onboarding, custom SLA" +msgstr "unbegrenzte Server, dediziertes Onboarding, Custom-SLA" + +msgid "varies" +msgstr "variabel" + +msgid "versioning, CVSS bands, signed artefacts ↗" +msgstr "Versionierung, CVSS-Bänder, signierte Artefakte ↗" + +msgid "via our email provider (see § 3a). We do not send marketing emails." +msgstr "" +"über unseren E-Mail-Provider (siehe § 3a). Wir senden keine " +"Marketing-E-Mails." + msgid "" "we publish an advisory once a fixed release is available, and credit " "reporters who wish to be named." @@ -637,6 +1764,9 @@ msgstr "" "wir veröffentlichen einen Advisory, sobald ein Fix-Release verfügbar ist," " und nennen Reporter, die genannt werden möchten." +msgid "when publication obligation applies, when not ↗" +msgstr "wann Veröffentlichungspflicht greift, wann nicht ↗" + msgid "with a" msgstr "mit einem" @@ -655,6 +1785,9 @@ msgstr "innerhalb von 7 Tagen, einschließlich einer Schweregrad-Bewertung." msgid "within 72 hours of receipt." msgstr "innerhalb von 72 Stunden nach Eingang." +msgid "your JWT session tokens; strictly necessary to keep you signed in." +msgstr "deine JWT-Session-Tokens; strikt notwendig um dich angemeldet zu halten." + msgid "© 2026 FileMorph — AGPLv3 Open Source" msgstr "© 2026 FileMorph — AGPLv3 Open Source" @@ -667,3 +1800,17 @@ msgstr "— erst eine Datei wählen —" msgid "← Back" msgstr "← Zurück" +#~ msgid "" +#~ "FileMorph — Free online file converter" +#~ " & compressor. Convert images, documents," +#~ " audio and video. Fast, private, no" +#~ " account required." +#~ msgstr "" +#~ "FileMorph — Kostenloser Online-Datei-" +#~ "Konverter & -Kompressor. Bilder, Dokumente," +#~ " Audio und Video konvertieren. Schnell, " +#~ "privat, kein Konto erforderlich." + +#~ msgid "Free forever — no credit card required" +#~ msgstr "Für immer kostenlos — keine Kreditkarte erforderlich" + diff --git a/locale/en/LC_MESSAGES/messages.mo b/locale/en/LC_MESSAGES/messages.mo index de63a55..01c8740 100644 Binary files a/locale/en/LC_MESSAGES/messages.mo and b/locale/en/LC_MESSAGES/messages.mo differ diff --git a/locale/en/LC_MESSAGES/messages.po b/locale/en/LC_MESSAGES/messages.po index 966ec23..6790ec5 100644 --- a/locale/en/LC_MESSAGES/messages.po +++ b/locale/en/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: FileMorph VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2026-05-08 15:52+0200\n" +"POT-Creation-Date: 2026-05-08 14:43+0200\n" "PO-Revision-Date: 2026-05-07 13:43+0200\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -18,9 +18,25 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.18.0\n" +msgid "" +" — for example: \"I hereby withdraw from the contract concluded on [date]" +" for the FileMorph [Pro / Business] subscription.\" Including your " +"registered email address speeds up identification of your account." +msgstr "" + msgid "(vs. 20 MB anonymous)" msgstr "" +msgid "" +"). The cascade removes your login credentials and API keys; conversion-" +"job and usage-record entries are anonymised (your account ID is nulled, " +"the rows are kept as anonymous aggregate data under DSGVO Art. 4(1)). A " +"confirmation email is sent after the row is gone." +msgstr "" + +msgid "+ New Key" +msgstr "" + msgid ", 1 concurrent, 10 req/min" msgstr "" @@ -30,12 +46,30 @@ msgstr "" msgid ", 5 concurrent, 10 req/min" msgstr "" +msgid "" +", hosted in Frankfurt, EU). Zoho receives the recipient address and the " +"email contents (including the reset link). Legal basis: Art. 6(1)(b) " +"GDPR. See" +msgstr "" + msgid "/mo" msgstr "" +msgid "1 server, ≤ 50 employees" +msgstr "" + +msgid "1. Acceptance" +msgstr "" + +msgid "1. Who is responsible?" +msgstr "" + msgid "10,000 API calls / month" msgstr "" +msgid "10. Contact" +msgstr "" + msgid "100 MB · 10k API" msgstr "" @@ -45,21 +79,66 @@ msgstr "" msgid "100,000 API calls / month" msgstr "" +msgid "2. Description of Service" +msgstr "" + +msgid "2. What data we process" +msgstr "" + msgid "25 files" msgstr "" +msgid "2a. Uploaded files:" +msgstr "" + +msgid "2b. User accounts (Cloud Edition):" +msgstr "" + +msgid "2c. Transactional emails:" +msgstr "" + +msgid "2d. Server logs:" +msgstr "" + +msgid "2e. API keys:" +msgstr "" + +msgid "3 servers, ≤ 2,000 employees" +msgstr "" + +msgid "3. Acceptable Use" +msgstr "" + +msgid "3. Legal basis (GDPR Art. 6)" +msgstr "" + msgid "30+ formats (images, docs, audio, video)" msgstr "" msgid "30+ formats incl. video" msgstr "" +msgid "3a. External services (Sub-Processors)" +msgstr "" + +msgid "4. Disclaimer of Warranties" +msgstr "" + +msgid "4. Hosting" +msgstr "" + msgid "404 – Not Found" msgstr "" msgid "5 files" msgstr "" +msgid "5. Limitation of Liability" +msgstr "" + +msgid "5. Your rights (GDPR)" +msgstr "" + msgid "50 MB · API key" msgstr "" @@ -72,36 +151,108 @@ msgstr "" msgid "500 – Server Error" msgstr "" +msgid "6. No cookies, no tracking" +msgstr "" + +msgid "6. Open Source License" +msgstr "" + +msgid "7. Governing Law" +msgstr "" + +msgid "7. Rate limiting & abuse prevention" +msgstr "" + +msgid "8. Changes to this policy" +msgstr "" + +msgid "8. Subscriptions (Cloud Edition)" +msgstr "" + +msgid "9. Admin access (transparency)" +msgstr "" + +msgid "9. Right of Withdrawal (Consumers)" +msgstr "" + msgid "A description of the vulnerability and its potential impact." msgstr "" +msgid "AGPLv3 for public authorities" +msgstr "" + msgid "API Docs" msgstr "" msgid "API Docs ↗" msgstr "" +msgid "API Keys" +msgstr "" + msgid "API key management" msgstr "" msgid "API key — " msgstr "" +msgid "" +"Account creation, paid subscriptions, and transactional emails are " +"processed on the basis of Art. 6(1)(b) GDPR (performance of a contract). " +"Server-log processing, rate-limiting, and abuse prevention are based on " +"our legitimate interest (Art. 6(1)(f) GDPR) in operating a secure and " +"reliable service." +msgstr "" + +msgid "Account deletion:" +msgstr "" + +msgid "" +"Accounts that have ever been linked to Stripe cannot use the self-service" +" path yet — German commercial law (HGB §257, AO §147) requires a 10-year " +"retention of tax-relevant records under Art. 17(3)(b) GDPR. For these " +"accounts, contact" +msgstr "" + msgid "Acknowledgement:" msgstr "" msgid "Affected version (commit hash or release tag if known)." msgstr "" +msgid "" +"All CSS (including Tailwind), JavaScript, fonts, and images are served " +"from the FileMorph domain; your browser never contacts a third-party CDN " +"to render the site." +msgstr "" + msgid "All prices excl. VAT where applicable. Payments processed by Stripe." msgstr "" msgid "Already have an account?" msgstr "" +msgid "" +"An orientation about the provider categories common in DACH RFPs. In " +"individual cases, a specific product may do more — please check " +"individually." +msgstr "" + +msgid "Apply as design partner" +msgstr "" + +msgid "Architecture overview" +msgstr "" + msgid "At least 8 characters" msgstr "" +msgid "Attempt to circumvent rate limits or security controls" +msgstr "" + +msgid "Audit log with hash chain" +msgstr "" + msgid "Back to Home" msgstr "" @@ -129,24 +280,63 @@ msgstr "" msgid "By target size" msgstr "" +msgid "" +"By using FileMorph (the \"Service\"), you agree to these Terms of Use. If" +" you do not agree, do not use the Service." +msgstr "" + msgid "Choose a password you haven't used before" msgstr "" msgid "Clear all" msgstr "" +msgid "Cloudflare's privacy policy" +msgstr "" + msgid "Coming soon" msgstr "" +msgid "Commercial license" +msgstr "" + +msgid "Commercial license on AGPL code" +msgstr "" + +msgid "Compliance" +msgstr "" + +msgid "Compliance Edition" +msgstr "" + msgid "Compliance Edition →" msgstr "" +msgid "Compliance Enterprise" +msgstr "" + +msgid "Compliance Standard" +msgstr "" + +msgid "Compliance Starter" +msgstr "" + +msgid "" +"Compliance assertions on this page cite German statutes (HGB §257, AO " +"§147, DSGVO Art 17). This English translation is provided for " +"accessibility — the German version is the authoritative legal text in " +"case of conflict." +msgstr "" + msgid "Compress" msgstr "" msgid "Compression mode" msgstr "" +msgid "Confidential inquiries via" +msgstr "" + msgid "Confirm Password" msgstr "" @@ -162,6 +352,19 @@ msgstr "" msgid "Confirming your email…" msgstr "" +msgid "" +"Conformance gate runs as CI workflow. No release without green veraPDF " +"against a worst-case source PDF." +msgstr "" + +msgid "" +"Conformance secured by veraPDF CI gate against a worst-case source PDF — " +"for beA attachments, citizen-application archiving, BSI TR-RESISCAN." +msgstr "" + +msgid "Contact:" +msgstr "" + msgid "Convert" msgstr "" @@ -171,12 +374,21 @@ msgstr "" msgid "Coordinated disclosure:" msgstr "" +msgid "Copy" +msgstr "" + +msgid "Copy this key now — it will not be shown again." +msgstr "" + msgid "Create Account" msgstr "" msgid "Create one" msgstr "" +msgid "Criterion" +msgstr "" + msgid "" "Custom volume, batch uploads up to 250 files, SLA, on-premise deployment," " dedicated support & contract. For DACH Behörden, hospitals, law firms " @@ -186,9 +398,24 @@ msgstr "" msgid "DOCX · PDF · TXT · MD · XLSX · CSV · JSON" msgstr "" +msgid "Dashboard" +msgstr "" + +msgid "Data Processing Agreement (DPA)" +msgstr "" + msgid "Dedicated onboarding" msgstr "" +msgid "Design Partner Programme" +msgstr "" + +msgid "Do I need the Enterprise tier for KRITIS?" +msgstr "" + +msgid "Do you also host if we can't operate ourselves?" +msgstr "" + msgid "Documented API endpoints and the web UI." msgstr "" @@ -204,9 +431,18 @@ msgstr "" msgid "E-mail support" msgstr "" +msgid "EU vendor with German imprint" +msgstr "" + +msgid "Early expiration of the right of withdrawal:" +msgstr "" + msgid "Email" msgstr "" +msgid "Engineering proof before contract" +msgstr "" + msgid "Enter your email to receive a reset link" msgstr "" @@ -219,6 +455,17 @@ msgstr "" msgid "Enterprise / Compliance" msgstr "" +msgid "" +"Every operation in a continuous hash chain. Tampering with an old row " +"breaks every following one." +msgstr "" + +msgid "" +"External ISO 27001 certification and external pen test are planned as " +"Year-2 roadmap items — both will be implemented as soon as the first " +"paying pilot economically justifies the effort." +msgstr "" + msgid "File Converter & Compressor" msgstr "" @@ -231,23 +478,79 @@ msgstr "" msgid "File conversion mode" msgstr "" +msgid "FileMorph Compliance Edition" +msgstr "" + +msgid "" +"FileMorph closes this gap: the open-source engine covers 16+ format pairs" +" and runs on your own Hetzner / on-premises / air-gap infrastructure. The" +" Compliance Edition additionally provides the contracts, SLAs and roadmap" +" guarantees that an EVB-IT-compliant procurement requires." +msgstr "" + +msgid "" +"FileMorph is a file conversion and compression service. The Community " +"Edition is provided free of charge, without warranty, and without SLA " +"commitments." +msgstr "" + +msgid "" +"FileMorph is open source software licensed under the GNU Affero General " +"Public License v3.0 (AGPLv3). The source code is available at" +msgstr "" + +msgid "" +"FileMorph is operated by Lennart Seidel, Reetwerder 25b, 21029 Hamburg, " +"Germany." +msgstr "" + +msgid "" +"FileMorph is stateless for conversions — there is nothing to export apart" +" from the audit log (Postgres, SQL-dumpable) and configuration (env " +"vars). Migration to a successor is a SQL-dump + container-image question," +" not a vendor lock-in." +msgstr "" + +msgid "FileMorph operates under German law (Hamburg)." +msgstr "" + +msgid "FileMorph sets" +msgstr "" + msgid "" "FileMorph — Free online file converter & compressor. Convert images, " -"documents, audio and video. Fast, private, no account required." +"documents, audio and video. Privacy-respecting, no account required." msgstr "" msgid "Files are processed server-side and deleted immediately after conversion." msgstr "" +msgid "" +"Files you upload for conversion or compression are processed entirely " +"server-side and deleted immediately after the converted output is " +"returned to you. No file content is stored, logged, or retained in any " +"form." +msgstr "" + msgid "Fix timeline:" msgstr "" msgid "For Developers" msgstr "" +msgid "" +"For a publicly accessible service integration, the AGPL publication " +"obligation applies. The commercial license lifts it — you can integrate " +"FileMorph into a citizen portal without disclosing your portal's source " +"code. Detail in" +msgstr "" + msgid "For issues in the open-source codebase itself, you may alternatively use" msgstr "" +msgid "For questions about these Terms, contact:" +msgstr "" + msgid "Forgot Password" msgstr "" @@ -257,7 +560,10 @@ msgstr "" msgid "Free" msgstr "" -msgid "Free forever — no credit card required" +msgid "Free accounts can be deleted from the API at" +msgstr "" + +msgid "Free tier forever — upgrade only when you need more" msgstr "" msgid "" @@ -265,6 +571,28 @@ msgid "" "go live once payment processing is fully set up." msgstr "" +msgid "Frequently asked questions" +msgstr "" + +msgid "" +"Full Compliance Edition. Onboarding together with the maintainer. " +"Priority bug hotfixes." +msgstr "" + +msgid "GDPR Art. 28 annex ↗" +msgstr "" + +msgid "" +"GDPR Art. 28-compliant DPA — drafted jointly in the pilot conversation " +"and adapted to your authority or clinic specifics." +msgstr "" + +msgid "GDPR DPA template in German form" +msgstr "" + +msgid "GDPR-aligned file engine for regulated administration." +msgstr "" + msgid "Get API Key →" msgstr "" @@ -284,23 +612,68 @@ msgid "" "hosted instance whenever possible." msgstr "" +msgid "Hetzner's privacy policy" +msgstr "" + +msgid "How does AGPLv3 behave with citizen-portal integrations?" +msgstr "" + +msgid "" +"I waive my 14-day right of withdrawal and consent to immediate contract " +"execution pursuant to §356 (5) BGB." +msgstr "" + msgid "If this email exists, you'll receive a reset link shortly." msgstr "" +msgid "" +"If you are a consumer (a natural person entering a contract for purposes " +"outside your trade, business or profession) and reside in the European " +"Union, you have the statutory right to withdraw from a paid subscription " +"within fourteen (14) days of contract conclusion — the date your first " +"Stripe payment is confirmed — without giving any reason." +msgstr "" + +msgid "" +"If you generate an API key (via the dashboard or command-line tool), only" +" the SHA-256 hash of your key is stored. The plaintext key is shown to " +"you exactly once at creation time and is never persisted on our servers." +msgstr "" + msgid "" "If you have discovered a security issue in FileMorph or in this " "deployment, please email" msgstr "" +msgid "" +"If you register an account, we store your email address, a bcrypt hash of" +" your password (never the plaintext), your subscription tier, your " +"account creation timestamp, and — once you upgrade to a paid tier — the " +"Stripe customer identifier that links your account to Stripe. Account " +"data is persisted in our PostgreSQL database for the lifetime of your " +"account and erased on deletion request (Art. 17 GDPR)." +msgstr "" + msgid "Images · Documents · Audio · Video · Spreadsheets" msgstr "" msgid "Impressum" msgstr "" +msgid "Imprint per German Telemediengesetz §5 (TMG)." +msgstr "" + msgid "In scope:" msgstr "" +msgid "Incident response plan" +msgstr "" + +msgid "" +"Infringe third-party intellectual property rights through the files you " +"process" +msgstr "" + msgid "Initial triage:" msgstr "" @@ -320,15 +693,45 @@ msgstr "" msgid "JPEG / WebP only." msgstr "" +msgid "" +"KRITIS and air-gap variants on request. All tiers include commercial " +"license, DPA template, signed Docker image and support SLA." +msgstr "" + msgid "Language" msgstr "" +msgid "Last updated: 2026-04-23 · Community + Cloud Edition" +msgstr "" + +msgid "Last updated: 2026-05-08 · Community + Cloud Edition" +msgstr "" + +msgid "" +"Lifts the AGPLv3 publication obligation for internal in-house " +"developments + public citizen-portal integrations." +msgstr "" + +msgid "Loading…" +msgstr "" + +msgid "" +"Logo mention as pilot customer (optional). Roadmap feedback every four " +"weeks. Willingness to prioritize feature tickets." +msgstr "" + msgid "MP4 · MOV · AVI · MKV · WebM" msgstr "" msgid "MP4 · MOV · AVI · MKV · WebM · MP3 · WAV · FLAC · OGG · M4A" msgstr "" +msgid "Member since" +msgstr "" + +msgid "Mermaid diagram and request lifecycle ↗" +msgstr "" + msgid "Min. 8 characters." msgstr "" @@ -341,6 +744,9 @@ msgstr "" msgid "Most popular" msgstr "" +msgid "Multi-format (image + audio + video + sheet)" +msgstr "" + msgid "New password" msgstr "" @@ -356,24 +762,71 @@ msgstr "" msgid "Open dashboard" msgstr "" +msgid "Operator staff with the" +msgstr "" + +msgid "Our pages load" +msgstr "" + msgid "Our response" msgstr "" +msgid "" +"Our web server automatically records standard access log data for each " +"request: IP address, request timestamp, HTTP method, URL path, response " +"status code, and response size. Application-level events (logins, " +"password-reset requests, subscription changes) are logged as structured " +"JSON without plaintext email addresses — only the email domain is kept " +"for debug purposes. Logs are rotated by the hosting infrastructure under " +"standard operational policies (typically up to 30 days) and accessed only" +" for security, abuse-detection, and debugging." +msgstr "" + msgid "Out of scope:" msgstr "" +msgid "PDF/A-2b output" +msgstr "" + +msgid "PDF/A-2b veraPDF-validated" +msgstr "" + msgid "Page not found" msgstr "" +msgid "" +"Paid plans (Pro €7/month, Business €19/month) are billed monthly via " +"Stripe and renew automatically until cancelled. You may cancel at any " +"time through the Stripe customer portal linked from your account " +"dashboard; cancellation takes effect at the end of the current billing " +"period and you retain access for the remainder of that period." +msgstr "" + msgid "Paid tiers — coming soon" msgstr "" msgid "Password" msgstr "" +msgid "" +"Password-reset and other account-related emails are delivered through " +"Zoho Mail (" +msgstr "" + +msgid "Patch policy" +msgstr "" + +msgid "" +"Payment processing is handled by Stripe Payments Europe Ltd.; Stripe's " +"terms apply to the processing of your payment details." +msgstr "" + msgid "Plans" msgstr "" +msgid "Price / year" +msgstr "" + msgid "Pricing" msgstr "" @@ -395,12 +848,49 @@ msgstr "" msgid "Processing…" msgstr "" +msgid "" +"Public authorities, hospitals and law firms often may not process citizen" +" and client data through public cloud conversion services — the GDPR data" +" chain and the EVB-IT contract framework set tight limits here. At the " +"same time, the typical IT department lacks the bandwidth to maintain a " +"conversion backend on its own." +msgstr "" + +msgid "" +"Public authority, clinic IT, law firm with a concrete GDPR conversion use" +" case. We filter for pilot readiness — not every applicant fits." +msgstr "" + +msgid "" +"Pursuant to § 356 (5) BGB, the right of withdrawal expires when we begin " +"executing the contract — i.e. when paid-tier API access becomes available" +" — provided you (a) expressly consented to this and (b) acknowledged that" +" you lose your right of withdrawal upon full performance. By ticking the " +"dedicated waiver checkbox on the pricing page before being redirected to " +"Stripe checkout, you give such consent. Without this acknowledgement, the" +" standard 14-day withdrawal protection applies. The Community Edition " +"(free of charge) is not subject to a right of withdrawal because no " +"contract for paid services is concluded." +msgstr "" + msgid "Quality" msgstr "" msgid "RFC 9116 · referenced from" msgstr "" +msgid "RFC 9116, with response times and scope" +msgstr "" + +msgid "Ready for a 15-minute pilot call?" +msgstr "" + +msgid "" +"Refunds are not issued for partial billing periods. In the event of a " +"documented service outage exceeding 24 hours within a single billing " +"period, you may request a discretionary credit by contacting:" +msgstr "" + msgid "Register" msgstr "" @@ -415,9 +905,37 @@ msgid "" "of-concept." msgstr "" +msgid "" +"Reproducible builds and air-gap update mechanism are also Year-2 " +"(required for the KRITIS variant, not critical in the standard tier)." +msgstr "" + +msgid "Request pilot call" +msgstr "" + +msgid "Request pilot call by email" +msgstr "" + msgid "Reset Password" msgstr "" +msgid "" +"Response-time targets by severity — critical 4 h, high 24 h, medium/low " +"in the next regular release. Targets apply Mon–Fri 09:00–18:00 CET, " +"excluding German public holidays." +msgstr "" + +msgid "SHA-256 audit log" +msgstr "" + +msgid "" +"SHA-256-chained operations log, ISO 27001 A.12.4.1 / BORA §50 / BeurkG " +"§39a." +msgstr "" + +msgid "STRIDE threat model" +msgstr "" + msgid "Safe-harbour" msgstr "" @@ -427,15 +945,30 @@ msgstr "" msgid "Scope" msgstr "" +msgid "Security Disclosure Policy" +msgstr "" + msgid "Security disclosure policy" msgstr "" +msgid "See" +msgstr "" + msgid "See all plans →" msgstr "" msgid "Select one or more files to convert or compress" msgstr "" +msgid "Self-hosted (data stays in-house)" +msgstr "" + +msgid "" +"Self-hosted behind your firewall. AGPLv3 + commercial license. EU vendor " +"with German imprint, individually drafted DPA template in pilot " +"conversation, and SBOM in every release." +msgstr "" + msgid "" "Self-hoster-specific deployment misconfiguration that is not caused by " "our defaults or documentation." @@ -444,6 +977,11 @@ msgstr "" msgid "Send Reset Link" msgstr "" +msgid "" +"Server-volume-based, not per user seat. Binding terms follow the personal" +" conversation." +msgstr "" + msgid "Set a new password" msgstr "" @@ -453,6 +991,12 @@ msgstr "" msgid "Sign in" msgstr "" +msgid "Signed image + SBOM" +msgstr "" + +msgid "Signed releases + SBOM" +msgstr "" + msgid "Simple, transparent pricing" msgstr "" @@ -462,12 +1006,39 @@ msgstr "" msgid "Something went wrong on our end. Please try again in a moment." msgstr "" +msgid "Source code" +msgstr "" + +msgid "" +"Standard tier is enough for most KRITIS requirements (self-hosting, audit" +" log, signed artefacts). Enterprise becomes relevant once air-gap update " +"mechanism, reproducible builds or dedicated support SLA are required. We " +"clarify this in 15 minutes by phone." +msgstr "" + msgid "Start free. Upgrade when you need more. No hidden fees." msgstr "" msgid "Steps to reproduce, including any required configuration or input files." msgstr "" +msgid "Stripe (payments):" +msgstr "" + +msgid "" +"Stripe may retain records of past transactions independently of our " +"deletion, to comply with its own legal and tax obligations." +msgstr "" + +msgid "Stripe's privacy policy" +msgstr "" + +msgid "Sub-processor list" +msgstr "" + +msgid "Support SLA" +msgstr "" + msgid "Supported: HEIC · JPG · PNG · WebP · BMP · TIFF · GIF" msgstr "" @@ -495,20 +1066,61 @@ msgid "" "release a patched version centrally." msgstr "" +msgid "" +"The Compliance Edition is self-hosted. If you can't operate your own " +"infrastructure, filemorph.io (Cloud Edition) is the right path — " +"different data class, different contracts, no EVB-IT anchor." +msgstr "" + msgid "The FileMorph application source code (this repository)." msgstr "" +msgid "" +"The Service is provided \"as is\" without warranty of any kind, express " +"or implied. We do not guarantee uptime, accuracy of conversion results, " +"or fitness for a particular purpose." +msgstr "" + +msgid "" +"The legal information below is provided in German as required by German " +"law." +msgstr "" + msgid "The official Docker images and release artifacts." msgstr "" msgid "The page you are looking for does not exist or has been moved." msgstr "" +msgid "" +"The table describes typical characteristics of the named provider " +"categories and is not a definitive comparison of specific products. " +"Individual providers may do more or less — please check the current offer" +" directly with the manufacturer." +msgstr "" + +msgid "" +"These Terms are governed by the laws of the Federal Republic of Germany. " +"Place of jurisdiction is Hamburg, Germany." +msgstr "" + +msgid "" +"These entries fall under the \"strictly necessary\" exemption of Art. " +"5(3) ePrivacy Directive / § 25 Abs. 2 Nr. 2 TTDSG and therefore do not " +"require a consent banner. For anonymous usage, nothing is stored in your " +"browser at all." +msgstr "" + msgid "" "Third-party services we depend on (Stripe, Zoho, Cloudflare, Hetzner) — " "please report to those vendors directly." msgstr "" +msgid "" +"This English translation is provided for accessibility. The German " +"version is the authoritative legal text in case of conflict." +msgstr "" + msgid "This link is missing a reset token. Request a new one from" msgstr "" @@ -517,12 +1129,52 @@ msgid "" "verification email from your dashboard." msgstr "" +msgid "" +"This service is hosted by Hetzner Online GmbH, Germany (Frankfurt data " +"centre). Your requests are routed through Cloudflare's network for DDoS " +"protection and performance. See" +msgstr "" + +msgid "" +"Three spots. Six months free. Direct influence on the Compliance Edition " +"roadmap." +msgstr "" + +msgid "Tier" +msgstr "" + +msgid "Tier overview" +msgstr "" + +msgid "To exercise the right of withdrawal, send an unambiguous statement to:" +msgstr "" + +msgid "" +"To operate FileMorph we rely on the following sub-processors. Each one " +"receives only the minimum data needed for its task:" +msgstr "" + +msgid "" +"To the extent permitted by applicable law, the operator of FileMorph " +"shall not be liable for any direct, indirect, incidental, or " +"consequential damages arising from your use of the Service." +msgstr "" + msgid "Toggle menu" msgstr "" +msgid "Trust basis before contract" +msgstr "" + msgid "Type it again" msgstr "" +msgid "Typical SaaS converters" +msgstr "" + +msgid "Typical open-source converters" +msgstr "" + msgid "Up to 100 MB per file" msgstr "" @@ -541,6 +1193,17 @@ msgstr "" msgid "Upgrade to Pro" msgstr "" +msgid "Upload files that contain malware, exploits, or illegal content" +msgstr "" + +msgid "" +"Use the Service for automated large-scale processing without prior " +"agreement" +msgstr "" + +msgid "Use these to authenticate programmatic API requests." +msgstr "" + msgid "Using anonymously: up to 20 MB per file." msgstr "" @@ -549,43 +1212,260 @@ msgid "" "10 requests/minute · no API access" msgstr "" +msgid "" +"We apply a temporary in-memory rate limit (max. 10 requests per minute " +"per IP address) to protect the service from abuse. IP addresses used by " +"the rate limiter are processed transiently in memory only and are never " +"written to disk or logs. Legal basis: Art. 6(1)(f) GDPR — legitimate " +"interest in service stability and security." +msgstr "" + +msgid "" +"We may update this policy when the service changes. Accounts and billing " +"are live as of April 2026; persistent file history (Cloud Edition Phase " +"2) is planned but not yet implemented. The date at the top indicates the " +"current version." +msgstr "" + +msgid "" +"We name it because an RFP reviewer would notice anyway — and because we " +"prefer to keep the roadmap transparent rather than embellished." +msgstr "" + msgid "Welcome back to FileMorph" msgstr "" +msgid "What does the Edition cost?" +msgstr "" + +msgid "What does the data export look like if we migrate?" +msgstr "" + +msgid "What happens if we cancel?" +msgstr "" + msgid "What to include in a report" msgstr "" +msgid "What we deliver compared to typical alternatives" +msgstr "" + +msgid "What we're transparent about" +msgstr "" + +msgid "What you get" +msgstr "" + +msgid "What you give" +msgstr "" + +msgid "What's in the Compliance Edition" +msgstr "" + +msgid "" +"When you request a password reset, we generate a single-use token (valid " +"for 30 minutes) and send it to your registered email address as a reset " +"link. The outgoing message is delivered from" +msgstr "" + +msgid "" +"When you start a paid-tier upgrade, you are redirected to Stripe Checkout" +" on the" +msgstr "" + +msgid "" +"When you upgrade to a paid tier, we create a Stripe customer record " +"containing your email address and an internal user identifier, then " +"redirect you to" +msgstr "" + msgid "Whether the issue has been disclosed publicly elsewhere." msgstr "" +msgid "Who's a fit" +msgstr "" + +msgid "Why a Compliance Edition?" +msgstr "" + +msgid "" +"You also have the right to lodge a complaint with your local data " +"protection authority." +msgstr "" + +msgid "" +"You can fully audit FileMorph before the first conversation. All relevant" +" security and architecture documents are freely accessible:" +msgstr "" + +msgid "" +"You have the right to access, rectify, erase, and restrict processing of " +"your personal data (Art. 15–21 GDPR). To exercise these rights, contact " +"us at" +msgstr "" + +msgid "" +"You keep the code (AGPLv3 stays). You lose the commercial license, the " +"updated DPA, new releases with compliance features, and the support SLA. " +"Existing installations continue running — no lock-in via forced updates." +msgstr "" + +msgid "You may not use the Service to:" +msgstr "" + +msgid "" +"You're evaluating conversion software for a public authority, hospital or" +" law firm? Write to us with your use case — we respond within one " +"business day." +msgstr "" + msgid "Your email is now verified." msgstr "" msgid "Your password has been updated." msgstr "" +msgid "Zoho Mail (transactional email):" +msgstr "" + +msgid "Zoho's privacy policy" +msgstr "" + +msgid "" +"after a three-field re-confirmation (your password, your email, and the " +"literal word" +msgstr "" + +msgid "and" +msgstr "" + +msgid "are encrypted with the same key." +msgstr "" + +msgid "" +"cosign keyless OIDC, cryptographically signed git tags, CycloneDX-JSON " +"SBOM in every GitHub release." +msgstr "" + +msgid "" +"cosign-signed Docker image, cryptographically signed git tags, CycloneDX-" +"JSON SBOM in every release. Aligned with the EVB-IT cloud clause (March " +"2026)." +msgstr "" + msgid "" "critical issues within 7 days, high severity within 30 days, medium/low " "within the next regular release." msgstr "" +msgid "" +"domain, which sets its own cookies. That is outside FileMorph's control " +"and is governed by" +msgstr "" + +msgid "escalation, post-mortem template ↗" +msgstr "" + +msgid "for full contact details." +msgstr "" + +msgid "for their data processing terms." +msgstr "" + +msgid "from € 24,900" +msgstr "" + +msgid "full GitHub repository ↗" +msgstr "" + msgid "hint. Large batches are processed sequentially inside the request." msgstr "" msgid "min 0.05 MB" msgstr "" +msgid "no cookies" +msgstr "" + +msgid "no external resources" +msgstr "" + +msgid "not applicable" +msgstr "" + +msgid "often limited to one area" +msgstr "" + +msgid "often ✓" +msgstr "" + +msgid "" +"on its own domain and runs no tracking or analytics scripts. A small " +"number of keys are written to your browser's" +msgstr "" + +msgid "only while you are signed in:" +msgstr "" + +msgid "" +"optional; remembers the API key shown in your dashboard across reloads so" +" you don't need to paste it again. Cleared on logout." +msgstr "" + +msgid "or apply directly as design partner →" +msgstr "" + msgid "or click to browse (multi-file supported)" msgstr "" msgid "per request" msgstr "" +msgid "rare" +msgstr "" + +msgid "" +"role can access an internal cockpit that lists registered email addresses" +" in plaintext, along with subscription tier, account creation date, and " +"Stripe subscription status — strictly for service operation, abuse " +"response, and support. Admin actions (tier changes, role changes, " +"deactivations) are recorded with the admin's user identifier, the target " +"user's identifier, and the change performed, to enable internal auditing." +" Legal basis: Art. 6(1)(f) GDPR." +msgstr "" + +msgid "threat-mitigation anchors per category ↗" +msgstr "" + +msgid "" +"to complete payment. Stripe handles all card details directly — FileMorph" +" never sees or stores your card data. After checkout, Stripe returns a " +"customer identifier which we store to manage your subscription. Stripe is" +" a US-based company; the transfer is covered by the EU Standard " +"Contractual Clauses under Stripe's Data Processing Agreement. Legal " +"basis: Art. 6(1)(b) GDPR. See" +msgstr "" + +msgid "unlimited servers, dedicated onboarding, custom SLA" +msgstr "" + +msgid "varies" +msgstr "" + +msgid "versioning, CVSS bands, signed artefacts ↗" +msgstr "" + +msgid "via our email provider (see § 3a). We do not send marketing emails." +msgstr "" + msgid "" "we publish an advisory once a fixed release is available, and credit " "reporters who wish to be named." msgstr "" +msgid "when publication obligation applies, when not ↗" +msgstr "" + msgid "with a" msgstr "" @@ -601,6 +1481,9 @@ msgstr "" msgid "within 72 hours of receipt." msgstr "" +msgid "your JWT session tokens; strictly necessary to keep you signed in." +msgstr "" + msgid "© 2026 FileMorph — AGPLv3 Open Source" msgstr "" @@ -613,3 +1496,13 @@ msgstr "" msgid "← Back" msgstr "" +#~ msgid "" +#~ "FileMorph — Free online file converter" +#~ " & compressor. Convert images, documents," +#~ " audio and video. Fast, private, no" +#~ " account required." +#~ msgstr "" + +#~ msgid "Free forever — no credit card required" +#~ msgstr "" + diff --git a/locale/messages.pot b/locale/messages.pot index 8832bf3..5d88063 100644 --- a/locale/messages.pot +++ b/locale/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: FileMorph VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2026-05-08 15:52+0200\n" +"POT-Creation-Date: 2026-05-08 15:18+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,9 +17,25 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.18.0\n" +msgid "" +" — for example: \"I hereby withdraw from the contract concluded on [date]" +" for the FileMorph [Pro / Business] subscription.\" Including your " +"registered email address speeds up identification of your account." +msgstr "" + msgid "(vs. 20 MB anonymous)" msgstr "" +msgid "" +"). The cascade removes your login credentials and API keys; conversion-" +"job and usage-record entries are anonymised (your account ID is nulled, " +"the rows are kept as anonymous aggregate data under DSGVO Art. 4(1)). A " +"confirmation email is sent after the row is gone." +msgstr "" + +msgid "+ New Key" +msgstr "" + msgid ", 1 concurrent, 10 req/min" msgstr "" @@ -29,12 +45,30 @@ msgstr "" msgid ", 5 concurrent, 10 req/min" msgstr "" +msgid "" +", hosted in Frankfurt, EU). Zoho receives the recipient address and the " +"email contents (including the reset link). Legal basis: Art. 6(1)(b) " +"GDPR. See" +msgstr "" + msgid "/mo" msgstr "" +msgid "1 server, ≤ 50 employees" +msgstr "" + +msgid "1. Acceptance" +msgstr "" + +msgid "1. Who is responsible?" +msgstr "" + msgid "10,000 API calls / month" msgstr "" +msgid "10. Contact" +msgstr "" + msgid "100 MB · 10k API" msgstr "" @@ -44,21 +78,66 @@ msgstr "" msgid "100,000 API calls / month" msgstr "" +msgid "2. Description of Service" +msgstr "" + +msgid "2. What data we process" +msgstr "" + msgid "25 files" msgstr "" +msgid "2a. Uploaded files:" +msgstr "" + +msgid "2b. User accounts (Cloud Edition):" +msgstr "" + +msgid "2c. Transactional emails:" +msgstr "" + +msgid "2d. Server logs:" +msgstr "" + +msgid "2e. API keys:" +msgstr "" + +msgid "3 servers, ≤ 2,000 employees" +msgstr "" + +msgid "3. Acceptable Use" +msgstr "" + +msgid "3. Legal basis (GDPR Art. 6)" +msgstr "" + msgid "30+ formats (images, docs, audio, video)" msgstr "" msgid "30+ formats incl. video" msgstr "" +msgid "3a. External services (Sub-Processors)" +msgstr "" + +msgid "4. Disclaimer of Warranties" +msgstr "" + +msgid "4. Hosting" +msgstr "" + msgid "404 – Not Found" msgstr "" msgid "5 files" msgstr "" +msgid "5. Limitation of Liability" +msgstr "" + +msgid "5. Your rights (GDPR)" +msgstr "" + msgid "50 MB · API key" msgstr "" @@ -71,36 +150,108 @@ msgstr "" msgid "500 – Server Error" msgstr "" +msgid "6. No cookies, no tracking" +msgstr "" + +msgid "6. Open Source License" +msgstr "" + +msgid "7. Governing Law" +msgstr "" + +msgid "7. Rate limiting & abuse prevention" +msgstr "" + +msgid "8. Changes to this policy" +msgstr "" + +msgid "8. Subscriptions (Cloud Edition)" +msgstr "" + +msgid "9. Admin access (transparency)" +msgstr "" + +msgid "9. Right of Withdrawal (Consumers)" +msgstr "" + msgid "A description of the vulnerability and its potential impact." msgstr "" +msgid "AGPLv3 for public authorities" +msgstr "" + msgid "API Docs" msgstr "" msgid "API Docs ↗" msgstr "" +msgid "API Keys" +msgstr "" + msgid "API key management" msgstr "" msgid "API key — " msgstr "" +msgid "" +"Account creation, paid subscriptions, and transactional emails are " +"processed on the basis of Art. 6(1)(b) GDPR (performance of a contract). " +"Server-log processing, rate-limiting, and abuse prevention are based on " +"our legitimate interest (Art. 6(1)(f) GDPR) in operating a secure and " +"reliable service." +msgstr "" + +msgid "Account deletion:" +msgstr "" + +msgid "" +"Accounts that have ever been linked to Stripe cannot use the self-service" +" path yet — German commercial law (HGB §257, AO §147) requires a 10-year " +"retention of tax-relevant records under Art. 17(3)(b) GDPR. For these " +"accounts, contact" +msgstr "" + msgid "Acknowledgement:" msgstr "" msgid "Affected version (commit hash or release tag if known)." msgstr "" +msgid "" +"All CSS (including Tailwind), JavaScript, fonts, and images are served " +"from the FileMorph domain; your browser never contacts a third-party CDN " +"to render the site." +msgstr "" + msgid "All prices excl. VAT where applicable. Payments processed by Stripe." msgstr "" msgid "Already have an account?" msgstr "" +msgid "" +"An orientation about the provider categories common in DACH RFPs. In " +"individual cases, a specific product may do more — please check " +"individually." +msgstr "" + +msgid "Apply as design partner" +msgstr "" + +msgid "Architecture overview" +msgstr "" + msgid "At least 8 characters" msgstr "" +msgid "Attempt to circumvent rate limits or security controls" +msgstr "" + +msgid "Audit log with hash chain" +msgstr "" + msgid "Back to Home" msgstr "" @@ -128,24 +279,63 @@ msgstr "" msgid "By target size" msgstr "" +msgid "" +"By using FileMorph (the \"Service\"), you agree to these Terms of Use. If" +" you do not agree, do not use the Service." +msgstr "" + msgid "Choose a password you haven't used before" msgstr "" msgid "Clear all" msgstr "" +msgid "Cloudflare's privacy policy" +msgstr "" + msgid "Coming soon" msgstr "" +msgid "Commercial license" +msgstr "" + +msgid "Commercial license on AGPL code" +msgstr "" + +msgid "Compliance" +msgstr "" + +msgid "Compliance Edition" +msgstr "" + msgid "Compliance Edition →" msgstr "" +msgid "Compliance Enterprise" +msgstr "" + +msgid "Compliance Standard" +msgstr "" + +msgid "Compliance Starter" +msgstr "" + +msgid "" +"Compliance assertions on this page cite German statutes (HGB §257, AO " +"§147, DSGVO Art 17). This English translation is provided for " +"accessibility — the German version is the authoritative legal text in " +"case of conflict." +msgstr "" + msgid "Compress" msgstr "" msgid "Compression mode" msgstr "" +msgid "Confidential inquiries via" +msgstr "" + msgid "Confirm Password" msgstr "" @@ -161,6 +351,19 @@ msgstr "" msgid "Confirming your email…" msgstr "" +msgid "" +"Conformance gate runs as CI workflow. No release without green veraPDF " +"against a worst-case source PDF." +msgstr "" + +msgid "" +"Conformance secured by veraPDF CI gate against a worst-case source PDF — " +"for beA attachments, citizen-application archiving, BSI TR-RESISCAN." +msgstr "" + +msgid "Contact:" +msgstr "" + msgid "Convert" msgstr "" @@ -170,12 +373,21 @@ msgstr "" msgid "Coordinated disclosure:" msgstr "" +msgid "Copy" +msgstr "" + +msgid "Copy this key now — it will not be shown again." +msgstr "" + msgid "Create Account" msgstr "" msgid "Create one" msgstr "" +msgid "Criterion" +msgstr "" + msgid "" "Custom volume, batch uploads up to 250 files, SLA, on-premise deployment," " dedicated support & contract. For DACH Behörden, hospitals, law firms " @@ -185,9 +397,24 @@ msgstr "" msgid "DOCX · PDF · TXT · MD · XLSX · CSV · JSON" msgstr "" +msgid "Dashboard" +msgstr "" + +msgid "Data Processing Agreement (DPA)" +msgstr "" + msgid "Dedicated onboarding" msgstr "" +msgid "Design Partner Programme" +msgstr "" + +msgid "Do I need the Enterprise tier for KRITIS?" +msgstr "" + +msgid "Do you also host if we can't operate ourselves?" +msgstr "" + msgid "Documented API endpoints and the web UI." msgstr "" @@ -203,9 +430,18 @@ msgstr "" msgid "E-mail support" msgstr "" +msgid "EU vendor with German imprint" +msgstr "" + +msgid "Early expiration of the right of withdrawal:" +msgstr "" + msgid "Email" msgstr "" +msgid "Engineering proof before contract" +msgstr "" + msgid "Enter your email to receive a reset link" msgstr "" @@ -218,6 +454,17 @@ msgstr "" msgid "Enterprise / Compliance" msgstr "" +msgid "" +"Every operation in a continuous hash chain. Tampering with an old row " +"breaks every following one." +msgstr "" + +msgid "" +"External ISO 27001 certification and external pen test are planned as " +"Year-2 roadmap items — both will be implemented as soon as the first " +"paying pilot economically justifies the effort." +msgstr "" + msgid "File Converter & Compressor" msgstr "" @@ -230,23 +477,79 @@ msgstr "" msgid "File conversion mode" msgstr "" +msgid "FileMorph Compliance Edition" +msgstr "" + +msgid "" +"FileMorph closes this gap: the open-source engine covers 16+ format pairs" +" and runs on your own Hetzner / on-premises / air-gap infrastructure. The" +" Compliance Edition additionally provides the contracts, SLAs and roadmap" +" guarantees that an EVB-IT-compliant procurement requires." +msgstr "" + +msgid "" +"FileMorph is a file conversion and compression service. The Community " +"Edition is provided free of charge, without warranty, and without SLA " +"commitments." +msgstr "" + +msgid "" +"FileMorph is open source software licensed under the GNU Affero General " +"Public License v3.0 (AGPLv3). The source code is available at" +msgstr "" + +msgid "" +"FileMorph is operated by Lennart Seidel, Reetwerder 25b, 21029 Hamburg, " +"Germany." +msgstr "" + +msgid "" +"FileMorph is stateless for conversions — there is nothing to export apart" +" from the audit log (Postgres, SQL-dumpable) and configuration (env " +"vars). Migration to a successor is a SQL-dump + container-image question," +" not a vendor lock-in." +msgstr "" + +msgid "FileMorph operates under German law (Hamburg)." +msgstr "" + +msgid "FileMorph sets" +msgstr "" + msgid "" "FileMorph — Free online file converter & compressor. Convert images, " -"documents, audio and video. Fast, private, no account required." +"documents, audio and video. Privacy-respecting, no account required." msgstr "" msgid "Files are processed server-side and deleted immediately after conversion." msgstr "" +msgid "" +"Files you upload for conversion or compression are processed entirely " +"server-side and deleted immediately after the converted output is " +"returned to you. No file content is stored, logged, or retained in any " +"form." +msgstr "" + msgid "Fix timeline:" msgstr "" msgid "For Developers" msgstr "" +msgid "" +"For a publicly accessible service integration, the AGPL publication " +"obligation applies. The commercial license lifts it — you can integrate " +"FileMorph into a citizen portal without disclosing your portal's source " +"code. Detail in" +msgstr "" + msgid "For issues in the open-source codebase itself, you may alternatively use" msgstr "" +msgid "For questions about these Terms, contact:" +msgstr "" + msgid "Forgot Password" msgstr "" @@ -256,7 +559,10 @@ msgstr "" msgid "Free" msgstr "" -msgid "Free forever — no credit card required" +msgid "Free accounts can be deleted from the API at" +msgstr "" + +msgid "Free tier forever — upgrade only when you need more" msgstr "" msgid "" @@ -264,6 +570,28 @@ msgid "" "go live once payment processing is fully set up." msgstr "" +msgid "Frequently asked questions" +msgstr "" + +msgid "" +"Full Compliance Edition. Onboarding together with the maintainer. " +"Priority bug hotfixes." +msgstr "" + +msgid "GDPR Art. 28 annex ↗" +msgstr "" + +msgid "" +"GDPR Art. 28-compliant DPA — drafted jointly in the pilot conversation " +"and adapted to your authority or clinic specifics." +msgstr "" + +msgid "GDPR DPA template in German form" +msgstr "" + +msgid "GDPR-aligned file engine for regulated administration." +msgstr "" + msgid "Get API Key →" msgstr "" @@ -283,23 +611,68 @@ msgid "" "hosted instance whenever possible." msgstr "" +msgid "Hetzner's privacy policy" +msgstr "" + +msgid "How does AGPLv3 behave with citizen-portal integrations?" +msgstr "" + +msgid "" +"I waive my 14-day right of withdrawal and consent to immediate contract " +"execution pursuant to §356 (5) BGB." +msgstr "" + msgid "If this email exists, you'll receive a reset link shortly." msgstr "" +msgid "" +"If you are a consumer (a natural person entering a contract for purposes " +"outside your trade, business or profession) and reside in the European " +"Union, you have the statutory right to withdraw from a paid subscription " +"within fourteen (14) days of contract conclusion — the date your first " +"Stripe payment is confirmed — without giving any reason." +msgstr "" + +msgid "" +"If you generate an API key (via the dashboard or command-line tool), only" +" the SHA-256 hash of your key is stored. The plaintext key is shown to " +"you exactly once at creation time and is never persisted on our servers." +msgstr "" + msgid "" "If you have discovered a security issue in FileMorph or in this " "deployment, please email" msgstr "" +msgid "" +"If you register an account, we store your email address, a bcrypt hash of" +" your password (never the plaintext), your subscription tier, your " +"account creation timestamp, and — once you upgrade to a paid tier — the " +"Stripe customer identifier that links your account to Stripe. Account " +"data is persisted in our PostgreSQL database for the lifetime of your " +"account and erased on deletion request (Art. 17 GDPR)." +msgstr "" + msgid "Images · Documents · Audio · Video · Spreadsheets" msgstr "" msgid "Impressum" msgstr "" +msgid "Imprint per German Telemediengesetz §5 (TMG)." +msgstr "" + msgid "In scope:" msgstr "" +msgid "Incident response plan" +msgstr "" + +msgid "" +"Infringe third-party intellectual property rights through the files you " +"process" +msgstr "" + msgid "Initial triage:" msgstr "" @@ -319,15 +692,45 @@ msgstr "" msgid "JPEG / WebP only." msgstr "" +msgid "" +"KRITIS and air-gap variants on request. All tiers include commercial " +"license, DPA template, signed Docker image and support SLA." +msgstr "" + msgid "Language" msgstr "" +msgid "Last updated: 2026-04-23 · Community + Cloud Edition" +msgstr "" + +msgid "Last updated: 2026-05-08 · Community + Cloud Edition" +msgstr "" + +msgid "" +"Lifts the AGPLv3 publication obligation for internal in-house " +"developments + public citizen-portal integrations." +msgstr "" + +msgid "Loading…" +msgstr "" + +msgid "" +"Logo mention as pilot customer (optional). Roadmap feedback every four " +"weeks. Willingness to prioritize feature tickets." +msgstr "" + msgid "MP4 · MOV · AVI · MKV · WebM" msgstr "" msgid "MP4 · MOV · AVI · MKV · WebM · MP3 · WAV · FLAC · OGG · M4A" msgstr "" +msgid "Member since" +msgstr "" + +msgid "Mermaid diagram and request lifecycle ↗" +msgstr "" + msgid "Min. 8 characters." msgstr "" @@ -340,6 +743,9 @@ msgstr "" msgid "Most popular" msgstr "" +msgid "Multi-format (image + audio + video + sheet)" +msgstr "" + msgid "New password" msgstr "" @@ -355,24 +761,71 @@ msgstr "" msgid "Open dashboard" msgstr "" +msgid "Operator staff with the" +msgstr "" + +msgid "Our pages load" +msgstr "" + msgid "Our response" msgstr "" +msgid "" +"Our web server automatically records standard access log data for each " +"request: IP address, request timestamp, HTTP method, URL path, response " +"status code, and response size. Application-level events (logins, " +"password-reset requests, subscription changes) are logged as structured " +"JSON without plaintext email addresses — only the email domain is kept " +"for debug purposes. Logs are rotated by the hosting infrastructure under " +"standard operational policies (typically up to 30 days) and accessed only" +" for security, abuse-detection, and debugging." +msgstr "" + msgid "Out of scope:" msgstr "" +msgid "PDF/A-2b output" +msgstr "" + +msgid "PDF/A-2b veraPDF-validated" +msgstr "" + msgid "Page not found" msgstr "" +msgid "" +"Paid plans (Pro €7/month, Business €19/month) are billed monthly via " +"Stripe and renew automatically until cancelled. You may cancel at any " +"time through the Stripe customer portal linked from your account " +"dashboard; cancellation takes effect at the end of the current billing " +"period and you retain access for the remainder of that period." +msgstr "" + msgid "Paid tiers — coming soon" msgstr "" msgid "Password" msgstr "" +msgid "" +"Password-reset and other account-related emails are delivered through " +"Zoho Mail (" +msgstr "" + +msgid "Patch policy" +msgstr "" + +msgid "" +"Payment processing is handled by Stripe Payments Europe Ltd.; Stripe's " +"terms apply to the processing of your payment details." +msgstr "" + msgid "Plans" msgstr "" +msgid "Price / year" +msgstr "" + msgid "Pricing" msgstr "" @@ -394,12 +847,49 @@ msgstr "" msgid "Processing…" msgstr "" +msgid "" +"Public authorities, hospitals and law firms often may not process citizen" +" and client data through public cloud conversion services — the GDPR data" +" chain and the EVB-IT contract framework set tight limits here. At the " +"same time, the typical IT department lacks the bandwidth to maintain a " +"conversion backend on its own." +msgstr "" + +msgid "" +"Public authority, clinic IT, law firm with a concrete GDPR conversion use" +" case. We filter for pilot readiness — not every applicant fits." +msgstr "" + +msgid "" +"Pursuant to § 356 (5) BGB, the right of withdrawal expires when we begin " +"executing the contract — i.e. when paid-tier API access becomes available" +" — provided you (a) expressly consented to this and (b) acknowledged that" +" you lose your right of withdrawal upon full performance. By ticking the " +"dedicated waiver checkbox on the pricing page before being redirected to " +"Stripe checkout, you give such consent. Without this acknowledgement, the" +" standard 14-day withdrawal protection applies. The Community Edition " +"(free of charge) is not subject to a right of withdrawal because no " +"contract for paid services is concluded." +msgstr "" + msgid "Quality" msgstr "" msgid "RFC 9116 · referenced from" msgstr "" +msgid "RFC 9116, with response times and scope" +msgstr "" + +msgid "Ready for a 15-minute pilot call?" +msgstr "" + +msgid "" +"Refunds are not issued for partial billing periods. In the event of a " +"documented service outage exceeding 24 hours within a single billing " +"period, you may request a discretionary credit by contacting:" +msgstr "" + msgid "Register" msgstr "" @@ -414,9 +904,37 @@ msgid "" "of-concept." msgstr "" +msgid "" +"Reproducible builds and air-gap update mechanism are also Year-2 " +"(required for the KRITIS variant, not critical in the standard tier)." +msgstr "" + +msgid "Request pilot call" +msgstr "" + +msgid "Request pilot call by email" +msgstr "" + msgid "Reset Password" msgstr "" +msgid "" +"Response-time targets by severity — critical 4 h, high 24 h, medium/low " +"in the next regular release. Targets apply Mon–Fri 09:00–18:00 CET, " +"excluding German public holidays." +msgstr "" + +msgid "SHA-256 audit log" +msgstr "" + +msgid "" +"SHA-256-chained operations log, ISO 27001 A.12.4.1 / BORA §50 / BeurkG " +"§39a." +msgstr "" + +msgid "STRIDE threat model" +msgstr "" + msgid "Safe-harbour" msgstr "" @@ -426,15 +944,30 @@ msgstr "" msgid "Scope" msgstr "" +msgid "Security Disclosure Policy" +msgstr "" + msgid "Security disclosure policy" msgstr "" +msgid "See" +msgstr "" + msgid "See all plans →" msgstr "" msgid "Select one or more files to convert or compress" msgstr "" +msgid "Self-hosted (data stays in-house)" +msgstr "" + +msgid "" +"Self-hosted behind your firewall. AGPLv3 + commercial license. EU vendor " +"with German imprint, individually drafted DPA template in pilot " +"conversation, and SBOM in every release." +msgstr "" + msgid "" "Self-hoster-specific deployment misconfiguration that is not caused by " "our defaults or documentation." @@ -443,6 +976,11 @@ msgstr "" msgid "Send Reset Link" msgstr "" +msgid "" +"Server-volume-based, not per user seat. Binding terms follow the personal" +" conversation." +msgstr "" + msgid "Set a new password" msgstr "" @@ -452,6 +990,12 @@ msgstr "" msgid "Sign in" msgstr "" +msgid "Signed image + SBOM" +msgstr "" + +msgid "Signed releases + SBOM" +msgstr "" + msgid "Simple, transparent pricing" msgstr "" @@ -461,12 +1005,39 @@ msgstr "" msgid "Something went wrong on our end. Please try again in a moment." msgstr "" +msgid "Source code" +msgstr "" + +msgid "" +"Standard tier is enough for most KRITIS requirements (self-hosting, audit" +" log, signed artefacts). Enterprise becomes relevant once air-gap update " +"mechanism, reproducible builds or dedicated support SLA are required. We " +"clarify this in 15 minutes by phone." +msgstr "" + msgid "Start free. Upgrade when you need more. No hidden fees." msgstr "" msgid "Steps to reproduce, including any required configuration or input files." msgstr "" +msgid "Stripe (payments):" +msgstr "" + +msgid "" +"Stripe may retain records of past transactions independently of our " +"deletion, to comply with its own legal and tax obligations." +msgstr "" + +msgid "Stripe's privacy policy" +msgstr "" + +msgid "Sub-processor list" +msgstr "" + +msgid "Support SLA" +msgstr "" + msgid "Supported: HEIC · JPG · PNG · WebP · BMP · TIFF · GIF" msgstr "" @@ -494,20 +1065,61 @@ msgid "" "release a patched version centrally." msgstr "" +msgid "" +"The Compliance Edition is self-hosted. If you can't operate your own " +"infrastructure, filemorph.io (Cloud Edition) is the right path — " +"different data class, different contracts, no EVB-IT anchor." +msgstr "" + msgid "The FileMorph application source code (this repository)." msgstr "" +msgid "" +"The Service is provided \"as is\" without warranty of any kind, express " +"or implied. We do not guarantee uptime, accuracy of conversion results, " +"or fitness for a particular purpose." +msgstr "" + +msgid "" +"The legal information below is provided in German as required by German " +"law." +msgstr "" + msgid "The official Docker images and release artifacts." msgstr "" msgid "The page you are looking for does not exist or has been moved." msgstr "" +msgid "" +"The table describes typical characteristics of the named provider " +"categories and is not a definitive comparison of specific products. " +"Individual providers may do more or less — please check the current offer" +" directly with the manufacturer." +msgstr "" + +msgid "" +"These Terms are governed by the laws of the Federal Republic of Germany. " +"Place of jurisdiction is Hamburg, Germany." +msgstr "" + +msgid "" +"These entries fall under the \"strictly necessary\" exemption of Art. " +"5(3) ePrivacy Directive / § 25 Abs. 2 Nr. 2 TTDSG and therefore do not " +"require a consent banner. For anonymous usage, nothing is stored in your " +"browser at all." +msgstr "" + msgid "" "Third-party services we depend on (Stripe, Zoho, Cloudflare, Hetzner) — " "please report to those vendors directly." msgstr "" +msgid "" +"This English translation is provided for accessibility. The German " +"version is the authoritative legal text in case of conflict." +msgstr "" + msgid "This link is missing a reset token. Request a new one from" msgstr "" @@ -516,12 +1128,52 @@ msgid "" "verification email from your dashboard." msgstr "" +msgid "" +"This service is hosted by Hetzner Online GmbH, Germany (Frankfurt data " +"centre). Your requests are routed through Cloudflare's network for DDoS " +"protection and performance. See" +msgstr "" + +msgid "" +"Three spots. Six months free. Direct influence on the Compliance Edition " +"roadmap." +msgstr "" + +msgid "Tier" +msgstr "" + +msgid "Tier overview" +msgstr "" + +msgid "To exercise the right of withdrawal, send an unambiguous statement to:" +msgstr "" + +msgid "" +"To operate FileMorph we rely on the following sub-processors. Each one " +"receives only the minimum data needed for its task:" +msgstr "" + +msgid "" +"To the extent permitted by applicable law, the operator of FileMorph " +"shall not be liable for any direct, indirect, incidental, or " +"consequential damages arising from your use of the Service." +msgstr "" + msgid "Toggle menu" msgstr "" +msgid "Trust basis before contract" +msgstr "" + msgid "Type it again" msgstr "" +msgid "Typical SaaS converters" +msgstr "" + +msgid "Typical open-source converters" +msgstr "" + msgid "Up to 100 MB per file" msgstr "" @@ -540,6 +1192,17 @@ msgstr "" msgid "Upgrade to Pro" msgstr "" +msgid "Upload files that contain malware, exploits, or illegal content" +msgstr "" + +msgid "" +"Use the Service for automated large-scale processing without prior " +"agreement" +msgstr "" + +msgid "Use these to authenticate programmatic API requests." +msgstr "" + msgid "Using anonymously: up to 20 MB per file." msgstr "" @@ -548,43 +1211,260 @@ msgid "" "10 requests/minute · no API access" msgstr "" +msgid "" +"We apply a temporary in-memory rate limit (max. 10 requests per minute " +"per IP address) to protect the service from abuse. IP addresses used by " +"the rate limiter are processed transiently in memory only and are never " +"written to disk or logs. Legal basis: Art. 6(1)(f) GDPR — legitimate " +"interest in service stability and security." +msgstr "" + +msgid "" +"We may update this policy when the service changes. Accounts and billing " +"are live as of April 2026; persistent file history (Cloud Edition Phase " +"2) is planned but not yet implemented. The date at the top indicates the " +"current version." +msgstr "" + +msgid "" +"We name it because an RFP reviewer would notice anyway — and because we " +"prefer to keep the roadmap transparent rather than embellished." +msgstr "" + msgid "Welcome back to FileMorph" msgstr "" +msgid "What does the Edition cost?" +msgstr "" + +msgid "What does the data export look like if we migrate?" +msgstr "" + +msgid "What happens if we cancel?" +msgstr "" + msgid "What to include in a report" msgstr "" +msgid "What we deliver compared to typical alternatives" +msgstr "" + +msgid "What we're transparent about" +msgstr "" + +msgid "What you get" +msgstr "" + +msgid "What you give" +msgstr "" + +msgid "What's in the Compliance Edition" +msgstr "" + +msgid "" +"When you request a password reset, we generate a single-use token (valid " +"for 30 minutes) and send it to your registered email address as a reset " +"link. The outgoing message is delivered from" +msgstr "" + +msgid "" +"When you start a paid-tier upgrade, you are redirected to Stripe Checkout" +" on the" +msgstr "" + +msgid "" +"When you upgrade to a paid tier, we create a Stripe customer record " +"containing your email address and an internal user identifier, then " +"redirect you to" +msgstr "" + msgid "Whether the issue has been disclosed publicly elsewhere." msgstr "" +msgid "Who's a fit" +msgstr "" + +msgid "Why a Compliance Edition?" +msgstr "" + +msgid "" +"You also have the right to lodge a complaint with your local data " +"protection authority." +msgstr "" + +msgid "" +"You can fully audit FileMorph before the first conversation. All relevant" +" security and architecture documents are freely accessible:" +msgstr "" + +msgid "" +"You have the right to access, rectify, erase, and restrict processing of " +"your personal data (Art. 15–21 GDPR). To exercise these rights, contact " +"us at" +msgstr "" + +msgid "" +"You keep the code (AGPLv3 stays). You lose the commercial license, the " +"updated DPA, new releases with compliance features, and the support SLA. " +"Existing installations continue running — no lock-in via forced updates." +msgstr "" + +msgid "You may not use the Service to:" +msgstr "" + +msgid "" +"You're evaluating conversion software for a public authority, hospital or" +" law firm? Write to us with your use case — we respond within one " +"business day." +msgstr "" + msgid "Your email is now verified." msgstr "" msgid "Your password has been updated." msgstr "" +msgid "Zoho Mail (transactional email):" +msgstr "" + +msgid "Zoho's privacy policy" +msgstr "" + +msgid "" +"after a three-field re-confirmation (your password, your email, and the " +"literal word" +msgstr "" + +msgid "and" +msgstr "" + +msgid "are encrypted with the same key." +msgstr "" + +msgid "" +"cosign keyless OIDC, cryptographically signed git tags, CycloneDX-JSON " +"SBOM in every GitHub release." +msgstr "" + +msgid "" +"cosign-signed Docker image, cryptographically signed git tags, CycloneDX-" +"JSON SBOM in every release. Aligned with the EVB-IT cloud clause (March " +"2026)." +msgstr "" + msgid "" "critical issues within 7 days, high severity within 30 days, medium/low " "within the next regular release." msgstr "" +msgid "" +"domain, which sets its own cookies. That is outside FileMorph's control " +"and is governed by" +msgstr "" + +msgid "escalation, post-mortem template ↗" +msgstr "" + +msgid "for full contact details." +msgstr "" + +msgid "for their data processing terms." +msgstr "" + +msgid "from € 24,900" +msgstr "" + +msgid "full GitHub repository ↗" +msgstr "" + msgid "hint. Large batches are processed sequentially inside the request." msgstr "" msgid "min 0.05 MB" msgstr "" +msgid "no cookies" +msgstr "" + +msgid "no external resources" +msgstr "" + +msgid "not applicable" +msgstr "" + +msgid "often limited to one area" +msgstr "" + +msgid "often ✓" +msgstr "" + +msgid "" +"on its own domain and runs no tracking or analytics scripts. A small " +"number of keys are written to your browser's" +msgstr "" + +msgid "only while you are signed in:" +msgstr "" + +msgid "" +"optional; remembers the API key shown in your dashboard across reloads so" +" you don't need to paste it again. Cleared on logout." +msgstr "" + +msgid "or apply directly as design partner →" +msgstr "" + msgid "or click to browse (multi-file supported)" msgstr "" msgid "per request" msgstr "" +msgid "rare" +msgstr "" + +msgid "" +"role can access an internal cockpit that lists registered email addresses" +" in plaintext, along with subscription tier, account creation date, and " +"Stripe subscription status — strictly for service operation, abuse " +"response, and support. Admin actions (tier changes, role changes, " +"deactivations) are recorded with the admin's user identifier, the target " +"user's identifier, and the change performed, to enable internal auditing." +" Legal basis: Art. 6(1)(f) GDPR." +msgstr "" + +msgid "threat-mitigation anchors per category ↗" +msgstr "" + +msgid "" +"to complete payment. Stripe handles all card details directly — FileMorph" +" never sees or stores your card data. After checkout, Stripe returns a " +"customer identifier which we store to manage your subscription. Stripe is" +" a US-based company; the transfer is covered by the EU Standard " +"Contractual Clauses under Stripe's Data Processing Agreement. Legal " +"basis: Art. 6(1)(b) GDPR. See" +msgstr "" + +msgid "unlimited servers, dedicated onboarding, custom SLA" +msgstr "" + +msgid "varies" +msgstr "" + +msgid "versioning, CVSS bands, signed artefacts ↗" +msgstr "" + +msgid "via our email provider (see § 3a). We do not send marketing emails." +msgstr "" + msgid "" "we publish an advisory once a fixed release is available, and credit " "reporters who wish to be named." msgstr "" +msgid "when publication obligation applies, when not ↗" +msgstr "" + msgid "with a" msgstr "" @@ -600,6 +1480,9 @@ msgstr "" msgid "within 72 hours of receipt." msgstr "" +msgid "your JWT session tokens; strictly necessary to keep you signed in." +msgstr "" + msgid "© 2026 FileMorph — AGPLv3 Open Source" msgstr "" diff --git a/tests/test_billing_consent.py b/tests/test_billing_consent.py new file mode 100644 index 0000000..1bc6221 --- /dev/null +++ b/tests/test_billing_consent.py @@ -0,0 +1,238 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Pre-Stripe consent gate: §312g BGB / §356 (5) BGB withdrawal-waiver. + +Cloud-Edition Pro/Business subscriptions activate paid-tier API access +immediately on Stripe checkout completion. Under §356 (5) BGB the consumer's +14-day right of withdrawal expires at that moment only if the consumer has +explicitly waived it before contract execution starts. The pricing page +gates each upgrade button behind a per-tier waiver checkbox; the checkout +endpoint enforces that the matching ``withdrawal_waiver_acknowledged: true`` +flag arrives in the request body, and records the consent as a SHA-256 +hash-chained audit event so it can be reproduced at dispute time. + +Properties verified +------------------- +1. ``POST /billing/checkout/pro`` with ``withdrawal_waiver_acknowledged: false`` + (or missing) returns 400 ``withdrawal_waiver_required`` and writes no audit + event. +2. ``POST /billing/checkout/pro`` with ``withdrawal_waiver_acknowledged: true`` + succeeds (mocked Stripe), writes one + ``billing.checkout.withdrawal_waiver_recorded`` audit event with + ``actor_user_id`` set to the user's id and ``payload`` containing + ``{"tier": "pro"}``. +3. Same for ``business``. +4. Unauthenticated requests are rejected before the body is even examined + (401), so no audit event is generated. +""" + +from __future__ import annotations + +import asyncio +import json +from unittest.mock import MagicMock + +import pytest +from sqlalchemy import delete, select +from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine +from sqlalchemy.pool import StaticPool + +from app.api.routes import billing as billing_module +from app.core import audit as audit_module +from app.core.auth import hash_password +from app.core.config import settings +from app.db.base import Base, get_db +from app.db.models import AuditEvent, TierEnum, User +from app.main import app + + +# ── Test engine ────────────────────────────────────────────────────────────── + +_test_engine = create_async_engine( + "sqlite+aiosqlite:///:memory:", + connect_args={"check_same_thread": False}, + poolclass=StaticPool, + echo=False, +) +_TestSession = async_sessionmaker(_test_engine, expire_on_commit=False, class_=AsyncSession) + + +async def _setup_schema() -> None: + async with _test_engine.begin() as conn: + await conn.run_sync(Base.metadata.create_all) + + +async def _wipe() -> None: + async with _TestSession() as s: + await s.execute(delete(AuditEvent)) + await s.execute(delete(User)) + await s.commit() + + +async def _override_get_db(): + async with _TestSession() as session: + yield session + + +@pytest.fixture(scope="module", autouse=True) +def _install_overrides(): + asyncio.run(_setup_schema()) + app.dependency_overrides[get_db] = _override_get_db + # Re-point audit's self-owned session factory at the test engine — + # without this, record_event early-returns when DATABASE_URL is unset. + original_audit = audit_module.AsyncSessionLocal + audit_module.AsyncSessionLocal = _TestSession + # Configure Stripe settings so _stripe_enabled() doesn't 503. + original_secret = settings.stripe_secret_key + original_pro = settings.stripe_pro_price_id + original_biz = settings.stripe_business_price_id + settings.__dict__["stripe_secret_key"] = "sk_test_dummy" + settings.__dict__["stripe_pro_price_id"] = "price_test_pro" + settings.__dict__["stripe_business_price_id"] = "price_test_business" + # Refresh the tier-to-price mapping the route reads at import time. + billing_module._TIER_TO_PRICE = { + "pro": "price_test_pro", + "business": "price_test_business", + } + yield + audit_module.AsyncSessionLocal = original_audit + settings.__dict__["stripe_secret_key"] = original_secret + settings.__dict__["stripe_pro_price_id"] = original_pro + settings.__dict__["stripe_business_price_id"] = original_biz + app.dependency_overrides.pop(get_db, None) + + +@pytest.fixture(autouse=True) +def _wipe_between_tests(): + asyncio.run(_wipe()) + yield + + +@pytest.fixture(autouse=True) +def _mock_stripe(monkeypatch): + """Mock Stripe SDK calls so tests don't hit the network.""" + fake_customer = MagicMock(id="cus_test_123") + fake_session = MagicMock(url="https://checkout.stripe.test/redirect") + monkeypatch.setattr( + billing_module.stripe.Customer, "create", MagicMock(return_value=fake_customer) + ) + monkeypatch.setattr( + billing_module.stripe.checkout.Session, + "create", + MagicMock(return_value=fake_session), + ) + + +# ── Helpers ────────────────────────────────────────────────────────────────── + + +def _events_by_type(event_type: str) -> list[AuditEvent]: + async def _q(): + async with _TestSession() as s: + res = await s.execute( + select(AuditEvent) + .where(AuditEvent.event_type == event_type) + .order_by(AuditEvent.id.asc()) + ) + return list(res.scalars().all()) + + return asyncio.run(_q()) + + +async def _insert_user(*, email: str, password: str = "secure-pw-1") -> User: + async with _TestSession() as s: + user = User(email=email, password_hash=hash_password(password), tier=TierEnum.free) + s.add(user) + await s.commit() + await s.refresh(user) + return user + + +def _login(client, email: str, password: str = "secure-pw-1") -> str: + res = client.post("/api/v1/auth/login", json={"email": email, "password": password}) + assert res.status_code == 200, res.text + return res.json()["access_token"] + + +# ── 1. Missing acknowledgement → 400, no audit event ───────────────────────── + + +def test_checkout_pro_without_acknowledgement_returns_400(client): + asyncio.run(_insert_user(email="pro-no-ack@example.com")) + token = _login(client, "pro-no-ack@example.com") + + res = client.post( + "/api/v1/billing/checkout/pro", + headers={"Authorization": f"Bearer {token}"}, + json={"withdrawal_waiver_acknowledged": False}, + ) + assert res.status_code == 400 + assert res.json()["detail"] == "withdrawal_waiver_required" + assert _events_by_type("billing.checkout.withdrawal_waiver_recorded") == [] + + +def test_checkout_business_with_missing_field_returns_400(client): + """An empty body (no `withdrawal_waiver_acknowledged` key) defaults to + False per the Pydantic schema and is therefore rejected.""" + asyncio.run(_insert_user(email="biz-empty@example.com")) + token = _login(client, "biz-empty@example.com") + + res = client.post( + "/api/v1/billing/checkout/business", + headers={"Authorization": f"Bearer {token}"}, + json={}, + ) + assert res.status_code == 400 + assert res.json()["detail"] == "withdrawal_waiver_required" + assert _events_by_type("billing.checkout.withdrawal_waiver_recorded") == [] + + +# ── 2. With acknowledgement → 200 + audit event ────────────────────────────── + + +def test_checkout_pro_with_acknowledgement_records_audit_event(client): + user = asyncio.run(_insert_user(email="pro-ok@example.com")) + token = _login(client, "pro-ok@example.com") + + res = client.post( + "/api/v1/billing/checkout/pro", + headers={"Authorization": f"Bearer {token}"}, + json={"withdrawal_waiver_acknowledged": True}, + ) + assert res.status_code == 200, res.text + assert res.json()["url"] == "https://checkout.stripe.test/redirect" + + rows = _events_by_type("billing.checkout.withdrawal_waiver_recorded") + assert len(rows) == 1 + assert str(rows[0].actor_user_id) == str(user.id) + payload = json.loads(rows[0].payload_json) + assert payload == {"tier": "pro"} + + +def test_checkout_business_with_acknowledgement_records_audit_event(client): + user = asyncio.run(_insert_user(email="biz-ok@example.com")) + token = _login(client, "biz-ok@example.com") + + res = client.post( + "/api/v1/billing/checkout/business", + headers={"Authorization": f"Bearer {token}"}, + json={"withdrawal_waiver_acknowledged": True}, + ) + assert res.status_code == 200, res.text + + rows = _events_by_type("billing.checkout.withdrawal_waiver_recorded") + assert len(rows) == 1 + assert str(rows[0].actor_user_id) == str(user.id) + payload = json.loads(rows[0].payload_json) + assert payload == {"tier": "business"} + + +# ── 3. Unauthenticated → 401, no audit event ───────────────────────────────── + + +def test_checkout_unauthenticated_returns_401(client): + res = client.post( + "/api/v1/billing/checkout/pro", + json={"withdrawal_waiver_acknowledged": True}, + ) + assert res.status_code == 401 + assert _events_by_type("billing.checkout.withdrawal_waiver_recorded") == [] diff --git a/tests/test_public_pages_reachability.py b/tests/test_public_pages_reachability.py index ce46610..45f69dc 100644 --- a/tests/test_public_pages_reachability.py +++ b/tests/test_public_pages_reachability.py @@ -24,12 +24,13 @@ @pytest.mark.parametrize( "path,expected_marker", [ - # /privacy and /terms are still raw English (PR-i18n-2c will handle - # them with a DE-as-authoritative legal footer). /impressum is DE - # in either prefix — same word in both languages. /security IS - # wrapped, so we hit the /en/ variant for the English marker. - ("/privacy", "Privacy Policy"), - ("/terms", "Terms of Use"), + # /privacy and /terms are now i18n-wrapped (PR-i18n-2c) — DE is the + # legal-authoritative version with EN footer. Default route renders DE + # so we hit /en/ for the EN marker. /impressum stays raw German (TMG- + # bound legal text); the word "Impressum" appears in both locales. + # /security was wrapped earlier and uses the same /en/ rule. + ("/en/privacy", "Privacy Policy"), + ("/en/terms", "Terms of Use"), ("/impressum", "Impressum"), ("/en/security", "Reporting a vulnerability"), ], @@ -98,3 +99,54 @@ def test_privacy_policy_mentions_gdpr_erasure_right(client) -> None: assert "art. 17" in text_lower or "erasure" in text_lower or "löschung" in text_lower, ( "Privacy policy should reference Art. 17 GDPR / right to erasure" ) + + +def test_enterprise_de_renders_authoritative_german(client, monkeypatch) -> None: + """PR-i18n-2c: /de/enterprise carries the legal-authoritative DE text + and must NOT show the EN-only disclaimer header (which calls itself + out as a non-binding translation).""" + from app.core.config import settings + + monkeypatch.setattr(settings, "pricing_page_enabled", True) + res = client.get("/de/enterprise") + assert res.status_code == 200 + text = res.text + # Pin a DE-only domain term (untranslated EN would say "public authorities") + assert "Behörden" in text, "/de/enterprise missing 'Behörden' (DE-authoritative content)" + # Disclaimer is gated to locale=='en' — DE must not see it + assert "authoritative legal text" not in text, ( + "/de/enterprise should not render the EN disclaimer (DE is authoritative)" + ) + + +def test_enterprise_en_renders_english_with_disclaimer(client, monkeypatch) -> None: + """PR-i18n-2c: /en/enterprise carries the EN translation plus the + disclaimer that points to the DE original as legally binding.""" + from app.core.config import settings + + monkeypatch.setattr(settings, "pricing_page_enabled", True) + res = client.get("/en/enterprise") + assert res.status_code == 200 + text = res.text + assert "authoritative legal text" in text, ( + "/en/enterprise must render the EN-only disclaimer pointing to DE original" + ) + # 'Behörden' would only appear if a string slipped through the EN-twin + assert "Behörden" not in text, ( + "/en/enterprise still has raw German term 'Behörden' — translation gap" + ) + + +def test_impressum_en_has_preamble_then_german(client) -> None: + """PR-i18n-2c: /en/impressum prepends an EN preamble explaining why + the legal body below stays in German (TMG § 5 Pflichtangaben).""" + res = client.get("/en/impressum") + assert res.status_code == 200 + text = res.text + assert "as required by German law" in text, ( + "/en/impressum missing EN preamble explaining DE legal text" + ) + # Raw DE TMG content must still be present below the preamble + assert "Verantwortlich" in text, ( + "/en/impressum missing the raw DE TMG section after the preamble" + ) diff --git a/tests/test_seo_foundation.py b/tests/test_seo_foundation.py index b3b4fbe..ba4b0ba 100644 --- a/tests/test_seo_foundation.py +++ b/tests/test_seo_foundation.py @@ -283,9 +283,14 @@ def test_pricing_renders_coming_soon_when_stripe_disabled(client, monkeypatch): assert "disabled" in body, "upgrade buttons must be disabled in Coming-Soon mode" -def test_pricing_renders_live_buttons_when_stripe_enabled(client, monkeypatch): - """Live mode: upgrade buttons must NOT carry the disabled attribute, so - real users can hit the Stripe checkout endpoint.""" +def test_pricing_renders_live_buttons_with_waiver_gate_when_stripe_enabled(client, monkeypatch): + """Live mode: upgrade buttons are gated behind a §356 (5) BGB withdrawal- + waiver checkbox. The button starts as ``disabled`` and ``pricing.js`` + unlocks it once the user actively ticks the matching waiver checkbox. + Without this two-step consent the §356 (5) BGB waiver in ``terms.html`` + §9 cannot be enforced. We assert the structural anchors here so a future + refactor that removes the gate fails loudly. + """ from app.core.config import settings monkeypatch.setattr(settings, "pricing_page_enabled", True) @@ -296,14 +301,17 @@ def test_pricing_renders_live_buttons_when_stripe_enabled(client, monkeypatch): r = client.get("/pricing") assert r.status_code == 200 - # Find the pro button line; it must not include the `disabled` attribute - # in its tag (the Coming-Soon variant has `disabled` directly on