Remember all capabilities given to a widget

Fixes https://github.com/vector-im/element-web/issues/18786

Instead of replacing the remembered set, we now add to it. This should be safe as the user expectation was previously to remember the capabilities, so we can keep appending to that list.

This commit also moves the utility functions closer to the widget driver as they aren't needed in the dialog anymore.
This commit is contained in:
Travis Ralston 2021-08-25 22:30:57 -06:00
parent ee95e36a7c
commit 76cc5bfb7d
2 changed files with 19 additions and 16 deletions

View file

@ -31,14 +31,6 @@ import LabelledToggleSwitch from "../elements/LabelledToggleSwitch";
import { CapabilityText } from "../../../widgets/CapabilityText"; import { CapabilityText } from "../../../widgets/CapabilityText";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
export function getRememberedCapabilitiesForWidget(widget: Widget): Capability[] {
return JSON.parse(localStorage.getItem(`widget_${widget.id}_approved_caps`) || "[]");
}
function setRememberedCapabilitiesForWidget(widget: Widget, caps: Capability[]) {
localStorage.setItem(`widget_${widget.id}_approved_caps`, JSON.stringify(caps));
}
interface IProps extends IDialogProps { interface IProps extends IDialogProps {
requestedCapabilities: Set<Capability>; requestedCapabilities: Set<Capability>;
widget: Widget; widget: Widget;
@ -95,10 +87,7 @@ export default class WidgetCapabilitiesPromptDialog extends React.PureComponent<
}; };
private closeAndTryRemember(approved: Capability[]) { private closeAndTryRemember(approved: Capability[]) {
if (this.state.rememberSelection) { this.props.onFinished({ approved, remember: this.state.rememberSelection });
setRememberedCapabilitiesForWidget(this.props.widget, approved);
}
this.props.onFinished({ approved });
} }
public render() { public render() {

View file

@ -33,9 +33,7 @@ import { MatrixClientPeg } from "../../MatrixClientPeg";
import ActiveRoomObserver from "../../ActiveRoomObserver"; import ActiveRoomObserver from "../../ActiveRoomObserver";
import Modal from "../../Modal"; import Modal from "../../Modal";
import WidgetOpenIDPermissionsDialog from "../../components/views/dialogs/WidgetOpenIDPermissionsDialog"; import WidgetOpenIDPermissionsDialog from "../../components/views/dialogs/WidgetOpenIDPermissionsDialog";
import WidgetCapabilitiesPromptDialog, { import WidgetCapabilitiesPromptDialog from "../../components/views/dialogs/WidgetCapabilitiesPromptDialog";
getRememberedCapabilitiesForWidget,
} from "../../components/views/dialogs/WidgetCapabilitiesPromptDialog";
import { WidgetPermissionCustomisations } from "../../customisations/WidgetPermissions"; import { WidgetPermissionCustomisations } from "../../customisations/WidgetPermissions";
import { OIDCState, WidgetPermissionStore } from "./WidgetPermissionStore"; import { OIDCState, WidgetPermissionStore } from "./WidgetPermissionStore";
import { WidgetType } from "../../widgets/WidgetType"; import { WidgetType } from "../../widgets/WidgetType";
@ -48,6 +46,14 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
// TODO: Purge this from the universe // TODO: Purge this from the universe
function getRememberedCapabilitiesForWidget(widget: Widget): Capability[] {
return JSON.parse(localStorage.getItem(`widget_${widget.id}_approved_caps`) || "[]");
}
function setRememberedCapabilitiesForWidget(widget: Widget, caps: Capability[]) {
localStorage.setItem(`widget_${widget.id}_approved_caps`, JSON.stringify(caps));
}
export class StopGapWidgetDriver extends WidgetDriver { export class StopGapWidgetDriver extends WidgetDriver {
private allowedCapabilities: Set<Capability>; private allowedCapabilities: Set<Capability>;
@ -100,6 +106,7 @@ export class StopGapWidgetDriver extends WidgetDriver {
} }
} }
// TODO: Do something when the widget requests new capabilities not yet asked for // TODO: Do something when the widget requests new capabilities not yet asked for
let rememberApproved = false;
if (missing.size > 0) { if (missing.size > 0) {
try { try {
const [result] = await Modal.createTrackedDialog( const [result] = await Modal.createTrackedDialog(
@ -111,12 +118,19 @@ export class StopGapWidgetDriver extends WidgetDriver {
widgetKind: this.forWidgetKind, widgetKind: this.forWidgetKind,
}).finished; }).finished;
(result.approved || []).forEach(cap => allowedSoFar.add(cap)); (result.approved || []).forEach(cap => allowedSoFar.add(cap));
rememberApproved = result.remember;
} catch (e) { } catch (e) {
console.error("Non-fatal error getting capabilities: ", e); console.error("Non-fatal error getting capabilities: ", e);
} }
} }
return new Set(iterableUnion(allowedSoFar, requested)); const allAllowed = new Set(iterableUnion(allowedSoFar, requested));
if (rememberApproved) {
setRememberedCapabilitiesForWidget(this.forWidget, Array.from(allAllowed));
}
return allAllowed;
} }
public async sendEvent(eventType: string, content: any, stateKey: string = null): Promise<ISendEventDetails> { public async sendEvent(eventType: string, content: any, stateKey: string = null): Promise<ISendEventDetails> {