/* eslint no-param-reassign: off, import/prefer-default-export: off */ const jwt = require('jsonwebtoken'); const { cert } = require('./config'); function Timeout(fn, interval) { this.id = setTimeout(fn, interval); this.cleared = false; this.clear = () => { this.cleared = true; clearTimeout(this.id); }; } const interval = (fn, initialTTL, output = {}) => { const getTimeout = ttl => new Timeout(async () => { let TTL; try { if (this.cleared) { return; } TTL = await Promise.resolve(fn()); } catch (error) { console.error(error); TTL = initialTTL; } if (this.cleared) { return; } const nextTTL = parseInt(TTL, 10) || initialTTL; interval(fn, nextTTL, output); }, ttl); const getOutput = (timeout) => { const stop = () => { if (timeout) { timeout.clear(); } }; return { start: (ttl) => { if (timeout && !timeout.cleared) { throw new Error('Interval is already started'); } const newOutput = getOutput(getTimeout(ttl || initialTTL)); Object.assign(output, getOutput(newOutput)); return output; }, startNow: () => { if (timeout && !timeout.cleared) { throw new Error('Interval is already started'); } Object.assign(output, getOutput(getTimeout(0))); return output; }, stop, restart: (ttl) => { stop(); Object.assign(output, getOutput(getTimeout(ttl || initialTTL))); return output; }, restartNow: () => { stop(); Object.assign(output, getOutput(getTimeout(0))); return output; }, }; }; if (Object.keys(output).length === 0) { Object.assign(output, getOutput(null)); } else { Object.assign(output, getOutput(getTimeout(initialTTL))); } return output; }; const generateRandomString = (length) => { let text = ''; const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-,;:!?./§ù*^$£%µ&"\'(='; for (let i = 0; i < length; i += 1) { text += possible.charAt(Math.floor(Math.random() * possible.length)); } return text; }; const createSignedJWT = () => jwt.sign({ state: generateRandomString(20) }, cert, { algorithm: 'RS256' }); module.exports = { interval, createSignedJWT };