/**
* @module bulb/replies
*/
'use strict';
class ControlReply {
/**
* Wraps a parsed reply forom the control port.
* @param {object} [parsedReply] - Parsed reply object.
*/
constructor(data = {}, type) {
this._type = type || '__DEFAULT';
for (let prop in data) {
this[prop] = data[prop];
}
}
/**
* Parses the reply from the AUTHCHALLENGE {@link module:bulb/commands~ControlCommand}.
* @param {string[]} output
* @returns {module:bulb/replies~ControlReply~AuthChallengeResult}
*/
static AUTHCHALLENGE(output) {
let result = output[0].split(' ');
let [, hash, nonce] = result;
return new AuthChallengeReply({
hash: hash.split('=').pop(),
nonce: nonce ? nonce.split('=').pop() : null
});
}
/**
* @typedef {object} module:bulb/replies~ControlReply~AuthChallengeResult
* @property {string} hash - The server hash.
* @property {string} nonce - The server nonce.
*/
/**
* Parses the reply from the PROTOCOLINFO {@link module:bulb/commands~ControlCommand}.
* @param {string[]} output
* @returns {module:bulb/replies~ControlReply~ProtocolInfoResult}
*/
static PROTOCOLINFO(output) {
let [proto, auth, version] = output;
proto = proto.split(' ');
auth = auth.split(' ');
version = version.split(' ');
auth.shift();
let methods = auth.shift();
let cookieFile = auth.length
? auth.join(' ').split('=')[1].split('"').join('')
: null;
return new ProtocolInfoReply({
protocol: proto[1],
auth: {
methods: methods.split('=')[1].split(','),
cookieFile
},
version: {
tor: version[1].split('=')[1].split('"').join('')
}
});
}
/**
* @typedef {object} module:bulb/replies~ControlReply~ProtocolInfoResult
* @property {string} protocol
* @property {object} auth
* @property {string[]} auth.methods
* @property {string} auth.cookieFile
* @property {object} version
* @property {string} version.tor
*/
/**
* Parses the response from the ADD_ONION {@link module:bulb/replies~ControlReply~AddOnionResult}
* @param {string[]} output
* @returns {AddOnionResult}
*/
static ADD_ONION(output) {
return new AddOnionReply({
serviceId: output[0].split('=')[1],
privateKey: (output[1] && output[1].includes('PrivateKey'))
? output[1].split('=')[1]
: null
});
}
/**
* @typedef {object} module:bulb/replies~ControlReply~AddOnionResult
* @property {string} serviceId - The hidden service url without .onion.
* @property {string} [privateKey] - The generated private key.
*/
/**
* Parses the result of the GETCONF {@link module:bulb/commands~ControlCommand}.
* @param {string[]} output
* @returns {module:bulb/replies~ControlReply~GetConfigResult}
*/
static GETCONF(output) {
return new GetConfReply({
conf: output.map((line) => line.split('=')[1])
});
}
/**
* @typedef {object} module:bulb/replies~ControlReply~GetConfigResult
* @property {string[]} conf
*/
/**
* Parses the result of the GETINFO {@link module:bulb/commands~ControlCommand}.
* @param {string[]} output
* @returns {module:bulb/replies~ControlReply~GetInfoResult}
*/
static GETINFO(output) {
if (output.length > 1) {
return new GetInfoReply({
info: output.map((line) => line.split('=')[1]).join('\n')
});
}
return new GetInfoReply({
info: output[0].split('=')[1]
});
}
/**
* @typedef {object} module:bulb/replies~ControlReply~GetInfoResult
* @property {string[]} info
*/
}
class AuthChallengeReply extends ControlReply {
/**
* @constructor
* @param {module:bulb/replies~ControlReply~AuthChallengeResult}
*/
constructor(data) {
super(data);
this._type = 'AUTHCHALLENGE';
}
}
class ProtocolInfoReply extends ControlReply {
/**
* @constructor
* @param {module:bulb/replies~ControlReply~ProtocolInfoResult}
*/
constructor(data) {
super(data, 'PROTOCOLINFO');
}
}
class AddOnionReply extends ControlReply {
/**
* @constructor
* @param {module:bulb/replies~ControlReply~AddOnionResult}
*/
constructor(data) {
super(data, 'ADD_ONION');
}
}
class GetInfoReply extends ControlReply {
/**
* @constructor
* @param {module:bulb/replies~ControlReply~GetInfoResult}
*/
constructor(data) {
super(data, 'GETINFO');
}
}
class GetConfReply extends ControlReply {
/**
* @constructor
* @param {module:bulb/replies~ControlReply~GetConfResult}
*/
constructor(data) {
super(data, 'GETCONF');
}
}
module.exports.ControlReply = ControlReply;
module.exports.AuthChallengeReply = AuthChallengeReply;
module.exports.ProtocolInfoReply = ProtocolInfoReply;
module.exports.AddOnionReply = AddOnionReply;
module.exports.GetInfoReply = GetInfoReply;
module.exports.GetConfReply = GetConfReply;