mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-20 10:20:15 +01:00
✨ feat: Implement Group Management with Create and Assign Functionality
This commit is contained in:
parent
06282b584f
commit
39649ce523
7 changed files with 167 additions and 0 deletions
6
api/models/Group.js
Normal file
6
api/models/Group.js
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const groupSchema = require('~/models/schema/groupSchema');
|
||||||
|
|
||||||
|
const Group = mongoose.model('Group', groupSchema);
|
||||||
|
|
||||||
|
module.exports = Group;
|
||||||
|
|
@ -40,6 +40,7 @@ const { getPreset, getPresets, savePreset, deletePresets } = require('./Preset')
|
||||||
const { createToken, findToken, updateToken, deleteTokens } = require('./Token');
|
const { createToken, findToken, updateToken, deleteTokens } = require('./Token');
|
||||||
const Balance = require('./Balance');
|
const Balance = require('./Balance');
|
||||||
const User = require('./User');
|
const User = require('./User');
|
||||||
|
const Group = require('./Group');
|
||||||
const Key = require('./Key');
|
const Key = require('./Key');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
@ -92,6 +93,7 @@ module.exports = {
|
||||||
countActiveSessions,
|
countActiveSessions,
|
||||||
|
|
||||||
User,
|
User,
|
||||||
|
Group,
|
||||||
Key,
|
Key,
|
||||||
Balance,
|
Balance,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
29
api/models/schema/groupSchema.js
Normal file
29
api/models/schema/groupSchema.js
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const groupSchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
allowedEndpoints: [
|
||||||
|
{
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
|
||||||
|
},
|
||||||
|
],
|
||||||
|
allowedModels: [
|
||||||
|
{
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ timestamps: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = groupSchema;
|
||||||
|
|
@ -143,6 +143,12 @@ const userSchema = mongoose.Schema(
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: 'Group',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{ timestamps: true },
|
{ timestamps: true },
|
||||||
|
|
|
||||||
62
config/assign-group.js
Normal file
62
config/assign-group.js
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
const path = require('path');
|
||||||
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
|
const { askQuestion, silentExit } = require('./helpers');
|
||||||
|
const User = require('~/models/User');
|
||||||
|
const Group = require('~/models/Group');
|
||||||
|
const connect = require('./connect');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
await connect();
|
||||||
|
|
||||||
|
console.purple('---------------------------------------');
|
||||||
|
console.purple('Assign a Group to a User');
|
||||||
|
console.purple('---------------------------------------');
|
||||||
|
|
||||||
|
// Read arguments from CLI or prompt the user
|
||||||
|
let userEmail = process.argv[2] || (await askQuestion('User email: '));
|
||||||
|
let groupName = process.argv[3] || (await askQuestion('Group name to assign: '));
|
||||||
|
|
||||||
|
// Validate email format
|
||||||
|
if (!userEmail.includes('@')) {
|
||||||
|
console.red('Error: Invalid email address!');
|
||||||
|
silentExit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the group by name
|
||||||
|
const group = await Group.findOne({ name: groupName });
|
||||||
|
if (!group) {
|
||||||
|
console.red('Error: No group with that name was found!');
|
||||||
|
silentExit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the user by email
|
||||||
|
const user = await User.findOne({ email: userEmail });
|
||||||
|
if (!user) {
|
||||||
|
console.red('Error: No user with that email was found!');
|
||||||
|
silentExit(1);
|
||||||
|
}
|
||||||
|
console.purple(`Found user: ${user.email}`);
|
||||||
|
|
||||||
|
// Assign the group to the user if not already assigned
|
||||||
|
try {
|
||||||
|
if (!user.groups) {
|
||||||
|
user.groups = [];
|
||||||
|
}
|
||||||
|
if (!user.groups.includes(group._id)) {
|
||||||
|
user.groups.push(group._id);
|
||||||
|
await user.save();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.red('Error assigning group to user: ' + error.message);
|
||||||
|
silentExit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.green(`User ${user.email} successfully assigned to group ${group.name}!`);
|
||||||
|
silentExit(0);
|
||||||
|
})();
|
||||||
|
|
||||||
|
process.on('uncaughtException', (err) => {
|
||||||
|
console.error('There was an uncaught error:');
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
60
config/create-group.js
Normal file
60
config/create-group.js
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
const path = require('path');
|
||||||
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
|
const { askQuestion, silentExit } = require('./helpers');
|
||||||
|
const Group = require('~/models/Group');
|
||||||
|
const connect = require('./connect');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
await connect();
|
||||||
|
|
||||||
|
console.purple('---------------------------------------');
|
||||||
|
console.purple('Create a New Group');
|
||||||
|
console.purple('---------------------------------------');
|
||||||
|
|
||||||
|
// Read arguments from CLI or prompt the user
|
||||||
|
let groupName = process.argv[2] || (await askQuestion('Group name: '));
|
||||||
|
let groupDescription =
|
||||||
|
process.argv[3] || (await askQuestion('Group description (optional): '));
|
||||||
|
let allowedEndpointsInput =
|
||||||
|
process.argv[4] ||
|
||||||
|
(await askQuestion(
|
||||||
|
'Allowed endpoints (comma separated, e.g., "assistants,agents", or enter "*" for all): ',
|
||||||
|
));
|
||||||
|
let allowedModelsInput =
|
||||||
|
process.argv[5] ||
|
||||||
|
(await askQuestion(
|
||||||
|
'Allowed models (comma separated, e.g., "gpt-4,chatgpt-4o-latest", or enter "*" for all): ',
|
||||||
|
));
|
||||||
|
|
||||||
|
// Process the comma-separated inputs into arrays
|
||||||
|
const allowedEndpoints = allowedEndpointsInput
|
||||||
|
.split(',')
|
||||||
|
.map((s) => s.trim())
|
||||||
|
.filter((s) => s);
|
||||||
|
const allowedModels = allowedModelsInput
|
||||||
|
.split(',')
|
||||||
|
.map((s) => s.trim())
|
||||||
|
.filter((s) => s);
|
||||||
|
|
||||||
|
// Create the group document
|
||||||
|
let group;
|
||||||
|
try {
|
||||||
|
group = await Group.create({
|
||||||
|
name: groupName,
|
||||||
|
description: groupDescription,
|
||||||
|
allowedEndpoints,
|
||||||
|
allowedModels,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.red('Error creating group: ' + error.message);
|
||||||
|
silentExit(1);
|
||||||
|
}
|
||||||
|
console.green(`Group created successfully with id: ${group._id}`);
|
||||||
|
silentExit(0);
|
||||||
|
})();
|
||||||
|
|
||||||
|
process.on('uncaughtException', (err) => {
|
||||||
|
console.error('There was an uncaught error:');
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
@ -32,6 +32,8 @@
|
||||||
"reset-password": "node config/reset-password.js",
|
"reset-password": "node config/reset-password.js",
|
||||||
"ban-user": "node config/ban-user.js",
|
"ban-user": "node config/ban-user.js",
|
||||||
"delete-user": "node config/delete-user.js",
|
"delete-user": "node config/delete-user.js",
|
||||||
|
"create-group": "node config/create-group.js",
|
||||||
|
"assign-group": "node config/assign-group.js",
|
||||||
"update-banner": "node config/update-banner.js",
|
"update-banner": "node config/update-banner.js",
|
||||||
"delete-banner": "node config/delete-banner.js",
|
"delete-banner": "node config/delete-banner.js",
|
||||||
"backend": "cross-env NODE_ENV=production node api/server/index.js",
|
"backend": "cross-env NODE_ENV=production node api/server/index.js",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue