SessionTests.js 14 KB

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