const RealTimeClient = require('./helpers/RealTimeClient') const FixturesManager = require('./helpers/FixturesManager') const Settings = require('@overleaf/settings') const signature = require('cookie-signature') const { expect } = require('chai') describe('SessionSockets', function () { beforeEach(function (done) { FixturesManager.setUpProject( { privilegeLevel: 'owner', }, (err, options) => { if (err) return done(err) this.checkSocket = function (fn) { RealTimeClient.connect(options.project_id, fn) } done() } ) }) describe('without cookies', function () { beforeEach(function () { RealTimeClient.cookie = null }) it('should return a lookup error', function (done) { this.checkSocket(error => { expect(error).to.exist expect(error.message).to.equal('invalid session') done() }) }) }) describe('with a different cookie', function () { beforeEach(function () { RealTimeClient.cookie = 'some.key=someValue' }) it('should return a lookup error', function (done) { this.checkSocket(error => { expect(error).to.exist expect(error.message).to.equal('invalid session') done() }) }) }) describe('with an invalid cookie', function () { beforeEach(function (done) { RealTimeClient.setSession({}, error => { if (error) { return done(error) } RealTimeClient.cookie = `${ Settings.cookieName }=${RealTimeClient.cookie.slice(17, 49)}` done() }) }) it('should return a lookup error', function (done) { this.checkSocket(error => { expect(error).to.exist expect(error.message).to.equal('invalid session') done() }) }) }) describe('with a valid cookie and no matching session', function () { beforeEach(function () { RealTimeClient.cookie = `${Settings.cookieName}=unknownId` }) it('should return a lookup error', function (done) { this.checkSocket(error => { expect(error).to.exist expect(error.message).to.equal('invalid session') done() }) }) }) describe('with a valid cookie and a matching session', function () { it('should not return an error', function (done) { this.checkSocket(error => { expect(error).to.not.exist done() }) }) }) describe('with a cookie signed by the fallback key and a matching session', function () { beforeEach(function () { RealTimeClient.cookie = RealTimeClient.cookieSignedWith.sessionSecretFallback }) it('should not return an error', function (done) { this.checkSocket(error => { expect(error).to.not.exist done() }) }) }) describe('with a cookie signed by the upcoming key and a matching session', function () { beforeEach(function () { RealTimeClient.cookie = RealTimeClient.cookieSignedWith.sessionSecretUpcoming }) it('should not return an error', function (done) { this.checkSocket(error => { expect(error).to.not.exist done() }) }) }) describe('with a cookie signed with an unrecognized secret and a matching session', function () { beforeEach(function () { const [sessionKey] = RealTimeClient.cookie.split('.') // sign the session key with a unrecognized secret RealTimeClient.cookie = signature.sign( sessionKey, 'unrecognised-session-secret' ) }) it('should return a lookup error', function (done) { this.checkSocket(error => { expect(error).to.exist expect(error.message).to.equal('invalid session') done() }) }) }) })