@@ -1936,144 +1936,7 @@ def check_auth(payload=None):
19361936 return jsonify ({"success" : True , "message" : "Authentication check successful" }), 200
19371937
19381938
1939- # --------------------------
1940- # Remember Me Validation endpoint
1941- # --------------------------
1942- @app .route ("/auth/validate-remember" , methods = ["POST" ])
1943- @validate_request (
1944- operation_id = "validate_remember" ,
1945- summary = "Validate Remember Me Token" ,
1946- description = "Validate a persistent Remember Me token against stored hash. Called from login page (no auth required)." ,
1947- request_model = ValidateRememberRequest ,
1948- response_model = ValidateRememberResponse ,
1949- tags = ["auth" ],
1950- auth_callable = None # No auth required - used on login page
1951- )
1952- def validate_remember (payload = None ):
1953- """
1954- Validate a Remember Me token from persistent cookie.
1955-
1956- Security: Uses timing-safe hash comparison to prevent timing attacks.
1957- Token format: hex-encoded 32 random bytes (64 chars) from bin2hex(random_bytes(32))
1958- """
1959- try :
1960- # Extract token from request
1961- data = request .get_json () or {}
1962- token = data .get ("token" )
1963-
1964- if not token :
1965- mylog ("verbose" , ["[auth/validate-remember] Missing token in request" ])
1966- return jsonify ({
1967- "success" : True ,
1968- "valid" : False ,
1969- "message" : "Token validation failed: missing token"
1970- }), 200
1971-
1972- # Validate token against stored hash
1973- params_instance = ParametersInstance ()
1974- result = params_instance .validate_token (token )
1975-
1976- if result ['valid' ]:
1977- mylog ("verbose" , ["[auth/validate-remember] Token validation successful" ])
1978- return jsonify ({
1979- "success" : True ,
1980- "valid" : True ,
1981- "message" : "Token validation successful"
1982- }), 200
1983- else :
1984- mylog ("verbose" , ["[auth/validate-remember] Token validation failed" ])
1985- return jsonify ({
1986- "success" : True ,
1987- "valid" : False ,
1988- "message" : "Token validation failed"
1989- }), 200
1990-
1991- except Exception as e :
1992- mylog ("verbose" , [f"[auth/validate-remember] Unexpected error: { e } " ])
1993- return jsonify ({
1994- "success" : False ,
1995- "valid" : False ,
1996- "error" : "Internal server error" ,
1997- "message" : "An unexpected error occurred during token validation"
1998- }), 500
1999-
2000-
2001- # --------------------------
2002- # Remember Me Save endpoint
2003- # --------------------------
2004- @app .route ("/auth/remember-me/save" , methods = ["POST" ])
2005- @validate_request (
2006- operation_id = "save_remember" ,
2007- summary = "Save Remember Me Token" ,
2008- description = "Save a Remember Me token to the database. Called after successful login to enable persistent authentication." ,
2009- request_model = SaveRememberRequest ,
2010- response_model = SaveRememberResponse ,
2011- tags = ["auth" ],
2012- auth_callable = None # No auth required - used on login page
2013- )
2014- def save_remember (payload = None ):
2015- """
2016- Save a Remember Me token.
2017-
2018- Flow:
2019- 1. User logs in with "Remember Me" checkbox
2020- 2. Password validated successfully
2021- 3. Token generated: bin2hex(random_bytes(32))
2022- 4. This endpoint called: saves hash(token) to Parameters table
2023- 5. Token (unhashed) set in persistent cookie
2024- 6. Session created and user redirected
2025-
2026- Security: Only the HASH is stored in the database, not the token itself.
2027- If database is compromised, attacker cannot use stolen hashes without the original token.
2028- """
2029- try :
2030- import uuid
2031- import hashlib
2032-
2033- # Extract token from request
2034- data = request .get_json () or {}
2035- token = data .get ("token" )
2036-
2037- if not token or len (token ) < 64 :
2038- mylog ("verbose" , ["[auth/remember-me/save] Invalid or missing token" ])
2039- return jsonify ({
2040- "success" : False ,
2041- "error" : "Invalid token" ,
2042- "message" : "Token must be 64+ hex characters"
2043- }), 400
2044-
2045- # Hash the token
2046- token_hash = hashlib .sha256 (token .encode ('utf-8' )).hexdigest ()
2047-
2048- # Generate UUID-based parameter ID
2049- token_id = f"remember_me_token_{ uuid .uuid4 ()} "
2050-
2051- # Store hash in Parameters table
2052- params_instance = ParametersInstance ()
2053- success = params_instance .set_parameter (token_id , token_hash )
2054-
2055- if success :
2056- mylog ("verbose" , [f"[auth/remember-me/save] Token saved successfully: { token_id } " ])
2057- return jsonify ({
2058- "success" : True ,
2059- "message" : "Remember Me token saved successfully" ,
2060- "token_id" : token_id
2061- }), 200
2062- else :
2063- mylog ("verbose" , ["[auth/remember-me/save] Failed to save token to database" ])
2064- return jsonify ({
2065- "success" : False ,
2066- "error" : "Database error" ,
2067- "message" : "Failed to save Remember Me token"
2068- }), 500
2069-
2070- except Exception as e :
2071- mylog ("verbose" , [f"[auth/remember-me/save] Unexpected error: { e } " ])
2072- return jsonify ({
2073- "success" : False ,
2074- "error" : "Internal server error" ,
2075- "message" : "An unexpected error occurred while saving Remember Me token"
2076- }), 500
1939+ # Remember Me is now implemented via cookies only (no API endpoints required)
20771940
20781941
20791942# --------------------------
0 commit comments