From 67b1f11d774571b7996329bee9f435beb7c4b73a Mon Sep 17 00:00:00 2001 From: Archil Date: Wed, 16 Jul 2025 17:21:02 +0530 Subject: [PATCH 1/2] Added user registration endpoint with validations and JWT token --- backend/app.py | 6 +++--- backend/models/transaction.py | 20 ++++++++++++++++++++ backend/models/user.py | 5 +++-- backend/routes/auth.py | 31 ++++++++++++++++++++++++++----- run.py | 4 +++- 5 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 backend/models/transaction.py diff --git a/backend/app.py b/backend/app.py index 892d585..83c00db 100644 --- a/backend/app.py +++ b/backend/app.py @@ -3,6 +3,7 @@ from flask_jwt_extended import JWTManager from flask_cors import CORS from backend.database import db, migrate +from backend.routes.auth import auth_bp def create_app(config_class): app = Flask(__name__, @@ -26,9 +27,8 @@ def index(): def api_status(): return jsonify({'message': 'API is working', 'status': 'success'}), 200 - # Register blueprints - from backend.routes.auth import auth_bp - + + app.register_blueprint(auth_bp, url_prefix='/api/auth') diff --git a/backend/models/transaction.py b/backend/models/transaction.py new file mode 100644 index 0000000..3d75d91 --- /dev/null +++ b/backend/models/transaction.py @@ -0,0 +1,20 @@ +from backend.database import db +from datetime import datetime + +class Transaction(db.Model): + __tablename__ = 'transactions' + + id = db.Column(db.Integer, primary_key=True) + amount = db.Column(db.Float, nullable=False) + description = db.Column(db.String(255)) + user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) + created_at = db.Column(db.DateTime, default=datetime.utcnow) + + def to_dict(self): + return { + 'id': self.id, + 'amount': self.amount, + 'description': self.description, + 'user_id': self.user_id, + 'created_at': self.created_at.isoformat() + } diff --git a/backend/models/user.py b/backend/models/user.py index 97ae7fe..ea15b34 100644 --- a/backend/models/user.py +++ b/backend/models/user.py @@ -1,5 +1,6 @@ from backend.database import db from werkzeug.security import generate_password_hash, check_password_hash +from backend.models.transaction import Transaction from datetime import datetime class User(db.Model): @@ -13,8 +14,8 @@ class User(db.Model): # Relationships transactions = db.relationship('Transaction', backref='user', lazy=True, cascade='all, delete-orphan') - categories = db.relationship('Category', backref='user', lazy=True, cascade='all, delete-orphan') - budgets = db.relationship('Budget', backref='user', lazy=True, cascade='all, delete-orphan') + # categories = db.relationship('Category', backref='user', lazy=True, cascade='all, delete-orphan') + # budgets = db.relationship('Budget', backref='user', lazy=True, cascade='all, delete-orphan') def set_password(self, password): self.password_hash = generate_password_hash(password) diff --git a/backend/routes/auth.py b/backend/routes/auth.py index 54bbfa1..f874058 100644 --- a/backend/routes/auth.py +++ b/backend/routes/auth.py @@ -2,17 +2,33 @@ from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity from backend.models.user import User from backend.database import db +from werkzeug.security import generate_password_hash +import re auth_bp = Blueprint('auth', __name__) +def is_password_strong(password): + return len(password) >= 6 @auth_bp.route('/register', methods=['POST']) def register(): data = request.get_json() - + + username = data.get('username') + email = data.get('email') + password = data.get('password') # Validate input if not data.get('username') or not data.get('email') or not data.get('password'): return jsonify({'error': 'Missing required fields'}), 400 + # Check the format of email + if not re.match(r"[^@]+@[^@]+\.[^@]+", email): + return jsonify({'error': "Invalid Email format"}), 400 + + # check if password is strong or not + if not is_password_strong(password): + return jsonify({'error': 'Password too weak (min 6 char)'}), 400 + + # Check if user exists if User.query.filter_by(email=data['email']).first(): return jsonify({'error': 'Email already registered'}), 400 @@ -20,15 +36,20 @@ def register(): if User.query.filter_by(username=data['username']).first(): return jsonify({'error': 'Username already taken'}), 400 - # Create new user - user = User(username=data['username'], email=data['email']) - user.set_password(data['password']) + user = User(username=username, email=email) + user.set_password(password) + + # hashing the password + + + + db.session.add(user) db.session.commit() # Create access token - access_token = create_access_token(identity=user.id) + access_token = create_access_token(identity= user.id) return jsonify({ 'message': 'User created successfully', diff --git a/run.py b/run.py index 9949b55..514054f 100644 --- a/run.py +++ b/run.py @@ -1,8 +1,10 @@ from backend.app import create_app from config import config +from backend.routes.auth import auth_bp import os if __name__ == '__main__': config_name = os.environ.get('FLASK_ENV') or 'default' app = create_app(config[config_name]) - app.run(host='0.0.0.0', port=4000, debug=True) + app.run(host='0.0.0.0', port=7000, debug=True) + app.register_blueprint(auth_bp) \ No newline at end of file From 02853eed7cf98af6e4dcb85e286e591fd7681217 Mon Sep 17 00:00:00 2001 From: Archil Date: Thu, 17 Jul 2025 12:17:35 +0530 Subject: [PATCH 2/2] fixed the changes which are requested --- backend/models/transaction.py | 20 -------------------- backend/models/user.py | 5 ++--- backend/routes/auth.py | 6 ------ run.py | 2 +- 4 files changed, 3 insertions(+), 30 deletions(-) delete mode 100644 backend/models/transaction.py diff --git a/backend/models/transaction.py b/backend/models/transaction.py deleted file mode 100644 index 3d75d91..0000000 --- a/backend/models/transaction.py +++ /dev/null @@ -1,20 +0,0 @@ -from backend.database import db -from datetime import datetime - -class Transaction(db.Model): - __tablename__ = 'transactions' - - id = db.Column(db.Integer, primary_key=True) - amount = db.Column(db.Float, nullable=False) - description = db.Column(db.String(255)) - user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) - created_at = db.Column(db.DateTime, default=datetime.utcnow) - - def to_dict(self): - return { - 'id': self.id, - 'amount': self.amount, - 'description': self.description, - 'user_id': self.user_id, - 'created_at': self.created_at.isoformat() - } diff --git a/backend/models/user.py b/backend/models/user.py index ea15b34..97ae7fe 100644 --- a/backend/models/user.py +++ b/backend/models/user.py @@ -1,6 +1,5 @@ from backend.database import db from werkzeug.security import generate_password_hash, check_password_hash -from backend.models.transaction import Transaction from datetime import datetime class User(db.Model): @@ -14,8 +13,8 @@ class User(db.Model): # Relationships transactions = db.relationship('Transaction', backref='user', lazy=True, cascade='all, delete-orphan') - # categories = db.relationship('Category', backref='user', lazy=True, cascade='all, delete-orphan') - # budgets = db.relationship('Budget', backref='user', lazy=True, cascade='all, delete-orphan') + categories = db.relationship('Category', backref='user', lazy=True, cascade='all, delete-orphan') + budgets = db.relationship('Budget', backref='user', lazy=True, cascade='all, delete-orphan') def set_password(self, password): self.password_hash = generate_password_hash(password) diff --git a/backend/routes/auth.py b/backend/routes/auth.py index f874058..016ad4d 100644 --- a/backend/routes/auth.py +++ b/backend/routes/auth.py @@ -2,7 +2,6 @@ from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity from backend.models.user import User from backend.database import db -from werkzeug.security import generate_password_hash import re auth_bp = Blueprint('auth', __name__) @@ -39,12 +38,7 @@ def register(): user = User(username=username, email=email) user.set_password(password) - - # hashing the password - - - db.session.add(user) db.session.commit() diff --git a/run.py b/run.py index 514054f..d4d7953 100644 --- a/run.py +++ b/run.py @@ -6,5 +6,5 @@ if __name__ == '__main__': config_name = os.environ.get('FLASK_ENV') or 'default' app = create_app(config[config_name]) - app.run(host='0.0.0.0', port=7000, debug=True) + app.run(host='0.0.0.0', port=4000, debug=True) app.register_blueprint(auth_bp) \ No newline at end of file