feat: add S/MIME store for managing key records and public certificates

- Implemented Zustand store for S/MIME functionality, including state management for key records and public certificates.
- Added methods for importing PKCS#12 files and public certificates, binding identities to keys, and managing unlocked keys.
- Introduced session storage for remembering unlocked keys across sessions.
- Enhanced error handling and loading states during data operations.
This commit is contained in:
Linus Rath
2026-03-17 20:14:01 +01:00
parent 7c5785e9e8
commit de35d1d8e8
45 changed files with 24687 additions and 64 deletions
+98 -2
View File
@@ -421,7 +421,16 @@
"continue_draft": "Continue draft",
"close_draft_title": "Save or discard draft?",
"close_draft_message": "You have unsaved changes. Would you like to save this as a draft or discard it?",
"save_draft": "Save Draft"
"save_draft": "Save Draft",
"smime_sign_on": "S/MIME signing enabled",
"smime_sign_off": "Enable S/MIME signing",
"smime_encrypt_on": "S/MIME encryption enabled",
"smime_encrypt_off": "Enable S/MIME encryption",
"smime_encrypt_unavailable": "S/MIME encryption unavailable missing recipient certificates",
"smime_unlock_title": "Unlock S/MIME Key",
"smime_unlock_message": "Enter the passphrase to unlock your S/MIME signing key.",
"smime_unlock_button": "Unlock",
"smime_passphrase_placeholder": "Passphrase"
},
"confirm_dialog": {
"confirm": "Confirm",
@@ -553,7 +562,8 @@
"keywords": "Keywords",
"security": "Security",
"files": "Files",
"contacts": "Contacts"
"contacts": "Contacts",
"encryption": "Encryption"
},
"tab_groups": {
"general": "General",
@@ -1412,6 +1422,15 @@
"categories": "Categories",
"related_contacts": "Related Contacts",
"crypto_keys": "Crypto Keys",
"cert_issuer": "Issuer",
"cert_expires": "Expires",
"cert_expired": "Expired",
"cert_fingerprint": "Fingerprint",
"cert_algorithm": "Algorithm",
"import_to_smime": "Import to S/MIME",
"cert_already_imported": "Already imported to S/MIME",
"cert_imported": "Certificate imported to S/MIME store",
"cert_import_failed": "Failed to import certificate",
"no_contact_selected": "Select a contact to view details",
"compose_email": "Compose email",
"copy_email": "Copy email",
@@ -1989,5 +2008,82 @@
"settings_folder_layout_desc": "Choose how folders are displayed: inline with files or in a sidebar tree",
"settings_folder_layout_inline": "Inline",
"settings_folder_layout_sidebar": "Sidebar"
},
"smime": {
"your_certificates": "Your Certificates",
"your_certificates_desc": "Import and manage your S/MIME certificates for signing and encrypting emails",
"recipient_certificates": "Recipient Certificates",
"recipient_certificates_desc": "Public certificates for encrypting emails to recipients",
"identity_bindings": "Identity Key Bindings",
"identity_bindings_desc": "Bind S/MIME certificates to your email identities",
"defaults_title": "Defaults",
"defaults_desc": "Configure default signing and encryption behavior",
"import_pkcs12": "Import PKCS#12 (.p12/.pfx)",
"import_public_cert": "Import Certificate",
"no_certificates": "No certificates imported yet",
"no_recipient_certs": "No recipient certificates",
"expires": "Expires",
"expired": "Expired",
"bound_to": "Bound to",
"no_key_bound": "None",
"lock": "Lock key",
"unlock": "Unlock key",
"details": "View details",
"delete": "Delete",
"encrypt_by_default": "Encrypt by default",
"encrypt_by_default_desc": "Automatically encrypt emails when all recipients have certificates",
"remember_unlocked": "Remember unlocked keys",
"remember_unlocked_desc": "Keep keys unlocked for the duration of this browser session",
"sign_default_for": "Sign by default for",
"enter_p12_passphrase": "Enter PKCS#12 Passphrase",
"p12_passphrase_desc": "Enter the passphrase that protects this certificate file",
"enter_storage_passphrase": "Set Storage Passphrase",
"storage_passphrase_desc": "Choose a passphrase to protect this key at rest in your browser",
"next": "Next",
"import": "Import",
"unlock_key": "Unlock Key",
"unlock_key_desc": "Enter the storage passphrase to unlock this key for signing or decryption",
"passphrase_placeholder": "Enter passphrase",
"confirm_passphrase_placeholder": "Confirm passphrase",
"passphrase_mismatch": "Passphrases do not match",
"cancel": "Cancel",
"processing": "Processing…",
"close": "Close",
"certificate_details": "Certificate Details",
"cert_subject": "Subject",
"cert_issuer": "Issuer",
"cert_email": "Email",
"cert_serial": "Serial Number",
"cert_validity": "Validity",
"cert_fingerprint": "Fingerprint (SHA-256)",
"cert_algorithm": "Algorithm",
"cert_capabilities": "Capabilities",
"cert_source": "Source",
"cert_expired": "This certificate has expired",
"cert_not_yet_valid": "This certificate is not yet valid",
"cap_sign": "Signing",
"cap_encrypt": "Encryption",
"cap_none": "None",
"show_passphrase": "Show passphrase",
"hide_passphrase": "Hide passphrase",
"sign_toggle": "Sign",
"encrypt_toggle": "Encrypt",
"missing_recipient_certs": "Missing certificates for: {emails}",
"missing_sender_cert": "No certificate bound to this identity",
"status_encrypted_ok": "This message was encrypted",
"status_encrypted_no_key": "This message is encrypted but no matching key was found",
"status_encrypted_failed": "Failed to decrypt this message",
"status_signed_valid": "Signature verified",
"status_signed_invalid": "Signature verification failed",
"status_signed_expired_cert": "Signed with an expired certificate",
"status_signed_mismatch": "Signature valid, but signer does not match sender",
"status_unsupported": "Unsupported S/MIME format",
"auto_import_signer_certs": "Auto-import signer certificates",
"auto_import_signer_certs_desc": "Automatically save certificates from verified signed emails for future encryption",
"export": "Export",
"enter_export_passphrase": "Set Export Passphrase",
"export_passphrase_desc": "Choose a passphrase to protect the exported PKCS#12 file",
"export_storage_desc": "Enter the storage passphrase to decrypt the key for export",
"incorrect_passphrase": "Incorrect passphrase"
}
}