Use device storage for allowed widgets if account data not supported

With guest accounts, account data is not available, so we use device storage to
hold allowed widgets as a good enough place.

Fixes https://github.com/vector-im/element-web/issues/16145
pull/21833/head
J. Ryan Stinnett 2021-01-14 17:30:25 +00:00
parent cb66f7493b
commit 658a8dfa99
4 changed files with 31 additions and 3 deletions

View File

@ -127,7 +127,8 @@ const WidgetContextMenu: React.FC<IProps> = ({
console.info("Revoking permission for widget to load: " + app.eventId); console.info("Revoking permission for widget to load: " + app.eventId);
const current = SettingsStore.getValue("allowedWidgets", roomId); const current = SettingsStore.getValue("allowedWidgets", roomId);
current[app.eventId] = false; current[app.eventId] = false;
SettingsStore.setValue("allowedWidgets", roomId, SettingLevel.ROOM_ACCOUNT, current).catch(err => { const level = SettingsStore.firstSupportedLevel("allowedWidgets");
SettingsStore.setValue("allowedWidgets", roomId, level, current).catch(err => {
console.error(err); console.error(err);
// We don't really need to do anything about this - the user will just hit the button again. // We don't really need to do anything about this - the user will just hit the button again.
}); });

View File

@ -240,7 +240,8 @@ export default class AppTile extends React.Component {
console.info("Granting permission for widget to load: " + this.props.app.eventId); console.info("Granting permission for widget to load: " + this.props.app.eventId);
const current = SettingsStore.getValue("allowedWidgets", roomId); const current = SettingsStore.getValue("allowedWidgets", roomId);
current[this.props.app.eventId] = true; current[this.props.app.eventId] = true;
SettingsStore.setValue("allowedWidgets", roomId, SettingLevel.ROOM_ACCOUNT, current).then(() => { const level = SettingsStore.firstSupportedLevel("allowedWidgets");
SettingsStore.setValue("allowedWidgets", roomId, level, current).then(() => {
this.setState({hasPermissionToLoad: true}); this.setState({hasPermissionToLoad: true});
// Fetch a token for the integration manager, now that we're allowed to // Fetch a token for the integration manager, now that we're allowed to

View File

@ -421,7 +421,8 @@ export const SETTINGS: {[setting: string]: ISetting} = {
default: true, default: true,
}, },
"allowedWidgets": { "allowedWidgets": {
supportedLevels: [SettingLevel.ROOM_ACCOUNT], supportedLevels: [SettingLevel.ROOM_ACCOUNT, SettingLevel.ROOM_DEVICE],
supportedLevelsAreOrdered: true,
default: {}, // none allowed default: {}, // none allowed
}, },
"analyticsOptIn": { "analyticsOptIn": {

View File

@ -467,6 +467,31 @@ export default class SettingsStore {
return LEVEL_HANDLERS[level].isSupported(); return LEVEL_HANDLERS[level].isSupported();
} }
/**
* Determines the first supported level out of all the levels that can be used for a
* specific setting.
* @param {string} settingName The setting name.
* @return {SettingLevel}
*/
public static firstSupportedLevel(settingName: string): SettingLevel {
// Verify that the setting is actually a setting
const setting = SETTINGS[settingName];
if (!setting) {
throw new Error("Setting '" + settingName + "' does not appear to be a setting.");
}
const levelOrder = (setting.supportedLevelsAreOrdered ? setting.supportedLevels : LEVEL_ORDER);
if (!levelOrder.includes(SettingLevel.DEFAULT)) levelOrder.push(SettingLevel.DEFAULT); // always include default
const handlers = SettingsStore.getHandlers(settingName);
for (const level of levelOrder) {
const handler = handlers[level];
if (!handler) continue;
return level;
}
}
/** /**
* Debugging function for reading explicit setting values without going through the * Debugging function for reading explicit setting values without going through the
* complicated/biased functions in the SettingsStore. This will print information to * complicated/biased functions in the SettingsStore. This will print information to