SessionTests.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. const { expect } = require('chai')
  2. const async = require('async')
  3. const User = require('./helpers/User')
  4. const redis = require('./helpers/redis')
  5. describe('Sessions', function () {
  6. beforeEach(function (done) {
  7. this.timeout(20000)
  8. this.user1 = new User()
  9. this.site_admin = new User({ email: 'admin@example.com' })
  10. async.series(
  11. [cb => this.user1.login(cb), cb => this.user1.logout(cb)],
  12. done
  13. )
  14. })
  15. describe('one session', function () {
  16. it('should have one session in UserSessions set', function (done) {
  17. async.series(
  18. [
  19. next => {
  20. redis.clearUserSessions(this.user1, next)
  21. },
  22. // login, should add session to set
  23. next => {
  24. this.user1.login(err => next(err))
  25. },
  26. next => {
  27. redis.getUserSessions(this.user1, (err, sessions) => {
  28. expect(err).to.not.exist
  29. expect(sessions.length).to.equal(1)
  30. expect(sessions[0].slice(0, 5)).to.equal('sess:')
  31. next()
  32. })
  33. },
  34. // should be able to access project list page
  35. next => {
  36. this.user1.getProjectListPage((err, statusCode) => {
  37. expect(err).to.equal(null)
  38. expect(statusCode).to.equal(200)
  39. next()
  40. })
  41. },
  42. // logout, should remove session from set
  43. next => {
  44. this.user1.logout(err => next(err))
  45. },
  46. next => {
  47. redis.getUserSessions(this.user1, (err, sessions) => {
  48. expect(err).to.not.exist
  49. expect(sessions.length).to.equal(0)
  50. next()
  51. })
  52. },
  53. ],
  54. (err, result) => {
  55. if (err) {
  56. throw err
  57. }
  58. done()
  59. }
  60. )
  61. })
  62. })
  63. describe('two sessions', function () {
  64. beforeEach(function () {
  65. // set up second session for this user
  66. this.user2 = new User()
  67. this.user2.email = this.user1.email
  68. this.user2.password = this.user1.password
  69. })
  70. it('should have two sessions in UserSessions set', function (done) {
  71. async.series(
  72. [
  73. next => {
  74. redis.clearUserSessions(this.user1, next)
  75. },
  76. // login, should add session to set
  77. next => {
  78. this.user1.login(err => next(err))
  79. },
  80. next => {
  81. redis.getUserSessions(this.user1, (err, sessions) => {
  82. expect(err).to.not.exist
  83. expect(sessions.length).to.equal(1)
  84. expect(sessions[0].slice(0, 5)).to.equal('sess:')
  85. next()
  86. })
  87. },
  88. // login again, should add the second session to set
  89. next => {
  90. this.user2.login(err => next(err))
  91. },
  92. next => {
  93. redis.getUserSessions(this.user1, (err, sessions) => {
  94. expect(err).to.not.exist
  95. expect(sessions.length).to.equal(2)
  96. expect(sessions[0].slice(0, 5)).to.equal('sess:')
  97. expect(sessions[1].slice(0, 5)).to.equal('sess:')
  98. next()
  99. })
  100. },
  101. // both should be able to access project list page
  102. next => {
  103. this.user1.getProjectListPage((err, statusCode) => {
  104. expect(err).to.equal(null)
  105. expect(statusCode).to.equal(200)
  106. next()
  107. })
  108. },
  109. next => {
  110. this.user2.getProjectListPage((err, statusCode) => {
  111. expect(err).to.equal(null)
  112. expect(statusCode).to.equal(200)
  113. next()
  114. })
  115. },
  116. // logout first session, should remove session from set
  117. next => {
  118. this.user1.logout(err => next(err))
  119. },
  120. next => {
  121. redis.getUserSessions(this.user1, (err, sessions) => {
  122. expect(err).to.not.exist
  123. expect(sessions.length).to.equal(1)
  124. next()
  125. })
  126. },
  127. // first session should not have access to project list page
  128. next => {
  129. this.user1.getProjectListPage((err, statusCode) => {
  130. expect(err).to.equal(null)
  131. expect(statusCode).to.equal(302)
  132. next()
  133. })
  134. },
  135. // second session should still have access to settings
  136. next => {
  137. this.user2.getProjectListPage((err, statusCode) => {
  138. expect(err).to.equal(null)
  139. expect(statusCode).to.equal(200)
  140. next()
  141. })
  142. },
  143. // logout second session, should remove last session from set
  144. next => {
  145. this.user2.logout(err => next(err))
  146. },
  147. next => {
  148. redis.getUserSessions(this.user1, (err, sessions) => {
  149. expect(err).to.not.exist
  150. expect(sessions.length).to.equal(0)
  151. next()
  152. })
  153. },
  154. // second session should not have access to project list page
  155. next => {
  156. this.user2.getProjectListPage((err, statusCode) => {
  157. expect(err).to.equal(null)
  158. expect(statusCode).to.equal(302)
  159. next()
  160. })
  161. },
  162. ],
  163. (err, result) => {
  164. if (err) {
  165. throw err
  166. }
  167. done()
  168. }
  169. )
  170. })
  171. })
  172. describe('three sessions, password reset', function () {
  173. beforeEach(function () {
  174. // set up second session for this user
  175. this.user2 = new User()
  176. this.user2.email = this.user1.email
  177. this.user2.password = this.user1.password
  178. this.user3 = new User()
  179. this.user3.email = this.user1.email
  180. this.user3.password = this.user1.password
  181. })
  182. it('should erase both sessions when password is reset', function (done) {
  183. async.series(
  184. [
  185. next => {
  186. redis.clearUserSessions(this.user1, next)
  187. },
  188. // login, should add session to set
  189. next => {
  190. this.user1.login(err => next(err))
  191. },
  192. next => {
  193. redis.getUserSessions(this.user1, (err, sessions) => {
  194. expect(err).to.not.exist
  195. expect(sessions.length).to.equal(1)
  196. expect(sessions[0].slice(0, 5)).to.equal('sess:')
  197. next()
  198. })
  199. },
  200. // login again, should add the second session to set
  201. next => {
  202. this.user2.login(err => next(err))
  203. },
  204. next => {
  205. redis.getUserSessions(this.user1, (err, sessions) => {
  206. expect(err).to.not.exist
  207. expect(sessions.length).to.equal(2)
  208. expect(sessions[0].slice(0, 5)).to.equal('sess:')
  209. expect(sessions[1].slice(0, 5)).to.equal('sess:')
  210. next()
  211. })
  212. },
  213. // login third session, should add the second session to set
  214. next => {
  215. this.user3.login(err => next(err))
  216. },
  217. next => {
  218. redis.getUserSessions(this.user1, (err, sessions) => {
  219. expect(err).to.not.exist
  220. expect(sessions.length).to.equal(3)
  221. expect(sessions[0].slice(0, 5)).to.equal('sess:')
  222. expect(sessions[1].slice(0, 5)).to.equal('sess:')
  223. next()
  224. })
  225. },
  226. // password reset from second session, should erase two of the three sessions
  227. next => {
  228. this.user2.changePassword(err => next(err))
  229. },
  230. next => {
  231. redis.getUserSessions(this.user2, (err, sessions) => {
  232. expect(err).to.not.exist
  233. expect(sessions.length).to.equal(1)
  234. next()
  235. })
  236. },
  237. // users one and three should not be able to access project list page
  238. next => {
  239. this.user1.getProjectListPage((err, statusCode) => {
  240. expect(err).to.equal(null)
  241. expect(statusCode).to.equal(302)
  242. next()
  243. })
  244. },
  245. next => {
  246. this.user3.getProjectListPage((err, statusCode) => {
  247. expect(err).to.equal(null)
  248. expect(statusCode).to.equal(302)
  249. next()
  250. })
  251. },
  252. // user two should still be logged in, and able to access project list page
  253. next => {
  254. this.user2.getProjectListPage((err, statusCode) => {
  255. expect(err).to.equal(null)
  256. expect(statusCode).to.equal(200)
  257. next()
  258. })
  259. },
  260. // logout second session, should remove last session from set
  261. next => {
  262. this.user2.logout(err => next(err))
  263. },
  264. next => {
  265. redis.getUserSessions(this.user1, (err, sessions) => {
  266. expect(err).to.not.exist
  267. expect(sessions.length).to.equal(0)
  268. next()
  269. })
  270. },
  271. ],
  272. (err, result) => {
  273. if (err) {
  274. throw err
  275. }
  276. done()
  277. }
  278. )
  279. })
  280. })
  281. describe('three sessions, sessions page', function () {
  282. beforeEach(function (done) {
  283. // set up second session for this user
  284. this.user2 = new User()
  285. this.user2.email = this.user1.email
  286. this.user2.password = this.user1.password
  287. this.user3 = new User()
  288. this.user3.email = this.user1.email
  289. this.user3.password = this.user1.password
  290. async.series([this.user2.login.bind(this.user2)], done)
  291. })
  292. it('should allow the user to erase the other two sessions', function (done) {
  293. async.series(
  294. [
  295. next => {
  296. redis.clearUserSessions(this.user1, next)
  297. },
  298. // login, should add session to set
  299. next => {
  300. this.user1.login(err => next(err))
  301. },
  302. next => {
  303. redis.getUserSessions(this.user1, (err, sessions) => {
  304. expect(err).to.not.exist
  305. expect(sessions.length).to.equal(1)
  306. expect(sessions[0].slice(0, 5)).to.equal('sess:')
  307. next()
  308. })
  309. },
  310. // login again, should add the second session to set
  311. next => {
  312. this.user2.login(err => next(err))
  313. },
  314. next => {
  315. redis.getUserSessions(this.user1, (err, sessions) => {
  316. expect(err).to.not.exist
  317. expect(sessions.length).to.equal(2)
  318. expect(sessions[0].slice(0, 5)).to.equal('sess:')
  319. expect(sessions[1].slice(0, 5)).to.equal('sess:')
  320. next()
  321. })
  322. },
  323. // login third session, should add the second session to set
  324. next => {
  325. this.user3.login(err => next(err))
  326. },
  327. next => {
  328. redis.getUserSessions(this.user1, (err, sessions) => {
  329. expect(err).to.not.exist
  330. expect(sessions.length).to.equal(3)
  331. expect(sessions[0].slice(0, 5)).to.equal('sess:')
  332. expect(sessions[1].slice(0, 5)).to.equal('sess:')
  333. next()
  334. })
  335. },
  336. // check the sessions page
  337. next => {
  338. this.user2.request.get(
  339. {
  340. uri: '/user/sessions',
  341. },
  342. (err, response, body) => {
  343. expect(err).to.be.oneOf([null, undefined])
  344. expect(response.statusCode).to.equal(200)
  345. next()
  346. }
  347. )
  348. },
  349. // clear sessions from second session, should erase two of the three sessions
  350. next => {
  351. this.user2.getCsrfToken(err => {
  352. expect(err).to.be.oneOf([null, undefined])
  353. this.user2.request.post(
  354. {
  355. uri: '/user/sessions/clear',
  356. },
  357. err => next(err)
  358. )
  359. })
  360. },
  361. next => {
  362. redis.getUserSessions(this.user2, (err, sessions) => {
  363. expect(err).to.not.exist
  364. expect(sessions.length).to.equal(1)
  365. next()
  366. })
  367. },
  368. // users one and three should not be able to access project list page
  369. next => {
  370. this.user1.getProjectListPage((err, statusCode) => {
  371. expect(err).to.equal(null)
  372. expect(statusCode).to.equal(302)
  373. next()
  374. })
  375. },
  376. next => {
  377. this.user3.getProjectListPage((err, statusCode) => {
  378. expect(err).to.equal(null)
  379. expect(statusCode).to.equal(302)
  380. next()
  381. })
  382. },
  383. // user two should still be logged in, and able to access project list page
  384. next => {
  385. this.user2.getProjectListPage((err, statusCode) => {
  386. expect(err).to.equal(null)
  387. expect(statusCode).to.equal(200)
  388. next()
  389. })
  390. },
  391. // logout second session, should remove last session from set
  392. next => {
  393. this.user2.logout(err => next(err))
  394. },
  395. next => {
  396. redis.getUserSessions(this.user1, (err, sessions) => {
  397. expect(err).to.not.exist
  398. expect(sessions.length).to.equal(0)
  399. next()
  400. })
  401. },
  402. // the user audit log should have been updated
  403. next => {
  404. this.user1.getAuditLogWithoutNoise((error, auditLog) => {
  405. expect(error).not.to.exist
  406. expect(auditLog).to.exist
  407. expect(auditLog[0].operation).to.equal('clear-sessions')
  408. expect(auditLog[0].ipAddress).to.exist
  409. expect(auditLog[0].initiatorId).to.exist
  410. expect(auditLog[0].timestamp).to.exist
  411. expect(auditLog[0].info.sessions.length).to.equal(2)
  412. next()
  413. })
  414. },
  415. ],
  416. (err, result) => {
  417. if (err) {
  418. throw err
  419. }
  420. done()
  421. }
  422. )
  423. })
  424. })
  425. })