diff --git a/app/controllers/auth_controller.py b/app/controllers/auth_controller.py index d6aeb97..161ba07 100644 --- a/app/controllers/auth_controller.py +++ b/app/controllers/auth_controller.py @@ -3,6 +3,7 @@ from flask_login import login_user, logout_user from app.models.users import User from datetime import datetime, timedelta from app.models import db +import re import sys @@ -42,4 +43,41 @@ def login(): def logout(): logout_user() flash('You have been logged out.', 'info') + return redirect(url_for('main.login_route')) + +def signup(): + username = request.form.get('username') + email = request.form.get('email') + password = request.form.get('password') + + # Server-side validation + if len(username) < 5: + flash('Username must be at least 5 characters long', 'danger') + return redirect(url_for('main.login_route')) + + email_regex = r'^[a-zA-Z][a-zA-Z0-9._-]*@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' + if not re.match(email_regex, email): + flash('Please enter a valid email address', 'danger') + return redirect(url_for('main.login_route')) + + password_regex = r'^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{8,}$' + if not re.match(password_regex, password): + flash('Password must be at least 8 characters long and contain a number and a special character', 'danger') + return redirect(url_for('main.login_route')) + + # Check if username or email already exists + if User.query.filter_by(username=username).first(): + flash('Username already exists', 'danger') + return redirect(url_for('main.login_route')) + + if User.query.filter_by(email=email).first(): + flash('Email already exists', 'danger') + return redirect(url_for('main.login_route')) + + # Create new user + new_user = User(username=username, email=email, password=password) + db.session.add(new_user) + db.session.commit() + + flash('Account created successfully! Please login.', 'success') return redirect(url_for('main.login_route')) \ No newline at end of file diff --git a/app/models/users.py b/app/models/users.py index e6f65b1..4c2ede1 100644 --- a/app/models/users.py +++ b/app/models/users.py @@ -7,4 +7,5 @@ class User(db.Model, UserMixin): username = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) password = db.Column(db.String(120), nullable=False) - + failed_login_attempts = db.Column(db.Integer, default=0, nullable=False) + last_failed_login_attempt = db.Column(db.DateTime, default=None, nullable=True) diff --git a/app/routes.py b/app/routes.py index b2154fc..0f4e3f6 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,8 +1,9 @@ from flask import Blueprint from flask_login import login_required -from app.controllers.auth_controller import login, logout +from app.controllers.auth_controller import login, logout, signup from app.controllers.home_controller import home + main = Blueprint('main', __name__) @main.route('/') @@ -16,4 +17,8 @@ def login_route(): @main.route('/logout') @login_required def logout_route(): - return logout() \ No newline at end of file + return logout() + +@main.route('/signup', methods=['POST']) +def signup_route(): + return signup() \ No newline at end of file diff --git a/app/views/login.html b/app/views/login.html index fbbdfe0..2410a38 100644 --- a/app/views/login.html +++ b/app/views/login.html @@ -50,8 +50,8 @@ border: 1px solid #D9D9D9; border-radius: 6px; background-color: #D9D9D9; - color: white; - font-size: 16px; + color: rgb(0, 0, 0); + font-size: 20px; box-sizing: border-box; } @@ -81,19 +81,6 @@ letter-spacing: 3px; } - - - @media (max-width: 768px) { - .login-container { - width: 95%; - padding: 20px; - } - } - - .error-message p { - color: red; - } - .signup-container { display: flex; justify-content: center; @@ -105,6 +92,19 @@ color: #8f8f8f; margin-top: 14px; align-items: center; + cursor: pointer; + } + + .signup u:hover { + color: #fff; + } + + .hidden { + display: none; + } + + .error-message p { + color: red; } {% endblock %} @@ -112,30 +112,57 @@ {% block content %}
-
- -
-

Login

- + +
+

Login

+ -
-
- - + +
+ + +
+ +
+ + +
+ + + + - -
- - -
- - - - + + {% with messages = get_flashed_messages() %} {% if messages %} @@ -148,4 +175,61 @@ {% endwith %}
+ + {% endblock %} \ No newline at end of file