mirror of
https://github.com/sotam0316/brain_dogfood.git
synced 2026-04-24 19:48:35 +09:00
feat: implement session timeout countdown and UI optimization
This commit is contained in:
+7
-1
@@ -88,11 +88,17 @@ def create_app():
|
||||
init_db()
|
||||
|
||||
# Session and Security configurations
|
||||
# config.json에서 타임아웃 로드 (기본 60분, 최소 10분 강제)
|
||||
session_timeout = cfg.get('session_timeout', 60)
|
||||
if not isinstance(session_timeout, int) or session_timeout < 10:
|
||||
session_timeout = 10
|
||||
|
||||
from datetime import timedelta
|
||||
app.config.update(
|
||||
SESSION_COOKIE_HTTPONLY=True,
|
||||
SESSION_COOKIE_SAMESITE='Lax',
|
||||
SESSION_COOKIE_SECURE=os.getenv('SESSION_COOKIE_SECURE', 'False').lower() == 'true',
|
||||
PERMANENT_SESSION_LIFETIME=3600 # 60 minutes (1 hour) session
|
||||
PERMANENT_SESSION_LIFETIME=timedelta(minutes=session_timeout)
|
||||
)
|
||||
|
||||
@app.after_request
|
||||
|
||||
@@ -23,3 +23,10 @@ def login():
|
||||
def logout():
|
||||
session.pop('logged_in', None)
|
||||
return redirect(url_for('main.login_page'))
|
||||
|
||||
@auth_bp.route('/api/auth/status')
|
||||
def auth_status():
|
||||
"""프론트엔드 세션 체크(Heartbeat)용 엔드포인트"""
|
||||
if session.get('logged_in'):
|
||||
return jsonify({'status': 'ok', 'logged_in': True})
|
||||
return jsonify({'error': 'Unauthorized', 'logged_in': False}), 401
|
||||
|
||||
+25
-5
@@ -16,9 +16,10 @@ DEFAULT_SETTINGS = {
|
||||
"ai_accent": "#8b5cf6",
|
||||
"enable_ai": True,
|
||||
"lang": "ko",
|
||||
"enable_categories": False, # 카테고리 기능 활성화 여부 (고급 옵션)
|
||||
"categories": [], # 무제한 전체 목록
|
||||
"pinned_categories": [] # 최대 3개 (Alt+2~4 할당용)
|
||||
"enable_categories": False,
|
||||
"categories": [],
|
||||
"pinned_categories": [],
|
||||
"session_timeout": 60 # 기본 60분
|
||||
}
|
||||
|
||||
@settings_bp.route('/api/settings', methods=['GET'])
|
||||
@@ -32,6 +33,9 @@ def get_settings():
|
||||
data = json.load(f)
|
||||
# 기본값과 병합하여 신규 필드 등 누락 방지
|
||||
full_data = {**DEFAULT_SETTINGS, **data}
|
||||
# 최소 10분 강제 적용
|
||||
if full_data.get('session_timeout', 0) < 10:
|
||||
full_data['session_timeout'] = 10
|
||||
return jsonify(full_data)
|
||||
except Exception as e:
|
||||
return jsonify(DEFAULT_SETTINGS)
|
||||
@@ -50,12 +54,28 @@ def save_settings():
|
||||
with open(CONFIG_PATH, 'r', encoding='utf-8') as f:
|
||||
current_data = json.load(f)
|
||||
|
||||
# 세션 타임아웃 검증 및 보정
|
||||
session_timeout = data.get('session_timeout')
|
||||
if session_timeout is not None:
|
||||
try:
|
||||
session_timeout = int(session_timeout)
|
||||
if session_timeout < 10:
|
||||
session_timeout = 10
|
||||
data['session_timeout'] = session_timeout
|
||||
except (ValueError, TypeError):
|
||||
data.pop('session_timeout', None)
|
||||
|
||||
updated_data = {**current_data, **data}
|
||||
|
||||
with open(CONFIG_PATH, 'w', encoding='utf-8') as f:
|
||||
json.dump(updated_data, f, indent=4, ensure_ascii=False)
|
||||
|
||||
current_app.logger.info(f"System Settings Updated: {list(data.keys())}")
|
||||
return jsonify({'message': 'Settings saved successfully'})
|
||||
# Flask 설정 즉시 반영
|
||||
if 'session_timeout' in updated_data:
|
||||
from datetime import timedelta
|
||||
current_app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=updated_data['session_timeout'])
|
||||
|
||||
current_app.logger.info(f"System Settings Updated: {list(data.keys())} (Session Timeout: {updated_data.get('session_timeout')} min)")
|
||||
return jsonify({'message': 'Settings saved successfully', 'session_timeout': updated_data.get('session_timeout')})
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
Reference in New Issue
Block a user