fix(web): 完善统一认证恢复与重配交互
为处理中、失败和清理中的配对展示明确状态与恢复动作,支持放弃并清理、作用域内退役冲突连接,并在 Active 状态引导管理员先安全禁用再使用新接入码。同步修复运行时切换后的浏览器会话残留与确认弹窗焦点约束。 验证:pnpm test;pnpm lint;pnpm build。
This commit is contained in:
+45
-15
@@ -122,7 +122,10 @@ import {
|
||||
persistAccessToken,
|
||||
readStoredAccessToken,
|
||||
} from './lib/auth-storage';
|
||||
import { restoreOIDCBrowserSession } from './lib/oidc-browser-session';
|
||||
import {
|
||||
reconcileOIDCBrowserSessionAfterRuntimeChange,
|
||||
restoreOIDCBrowserSession,
|
||||
} from './lib/oidc-browser-session';
|
||||
import {
|
||||
consumeOIDCCallbackError,
|
||||
loadOIDCRuntimeConfiguration,
|
||||
@@ -260,7 +263,15 @@ export function App() {
|
||||
const [state, setState] = useState<LoadState>('idle');
|
||||
const [error, setError] = useState('');
|
||||
const [oidcCallbackError, setOIDCCallbackError] = useState(() => consumeOIDCCallbackError());
|
||||
const [oidcEnabled, setOIDCEnabled] = useState(false);
|
||||
const [oidcEnabled, setOIDCEnabled] = useState(false);
|
||||
const currentCredentialRef = useRef(token);
|
||||
const resetAuthenticatedSessionRef = useRef<() => void>(() => undefined);
|
||||
currentCredentialRef.current = token;
|
||||
resetAuthenticatedSessionRef.current = () => {
|
||||
resetAuthenticatedSession();
|
||||
setAuthMode('login');
|
||||
setError('统一认证配置已变更,当前登录会话已失效,请重新登录。');
|
||||
};
|
||||
const loadedDataKeysRef = useRef(new Set<DataKey>());
|
||||
const loadingDataKeysRef = useRef(new Set<DataKey>());
|
||||
const loadedTaskQueryKeyRef = useRef('');
|
||||
@@ -294,29 +305,48 @@ export function App() {
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
const loadIdentityRuntime = async (force = false) => {
|
||||
const configuration = await loadOIDCRuntimeConfiguration(force);
|
||||
if (cancelled) return;
|
||||
setOIDCEnabled(configuration.enabled && configuration.oidcLogin);
|
||||
if (oidcCallbackError || readStoredAccessToken() || !configuration.enabled || !configuration.oidcLogin) return;
|
||||
const restored = await restoreOIDCBrowserSession();
|
||||
if (!restored || cancelled) return;
|
||||
const applyRestoredSession = (restored: NonNullable<Awaited<ReturnType<typeof restoreOIDCBrowserSession>>>) => {
|
||||
if (cancelled) return;
|
||||
setCurrentUser(restored.user);
|
||||
loadedDataKeysRef.current.add('currentUser');
|
||||
setToken(restored.credential);
|
||||
setState('idle');
|
||||
setError('');
|
||||
};
|
||||
const runtimeChanged = () => { void loadIdentityRuntime(true); };
|
||||
window.addEventListener('identity-runtime-changed', runtimeChanged);
|
||||
void loadIdentityRuntime().catch((err) => {
|
||||
};
|
||||
const loadIdentityRuntime = async (force = false) => {
|
||||
const configuration = await loadOIDCRuntimeConfiguration(force);
|
||||
if (cancelled) return;
|
||||
const identityEnabled = configuration.enabled && configuration.oidcLogin;
|
||||
setOIDCEnabled(identityEnabled);
|
||||
if (force && currentCredentialRef.current === OIDC_BROWSER_SESSION_CREDENTIAL) {
|
||||
await reconcileOIDCBrowserSessionAfterRuntimeChange({
|
||||
credential: currentCredentialRef.current,
|
||||
oidcEnabled: identityEnabled,
|
||||
onReset: () => {
|
||||
if (!cancelled) resetAuthenticatedSessionRef.current();
|
||||
},
|
||||
onRestored: applyRestoredSession,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (oidcCallbackError || readStoredAccessToken() || !identityEnabled) return;
|
||||
const restored = await restoreOIDCBrowserSession();
|
||||
if (!restored || cancelled) return;
|
||||
applyRestoredSession(restored);
|
||||
};
|
||||
const handleLoadError = (err: unknown) => {
|
||||
if (cancelled) return;
|
||||
setState('error');
|
||||
setError(err instanceof Error ? err.message : '统一认证登录失败');
|
||||
});
|
||||
};
|
||||
const runtimeChanged = () => {
|
||||
void loadIdentityRuntime(true).catch(handleLoadError);
|
||||
};
|
||||
window.addEventListener('identity-runtime-changed', runtimeChanged);
|
||||
void loadIdentityRuntime().catch(handleLoadError);
|
||||
return () => {
|
||||
cancelled = true;
|
||||
window.removeEventListener('identity-runtime-changed', runtimeChanged);
|
||||
window.removeEventListener('identity-runtime-changed', runtimeChanged);
|
||||
};
|
||||
}, [oidcCallbackError]);
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user