Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
83f1c5a
Ignore
awehttam May 22, 2026
439e059
Accept QWK REP uploads at FTP root for Synchronet QNET-FTP compatibility
awehttam May 22, 2026
5772ee0
WIP: add QWK network exchange support
awehttam May 23, 2026
277f1fa
WIP
awehttam May 23, 2026
3642b63
Show QWK packet at FTP root with real file size
awehttam May 23, 2026
46a7be7
WIP: qwk polling and ui fixes
awehttam May 23, 2026
4bd09be
WIP: add qwknet headers.dat support
awehttam May 23, 2026
cff185f
Merge branch 'claudesbbs' into qwknet
awehttam May 23, 2026
3985e8a
WIP: add qwk network defaults and filters
awehttam May 23, 2026
7b3946a
WIP: improve echo area deletion handling
awehttam May 23, 2026
3f83d3b
Fix QWK REP conference header padding
awehttam May 23, 2026
ecde1c9
Update QWK mailbox handling and docs
awehttam May 23, 2026
8bcc03a
Split QWK offline and networking docs
awehttam May 23, 2026
cf89bac
Align QWK polling with scheduler and UI flows
awehttam May 23, 2026
74f08e6
Document QWK classes and phpDoc requirements
awehttam May 23, 2026
965b229
Improve 1.9.8 upgrade notes
awehttam May 23, 2026
4927738
Fix QWK usage phpDoc labels
awehttam May 23, 2026
b156948
Merge branch 'claudesbbs' into qwknet
awehttam May 24, 2026
7e8e43c
Abstract realtime and database bootstrap setup
awehttam May 25, 2026
e3fbc1e
Expand PostgreSQL dependency inventory
awehttam May 25, 2026
6078229
Merge branch 'qwknet' into claudesbbs
awehttam May 25, 2026
a78bc75
Harden admin daemon SSE maintenance
awehttam May 25, 2026
c9e3a3c
Revert "Merge branch 'qwknet' into claudesbbs"
awehttam May 25, 2026
8fb1a77
Fix stale active BinkP session cleanup
awehttam May 25, 2026
36dd166
Clarify supported hosting environments
awehttam May 26, 2026
6bd7534
Fix dashboard caller time display
awehttam May 26, 2026
1c6ddc1
Document AI assistant credit response
awehttam May 26, 2026
2bf1a1a
Document response frames for truncated API endpoints
awehttam May 26, 2026
125fc21
Complete API.md response field documentation
awehttam May 26, 2026
11d51d7
Strengthen API.md response table documentation rules
awehttam May 26, 2026
eb71994
Add configurable pipe code parser mode
awehttam May 28, 2026
1657278
Add PGP key management and messaging
awehttam Jun 2, 2026
225d540
Add destination-aware PGP lookup
awehttam Jun 2, 2026
05a5c5a
Use hostname fallback for remote PGP lookup
awehttam Jun 2, 2026
966a1ec
Trap keyboard input in PGP decrypt modal
awehttam Jun 2, 2026
21e8d11
Add address-book linked PGP correspondent keys
awehttam Jun 2, 2026
389ae8d
Select matching PGP key when decrypting
awehttam Jun 2, 2026
cb49650
Ungate core echomail scripts from interests
awehttam Jun 2, 2026
c3199cd
Add HKPS discovery routes
awehttam Jun 2, 2026
a13e318
Clarify PGP local vs managed workflows
awehttam Jun 2, 2026
9175245
Document PGP DNS discovery example
awehttam Jun 2, 2026
2891aa3
Improve PGP keyserver network lookups
awehttam Jun 3, 2026
f055e10
Expand PGP keyserver search help
awehttam Jun 3, 2026
4a81068
Allow PGP encrypt-only netmail compose
awehttam Jun 3, 2026
c90d555
Align netmail reader To and Subject
awehttam Jun 3, 2026
103a7c3
Use saved correspondent keys for PGP verification
awehttam Jun 3, 2026
e6c0d10
Increase user theme column length
awehttam Jun 3, 2026
cc5d5a6
Escape slash in HKPS lookup route regex
awehttam Jun 5, 2026
491892b
Refactor MeshCore advert storage
awehttam Jun 6, 2026
f165785
Fix CWN MeshCore node detail lookup
awehttam Jun 6, 2026
eb414ef
Fix PacketBBS node detail query
awehttam Jun 6, 2026
6925352
Add echomail list explain helper
awehttam Jun 9, 2026
2c9c13c
Adjust compose and message refresh behavior
awehttam Jun 12, 2026
9167c02
Optimize echomail list query performance
awehttam Jun 12, 2026
24df4db
Bump service worker cache for echomail JS changes
awehttam Jun 12, 2026
2dee252
Document echomail list performance improvements
awehttam Jun 12, 2026
c451763
Cache echomail stats requests on the client
awehttam Jun 12, 2026
d209f97
Centralize echomail page refreshes
awehttam Jun 12, 2026
34588f8
Fix stale echomail area header
awehttam Jun 12, 2026
cf4119d
Fix subscriptions message-only filter
awehttam Jun 12, 2026
13bf59f
Clear managed PGP settings fields
awehttam Jun 12, 2026
ecdcfad
Optimize echomail unread filters
awehttam Jun 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ window.t('ui.polls.create.submit', { cost: 25 }, 'Create Poll ({cost} credits)')
3. Replace JS literals with `window.t(...)` (or `uiT(...)`) fallbacks, but do not invent a new inline fallback unless the corresponding catalog key was added first.
4. Ensure API errors return `error_code`.
5. Run both i18n check scripts before commit.
6. **API route changes**: When adding, removing, or modifying routes in `routes/api-routes.php`, update `docs/API.md` to reflect the change.
6. **API route changes**: When adding, removing, or modifying routes in `routes/api-routes.php`, update `docs/API.md`. Response tables must be complete: every field typed `object` or `array of objects` must have its sub-fields listed in the same table using dot-notation (`parent.child`) or bracket-notation (`items[].child`). A row typed `object` or `array` with no sub-rows is incomplete and must not be committed. See **Response table format** in `docs/DEVELOPER_GUIDE.md` for the full rules and an example.

