doorbird
Version:
Node JS library for the Doorbird LAN API.
1,017 lines • 43 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
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());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DoorbirdUdpSocket = exports.FavoriteType = exports.Scheme = void 0;
exports.getDoorstationCertificate = getDoorstationCertificate;
var axios_1 = __importDefault(require("axios"));
var chacha = __importStar(require("chacha-js"));
var dgram = __importStar(require("dgram"));
var https = __importStar(require("https"));
var libsodium_wrappers_sumo_1 = __importDefault(require("libsodium-wrappers-sumo"));
var tls = __importStar(require("tls"));
/**
* Identifier of UDP packages (as of documentation)
*/
var udpIdentifier = Buffer.from([0xde, 0xad, 0xbe]);
/**
* Fixed argon key length (as of documentation)
*/
var argonKeyLength = 32;
/**
* Utility method to retrieve the Doorstation's self signed certificate in PEM representation.
* @param host host to retrieve the certificate for
*/
function getDoorstationCertificate(host) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, new Promise(function (resolve) {
var socket = tls.connect({
host: host,
port: 443,
rejectUnauthorized: false,
}, function () {
var peerCert = socket.getPeerCertificate().raw.toString("base64");
socket.destroy();
resolve("-----BEGIN CERTIFICATE-----\n".concat(peerCert, "\n-----END CERTIFICATE-----"));
});
})];
});
});
}
/**
* Scheme for API communication with the door station.
*/
var Scheme;
(function (Scheme) {
Scheme["http"] = "http";
Scheme["https"] = "https";
})(Scheme || (exports.Scheme = Scheme = {}));
/**
* Type for Doorbird favorites.
*/
var FavoriteType;
(function (FavoriteType) {
FavoriteType["sip"] = "sip";
FavoriteType["http"] = "http";
})(FavoriteType || (exports.FavoriteType = FavoriteType = {}));
/**
* Wrapper class for a UDP socket, that is capable to handle Doorbird's UDP messages.
*/
var DoorbirdUdpSocket = /** @class */ (function () {
/**
* Construct a new DoorbirdUdpSocket
*
* @param port Doorbird sends to ports 6524 and 35344.
* @param username username of the Doorbird user.
* @param password password of the Doorbird user.
* @param client the parent instance of the Doorbird api.
* @param suppressBurst flag to suppress multiple burst messages (callback is only called once)
*/
function DoorbirdUdpSocket(port, username, password, client, suppressBurst, debug) {
if (suppressBurst === void 0) { suppressBurst = false; }
if (debug === void 0) { debug = false; }
var _this = this;
this.debug = false;
this.lastEventTimestamp = 0;
this.ringListeners = [];
this.motionListeners = [];
this.notificationEncryptionKey = null;
this.log = function (msg) {
if (!_this.debug) {
return;
}
if (typeof msg === 'function') {
console.log(msg());
return;
}
console.log(msg);
};
this.strech = function (salt, opslimit, memlimit) { return __awaiter(_this, void 0, void 0, function () {
var sodium, streched;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, libsodium_wrappers_sumo_1.default.ready];
case 1:
_a.sent();
sodium = libsodium_wrappers_sumo_1.default;
streched = Buffer.from(sodium.crypto_pwhash(argonKeyLength, this.password.substring(0, 5), salt, opslimit.readInt32BE(), memlimit.readInt32BE(), sodium.crypto_pwhash_ALG_ARGON2I13));
return [2 /*return*/, streched];
}
});
}); };
this.onMessage = function (msg) { return __awaiter(_this, void 0, void 0, function () {
var identifier, version;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.log(function () { return 'Received UDP message.'; });
this.log(msg);
identifier = msg.subarray(0, 3);
version = msg.subarray(3, 4);
this.log(function () { return "Identifier: \"".concat(identifier, "\", Version: \"").concat(version, "\"."); });
if (udpIdentifier.toString("base64") !== identifier.toString("base64")) {
this.log('Identifier does not match.');
return [2 /*return*/];
}
if (!(version[0] === 0x01)) return [3 /*break*/, 2];
return [4 /*yield*/, this.handleV1(msg)];
case 1:
_a.sent();
return [3 /*break*/, 5];
case 2:
if (!(version[0] == 0x02)) return [3 /*break*/, 4];
return [4 /*yield*/, this.handleV2(msg)];
case 3:
_a.sent();
return [3 /*break*/, 5];
case 4: throw new Error("Unsupported version of UDP package.");
case 5: return [2 /*return*/];
}
});
}); };
this.handleV1 = function (msg) { return __awaiter(_this, void 0, void 0, function () {
var eventTimestamp, decrypted, intercomId, event, timestamp, date, trimmedEvent;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (this.suppressBurst) {
this.log('Checking burst suppression.');
eventTimestamp = new Date().valueOf();
if (eventTimestamp - this.lastEventTimestamp < 1000) {
this.log('Suppressing message due to burst detection.');
return [2 /*return*/];
}
this.lastEventTimestamp = eventTimestamp;
}
return [4 /*yield*/, this.decryptV1(msg)];
case 1:
decrypted = _a.sent();
intercomId = decrypted.subarray(0, 6);
event = decrypted.subarray(6, 14);
timestamp = decrypted.subarray(14, 18);
this.log(function () { return "IntercomId: \"".concat(intercomId, "\", Event: \"").concat(event, "\", Timestamp: \"").concat(timestamp, "\"."); });
if (this.username.substring(0, 6) !== intercomId.toString("utf-8")) {
this.log('Username prefix missmatch.');
return [2 /*return*/];
}
date = new Date(0);
date.setUTCSeconds(timestamp.readInt32BE());
trimmedEvent = event.toString("utf-8").trim();
if ("motion" === trimmedEvent) {
this.log('Detected motion event.');
this.motionListeners.forEach(function (listener) {
return listener({
intercomId: intercomId.toString("utf-8"),
timestamp: date,
});
});
}
else {
this.log('Detected ring event.');
this.ringListeners.forEach(function (listener) {
return listener({
intercomId: intercomId.toString("utf-8"),
event: trimmedEvent,
timestamp: date,
});
});
}
return [2 /*return*/];
}
});
}); };
this.handleV2 = function (msg) { return __awaiter(_this, void 0, void 0, function () {
var decrypted, intercomId, event, timestamp, eventTimestamp, date, trimmedEvent;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.decryptV2(msg)];
case 1:
decrypted = _a.sent();
intercomId = decrypted.subarray(0, 6);
event = decrypted.subarray(6, 14);
timestamp = decrypted.subarray(14, 18);
this.log(function () { return "IntercomId: \"".concat(intercomId, "\", Event: \"").concat(event, "\", Timestamp: \"").concat(timestamp, "\"."); });
if (this.username.substring(0, 6) !== intercomId.toString("utf-8")) {
this.log('Username prefix missmatch.');
return [2 /*return*/];
}
if (this.suppressBurst) {
this.log('Checking burst suppression.');
eventTimestamp = new Date().valueOf();
if (eventTimestamp - this.lastEventTimestamp < 1000) {
this.log('Suppressing message due to burst detection.');
return [2 /*return*/];
}
this.lastEventTimestamp = eventTimestamp;
}
date = new Date(0);
date.setUTCSeconds(timestamp.readInt32BE());
trimmedEvent = event.toString("utf-8").trim();
if ("motion" === trimmedEvent) {
this.log('Detected motion event.');
this.motionListeners.forEach(function (listener) {
return listener({
intercomId: intercomId.toString("utf-8"),
timestamp: date,
});
});
}
else {
this.log('Detected ring event.');
this.ringListeners.forEach(function (listener) {
return listener({
intercomId: intercomId.toString("utf-8"),
event: trimmedEvent,
timestamp: date,
});
});
}
return [2 /*return*/];
}
});
}); };
this.decryptV1 = function (msg) { return __awaiter(_this, void 0, void 0, function () {
var opslimit, memlimit, salt, nonce, ciphertext, streched, decipher;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
opslimit = msg.subarray(4, 8);
memlimit = msg.subarray(8, 12);
salt = msg.subarray(12, 28);
nonce = msg.subarray(28, 36);
ciphertext = msg.subarray(36, 70);
return [4 /*yield*/, this.strech(salt, opslimit, memlimit)];
case 1:
streched = _a.sent();
decipher = chacha.AeadLegacy(streched, nonce, true);
return [2 /*return*/, decipher.update(ciphertext)];
}
});
}); };
this.decryptV2 = function (msg) { return __awaiter(_this, void 0, void 0, function () {
var nonce, ciphertext, decipher, _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
nonce = msg.subarray(4, 12);
ciphertext = msg.subarray(12, 46);
_b = (_a = chacha).AeadLegacy;
return [4 /*yield*/, this.getNotificationEncryptionKey()];
case 1:
decipher = _b.apply(_a, [_c.sent(), nonce, true]);
return [2 /*return*/, decipher.update(ciphertext)];
}
});
}); };
this.getNotificationEncryptionKey = function () { return __awaiter(_this, void 0, void 0, function () {
var _a, _b, _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
if (!(this.notificationEncryptionKey === null)) return [3 /*break*/, 2];
_a = this;
_c = (_b = Buffer).from;
return [4 /*yield*/, this.client.initializeSession()];
case 1:
_a.notificationEncryptionKey = _c.apply(_b, [(_d.sent()).BHA.NOTIFICATION_ENCRYPTION_KEY,
"utf-8"]);
_d.label = 2;
case 2: return [2 /*return*/, this.notificationEncryptionKey];
}
});
}); };
this.username = username;
this.password = password;
this.client = client;
this.suppressBurst = suppressBurst;
this.debug = debug;
this.server = dgram.createSocket({
type: "udp4",
reuseAddr: true,
});
this.server.bind(port);
this.server.on("message", this.onMessage);
}
/**
* Register a ring listener.
*
* @param listener ring listener
*/
DoorbirdUdpSocket.prototype.registerRingListener = function (listener) {
this.ringListeners.push(listener);
};
/**
* Register a motion listner.
*
* @param listener motion listener
*/
DoorbirdUdpSocket.prototype.registerMotionListener = function (listener) {
this.motionListeners.push(listener);
};
/**
* Close the UDP socket.
*/
DoorbirdUdpSocket.prototype.close = function () {
if (this.server) {
this.server.close();
}
};
return DoorbirdUdpSocket;
}());
exports.DoorbirdUdpSocket = DoorbirdUdpSocket;
/**
* Doorbird client class.
*/
var Doorbird = /** @class */ (function () {
/**
* Construct a Doorbird client.
*
* @param options options for the Doorbird client
*/
function Doorbird(options) {
this.options = options;
}
/**
* Initialize a session.
*
* @returns session response
*/
Doorbird.prototype.initializeSession = function () {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/getsession.cgi"))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Destroy a session.
*
* @param session session response or id
* @returns session response
*/
Doorbird.prototype.destroySession = function (session) {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if ("object" === typeof session) {
session = session.BHA.SESSIONID;
}
return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/getsession.cgi?invalidate=".concat(session)))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Get info of the Doorbird installation.
*
* @returns Doorbird info response
*/
Doorbird.prototype.getInfo = function () {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/info.cgi"))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Opens a door via a relay of your doorbird system.
*
* @deprecated use toggleRelay instead
* @param relay the relay that opens the door
* @returns http response of the call
*/
Doorbird.prototype.openDoor = function (relay) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this.toggleRelay(relay)];
});
});
};
/**
* Toggle a relay.
*
* @param relay the ID of the relay to be toggled
* @returns base response
*/
Doorbird.prototype.toggleRelay = function (relay) {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/open-door.cgi?r=".concat(relay)))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Enable the infra red lights of the door station.
*
* @returns base response
*/
Doorbird.prototype.lightOn = function () {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/light-on.cgi"))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Get a list of favorites.
*
* @returns favorites list
*/
Doorbird.prototype.listFavorites = function () {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/favorites.cgi"))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Create a new favorite.
*
* @param type new favorite type
* @param favoriteInfo favorite info
* @returns empty promise
*/
Doorbird.prototype.createFavorite = function (type, favoriteInfo) {
return this.doCreateUpdateFavorite(type, favoriteInfo);
};
/**
* Update a favorite.
*
* @param id id of the favorite to be updated
* @param type type of the favorite to be updated
* @param favoriteInfo new favorite info
* @returns empty promise
*/
Doorbird.prototype.updateFavorite = function (id, type, favoriteInfo) {
return this.doCreateUpdateFavorite(type, favoriteInfo, id);
};
Doorbird.prototype.doCreateUpdateFavorite = function (type, favoriteInfo, id) {
return __awaiter(this, void 0, void 0, function () {
var url, http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
url = "/bha-api/favorites.cgi?action=save&type=".concat(type, "&title=").concat(encodeURIComponent(favoriteInfo.title), "&value=").concat(encodeURIComponent(favoriteInfo.value));
if (id) {
url += "&id=".concat(id);
}
return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri(url))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.headers['favoriteid']];
}
});
});
};
/**
* Delete a favorite.
*
* @param id id of the favorite to be deleted
* @param type type of the favorite to be deleted
* @returns empty promise
*/
Doorbird.prototype.deleteFavorite = function (id, type) {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/favorites.cgi?action=remove&type=".concat(type, "&id=").concat(id)))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Get the schedule of the Doorbird system.
*
* @returns schedule response
*/
Doorbird.prototype.getSchedule = function () {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/schedule.cgi"))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Create a schedule entry.
*
* @param scheduleEntry new schedule entry
* @returns empty promise
*/
Doorbird.prototype.createScheduleEntry = function (scheduleEntry) {
return this.updateScheduleEntry(scheduleEntry);
};
/**
* Update a schedule entry.
*
* @param scheduleEntry updated schedule entry
* @returns empty promise
*/
Doorbird.prototype.updateScheduleEntry = function (scheduleEntry) {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.post(this.uri("/bha-api/schedule.cgi"), {
data: scheduleEntry,
})];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Delete a schedule entry.
*
* @param input input type of the entry to be deleted
* @param param param of the entry to be deleted
* @returns empty promise
*/
Doorbird.prototype.deleteScheduleEntry = function (input, param) {
return __awaiter(this, void 0, void 0, function () {
var url, http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
url = "/bha-api/schedule.cgi?action=remove&input=".concat(input);
if (param) {
url += "¶m=".concat(param);
}
return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri(url))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Restart the door station.
*
* @returns empty promise
*/
Doorbird.prototype.restart = function () {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/restart.cgi"))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Create a SIP registration.
*
* @param user user for the sip registration
* @param password password for the sip registration
* @param url url for the sip registration
* @returns empty promise
*/
Doorbird.prototype.sipRegistration = function (user, password, url) {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/sip.cgi?action=registration&user=".concat(user, "&password=").concat(password, "&url=").concat(url)))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Initiate a SIP call.
*
* @param url url for the SIP call
* @returns empty promise
*/
Doorbird.prototype.sipCall = function (url) {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/sip.cgi?action=makecall&url=".concat(url)))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* End a SIP call.
*
* @returns empty promise
*/
Doorbird.prototype.sipHangup = function () {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/sip.cgi?action=hangup"))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Update SIP settings.
*
* @param enable enable or disable SIP registration after device reboot
* @param mic_volume microphone volume (1-100)
* @param spk_volume speaker volume (1-100)
* @param dtmf enable or disable DTMF support
* @param relay1_passcode pincode for triggering the door open relay
* @param incoming_call_enable enable or disable incoming calls
* @param incoming_call_user Allowed SIP user which will be authenticated for Doorbird
* @param anc enable or disable acoustic noise cancellation
* @returns empty promise
*/
Doorbird.prototype.sipSettings = function (enable, mic_volume, spk_volume, dtmf, relay1_passcode, incoming_call_enable, incoming_call_user, anc, ringTimeLimit, callTimeLimit) {
return __awaiter(this, void 0, void 0, function () {
var url, http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
url = "/bha-api/sip.cgi?action=settings";
if (enable) {
url += "&enable=".concat(enable);
}
if (mic_volume) {
url += "&mic_volume=".concat(mic_volume);
}
if (spk_volume) {
url += "&spk_volume=".concat(spk_volume);
}
if (dtmf) {
url += "&dtmf=".concat(dtmf);
}
if (relay1_passcode) {
url += "&relay1_passcode=".concat(relay1_passcode);
}
if (incoming_call_enable) {
url += "&incoming_call_enable=".concat(incoming_call_enable);
}
if (incoming_call_user) {
url += "&incoming_call_user=".concat(incoming_call_user);
}
if (anc) {
url += "&anc=".concat(anc);
}
if (ringTimeLimit) {
url += "&ring_time_limit=".concat(ringTimeLimit);
}
if (callTimeLimit) {
url += "&call_time_limit=".concat(callTimeLimit);
}
return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri(url))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Get the SIP status.
*
* @returns Specific BHA for SIP status
*/
Doorbird.prototype.sipStatus = function () {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/sip.cgi?action=status"))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Reset the SIP settings.
*
* @returns empty promise
*/
Doorbird.prototype.sipSettingsReset = function () {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.uri("/bha-api/sip.cgi?action=reset"))];
case 2:
resp = _a.sent();
return [2 /*return*/, resp.data];
}
});
});
};
/**
* Start a UDP socket.
*
* @param port port to listen on
* @param suppressBurst suppress multiple UDP messages into a single callback
* @returns DoorbirdUdpSocket object
*/
Doorbird.prototype.startUdpSocket = function (port, suppressBurst, debug) {
if (suppressBurst === void 0) { suppressBurst = false; }
if (debug === void 0) { debug = false; }
return new DoorbirdUdpSocket(port, this.options.username, this.options.password, this, suppressBurst, debug);
};
/**
* Get the Doorbird image url.
*
* @returns image url
*/
Doorbird.prototype.getImageUrl = function () {
return ("".concat(this.options.scheme, "://").concat(this.options.host, "/bha-api/image.cgi") +
"?http-user=".concat(this.options.username, "&http-password=").concat(this.options.password));
};
/**
* Get the current image.
*
* @returns buffer with image data
*/
Doorbird.prototype.getImage = function () {
return __awaiter(this, void 0, void 0, function () {
var http, resp;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getHttp()];
case 1:
http = _a.sent();
return [4 /*yield*/, http.get(this.getImageUrl(), {
responseType: "arraybuffer",
})];
case 2:
resp = _a.sent();
return [2 /*return*/, Buffer.from(resp.data, "binary")];
}
});
});
};
/**
* Get the Doorbird live audio url.
*
* ATTENTION: if you do not provide a session id or object, the URL will contain sensitive credentials.
*
* @param session session object or id
*
* @returns audio url
*/
Doorbird.prototype.getAudioUrl = function (session) {
var baseUri = "http://".concat(this.options.host, "/bha-api/audio-receive.cgi");
if (!session) {
// Audio stream does not support https.
return "".concat(baseUri, "?http-user=").concat(this.options.username, "&http-password=").concat(this.options.password);
}
if ("object" === typeof session) {
session = session.SESSIONID;
}
// Audio stream does not support https.
return "".concat(baseUri, "?sessionid=").concat(session);
};
/**
* Get the Doorbird video url.
*
* ATTENTION: if you do not provide a session id or object, the URL will contain sensitive credentials.
*
* @param session session object or id
*
* @returns video url
*/
Doorbird.prototype.getVideoUrl = function (session) {
var baseUri = "http://".concat(this.options.host, "/bha-api/video.cgi");
if (!session) {
// Video stream does not support https.
return "".concat(baseUri, "?http-user=").concat(this.options.username, "&http-password=").concat(this.options.password);
}
if ("object" === typeof session) {
session = session.SESSIONID;
}
// Video stream does not support https.
return "".concat(baseUri, "?sessionid=").concat(session);
};
Doorbird.prototype.getHttp = function () {
return __awaiter(this, void 0, void 0, function () {
var axiosDefaults, certificate;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this.http === undefined)) return [3 /*break*/, 5];
axiosDefaults = {
headers: {
Authorization: this.authHeader(),
},
};
if (!(this.options.scheme === Scheme.https)) return [3 /*break*/, 4];
certificate = void 0;
if (!this.options.certificate) return [3 /*break*/, 1];
certificate = this.options.certificate;
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, getDoorstationCertificate(this.options.host)];
case 2:
certificate = _a.sent();
_a.label = 3;
case 3:
axiosDefaults.httpsAgent = new https.Agent({
ca: certificate,
checkServerIdentity: function () {
// we cannot check the identity, as the CN of the certifcate will not
// match the servername (likely a IP address or a network specific DN)
return undefined;
},
});
_a.label = 4;
case 4:
this.http = axios_1.default.create(axiosDefaults);
_a.label = 5;
case 5: return [2 /*return*/, this.http];
}
});
});
};
Doorbird.prototype.uri = function (path) {
return "".concat(this.baseUri()).concat(path);
};
Doorbird.prototype.baseUri = function () {
return "".concat(this.options.scheme, "://").concat(this.options.host);
};
Doorbird.prototype.authHeader = function () {
var auth = Buffer.from("".concat(this.options.username, ":").concat(this.options.password)).toString("base64");
return "Basic " + auth;
};
return Doorbird;
}());
exports.default = Doorbird;
//# sourceMappingURL=index.js.map