diff --git a/server/package.json b/server/package.json index edcf47d16..6a80c177c 100644 --- a/server/package.json +++ b/server/package.json @@ -1,6 +1,6 @@ { "name": "ontime", - "version": "1.3.2", + "version": "1.4.0", "author": "Carlos Valente", "description": "Time keeping for live events", "repository": "https://github.com/cpvalente/ontime", diff --git a/server/src/app.js b/server/src/app.js index ceb84b766..ced15b2ec 100644 --- a/server/src/app.js +++ b/server/src/app.js @@ -87,6 +87,11 @@ const oscInEnabled = osc?.enabled !== undefined ? osc.enabled : config.osc.input const serverPort = data.settings.serverPort || config.server.port; +/** + * @description starts OSC server + * @param overrideConfig + * @return {Promise} + */ export const startOSCServer = async (overrideConfig = null) => { if (!oscInEnabled) { global.timer.info('RX', 'OSC Input Disabled'); @@ -106,6 +111,11 @@ export const startOSCServer = async (overrideConfig = null) => { // create HTTP server const server = http.createServer(app); +/** + * @description Starts all necessary services + * @param overrideConfig + * @return {Promise} + */ export const startServer = async (overrideConfig = null) => { const port = 4001; // port hardcoded @@ -126,6 +136,10 @@ export const startServer = async (overrideConfig = null) => { return returnMessage; }; +/** + * @description clean shutdown app services + * @return {Promise} + */ export const shutdown = async () => { console.log('Node service shutdown'); // shutdown express server diff --git a/server/src/classes/EventTimer.js b/server/src/classes/EventTimer.js index c87cb87fc..7a78a1cd7 100644 --- a/server/src/classes/EventTimer.js +++ b/server/src/classes/EventTimer.js @@ -183,79 +183,135 @@ export class EventTimer extends Timer { /** * @description Interface for triggering playback actions * @param {string} action - state to be triggered + * @param {string|number} [payload] - optional action payload * @returns {boolean} Whether action was called */ - trigger(action) { - let reply = true; + trigger(action, payload) { + let success = true; switch (action) { - case 'start': + case 'start': { if (this.numEvents === 0 || this.numEvents == null) return false; // Call action and force update this.info('PLAYBACK', 'Play Mode Start'); this.start(); break; - case 'pause': + } + case 'startById': { + if (this.numEvents === 0 || this.numEvents == null) return false; + const loaded = this.loadEventById(payload); + if (loaded) { + this.info('PLAYBACK', `Loaded event with ID ${payload}`); + this.info('PLAYBACK', 'Play Mode Start'); + this.start(); + } else { + return false; + } + break; + } + case 'startByIndex': { + if (this.numEvents === 0 || this.numEvents == null) return false; + const loaded = this.loadEventByIndex(payload); + if (loaded) { + this.info('PLAYBACK', `Loaded event with index ${payload}`); + this.info('PLAYBACK', 'Play Mode Start'); + this.start(); + } else { + return false; + } + break; + } + case 'pause': { if (this.numEvents === 0 || this.numEvents == null) return false; // Call action and force update this.info('PLAYBACK', 'Play Mode Pause'); this.pause(); break; - case 'stop': + } + case 'stop': { if (this.numEvents === 0 || this.numEvents == null) return false; // Call action and force update this.info('PLAYBACK', 'Play Mode Stop'); this.stop(); break; - case 'roll': + } + case 'roll': { if (this.numEvents === 0 || this.numEvents == null) return false; // Call action and force update this.info('PLAYBACK', 'Play Mode Roll'); this.roll(); break; - case 'previous': + } + case 'previous': { if (this.numEvents === 0 || this.numEvents == null) return false; // Call action and force update this.info('PLAYBACK', 'Play Mode Previous'); this.previous(); break; - case 'next': + } + case 'next': { if (this.numEvents === 0 || this.numEvents == null) return false; // Call action and force update this.info('PLAYBACK', 'Play Mode Next'); this.next(); break; - case 'unload': + } + case 'loadById': { + if (this.numEvents === 0 || this.numEvents == null) return false; + const loaded = this.loadEventById(payload); + if (loaded) { + this.info('PLAYBACK', `Loaded event with ID ${payload}`); + } else { + return false; + } + break; + } + case 'loadByIndex': { + if (this.numEvents === 0 || this.numEvents == null) return false; + const loaded = this.loadEventByIndex(payload); + if (loaded) { + this.info('PLAYBACK', `Loaded event with index ${payload}`); + } else { + return false; + } + break; + } + case 'unload': { if (this.numEvents === 0 || this.numEvents == null) return false; // Call action and force update this.info('PLAYBACK', 'Events unloaded'); this.unload(); break; - case 'reload': + } + case 'reload': { if (this.numEvents === 0 || this.numEvents == null) return false; // Call action and force update this.info('PLAYBACK', 'Reloaded event'); this.reload(); break; - case 'onAir': + } + case 'onAir': { // Call action this.info('PLAYBACK', 'Going On Air'); this.setonAir(true); break; - case 'offAir': + } + case 'offAir': { // Call action and force update this.info('PLAYBACK', 'Going Off Air'); this.setonAir(false); break; - default: + } + default: { // Error, disable flag this.error('RX', `Unhandled action triggered ${action}`); - reply = false; + success = false; break; + } } // update state this.runCycle(); - return reply; + return success; } /** @@ -553,9 +609,82 @@ export class EventTimer extends Timer { /***************************************/ /*** TIMER STATE GETTERS / SETTERS ***/ + /*** ------- WEBSOCKET API ------- ***/ /*** ----------------------------- ***/ /***************************************/ + /*******************************************/ + socket.on('ontime-test', () => { + socket.emit('hello'); + }); + + socket.on('set-start', () => { + this.trigger('start'); + socket.emit('playstate', this.state); + }); + + socket.on('set-startid', (data) => { + this.trigger('startById', data); + socket.emit('playstate', this.state); + }); + + socket.on('set-startindex', (data) => { + const eventIndex = Number(data); + if (isNaN(eventIndex)) { + return; + } + this.trigger('startByIndex', data); + socket.emit('playstate', this.state); + }); + + socket.on('set-pause', () => { + this.trigger('pause'); + socket.emit('playstate', this.state); + }); + + socket.on('set-stop', () => { + this.trigger('stop'); + socket.emit('playstate', this.state); + }); + + socket.on('set-reload', () => { + this.trigger('reload'); + socket.emit('playstate', this.state); + }); + + socket.on('set-previous', () => { + this.trigger('previous'); + socket.emit('playstate', this.state); + }); + + socket.on('set-next', () => { + this.trigger('next'); + socket.emit('playstate', this.state); + }); + + socket.on('set-roll', () => { + this.trigger('roll'); + socket.emit('playstate', this.state); + }); + + socket.on('set-delay', (data) => { + const delayTime = Number(data); + if (isNaN(delayTime)) { + return; + } + this.increment(delayTime * 1000 * 60); + }); + + socket.on('set-onAir', (data) => { + try { + const d = JSON.parse(data); + this.onAir = !!d; + this.broadcastThis('onAir', this.onAir); + } catch (error) { + this.error('RX', `Failed to parse message ${data}`); + } + }); + /*******************************************/ // general playback state socket.on('get-state', () => { @@ -593,11 +722,6 @@ export class EventTimer extends Timer { socket.emit('playstate', this.state); }); - socket.on('set-onAir', (data) => { - this.onAir = data; - this.broadcastThis('onAir', this.onAir); - }); - socket.on('get-onAir', () => { socket.emit('onAir', this.onAir); }); @@ -880,11 +1004,12 @@ export class EventTimer extends Timer { loadEventById(eventId) { const eventIndex = this._eventlist.findIndex((e) => e.id === eventId); - if (eventIndex === -1) return; + if (eventIndex === -1) return false; this.pause(); this.loadEvent(eventIndex, 'load'); // run cycle this.runCycle(); + return true; } /** @@ -892,11 +1017,12 @@ export class EventTimer extends Timer { * @param {number} eventIndex - Index of event in eventlist */ loadEventByIndex(eventIndex) { - if (eventIndex === -1 || eventIndex > this.numEvents) return; + if (eventIndex === -1 || eventIndex > this.numEvents) return false; this.pause(); this.loadEvent(eventIndex, 'load'); // run cycle this.runCycle(); + return true; } /** @@ -905,7 +1031,7 @@ export class EventTimer extends Timer { * @param {string} [type='load'] - 'load' or 'reload', whether we are keeping running time */ loadEvent(eventIndex, type = 'load') { - const e = this._eventlist[eventIndex]; + const e = this._eventlist?.[eventIndex]; if (e == null) return; const start = e.timeStart == null || e.timeStart === '' ? 0 : e.timeStart; diff --git a/server/src/classes/integrations/Osc.js b/server/src/classes/integrations/Osc.js index 49f3fe608..fdfd42d8b 100644 --- a/server/src/classes/integrations/Osc.js +++ b/server/src/classes/integrations/Osc.js @@ -89,7 +89,7 @@ export class OSCIntegration { // only specify special cases switch (payload) { - case 'overtime': + case 'overtime': { // Whether timer is negative this.oscClient.send(`${this.ADDRESS}/overtime`, payload, (err) => { if (err) { @@ -98,8 +98,8 @@ export class OSCIntegration { } }); break; - - case 'title': + } + case 'title': { if (payload != null && payload !== '') { // Send Title of current event this.oscClient.send(`${this.ADDRESS}/title`, payload, (err) => { @@ -113,8 +113,8 @@ export class OSCIntegration { reply.message = 'Missing message data'; } break; - - case 'eventNumber': + } + case 'eventNumber': { if (payload != null && payload !== '') { // Send event number of current event this.oscClient.send(`${this.ADDRESS}/eventNumber`, payload, (err) => { @@ -128,8 +128,8 @@ export class OSCIntegration { reply.message = 'Missing message data'; } break; - - case 'presenter': + } + case 'presenter': { if (payload != null && payload !== '') { // Send timer data on current event this.oscClient.send(`${this.ADDRESS}/presenter`, payload, (err) => { @@ -143,11 +143,10 @@ export class OSCIntegration { reply.message = 'Missing message data'; } break; - - default: + } + default: { // catch all for messages, allows to add new messages // but should be used with the integrations definition - // eslint-disable-next-line no-case-declarations const message = new Message(`${this.ADDRESS}/${messageType}`); if (payload != null) message.append(payload); this.oscClient.send(message, (err) => { @@ -157,6 +156,7 @@ export class OSCIntegration { } }); break; + } } return reply; } diff --git a/server/src/controllers/OscController.js b/server/src/controllers/OscController.js index ced00ddc9..0233a547e 100644 --- a/server/src/controllers/OscController.js +++ b/server/src/controllers/OscController.js @@ -42,36 +42,67 @@ export const initiateOSC = (config) => { // get second part (command) switch (path.toLowerCase()) { - case 'onair': + case 'onair': { global.timer.setonAir(true); break; - case 'offair': + } + case 'offair': { global.timer.setonAir(false); break; - case 'start': - case 'play': + } + case 'play': { global.timer.trigger('start'); break; - case 'pause': + } + case 'start': { + try { + const eventIndex = Number(args); + if (isNaN(eventIndex)) { + global.timer.error('RX', `OSC IN: event index not recognised ${args}`); + return; + } + const success = global.timer.trigger('startByIndex', eventIndex); + if (!success) { + global.timer.error('RX', `OSC IN: event index not recognised ${args}`); + } + } catch (error) { + console.log('error parsing: ', error); + } + break; + } + case 'startid': { + const success = global.timer.trigger('startById', args); + if (!success) { + global.timer.error('RX', `OSC IN: event ID not recognised ${args}`); + } + break; + } + case 'pause': { global.timer.trigger('pause'); break; - case 'prev': + } + case 'prev': { global.timer.trigger('previous'); break; - case 'next': + } + case 'next': { global.timer.trigger('next'); break; + } case 'unload': - case 'stop': + case 'stop': { global.timer.trigger('unload'); break; - case 'reload': + } + case 'reload': { global.timer.trigger('reload'); break; - case 'roll': + } + case 'roll': { global.timer.trigger('roll'); break; - case 'delay': + } + case 'delay': { try { const t = parseInt(args, 10); if (isNaN(t)) { @@ -83,7 +114,9 @@ export const initiateOSC = (config) => { console.log('error parsing: ', error); } break; + } case 'goto': + case 'load': { try { const eventIndex = parseInt(args, 10); if (isNaN(eventIndex) || eventIndex <= 0) { @@ -97,8 +130,9 @@ export const initiateOSC = (config) => { global.timer.error('RX', `OSC IN: error calling goto ${error}`); } break; + } case 'gotoid': - console.log('calling gotoid with', args); + case 'loadid': { if (args == null) { global.timer.error('RX', `OSC IN: event id not recognised or out of range ${args}}`); return; @@ -109,10 +143,12 @@ export const initiateOSC = (config) => { global.timer.error('RX', `OSC IN: error calling goto ${error}`); } break; + } - default: + default: { global.timer.warning('RX', `OSC IN: unhandled message ${path}`); break; + } } }); }; diff --git a/server/src/controllers/eventsController.js b/server/src/controllers/eventsController.js index 076b94e10..632faa91d 100644 --- a/server/src/controllers/eventsController.js +++ b/server/src/controllers/eventsController.js @@ -46,6 +46,13 @@ async function _insertAt(entry, index) { await db.write(); } +/** + * @description Inserts an entry after an element with given Id + * @param entry + * @param id + * @return {Promise} + * @private + */ async function _insertAfterId(entry, id) { const index = [...data.events].findIndex((event) => event.id === id); await _insertAt(entry, index + 1); diff --git a/server/src/controllers/playbackController.js b/server/src/controllers/playbackController.js index 4014c3ace..5ea8445c2 100644 --- a/server/src/controllers/playbackController.js +++ b/server/src/controllers/playbackController.js @@ -19,7 +19,23 @@ export const offAir = async (req, res) => { // Create controller for GET request to '/playback/start' // Starts timer object export const pbStart = async (req, res) => { - global.timer.trigger('start') ? res.sendStatus(200) : res.sendStatus(400); + const { eventId, eventIndex } = req.query; + if (eventId) { + global.timer.trigger('startById', eventId) + ? res.sendStatus(200) + : res.status(400).send('Invalid event ID'); + } else if (eventIndex) { + const index = Number(eventIndex); + if (!isNaN(index)) { + global.timer.trigger('startByIndex', index - 1) + ? res.sendStatus(200) + : res.status(400).send('Invalid event index'); + } else { + res.status(400).send('Invalid event index'); + } + } else { + global.timer.trigger('start') ? res.sendStatus(200) : res.sendStatus(400); + } }; // Create controller for GET request to '/playback/pause' @@ -52,6 +68,28 @@ export const pbNext = async (req, res) => { global.timer.trigger('next') ? res.sendStatus(200) : res.sendStatus(400); }; +// Create controller for GET request to '/playback/load' +// Load requested event +export const pbLoad = async (req, res) => { + const { eventId, eventIndex } = req.query; + if (eventId) { + global.timer.trigger('loadById', eventId) + ? res.sendStatus(200) + : res.status(400).send('Invalid event ID'); + } else if (eventIndex) { + const index = Number(eventIndex); + if (!isNaN(index)) { + global.timer.trigger('loadByIndex', index - 1) + ? res.sendStatus(200) + : res.status(400).send('Invalid event index'); + } else { + res.status(400).send('Invalid event index'); + } + } else { + res.status(400).send('No event given'); + } +}; + // Create controller for GET request to '/playback/unload' // Unloads any events export const pbUnload = async (req, res) => { diff --git a/server/src/package.json b/server/src/package.json index 3d63c1a0e..ab0e80ca0 100644 --- a/server/src/package.json +++ b/server/src/package.json @@ -1,20 +1,19 @@ { "name": "ontime-server", "type": "module", - "version": "1.1.1", + "version": "1.2.0", "dependencies": { "body-parser": "^1.20.0", - "dotenv": "^16.0.0", - "express": "^4.18.0", - "express-session": "~1.17.1", + "dotenv": "^16.0.1", + "express": "^4.18.1", + "express-session": "^1.17.3", "lowdb": "3.0.0", "multer": "^1.4.4", "nanoid": "^3.3.3", "node-osc": "^6.1.16", "node-xlsx": "^0.21.0", - "passport": "^0.5.2", + "passport": "^0.6.0", "passport-local": "~1.0.0", - "socket-io": "^1.0.0", "socket.io": "^4.4.1" }, "devDependencies": { diff --git a/server/src/routes/__tests__/playbackRouter.tests.js b/server/src/routes/__tests__/playbackRouter.tests.js index d3bbae9d7..6c555246e 100644 --- a/server/src/routes/__tests__/playbackRouter.tests.js +++ b/server/src/routes/__tests__/playbackRouter.tests.js @@ -18,100 +18,91 @@ describe('When a GET request request is sent', () => { }); }); -describe('When a GET state change is sent', () => { - test('GET /playback/onAir returns 200', async () => { +describe('When a POST state change is sent', () => { + test('POST /playback/onAir returns 200', async () => { await supertest(server) - .get('/playback/onAir') + .post('/playback/onAir') .expect(200) .then((response) => { expect(response.text.includes('')).toBe(false); }); }); - test('GET /playback/offAir returns 200', async () => { + test('POST /playback/offAir returns 200', async () => { await supertest(server) - .get('/playback/offAir') + .post('/playback/offAir') .expect(200) .then((response) => { expect(response.text.includes('')).toBe(false); }); }); - test('GET /playback/start returns 200', async () => { + test('POST /playback/start returns 200', async () => { await supertest(server) - .get('/playback/start') + .post('/playback/start') .expect(200) .then((response) => { expect(response.text.includes('')).toBe(false); }); }); - test('GET /playback/play returns 200', async () => { + test('POST /playback/pause returns 200', async () => { await supertest(server) - .get('/playback/play') + .post('/playback/pause') .expect(200) .then((response) => { expect(response.text.includes('')).toBe(false); }); }); - test('GET /playback/pause returns 200', async () => { + test('POST /playback/stop returns 200', async () => { await supertest(server) - .get('/playback/pause') + .post('/playback/stop') .expect(200) .then((response) => { expect(response.text.includes('')).toBe(false); }); }); - test('GET /playback/stop returns 200', async () => { + test('POST /playback/roll returns 200', async () => { await supertest(server) - .get('/playback/stop') + .post('/playback/roll') .expect(200) .then((response) => { expect(response.text.includes('')).toBe(false); }); }); - test('GET /playback/roll returns 200', async () => { + test('POST /playback/previous returns 200', async () => { await supertest(server) - .get('/playback/roll') + .post('/playback/previous') .expect(200) .then((response) => { expect(response.text.includes('')).toBe(false); }); }); - test('GET /playback/previous returns 200', async () => { + test('POST /playback/next returns 200', async () => { await supertest(server) - .get('/playback/previous') + .post('/playback/next') .expect(200) .then((response) => { expect(response.text.includes('')).toBe(false); }); }); - test('GET /playback/next returns 200', async () => { + test('POST /playback/unload returns 200', async () => { await supertest(server) - .get('/playback/next') + .post('/playback/unload') .expect(200) .then((response) => { expect(response.text.includes('')).toBe(false); }); }); - test('GET /playback/unload returns 200', async () => { + test('POST /playback/reload returns 200', async () => { await supertest(server) - .get('/playback/unload') - .expect(200) - .then((response) => { - expect(response.text.includes('')).toBe(false); - }); - }); - - test('GET /playback/reload returns 200', async () => { - await supertest(server) - .get('/playback/reload') + .post('/playback/reload') .expect(200) .then((response) => { expect(response.text.includes('')).toBe(false); @@ -126,4 +117,82 @@ describe('When a GET state change is sent', () => { expect(response.text.includes('')).toBe(true); }); }); + + test('POST of unknown request returns 404', async () => { + await supertest(server).post('/playback/madeup').expect(404); + }); +}); + +describe('Test POST requests with payload', () => { + describe('Start given event', () => { + test('POST /playback/start with correctly given ID', async () => { + await supertest(server) + .post('/playback/start') + .query({eventId: '5946'}) + .expect(200); + }); + test('POST /playback/start with correctly given index', async () => { + await supertest(server) + .post('/playback/start') + .query({eventIndex: '2'}) + .expect(200); + }); + test('POST /playback/start with incorrectly given ID', async () => { + await supertest(server) + .post('/playback/start') + .query({ + eventId: 'doesntexist', + }) + .expect(400); + }); + test('POST /playback/start with incorrectly given index', async () => { + await supertest(server) + .post('/playback/start') + .query({ + eventIndex: '25', + }) + .expect(400); + }); + test('POST /playback/start with incorrectly given index (NaN)', async () => { + await supertest(server) + .post('/playback/start') + .query({ + eventIndex: 'notanumber', + }) + .expect(400); + }); + }); + + describe('Load given event', () => { + test('POST /playback/load with correctly given ID', async () => { + await supertest(server) + .post('/playback/load') + .query({eventId: '5946'}) + .expect(200); + }); + test('POST /playback/load with correctly given index', async () => { + await supertest(server) + .post('/playback/load') + .query({eventIndex: '2'}) + .expect(200); + }); + test('POST /playback/load with incorrectly given ID', async () => { + await supertest(server) + .post('/playback/load') + .query({eventId: 'doesntexist'}) + .expect(400); + }); + test('POST /playback/load with incorrectly given index', async () => { + await supertest(server) + .post('/playback/load') + .query({eventIndex: '25'}) + .expect(400); + }); + test('POST /playback/load with incorrectly given index (NaN)', async () => { + await supertest(server) + .post('/playback/load') + .query({ eventIndex: 'notanumber' }) + .expect(400); + }); + }); }); diff --git a/server/src/routes/playbackRouter.js b/server/src/routes/playbackRouter.js index dcad1b0bd..4967c512f 100644 --- a/server/src/routes/playbackRouter.js +++ b/server/src/routes/playbackRouter.js @@ -12,6 +12,7 @@ import { pbRoll, pbPrevious, pbNext, + pbLoad, pbUnload, pbReload, } from '../controllers/playbackController.js'; @@ -20,32 +21,34 @@ import { router.get('/', pbGet); // create route between controller and '/playback/onAir' endpoint -router.get('/onAir', onAir); +router.post('/onAir', onAir); // create route between controller and '/playback/offAir' endpoint -router.get('/offAir', offAir); +router.post('/offAir', offAir); // create route between controller and '/playback/start' endpoint -router.get('/start', pbStart); -router.get('/play', pbStart); +router.post('/start', pbStart); // create route between controller and '/playback/pause' endpoint -router.get('/pause', pbPause); +router.post('/pause', pbPause); // create route between controller and '/playback/stop' endpoint -router.get('/stop', pbStop); +router.post('/stop', pbStop); // create route between controller and '/playback/roll' endpoint -router.get('/roll', pbRoll); +router.post('/roll', pbRoll); // create route between controller and '/playback/previous' endpoint -router.get('/previous', pbPrevious); +router.post('/previous', pbPrevious); // create route between controller and '/playback/next' endpoint -router.get('/next', pbNext); +router.post('/next', pbNext); + +// create route between controller and '/playback/load' endpoint +router.post('/load', pbLoad); // create route between controller and '/playback/unload' endpoint -router.get('/unload', pbUnload); +router.post('/unload', pbUnload); // create route between controller and '/playback/reload' endpoint -router.get('/reload', pbReload); +router.post('/reload', pbReload); diff --git a/server/src/yarn.lock b/server/src/yarn.lock index 7f6773bca..c18ab4efb 100644 --- a/server/src/yarn.lock +++ b/server/src/yarn.lock @@ -282,16 +282,21 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.4.1, cookie@~0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" - integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== +cookie@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== cookie@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -373,10 +378,10 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dotenv@^16.0.0: - version "16.0.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.0.tgz#c619001253be89ebb638d027b609c75c26e47411" - integrity sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q== +dotenv@^16.0.1: + version "16.0.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d" + integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ== ee-first@1.1.1: version "1.1.1" @@ -540,12 +545,12 @@ exit-on-epipe@~1.0.1: resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== -express-session@~1.17.1: - version "1.17.2" - resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.2.tgz#397020374f9bf7997f891b85ea338767b30d0efd" - integrity sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ== +express-session@^1.17.3: + version "1.17.3" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.3.tgz#14b997a15ed43e5949cb1d073725675dd2777f36" + integrity sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw== dependencies: - cookie "0.4.1" + cookie "0.4.2" cookie-signature "1.0.6" debug "2.6.9" depd "~2.0.0" @@ -554,10 +559,10 @@ express-session@~1.17.1: safe-buffer "5.2.1" uid-safe "~2.1.5" -express@^4.18.0: - version "4.18.0" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.0.tgz#7a426773325d0dd5406395220614c0db10b6e8e2" - integrity sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg== +express@^4.18.1: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== dependencies: accepts "~1.3.8" array-flatten "1.1.1" @@ -1051,13 +1056,14 @@ passport-strategy@1.x.x: resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= -passport@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/passport/-/passport-0.5.2.tgz#0cb38dd8a71552c8390dfa6a9a6f7f3909954bcf" - integrity sha512-w9n/Ot5I7orGD4y+7V3EFJCQEznE5RxHamUxcqLT2QoJY0f2JdN8GyHonYFvN0Vz+L6lUJfVhrk2aZz2LbuREw== +passport@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.6.0.tgz#e869579fab465b5c0b291e841e6cc95c005fac9d" + integrity sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug== dependencies: passport-strategy "1.x.x" pause "0.0.1" + utils-merge "^1.0.1" path-is-absolute@^1.0.0: version "1.0.1" @@ -1266,11 +1272,6 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -socket-io@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/socket-io/-/socket-io-1.0.0.tgz#fc566f4d30a6370224d07e65dcef386bd8f5d296" - integrity sha1-/FZvTTCmNwIk0H5l3O84a9j10pY= - socket.io-adapter@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz#4d6111e4d42e9f7646e365b4f578269821f13486" @@ -1409,7 +1410,7 @@ util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -utils-merge@1.0.1: +utils-merge@1.0.1, utils-merge@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=