fuck you i aint commiting with actual messages

This commit is contained in:
i-am-called-glitchy 2025-06-03 12:51:30 +00:00
parent af461666f2
commit 2616417011
3 changed files with 49 additions and 10 deletions

38
app.py
View file

@ -5,16 +5,28 @@ import os
import hashlib import hashlib
import base64 import base64
import dotenv import dotenv
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
import time
dotenv.load_dotenv() dotenv.load_dotenv()
app = Flask(__name__) app = Flask(__name__)
app.secret_key = os.getenv("SECRET") app.secret_key = os.getenv("SECRET")
USERS_FILE = "users.txt" USERS_FILE = "users.txt"
DATA_DIR = "notes" DATA_DIR = "notes"
os.makedirs(DATA_DIR, exist_ok=True) os.makedirs(DATA_DIR, exist_ok=True)
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 # 16 KB
limiter = Limiter(key_func=get_remote_address)
limiter.init_app(app)
@app.errorhandler(413)
def payload_too_large(e):
return "someone call caseoh, he's got competition — I think his number is 413?", 413
# === UTILS === # === UTILS ===
@ -37,6 +49,7 @@ def get_key_for_user(user, password):
# === ROUTES === # === ROUTES ===
@app.route("/api/<note>", methods=["GET", "POST"]) @app.route("/api/<note>", methods=["GET", "POST"])
@limiter.limit("100 per hour", per_method=True, key_func=get_remote_address)
def api(note): def api(note):
user = get_user() user = get_user()
key = session.get("key") key = session.get("key")
@ -49,22 +62,35 @@ def api(note):
if request.method == "GET": if request.method == "GET":
if not os.path.exists(path): if not os.path.exists(path):
return "", 200 return "", 200
with open(path, "rb") as f: try:
try: with open(path, "rb") as f:
return fernet.decrypt(f.read()).decode(), 200 return fernet.decrypt(f.read()).decode(), 200
except Exception: except Exception:
return "Corrupted note or invalid key", 500 return "Corrupted note or invalid key", 500
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = request.get_json()
if not data or "content" not in data: if not data or "content" not in data:
return "Bad request", 400 return "Bad request", 400
# Check if this is a new note
is_new = not os.path.exists(path)
if is_new:
now = time.time()
record = session.setdefault("note_creations", [])
# Clean up old timestamps
record = [t for t in record if now - t < 3600]
if len(record) >= 10:
return "Slow down, Picasso — max 10 new notes per hour", 429
record.append(now)
session["note_creations"] = record
ciphertext = fernet.encrypt(data["content"].encode()) ciphertext = fernet.encrypt(data["content"].encode())
with open(path, "wb") as f: with open(path, "wb") as f:
f.write(ciphertext) f.write(ciphertext)
return jsonify({"status": "saved"}) return jsonify({"status": "saved"})
@app.route("/n/<note>") @app.route("/n/<note>")
@app.route("/notes/<note>") @app.route("/notes/<note>")
def serve_note(note): def serve_note(note):

View file

@ -1,11 +1,19 @@
const textarea = document.getElementById("editor"); const textarea = document.getElementById("editor");
const status = document.getElementById("status"); const status = document.getElementById("status");
const error = document.getElementById("error");
fetch("/api/" + noteName) fetch("/api/" + noteName)
.then(res => res.ok ? res.text() : "") .then(res => {
if (!res.ok) throw new Error("Failed to load note. Status: " + res.status);
return res.text();
})
.then(text => { .then(text => {
textarea.value = text; textarea.value = text;
status.textContent = "Loaded"; status.textContent = "Loaded";
})
.catch(err => {
error.textContent = "Error loading note: " + err.message;
status.textContent = "Load failed";
}); });
let timeout; let timeout;
@ -21,17 +29,21 @@ textarea.addEventListener("input", () => {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ content: text }) body: JSON.stringify({ content: text })
}).then(res => { })
.then(async res => {
if (res.ok) { if (res.ok) {
last = text; last = text;
status.textContent = "Saved"; status.textContent = "Saved";
} else { } else {
status.textContent = "Save failed"; const msg = await res.text();
status.textContent = "Save failed: " + msg;
} }
})
.catch(err => {
status.textContent = "Save failed: " + err.message;
}); });
} else { } else {
status.textContent = "No changes"; status.textContent = "No changes";
} }
}, 500); }, 500);
}); });

View file

@ -9,6 +9,7 @@
</style> </style>
</head> </head>
<body> <body>
<div id="error"></div>
<textarea id="editor" placeholder="Type here!"></textarea> <textarea id="editor" placeholder="Type here!"></textarea>
<div id="status">Loading...</div> <div id="status">Loading...</div>
<script> <script>