diff --git a/Web/app.py b/Web/app.py index 8e25515..8326e7f 100755 --- a/Web/app.py +++ b/Web/app.py @@ -8220,11 +8220,26 @@ def admin_audit_export_pdf_official(): audit_rows = list(db['audit_log'].find({}).sort('chain_index', -1).limit(limit)) - # DEC_START: Decrypt sensitive fields for the PDF report for row in audit_rows: - if "payload" in row: - decrypt_document_fields(row["payload"], SENSITIVE_AUDIT_FIELDS) - # DEC_END + payload_raw = row.get("payload") + + if payload_raw and isinstance(payload_raw, str): + try: + # Safely evaluate the python-like dict string with custom token support + safe_context = {"ObjectId": ObjectId, "None": None, "True": True, "False": False} + payload_dict = eval(payload_raw, {"__builtins__": {}}, safe_context) + + if isinstance(payload_dict, dict): + # Decrypt the dictionary fields in-place + decrypt_document_fields(payload_dict, SENSITIVE_AUDIT_FIELDS) + # Replace string with the clean dictionary so the PDF generator can read it + row["payload"] = payload_dict + except Exception as parse_err: + app.logger.error(f"Failed to parse audit payload string for PDF export at index {row.get('chain_index')}: {parse_err}") + + elif payload_raw and isinstance(payload_raw, dict): + # Fallback for standard dict payloads + decrypt_document_fields(payload_raw, SENSITIVE_AUDIT_FIELDS) # Get school information from settings or use defaults school_info = _get_school_info_for_export()