UNPKG

doorbird

Version:

Node JS library for the Doorbird LAN API.

1,017 lines 43 kB
"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 += "&param=".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