diff --git a/src/api/admin/AdminIrcService.ts b/src/api/admin/AdminIrcService.ts index f5c2310..6461598 100644 --- a/src/api/admin/AdminIrcService.ts +++ b/src/api/admin/AdminIrcService.ts @@ -22,6 +22,7 @@ interface BridgeResponse { provisionUrl?: string; isEnabled: boolean; availableNetworks: AvailableNetworks; + isOnline: boolean; } interface SetEnabledRequest { @@ -42,12 +43,21 @@ export class AdminIrcService { const bridges = await IrcBridgeRecord.findAll(); const client = new IrcBridge(userId); return Promise.all(bridges.map(async b => { + let networks = null; + let isOnline = true; + try { + networks = await client.getNetworks(b); + } catch (e) { + LogService.error("AdminIrcService", e); + isOnline = false; + } return { id: b.id, upstreamId: b.upstreamId, provisionUrl: b.provisionUrl, isEnabled: b.isEnabled, - availableNetworks: await client.getNetworks(b), + availableNetworks: networks, + isOnline: isOnline, }; })); } @@ -61,12 +71,21 @@ export class AdminIrcService { if (!ircBridge) throw new ApiError(404, "IRC Bridge not found"); const client = new IrcBridge(userId); + let networks = null; + let isOnline = true; + try { + networks = await client.getNetworks(ircBridge); + } catch (e) { + LogService.error("AdminIrcService", e); + isOnline = false; + } return { id: ircBridge.id, upstreamId: ircBridge.upstreamId, provisionUrl: ircBridge.provisionUrl, isEnabled: ircBridge.isEnabled, - availableNetworks: await client.getNetworks(ircBridge), + availableNetworks: networks, + isOnline: isOnline, }; } diff --git a/src/api/dimension/DimensionIntegrationsService.ts b/src/api/dimension/DimensionIntegrationsService.ts index 1e2431d..7ef18b0 100644 --- a/src/api/dimension/DimensionIntegrationsService.ts +++ b/src/api/dimension/DimensionIntegrationsService.ts @@ -11,6 +11,7 @@ import { ComplexBot } from "../../integrations/ComplexBot"; import { Bridge } from "../../integrations/Bridge"; import { BridgeStore } from "../../db/BridgeStore"; import { BotStore } from "../../db/BotStore"; +import { AdminService } from "../admin/AdminService"; export interface IntegrationsResponse { widgets: Widget[], @@ -65,6 +66,11 @@ export class DimensionIntegrationsService { .map(b => SimpleBot.fromCached(b)); const bots = [...nebs, ...custom]; Cache.for(CACHE_INTEGRATIONS).put("simple_bots", bots); + + if (!AdminService.isAdmin(userId)) { + return bots.filter(b => b.isOnline); + } + return bots; } @@ -80,6 +86,11 @@ export class DimensionIntegrationsService { const bots = await NebStore.listComplexBots(userId, roomId); Cache.for(CACHE_INTEGRATIONS).put("complex_bots_" + roomId, bots); + + if (!AdminService.isAdmin(userId)) { + return bots.filter(b => b.isOnline); + } + return bots; } diff --git a/src/db/BridgeStore.ts b/src/db/BridgeStore.ts index 60ecb9b..e58b3ff 100644 --- a/src/db/BridgeStore.ts +++ b/src/db/BridgeStore.ts @@ -34,6 +34,10 @@ export class BridgeStore { } catch (e) { LogService.error("BridgeStore", "Failed to load configuration for bridge: " + bridgeRecord.name); LogService.error("BridgeStore", e); + + const bridge = new Bridge(bridgeRecord, {}); + bridge.isOnline = false; + enabledBridges.push(bridge); } } diff --git a/src/db/NebStore.ts b/src/db/NebStore.ts index f1832aa..83854f2 100644 --- a/src/db/NebStore.ts +++ b/src/db/NebStore.ts @@ -129,7 +129,15 @@ export class NebStore { const rawIntegrations = await NebStore.listEnabledNebSimpleBots(); return Promise.all(rawIntegrations.map(async i => { const proxy = new NebProxy(i.neb, requestingUserId); - return SimpleBot.fromNeb(i.integration, await proxy.getBotUserId(i.integration)); + let userId = null; + try { + userId = await proxy.getBotUserId(i.integration); + } catch (e) { + LogService.error("NebStore", e); + } + const bot = SimpleBot.fromNeb(i.integration, userId); + bot.isOnline = !!userId; + return bot; })); } @@ -137,10 +145,18 @@ export class NebStore { const rawIntegrations = await NebStore.listEnabledNebComplexBots(); return Promise.all(rawIntegrations.map(async i => { const proxy = new NebProxy(i.neb, requestingUserId); - const notifUserId = await proxy.getNotificationUserId(i.integration, roomId); - const botUserId = null; // TODO: For github - const botConfig = await proxy.getServiceConfiguration(i.integration, roomId); - return new ComplexBot(i.integration, notifUserId, botUserId, botConfig); + try { + const notifUserId = await proxy.getNotificationUserId(i.integration, roomId); + const botUserId = null; // TODO: For github + const botConfig = await proxy.getServiceConfiguration(i.integration, roomId); + return new ComplexBot(i.integration, notifUserId, botUserId, botConfig); + } catch (e) { + LogService.error("NebStore", e); + + const bot = new ComplexBot(i.integration, null, null, null); + bot.isOnline = false; + return bot; + } })); } diff --git a/src/integrations/Integration.ts b/src/integrations/Integration.ts index c30a071..c096995 100644 --- a/src/integrations/Integration.ts +++ b/src/integrations/Integration.ts @@ -13,6 +13,7 @@ export class Integration { public description: string; public isEnabled: boolean; public isPublic: boolean; + public isOnline: boolean; constructor(record: IntegrationRecord) { this.type = record.type; @@ -21,6 +22,7 @@ export class Integration { this.description = record.description; this.isEnabled = record.isEnabled; this.isPublic = record.isPublic; + this.isOnline = true; } } diff --git a/web/app/admin/bridges/irc/irc.component.html b/web/app/admin/bridges/irc/irc.component.html index bc03342..59b567f 100644 --- a/web/app/admin/bridges/irc/irc.component.html +++ b/web/app/admin/bridges/irc/irc.component.html @@ -27,10 +27,14 @@ {{ bridge.upstreamId ? "matrix.org's bridge" : "Self-hosted bridge" }} ({{ bridge.provisionUrl }}) -