Enhance configuration and logging for user management commands
CI / Backend (build + test) (push) Successful in 1m18s
CI / Frontend (lint + typecheck + build) (push) Successful in 31s

- Updated `.env.example` to include new settings for trusted proxies and networks for better security with X-Forwarded headers.
- Modified `BlockUserCommandHandler` and `UnblockUserCommandHandler` to include logging for gateway update failures, ensuring better traceability of issues during user blocking/unblocking.
- Adjusted tests for command handlers to incorporate logging functionality, improving test coverage and reliability.
- Updated frontend configuration to dynamically set the server port based on environment variables.
This commit is contained in:
Leonid Pershin
2026-07-02 14:33:32 +03:00
parent cdd67f8e2b
commit c04e0d7261
13 changed files with 162 additions and 17 deletions
@@ -27,7 +27,7 @@ export function PublishInboundDialog({
const [maxClients, setMaxClients] = useState(inbound.maxClients?.toString() ?? '')
const [selectedRoles, setSelectedRoles] = useState<Set<string>>(new Set(inbound.allowedRoleIds))
const rolesQuery = useQuery({ queryKey: ['admin-roles-page'], queryFn: listRoles, enabled: open })
const rolesQuery = useQuery({ queryKey: ['admin-roles'], queryFn: listRoles, enabled: open })
const mutation = useMutation({
mutationFn: () =>
@@ -35,6 +35,8 @@ export function PublishInboundDialog({
onSuccess: async () => {
toast.success(t('admin.nodes.publishSaved'))
await queryClient.invalidateQueries({ queryKey: ['admin-inbounds', inbound.nodeId] })
// Публикация/список ролей инбаунда влияет на то, что видит пользователь при создании конфига.
await queryClient.invalidateQueries({ queryKey: ['available-inbounds'] })
onOpenChange(false)
},
onError: (error) => toast.error(error instanceof HttpError ? error.detail : t('auth.genericError')),
@@ -51,6 +51,8 @@ export function NodeCard({ node }: { node: NodeDto }) {
toast.success(t('admin.nodes.syncSuccess', { count: result.inboundsSynced }))
await invalidateNodes()
await queryClient.invalidateQueries({ queryKey: ['admin-inbounds', node.id] })
// Синхронизация могла добавить/убрать инбаунды, доступные пользователю при создании конфига.
await queryClient.invalidateQueries({ queryKey: ['available-inbounds'] })
},
onError: (error) => toast.error(error instanceof HttpError ? error.detail : t('auth.genericError')),
})
@@ -33,7 +33,7 @@ export function RoleFormDialog({
mutationFn: () => (role ? updateRole(role.id, Number(maxConfigs)) : createRole(name.trim(), Number(maxConfigs))),
onSuccess: async () => {
toast.success(role ? t('admin.roles.updated') : t('admin.roles.created'))
await queryClient.invalidateQueries({ queryKey: ['admin-roles-page'] })
await queryClient.invalidateQueries({ queryKey: ['admin-roles'] })
setDialogOpen(false)
setName('')
setMaxConfigs('3')
+6
View File
@@ -8,6 +8,12 @@ import { ThemeProvider } from './theme/ThemeProvider'
import { ToastProvider } from './shared/ui/toast-store'
import { RealtimeProvider } from './shared/realtime/RealtimeProvider'
import { router } from './router'
import { setUnauthorizedHandler } from './shared/api/client'
import { clearSession } from './features/auth/api'
// Если refresh-токен недействителен (истёк/отозван) — очищаем стор авторизации, чтобы
// useRequireAuth/useRequireAdmin увидели user === null и сами увели на /login.
setUnauthorizedHandler(clearSession)
const queryClient = new QueryClient()
+2 -2
View File
@@ -16,13 +16,13 @@ function AdminRolesPage() {
const queryClient = useQueryClient()
const [editing, setEditing] = useState<RoleDto | null>(null)
const { data, isLoading, isError, refetch } = useQuery({ queryKey: ['admin-roles-page'], queryFn: listRoles })
const { data, isLoading, isError, refetch } = useQuery({ queryKey: ['admin-roles'], queryFn: listRoles })
const deleteMutation = useMutation({
mutationFn: deleteRole,
onSuccess: async () => {
toast.success(t('admin.roles.deleted'))
await queryClient.invalidateQueries({ queryKey: ['admin-roles-page'] })
await queryClient.invalidateQueries({ queryKey: ['admin-roles'] })
},
onError: () => toast.error(t('auth.genericError')),
})