diff --git a/__init__.py b/__init__.py index 754a728..96b6b3c 100644 --- a/__init__.py +++ b/__init__.py @@ -54,12 +54,10 @@ def load(app): # Rate Limiting last_sub = Submissions.query.filter_by(user_id=user.id).order_by(Submissions.date.desc()).first() if last_sub and (time.time() - last_sub.date.timestamp() < cooldown): - return jsonify({'success': False, 'message': f'Wait {cooldown}s between tries'}) + return jsonify({'success': False, 'message': f'Wait {cooldown}s'}) - # Optimized Solve Check (Unified User/Team Mode) + # Find unsolved challenges solve_filter = (Solves.team_id == team.id) if team else (Solves.user_id == user.id) - - # Only query unsolved challenges in the specific category challenges = Challenges.query.filter( Challenges.category == category, Challenges.state == 'visible', @@ -69,22 +67,21 @@ def load(app): for chall in challenges: for flag in Flags.query.filter_by(challenge_id=chall.id).all(): try: - # Supports Static, Regex, and Case-Insensitive flags via CTFd internal classes if get_flag_class(flag.type).compare(flag, provided_flag): - solve = Solves( - user_id=user.id, team_id=team.id if team else None, - challenge_id=chall.id, ip=request.remote_addr, provided=provided_flag - ) - db.session.add(solve) - db.session.add(Submissions( - user_id=user.id, team_id=team.id if team else None, - challenge_id=chall.id, ip=request.remote_addr, provided=provided_flag, type='correct' - )) + # USE NATIVE CTFd SOLVE LOGIC + # This handles Solves, Submissions, and Scoreboard updates correctly. + chal_class = get_chal_class(chall.type) + chal_class.solve(user=user, team=team, challenge=chall, request=request) + db.session.commit() - return jsonify({'success': True, 'message': f'Correct: {chall.name}'}) + return jsonify({ + 'success': True, + 'message': f'Correct! You solved: {chall.name}', + 'challenge_id': chall.id # Pass this back to help the JS + }) except Exception: continue - # Record failed attempt for audit/brute-force detection + # Log incorrect submission natively db.session.add(Submissions( user_id=user.id, team_id=team.id if team else None, challenge_id=None, ip=request.remote_addr, provided=provided_flag, type='incorrect' diff --git a/assets/category_submit.js b/assets/category_submit.js index 9ecdb2b..c30c1bd 100644 --- a/assets/category_submit.js +++ b/assets/category_submit.js @@ -1,52 +1,44 @@ (function() { if (window.location.pathname !== '/challenges') return; - function injectSubmissionBoxes(config) { + function injectBoxes(config) { const enabledCategories = config.categories || []; - const headers = document.querySelectorAll('.category-header'); - - headers.forEach(header => { + document.querySelectorAll('.category-header').forEach(header => { const catName = header.textContent.trim(); - const alreadyInjected = header.nextElementSibling && - header.nextElementSibling.classList.contains('cat-sub-row'); - - if (enabledCategories.includes(catName) && !alreadyInjected) { - // Create a row container to match CTFd's grid layout + if (enabledCategories.includes(catName) && !header.nextElementSibling.classList.contains('cat-sub-row')) { const row = document.createElement('div'); row.className = "cat-sub-row row mb-4 justify-content-center"; - - // Use col-md-8 or 10 to keep the box from being too wide row.innerHTML = `