qecho / qecho.py
valent-p's picture
feat: Add secure message storage and retrieval via Supabase with burn and retrieval limit options.
2d68192
Raw History Blame Contribute Delete
4.01 kB
import argparse
import requests
import sys
import json
from datetime import datetime
# ==========================================
# CONFIGURATION
# ==========================================
API_URL = "https://valent-p-qecho.hf.space"
# ==========================================
def print_error(msg):
print(f"[-] ERROR: {msg}")
def print_success(msg):
print(f"[+] {msg}")
def print_info(msg):
print(f"[*] {msg}")
def cmd_send(args):
payload = {
"group_name": args.group,
"password": args.key,
"data": args.msg
}
try:
print_info(f"Encrypting and sending to channel '{args.group}'...")
response = requests.post(f"{API_URL}/store", json=payload)
if response.status_code == 200:
data = response.json()
print_success(f"Transmission Complete.")
print(f" ID: {data.get('uuid')}")
else:
print_error(f"Server returned {response.status_code}")
print(response.text)
except requests.exceptions.ConnectionError:
print_error("Could not connect to server. Check your API_URL.")
def cmd_get(args):
payload = {
"group_name": args.group,
"password": args.key,
"password": args.key,
"burn": args.burn,
"limit": args.limit
}
try:
print_info(f"Authenticating with Twin-Key for '{args.group}'...")
response = requests.post(f"{API_URL}/retrieve", json=payload)
if response.status_code == 200:
data = response.json()
messages = data.get("messages", [])
if not messages:
print(" [!] No messages found (or invalid credentials).")
return
print_success(f"Retrieved {len(messages)} record(s):\n")
for msg in messages:
# Handle system messages (like "Burned X messages")
if 'system_info' in msg:
print(f" >>> SYSTEM: {msg['system_info']}")
continue
# Handle standard messages
ts = msg.get('timestamp', 'Unknown Time')
content = msg.get('content', '')
msg_id = msg.get('id', '')
print(f" [{ts}] ID: {msg_id[:8]}...")
print(f" DATA: {content}")
print("-" * 40)
if args.burn:
print_info("Burn sequence complete. Data destroyed on server.")
else:
print_error(f"Server returned {response.status_code}")
print(response.text)
except requests.exceptions.ConnectionError:
print_error("Could not connect to server. Check your API_URL.")
def main():
parser = argparse.ArgumentParser(description="QEcho: Zero-Knowledge Dead Drop Interface")
subparsers = parser.add_subparsers(dest="command", required=True)
# --- SEND COMMAND ---
send_parser = subparsers.add_parser("send", help="Encrypt and upload data")
send_parser.add_argument("--group", required=True, help="Channel/Topic Name")
send_parser.add_argument("--key", required=True, help="Secret Password")
send_parser.add_argument("--msg", required=True, help="The data/message to store")
# --- GET COMMAND ---
get_parser = subparsers.add_parser("get", help="Retrieve and decrypt data")
get_parser.add_argument("--group", required=True, help="Channel/Topic Name")
get_parser.add_argument("--key", required=True, help="Secret Password")
get_parser.add_argument("--limit", type=int, default=100, help="Max number of messages to retrieve")
get_parser.add_argument("--burn", action="store_true", help="Delete messages from server after reading")
args = parser.parse_args()
if args.command == "send":
cmd_send(args)
elif args.command == "get":
cmd_get(args)
if __name__ == "__main__":
main()