## URL Construction

Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,12 @@ See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full component diagram,

BinktermPHP supports two installation methods:

- **Installer (recommended)** download and run `binkterm-installer.phar` for a guided, automated setup that handles PHP, PostgreSQL, web server configuration, and migrations
- **Git (for developers)** clone the repository and run setup scripts for full control over the installation
- **Installer (recommended)** - download and run `binkterm-installer.phar` for a guided, automated setup that handles PHP, PostgreSQL, web server configuration, and migrations
- **Git (for developers)** - clone the repository and run setup scripts for full control over the installation

For complete installation instructions — system requirements, Ubuntu/Debian package setup, PostgreSQL configuration, web server configuration (Caddy, Nginx, Apache), cron job setup, and a network port reference — see **[docs/INSTALL.md](docs/INSTALL.md)**.
BinktermPHP is intended for a VPS, dedicated server, Raspberry Pi, or similar environment where you control PostgreSQL, background daemons, and multiple network ports. Shared hosting is not recommended.

For complete installation instructions - system requirements, Ubuntu/Debian package setup, PostgreSQL configuration, web server configuration (Caddy, Nginx, Apache), cron job setup, and a network port reference - see **[docs/INSTALL.md](docs/INSTALL.md)**.

---

Expand Down
4 changes: 3 additions & 1 deletion config/bbs.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"guest_doors_page": false,
"bbs_directory": true,
"public_files_index": false,
"qwk": true
"qwk": true,
"pgp": false,
"pgp_managed_keys": false
},
"default_echo_interface": "echolist",
"bulletin_display_mode": "once",
Expand Down
95 changes: 95 additions & 0 deletions config/i18n/de/common.php
Original file line number Diff line number Diff line change
Expand Up @@ -1813,6 +1813,10 @@
'ui.admin.bbs_settings.features.bbs_directory_help' => 'Zeigt die öffentliche Seite /bbs-directory und das BBS-Listen-Menü an. Wenn deaktiviert, liefert die Seite 404.',
'ui.admin.bbs_settings.features.enable_qwk' => 'Enable QWK Offline Mail',
'ui.admin.bbs_settings.features.qwk_help' => 'Erlaubt Benutzern, QWK-Pakete herunterzuladen und REP-Antwortpakete für Offline-Mail hochzuladen.',
'ui.admin.bbs_settings.features.enable_pgp' => 'PGP aktivieren',
'ui.admin.bbs_settings.features.pgp_help' => 'Aktiviert die PGP-Schluesselverwaltung fuer Benutzer, den oeffentlichen Keyserver und HKP-aehnliche Suchendpunkte fuer oeffentliche Schluessel.',
'ui.admin.bbs_settings.features.enable_pgp_managed_keys' => 'BBS-verwaltete private Schluessel erlauben',
'ui.admin.bbs_settings.features.pgp_managed_keys_help' => 'Wenn aktiviert, koennen Benutzer browserseitig PGP-Schluesselpaare erzeugen und den verschluesselten privaten Schluessel auf diesem Server speichern.',
'ui.admin.bbs_settings.features.qwk_bbs_id' => 'QWK BBS ID',
'ui.admin.bbs_settings.features.qwk_bbs_id_help' => 'Bis zu 8 alphanumerische Zeichen als Paketkennung (BBSID). Eine Änderung kann bereits konfigurierte Offline-Reader dieser BBS unbrauchbar machen.',
'ui.admin.bbs_settings.validation.qwk_bbs_id_invalid' => 'QWK BBS ID muss sein 1–8 letters or digits.',
Expand Down Expand Up @@ -2793,6 +2797,10 @@
'ui.address_book.node_address_help' => 'Format: zone:net/node oder zone:net/node.point',
'ui.address_book.email_help' => 'Nur zu Deiner Referenz – wird nicht für Nachrichten verwendet',
'ui.address_book.description_placeholder' => 'Notes about this contact...',
'ui.address_book.pgp_public_key' => 'PGP-Oeffentlicher Schluessel',
'ui.address_book.pgp_public_key_placeholder' => '-----BEGIN PGP PUBLIC KEY BLOCK-----',
'ui.address_book.pgp_public_key_help' => 'Speichern Sie optional den oeffentlichen Schluessel dieses Kontakts fuer verschluesselte Antworten an entfernte Systeme.',
'ui.address_book.pgp_key_linked' => 'PGP-Schluessel verknuepft',
'ui.address_book.always_crashmail' => 'Always use crashmail for this Empfänger',
'ui.address_book.always_crashmail_help' => 'Crashmail beim Verfassen von Nachrichten an diesen Kontakt automatisch aktivieren.',

