RealTimeClient.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* eslint-disable
  2. no-return-assign,
  3. */
  4. // TODO: This file was created by bulk-decaffeinate.
  5. // Fix any style issues and re-enable lint.
  6. /*
  7. * decaffeinate suggestions:
  8. * DS102: Remove unnecessary code created because of implicit returns
  9. * DS207: Consider shorter variations of null checks
  10. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  11. */
  12. let Client
  13. const { XMLHttpRequest } = require('../../libs/XMLHttpRequest')
  14. const io = require('socket.io-client')
  15. const async = require('async')
  16. const request = require('request')
  17. const Settings = require('@overleaf/settings')
  18. const redis = require('@overleaf/redis-wrapper')
  19. const rclient = redis.createClient(Settings.redis.websessions)
  20. const uid = require('uid-safe').sync
  21. const signature = require('cookie-signature')
  22. io.util.request = function () {
  23. const xhr = new XMLHttpRequest()
  24. const _open = xhr.open
  25. xhr.open = function () {
  26. _open.apply(xhr, arguments)
  27. if (Client.cookie != null) {
  28. return xhr.setRequestHeader('Cookie', Client.cookie)
  29. }
  30. }
  31. return xhr
  32. }
  33. module.exports = Client = {
  34. cookie: null,
  35. setSession(session, callback) {
  36. if (callback == null) {
  37. callback = function () {}
  38. }
  39. const sessionId = uid(24)
  40. session.cookie = {}
  41. return rclient.set('sess:' + sessionId, JSON.stringify(session), error => {
  42. if (error != null) {
  43. return callback(error)
  44. }
  45. const secret = Settings.security.sessionSecret
  46. const cookieKey = 's:' + signature.sign(sessionId, secret)
  47. Client.cookie = `${Settings.cookieName}=${cookieKey}`
  48. return callback()
  49. })
  50. },
  51. unsetSession(callback) {
  52. if (callback == null) {
  53. callback = function () {}
  54. }
  55. Client.cookie = null
  56. return callback()
  57. },
  58. connect(query) {
  59. const client = io.connect('http://localhost:3026', {
  60. 'force new connection': true,
  61. query,
  62. })
  63. client.on(
  64. 'connectionAccepted',
  65. (_, publicId) => (client.publicId = publicId)
  66. )
  67. client.on(
  68. 'joinProjectResponse',
  69. ({ publicId }) => (client.publicId = publicId)
  70. )
  71. return client
  72. },
  73. getConnectedClients(callback) {
  74. if (callback == null) {
  75. callback = function () {}
  76. }
  77. return request.get(
  78. {
  79. url: 'http://localhost:3026/clients',
  80. json: true,
  81. },
  82. (error, response, data) => callback(error, data)
  83. )
  84. },
  85. getConnectedClient(clientId, callback) {
  86. if (callback == null) {
  87. callback = function () {}
  88. }
  89. return request.get(
  90. {
  91. url: `http://localhost:3026/clients/${clientId}`,
  92. json: true,
  93. },
  94. (error, response, data) => {
  95. if (response?.statusCode === 404) {
  96. callback(new Error('not found'))
  97. } else {
  98. callback(error, data)
  99. }
  100. }
  101. )
  102. },
  103. disconnectClient(clientId, callback) {
  104. request.post(
  105. {
  106. url: `http://localhost:3026/client/${clientId}/disconnect`,
  107. },
  108. (error, response, data) => callback(error, data)
  109. )
  110. return null
  111. },
  112. disconnectAllClients(callback) {
  113. return Client.getConnectedClients((error, clients) => {
  114. if (error) return callback(error)
  115. async.each(
  116. clients,
  117. (clientView, cb) => Client.disconnectClient(clientView.client_id, cb),
  118. callback
  119. )
  120. })
  121. },
  122. }