sinch-rtc
Version:
RTC JavaScript/Web SDK
146 lines • 5.22 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProtocolV10Factory = exports.ProtocolV10 = void 0;
const CryptoJS = require("crypto-js");
const _1 = require("./");
const models_1 = require("./models");
class ProtocolV10 {
constructor() {
this.Version = "10";
this.sessionBuffer = new _1.SessionMessageBuffer();
}
decode(data, key) {
const transport = ProtocolV10.getMXPDataParts(data);
if (transport.partTotal === "1") {
// Single-Part message
return {
transport: transport,
message: this.prepareMessage(transport.data, transport.sessionId, key),
};
}
else {
// Multi-Part message
this.sessionBuffer.addTransportMessage(transport);
const payload = this.sessionBuffer.getPayload(transport);
if (payload) {
return {
transport: transport,
message: this.prepareMessage(payload, transport.sessionId, key),
};
}
}
return null;
}
encode(message, key) {
const chunkSize = 30000;
const serializedPayload = this.serialize(message);
const encryptedPayload = _1.Codec.encrypt(serializedPayload, key);
const parts = Math.floor(1 + encryptedPayload.length / chunkSize);
const msgId = parts === 1 ? "-" : CryptoJS.lib.WordArray.random(16).toString();
const messages = new Array();
for (let i = 0; i < parts; i++) {
const partData = this.payloadSlice(encryptedPayload, i, chunkSize);
const partMessage = this.buildTransportMessage(this.Version, message.sessionId, msgId, i, parts, partData);
/** Emit outbound message event with every part */
messages.push(partMessage);
}
return messages;
}
prepareMessage(data, sessionId, key) {
try {
const decryptedPayload = _1.Codec.decrypt(data, key);
const payload = JSON.parse(decryptedPayload);
const client = this.encodeClient(payload);
const body = new models_1.Body(payload.bt, payload.bd);
return new _1.Message(parseInt(payload.md), sessionId, client, body, payload.nvps);
}
catch (error) {
if (error.name !== "MXPError") {
throw new _1.MXPError(_1.MXPError.Codes.INVALID_MESSAGE, error);
}
else {
throw error;
}
}
}
encodeClient(model) {
return {
cli: model.fc,
channel: model.fs,
instanceId: model.fi,
userId: model.fu,
deviceDescription: model.fd,
domain: model.fdom,
};
}
/**
* Prepares actual MXP message format used within protocol
* @param version - MXP protocol version
* @param sessionId - ULID of current session
* @param msgId - determines whether message is single-part or multi-part
* @param partNo - index of particular part
* @param partTotal - number of all parts
* @param data - base64 encoded encrypted payload
*/
buildTransportMessage(version, sessionId, msgId, partNo, partTotal, data) {
return `${version} ${sessionId} ${msgId} ${partNo} ${partTotal} ${data}`;
}
/**
* Returns dictionary containing transport data parts from MXP message
* @param raw -
*/
static getMXPDataParts(raw) {
const msg = raw.split(" ");
return {
version: msg[0],
sessionId: msg[1],
msgId: msg[2],
partNo: msg[3],
partTotal: msg[4],
data: msg[5],
};
}
/**
*
* @param payload - whole payload encrypted
* @param part - number of message in sequence
* @param chunkSize - constant value of maximum part size
*/
payloadSlice(payload, part, chunkSize) {
return payload.substr(part * chunkSize, Math.min(chunkSize, payload.length - part * chunkSize));
}
serialize(msg) {
let model = {};
model.md = msg.method;
model = this.addBody(msg, model);
model = this.addClient(msg, model);
model = this.addValues(msg, model);
return JSON.stringify(model);
}
addBody(msg, model) {
if (!msg.body) {
return model;
}
return Object.assign(Object.assign({}, model), { bd: msg.body.data, bt: msg.body.type });
}
addClient(msg, model) {
if (!msg.from) {
return model;
}
return Object.assign(Object.assign({}, model), { fs: msg.from.channel, fc: msg.from.cli, fd: msg.from.deviceDescription, fi: msg.from.instanceId, fu: msg.from.userId });
}
addValues(msg, model) {
if (!msg.values) {
return model;
}
return Object.assign(Object.assign({}, model), { nvps: msg.values });
}
}
exports.ProtocolV10 = ProtocolV10;
class ProtocolV10Factory {
static create() {
return new ProtocolV10();
}
}
exports.ProtocolV10Factory = ProtocolV10Factory;
//# sourceMappingURL=Protocol.js.map