Skip to content

Commit ce79680

Browse files
author
Aarushi Keshari
committed
fix: added missing vault-author-fix file, removed old auth UI and unused middleware
1 parent 1127b4f commit ce79680

4 files changed

Lines changed: 21 additions & 113 deletions

File tree

‎backend/app.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
validate_jwt_secret,
7373
is_production_mode
7474
)
75-
from middleware import require_strong_password # Issue #790
75+
7676
from collections import defaultdict, deque
7777
from math import ceil
7878
from time import time
@@ -1487,7 +1487,7 @@ def sync_library():
14871487
# =========================================================================
14881488
@app.route('/api/v1/register', methods=['POST'])
14891489
@limiter.limit("5 per minute")
1490-
@require_strong_password
1490+
14911491
def register():
14921492
"""Register a new user and return JWT token."""
14931493
try:

‎backend/middleware.py‎

Lines changed: 1 addition & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@
1212
DEFAULT_ALLOWED_CONTENT_TYPES,
1313
validate_content_type as _validate_content_type_header,
1414
)
15-
from .validators import validate_password_strength
1615
except ImportError:
1716
from error_responses import invalid_json_error
1817
from security_parsers import DEFAULT_ALLOWED_CONTENT_TYPES, validate_content_type as _validate_content_type_header
19-
from validators import validate_password_strength
18+
2019

2120
logger = logging.getLogger(__name__)
2221

@@ -181,80 +180,6 @@ def decorated_function(*args, **kwargs):
181180
return decorator
182181

183182

184-
# ─────────────────────────────────────────────────────────────────────────────
185-
# PASSWORD STRENGTH ENFORCEMENT (Issue #790)
186-
# ─────────────────────────────────────────────────────────────────────────────
187-
188-
def require_strong_password(f):
189-
"""
190-
Decorator that enforces strong password policy on any endpoint that
191-
receives a 'password' field in its JSON body (e.g. /api/v1/register).
192-
193-
This acts as a second layer of defence — RegisterRequest in validators.py
194-
already runs the same check via Pydantic. Having it here means the rule
195-
is enforced even if the route is called without the Pydantic schema, and
196-
it returns a consistent, descriptive 400 response before any business
197-
logic runs.
198-
199-
Usage:
200-
@app.route('/api/v1/register', methods=['POST'])
201-
@require_strong_password
202-
def register():
203-
...
204-
205-
Response on failure (HTTP 400):
206-
{
207-
"success": false,
208-
"error": "Password does not meet security requirements",
209-
"requirements": [
210-
"Minimum 8 characters required",
211-
"At least one uppercase letter (A–Z) required"
212-
]
213-
}
214-
"""
215-
@wraps(f)
216-
def decorated_function(*args, **kwargs):
217-
# Only check POST / PUT / PATCH — skip GET, HEAD, DELETE
218-
if request.method not in ('POST', 'PUT', 'PATCH'):
219-
return f(*args, **kwargs)
220-
221-
data = request.get_json(silent=True) or {}
222-
password = data.get('password', '')
223-
224-
if not password:
225-
logger.warning(
226-
f"[require_strong_password] Missing password field "
227-
f"on {request.method} {request.path} from {request.remote_addr}"
228-
)
229-
return jsonify({
230-
'success': False,
231-
'error': 'Password is required',
232-
'requirements': []
233-
}), 400
234-
235-
is_valid, errors = validate_password_strength(password)
236-
237-
if not is_valid:
238-
logger.warning(
239-
f"[require_strong_password] Weak password rejected "
240-
f"on {request.path} from {request.remote_addr} — "
241-
f"failed rules: {errors}"
242-
)
243-
return jsonify({
244-
'success': False,
245-
'error': 'Password does not meet security requirements',
246-
'requirements': errors
247-
}), 400
248-
249-
return f(*args, **kwargs)
250-
251-
return decorated_function
252-
253-
# ─────────────────────────────────────────────────────────────────────────────
254-
# END PASSWORD STRENGTH ENFORCEMENT
255-
# ─────────────────────────────────────────────────────────────────────────────
256-
257-
258183
def csrf_token_required(f):
259184
"""
260185
=============================================================================

‎frontend/js/vault-author-fix.js‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
document.addEventListener('DOMContentLoaded', () => {
2+
document.querySelectorAll('.vault-author, [data-author]').forEach(el => {
3+
if (el.textContent) el.textContent = el.textContent.trim();
4+
});
5+
});

‎frontend/pages/auth.html‎

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -424,31 +424,20 @@ <h2 id="authTitle">Welcome Back</h2>
424424
<i class="fa-solid fa-eye password-toggle-icon" id="togglePassword" title="Show Password"
425425
aria-label="Show password" role="button" tabindex="0"></i>
426426
</div>
427+
428+
<!-- PASSWORD STRENGTH UI -->
427429
<div class="password-strength-bar">
428-
<div id="strength-fill" class="strength-fill"></div>
429-
</div>
430-
431-
<p id="strength-label" class="strength-label"></p>
432-
433-
<ul class="pw-checklist" id="pw-checklist">
434-
<li id="chk-len">At least 8 characters</li>
435-
<li id="chk-up">One uppercase letter</li>
436-
<li id="chk-low">One lowercase letter</li>
437-
<li id="chk-num">One digit (0–9)</li>
438-
<li id="chk-spec">One special character</li>
439-
</ul>
440-
441-
<!--
442-
=============================================================
443-
SECURITY COMPLIANCE: CSRF TOKEN FIELD
444-
=============================================================
445-
This hidden input is dynamically populated with a one-time
446-
security token provided by the backend. It protects against
447-
Cross-Site Request Forgery attacks by ensuring that the
448-
form submission originated from this specific application
449-
instance.
450-
=============================================================
451-
-->
430+
<div id="strength-fill" class="strength-fill"></div>
431+
</div>
432+
<p id="strength-label" class="strength-label"></p>
433+
<ul class="pw-checklist" id="pw-checklist">
434+
<li id="chk-len">At least 8 characters</li>
435+
<li id="chk-up">One uppercase letter</li>
436+
<li id="chk-low">One lowercase letter</li>
437+
<li id="chk-num">One digit (0–9)</li>
438+
<li id="chk-spec">One special character</li>
439+
</ul>
440+
452441
<input type="hidden" id="csrf_token" name="csrf_token" value="">
453442

454443
<!-- Primary Action Button -->
@@ -524,7 +513,6 @@ <h3 style="color: var(--text-main) !important;">Ambient Sanctuary</h3>
524513
</div>
525514
</div>
526515

527-
528516
<script src="../js/config.js"></script>
529517
<script src="../js/footer.js"></script>
530518
<script src="../js/app.js"></script>
@@ -601,18 +589,8 @@ <h3 style="color: var(--text-main) !important;">Ambient Sanctuary</h3>
601589
</script>
602590
<script src="../js/pwa.js"></script>
603591
<script>
604-
/**
605-
* ==============================================================================
606-
* CSRF INITIALIZATION LOGIC
607-
* ==============================================================================
608-
* On document load, we query the backend's CSRF endpoint to retrieve a
609-
* fresh security token. This token is then stored in the hidden form
610-
* field and utilized in the 'handleAuth' submission headers.
611-
* ==============================================================================
612-
*/
613592
document.addEventListener('DOMContentLoaded', async () => {
614593
try {
615-
// We use MOOD_API_BASE from config.js
616594
const response = await fetch(`${MOOD_API_BASE}/csrf-token`, {
617595
method: 'GET',
618596
credentials: 'include'

0 commit comments

Comments
 (0)