Harden Settings using mapped types (#28775)
* Harden Settings using mapped types Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Fix issues found during hardening Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Remove oidc native flow stale key Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
@@ -127,7 +127,7 @@ export class BreadcrumbsStore extends AsyncStoreWithClient<IState> {
|
||||
};
|
||||
|
||||
private async updateRooms(): Promise<void> {
|
||||
let roomIds = SettingsStore.getValue<string[]>("breadcrumb_rooms");
|
||||
let roomIds = SettingsStore.getValue("breadcrumb_rooms");
|
||||
if (!roomIds || roomIds.length === 0) roomIds = [];
|
||||
|
||||
const rooms = filterBoolean(roomIds.map((r) => this.matrixClient?.getRoom(r)));
|
||||
|
||||
@@ -61,7 +61,7 @@ export class CallStore extends AsyncStoreWithClient<{}> {
|
||||
// If the room ID of a previously connected call is still in settings at
|
||||
// this time, that's a sign that we failed to disconnect from it
|
||||
// properly, and need to clean up after ourselves
|
||||
const uncleanlyDisconnectedRoomIds = SettingsStore.getValue<string[]>("activeCallRoomIds");
|
||||
const uncleanlyDisconnectedRoomIds = SettingsStore.getValue("activeCallRoomIds");
|
||||
if (uncleanlyDisconnectedRoomIds.length) {
|
||||
await Promise.all([
|
||||
...uncleanlyDisconnectedRoomIds.map(async (uncleanlyDisconnectedRoomId): Promise<void> => {
|
||||
|
||||
@@ -26,7 +26,9 @@ export type Feature = (typeof FEATURES)[number];
|
||||
* The stored settings for the release announcements.
|
||||
* The boolean is at true when the user has viewed the feature
|
||||
*/
|
||||
type StoredSettings = Record<Feature, boolean>;
|
||||
type StoredSettings = Partial<Record<Feature, boolean>>;
|
||||
|
||||
export type ReleaseAnnouncementData = StoredSettings;
|
||||
|
||||
/**
|
||||
* The events emitted by the ReleaseAnnouncementStore.
|
||||
@@ -82,7 +84,7 @@ export class ReleaseAnnouncementStore extends TypedEventEmitter<ReleaseAnnouncem
|
||||
*/
|
||||
private getViewedReleaseAnnouncements(): StoredSettings {
|
||||
// Clone the settings to avoid to mutate the internal stored value in the SettingsStore
|
||||
return cloneDeep(SettingsStore.getValue<StoredSettings>("releaseAnnouncementData"));
|
||||
return cloneDeep(SettingsStore.getValue("releaseAnnouncementData"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +92,7 @@ export class ReleaseAnnouncementStore extends TypedEventEmitter<ReleaseAnnouncem
|
||||
* @private
|
||||
*/
|
||||
private isReleaseAnnouncementEnabled(): boolean {
|
||||
return SettingsStore.getValue<boolean>(Features.ReleaseAnnouncement);
|
||||
return SettingsStore.getValue(Features.ReleaseAnnouncement);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -252,10 +252,13 @@ export default class RightPanelStore extends ReadyWatchingStore {
|
||||
const room = this.mxClient?.getRoom(this.viewedRoomId);
|
||||
if (!!room) {
|
||||
this.global =
|
||||
this.global ?? convertToStatePanel(SettingsStore.getValue("RightPanel.phasesGlobal"), room);
|
||||
this.global ??
|
||||
convertToStatePanel(SettingsStore.getValue("RightPanel.phasesGlobal"), room) ??
|
||||
undefined;
|
||||
this.byRoom[this.viewedRoomId] =
|
||||
this.byRoom[this.viewedRoomId] ??
|
||||
convertToStatePanel(SettingsStore.getValue("RightPanel.phases", this.viewedRoomId), room);
|
||||
convertToStatePanel(SettingsStore.getValue("RightPanel.phases", this.viewedRoomId), room) ??
|
||||
undefined;
|
||||
} else {
|
||||
logger.warn(
|
||||
"Could not restore the right panel after load because there was no associated room object.",
|
||||
|
||||
@@ -57,10 +57,10 @@ export interface IRightPanelForRoom {
|
||||
history: Array<IRightPanelCard>;
|
||||
}
|
||||
|
||||
interface IRightPanelForRoomStored {
|
||||
export type IRightPanelForRoomStored = {
|
||||
isOpen: boolean;
|
||||
history: Array<IRightPanelCardStored>;
|
||||
}
|
||||
};
|
||||
|
||||
export function convertToStorePanel(cacheRoom?: IRightPanelForRoom): IRightPanelForRoomStored | undefined {
|
||||
if (!cacheRoom) return undefined;
|
||||
@@ -68,7 +68,7 @@ export function convertToStorePanel(cacheRoom?: IRightPanelForRoom): IRightPanel
|
||||
return { isOpen: cacheRoom.isOpen, history: storeHistory };
|
||||
}
|
||||
|
||||
export function convertToStatePanel(storeRoom: IRightPanelForRoomStored, room: Room): IRightPanelForRoom {
|
||||
export function convertToStatePanel(storeRoom: IRightPanelForRoomStored | null, room: Room): IRightPanelForRoom | null {
|
||||
if (!storeRoom) return storeRoom;
|
||||
const stateHistory = [...storeRoom.history].map((panelStateStore) => convertStoreToCard(panelStateStore, room));
|
||||
return { history: stateHistory, isOpen: storeRoom.isOpen };
|
||||
|
||||
@@ -239,7 +239,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
||||
if (!isMetaSpace(space)) {
|
||||
cliSpace = this.matrixClient.getRoom(space);
|
||||
if (!cliSpace?.isSpaceRoom()) return;
|
||||
} else if (!this.enabledMetaSpaces.includes(space as MetaSpace)) {
|
||||
} else if (!this.enabledMetaSpaces.includes(space)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1178,7 +1178,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
||||
}
|
||||
|
||||
// restore selected state from last session if any and still valid
|
||||
const lastSpaceId = window.localStorage.getItem(ACTIVE_SPACE_LS_KEY);
|
||||
const lastSpaceId = window.localStorage.getItem(ACTIVE_SPACE_LS_KEY) as MetaSpace;
|
||||
const valid =
|
||||
lastSpaceId &&
|
||||
(!isMetaSpace(lastSpaceId) ? this.matrixClient.getRoom(lastSpaceId) : enabledMetaSpaces[lastSpaceId]);
|
||||
|
||||
@@ -48,7 +48,7 @@ export interface ISuggestedRoom extends HierarchyRoom {
|
||||
viaServers: string[];
|
||||
}
|
||||
|
||||
export function isMetaSpace(spaceKey?: SpaceKey): boolean {
|
||||
export function isMetaSpace(spaceKey?: SpaceKey): spaceKey is MetaSpace {
|
||||
return (
|
||||
spaceKey === MetaSpace.Home ||
|
||||
spaceKey === MetaSpace.Favourites ||
|
||||
|
||||
@@ -25,9 +25,9 @@ import { Container, IStoredLayout, ILayoutStateEvent, WIDGET_LAYOUT_EVENT_TYPE,
|
||||
export type { IStoredLayout, ILayoutStateEvent };
|
||||
export { Container, WIDGET_LAYOUT_EVENT_TYPE };
|
||||
|
||||
interface ILayoutSettings extends ILayoutStateEvent {
|
||||
export type ILayoutSettings = Partial<ILayoutStateEvent> & {
|
||||
overrides?: string; // event ID for layout state event, if present
|
||||
}
|
||||
};
|
||||
|
||||
// Dev note: "Pinned" widgets are ones in the top container.
|
||||
export const MAX_PINNED = 3;
|
||||
@@ -149,7 +149,7 @@ export class WidgetLayoutStore extends ReadyWatchingStore {
|
||||
|
||||
const layoutEv = room.currentState.getStateEvents(WIDGET_LAYOUT_EVENT_TYPE, "");
|
||||
const legacyPinned = SettingsStore.getValue("Widgets.pinned", room.roomId);
|
||||
let userLayout = SettingsStore.getValue<ILayoutSettings | null>("Widgets.layout", room.roomId);
|
||||
let userLayout = SettingsStore.getValue("Widgets.layout", room.roomId);
|
||||
|
||||
if (layoutEv && userLayout && userLayout.overrides !== layoutEv.getId()) {
|
||||
// For some other layout that we don't really care about. The user can reset this
|
||||
|
||||
@@ -53,10 +53,7 @@ export class WidgetPermissionStore {
|
||||
public setOIDCState(widget: Widget, kind: WidgetKind, roomId: string | undefined, newState: OIDCState): void {
|
||||
const settingsKey = this.packSettingKey(widget, kind, roomId);
|
||||
|
||||
let currentValues = SettingsStore.getValue<{
|
||||
allow?: string[];
|
||||
deny?: string[];
|
||||
}>("widgetOpenIDPermissions");
|
||||
let currentValues = SettingsStore.getValue("widgetOpenIDPermissions");
|
||||
if (!currentValues) {
|
||||
currentValues = {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user