Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.

Commit d9b2ec0

Browse files
authored
Configure widget permissions using ModuleRunner.instance.invoke (#11)
* widget permissions using "events" object Signed-off-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net> * lint fix Signed-off-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net> * WidgetLifecycle test Signed-off-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net> --------- Signed-off-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net> Co-authored-by: Mikhail Aheichyk <mikhail.aheichyk@nordeck.net>
1 parent c1b673b commit d9b2ec0

File tree

3 files changed

+166
-0
lines changed

3 files changed

+166
-0
lines changed

src/lifecycles/WidgetLifecycle.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
Copyright 2023 Mikhail Aheichyk
3+
Copyright 2023 Nordeck IT + Consulting GmbH.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
export enum WidgetLifecycle {
19+
CapabilitiesRequest = "capabilities_request",
20+
PreLoadRequest = "preload_request",
21+
IdentityRequest = "identity_request",
22+
}
23+
24+
export type CapabilitiesOpts = {
25+
approvedCapabilities: Set<string> | undefined;
26+
};
27+
28+
export type ApprovalOpts = {
29+
approved: boolean | undefined;
30+
};
31+
32+
export type CapabilitiesListener = (
33+
capabilitiesOpts: CapabilitiesOpts,
34+
widgetInfo: WidgetInfo,
35+
requestedCapabilities: Set<string>,
36+
) => void;
37+
38+
/**
39+
* Listener for PreLoad and Identity requests
40+
*/
41+
export type ApprovalListener = (
42+
approvalOpts: ApprovalOpts,
43+
widgetInfo: WidgetInfo
44+
) => void;
45+
46+
/**
47+
* Represents the widget
48+
*/
49+
export interface WidgetInfo {
50+
/**
51+
* The user ID who created the widget.
52+
*/
53+
creatorUserId: string;
54+
55+
/**
56+
* The type of widget.
57+
*/
58+
type: string;
59+
60+
/**
61+
* The ID of the widget.
62+
*/
63+
id: string;
64+
65+
/**
66+
* The name of the widget, or null if not set.
67+
*/
68+
name: string | null;
69+
70+
/**
71+
* The title for the widget, or null if not set.
72+
*/
73+
title: string | null;
74+
75+
/**
76+
* The templated URL for the widget.
77+
*/
78+
templateUrl: string;
79+
80+
/**
81+
* The origin for this widget.
82+
*/
83+
origin: string;
84+
}

src/lifecycles/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ limitations under the License.
1515
*/
1616

1717
import { RoomViewLifecycle } from "./RoomViewLifecycle";
18+
import { WidgetLifecycle } from "./WidgetLifecycle";
1819

1920
export type AnyLifecycle =
2021
| RoomViewLifecycle
22+
| WidgetLifecycle
2123
;
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
Copyright 2023 Mikhail Aheichyk
3+
Copyright 2023 Nordeck IT + Consulting GmbH.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
import {
19+
ApprovalListener, ApprovalOpts,
20+
CapabilitiesListener,
21+
CapabilitiesOpts,
22+
WidgetInfo, WidgetLifecycle,
23+
} from "../../src/lifecycles/WidgetLifecycle";
24+
import { RuntimeModule } from "../../src/RuntimeModule";
25+
26+
describe("WidgetLifecycle", () => {
27+
const mockWidget: WidgetInfo = {
28+
creatorUserId: "@user-id",
29+
type: "m.custom",
30+
id: "widget-id",
31+
name: null,
32+
title: null,
33+
templateUrl: "https://example.com/some_path",
34+
origin: "https://example.com",
35+
};
36+
37+
let module: RuntimeModule;
38+
39+
beforeAll(() => {
40+
module = new class extends RuntimeModule {
41+
constructor() {
42+
super(undefined);
43+
44+
this.on(WidgetLifecycle.CapabilitiesRequest, this.capabilitiesListener);
45+
this.on(WidgetLifecycle.PreLoadRequest, this.preloadListener);
46+
this.on(WidgetLifecycle.IdentityRequest, this.identityListener);
47+
}
48+
49+
protected capabilitiesListener: CapabilitiesListener = (
50+
capabilitiesOpts: CapabilitiesOpts,
51+
widgetInfo: WidgetInfo,
52+
requestedCapabilities: Set<string>,
53+
) => {
54+
capabilitiesOpts.approvedCapabilities = requestedCapabilities;
55+
};
56+
57+
protected preloadListener: ApprovalListener = (approvalOpts: ApprovalOpts, widgetInfo: WidgetInfo) => {
58+
approvalOpts.approved = true;
59+
};
60+
61+
protected identityListener: ApprovalListener = (approvalOpts: ApprovalOpts, widgetInfo: WidgetInfo) => {
62+
approvalOpts.approved = false;
63+
};
64+
};
65+
});
66+
67+
it('should handle widget permissions requests', () => {
68+
const capabilitiesOpts: CapabilitiesOpts = {approvedCapabilities: new Set()};
69+
module.emit(WidgetLifecycle.CapabilitiesRequest, capabilitiesOpts, mockWidget, new Set(["org.matrix.msc2931.navigate"]));
70+
expect(capabilitiesOpts.approvedCapabilities).toEqual(new Set(["org.matrix.msc2931.navigate"]));
71+
72+
const preloadOpts: ApprovalOpts = {approved: undefined};
73+
module.emit(WidgetLifecycle.PreLoadRequest, preloadOpts, mockWidget);
74+
expect(preloadOpts.approved).toBe(true);
75+
76+
const identityOpts: ApprovalOpts = {approved: undefined};
77+
module.emit(WidgetLifecycle.IdentityRequest, identityOpts, mockWidget);
78+
expect(identityOpts.approved).toBe(false);
79+
});
80+
});

0 commit comments

Comments
 (0)