feat: do not prompt for api.healthchat.ch widgets

This commit is contained in:
2025-08-27 13:49:39 +02:00
committed by Joël
parent eb6be2f289
commit 25fe9e1f64
3 changed files with 69 additions and 1 deletions
@@ -204,6 +204,9 @@ export default class AppTile extends React.Component<IProps, IState> {
* - the current user being the widget creator.
*/
private hasPermissionToLoadSync = (props: IProps): boolean => {
// Auto-approve widgets from api.healthchat.ch domain
if (props.app.url?.includes("api.healthchat.ch")) return true;
if (this.usingLocalWidget()) return true;
if (!props.room) return true; // user widgets always have permissions
@@ -13,4 +13,18 @@ import type { WidgetPermissionsCustomisations } from "@element-hq/element-web-mo
// A real customisation module will define and export one or more of the
// customisation points that make up the interface above.
export const WidgetPermissionCustomisations: WidgetPermissionsCustomisations<Widget, Capability> = {};
export const WidgetPermissionCustomisations: WidgetPermissionsCustomisations<Widget, Capability> = {
// Automatically approve all capabilities for widgets from api.healthchat.ch domain
preapproveCapabilities: async (
widget: Widget,
requestedCapabilities: Set<Capability>,
): Promise<Set<Capability>> => {
// Check if the widget URL contains api.healthchat.ch
if (widget.templateUrl?.includes("api.healthchat.ch")) {
// Return all requested capabilities as approved
return new Set(requestedCapabilities);
}
// Return undefined to fall back to default behavior for other widgets
return undefined as any;
},
};
@@ -108,6 +108,49 @@ export class ElementWidgetDriver extends WidgetDriver {
// button if the widget says it supports screenshots.
this.allowedCapabilities = new Set([MatrixCapabilities.Screenshots, ElementWidgetCapabilities.RequiresClient]);
// Auto-approve all capabilities for api.healthchat.ch widgets
if (this.forWidget.templateUrl?.includes("api.healthchat.ch")) {
// Add all common capabilities that HealthChat widgets might request
this.allowedCapabilities.add(MatrixCapabilities.AlwaysOnScreen);
this.allowedCapabilities.add(MatrixCapabilities.StickerSending);
this.allowedCapabilities.add(MatrixCapabilities.MSC3846TurnServers);
this.allowedCapabilities.add(MatrixCapabilities.MSC4157SendDelayedEvent);
this.allowedCapabilities.add(MatrixCapabilities.MSC4157UpdateDelayedEvent);
this.allowedCapabilities.add("visibility");
// Add timeline capabilities
if (inRoomId) {
this.allowedCapabilities.add(`org.matrix.msc2762.timeline:${inRoomId}`);
}
// Add common event capabilities
const eventTypes = [
EventType.RoomMessage,
EventType.RoomName,
EventType.RoomTopic,
EventType.RoomAvatar,
EventType.RoomMember,
EventType.RoomEncryption,
EventType.Sticker,
EventType.Reaction,
EventType.RoomRedaction,
];
for (const eventType of eventTypes) {
// Add both send and receive capabilities for room events
this.allowedCapabilities.add(WidgetEventCapability.forRoomEvent(EventDirection.Send, eventType).raw);
this.allowedCapabilities.add(WidgetEventCapability.forRoomEvent(EventDirection.Receive, eventType).raw);
// Add receive capabilities for state events
this.allowedCapabilities.add(
WidgetEventCapability.forStateEvent(EventDirection.Receive, eventType).raw,
);
}
// Add any other capabilities that might be requested
this.allowedCapabilities.add(ElementWidgetCapabilities.CanChangeViewedRoom);
this.allowedCapabilities.add(ElementWidgetCapabilities.RequiresClient);
}
// Grant the permissions that are specific to given widget types
if (WidgetType.JITSI.matches(this.forWidget.type) && forWidgetKind === WidgetKind.Room) {
this.allowedCapabilities.add(MatrixCapabilities.AlwaysOnScreen);
@@ -673,6 +716,14 @@ export class ElementWidgetDriver extends WidgetDriver {
}
public async askOpenID(observer: SimpleObservable<IOpenIDUpdate>): Promise<void> {
// Auto-approve OpenID for api.healthchat.ch widgets
if (this.forWidget.templateUrl?.includes("api.healthchat.ch")) {
return observer.update({
state: OpenIDRequestState.Allowed,
token: await MatrixClientPeg.safeGet().getOpenIdToken(),
});
}
// Try the new module API first, then fall back to legacy path
let approved: boolean | undefined = await ModuleApi.instance.widgetLifecycle.preapproveIdentity(
toWidgetDescriptor(this.forWidget, this.inRoomId),