Skip to content

Commit

Permalink
fix(core): use Map to avoid prototype pollution
Browse files Browse the repository at this point in the history
  • Loading branch information
jmbuss committed Mar 21, 2023
1 parent cc0d584 commit fa0b7ef
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 14 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/viewportManager/viewportManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const VIEWPORT = { duration: '2m' };

it('subscribes to a new viewport group and returned an undefined viewport', () => {
const { viewport } = viewportManager.subscribe('some-group', () => {});
expect(viewport).toBeUndefined();
expect(viewport).toBeNull();
});

it('broadcast updates to viewport group', () => {
Expand All @@ -32,7 +32,7 @@ it('returns no viewport is returned on initial subscription when reset is called
viewportManager.reset();
const { viewport } = viewportManager.subscribe('some-group', listener);

expect(viewport).toBeUndefined();
expect(viewport).toBeNull();
});

it('does not broadcast viewport updates to different viewport groups ', () => {
Expand Down
27 changes: 15 additions & 12 deletions packages/core/src/viewportManager/viewportManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import type { Viewport } from '../data-module/data-cache/requestTypes';

type ViewportListener = (viewport: Viewport) => void;

let listenerMap: { [group: string]: { [id: string]: ViewportListener } } = {};
let viewportMap: { [group: string]: Viewport } = {};
const listenerMap: Map<string, Map<string, ViewportListener>> = new Map();
const viewportMap: Map<string, Viewport> = new Map();
/**
* Publicly exposed manager of viewport groups. Allows components, both internally to IoT App Kit,
* and external components / code to broadcast updates to viewports within a group.
Expand All @@ -17,8 +17,8 @@ export const viewportManager = {
* Resets all state related to viewport groups.
*/
reset: () => {
listenerMap = {};
viewportMap = {};
listenerMap.clear();
viewportMap.clear();
},
/**
* Subscribe to viewport group
Expand All @@ -34,23 +34,26 @@ export const viewportManager = {
viewport: Viewport | null;
} => {
const id = v4();
if (listenerMap[viewportGroup] == null) {
listenerMap[viewportGroup] = {};
}
listenerMap[viewportGroup][id] = viewportListener;
const listeners = listenerMap.get(viewportGroup) || new Map<string, ViewportListener>();
listeners.set(id, viewportListener);
listenerMap.set(viewportGroup, listeners);

return {
// Current viewport for the group
viewport: viewportMap[viewportGroup],
viewport: viewportMap.get(viewportGroup) || null,
// Leave viewport group, prevents listener from being called in the future
unsubscribe: () => {
delete listenerMap[viewportGroup][id];
listenerMap.get(viewportGroup)?.delete(id);
},
};
},
update: (viewportGroup: string, viewport: Viewport): void => {
viewportMap[viewportGroup] = viewport;
viewportMap.set(viewportGroup, viewport);
const listeners = listenerMap.get(viewportGroup);
if (!listeners) return;
// broadcast update to all listeners within the group
Object.keys(listenerMap[viewportGroup] || {}).forEach((id) => listenerMap[viewportGroup][id](viewport));
for (const [, viewportListener] of listeners) {
viewportListener(viewport);
}
},
};

0 comments on commit fa0b7ef

Please sign in to comment.