Expand Down Expand Up @@ -4959,4 +4967,91 @@
'ui.admin.networks.deleted' => 'Network deleted',
'ui.admin.networks.change_domain_failed' => 'Failed to change domain',
'ui.admin.networks.domain_changed' => 'Domain changed',
'ui.settings.tab.pgp' => 'PGP',
'ui.settings.pgp.heading' => 'PGP-Schluessel',
'ui.settings.pgp.help' => 'Oeffentliche Schluessel hochladen, BBS-verwaltete private Schluessel erzeugen und den bevorzugten oeffentlichen Schluessel fuer den Keyserver auswaehlen.',
'ui.settings.pgp.upload_heading' => 'Oeffentlichen Schluessel hochladen',
'ui.settings.pgp.key_label' => 'Schluesselbezeichnung',
'ui.settings.pgp.key_label_placeholder' => 'Laptop-Schluessel, Arbeitsschluessel, Archivschluessel',
'ui.settings.pgp.public_key' => 'ASCII-armored oeffentlicher Schluessel',
'ui.settings.pgp.public_key_placeholder' => '-----BEGIN PGP PUBLIC KEY BLOCK-----',
'ui.settings.pgp.upload_button' => 'Oeffentlichen Schluessel hochladen',
'ui.settings.pgp.generate_heading' => 'BBS-verwalteten Schluessel erzeugen',
'ui.settings.pgp.managed_label_placeholder' => 'BinktermPHP verwalteter Schluessel',
'ui.settings.pgp.passphrase' => 'PGP-Passphrase',
'ui.settings.pgp.passphrase_placeholder' => 'PGP-Passphrase eingeben',
'ui.settings.pgp.passphrase_help' => 'Verwenden Sie eine Passphrase, die sich von Ihrem Login-Passwort unterscheidet.',
'ui.settings.pgp.passphrase_confirm' => 'Passphrase bestaetigen',
'ui.settings.pgp.passphrase_confirm_placeholder' => 'PGP-Passphrase erneut eingeben',
'ui.settings.pgp.generate_button' => 'Verwalteten Schluessel erzeugen',
'ui.settings.pgp.generate_help' => 'Dieses erzeugt das Schluesselpaar im Browser und speichert nur den verschluesselten privaten Schluessel auf dem Server.',
'ui.settings.pgp.managed_disabled_notice' => 'Diese BBS erlaubt das Hochladen oeffentlicher PGP-Schluessel, aber das Hosten BBS-verwalteter privater Schluessel ist vom Sysop deaktiviert.',
'ui.settings.pgp.saved_keys_heading' => 'Gespeicherte Schluessel',
'ui.settings.pgp.keyserver_button' => 'Keyserver durchsuchen',
'ui.settings.pgp.no_keys' => 'Noch keine PGP-Schluessel gespeichert.',
'ui.settings.pgp.col_primary' => 'Status',
'ui.settings.pgp.col_label' => 'Bezeichnung',
'ui.settings.pgp.col_fingerprint' => 'Fingerprint',
'ui.settings.pgp.col_source' => 'Quelle',
'ui.settings.pgp.col_created' => 'Erstellt',
'ui.settings.pgp.col_actions' => 'Aktionen',
'ui.settings.pgp.source_managed' => 'BBS verwaltet',
'ui.settings.pgp.source_uploaded' => 'Hochgeladen',
'ui.settings.pgp.private_key_available' => 'Verschluesselter privater Schluessel gespeichert',
'ui.settings.pgp.primary_selector' => 'Bevorzugter oeffentlicher Schluessel',
'ui.settings.pgp.primary_help' => 'Waehle hier einen Schluessel aus oder nutze die Schaltflaeche "Als primaer festlegen" in der Tabelle unten, um zu aendern, welcher oeffentliche Schluessel auf dem Keyserver bevorzugt angezeigt wird.',
'ui.settings.pgp.primary_selected' => 'Primaer',
'ui.settings.pgp.secondary_key' => 'Sekundaer',
'ui.settings.pgp.make_primary_button' => 'Als primaer festlegen',
'ui.settings.pgp.current_primary_button' => 'Aktuell primaer',
'ui.settings.pgp.uploading' => 'Oeffentlichen Schluessel wird hochgeladen...',
'ui.settings.pgp.upload_success' => 'PGP-Schluessel gespeichert.',
'ui.settings.pgp.openpgp_missing' => 'OpenPGP.js ist auf diesem BBS noch nicht installiert, daher ist die Browser-Schluesselerzeugung nicht verfuegbar.',
'ui.settings.pgp.generating' => 'PGP-Schluesselpaar wird erzeugt...',
'ui.settings.pgp.generate_success' => 'Verwalteter PGP-Schluessel wurde erzeugt und gespeichert.',
'ui.settings.pgp.primary_updated' => 'Primaerer PGP-Schluessel aktualisiert.',
'ui.settings.pgp.delete_confirm' => 'Diesen PGP-Schluessel loeschen?',
'ui.settings.pgp.delete_success' => 'PGP-Schluessel geloescht.',
'ui.settings.pgp.copy_success' => 'Fingerprint kopiert.',
'ui.settings.pgp.copy_public_key_button' => 'Oeffentlichen Schluessel kopieren',
'ui.settings.pgp.download_public_key_button' => 'Oeffentlichen Schluessel herunterladen',
'ui.settings.pgp.copy_public_key_success' => 'Oeffentlicher Schluessel kopiert.',
'ui.settings.pgp.key_details_title' => 'PGP-Schluesseldetails',
'ui.settings.pgp.algorithm' => 'Algorithmus',
'ui.compose.pgp.title' => 'PGP',
'ui.compose.pgp.encrypt_netmail' => 'Dieses Netmail verschlüsseln',
'ui.compose.pgp.encrypt_netmail_help' => 'Verschlüsselt die Nachricht für den Empfänger mit dessen veröffentlichtem öffentlichen Schlüssel.',
'ui.compose.pgp.sign_echomail' => 'Dieses Echomail signieren',
'ui.compose.pgp.sign_echomail_help' => 'Signiert die Nachricht mit Deinem gespeicherten verwalteten privaten Schlüssel.',
'ui.compose.pgp.encrypt_only_notice' => 'Netmail-Verschluesselung braucht nur den oeffentlichen Schluessel des Empfaengers. Signieren und Entschluesseln erfordern Deinen verwalteten privaten Schluessel.',
'ui.compose.pgp.encrypt_recipient_label' => 'Öffentlicher Schlüssel des Empfängers',
'ui.compose.pgp.encrypt_recipient_help' => 'Wähle den öffentlichen Schlüssel, mit dem dieses Netmail verschlüsselt wird.',
'ui.compose.pgp.encrypt_recipient_placeholder' => 'Öffentlichen Schlüssel zum Verschlüsseln auswählen',
'ui.compose.pgp.encrypt_no_key' => 'Kein passender öffentlicher Schlüssel gefunden.',
'ui.compose.pgp.encrypt_no_key_help' => 'Gib einen Empfänger mit veröffentlichtem öffentlichen Schlüssel an.',
'ui.compose.pgp.encrypting_for' => 'Verschlüsselung für {recipient}',
'ui.pgp.notice' => 'PGP-Aktionen verwenden Deinen gespeicherten verwalteten privaten Schlüssel. Wenn Du nur einen öffentlichen Schlüssel hochgeladen hast, sind Signieren und Entschlüsseln nicht verfügbar.',
'ui.pgp.decrypt_button' => 'Entschlüsseln',
'ui.pgp.decrypt_help' => 'Diese Nachricht ist mit PGP verschlüsselt.',
'ui.pgp.passphrase_prompt' => 'Gib Deine PGP-Passphrase ein, um diese Nachricht zu entschlüsseln.',
'ui.pgp.decrypted' => 'PGP entschlüsselt',
'ui.pgp.verifying' => 'PGP-Signatur wird überprüft...',
'ui.pgp.verified' => 'PGP-Signatur bestätigt',
'ui.pgp.no_public_key' => 'Öffentlicher PGP-Schlüssel nicht gefunden',
'ui.pgp.invalid' => 'Ungültige PGP-Signatur',
'ui.keyserver.title' => 'PGP-Keyserver',
'ui.keyserver.manage_keys' => 'Meine Schluessel verwalten',
'ui.keyserver.search_label' => 'Suche',
'ui.keyserver.search_placeholder' => 'Benutzername, Realname, E-Mail oder Fingerprint',
'ui.keyserver.search_help' => 'Suchen Sie nach Kontoname, E-Mail-Adresse, vollstaendigem Fingerprint oder einer entfernten qualifizierten Suche wie awehttam@227:1/200 oder foobar@claudes.lovelybits.org.',
'ui.keyserver.search_button' => 'Suchen',
'ui.keyserver.results_heading' => 'Oeffentliche Schluessel',
'ui.keyserver.col_user' => 'Benutzer',
'ui.keyserver.col_fingerprint' => 'Fingerprint',
'ui.keyserver.col_type' => 'Typ',
'ui.keyserver.col_created' => 'Erstellt',
'ui.keyserver.col_actions' => 'Aktionen',
'ui.keyserver.primary_badge' => 'Primaer',
'ui.keyserver.download_button' => 'Herunterladen',
'ui.keyserver.no_results' => 'Keine oeffentlichen Schluessel entsprechen Ihrer Suche.',
Comment on lines +4970 to +5056

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# run locally before merge
php scripts/check_i18n_syntax.php --locale=de
git diff -- public_html/sw.js

