expect = require("chai").expect async = require("async") User = require "./helpers/User" request = require "./helpers/request" settings = require "settings-sharelatex" redis = require "./helpers/redis" describe "Sessions", -> before (done) -> @timeout(20000) @user1 = new User() @site_admin = new User({email: "admin@example.com"}) async.series [ (cb) => @user1.login cb (cb) => @user1.logout cb ], done describe "one session", -> it "should have one session in UserSessions set", (done) -> async.series( [ (next) => redis.clearUserSessions @user1, next # login, should add session to set , (next) => @user1.login (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 1 expect(sessions[0].slice(0, 5)).to.equal 'sess:' next() # should be able to access project list page , (next) => @user1.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 200 next() # logout, should remove session from set , (next) => @user1.logout (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 0 next() ], (err, result) => if err throw err done() ) describe "two sessions", -> before -> # set up second session for this user @user2 = new User() @user2.email = @user1.email @user2.password = @user1.password it "should have two sessions in UserSessions set", (done) -> async.series( [ (next) => redis.clearUserSessions @user1, next # login, should add session to set , (next) => @user1.login (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 1 expect(sessions[0].slice(0, 5)).to.equal 'sess:' next() # login again, should add the second session to set , (next) => @user2.login (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 2 expect(sessions[0].slice(0, 5)).to.equal 'sess:' expect(sessions[1].slice(0, 5)).to.equal 'sess:' next() # both should be able to access project list page , (next) => @user1.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 200 next() , (next) => @user2.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 200 next() # logout first session, should remove session from set , (next) => @user1.logout (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 1 next() # first session should not have access to project list page , (next) => @user1.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 302 next() # second session should still have access to settings , (next) => @user2.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 200 next() # logout second session, should remove last session from set , (next) => @user2.logout (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 0 next() # second session should not have access to project list page , (next) => @user2.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 302 next() ], (err, result) => if err throw err done() ) describe 'three sessions, password reset', -> before -> # set up second session for this user @user2 = new User() @user2.email = @user1.email @user2.password = @user1.password @user3 = new User() @user3.email = @user1.email @user3.password = @user1.password it "should erase both sessions when password is reset", (done) -> async.series( [ (next) => redis.clearUserSessions @user1, next # login, should add session to set , (next) => @user1.login (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 1 expect(sessions[0].slice(0, 5)).to.equal 'sess:' next() # login again, should add the second session to set , (next) => @user2.login (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 2 expect(sessions[0].slice(0, 5)).to.equal 'sess:' expect(sessions[1].slice(0, 5)).to.equal 'sess:' next() # login third session, should add the second session to set , (next) => @user3.login (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 3 expect(sessions[0].slice(0, 5)).to.equal 'sess:' expect(sessions[1].slice(0, 5)).to.equal 'sess:' next() # password reset from second session, should erase two of the three sessions , (next) => @user2.changePassword (err) -> next(err) , (next) => redis.getUserSessions @user2, (err, sessions) => expect(sessions.length).to.equal 1 next() # users one and three should not be able to access project list page , (next) => @user1.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 302 next() , (next) => @user3.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 302 next() # user two should still be logged in, and able to access project list page , (next) => @user2.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 200 next() # logout second session, should remove last session from set , (next) => @user2.logout (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 0 next() ], (err, result) => if err throw err done() ) describe 'three sessions, sessions page', -> before -> # set up second session for this user @user2 = new User() @user2.email = @user1.email @user2.password = @user1.password @user3 = new User() @user3.email = @user1.email @user3.password = @user1.password it "should allow the user to erase the other two sessions", (done) -> async.series( [ (next) => redis.clearUserSessions @user1, next # login, should add session to set , (next) => @user1.login (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 1 expect(sessions[0].slice(0, 5)).to.equal 'sess:' next() # login again, should add the second session to set , (next) => @user2.login (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 2 expect(sessions[0].slice(0, 5)).to.equal 'sess:' expect(sessions[1].slice(0, 5)).to.equal 'sess:' next() # login third session, should add the second session to set , (next) => @user3.login (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 3 expect(sessions[0].slice(0, 5)).to.equal 'sess:' expect(sessions[1].slice(0, 5)).to.equal 'sess:' next() # enter sudo-mode , (next) => @user2.getCsrfToken (err) => expect(err).to.be.oneOf [null, undefined] @user2.request.post { uri: '/confirm-password', json: password: @user2.password }, (err, response, body) => expect(err).to.be.oneOf [null, undefined] expect(response.statusCode).to.equal 200 next() # check the sessions page , (next) => @user2.request.get { uri: '/user/sessions' }, (err, response, body) => expect(err).to.be.oneOf [null, undefined] expect(response.statusCode).to.equal 200 next() # clear sessions from second session, should erase two of the three sessions , (next) => @user2.getCsrfToken (err) => expect(err).to.be.oneOf [null, undefined] @user2.request.post { uri: '/user/sessions/clear' }, (err) -> next(err) , (next) => redis.getUserSessions @user2, (err, sessions) => expect(sessions.length).to.equal 1 next() # users one and three should not be able to access project list page , (next) => @user1.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 302 next() , (next) => @user3.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 302 next() # user two should still be logged in, and able to access project list page , (next) => @user2.getProjectListPage (err, statusCode) => expect(err).to.equal null expect(statusCode).to.equal 200 next() # logout second session, should remove last session from set , (next) => @user2.logout (err) -> next(err) , (next) => redis.getUserSessions @user1, (err, sessions) => expect(sessions.length).to.equal 0 next() ], (err, result) => if err throw err done() )