055-account.js 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. Critical path: account self-management (password change).
  3. Exercises the "My Account" flow end to end on a dedicated throwaway
  4. user (so the shared admin credentials the other specs rely on stay
  5. intact): the account settings UI renders, userinfo reports identity,
  6. a wrong old password is refused, a correct change succeeds, and
  7. afterwards only the new password can sign in.
  8. */
  9. "use strict";
  10. const h = require("../lib/system-harness");
  11. const USER = "e2eaccount";
  12. const OLD_PASS = "e2e-Old-Passw0rd";
  13. const NEW_PASS = "e2e-New-Passw0rd";
  14. function sleep(ms) { return new Promise(function (r) { setTimeout(r, ms); }); }
  15. h.run("ACCOUNT", async function (env) {
  16. const base = env.baseURL;
  17. // Admin creates the throwaway account.
  18. const adminPage = await h.newPage(env.browser);
  19. await h.loginViaAPI(adminPage, base, env.admin.username, env.admin.password);
  20. let resp = await h.postForm(adminPage, base + "/system/auth/register", {
  21. username: USER, password: OLD_PASS, group: "administrator"
  22. });
  23. if (resp.toLowerCase().indexOf("ok") === -1) h.fail("could not create test account: " + resp);
  24. h.ok("admin creates a throwaway account for the password-change test");
  25. // The user signs in and opens their account settings page.
  26. const userPage = await h.newPage(env.browser);
  27. await h.loginViaAPI(userPage, base, USER, OLD_PASS);
  28. await userPage.goto(base + "/SystemAO/users/account.html", { waitUntil: "domcontentloaded" });
  29. await userPage.waitForSelector("#heroAvatar", { state: "attached", timeout: 20000 });
  30. h.ok("account settings page renders for the signed-in user");
  31. // userinfo reports this user's identity.
  32. const info = await h.getJSON(userPage, base + "/system/users/userinfo");
  33. if (JSON.stringify(info).indexOf(USER) === -1) {
  34. h.fail("userinfo did not report the signed-in user: " + JSON.stringify(info).slice(0, 200));
  35. }
  36. h.ok("userinfo reports the signed-in user's identity");
  37. // ── Wrong old password is refused ──
  38. resp = await h.postForm(userPage, base + "/system/users/userinfo", {
  39. opr: "changepw", oldpw: "not-the-old-password", newpw: NEW_PASS
  40. });
  41. if (resp.toLowerCase().indexOf("error") === -1) {
  42. h.fail("password change with a wrong old password was not refused: " + resp);
  43. }
  44. h.ok("password change with a wrong old password is refused");
  45. // ── Correct old password changes the password ──
  46. resp = await h.postForm(userPage, base + "/system/users/userinfo", {
  47. opr: "changepw", oldpw: OLD_PASS, newpw: NEW_PASS
  48. });
  49. if (resp.toLowerCase().indexOf("ok") === -1) h.fail("valid password change failed: " + resp);
  50. h.ok("password change with the correct old password succeeds");
  51. // ── The old password no longer signs in ──
  52. const probe = await h.newPage(env.browser);
  53. const oldLogin = await probe.request.post(base + "/system/auth/login", {
  54. form: { username: USER, password: OLD_PASS, rmbme: "false" }
  55. });
  56. await oldLogin.text();
  57. if (await h.isLoggedIn(probe, base)) h.fail("the old password still signs in after the change");
  58. h.ok("the old password no longer signs in");
  59. // A failed login throttles this user/IP for ~2s; wait it out, then the
  60. // new password must work.
  61. await sleep(3000);
  62. await h.loginViaAPI(probe, base, USER, NEW_PASS);
  63. if (!(await h.isLoggedIn(probe, base))) h.fail("the new password does not sign in");
  64. h.ok("the new password signs in");
  65. await probe.close();
  66. await userPage.close();
  67. // ── Cleanup: admin removes the throwaway account ──
  68. resp = await h.postForm(adminPage, base + "/system/users/removeUser", { username: USER });
  69. if (resp.toLowerCase().indexOf("ok") === -1) h.fail("could not remove test account: " + resp);
  70. h.ok("admin removes the throwaway account");
  71. await adminPage.close();
  72. });