feat: Implement user validation and ownership checks for image, reward, and task APIs
All checks were successful
Gitea Actions Demo / build-and-push (push) Successful in 36s

- Added `get_validated_user_id` utility function to validate user authentication across multiple APIs.
- Updated image upload, request, and listing endpoints to ensure user ownership and proper error handling.
- Enhanced reward management endpoints to include user validation and ownership checks.
- Modified task management endpoints to enforce user authentication and ownership verification.
- Updated models to include `user_id` for images, rewards, tasks, and children to track ownership.
- Implemented frontend changes to ensure UI reflects the ownership of tasks and rewards.
- Added a new feature specification to prevent deletion of system tasks and rewards.
This commit is contained in:
2026-01-31 19:48:51 -05:00
parent 6f5b61de7f
commit f14de28daa
18 changed files with 361 additions and 121 deletions

View File

@@ -100,7 +100,7 @@ def verify():
if not user.email:
logger.error("Verified user has no email field.")
else:
user_image_dir = get_user_image_dir(sanitize_email(user.email))
user_image_dir = get_user_image_dir(user.id)
os.makedirs(user_image_dir, exist_ok=True)
return jsonify({'status': status, 'reason': reason, 'code': code}), http_status
@@ -148,6 +148,7 @@ def login():
payload = {
'email': norm_email,
'user_id': user.id,
'exp': datetime.utcnow() + timedelta(hours=24*7)
}
token = jwt.encode(payload, current_app.config['SECRET_KEY'], algorithm='HS256')
@@ -164,14 +165,14 @@ def me():
try:
payload = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=['HS256'])
email = payload.get('email')
user_dict = users_db.get(UserQuery.email == email)
user_id = payload.get('user_id', '')
user_dict = users_db.get(UserQuery.id == user_id)
user = User.from_dict(user_dict) if user_dict else None
if not user:
return jsonify({'error': 'User not found', 'code': USER_NOT_FOUND}), 404
return jsonify({
'email': user.email,
'id': sanitize_email(user.email),
'id': user_id,
'first_name': user.first_name,
'last_name': user.last_name,
'verified': user.verified
@@ -253,3 +254,10 @@ def reset_password():
users_db.update(user.to_dict(), UserQuery.email == user.email)
return jsonify({'message': 'Password has been reset'}), 200
@auth_api.route('/logout', methods=['POST'])
def logout():
resp = jsonify({'message': 'Logged out'})
# Remove the token cookie by setting it to empty and expiring it
resp.set_cookie('token', '', expires=0, httponly=True, secure=True, samesite='Strict')
return resp, 200