UNPKG

domotz-remote-pawn

Version:

Domotz Agent

145 lines (129 loc) 5.74 kB
/** 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;