2025-08-05 00:31:43 +03:00
|
|
|
import { ReactiveCache } from '/imports/reactiveCache';
|
|
|
|
|
|
|
|
|
|
// Method to find locked users and release them if needed
|
|
|
|
|
Meteor.methods({
|
2026-01-29 21:29:56 +02:00
|
|
|
async getLockedUsers() {
|
2025-08-05 00:31:43 +03:00
|
|
|
// Check if user has admin rights
|
|
|
|
|
const userId = Meteor.userId();
|
|
|
|
|
if (!userId) {
|
|
|
|
|
throw new Meteor.Error('error-invalid-user', 'Invalid user');
|
|
|
|
|
}
|
Update ReactiveCache call sites to use async/await for Meteor 3.0
Part 3 of ReactiveCache async migration:
- Add await before all ReactiveCache.getX() calls
- Make functions containing ReactiveCache calls async
- Convert forEach/map/filter loops with async callbacks to for...of
- Update model helpers, Meteor methods, JsonRoutes handlers
- Update collection hooks (.before/.after insert/update/remove)
- Update .allow() callbacks to async
Files updated across models/ and server/ directories:
- Model files: cards, boards, lists, swimlanes, activities, users,
checklists, checklistItems, customFields, attachments, integrations,
cardComments, settings files, creators, exporters, and more
- Server files: publications, methods, notifications, routes, migrations
2026-02-01 00:54:38 +02:00
|
|
|
const user = await ReactiveCache.getUser(userId);
|
2025-08-05 00:31:43 +03:00
|
|
|
if (!user || !user.isAdmin) {
|
|
|
|
|
throw new Meteor.Error('error-not-allowed', 'Not allowed');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Current time to check against unlockTime
|
|
|
|
|
const currentTime = Number(new Date());
|
|
|
|
|
|
|
|
|
|
// Find users that are locked (known users)
|
2026-01-29 21:29:56 +02:00
|
|
|
const lockedUsers = await Meteor.users.find(
|
2025-08-05 00:31:43 +03:00
|
|
|
{
|
|
|
|
|
'services.accounts-lockout.unlockTime': {
|
|
|
|
|
$gt: currentTime,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
fields: {
|
|
|
|
|
_id: 1,
|
|
|
|
|
username: 1,
|
|
|
|
|
emails: 1,
|
|
|
|
|
'services.accounts-lockout.unlockTime': 1,
|
|
|
|
|
'services.accounts-lockout.failedAttempts': 1
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-29 21:29:56 +02:00
|
|
|
).fetchAsync();
|
2025-08-05 00:31:43 +03:00
|
|
|
|
|
|
|
|
// Format the results for the UI
|
|
|
|
|
return lockedUsers.map(user => {
|
|
|
|
|
const email = user.emails && user.emails.length > 0 ? user.emails[0].address : 'No email';
|
|
|
|
|
const remainingLockTime = Math.round((user.services['accounts-lockout'].unlockTime - currentTime) / 1000);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
_id: user._id,
|
|
|
|
|
username: user.username || 'No username',
|
|
|
|
|
email,
|
|
|
|
|
failedAttempts: user.services['accounts-lockout'].failedAttempts || 0,
|
|
|
|
|
unlockTime: user.services['accounts-lockout'].unlockTime,
|
|
|
|
|
remainingLockTime // in seconds
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2026-01-29 21:29:56 +02:00
|
|
|
async unlockUser(userId) {
|
2025-08-05 00:31:43 +03:00
|
|
|
// Check if user has admin rights
|
|
|
|
|
const adminId = Meteor.userId();
|
|
|
|
|
if (!adminId) {
|
|
|
|
|
throw new Meteor.Error('error-invalid-user', 'Invalid user');
|
|
|
|
|
}
|
Update ReactiveCache call sites to use async/await for Meteor 3.0
Part 3 of ReactiveCache async migration:
- Add await before all ReactiveCache.getX() calls
- Make functions containing ReactiveCache calls async
- Convert forEach/map/filter loops with async callbacks to for...of
- Update model helpers, Meteor methods, JsonRoutes handlers
- Update collection hooks (.before/.after insert/update/remove)
- Update .allow() callbacks to async
Files updated across models/ and server/ directories:
- Model files: cards, boards, lists, swimlanes, activities, users,
checklists, checklistItems, customFields, attachments, integrations,
cardComments, settings files, creators, exporters, and more
- Server files: publications, methods, notifications, routes, migrations
2026-02-01 00:54:38 +02:00
|
|
|
const admin = await ReactiveCache.getUser(adminId);
|
2025-08-05 00:31:43 +03:00
|
|
|
if (!admin || !admin.isAdmin) {
|
|
|
|
|
throw new Meteor.Error('error-not-allowed', 'Not allowed');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make sure the user to unlock exists
|
2026-01-29 21:29:56 +02:00
|
|
|
const userToUnlock = await Meteor.users.findOneAsync(userId);
|
2025-08-05 00:31:43 +03:00
|
|
|
if (!userToUnlock) {
|
|
|
|
|
throw new Meteor.Error('error-user-not-found', 'User not found');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Unlock the user
|
2026-01-29 21:29:56 +02:00
|
|
|
await Meteor.users.updateAsync(
|
2025-08-05 00:31:43 +03:00
|
|
|
{ _id: userId },
|
|
|
|
|
{
|
|
|
|
|
$unset: {
|
|
|
|
|
'services.accounts-lockout': 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
},
|
|
|
|
|
|
2026-01-29 21:29:56 +02:00
|
|
|
async unlockAllUsers() {
|
2025-08-05 00:31:43 +03:00
|
|
|
// Check if user has admin rights
|
|
|
|
|
const adminId = Meteor.userId();
|
|
|
|
|
if (!adminId) {
|
|
|
|
|
throw new Meteor.Error('error-invalid-user', 'Invalid user');
|
|
|
|
|
}
|
Update ReactiveCache call sites to use async/await for Meteor 3.0
Part 3 of ReactiveCache async migration:
- Add await before all ReactiveCache.getX() calls
- Make functions containing ReactiveCache calls async
- Convert forEach/map/filter loops with async callbacks to for...of
- Update model helpers, Meteor methods, JsonRoutes handlers
- Update collection hooks (.before/.after insert/update/remove)
- Update .allow() callbacks to async
Files updated across models/ and server/ directories:
- Model files: cards, boards, lists, swimlanes, activities, users,
checklists, checklistItems, customFields, attachments, integrations,
cardComments, settings files, creators, exporters, and more
- Server files: publications, methods, notifications, routes, migrations
2026-02-01 00:54:38 +02:00
|
|
|
const admin = await ReactiveCache.getUser(adminId);
|
2025-08-05 00:31:43 +03:00
|
|
|
if (!admin || !admin.isAdmin) {
|
|
|
|
|
throw new Meteor.Error('error-not-allowed', 'Not allowed');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Unlock all users
|
2026-01-29 21:29:56 +02:00
|
|
|
await Meteor.users.updateAsync(
|
2025-08-05 00:31:43 +03:00
|
|
|
{ 'services.accounts-lockout.unlockTime': { $exists: true } },
|
|
|
|
|
{
|
|
|
|
|
$unset: {
|
|
|
|
|
'services.accounts-lockout': 1
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ multi: true }
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
});
|