node-firewalla
Version:
Package to talk your firewalla box & API
146 lines (145 loc) • 6.75 kB
JavaScript
;
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();