feat: implement long-term user login with refresh tokens
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 3m23s

- Introduced a dual-token system for user authentication: a short-lived access token and a long-lived rotating refresh token.
- Created a new RefreshToken model to manage refresh tokens securely.
- Updated auth_api.py to handle login, refresh, and logout processes with the new token system.
- Enhanced security measures including token rotation and theft detection.
- Updated frontend to handle token refresh on 401 errors and adjusted SSE authentication.
- Removed CORS middleware as it's unnecessary behind the nginx proxy.
- Added tests to ensure functionality and security of the new token system.
This commit is contained in:
2026-03-01 19:27:25 -05:00
parent d7316bb00a
commit ebaef16daf
32 changed files with 713 additions and 201 deletions

View File

@@ -7,13 +7,15 @@ from models.user import User
from werkzeug.security import generate_password_hash
from datetime import datetime, timedelta
import jwt
from tests.conftest import TEST_SECRET_KEY, TEST_REFRESH_TOKEN_EXPIRY_DAYS
@pytest.fixture
def client():
app = Flask(__name__)
app.register_blueprint(auth_api, url_prefix='/auth')
app.config['TESTING'] = True
app.config['SECRET_KEY'] = 'supersecretkey'
app.config['SECRET_KEY'] = TEST_SECRET_KEY
app.config['REFRESH_TOKEN_EXPIRY_DAYS'] = TEST_REFRESH_TOKEN_EXPIRY_DAYS
with app.test_client() as client:
yield client
@@ -70,12 +72,13 @@ def test_me_marked_for_deletion(client):
payload = {
'email': email,
'user_id': user.id,
'token_version': user.token_version,
'exp': datetime.utcnow() + timedelta(hours=24)
}
token = jwt.encode(payload, 'supersecretkey', algorithm='HS256')
token = jwt.encode(payload, TEST_SECRET_KEY, algorithm='HS256')
# Make request with token cookie
client.set_cookie('token', token)
client.set_cookie('access_token', token)
response = client.get('/auth/me')
assert response.status_code == 403