sinch-rtc
Version:
RTC JavaScript/Web SDK
274 lines • 14.1 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiClientFactory = exports.OcraClient = exports.InvalidInstanceAuthenticationError = void 0;
/* eslint-disable @typescript-eslint/no-var-requires */
const utils_1 = require("../utils");
const Errors_1 = require("../utils/Errors");
const api_1 = require("./api");
const apis_1 = require("./api/apis");
const CorrelationContext_1 = require("./requestHeaders/CorrelationContext");
const requestHeaders_1 = require("./requestHeaders");
const SinchError_1 = require("../SinchError");
const GzipEncodingMiddleware_1 = require("./GzipEncodingMiddleware");
const { version } = require("../../package.json");
const X_SIN_REQUEST_ID_HEADER = "x-sin-request-id";
const X_SIN_OBJECT_ID_HEADER = "x-sin-client-obj-id";
const X_SIN_CC_HEADER = "x-sin-cc";
const X_SIN_CLIENT_PLATFORM = "x-sin-client-platform";
const X_SIN_CLIENT_VERSION_HEADER = "x-sin-client-version";
class InvalidInstanceAuthenticationError extends Error {
constructor(error) {
super(`Invalid InstanceAuthentication, code: ${error.code}`);
this.error = error;
}
get code() {
return this.error.code;
}
}
exports.InvalidInstanceAuthenticationError = InvalidInstanceAuthenticationError;
class OcraClient {
constructor(configuration) {
this.getRequestHeaders = (correlationContext) => {
// See https://git.sinch.se/sinch-backend/ocra-design/-/blob/master/design/README.md#ocra-specific-http-headers
const requestHeaders = {};
requestHeaders[X_SIN_REQUEST_ID_HEADER] = utils_1.StringHelper.UUID();
requestHeaders[X_SIN_OBJECT_ID_HEADER] = this.clientId;
requestHeaders[X_SIN_CC_HEADER] = correlationContext.toHttpHeader();
requestHeaders[X_SIN_CLIENT_PLATFORM] = "js";
requestHeaders[X_SIN_CLIENT_VERSION_HEADER] = version;
return requestHeaders;
};
// if new instance created update request with new instanceId if necessary
this.updateRequestInstance = (request) => {
return Object.assign(Object.assign({}, request), { instanceId: this.authentication.instance.id });
};
this.clientId = utils_1.StringHelper.UUID();
this.instanceApi = new apis_1.InstanceApi(configuration);
this.callApi = new apis_1.CallApi(configuration).withMiddleware(this);
this.configApi = new apis_1.ConfigApi(configuration).withMiddleware(this);
this.iceApi = new apis_1.IceApi(configuration).withMiddleware(this);
this.callReportApi = new apis_1.CallReportApi(configuration).withMiddleware(this);
this.pushApi = new apis_1.PushApi(configuration).withMiddleware(this);
this.featureFlagsApi = new apis_1.FeatureFlagsApi(configuration);
}
getDefaultCorrelationContext() {
var _a, _b;
return new CorrelationContext_1.CorrelationContext((_a = this.instanceAuthentication) === null || _a === void 0 ? void 0 : _a.credentials.username, (_b = this.instanceAuthentication) === null || _b === void 0 ? void 0 : _b.instance.id);
}
deletePushProfile(request) {
const requestHeaders = new requestHeaders_1.SinchRequestHeaders(this.getRequestHeaders(this.getDefaultCorrelationContext()));
return this.makeRequest(request, (request) => __awaiter(this, void 0, void 0, function* () {
return this.pushApi
.withMiddleware(this.authentication)
.withMiddleware(requestHeaders)
.deletePushProfile(request);
}), this.updateRequestInstance);
}
updatePushProfile(request) {
const requestHeaders = new requestHeaders_1.SinchRequestHeaders(this.getRequestHeaders(this.getDefaultCorrelationContext()));
return this.makeRequest(request, (request) => __awaiter(this, void 0, void 0, function* () {
return this.pushApi
.withMiddleware(this.authentication)
.withMiddleware(requestHeaders)
.updatePushProfile(request);
}), this.updateRequestInstance);
}
sendPushNotification(request) {
const requestHeaders = new requestHeaders_1.SinchRequestHeaders(this.getRequestHeaders(this.getDefaultCorrelationContext()));
return this.makeRequest(request, (request) => __awaiter(this, void 0, void 0, function* () {
return this.pushApi
.withMiddleware(this.authentication)
.withMiddleware(requestHeaders)
.sendPushNotification(request);
}));
}
initiateCall(request) {
const correlationContext = this.getDefaultCorrelationContext();
correlationContext.callId = request.callInitiationRequest.callId;
const requestHeaders = new requestHeaders_1.SinchRequestHeaders(this.getRequestHeaders(correlationContext));
return this.makeRequest(request, (request) => __awaiter(this, void 0, void 0, function* () {
return this.callApi
.withMiddleware(this.authentication)
.withMiddleware(requestHeaders)
.initiateCall(request);
}));
}
getConfig(request) {
return __awaiter(this, void 0, void 0, function* () {
const requestHeaders = new requestHeaders_1.SinchRequestHeaders(this.getRequestHeaders(this.getDefaultCorrelationContext()));
return this.makeRequest(request, (request) => __awaiter(this, void 0, void 0, function* () {
return this.configApi
.withMiddleware(this.authentication)
.withMiddleware(requestHeaders)
.getConfig(request);
}), this.updateRequestInstance);
});
}
getIceServers(request) {
const requestHeaders = new requestHeaders_1.SinchRequestHeaders(this.getRequestHeaders(this.getDefaultCorrelationContext()));
return this.makeRequest(request, (request) => __awaiter(this, void 0, void 0, function* () {
return this.iceApi
.withMiddleware(this.authentication)
.withMiddleware(requestHeaders)
.getIceServers(request);
}), this.updateRequestInstance);
}
getFeatureFlags(request) {
return __awaiter(this, void 0, void 0, function* () {
const requestHeaders = new requestHeaders_1.SinchRequestHeaders(this.getRequestHeaders(this.getDefaultCorrelationContext()));
return this.makeRequest(request, (request) => __awaiter(this, void 0, void 0, function* () {
return this.featureFlagsApi
.withMiddleware(this.authentication)
.withMiddleware(requestHeaders)
.getFeatureFlags(request);
}), this.updateRequestInstance);
});
}
createInstance(authentication, request) {
// Skip using `getDefaultCorrelationContext()` here, since `this.instanceAuthentication` is not expected to be be valid at this point.
const correlationContext = new CorrelationContext_1.CorrelationContext(request.createInstanceRequest.userId);
const requestHeaders = new requestHeaders_1.SinchRequestHeaders(this.getRequestHeaders(correlationContext));
return this.instanceApi
.withMiddleware(authentication)
.withMiddleware(requestHeaders)
.createInstance(request);
}
createCallReport(request) {
const correlationContext = this.getDefaultCorrelationContext();
correlationContext.callId = request.callReport.callId;
const requestHeaders = new requestHeaders_1.SinchRequestHeaders(this.getRequestHeaders(correlationContext));
const gzipRequestEncoder = new GzipEncodingMiddleware_1.GzipEncodingMiddleware();
return this.callReportApi
.withMiddleware(this.authentication)
.withMiddleware(requestHeaders)
.withMiddleware(gzipRequestEncoder)
.createCallReport(request);
}
updateInstance(request) {
const requestHeaders = new requestHeaders_1.SinchRequestHeaders(this.getRequestHeaders(this.getDefaultCorrelationContext()));
return this.instanceApi
.withMiddleware(this.authentication)
.withMiddleware(requestHeaders)
.updateInstance(request);
}
updateInstanceTtl(authentication, request) {
const requestHeaders = new requestHeaders_1.SinchRequestHeaders(this.getRequestHeaders(this.getDefaultCorrelationContext()));
return this.instanceApi
.withMiddleware(authentication)
.withMiddleware(requestHeaders)
.updateInstanceTtl(request);
}
setInstanceAuthentication(authentication, onAuthenticationRequired) {
this.instanceAuthentication = authentication;
this.onAuthenticationRequired = onAuthenticationRequired;
}
setUpdateInstanceTtlWindow(updateTtlWindowDays) {
this.updateTtlWindowDays = updateTtlWindowDays;
}
get authentication() {
if (!this.instanceAuthentication)
throw new Errors_1.InvalidOperationError("Missing instance authentication");
else
return this.instanceAuthentication;
}
// check expireAt before request
pre(_) {
return __awaiter(this, void 0, void 0, function* () {
this.validateInstanceTtl();
});
}
// check if response is an invalid instance response
post(context) {
return __awaiter(this, void 0, void 0, function* () {
yield this.processOcraApiErrors(context.response);
});
}
validateInstanceTtl() {
if (this.hasAuthenticationExpired(this.authentication))
// if instance has expired treath it as it doesn't exist and require new instance creation
throw new InvalidInstanceAuthenticationError({
message: OcraClient.EXPIRED_AUTH_MESSAGE,
code: 1104,
});
}
processOcraApiErrors(response) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const isErrorResponse = response.status >= 400;
if (!isErrorResponse) {
return;
}
const isJsonBody = (_c = (_b = (_a = response.headers) === null || _a === void 0 ? void 0 : _a.get(OcraClient.HEADER_CONTENT_TYPE)) === null || _b === void 0 ? void 0 : _b.includes(OcraClient.HEADER_VALUE_JSON_CONTENT_TYPE)) !== null && _c !== void 0 ? _c : false;
if (!isJsonBody) {
throw new SinchError_1.SinchError(OcraClient.GENERAL_ERROR_MESSAGE, response.status || SinchError_1.ErrorCode.Generic, SinchError_1.ErrorType.Http);
}
const json = yield response.json();
if (this.isAuthenticationInvalid(response.status) &&
((_d = json.error) === null || _d === void 0 ? void 0 : _d.code) == OcraClient.INVALID_INSTANCE_AUTHENTICATION_ERROR_CODE) {
throw new InvalidInstanceAuthenticationError(json.error);
}
throw this.getSinchErrorFromJson(json, response.status);
});
}
getSinchErrorFromJson(json, responseCode) {
if (!(0, api_1.exists)(json, "error")) {
return new SinchError_1.SinchError(OcraClient.GENERAL_ERROR_MESSAGE, responseCode, SinchError_1.ErrorType.Http);
}
const error = json["error"];
const message = error["message"];
const code = error["code"];
return new SinchError_1.SinchError(message, code !== null && code !== void 0 ? code : responseCode, SinchError_1.ErrorType.Http);
}
isAuthenticationInvalid(status) {
return status == 404 || status == 401;
}
// if error is InvalidInstanceAuthenticationError we need to create a new instance.
newInstanceAuthenticationRequired(error) {
return error instanceof InvalidInstanceAuthenticationError;
}
hasAuthenticationExpired(authentication) {
return authentication.instance.hasExpired();
}
makeRequest(request, apiRequest, onUpdateRequest) {
return __awaiter(this, void 0, void 0, function* () {
try {
if (this.updateTtlWindowDays &&
this.authentication.instance.shouldProlong(this.updateTtlWindowDays)) {
yield this.authentication.prolong();
}
return yield apiRequest(request);
}
catch (error) {
if (this.newInstanceAuthenticationRequired(error) &&
this.onAuthenticationRequired) {
yield this.onAuthenticationRequired();
return apiRequest(onUpdateRequest ? onUpdateRequest(request) : request);
}
else
throw error;
}
});
}
}
exports.OcraClient = OcraClient;
OcraClient.GENERAL_ERROR_MESSAGE = "Error while executing http request";
OcraClient.EXPIRED_AUTH_MESSAGE = "InstanceAuthentication expired";
OcraClient.HEADER_CONTENT_TYPE = "Content-Type";
OcraClient.HEADER_VALUE_JSON_CONTENT_TYPE = "application/json";
OcraClient.INVALID_INSTANCE_AUTHENTICATION_ERROR_CODE = 1104;
class ApiClientFactory {
static create(configuration) {
return new OcraClient(configuration);
}
}
exports.ApiClientFactory = ApiClientFactory;
//# sourceMappingURL=ApiClient.js.map