Add feature to use Real name on journals

This commit is contained in:
2026-09-01 18:29:18 +03:00
parent 65bebd19c5
commit 8ad292c793
11 changed files with 89 additions and 13 deletions
+34 -6
View File
@@ -121,6 +121,7 @@ def init_db():
"mfa_enabled": "ALTER TABLE users ADD COLUMN mfa_enabled INTEGER NOT NULL DEFAULT 0",
"email": "ALTER TABLE users ADD COLUMN email TEXT",
"email_verified": "ALTER TABLE users ADD COLUMN email_verified INTEGER NOT NULL DEFAULT 0",
"real_name": "ALTER TABLE users ADD COLUMN real_name TEXT",
}
post_columns = {row["name"] for row in db.execute("PRAGMA table_info(posts)")}
for column, statement in migrations.items():
@@ -252,6 +253,14 @@ def valid_email(email):
return re.fullmatch(r"[^\s@]+@[^\s@]+\.[^\s@]+", email) is not None
def normalize_real_name(real_name):
return " ".join(real_name.split())
def valid_real_name(real_name):
return 2 <= len(real_name) <= 100 and all(character.isalnum() or character in " .'-" for character in real_name)
def create_reset_token(user_id):
token = token_urlsafe(32)
now = datetime.now(timezone.utc)
@@ -321,14 +330,14 @@ def send_verification_email(user, email_address, token_type):
def inject_current_user():
user = None
if "user_id" in session:
user = get_db().execute("SELECT id, username, role FROM users WHERE id = ?", (session["user_id"],)).fetchone()
user = get_db().execute("SELECT id, username, real_name, role FROM users WHERE id = ?", (session["user_id"],)).fetchone()
return {"current_user": user}
@app.route("/")
def index():
posts = get_db().execute(
"""SELECT posts.*, users.username FROM posts JOIN users ON users.id = posts.author_id
"""SELECT posts.*, users.username, users.real_name FROM posts JOIN users ON users.id = posts.author_id
ORDER BY posts.created_at DESC"""
).fetchall()
return render_template("index.html", posts=posts)
@@ -337,7 +346,7 @@ def index():
@app.route("/post/<slug>")
def post(slug):
article = get_db().execute(
"""SELECT posts.*, users.username FROM posts JOIN users ON users.id = posts.author_id
"""SELECT posts.*, users.username, users.real_name FROM posts JOIN users ON users.id = posts.author_id
WHERE posts.slug = ?""",
(slug,),
).fetchone()
@@ -356,10 +365,13 @@ def uploaded_image(filename):
def register():
if request.method == "POST":
username = request.form.get("username", "").strip().lower()
real_name = normalize_real_name(request.form.get("real_name", ""))
email = request.form.get("email", "").strip().lower()
password = request.form.get("password", "")
if not re.fullmatch(r"[a-z0-9_-]{3,32}", username):
flash("Use 3-32 lowercase letters, numbers, hyphens, or underscores.", "error")
elif not valid_real_name(real_name):
flash("Enter a real name using 2-100 letters, numbers, spaces, hyphens, apostrophes, or periods.", "error")
elif len(password) < 10:
flash("Choose a password with at least 10 characters.", "error")
elif not valid_email(email):
@@ -367,8 +379,8 @@ def register():
else:
try:
cursor = get_db().execute(
"INSERT INTO users (username, email, password_hash, created_at, is_approved) VALUES (?, ?, ?, ?, 0)",
(username, email, generate_password_hash(password), datetime.now(timezone.utc).isoformat()),
"INSERT INTO users (username, real_name, email, password_hash, created_at, is_approved) VALUES (?, ?, ?, ?, ?, 0)",
(username, real_name, email, generate_password_hash(password), datetime.now(timezone.utc).isoformat()),
)
get_db().commit()
user = {"id": cursor.lastrowid, "username": username}
@@ -509,6 +521,22 @@ def change_password():
return render_template("password_form.html", mode="change")
@app.route("/account/profile", methods=("GET", "POST"))
@login_required
def change_profile():
user = get_db().execute("SELECT real_name FROM users WHERE id = ?", (session["user_id"],)).fetchone()
if request.method == "POST":
real_name = normalize_real_name(request.form.get("real_name", ""))
if not valid_real_name(real_name):
flash("Enter a real name using 2-100 letters, numbers, spaces, hyphens, apostrophes, or periods.", "error")
else:
get_db().execute("UPDATE users SET real_name = ? WHERE id = ?", (real_name, session["user_id"]))
get_db().commit()
flash("Profile updated.", "success")
return redirect(url_for("index"))
return render_template("profile_form.html", real_name=user["real_name"] or "")
@app.route("/account/email", methods=("GET", "POST"))
@login_required
def change_email():
@@ -599,7 +627,7 @@ def mfa_verify():
@admin_required
def admin_users():
users = get_db().execute(
"SELECT id, username, email, email_verified, created_at, is_approved, mfa_enabled, role FROM users ORDER BY is_approved, created_at DESC"
"SELECT id, username, real_name, email, email_verified, created_at, is_approved, mfa_enabled, role FROM users ORDER BY is_approved, created_at DESC"
).fetchall()
return render_template("admin_users.html", users=users)