A social pastebin built on atproto.
1import json
2import os
3import time
4from pathlib import Path
5
6from authlib.jose import JsonWebKey
7from flask import Flask
8
9
10def _generate_flask_secret() -> str:
11 return os.urandom(32).hex()
12
13
14def _generate_client_jwk() -> str:
15 key = JsonWebKey.generate_key("EC", "P-256", is_private=True)
16 key_dict = json.loads(key.as_json(is_private=True))
17 key_dict["kid"] = f"morsel-{int(time.time())}"
18 return json.dumps(key_dict)
19
20
21def load_config(app: Flask, data_dir: str = ".") -> None:
22 """Load or generate config. Persists secrets to a file so they survive restarts."""
23 secrets_path = Path(data_dir) / "secrets.json"
24
25 if secrets_path.exists():
26 secrets = json.loads(secrets_path.read_text())
27 else:
28 secrets = {
29 "flask_secret_key": _generate_flask_secret(),
30 "client_secret_jwk": _generate_client_jwk(),
31 }
32 secrets_path.write_text(json.dumps(secrets, indent=2))
33 print(f"Generated new secrets at {secrets_path}")
34
35 app.secret_key = secrets["flask_secret_key"]
36 app.config["CLIENT_SECRET_JWK"] = secrets["client_secret_jwk"]