diff --git a/requirements.txt b/requirements.txt
index d185f9d..9524e22 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,3 +2,4 @@ Flask
Flask-SQLAlchemy
SQLAlchemy
PyMySQL
+python-gnupg
diff --git a/src/main.py b/src/main.py
index 2f7d027..0b0a06c 100644
--- a/src/main.py
+++ b/src/main.py
@@ -1,11 +1,16 @@
-from flask import Flask, render_template
+from flask import Flask, render_template, request, redirect, url_for, flash, session
from flask_sqlalchemy import SQLAlchemy
from datetime import date
+import gnupg
+import secrets
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://love:love@localhost:3309/lovedb'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
+app.config['SECRET_KEY'] = 'random'
+
+gpg = gnupg.GPG()
db = SQLAlchemy(app)
@@ -13,7 +18,7 @@ class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(128), unique=True, nullable=False)
- password = db.Column(db.String(128), nullable=False)
+ pgp = db.Column(db.String(4096), nullable=False)
firstname = db.Column(db.String(128), nullable=False)
lastname = db.Column(db.String(128), nullable=False)
@@ -47,14 +52,175 @@ class User(db.Model):
def home():
return render_template("index.html")
-@app.route("/register")
+@app.route("/register", methods=["GET", "POST"])
def register():
+ if request.method == "POST":
+
+ username = request.form.get("username")
+ pgp = request.form.get("pgp")
+ firstname = request.form.get("firstname")
+ lastname = request.form.get("lastname")
+ sex = request.form.get("sex")
+ date_of_birth = request.form.get("date_of_birth")
+ profile_picture = request.form.get("profile_picture")
+ country = request.form.get("country")
+ xmpp = request.form.get("xmpp")
+
+ email = request.form.get("email")
+ phone = request.form.get("phone")
+ city = request.form.get("city")
+ height = request.form.get("height")
+ weight = request.form.get("weight")
+ race = request.form.get("race")
+ prefered_age_range = request.form.get("prefered_age_range")
+
+ if not all([username, pgp, firstname, lastname, sex,
+ date_of_birth, profile_picture, country, xmpp]):
+ flash("Please fill all required fields.")
+ return redirect(url_for("register"))
+
+ if User.query.filter_by(username=username).first():
+ flash("Username already exists.")
+ return redirect(url_for("register"))
+
+ if User.query.filter_by(xmpp=xmpp).first():
+ flash("XMPP already exists.")
+ return redirect(url_for("register"))
+
+ if email and User.query.filter_by(email=email).first():
+ flash("Email already exists.")
+ return redirect(url_for("register"))
+
+ if phone and User.query.filter_by(phone=phone).first():
+ flash("Phone already exists.")
+ return redirect(url_for("register"))
+
+ try:
+ dob = date.fromisoformat(date_of_birth)
+ except ValueError:
+ flash("Invalid date format.")
+ return redirect(url_for("register"))
+
+ today = date.today()
+ age = today.year - dob.year - ((today.month, today.day) < (dob.month, dob.day))
+ if age < 18:
+ flash("You must be at least 18 years old to register.")
+ return redirect(url_for("register"))
+
+ session["pending_user"] = {
+ "username": username,
+ "pgp": pgp,
+ "firstname": firstname,
+ "lastname": lastname,
+ "sex": sex,
+ "date_of_birth": date_of_birth,
+ "profile_picture": profile_picture,
+ "country": country,
+ "xmpp": xmpp,
+ "email": email,
+ "phone": phone,
+ "city": city,
+ "height": height,
+ "weight": weight,
+ "race": race,
+ "prefered_age_range": prefered_age_range
+ }
+
+ import_result = gpg.import_keys(pgp)
+ if not import_result.fingerprints:
+ flash("Invalid PGP key. Make sure you pasted the full ASCII-armored public key.")
+ return redirect(url_for("register"))
+
+ fingerprint = import_result.fingerprints[0]
+
+ random_string = secrets.token_hex(16)
+ challenge_phrase = f"this is the unencrypted string: {random_string}"
+
+ encrypted_data = gpg.encrypt(
+ challenge_phrase,
+ recipients=[fingerprint]
+ )
+
+ if not encrypted_data.ok:
+ flash("Failed to encrypt challenge. Check your PGP key.")
+ return redirect(url_for("register"))
+
+ session["pgp_expected_phrase"] = challenge_phrase
+
+ return render_template(
+ "verify.html",
+ encrypted_message=str(encrypted_data)
+ )
+
return render_template("register.html")
+@app.route("/verify", methods=["POST"])
+def verify():
+
+ expected_phrase = session.get("pgp_expected_phrase")
+ data = session.get("pending_user")
+
+ if not expected_phrase or not data:
+ flash("Verification session expired.")
+ return redirect(url_for("register"))
+
+ submitted = request.form.get("decrypted_message")
+
+ if not submitted:
+ flash("You must paste the decrypted message.")
+ return redirect(url_for("register"))
+
+ if submitted.strip() != expected_phrase:
+ flash("Verification failed.")
+ return redirect(url_for("register"))
+
+ dob = date.fromisoformat(data["date_of_birth"])
+
+ new_user = User(
+ username=data["username"],
+ pgp=data["pgp"],
+ firstname=data["firstname"],
+ lastname=data["lastname"],
+ sex=data["sex"],
+ date_of_birth=dob,
+ profile_picture=data["profile_picture"],
+ country=data["country"],
+ xmpp=data["xmpp"],
+ email=data["email"] or None,
+ phone=data["phone"] or None,
+ city=data["city"] or None,
+ height=float(data["height"]) if data["height"] else None,
+ weight=int(data["weight"]) if data["weight"] else None,
+ race=data["race"] or None,
+ prefered_age_range=data["prefered_age_range"] or None,
+ is_verified=True
+ )
+
+ db.session.add(new_user)
+ db.session.commit()
+
+ # Clear session
+ session.pop("pending_user", None)
+ session.pop("pgp_expected_phrase", None)
+
+ flash("PGP verification successful!")
+
+ session['user_id'] = user.id
+ session['username'] = user.username
+
+ return redirect(url_for("login"))
+
@app.route("/login")
def login():
return render_template("login.html")
+@app.route("/logout")
+def logout():
+ session.pop('user_id', None)
+ session.pop('username', None)
+ flash("Logged out successfully")
+ return redirect(url_for("home"))
+
if __name__ == "__main__":
with app.app_context():
db.create_all()
diff --git a/src/templates/page.html b/src/templates/page.html
index 20cb983..0f95a01 100644
--- a/src/templates/page.html
+++ b/src/templates/page.html
@@ -5,7 +5,19 @@
Dating Website
Page text
-Page text
-Page text
-Page text
-Page text
-Page text
-Page text
-Page text
-Page text
-Page text
+Decrypt the message below using your private key and paste the result.
+ + + + + +{% endblock %}