login.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import { runScript } from './hostAdminClient'
  2. const DEFAULT_PASSWORD = 'Passw0rd!'
  3. const createdUsers = new Set<string>()
  4. export function resetCreatedUsersCache() {
  5. createdUsers.clear()
  6. }
  7. export async function createMongoUser({
  8. email,
  9. isAdmin = false,
  10. }: {
  11. email: string
  12. isAdmin?: boolean
  13. }) {
  14. const t0 = Math.floor(Date.now() / 1000)
  15. const { stdout } = await runScript({
  16. cwd: 'services/web',
  17. script: 'modules/server-ce-scripts/scripts/create-user.js',
  18. args: [`--email=${email}`, `--admin=${isAdmin}`],
  19. })
  20. const [url] = stdout.match(/http:\/\/.+\/user\/activate\?token=\S+/)!
  21. const userId = new URL(url, location.origin).searchParams.get('user_id')!
  22. const signupDate = parseInt(userId.slice(0, 8), 16)
  23. if (signupDate < t0) {
  24. return { url, exists: true }
  25. }
  26. return { url, exists: false }
  27. }
  28. export function ensureUserExists({
  29. email,
  30. password = DEFAULT_PASSWORD,
  31. isAdmin = false,
  32. }: {
  33. email: string
  34. password?: string
  35. isAdmin?: boolean
  36. }) {
  37. let url: string
  38. let exists: boolean
  39. before(async function () {
  40. exists = createdUsers.has(email)
  41. if (exists) return
  42. ;({ url, exists } = await createMongoUser({ email, isAdmin }))
  43. })
  44. before(function () {
  45. if (exists) return
  46. activateUser(url, password)
  47. cy.then(() => {
  48. createdUsers.add(email)
  49. })
  50. })
  51. }
  52. export function login(username: string, password = DEFAULT_PASSWORD) {
  53. cy.session(
  54. [username, password],
  55. () => {
  56. cy.visit('/login')
  57. cy.get('input[name="email"]').type(username)
  58. cy.get('input[name="password"]').type(password)
  59. cy.findByRole('button', { name: 'Login' }).click()
  60. cy.url().should('contain', '/project')
  61. },
  62. {
  63. cacheAcrossSpecs: true,
  64. async validate() {
  65. cy.request({ url: '/project', followRedirect: false }).then(
  66. response => {
  67. expect(response.status).to.equal(200)
  68. }
  69. )
  70. },
  71. }
  72. )
  73. }
  74. let activateRateLimitState = { count: 0, reset: 0 }
  75. export function resetActivateUserRateLimit() {
  76. activateRateLimitState = { count: 0, reset: 0 }
  77. }
  78. function handleActivateUserRateLimit() {
  79. cy.then(() => {
  80. activateRateLimitState.count++
  81. if (activateRateLimitState.reset < Date.now()) {
  82. activateRateLimitState.reset = Date.now() + 65_000
  83. activateRateLimitState.count = 1
  84. } else if (activateRateLimitState.count >= 6) {
  85. cy.wait(activateRateLimitState.reset - Date.now())
  86. activateRateLimitState.count = 1
  87. }
  88. })
  89. }
  90. export function activateUser(url: string, password = DEFAULT_PASSWORD) {
  91. handleActivateUserRateLimit()
  92. cy.session(url, () => {
  93. cy.visit(url)
  94. cy.url().then(url => {
  95. if (url.includes('/login')) return
  96. cy.url().should('contain', '/user/activate')
  97. cy.get('input[name="password"]').type(password)
  98. cy.findByRole('button', { name: 'Activate' }).click()
  99. cy.url().should('contain', '/project')
  100. })
  101. })
  102. }