mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-08-31 06:02:09 +00:00
Prevent people from adding widgets in rooms where they have no permission
This commit is contained in:
parent
cbcee69b57
commit
51344656b2
@ -18,22 +18,16 @@ import { ScalarCloseComponent } from "./riot/scalar-close/scalar-close.component
|
||||
import { IntegrationService } from "./shared/integration.service";
|
||||
import { BootstrapModalModule } from "ngx-modialog/plugins/bootstrap";
|
||||
import { ModalModule } from "ngx-modialog";
|
||||
import { RssConfigComponent } from "./configs/rss/rss-config.component";
|
||||
import { IrcConfigComponent } from "./configs/irc/irc-config.component";
|
||||
import { IrcApiService } from "./shared/irc-api.service";
|
||||
import { TravisCiConfigComponent } from "./configs/travisci/travisci-config.component";
|
||||
import { CustomWidgetConfigComponent } from "./configs/widget/custom_widget/custom_widget-config.component";
|
||||
import { MyFilterPipe } from "./shared/my-filter.pipe";
|
||||
import { GenericWidgetWrapperComponent } from "./widget_wrappers/generic/generic.component";
|
||||
import { ToggleFullscreenDirective } from "./shared/toggle-fullscreen.directive";
|
||||
import { FullscreenButtonComponent } from "./fullscreen-button/fullscreen-button.component";
|
||||
import { YoutubeWidgetConfigComponent } from "./configs/widget/youtube/youtube-config.component";
|
||||
import { TwitchWidgetConfigComponent } from "./configs/widget/twitch/twitch-config.component";
|
||||
import { EtherpadWidgetConfigComponent } from "./configs/widget/etherpad/etherpad-config.component";
|
||||
import { VideoWidgetWrapperComponent } from "./widget_wrappers/video/video.component";
|
||||
import { JitsiWidgetConfigComponent } from "./configs/widget/jitsi/jitsi-config.component";
|
||||
import { JitsiWidgetWrapperComponent } from "./widget_wrappers/jitsi/jitsi.component";
|
||||
|
||||
const WIDGET_CONFIGURATION_COMPONENTS: any[] = IntegrationService.getAllConfigComponents();
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@ -48,24 +42,17 @@ import { JitsiWidgetWrapperComponent } from "./widget_wrappers/jitsi/jitsi.compo
|
||||
BootstrapModalModule,
|
||||
],
|
||||
declarations: [
|
||||
...WIDGET_CONFIGURATION_COMPONENTS,
|
||||
AppComponent,
|
||||
HomeComponent,
|
||||
RiotComponent,
|
||||
IntegrationComponent,
|
||||
ScalarCloseComponent,
|
||||
RssConfigComponent,
|
||||
IrcConfigComponent,
|
||||
TravisCiConfigComponent,
|
||||
CustomWidgetConfigComponent,
|
||||
MyFilterPipe,
|
||||
GenericWidgetWrapperComponent,
|
||||
ToggleFullscreenDirective,
|
||||
FullscreenButtonComponent,
|
||||
YoutubeWidgetConfigComponent,
|
||||
TwitchWidgetConfigComponent,
|
||||
EtherpadWidgetConfigComponent,
|
||||
VideoWidgetWrapperComponent,
|
||||
JitsiWidgetConfigComponent,
|
||||
JitsiWidgetWrapperComponent,
|
||||
|
||||
// Vendor
|
||||
@ -81,14 +68,7 @@ import { JitsiWidgetWrapperComponent } from "./widget_wrappers/jitsi/jitsi.compo
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
entryComponents: [
|
||||
RssConfigComponent,
|
||||
TravisCiConfigComponent,
|
||||
IrcConfigComponent,
|
||||
CustomWidgetConfigComponent,
|
||||
YoutubeWidgetConfigComponent,
|
||||
TwitchWidgetConfigComponent,
|
||||
EtherpadWidgetConfigComponent,
|
||||
JitsiWidgetConfigComponent,
|
||||
...WIDGET_CONFIGURATION_COMPONENTS,
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
|
@ -7,7 +7,7 @@
|
||||
<ui-switch [checked]="integration.isEnabled" size="small" [disabled]="integration.isBroken"
|
||||
(change)="update()"></ui-switch>
|
||||
</div>
|
||||
<div class="switch" *ngIf="integration.type == 'bridge' && !integration.isEnabled">
|
||||
<div class="switch" *ngIf="canHaveErrors(integration) && !integration.isEnabled">
|
||||
<i class="fa fa-warning text-warning" ngbTooltip="{{ integration.bridgeError }}"></i>
|
||||
</div>
|
||||
<div class="toolbar">
|
||||
|
@ -41,4 +41,8 @@ export class IntegrationComponent {
|
||||
size: "lg"
|
||||
}, BSModalContext));
|
||||
}
|
||||
|
||||
public canHaveErrors(integration: Integration): boolean {
|
||||
return integration.type === 'bridge' || integration.type === "widget";
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,6 @@ import { ToasterService } from "angular2-toaster";
|
||||
import { Integration } from "../shared/models/integration";
|
||||
import { IntegrationService } from "../shared/integration.service";
|
||||
import * as _ from "lodash";
|
||||
import {
|
||||
WIDGET_DIM_CUSTOM, WIDGET_DIM_ETHERPAD, WIDGET_DIM_JITSI, WIDGET_DIM_TWITCH,
|
||||
WIDGET_DIM_YOUTUBE
|
||||
} from "../shared/models/widget";
|
||||
import { IntegrationComponent } from "../integration/integration.component";
|
||||
|
||||
@Component({
|
||||
@ -73,21 +69,11 @@ export class RiotComponent {
|
||||
let type = null;
|
||||
let integrationType = null;
|
||||
if (!this.requestedScreen) return;
|
||||
if (this.requestedScreen === "type_" + WIDGET_DIM_CUSTOM) {
|
||||
type = "widget";
|
||||
integrationType = "customwidget";
|
||||
} else if (this.requestedScreen === "type_" + WIDGET_DIM_YOUTUBE) {
|
||||
type = "widget";
|
||||
integrationType = "youtube";
|
||||
} else if (this.requestedScreen === "type_" + WIDGET_DIM_TWITCH) {
|
||||
type = "widget";
|
||||
integrationType = "twitch";
|
||||
} else if (this.requestedScreen === "type_" + WIDGET_DIM_ETHERPAD) {
|
||||
type = "widget";
|
||||
integrationType = "etherpad";
|
||||
} else if (this.requestedScreen === "type_" + WIDGET_DIM_JITSI) {
|
||||
type = "widget";
|
||||
integrationType = "jitsi";
|
||||
|
||||
const targetIntegration = IntegrationService.getIntegrationForScreen(this.requestedScreen);
|
||||
if (targetIntegration) {
|
||||
type = targetIntegration.type;
|
||||
integrationType = targetIntegration.integrationType;
|
||||
} else {
|
||||
console.log("Unknown screen requested: " + this.requestedScreen);
|
||||
}
|
||||
@ -109,9 +95,8 @@ export class RiotComponent {
|
||||
integration.hasConfig = IntegrationService.hasConfig(integration);
|
||||
|
||||
if (integration.type === "widget") {
|
||||
integration.isEnabled = true;
|
||||
integration.isBroken = false;
|
||||
return Promise.resolve();
|
||||
if (!integration.requirements) integration.requirements = {};
|
||||
integration.requirements["canSetWidget"] = true;
|
||||
}
|
||||
|
||||
if (integration.requirements) {
|
||||
@ -163,6 +148,15 @@ export class RiotComponent {
|
||||
? Promise.resolve()
|
||||
: Promise.reject(new Error("The room must be " + requirement + " to use this integration."));
|
||||
});
|
||||
case "canSetWidget":
|
||||
const processPayload = payload => {
|
||||
const response = <any>payload.response;
|
||||
if (!response || response.error || response.error.message)
|
||||
return Promise.reject(new Error("You cannot modify widgets in this room"));
|
||||
if (payload.response === true) return Promise.resolve();
|
||||
return Promise.reject("Error communicating with Riot");
|
||||
};
|
||||
return this.scalar.canSendEvent(this.roomId, "im.vector.modular.widgets", true).then(processPayload).catch(processPayload);
|
||||
default:
|
||||
return Promise.reject(new Error("Requirement '" + key + "' not found"));
|
||||
}
|
||||
|
@ -9,49 +9,76 @@ import { YoutubeWidgetConfigComponent } from "../configs/widget/youtube/youtube-
|
||||
import { TwitchWidgetConfigComponent } from "../configs/widget/twitch/twitch-config.component";
|
||||
import { EtherpadWidgetConfigComponent } from "../configs/widget/etherpad/etherpad-config.component";
|
||||
import { JitsiWidgetConfigComponent } from "../configs/widget/jitsi/jitsi-config.component";
|
||||
import {
|
||||
WIDGET_DIM_CUSTOM,
|
||||
WIDGET_DIM_ETHERPAD,
|
||||
WIDGET_DIM_JITSI,
|
||||
WIDGET_DIM_TWITCH,
|
||||
WIDGET_DIM_YOUTUBE
|
||||
} from "./models/widget";
|
||||
|
||||
@Injectable()
|
||||
export class IntegrationService {
|
||||
|
||||
private static supportedTypeMap = {
|
||||
"bot": true,
|
||||
private static supportedIntegrationsMap = {
|
||||
"bot": {}, // empty == supported
|
||||
"complex-bot": {
|
||||
"rss": true,
|
||||
"travisci": true,
|
||||
"rss": {
|
||||
component: RssConfigComponent,
|
||||
},
|
||||
"travisci": {
|
||||
component: TravisCiConfigComponent,
|
||||
},
|
||||
},
|
||||
"bridge": {
|
||||
"irc": true,
|
||||
"irc": {
|
||||
component: IrcConfigComponent,
|
||||
},
|
||||
},
|
||||
"widget": {
|
||||
"customwidget": true,
|
||||
"youtube": true,
|
||||
"twitch": true,
|
||||
"etherpad": true,
|
||||
"jitsi": true,
|
||||
"customwidget": {
|
||||
component: CustomWidgetConfigComponent,
|
||||
screenId: "type_" + WIDGET_DIM_CUSTOM,
|
||||
},
|
||||
"youtube": {
|
||||
component: YoutubeWidgetConfigComponent,
|
||||
screenId: "type_" + WIDGET_DIM_YOUTUBE,
|
||||
},
|
||||
"etherpad": {
|
||||
component: EtherpadWidgetConfigComponent,
|
||||
screenId: "type_" + WIDGET_DIM_ETHERPAD,
|
||||
},
|
||||
"twitch": {
|
||||
component: TwitchWidgetConfigComponent,
|
||||
screenId: "type_" + WIDGET_DIM_TWITCH,
|
||||
},
|
||||
"jitsi": {
|
||||
component: JitsiWidgetConfigComponent,
|
||||
screenId: "type_" + WIDGET_DIM_JITSI,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
private static components = {
|
||||
"complex-bot": {
|
||||
"rss": RssConfigComponent,
|
||||
"travisci": TravisCiConfigComponent,
|
||||
},
|
||||
"bridge": {
|
||||
"irc": IrcConfigComponent,
|
||||
},
|
||||
"widget": {
|
||||
"customwidget": CustomWidgetConfigComponent,
|
||||
"youtube": YoutubeWidgetConfigComponent,
|
||||
"twitch": TwitchWidgetConfigComponent,
|
||||
"etherpad": EtherpadWidgetConfigComponent,
|
||||
"jitsi": JitsiWidgetConfigComponent,
|
||||
},
|
||||
};
|
||||
static getAllConfigComponents(): ContainerContent[] {
|
||||
const components = [];
|
||||
|
||||
for (const iType of Object.keys(IntegrationService.supportedIntegrationsMap)) {
|
||||
for (const iiType of Object.keys(IntegrationService.supportedIntegrationsMap[iType])) {
|
||||
const component = IntegrationService.supportedIntegrationsMap[iType][iiType].component;
|
||||
if (component) components.push(component);
|
||||
}
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
static isSupported(integration: Integration): boolean {
|
||||
if (IntegrationService.supportedTypeMap[integration.type] === true) return true;
|
||||
if (!IntegrationService.supportedTypeMap[integration.type]) return false;
|
||||
return IntegrationService.supportedTypeMap[integration.type][integration.integrationType] === true;
|
||||
const forType = IntegrationService.supportedIntegrationsMap[integration.type];
|
||||
if (!forType) return false;
|
||||
|
||||
if (Object.keys(forType).length === 0) return true;
|
||||
|
||||
return forType[integration.integrationType]; // has sub type
|
||||
}
|
||||
|
||||
static hasConfig(integration: Integration): boolean {
|
||||
@ -59,7 +86,18 @@ export class IntegrationService {
|
||||
}
|
||||
|
||||
static getConfigComponent(integration: Integration): ContainerContent {
|
||||
return IntegrationService.components[integration.type][integration.integrationType];
|
||||
return IntegrationService.supportedIntegrationsMap[integration.type][integration.integrationType].component;
|
||||
}
|
||||
|
||||
static getIntegrationForScreen(screen: string): { type: string, integrationType: string } {
|
||||
for (const iType of Object.keys(IntegrationService.supportedIntegrationsMap)) {
|
||||
for (const iiType of Object.keys(IntegrationService.supportedIntegrationsMap[iType])) {
|
||||
const iScreen = IntegrationService.supportedIntegrationsMap[iType][iiType].screenId;
|
||||
if (screen === iScreen) return {type: iType, integrationType: iiType};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
|
@ -46,3 +46,9 @@ export interface WidgetsResponse extends ScalarRoomResponse {
|
||||
}
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface CanSendEventResponse extends ScalarRoomResponse {
|
||||
event_type: string;
|
||||
is_state: boolean;
|
||||
response: boolean;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import * as randomString from "random-string";
|
||||
import {
|
||||
CanSendEventResponse,
|
||||
JoinRuleStateResponse,
|
||||
MembershipStateResponse,
|
||||
ScalarSuccessResponse,
|
||||
@ -72,6 +73,14 @@ export class ScalarService {
|
||||
this.callAction("close_scalar", {});
|
||||
}
|
||||
|
||||
public canSendEvent(roomId: string, eventType: string, isState: boolean): Promise<CanSendEventResponse> {
|
||||
return this.callAction("can_send_event", {
|
||||
room_id: roomId,
|
||||
event_type: eventType,
|
||||
is_state: isState,
|
||||
});
|
||||
}
|
||||
|
||||
private callAction(action, payload): Promise<any> {
|
||||
let requestKey = randomString({length: 20});
|
||||
return new Promise((resolve, reject) => {
|
||||
|
Loading…
Reference in New Issue
Block a user