- Created a new SQL migration for the sag_salgsvarer table to manage sales and purchase items. - Implemented a new HTML template for the Varekøb & Salg module, including summary cards and tables for sales and purchases. - Added JavaScript functions for loading and rendering order data dynamically. - Introduced a new backend search module for customers, contacts, hardware, and locations with autocomplete functionality. - Developed an email templates API for managing system and customer-specific email templates. - Created multiple migrations for Nextcloud instances, cache, audit logs, email templates, sag comments, hardware locations, and billing methods. - Enhanced the sag module with solutions, order lines, work types, and 2FA support for user authentication.
32 lines
853 B
Python
32 lines
853 B
Python
"""
|
|
Crypto helpers for encrypting/decrypting secrets at rest.
|
|
"""
|
|
|
|
import logging
|
|
from typing import Optional
|
|
from cryptography.fernet import Fernet, InvalidToken
|
|
|
|
from app.core.config import settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _get_fernet() -> Fernet:
|
|
if not settings.NEXTCLOUD_ENCRYPTION_KEY:
|
|
raise ValueError("NEXTCLOUD_ENCRYPTION_KEY not configured")
|
|
return Fernet(settings.NEXTCLOUD_ENCRYPTION_KEY.encode())
|
|
|
|
|
|
def encrypt_secret(value: str) -> str:
|
|
fernet = _get_fernet()
|
|
return fernet.encrypt(value.encode()).decode()
|
|
|
|
|
|
def decrypt_secret(value: str) -> Optional[str]:
|
|
try:
|
|
fernet = _get_fernet()
|
|
return fernet.decrypt(value.encode()).decode()
|
|
except (InvalidToken, ValueError) as exc:
|
|
logger.error("❌ Nextcloud credential decryption failed: %s", exc)
|
|
return None
|