UNPKG

node-firewalla

Version:

Package to talk your firewalla box & API

146 lines (145 loc) 6.75 kB
"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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Networker_js_1 = require("./Networker.js"); const AuthApi_js_1 = require("./AuthApi.js"); const index_js_1 = require("../utils/index.js"); const node_fetch_1 = __importDefault(require("node-fetch")); const index_js_2 = require("../models/index.js"); const FWWebLoginAPI_js_1 = __importDefault(require("./FWWebLoginAPI.js")); const node_querystring_1 = __importDefault(require("node:querystring")); const sleep = ms => new Promise(r => setTimeout(r, ms)); class FWGroupApi extends AuthApi_js_1.AuthApi { constructor() { if (FWGroupApi._instance) { return FWGroupApi._instance; } super(); FWGroupApi._instance = this; let serverInstance = "v2"; this.setApiNetworker(new Networker_js_1.Networker(`https://firewalla.encipher.io/app/api/${serverInstance}`)); } receiveMessageFromGroup(fwGroup, count = 1, since = 0) { return __awaiter(this, void 0, void 0, function* () { let query = node_querystring_1.default.encode({ count, peerId: fwGroup.gid, since, }); return this.getApiNetworker().authGetRelative(`/service/message/${fwGroup.aid}/${fwGroup.gid}/eptgroup/${fwGroup.eid}?${query}`); }); } startRendezVous(rendezVousId, license) { return __awaiter(this, void 0, void 0, function* () { return this.getApiNetworker().authPostRelative(`/ept/rendezvous/me`, { rid: rendezVousId, evalue: JSON.stringify({ license }) }); }); } /** * @param qrcode - The QR code JSON isible in the Firewalla App -> Select your box -> Settings -> Advanced -> Allow Additional Pairing -> Turn on Additional Pairing * @param email - The email that should be linked to the ETP token (visible in the app) * @param localIp - The IP of the box you want to connect to */ joinGroup(qrcode, email, localIp) { return __awaiter(this, void 0, void 0, function* () { let firstTime = false; // where to get this? let prefix = firstTime ? "cybersecuritymadesimple" : qrcode.license.substring(0, 8); let aesKey = prefix + qrcode.seed; let rid = index_js_1.SecureUtil.aesDecrypt(qrcode.ek, aesKey); let { access_token } = yield this.login(email); this.setAuth(access_token); yield this.startRendezVous(rid, qrcode.license); let maxTries = 10; let currTry = 0; let newGroup = undefined; do { if (currTry >= maxTries) { throw "Handshake failed, max tries exceeded"; } yield sleep(currTry == 0 ? 0 : 3000); let response = yield this.login(email); newGroup = response.groups.filter(e => e._id == qrcode.gid)[0]; currTry++; } while (!newGroup); return index_js_2.FWGroup.fromJson(newGroup, localIp); }); } /** * @param email - The email that should be linked to the ETP token (Only required when first creating your ETP token) */ login(email = "") { return __awaiter(this, void 0, void 0, function* () { let body = { assertion: { name: email, info: { name: "circle" }, publicKey: index_js_1.SecureUtil.publicKey, appId: "com.rottiesoft.circle", appSecret: "fbb05afa-9145-41f1-8076-9de8be56f104", signature: "" } }; let response = yield (0, node_fetch_1.default)("https://firewalla.encipher.io/app/api/v2/login/eptoken", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) }).then((r) => r.json()); this.setAuth(response.access_token); return response; }); } /** * * @param fwGroup - The Firewalla Group/Box the token needs access to * @param validDays - How many days the token should be valid for * @returns WebLoginTokenResponse */ /** */ getFireguardToken(fwGroup, validDays = 1) { return __awaiter(this, void 0, void 0, function* () { let token = crypto.randomUUID(); let response = yield this.getApiNetworker().authPost(`https://my.firewalla.com/v1/auth/authorize/${token}?days=${validDays}`, [{ gid: fwGroup.gid }]); FWWebLoginAPI_js_1.default.setAuth(response.token); return response; }); } sendMessageToBox(fwGroup, fwMessage) { return __awaiter(this, void 0, void 0, function* () { let url = fwGroup.getMessageUrl(); let encryptionKey = fwGroup.getSymmetricKey(); let messageString = JSON.stringify(fwMessage.toJSON(fwGroup.eid)); let message = index_js_1.SecureUtil.aesEncrypt(messageString, encryptionKey); let timestamp = Math.floor(Number(new Date()) / 1000); let response = yield this.getApiNetworker().authPost(url, { timestamp, message }); if (response.error) { throw response.error; } response = JSON.parse(index_js_1.SecureUtil.aesDecrypt(response.message, encryptionKey)); if (response.code !== 200) { throw response; } return response.data; }); } } exports.default = new FWGroupApi();