feat: fail closed before domain runtime entry

This commit is contained in:
冰朔 2026-08-10 01:23:52 +08:00
commit 0990e96c0e
6 changed files with 160 additions and 8 deletions

View file

@ -40,6 +40,12 @@ interface ServerProfile {
channelSubtitle?: string;
}
interface DomainAccessStatus {
blockers: string[];
runtimeReady: boolean;
stage: 'checking' | 'login-required' | 'identity-verified' | 'runtime-ready';
}
function findFirstDocument(nodes: DocTreeNode[]): string | null {
for (const node of nodes) {
if (node.type === 'document') return node.path;
@ -90,6 +96,7 @@ export default function App() {
const [moduleMessage, setModuleMessage] = useState('');
const [lastChannelReceipt, setLastChannelReceipt] = useState('');
const [worldEntered, setWorldEntered] = useState(false);
const [domainAccess, setDomainAccess] = useState<DomainAccessStatus>({ blockers: [], runtimeReady: false, stage: 'checking' });
const storageMode = repositoryStatus?.remote ? 'server' : 'local';
const storageLabel = storageMode === 'server' ? '服务器已托管' : '仅本机';
@ -165,6 +172,19 @@ export default function App() {
}
}, []);
const refreshDomainAccess = useCallback(async () => {
const server = (window as any).hololake?.server;
if (!server?.domainAccess) {
setDomainAccess({ blockers: ['desktop_runtime_required'], runtimeReady: false, stage: 'login-required' });
return;
}
try {
setDomainAccess(await server.domainAccess('DOM-FIFTH-0001'));
} catch {
setDomainAccess({ blockers: ['domain_access_probe_failed'], runtimeReady: false, stage: 'login-required' });
}
}, []);
const refreshChannel = useCallback(async () => {
try {
const [channel, registry] = await Promise.all([api.getChannel(), api.getModules()]);
@ -179,8 +199,9 @@ export default function App() {
refreshTree();
refreshRepositoryStatus();
refreshServerSession();
refreshDomainAccess();
refreshChannel();
}, [refreshTree, refreshRepositoryStatus, refreshServerSession, refreshChannel]);
}, [refreshTree, refreshRepositoryStatus, refreshServerSession, refreshDomainAccess, refreshChannel]);
const changeModuleState = useCallback(async (moduleId: string, installed: boolean, mounted: boolean) => {
setModuleBusy(true);
@ -358,7 +379,13 @@ export default function App() {
<>
{!worldEntered && (
<WorldEntry
onEnterFifth={() => {
access={domainAccess}
onEnterFifthRuntime={() => {
setActiveRoute('fifth');
setActiveModule('knowledge');
setWorldEntered(true);
}}
onEnterLocalWorkspace={() => {
setActiveRoute('fifth');
setActiveModule('knowledge');
setWorldEntered(true);
@ -547,6 +574,7 @@ export default function App() {
onApplied={() => {
refreshRepositoryStatus();
refreshServerSession();
refreshDomainAccess();
}}
/>
<HumanSettings