lockedUsersBody.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import { ReactiveCache } from '/imports/reactiveCache';
  2. import LockoutSettings from '/models/lockoutSettings';
  3. BlazeComponent.extendComponent({
  4. onCreated() {
  5. this.lockedUsers = new ReactiveVar([]);
  6. this.isLoadingLockedUsers = new ReactiveVar(false);
  7. // Don't load immediately to prevent unnecessary spinner
  8. // The data will be loaded when the tab is selected in peopleBody.js switchMenu
  9. },
  10. refreshLockedUsers() {
  11. // Set loading state initially, but we'll hide it if no users are found
  12. this.isLoadingLockedUsers.set(true);
  13. Meteor.call('getLockedUsers', (err, users) => {
  14. if (err) {
  15. this.isLoadingLockedUsers.set(false);
  16. const reason = err.reason || '';
  17. const message = `${TAPi18n.__(err.error)}\n${reason}`;
  18. alert(message);
  19. return;
  20. }
  21. // If no users are locked, don't show loading spinner and set empty array
  22. if (!users || users.length === 0) {
  23. this.isLoadingLockedUsers.set(false);
  24. this.lockedUsers.set([]);
  25. return;
  26. }
  27. // Format the remaining time to be more human-readable
  28. users.forEach(user => {
  29. if (user.remainingLockTime > 60) {
  30. const minutes = Math.floor(user.remainingLockTime / 60);
  31. const seconds = user.remainingLockTime % 60;
  32. user.remainingTimeFormatted = `${minutes}m ${seconds}s`;
  33. } else {
  34. user.remainingTimeFormatted = `${user.remainingLockTime}s`;
  35. }
  36. });
  37. this.lockedUsers.set(users);
  38. this.isLoadingLockedUsers.set(false);
  39. });
  40. },
  41. unlockUser(event) {
  42. const userId = $(event.currentTarget).data('user-id');
  43. if (!userId) return;
  44. if (confirm(TAPi18n.__('accounts-lockout-confirm-unlock'))) {
  45. Meteor.call('unlockUser', userId, (err, result) => {
  46. if (err) {
  47. const reason = err.reason || '';
  48. const message = `${TAPi18n.__(err.error)}\n${reason}`;
  49. alert(message);
  50. return;
  51. }
  52. if (result) {
  53. alert(TAPi18n.__('accounts-lockout-user-unlocked'));
  54. this.refreshLockedUsers();
  55. }
  56. });
  57. }
  58. },
  59. unlockAllUsers() {
  60. if (confirm(TAPi18n.__('accounts-lockout-confirm-unlock-all'))) {
  61. Meteor.call('unlockAllUsers', (err, result) => {
  62. if (err) {
  63. const reason = err.reason || '';
  64. const message = `${TAPi18n.__(err.error)}\n${reason}`;
  65. alert(message);
  66. return;
  67. }
  68. if (result) {
  69. alert(TAPi18n.__('accounts-lockout-user-unlocked'));
  70. this.refreshLockedUsers();
  71. }
  72. });
  73. }
  74. },
  75. saveLockoutSettings() {
  76. // Get values from form
  77. const knownFailuresBeforeLockout = parseInt($('#known-failures-before-lockout').val(), 10) || 3;
  78. const knownLockoutPeriod = parseInt($('#known-lockout-period').val(), 10) || 60;
  79. const knownFailureWindow = parseInt($('#known-failure-window').val(), 10) || 15;
  80. const unknownFailuresBeforeLockout = parseInt($('#unknown-failures-before-lockout').val(), 10) || 3;
  81. const unknownLockoutPeriod = parseInt($('#unknown-lockout-period').val(), 10) || 60;
  82. const unknownFailureWindow = parseInt($('#unknown-failure-window').val(), 10) || 15;
  83. // Update the database
  84. LockoutSettings.update('known-failuresBeforeLockout', {
  85. $set: { value: knownFailuresBeforeLockout },
  86. });
  87. LockoutSettings.update('known-lockoutPeriod', {
  88. $set: { value: knownLockoutPeriod },
  89. });
  90. LockoutSettings.update('known-failureWindow', {
  91. $set: { value: knownFailureWindow },
  92. });
  93. LockoutSettings.update('unknown-failuresBeforeLockout', {
  94. $set: { value: unknownFailuresBeforeLockout },
  95. });
  96. LockoutSettings.update('unknown-lockoutPeriod', {
  97. $set: { value: unknownLockoutPeriod },
  98. });
  99. LockoutSettings.update('unknown-failureWindow', {
  100. $set: { value: unknownFailureWindow },
  101. });
  102. // Reload the AccountsLockout configuration
  103. Meteor.call('reloadAccountsLockout', (err, ret) => {
  104. if (!err && ret) {
  105. const message = TAPi18n.__('accounts-lockout-settings-updated');
  106. alert(message);
  107. } else {
  108. const reason = err?.reason || '';
  109. const message = `${TAPi18n.__(err?.error || 'error-updating-settings')}\n${reason}`;
  110. alert(message);
  111. }
  112. });
  113. },
  114. knownFailuresBeforeLockout() {
  115. return LockoutSettings.findOne('known-failuresBeforeLockout')?.value || 3;
  116. },
  117. knownLockoutPeriod() {
  118. return LockoutSettings.findOne('known-lockoutPeriod')?.value || 60;
  119. },
  120. knownFailureWindow() {
  121. return LockoutSettings.findOne('known-failureWindow')?.value || 15;
  122. },
  123. unknownFailuresBeforeLockout() {
  124. return LockoutSettings.findOne('unknown-failuresBeforeLockout')?.value || 3;
  125. },
  126. unknownLockoutPeriod() {
  127. return LockoutSettings.findOne('unknown-lockoutPeriod')?.value || 60;
  128. },
  129. unknownFailureWindow() {
  130. return LockoutSettings.findOne('unknown-failureWindow')?.value || 15;
  131. },
  132. lockedUsers() {
  133. return this.lockedUsers.get();
  134. },
  135. isLoadingLockedUsers() {
  136. return this.isLoadingLockedUsers.get();
  137. },
  138. events() {
  139. return [
  140. {
  141. 'click button.js-refresh-locked-users': this.refreshLockedUsers,
  142. 'click button#refreshLockedUsers': this.refreshLockedUsers,
  143. 'click button.js-unlock-user': this.unlockUser,
  144. 'click button.js-unlock-all-users': this.unlockAllUsers,
  145. 'click button.js-lockout-save': this.saveLockoutSettings,
  146. },
  147. ];
  148. },
  149. }).register('lockedUsersGeneral');