Repository: awehttam/binkterm-php

Length of output: 214


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== sw.js CACHE_NAME diff ==="
git diff -- public_html/sw.js | sed -n '1,200p'

echo
echo "=== current sw.js CACHE_NAME ==="
rg -n "CACHE_NAME" public_html/sw.js || true
sed -n '1,220p' public_html/sw.js | rg -n "CACHE_NAME|binkcache-" || true

Repository: awehttam/binkterm-php

Length of output: 1215


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "i18n|config/i18n|translator|locale|common\.php|errors\.php|terminalserver\.php|/de/" public_html/sw.js || true

Repository: awehttam/binkterm-php

Length of output: 378


🏁 Script executed:

#!/bin/bash
set -euo pipefail
nl -ba public_html/sw.js | sed -n '1,220p'
nl -ba public_html/sw.js | sed -n '220,320p'

Repository: awehttam/binkterm-php

Length of output: 108


🏁 Script executed:

#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from itertools import islice
path="public_html/sw.js"
with open(path,'r',encoding='utf-8') as f:
    lines=list(f)
for start,end in [(120,220),(180,260)]:
    print(f"\n=== {path} lines {start}-{end} ===")
    for i in range(start-1,end):
        if i<0 or i>=len(lines): continue
        print(f"{i+1}: {lines[i].rstrip()}")
