mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-10-01 05:05:53 +00:00
Add a bit of safety around the IRC bridge and other integrations
This commit is contained in:
parent
0c66f0f5d2
commit
52f3c72db6
@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,10 +27,14 @@
|
||||
{{ bridge.upstreamId ? "matrix.org's bridge" : "Self-hosted bridge" }}
|
||||
<span class="text-muted" style="display: inline-block;" *ngIf="!bridge.upstreamId">({{ bridge.provisionUrl }})</span>
|
||||
</td>
|
||||
<td>
|
||||
<td *ngIf="bridge.isOnline">
|
||||
{{ getEnabledNetworksString(bridge) }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<td *ngIf="!bridge.isOnline" class="error-text" colspan="2">
|
||||
<i class="fa fa-exclamation-triangle"></i>
|
||||
This bridge is offline or unavailable.
|
||||
</td>
|
||||
<td class="text-center" *ngIf="bridge.isOnline">
|
||||
<span class="editButton" (click)="editNetworks(bridge)">
|
||||
<i class="fa fa-pencil-alt"></i>
|
||||
</span>
|
||||
|
@ -4,5 +4,6 @@
|
||||
<div class="integration-name">{{ integration.displayName }}</div>
|
||||
<div class="integration-description">{{ integration.description }}</div>
|
||||
<div class="integration-arrow"><i class="fa fa-chevron-right"></i></div>
|
||||
<div class="integration-offline error-text" *ngIf="!integration.isOnline"><i class="fa fa-exclamation-triangle"></i></div>
|
||||
</div>
|
||||
</div>
|
@ -55,4 +55,10 @@
|
||||
margin-right: 5px;
|
||||
color: themed(integrationDescriptionColor);
|
||||
}
|
||||
|
||||
.integration .integration-offline {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 6px;
|
||||
}
|
||||
}
|
@ -233,6 +233,12 @@ export class RiotHomeComponent {
|
||||
}
|
||||
|
||||
private async updateIntegrationState(integration: FE_Integration) {
|
||||
if (!integration.isOnline) {
|
||||
integration._isSupported = false;
|
||||
integration._notSupportedReason = "This integration is offline or unavailable";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!integration.requirements) return;
|
||||
|
||||
let promises = integration.requirements.map(r => this.checkRequirement(r));
|
||||
|
@ -8,6 +8,7 @@ export interface FE_Integration {
|
||||
description: string;
|
||||
isEnabled: boolean;
|
||||
isPublic: boolean;
|
||||
isOnline: boolean;
|
||||
|
||||
// Used by us
|
||||
_inRoom: boolean;
|
||||
|
@ -3,6 +3,7 @@ export interface FE_IrcBridge {
|
||||
upstreamId?: number;
|
||||
provisionUrl?: string;
|
||||
isEnabled: boolean;
|
||||
isOnline: boolean;
|
||||
availableNetworks: FE_IrcBridgeAvailableNetworks;
|
||||
}
|
||||
|
||||
|
@ -52,3 +52,7 @@ button {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
color: #bd362f;
|
||||
}
|
Loading…
Reference in New Issue
Block a user