domotz-remote-pawn
Version:
Domotz Agent
145 lines (129 loc) • 5.74 kB
JavaScript
/** This file is part of Domotz Agent.
* Copyright (C) 2021 Domotz Ltd
*
* Domotz Agent is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Domotz Agent is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>.
**/
/**
*
* Created by Alessandro Pagiaro <a.pagiaro@domotz.com> on 06/07/2021.
*/
var factory = function (resourceLocator, host, registerRequest) {
var fileUtils = resourceLocator.utils.file;
var path = resourceLocator.path;
var os = resourceLocator.os;
var fsActivationTokenPath = path.join(os.tmpdir(), 'domotz_activation_token.json');
var configurationUpdater = resourceLocator.configurationUpdater;
var myConsole = resourceLocator.log.decorateLogs();
var tokenExpirationTimeout = null;
var pollingInterval = null;
var activationTokenInfo = null;
function clearTimeoutAndInterval() {
if (tokenExpirationTimeout !== null) {
clearTimeout(tokenExpirationTimeout);
tokenExpirationTimeout = null;
}
if (pollingInterval !== null) {
clearInterval(pollingInterval);
pollingInterval = null;
}
}
function storeActivationTokenCache(body) {
myConsole.debug('Storing ActivationToken %s in %s', body.token, fsActivationTokenPath);
fileUtils.writeFileSafe(fsActivationTokenPath, JSON.stringify(body));
activationTokenInfo = body;
}
function resetActivationTokenCache() {
myConsole.debug('Deleting %s', fsActivationTokenPath);
fileUtils.deleteFile(fsActivationTokenPath);
activationTokenInfo = null;
}
function handleToken(activationToken, tokenExpirationTime) {
pollingInterval = setInterval(function () {
getActivationUrl(activationToken)
.then(function (response) {
var configurationUrl = response.activation_url;
myConsole.info('Received configuration url');
configurationUpdater.getInitialConfiguration(configurationUrl);
resetActivationTokenCache();
clearTimeoutAndInterval();
})
.catch(function (error) {
myConsole.error('Unable to retrieve activation URL: <message: %s>', error.message);
});
}, 10000);
tokenExpirationTimeout = setTimeout(function () {
myConsole.warn('Current ActivationToken expired');
resetActivationTokenCache();
clearTimeoutAndInterval();
}, tokenExpirationTime);
}
function create(ipAddress, listeningPort) {
var body = {
private_ip: ipAddress,
port: listeningPort,
};
return registerRequest.sendWithPromise('not-configured-agent/' + host.getMAC() + '/activation-token', 'POST', body);
}
function getActivationUrl(token) {
return registerRequest.sendWithPromise('agent/activation-token/' + token + '/activation-url', 'GET');
}
function checkTokenValidity(tokenReceivedTime, expiresInMinutes) {
const tokenExpirationTime = expiresInMinutes * 60 * 1000;
const tokenAvailableTime = Date.now() - tokenReceivedTime;
return tokenAvailableTime < tokenExpirationTime;
}
function getAvailableTime(tokenReceivedTime) {
return Date.now() - tokenReceivedTime;
}
var fileStats = fileUtils.getFileStats(fsActivationTokenPath);
if (fileStats) {
var cachedBody = fileUtils.readFile(fsActivationTokenPath, JSON.parse);
if (cachedBody && cachedBody.token && cachedBody.token_received_time) {
var readableDate = new Date(cachedBody.token_received_time);
var tokenAvailableTime = getAvailableTime(cachedBody.token_received_time);
if (checkTokenValidity(cachedBody.token_received_time, cachedBody.expires_in_minutes)) {
myConsole.info(
'Found ActivationToken %s in cache with receivedTime: %s, use this token for activating the agent',
cachedBody.token,
readableDate.toString()
);
handleToken(cachedBody.token, tokenAvailableTime);
} else {
myConsole.warn('Found ActivationToken %s in cache expired, receivedTime: %s', cachedBody.token, readableDate.toString());
resetActivationTokenCache();
}
}
}
function getActivationToken() {
if (!activationTokenInfo) {
return null;
}
if (checkTokenValidity(activationTokenInfo.token_received_time, activationTokenInfo.expires_in_minutes)) {
return activationTokenInfo.token;
} else {
myConsole.warn('ActivationToken is not valid, returning null');
return null;
}
}
return {
clearTimeoutAndInterval: clearTimeoutAndInterval,
create: create,
getActivationUrl: getActivationUrl,
handleToken: handleToken,
resetActivationTokenCache: resetActivationTokenCache,
storeActivationTokenCache: storeActivationTokenCache,
getActivationToken: getActivationToken,
};
};
module.exports.factory = factory;