From 5f0ae6bc5a45eecb98ec44ef989cccfccd49c58e Mon Sep 17 00:00:00 2001 From: bunker-admin Date: Thu, 9 Apr 2026 14:01:02 -0600 Subject: [PATCH] Revert NocoDB auto sign-in, keep CSP fix for embed proxy NocoDB v2 stores auth tokens in-memory (Pinia store), not in cookies accessible to external pages. The auth bridge approach can't inject tokens into NocoDB's SPA state. Reverted to the original banner approach ("sign in to NocoDB in a new tab"). Kept: CSP fix (frame-ancestors http://localhost:* instead of just localhost, which only matched port 80). Bunker Admin --- admin/src/pages/NocoDBPage.tsx | 69 +++++++-------------- api/src/config/env.ts | 2 - api/src/modules/services/services.routes.ts | 42 ------------- docker-compose.prod.yml | 3 - docker-compose.yml | 3 - nginx/conf.d/services.conf.template | 27 ++------ 6 files changed, 28 insertions(+), 118 deletions(-) diff --git a/admin/src/pages/NocoDBPage.tsx b/admin/src/pages/NocoDBPage.tsx index 4373b7ed..f867e0a6 100644 --- a/admin/src/pages/NocoDBPage.tsx +++ b/admin/src/pages/NocoDBPage.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback, useMemo, useRef } from 'react'; +import { useState, useEffect, useCallback, useMemo } from 'react'; import { useOutletContext } from 'react-router-dom'; import { Button, Space, Badge, Spin, Grid, Result, Alert } from 'antd'; import { ReloadOutlined, LinkOutlined, DatabaseOutlined } from '@ant-design/icons'; @@ -7,6 +7,8 @@ import type { AppOutletContext } from '@/components/AppLayout'; import type { ServicesStatus, ServicesConfig } from '@/types/api'; import { buildServiceUrl } from '@/lib/service-url'; +const BANNER_DISMISSED_KEY = 'nocodb-auth-banner-dismissed'; + export default function NocoDBPage() { const { setPageHeader } = useOutletContext(); const screens = Grid.useBreakpoint(); @@ -15,9 +17,9 @@ export default function NocoDBPage() { const [online, setOnline] = useState(null); const [config, setConfig] = useState(null); const [loading, setLoading] = useState(true); - const [iframeSrc, setIframeSrc] = useState(null); - const [authFailed, setAuthFailed] = useState(false); - const authAttempted = useRef(false); + const [bannerDismissed, setBannerDismissed] = useState( + () => localStorage.getItem(BANNER_DISMISSED_KEY) === 'true' + ); const fetchStatus = useCallback(async () => { try { @@ -42,31 +44,7 @@ export default function NocoDBPage() { ? buildServiceUrl(config.nocodbSubdomain, config.domain, config.nocodbPort) : null; - // Auto sign-in: fetch NocoDB auth token and navigate iframe to auth bridge - useEffect(() => { - if (!serviceUrl || !online || authAttempted.current) return; - authAttempted.current = true; - - (async () => { - try { - const res = await api.get<{ token: string }>('/services/nocodb-auth'); - if (res.data.token) { - // Navigate iframe to auth bridge (same origin as NocoDB) which sets the cookie - setIframeSrc(`${serviceUrl}/auth-bridge#${res.data.token}`); - return; - } - } catch { - // Auth endpoint unavailable — fall back to direct URL - } - setAuthFailed(true); - setIframeSrc(serviceUrl); - })(); - }, [serviceUrl, online]); - const handleRefresh = useCallback(() => { - authAttempted.current = false; - setIframeSrc(null); - setAuthFailed(false); fetchStatus(); }, [fetchStatus]); @@ -137,11 +115,11 @@ export default function NocoDBPage() { return (
- {authFailed && ( + {!bannerDismissed && ( - Auto sign-in unavailable. You may need to{' '} + If the database browser appears blank, you may need to{' '} sign in to NocoDB in a new tab {' '} @@ -151,26 +129,23 @@ export default function NocoDBPage() { type="info" showIcon closable - onClose={() => setAuthFailed(false)} + onClose={() => { + setBannerDismissed(true); + localStorage.setItem(BANNER_DISMISSED_KEY, 'true'); + }} style={{ borderRadius: 0, flexShrink: 0 }} /> )} - {iframeSrc ? ( -