Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
@netless/app-embedded-page-sdk
Advanced tools
SDK for storing shared replayable states and sending/receiving replayable events inside @netless/app-embedded-page
.
npm add @netless/app-embedded-page-sdk
import { createEmbeddedApp } from "@netless/app-embedded-page-sdk";
interface State {
count: number;
}
type Message = {
type: "click";
payload: { id: string };
};
const app = await createEmbeddedApp<State, Message>();
app.ensureState({ count: 0 });
app.state; // => { count: 0 }
app.setState({ count: 2 });
app.onStateChanged.addListener(diff => {
if (diff.count) {
// count: 0 -> 2
console.log("count:", diff.count.oldValue, "->", diff.count.newValue);
console.log(diff.count.newValue === app.state.count);
}
});
app.sendMessage({ type: "click", payload: { id: "item1" } });
app.onMessage.addListener(({ type, payload }) => {
if (type === "click") {
click(payload.id);
}
});
createEmbeddedApp()
Creates an embedded app instance.
Returns: Promise<EmbeddedApp<State, Message>>
const app = await createEmbeddedApp();
app.appId
Type: string
App ID. Each app is assigned with a unique ID on creation and will keep the same ID until destroyed.
app.state
Type: State
Default: initialState
The synchronized state across all clients. To change it, call app.setState()
.
app.page
Type: string | undefined
Current whiteboard scene. It works only if scenePath
has been set when calling addApp
.
To switch between pages, call app.setPage()
app.isWritable
Type: boolean
When it is false
, calling app.setState()
, app.setPage()
, app.sendMessage()
has no effect.
app.meta
Type: { sessionUID: number; uid: string; roomUUID?: string; userPayload: unknown }
Room information, including
sessionUID
: a unique number of current session. will change after refreshing.uid
: a unique id of current user passed in when calling joinRoom()
.roomUUID
: current room's UUID.userPayload
: the object passed in when calling joinRoom()
.app.roomMembers
Type: ReadonlyArray<{ sessionUID: number; uid: string; userPayload: unknown }>
All members in the room.
sessionUID
: a unique number of current session. will change after refreshing.uid
: a unique id of current user passed in when calling joinRoom()
.userPayload
: the object passed in when calling joinRoom()
.app.ensureState(partialState)
Make sure app.state
has some initial values, work as if:
// this code won't work because app.state is readonly
app.state = { ...partialState, ...app.state };
partialState
Type: Partial<State>
app.state; // { a: 1 }
app.ensureState({ a: 0, b: 0 });
app.state; // { a: 1, b: 0 }
app.setState(partialState)
Works like React's setState
, it updates app.state
and synchronize it to other clients.
When some field's value is undefined
, it will be removed from app.state
.
Important: Do not rely on the order of state changes:
app.setState()
altersapp.state
synchronously butonStateChanged
will wait until the data is successfully synced.- State syncing time span varies due to network status and data size. It is recommended to store only necessary data in the store.
partialState
Type: Partial<State>
app.state; //=> { count: 0, a: 1 }
app.setState({ count: app.state.count + 1, a: undefined, b: 2 });
app.state; //=> { count: 1, b: 2 }
app.setPage(page)
Change the whiteboard scene on top of your page.
page
Type: string
Important: This argument must not include
/
.
app.setPage("1");
app.sendMessage(message)
Broadcast a message to other clients.
message
Type: anything that can be serialized in JSON.
app.sendMessage("hello, world!");
app.moveCamera(partialCameraState)
Change the whiteboard scene's position on top of your page.
partialCameraState
Type: Partial<{ x: number, y: number, scale: number }>
The default camera state is { x: 0, y: 0, scale: 1 }
, at the center of your page.
app.moveCamera({ scale: 0.5 });
app.onStateChanged
It fires after someone called app.setState()
(including the app itself).
Type: Emitter<{ [key: string]: { oldValue?, newValue? } }>
app.onStateChanged.addListener(diff => {
console.log("state changed", app.state);
});
app.onPageChanged
It fires after someone called app.setPage()
(including the app itself).
Type: Emitter<{ oldValue?: string, newValue?: string }>
app.onPageChanged.addListener(diff => {
console.log("switch page to", app.page);
});
app.onWritableChanged
It fires when app writable state changes.
Type: Emitter<{ oldValue?: boolean, newValue?: boolean }>
app.onWritableChanged.addListener(diff => {
console.log("my writable becomes", app.isWritable);
});
app.onRoomMembersChanged
It fires when room members changes.
Type: Emitter<{ oldValue?: RoomMember[], newValue?: RoomMember[] }>
interface RoomMember {
sessionUID: number;
uid: string;
userPayload: unknown;
}
app.onRoomMembersChanged.addListener(diff => {
console.log("room members changed", app.roomMembers);
});
app.onMessage
It fires when receiving messages from other clients (when other clients called app.sendMessage()
).
Note: Won't receive
app.sendMessage()
messages sent by itself.
Type: Emitter<any>
app.onMessage.addListener(message => {
console.log("received message", message);
});
MIT @ netless
FAQs
Unknown package
The npm package @netless/app-embedded-page-sdk receives a total of 0 weekly downloads. As such, @netless/app-embedded-page-sdk popularity was classified as not popular.
We found that @netless/app-embedded-page-sdk demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 10 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.