no jibo cloud calls via JIBO_BYPASS_PORTAL

This commit is contained in:
2026-04-06 02:03:56 +03:00
parent ebee3a5534
commit c32c27b3cb
5 changed files with 126 additions and 16 deletions

View File

@@ -4,6 +4,18 @@ const axios_1 = require("axios");
const events_1 = require("events");
const command_requester_1 = require("@jibo/command-requester");
const constants_1 = require("./constants");
const fs_1 = require("fs");
function readIfExists(path) {
if (!path) {
return undefined;
}
try {
return fs_1.readFileSync(path, "utf8");
}
catch (_a) {
return undefined;
}
}
/**
* An API handle to a Jibo robot, used to request commands
* @class Robot
@@ -38,6 +50,34 @@ class Robot extends events_1.EventEmitter {
get requester() {
return this._requester;
}
/**
* Configure direct/offline connection values to avoid cloud lookup.
* Accepts inline PEM values or *_PATH values.
*/
configureDirectConnection(config) {
if (!config) {
return;
}
console.log("[JIBO_BYPASS] configureDirectConnection(): applying offline connection config");
if (config.ip) {
this._ip = config.ip;
}
if (config.skipTls) {
this._skipTls = true;
console.log("[JIBO_BYPASS] configureDirectConnection(): TLS disabled for direct websocket connection");
}
if (config.fingerprint) {
this._fingerprint = config.fingerprint;
}
const cert = config.certPem || readIfExists(config.certPath);
if (cert) {
this._certificate = cert;
}
const key = config.keyPem || readIfExists(config.keyPath);
if (key) {
this._key = key;
}
}
/**
* Establish a connection to this robot
* @method Robot.connect
@@ -50,24 +90,35 @@ class Robot extends events_1.EventEmitter {
await this._requestCertificate();
await this._retrieveCertificate();
}
if (!this._skipTls && (!this._certificate || !this._key)) {
console.log("[JIBO_BYPASS] connect(): missing direct credentials", {
hasIp: !!this._ip,
hasCert: !!this._certificate,
hasKey: !!this._key,
hasFingerprint: !!this._fingerprint,
});
throw new Error("Missing certificate/key for direct robot connection");
}
const options = {
port: constants_1.PORT,
key: this._key,
cert: this._certificate,
rejectUnauthorized: false,
perMessageDeflate: false,
fingerprint: this._fingerprint,
};
if (!this._skipTls) {
options.key = this._key;
options.cert = this._certificate;
options.rejectUnauthorized = false;
options.fingerprint = this._fingerprint;
}
this._requester = new command_requester_1.CommandRequester();
this._requester.disconnected.on(data => {
this._connected = false;
this.emit('disconnected', data);
this.emit('status', 'disconnected');
this.emit("disconnected", data);
this.emit("status", "disconnected");
});
return this._requester.connect(this._ip, options)
.then(() => {
this._connected = true;
this.emit('status', 'connected');
this.emit("status", "connected");
})
.catch(err => { throw new Error(err.message); });
}
@@ -79,27 +130,29 @@ class Robot extends events_1.EventEmitter {
// Don't throw an error if this is called in a late cleanup and this
// falls out of scope
if (this) {
this._requester.disconnect();
if (this._requester) {
this._requester.disconnect();
}
this._certificate = null;
this._connected = false;
this._fingerprint = null;
this._ip = null;
this._key = null;
this._requester = null;
this.emit('status', 'disconnected');
this.emit("status", "disconnected");
}
}
async _requestCertificate() {
const certificateCreationUri = `https://${constants_1.ENDPOINT}/rom/v1/certificates`;
const body = { friendlyId: this.serialName };
const headers = { 'Authorization': `${this.tokenType} ${this.accessToken}` };
const headers = { Authorization: `${this.tokenType} ${this.accessToken}` };
await axios_1.default.post(certificateCreationUri, body, { headers })
.then(() => this.emit('status', 'certificateRequested'))
.then(() => this.emit("status", "certificateRequested"))
.catch(err => { throw new Error(err.message); });
}
async _retrieveCertificate() {
const certificateRetrievalUri = `https://${constants_1.ENDPOINT}/rom/v1/certificates/client?friendlyId=${this.serialName}`;
const headers = { 'Authorization': `${this.tokenType} ${this.accessToken}` };
const headers = { Authorization: `${this.tokenType} ${this.accessToken}` };
this._ip = null;
let numTries = 0;
while (!this._ip && numTries < constants_1.MAX_CERT_TRIES) {
@@ -119,9 +172,9 @@ class Robot extends events_1.EventEmitter {
}
}
if (!this._ip) {
throw new Error('Failed to retrieve certificate');
throw new Error("Failed to retrieve certificate");
}
this.emit('status', 'certificateReceived');
this.emit("status", "certificateReceived");
}
}
exports.Robot = Robot;