nativescript-connectycube
Version:
ConnectyCube chat and video chat SDK for NativeScript
310 lines (263 loc) • 8.46 kB
JavaScript
const config = require('./cubeConfig');
const IS_BROWSER_ENV = typeof window === 'object' && typeof document === 'object';
const IS_RN_ENV = typeof navigator === 'object' && navigator.product === 'ReactNative';
const IS_NS_ENV =
typeof global === 'object' && (typeof global.android !== 'undefined' || typeof global.NSObject !== 'undefined');
const IS_NODE_ENV = typeof process === 'object' && typeof process.versions === 'object' && !!process.versions.node;
const IS_EXPO_ENV = typeof global.Expo !== 'undefined';
class InternalUtils {
static getEnv() {
return {
nativescript: IS_NS_ENV,
reactnative: IS_RN_ENV,
browser: IS_BROWSER_ENV,
node: IS_NODE_ENV,
expo: IS_EXPO_ENV,
};
}
static isRNWebRTCAvailable() {
if (IS_RN_ENV && !IS_EXPO_ENV) {
const {
RTCView,
RTCPeerConnection,
RTCIceCandidate,
RTCSessionDescription,
MediaStream,
mediaDevices,
} = require('./cubeDependencies');
return RTCView && RTCPeerConnection && RTCIceCandidate && RTCSessionDescription && MediaStream && mediaDevices;
}
return false;
}
static isWebRTCAvailable() {
return (
(IS_RN_ENV && this.isRNWebRTCAvailable()) ||
(IS_BROWSER_ENV && window.RTCPeerConnection && window.RTCIceCandidate && window.RTCSessionDescription)
);
}
static safeCallbackCall() {
const callback = arguments[0];
if (typeof callback !== 'function') {
return;
}
const callbackString = callback.toString();
const callbackName = callbackString.split('(')[0].split(' ')[1];
const argumentsCopy = [];
let listenerCall;
for (let i = 0; i < arguments.length; i++) {
argumentsCopy.push(arguments[i]);
}
listenerCall = argumentsCopy.shift();
try {
listenerCall.apply(null, argumentsCopy);
} catch (err) {
if (callbackName === '') {
console.error('Error: ' + err);
} else {
console.error('Error in listener ' + callbackName + ': ' + err);
}
}
}
static randomNonce() {
return Math.floor(Math.random() * 10000);
}
static unixTime() {
return Math.floor(Date.now() / 1000);
}
static getUrl(base, id, extension) {
let resource = `${id ? '/' + id : ''}`;
extension = `${extension ? '/' + extension : ''}`;
return `https://${config.endpoints.api}/${base}${resource}${extension}${config.urls.type}`;
}
static isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
}
static isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
static getBsonObjectId() {
const timestamp = this.unixTime().toString(16);
const increment = (ObjectId.increment++).toString(16);
if (increment > 0xffffff) ObjectId.increment = 0;
return (
'00000000'.substr(0, 8 - timestamp.length) +
timestamp +
'000000'.substr(0, 6 - ObjectId.machine.length) +
ObjectId.machine +
'0000'.substr(0, 4 - ObjectId.pid.length) +
ObjectId.pid +
'000000'.substr(0, 6 - increment.length) +
increment
);
}
static DLog() {
if (this.loggers) {
for (let i = 0; i < this.loggers.length; ++i) {
this.loggers[i](arguments);
}
return;
}
let logger;
this.loggers = [];
const consoleLoggerFunction = function () {
const logger = function (args) {
console.log.apply(console, Array.prototype.slice.call(args));
};
return logger;
};
if (typeof config.debug === 'object') {
if (typeof config.debug.mode === 'number') {
if (config.debug.mode == 1) {
logger = consoleLoggerFunction();
this.loggers.push(logger);
}
} else if (typeof config.debug.mode === 'object') {
config.debug.mode.forEach(function (mode) {
if (mode === 1) {
logger = consoleLoggerFunction();
this.loggers.push(logger);
}
});
}
}
if (this.loggers) {
for (let j = 0; j < this.loggers.length; ++j) {
this.loggers[j](arguments);
}
}
}
static isExpiredSessionError(error) {
try {
return error && error.code === 401 && error.info.errors.base[0] === 'Required session does not exist';
} catch (ex) {
return false;
}
}
static mergeArrays(arrayTo, arrayFrom) {
const merged = this.cloneObject(arrayTo);
firstLevel: for (let i = 0; i < arrayFrom.length; i++) {
const newItem = arrayFrom[i];
for (let j = 0; j < merged.length; j++) {
if (newItem.user_id === merged[j].user_id) {
merged[j] = newItem;
continue firstLevel;
}
}
merged.push(newItem);
}
return merged;
}
static toBase64(str) {
if (this.getEnv().browser) {
return btoa(
encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
return String.fromCharCode('0x' + p1);
})
);
} else if (this.getEnv().reactnative) {
return global.encodeToBase64(str);
} else {
// Node.js & NativeScript
return Buffer.from(str).toString('base64');
}
}
static generateCreateSessionParams(params = {}) {
const message = {
application_id: config.creds.appId,
auth_key: config.creds.authKey,
nonce: this.randomNonce(),
timestamp: params.timestamp || this.unixTime(),
};
if (params) {
if (params.guest) {
message.user = params;
} else if (params.login && params.password) {
message.user = { login: params.login, password: params.password };
} else if (params.email && params.password) {
message.user = { email: params.email, password: params.password };
} else if (params.provider) {
// Via social networking provider (e.g. facebook, twitter etc.)
message.provider = params.provider;
if (params.scope) {
message.scope = params.scope;
}
if (params.keys && params.keys.token) {
message.keys = { token: params.keys.token };
}
if (params.keys && params.keys.secret) {
message.keys.secret = params.keys.secret;
}
} else if (params.hasOwnProperty('long')) {
message.long = params.long;
}
}
return message;
}
static signParams(message, secret) {
const sessionMsg = Object.keys(message)
.map(function (val) {
if (typeof message[val] === 'object') {
return Object.keys(message[val])
.map(function (val1) {
return val + '[' + val1 + ']=' + message[val][val1];
})
.sort()
.join('&');
} else {
return val + '=' + message[val];
}
})
.sort()
.join('&');
let cryptoSessionMsg;
if (config.hash === 'sha1') {
const sha1 = require('crypto-js/hmac-sha1');
cryptoSessionMsg = sha1(sessionMsg, secret).toString();
} else if (config.hash === 'sha256') {
const sha256 = require('crypto-js/hmac-sha256');
cryptoSessionMsg = sha256(sessionMsg, secret).toString();
} else {
throw new Error('Unknown crypto standards, available sha1 or sha256');
}
return cryptoSessionMsg;
}
static getSizeOfString(str) {
return new Blob([str]).size;
}
static getDateSize(data) {
let size = 0;
if (data.body) {
let body = data.body;
if (typeof body != 'string') {
body = JSON.stringify(body);
}
size += this.getSizeOfString(body);
}
if (data.headers) {
size += this.getSizeOfString(JSON.stringify(data.headers));
}
return size;
}
static callTrafficUsageCallback(callbackName, data) {
if (typeof config.on[callbackName] === 'function') {
config.on[callbackName](this.getDateSize(data));
}
}
static cloneObject(obj = {}, escapeNull = false) {
try {
const json = JSON.stringify(obj);
const jsonObject = escapeNull ? json.replace(/null/g, '""') : json;
return JSON.parse(jsonObject);
} catch (error) {
return obj;
}
}
}
// The object for type MongoDB.Bson.ObjectId
// http://docs.mongodb.org/manual/reference/object-id/
const ObjectId = {
machine: Math.floor(Math.random() * 16777216).toString(16),
pid: Math.floor(Math.random() * 32767).toString(16),
increment: 0,
};
module.exports = InternalUtils;