(res: http.ServerResponse)
| 2033 | } |
| 2034 | |
| 2035 | private async serveSharingStatus(res: http.ServerResponse): Promise<void> { |
| 2036 | const sharing = this.ctx?.config?.sharing; |
| 2037 | const persisted = this.store.getClientHubConnection(); |
| 2038 | const resolvedHubUrl = sharing?.client?.hubAddress ? normalizeHubUrl(sharing.client.hubAddress) : persisted?.hubUrl ?? null; |
| 2039 | const hasClientConfig = Boolean( |
| 2040 | (sharing?.client?.hubAddress && sharing?.client?.userToken) || |
| 2041 | (persisted?.hubUrl && persisted?.userToken), |
| 2042 | ); |
| 2043 | const base = { |
| 2044 | enabled: Boolean(sharing?.enabled), |
| 2045 | role: sharing?.role ?? null, |
| 2046 | clientConfigured: hasClientConfig, |
| 2047 | hubUrl: resolvedHubUrl, |
| 2048 | connection: { connected: false, user: null as any, hubUrl: undefined as string | undefined, teamName: null as string | null, apiVersion: null as string | null }, |
| 2049 | admin: { canManageUsers: false, rejectSupported: false }, |
| 2050 | }; |
| 2051 | |
| 2052 | if (!this.ctx || !sharing?.enabled) { |
| 2053 | this.jsonResponse(res, base); |
| 2054 | return; |
| 2055 | } |
| 2056 | |
| 2057 | // Hub 模式下,本机就是管理者,直接赋予 admin 权限 |
| 2058 | if (sharing.role === "hub") { |
| 2059 | base.admin.canManageUsers = true; |
| 2060 | base.admin.rejectSupported = true; |
| 2061 | base.connection.connected = true; |
| 2062 | base.connection.hubUrl = resolvedHubUrl ?? undefined; |
| 2063 | |
| 2064 | let adminUser: any = { username: "hub-admin", role: "admin" }; |
| 2065 | try { |
| 2066 | const hub = this.resolveHubConnection(); |
| 2067 | if (hub) { |
| 2068 | const me = await hubRequestJson(hub.hubUrl, hub.userToken, "/api/v1/hub/me", { method: "GET" }) as any; |
| 2069 | if (me) { |
| 2070 | adminUser = { |
| 2071 | id: me.id, |
| 2072 | username: me.username ?? "hub-admin", |
| 2073 | role: me.role ?? "admin", |
| 2074 | }; |
| 2075 | } |
| 2076 | } |
| 2077 | } catch { /* fallback to default */ } |
| 2078 | base.connection.user = adminUser; |
| 2079 | |
| 2080 | // Fetch team info from own hub |
| 2081 | try { |
| 2082 | const selfUrl = resolvedHubUrl || `http://localhost:${sharing.hub?.port ?? 21816}`; |
| 2083 | const info = await fetch(`${selfUrl}/api/v1/hub/info`).then(r => r.ok ? r.json() : null).catch(() => null) as any; |
| 2084 | base.connection.teamName = info?.teamName ?? sharing.hub?.teamName ?? null; |
| 2085 | base.connection.apiVersion = info?.apiVersion ?? null; |
| 2086 | } catch { /* ignore */ } |
| 2087 | |
| 2088 | const hubStats: any = { totalMembers: 0, onlineMembers: 0, pendingMembers: 0 }; |
| 2089 | try { |
| 2090 | const activeUsers = this.store.listHubUsers("active"); |
| 2091 | const pendingUsers = this.store.listHubUsers("pending"); |
| 2092 | const now = Date.now(); |
no test coverage detected