Add refresh token functionality and improve login response handling

- Introduced RefreshTokenView to allow users to refresh their access tokens using a valid refresh token.
- Enhanced LoginView to ensure correct user/account loading and improved error handling during user serialization.
- Updated API response structure to include access and refresh token expiration times.
- Adjusted frontend API handling to support both new and legacy token response formats.
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-16 21:06:22 +00:00
parent 1531f41226
commit fc6dd5623a
8 changed files with 155 additions and 33 deletions

View File

@@ -235,6 +235,15 @@ class ModuleSettingsViewSet(AccountModelViewSet):
def retrieve(self, request, pk=None):
"""Get setting by key (pk can be key string)"""
# Special case: if pk is "enable", this is likely a routing conflict
# The correct endpoint is /settings/modules/enable/ which should go to ModuleEnableSettingsViewSet
if pk == 'enable':
return error_response(
error='Use /api/v1/system/settings/modules/enable/ endpoint for module enable settings',
status_code=status.HTTP_404_NOT_FOUND,
request=request
)
queryset = self.get_queryset()
try:
# Try to get by ID first
@@ -301,7 +310,7 @@ class ModuleEnableSettingsViewSet(AccountModelViewSet):
Allow read access to all authenticated users,
but restrict write access to admins/owners
"""
if self.action in ['list', 'retrieve']:
if self.action in ['list', 'retrieve', 'get_current']:
permission_classes = [IsAuthenticatedAndActive, HasTenantAccess]
else:
permission_classes = [IsAuthenticatedAndActive, HasTenantAccess, IsAdminOrOwner]
@@ -321,6 +330,14 @@ class ModuleEnableSettingsViewSet(AccountModelViewSet):
queryset = queryset.filter(account=account)
return queryset
@action(detail=False, methods=['get', 'put'], url_path='current', url_name='current')
def get_current(self, request):
"""Get or update current account's module enable settings"""
if request.method == 'GET':
return self.list(request)
else:
return self.update(request, pk=None)
def list(self, request, *args, **kwargs):
"""Get or create module enable settings for current account"""
try:

View File

@@ -16,8 +16,8 @@ router.register(r'strategies', StrategyViewSet, basename='strategy')
router.register(r'settings/system', SystemSettingsViewSet, basename='system-settings')
router.register(r'settings/account', AccountSettingsViewSet, basename='account-settings')
router.register(r'settings/user', UserSettingsViewSet, basename='user-settings')
# Register ModuleSettingsViewSet first
router.register(r'settings/modules', ModuleSettingsViewSet, basename='module-settings')
router.register(r'settings/modules/enable', ModuleEnableSettingsViewSet, basename='module-enable-settings')
router.register(r'settings/ai', AISettingsViewSet, basename='ai-settings')
# Custom URL patterns for integration settings - matching reference plugin structure
@@ -50,7 +50,20 @@ integration_image_gen_settings_viewset = IntegrationSettingsViewSet.as_view({
'get': 'get_image_generation_settings',
})
# Custom view for module enable settings to avoid URL routing conflict with ModuleSettingsViewSet
# This must be defined as a custom path BEFORE router.urls to ensure it matches first
# The update method handles pk=None correctly, so we can use as_view
module_enable_viewset = ModuleEnableSettingsViewSet.as_view({
'get': 'list',
'put': 'update',
'patch': 'partial_update',
})
urlpatterns = [
# Module enable settings endpoint - MUST come before router.urls to avoid conflict
# When /settings/modules/enable/ is called, it would match ModuleSettingsViewSet with pk='enable'
# So we define it as a custom path first
path('settings/modules/enable/', module_enable_viewset, name='module-enable-settings'),
path('', include(router.urls)),
# Public health check endpoint (API Standard v1.0 requirement)
path('ping/', ping, name='system-ping'),