Add feature to use Real name on journals
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user