Use the WidgetDriver to run OIDC requests
Fixes https://github.com/vector-im/element-web/issues/15775
This commit is contained in:
parent
2144932bbc
commit
28c78509a1
2 changed files with 42 additions and 57 deletions
|
@ -17,8 +17,6 @@
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import {
|
import {
|
||||||
ClientWidgetApi,
|
ClientWidgetApi,
|
||||||
IGetOpenIDActionRequest,
|
|
||||||
IGetOpenIDActionResponseData,
|
|
||||||
IStickerActionRequest,
|
IStickerActionRequest,
|
||||||
IStickyActionRequest,
|
IStickyActionRequest,
|
||||||
ITemplateParams,
|
ITemplateParams,
|
||||||
|
@ -27,10 +25,8 @@ import {
|
||||||
IWidgetApiRequestEmptyData,
|
IWidgetApiRequestEmptyData,
|
||||||
IWidgetData,
|
IWidgetData,
|
||||||
MatrixCapabilities,
|
MatrixCapabilities,
|
||||||
OpenIDRequestState,
|
|
||||||
runTemplate,
|
runTemplate,
|
||||||
Widget,
|
Widget,
|
||||||
WidgetApiToWidgetAction,
|
|
||||||
WidgetApiFromWidgetAction,
|
WidgetApiFromWidgetAction,
|
||||||
IModalWidgetOpenRequest,
|
IModalWidgetOpenRequest,
|
||||||
IWidgetApiErrorResponseData,
|
IWidgetApiErrorResponseData,
|
||||||
|
@ -50,8 +46,6 @@ import ActiveWidgetStore from "../ActiveWidgetStore";
|
||||||
import { objectShallowClone } from "../../utils/objects";
|
import { objectShallowClone } from "../../utils/objects";
|
||||||
import defaultDispatcher from "../../dispatcher/dispatcher";
|
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||||
import { ElementWidgetActions, IViewRoomApiRequest } from "./ElementWidgetActions";
|
import { ElementWidgetActions, IViewRoomApiRequest } from "./ElementWidgetActions";
|
||||||
import Modal from "../../Modal";
|
|
||||||
import WidgetOpenIDPermissionsDialog from "../../components/views/dialogs/WidgetOpenIDPermissionsDialog";
|
|
||||||
import {ModalWidgetStore} from "../ModalWidgetStore";
|
import {ModalWidgetStore} from "../ModalWidgetStore";
|
||||||
import ThemeWatcher from "../../settings/watchers/ThemeWatcher";
|
import ThemeWatcher from "../../settings/watchers/ThemeWatcher";
|
||||||
import {getCustomTheme} from "../../theme";
|
import {getCustomTheme} from "../../theme";
|
||||||
|
@ -235,55 +229,6 @@ export class StopGapWidget extends EventEmitter {
|
||||||
return this.messaging.widget.id;
|
return this.messaging.widget.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private onOpenIdReq = async (ev: CustomEvent<IGetOpenIDActionRequest>) => {
|
|
||||||
ev.preventDefault();
|
|
||||||
|
|
||||||
const rawUrl = this.appTileProps.app.url;
|
|
||||||
const widgetSecurityKey = WidgetUtils.getWidgetSecurityKey(this.widgetId, rawUrl, this.appTileProps.userWidget);
|
|
||||||
|
|
||||||
const settings = SettingsStore.getValue("widgetOpenIDPermissions");
|
|
||||||
if (settings.deny && settings.deny.includes(widgetSecurityKey)) {
|
|
||||||
this.messaging.transport.reply(ev.detail, <IGetOpenIDActionResponseData>{
|
|
||||||
state: OpenIDRequestState.Blocked,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (settings.allow && settings.allow.includes(widgetSecurityKey)) {
|
|
||||||
const credentials = await MatrixClientPeg.get().getOpenIdToken();
|
|
||||||
this.messaging.transport.reply(ev.detail, <IGetOpenIDActionResponseData>{
|
|
||||||
state: OpenIDRequestState.Allowed,
|
|
||||||
...credentials,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Confirm that we received the request
|
|
||||||
this.messaging.transport.reply(ev.detail, <IGetOpenIDActionResponseData>{
|
|
||||||
state: OpenIDRequestState.PendingUserConfirmation,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Actually ask for permission to send the user's data
|
|
||||||
Modal.createTrackedDialog("OpenID widget permissions", '', WidgetOpenIDPermissionsDialog, {
|
|
||||||
widgetUrl: rawUrl,
|
|
||||||
widgetId: this.widgetId,
|
|
||||||
isUserWidget: this.appTileProps.userWidget,
|
|
||||||
|
|
||||||
onFinished: async (confirm) => {
|
|
||||||
const responseBody: IGetOpenIDActionResponseData = {
|
|
||||||
state: confirm ? OpenIDRequestState.Allowed : OpenIDRequestState.Blocked,
|
|
||||||
original_request_id: ev.detail.requestId, // eslint-disable-line camelcase
|
|
||||||
};
|
|
||||||
if (confirm) {
|
|
||||||
const credentials = await MatrixClientPeg.get().getOpenIdToken();
|
|
||||||
Object.assign(responseBody, credentials);
|
|
||||||
}
|
|
||||||
this.messaging.transport.send(WidgetApiToWidgetAction.OpenIDCredentials, responseBody).catch(error => {
|
|
||||||
console.error("Failed to send OpenID credentials: ", error);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private onOpenModal = async (ev: CustomEvent<IModalWidgetOpenRequest>) => {
|
private onOpenModal = async (ev: CustomEvent<IModalWidgetOpenRequest>) => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
if (ModalWidgetStore.instance.canOpenModalWidget()) {
|
if (ModalWidgetStore.instance.canOpenModalWidget()) {
|
||||||
|
@ -305,7 +250,6 @@ export class StopGapWidget extends EventEmitter {
|
||||||
this.messaging = new ClientWidgetApi(this.mockWidget, iframe, driver);
|
this.messaging = new ClientWidgetApi(this.mockWidget, iframe, driver);
|
||||||
this.messaging.on("preparing", () => this.emit("preparing"));
|
this.messaging.on("preparing", () => this.emit("preparing"));
|
||||||
this.messaging.on("ready", () => this.emit("ready"));
|
this.messaging.on("ready", () => this.emit("ready"));
|
||||||
this.messaging.on(`action:${WidgetApiFromWidgetAction.GetOpenIDCredentials}`, this.onOpenIdReq);
|
|
||||||
this.messaging.on(`action:${WidgetApiFromWidgetAction.OpenModalWidget}`, this.onOpenModal);
|
this.messaging.on(`action:${WidgetApiFromWidgetAction.OpenModalWidget}`, this.onOpenModal);
|
||||||
WidgetMessagingStore.instance.storeMessaging(this.mockWidget, this.messaging);
|
WidgetMessagingStore.instance.storeMessaging(this.mockWidget, this.messaging);
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,12 @@
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Capability,
|
Capability,
|
||||||
|
IOpenIDCredentials,
|
||||||
|
IOpenIDUpdate,
|
||||||
ISendEventDetails,
|
ISendEventDetails,
|
||||||
MatrixCapabilities,
|
MatrixCapabilities,
|
||||||
|
OpenIDRequestState,
|
||||||
|
SimpleObservable,
|
||||||
Widget,
|
Widget,
|
||||||
WidgetDriver,
|
WidgetDriver,
|
||||||
WidgetKind,
|
WidgetKind,
|
||||||
|
@ -26,6 +30,9 @@ import { iterableDiff, iterableUnion } from "../../utils/iterables";
|
||||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||||
import ActiveRoomObserver from "../../ActiveRoomObserver";
|
import ActiveRoomObserver from "../../ActiveRoomObserver";
|
||||||
import Modal from "../../Modal";
|
import Modal from "../../Modal";
|
||||||
|
import WidgetUtils from "../../utils/WidgetUtils";
|
||||||
|
import SettingsStore from "../../settings/SettingsStore";
|
||||||
|
import WidgetOpenIDPermissionsDialog from "../../components/views/dialogs/WidgetOpenIDPermissionsDialog";
|
||||||
import WidgetCapabilitiesPromptDialog, {
|
import WidgetCapabilitiesPromptDialog, {
|
||||||
getRememberedCapabilitiesForWidget,
|
getRememberedCapabilitiesForWidget,
|
||||||
} from "../../components/views/dialogs/WidgetCapabilitiesPromptDialog";
|
} from "../../components/views/dialogs/WidgetCapabilitiesPromptDialog";
|
||||||
|
@ -79,7 +86,7 @@ export class StopGapWidgetDriver extends WidgetDriver {
|
||||||
|
|
||||||
if (!client || !roomId) throw new Error("Not in a room or not attached to a client");
|
if (!client || !roomId) throw new Error("Not in a room or not attached to a client");
|
||||||
|
|
||||||
let r: {event_id: string} = null; // eslint-disable-line camelcase
|
let r: { event_id: string } = null; // eslint-disable-line camelcase
|
||||||
if (stateKey !== null) {
|
if (stateKey !== null) {
|
||||||
// state event
|
// state event
|
||||||
r = await client.sendStateEvent(roomId, eventType, content, stateKey);
|
r = await client.sendStateEvent(roomId, eventType, content, stateKey);
|
||||||
|
@ -90,4 +97,38 @@ export class StopGapWidgetDriver extends WidgetDriver {
|
||||||
|
|
||||||
return {roomId, eventId: r.event_id};
|
return {roomId, eventId: r.event_id};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async askOpenID(observer: SimpleObservable<IOpenIDUpdate>) {
|
||||||
|
const isUserWidget = this.forWidgetKind !== WidgetKind.Room; // modal and account widgets are "user" widgets
|
||||||
|
const rawUrl = this.forWidget.templateUrl;
|
||||||
|
const widgetSecurityKey = WidgetUtils.getWidgetSecurityKey(this.forWidget.id, rawUrl, isUserWidget);
|
||||||
|
|
||||||
|
const getToken = (): Promise<IOpenIDCredentials> => {
|
||||||
|
return MatrixClientPeg.get().getOpenIdToken();
|
||||||
|
};
|
||||||
|
|
||||||
|
const settings = SettingsStore.getValue("widgetOpenIDPermissions");
|
||||||
|
if (settings?.deny?.includes(widgetSecurityKey)) {
|
||||||
|
return observer.update({state: OpenIDRequestState.Blocked});
|
||||||
|
}
|
||||||
|
if (settings?.allow?.includes(widgetSecurityKey)) {
|
||||||
|
return observer.update({state: OpenIDRequestState.Allowed, token: await getToken()});
|
||||||
|
}
|
||||||
|
|
||||||
|
observer.update({state: OpenIDRequestState.PendingUserConfirmation});
|
||||||
|
|
||||||
|
Modal.createTrackedDialog("OpenID widget permissions", '', WidgetOpenIDPermissionsDialog, {
|
||||||
|
widgetUrl: rawUrl,
|
||||||
|
widgetId: this.forWidget.id,
|
||||||
|
isUserWidget: isUserWidget,
|
||||||
|
|
||||||
|
onFinished: async (confirm) => {
|
||||||
|
if (!confirm) {
|
||||||
|
return observer.update({state: OpenIDRequestState.Blocked});
|
||||||
|
}
|
||||||
|
|
||||||
|
return observer.update({state: OpenIDRequestState.Allowed, token: await getToken()});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue