SessionSockets.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. const metrics = require('@overleaf/metrics')
  2. const OError = require('@overleaf/o-error')
  3. const { EventEmitter } = require('node:events')
  4. const { MissingSessionError } = require('./Errors')
  5. module.exports = function (io, sessionStore, cookieParser, cookieName) {
  6. const missingSessionError = new MissingSessionError()
  7. const sessionSockets = new EventEmitter()
  8. function next(error, socket, session) {
  9. sessionSockets.emit('connection', error, socket, session)
  10. }
  11. io.on('connection', function (socket) {
  12. const req = socket.handshake
  13. cookieParser(req, {}, function () {
  14. const sessionId = req.signedCookies && req.signedCookies[cookieName]
  15. if (!sessionId) {
  16. metrics.inc('session.cookie', 1, {
  17. // the cookie-parser middleware sets the signed cookie to false if the
  18. // signature is invalid, so we can use this to detect bad signatures
  19. status: sessionId === false ? 'bad-signature' : 'none',
  20. })
  21. return next(missingSessionError, socket)
  22. }
  23. sessionStore.get(sessionId, function (error, session) {
  24. if (error) {
  25. metrics.inc('session.cookie', 1, { status: 'error' })
  26. OError.tag(error, 'error getting session from sessionStore', {
  27. sessionId,
  28. })
  29. return next(error, socket)
  30. }
  31. if (!session) {
  32. metrics.inc('session.cookie', 1, { status: 'missing' })
  33. return next(missingSessionError, socket)
  34. }
  35. metrics.inc('session.cookie', 1, { status: 'signed' })
  36. next(null, socket, session)
  37. })
  38. })
  39. })
  40. return sessionSockets
  41. }