PY

Repository: awehttam/binkterm-php

Length of output: 6064


Update SERVICE WORKER cache version for i18n changes (de/common.php)

  • php scripts/check_i18n_syntax.php --locale=de passes (includes i18n/de/common.php).
  • public_html/sw.js CACHE_NAME was not incremented in this change; since the service worker caches /api/i18n/catalog cache-first, bump CACHE_NAME so clients fetch the updated German catalog.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@config/i18n/de/common.php` around lines 4970 - 5056, The service worker cache
version wasn't bumped after updating i18n/de/common.php, so clients may still
serve the old /api/i18n/catalog; open public_html/sw.js, locate the CACHE_NAME
constant (and any CACHE_VERSION or cache name string) and increment its version
value (e.g. append or increment the numeric suffix) so the service worker treats
caches as changed and fetches the updated German catalog; then rebuild/deploy so
clients get the new sw.js.

];
17 changes: 17 additions & 0 deletions config/i18n/de/errors.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@
'errors.messages.send.invalid_type' => 'Ungültig: message type',
'errors.messages.send.failed' => 'Nachricht konnte nicht gesendet werden',
'errors.messages.send.exception' => 'Nachricht konnte nicht gesendet werden',
'errors.pgp.decrypt_failed' => 'PGP-Nachricht konnte nicht entschlüsselt werden.',
'errors.pgp.recipient_required' => 'Es konnte kein öffentlicher Schlüssel für den Empfänger ermittelt werden.',
'errors.pgp.passphrase_required' => 'Bitte gib Deine PGP-Passphrase ein.',
'errors.pgp.private_key_required' => 'Zum Signieren ist ein verwalteter privater Schluessel erforderlich.',

// Notify
'errors.notify.user_id_missing' => 'Kann nicht aufgelöst werden: user session',
Expand Down Expand Up @@ -722,4 +726,17 @@
'errors.meshcore.not_found' => 'Kontakt nicht gefunden.',
'errors.meshcore.qr_unrecognized' => 'Unbekanntes QR-Code-Format.',
'errors.meshcore.qr_camera_denied' => 'Kamerazugriff verweigert.',
'errors.pgp.load_failed' => 'PGP-Schluessel konnten nicht geladen werden.',
'errors.pgp.public_key_required' => 'Ein oeffentlicher Schluessel ist erforderlich.',
'errors.pgp.invalid_key' => 'Ungueltiger PGP-Schluessel.',
'errors.pgp.save_failed' => 'PGP-Schluessel konnte nicht gespeichert werden.',
'errors.pgp.invalid_keypair' => 'Ungueltiges PGP-Schluesselpaar.',
'errors.pgp.key_not_found' => 'PGP-Schluessel nicht gefunden.',
'errors.pgp.private_key_not_found' => 'Privater Schluessel nicht gefunden.',
'errors.pgp.delete_failed' => 'PGP-Schluessel konnte nicht geloescht werden.',
'errors.pgp.disabled' => 'PGP ist auf diesem System deaktiviert.',
'errors.pgp.managed_disabled' => 'Die Erzeugung verwalteter PGP-Schluessel ist auf diesem System deaktiviert.',
'errors.pgp.passphrase_too_short' => 'Verwenden Sie eine laengere PGP-Passphrase.',
'errors.pgp.passphrase_mismatch' => 'Die Passphrase-Bestaetigung stimmt nicht ueberein.',
'errors.pgp.generation_failed' => 'BBS-verwalteter PGP-Schluessel konnte nicht erzeugt werden.',
];
Loading
Loading