AI Newsletter Digest improvements: fixed QP soft line break decoding, URL extraction, and content cleaning
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Encrypt a JSON payload for C2C messaging."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from nacl.public import Box, PrivateKey, PublicKey
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
|
||||
sender = parser.add_mutually_exclusive_group(required=True)
|
||||
sender.add_argument("--sender-private-key", help="Sender private key (base64)")
|
||||
sender.add_argument("--sender-private-key-file", help="Path to sender private key file or key JSON")
|
||||
|
||||
recipient = parser.add_mutually_exclusive_group(required=True)
|
||||
recipient.add_argument("--recipient-public-key", help="Recipient public key (base64)")
|
||||
recipient.add_argument("--recipient-public-key-file", help="Path to recipient public key file or key JSON")
|
||||
|
||||
payload = parser.add_mutually_exclusive_group()
|
||||
payload.add_argument("--payload-json", help="Inline JSON payload string")
|
||||
payload.add_argument("--payload-file", help="Path to payload JSON file")
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def read_text(path: str) -> str:
|
||||
return Path(path).expanduser().read_text(encoding="utf-8").strip()
|
||||
|
||||
|
||||
def coerce_key(text: str, key_name: str) -> str:
|
||||
text = text.strip()
|
||||
if text.startswith("{"):
|
||||
return json.loads(text)[key_name]
|
||||
return text
|
||||
|
||||
|
||||
def read_key(arg_value: str | None, file_value: str | None, key_name: str) -> str:
|
||||
if arg_value:
|
||||
return arg_value.strip()
|
||||
if not file_value:
|
||||
raise ValueError(f"Missing {key_name}")
|
||||
return coerce_key(read_text(file_value), key_name)
|
||||
|
||||
|
||||
def read_payload(args: argparse.Namespace):
|
||||
if args.payload_json:
|
||||
return json.loads(args.payload_json)
|
||||
if args.payload_file:
|
||||
return json.loads(read_text(args.payload_file))
|
||||
|
||||
stdin = sys.stdin.read().strip()
|
||||
if not stdin:
|
||||
raise ValueError("Provide --payload-json, --payload-file, or JSON on stdin")
|
||||
return json.loads(stdin)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = parse_args()
|
||||
|
||||
sender_private_b64 = read_key(args.sender_private_key, args.sender_private_key_file, "privateKey")
|
||||
recipient_public_b64 = read_key(args.recipient_public_key, args.recipient_public_key_file, "publicKey")
|
||||
payload = read_payload(args)
|
||||
|
||||
sender_private = PrivateKey(base64.b64decode(sender_private_b64))
|
||||
recipient_public = PublicKey(base64.b64decode(recipient_public_b64))
|
||||
|
||||
box = Box(sender_private, recipient_public)
|
||||
plaintext = json.dumps(payload, separators=(",", ":")).encode("utf-8")
|
||||
encrypted = box.encrypt(plaintext)
|
||||
print(base64.b64encode(bytes(encrypted)).decode("ascii"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user