fix: use UnauthorizedAndForceLogout to trigger frontend logout on license expiry

Change license check to raise UnauthorizedAndForceLogout exception instead
of returning generic JSON response. This ensures proper frontend handling:

Frontend behavior (service/base.ts line 588):
- Checks if code === 'unauthorized_and_force_logout'
- Executes globalThis.location.reload()
- Forces user logout and redirect to login page
- Login page displays license expiration UI (already exists)

Response format:
- HTTP 401 (not 403)
- code: "unauthorized_and_force_logout"
- Triggers frontend reload which clears auth state

This completes the license enforcement flow:
1. Backend blocks all business APIs when license expires
2. Backend returns proper error code to trigger logout
3. Frontend reloads and redirects to login
4. Login page shows license expiration message
This commit is contained in:
GareArc 2026-03-04 20:30:53 -08:00
parent 0ed39d81e9
commit 0e9dc86f3b
No known key found for this signature in database

View File

@ -1,12 +1,13 @@
import logging
import time
from flask import jsonify, request
from flask import request
from opentelemetry.trace import get_current_span
from opentelemetry.trace.span import INVALID_SPAN_ID, INVALID_TRACE_ID
from configs import dify_config
from contexts.wrapper import RecyclableContextVar
from controllers.console.error import UnauthorizedAndForceLogout
from core.logging.context import init_request_context
from dify_app import DifyApp
from services.feature_service import FeatureService, LicenseStatus
@ -61,14 +62,15 @@ def create_flask_app_with_configs() -> DifyApp:
LicenseStatus.EXPIRED,
LicenseStatus.LOST,
]:
return jsonify({
"code": "license_expired",
"message": (
f"Enterprise license is {system_features.license.status.value}. "
"Please contact your administrator."
),
"status": system_features.license.status.value,
}), 403
# Raise UnauthorizedAndForceLogout to trigger frontend reload and logout
# Frontend checks code === 'unauthorized_and_force_logout' and calls location.reload()
raise UnauthorizedAndForceLogout(
f"Enterprise license is {system_features.license.status.value}. "
"Please contact your administrator."
)
except UnauthorizedAndForceLogout:
# Re-raise to let Flask error handler convert to proper JSON response
raise
except Exception:
# If license check fails, log but don't block the request
# This prevents service disruption if enterprise API is temporarily unavailable