mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-16 16:30:15 +01:00
📃 feat: add list-balances, remove-user, and improve User scripts (#1418)
* Refactoring opening of DB to config/helpers.js * Adding two user scripts: - 'delete-user' to remove a user definitely - 'list-balances' to show the balances of all the users
This commit is contained in:
parent
8735db0980
commit
1a95bef677
10 changed files with 137 additions and 82 deletions
|
|
@ -1,36 +1,11 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { askQuestion, silentExit } = require('./helpers');
|
const { askQuestion, silentExit, connectWithTimeout } = require('./helpers');
|
||||||
const Transaction = require('~/models/Transaction');
|
const Transaction = require('~/models/Transaction');
|
||||||
const connectDb = require('~/lib/db/connectDb');
|
|
||||||
const User = require('~/models/User');
|
const User = require('~/models/User');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
/**
|
await connectWithTimeout();
|
||||||
* Connect to the database
|
|
||||||
* - If it takes a while, we'll warn the user
|
|
||||||
*/
|
|
||||||
// Warn the user if this is taking a while
|
|
||||||
let timeout = setTimeout(() => {
|
|
||||||
console.orange(
|
|
||||||
'This is taking a while... You may need to check your connection if this fails.',
|
|
||||||
);
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
console.orange('Still going... Might as well assume the connection failed...');
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
console.orange('Error incoming in 3... 2... 1...');
|
|
||||||
}, 13000);
|
|
||||||
}, 10000);
|
|
||||||
}, 5000);
|
|
||||||
// Attempt to connect to the database
|
|
||||||
try {
|
|
||||||
console.orange('Warming up the engines...');
|
|
||||||
await connectDb();
|
|
||||||
clearTimeout(timeout);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
silentExit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the welcome / help menu
|
* Show the welcome / help menu
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,11 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { askQuestion, silentExit } = require('./helpers');
|
const { askQuestion, silentExit, connectWithTimeout } = require('./helpers');
|
||||||
const banViolation = require('~/cache/banViolation');
|
const banViolation = require('~/cache/banViolation');
|
||||||
const connectDb = require('~/lib/db/connectDb');
|
|
||||||
const User = require('~/models/User');
|
const User = require('~/models/User');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
/**
|
await connectWithTimeout();
|
||||||
* Connect to the database
|
|
||||||
* - If it takes a while, we'll warn the user
|
|
||||||
*/
|
|
||||||
// Warn the user if this is taking a while
|
|
||||||
let timeout = setTimeout(() => {
|
|
||||||
console.orange(
|
|
||||||
'This is taking a while... You may need to check your connection if this fails.',
|
|
||||||
);
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
console.orange('Still going... Might as well assume the connection failed...');
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
console.orange('Error incoming in 3... 2... 1...');
|
|
||||||
}, 13000);
|
|
||||||
}, 10000);
|
|
||||||
}, 5000);
|
|
||||||
// Attempt to connect to the database
|
|
||||||
try {
|
|
||||||
console.orange('Warming up the engines...');
|
|
||||||
await connectDb();
|
|
||||||
clearTimeout(timeout);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
silentExit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.purple('---------------------');
|
console.purple('---------------------');
|
||||||
console.purple('Ban a user account!');
|
console.purple('Ban a user account!');
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,11 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { registerUser } = require('~/server/services/AuthService');
|
const { registerUser } = require('~/server/services/AuthService');
|
||||||
const { askQuestion, silentExit } = require('./helpers');
|
const { askQuestion, silentExit, connectWithTimeout } = require('./helpers');
|
||||||
const connectDb = require('~/lib/db/connectDb');
|
|
||||||
const User = require('~/models/User');
|
const User = require('~/models/User');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
/**
|
await connectWithTimeout();
|
||||||
* Connect to the database
|
|
||||||
* - If it takes a while, we'll warn the user
|
|
||||||
*/
|
|
||||||
// Warn the user if this is taking a while
|
|
||||||
let timeout = setTimeout(() => {
|
|
||||||
console.orange(
|
|
||||||
'This is taking a while... You may need to check your connection if this fails.',
|
|
||||||
);
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
console.orange('Still going... Might as well assume the connection failed...');
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
console.orange('Error incoming in 3... 2... 1...');
|
|
||||||
}, 13000);
|
|
||||||
}, 10000);
|
|
||||||
}, 5000);
|
|
||||||
// Attempt to connect to the database
|
|
||||||
try {
|
|
||||||
console.orange('Warming up the engines...');
|
|
||||||
await connectDb();
|
|
||||||
clearTimeout(timeout);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
silentExit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the welcome / help menu
|
* Show the welcome / help menu
|
||||||
|
|
|
||||||
48
config/delete-user.js
Normal file
48
config/delete-user.js
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
const path = require('path');
|
||||||
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
|
const { connectWithTimeout, askQuestion, silentExit } = require('./helpers');
|
||||||
|
const User = require('~/models/User');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
await connectWithTimeout();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the welcome / help menu
|
||||||
|
*/
|
||||||
|
console.purple('---------------');
|
||||||
|
console.purple('Deleting a user');
|
||||||
|
console.purple('---------------');
|
||||||
|
|
||||||
|
let email = '';
|
||||||
|
if (process.argv.length >= 3) {
|
||||||
|
email = process.argv[2];
|
||||||
|
} else {
|
||||||
|
email = await askQuestion('Email:');
|
||||||
|
}
|
||||||
|
let user = await User.findOne({ email: email });
|
||||||
|
if (user !== null) {
|
||||||
|
if ((await askQuestion(`Delete user ${user}?`)) === 'y') {
|
||||||
|
user = await User.findOneAndDelete({ _id: user._id });
|
||||||
|
if (user !== null) {
|
||||||
|
console.yellow(`Deleted user ${user}`);
|
||||||
|
} else {
|
||||||
|
console.yellow(`Couldn't delete user with email ${email}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.yellow(`Didn't find user with email ${email}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
silentExit(0);
|
||||||
|
})();
|
||||||
|
|
||||||
|
process.on('uncaughtException', (err) => {
|
||||||
|
if (!err.message.includes('fetch failed')) {
|
||||||
|
console.error('There was an uncaught error:');
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!err.message.includes('fetch failed')) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -6,6 +6,7 @@ const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const readline = require('readline');
|
const readline = require('readline');
|
||||||
const { execSync } = require('child_process');
|
const { execSync } = require('child_process');
|
||||||
|
const { connectDb } = require('@librechat/backend/lib/db');
|
||||||
|
|
||||||
const askQuestion = (query) => {
|
const askQuestion = (query) => {
|
||||||
const rl = readline.createInterface({
|
const rl = readline.createInterface({
|
||||||
|
|
@ -43,6 +44,33 @@ const silentExit = (code = 0) => {
|
||||||
process.exit(code);
|
process.exit(code);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function connectWithTimeout() {
|
||||||
|
/**
|
||||||
|
* Connect to the database
|
||||||
|
* - If it takes a while, we'll warn the user
|
||||||
|
*/
|
||||||
|
let timeout = setTimeout(() => {
|
||||||
|
console.orange(
|
||||||
|
'This is taking a while... You may need to check your connection if this fails.',
|
||||||
|
);
|
||||||
|
timeout = setTimeout(() => {
|
||||||
|
console.orange('Still going... Might as well assume the connection failed...');
|
||||||
|
timeout = setTimeout(() => {
|
||||||
|
console.orange('Error incoming in 3... 2... 1...');
|
||||||
|
}, 13000);
|
||||||
|
}, 10000);
|
||||||
|
}, 5000);
|
||||||
|
// Attempt to connect to the database
|
||||||
|
try {
|
||||||
|
console.orange('Warming up the engines...');
|
||||||
|
await connectDb();
|
||||||
|
clearTimeout(timeout);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
silentExit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set the console colours
|
// Set the console colours
|
||||||
console.orange = (msg) => console.log('\x1b[33m%s\x1b[0m', msg);
|
console.orange = (msg) => console.log('\x1b[33m%s\x1b[0m', msg);
|
||||||
console.green = (msg) => console.log('\x1b[32m%s\x1b[0m', msg);
|
console.green = (msg) => console.log('\x1b[32m%s\x1b[0m', msg);
|
||||||
|
|
@ -58,5 +86,6 @@ module.exports = {
|
||||||
askQuestion,
|
askQuestion,
|
||||||
silentExit,
|
silentExit,
|
||||||
isDockerRunning,
|
isDockerRunning,
|
||||||
|
connectWithTimeout,
|
||||||
deleteNodeModules,
|
deleteNodeModules,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
39
config/list-balances.js
Normal file
39
config/list-balances.js
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
const path = require('path');
|
||||||
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
|
const { connectWithTimeout, silentExit } = require('./helpers');
|
||||||
|
const Balance = require('~/models/Balance');
|
||||||
|
const User = require('~/models/User');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
await connectWithTimeout();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the welcome / help menu
|
||||||
|
*/
|
||||||
|
console.purple('-----------------------------');
|
||||||
|
console.purple('Show the balance of all users');
|
||||||
|
console.purple('-----------------------------');
|
||||||
|
|
||||||
|
let users = await User.find({});
|
||||||
|
for (const user of users) {
|
||||||
|
let balance = await Balance.findOne({ user: user._id });
|
||||||
|
if (balance !== null) {
|
||||||
|
console.green(`User ${user.name} has a balance of ${balance.tokenCredits}`);
|
||||||
|
} else {
|
||||||
|
console.yellow(`User ${user.name} has no balance`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
silentExit(0);
|
||||||
|
})();
|
||||||
|
|
||||||
|
process.on('uncaughtException', (err) => {
|
||||||
|
if (!err.message.includes('fetch failed')) {
|
||||||
|
console.error('There was an uncaught error:');
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!err.message.includes('fetch failed')) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -30,6 +30,14 @@ npm run add-balance danny@librechat.ai 1000
|
||||||
|
|
||||||
This works well to track your own usage for personal use; 1000 credits = $0.001 (1 mill USD)
|
This works well to track your own usage for personal use; 1000 credits = $0.001 (1 mill USD)
|
||||||
|
|
||||||
|
## Listing of balances
|
||||||
|
|
||||||
|
To see the balances of your users, you can run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run list-balances
|
||||||
|
```
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- With summarization enabled, you will be blocked from making an API request if the cost of the content that you need to summarize + your messages payload exceeds the current balance
|
- With summarization enabled, you will be blocked from making an API request if the cost of the content that you need to summarize + your messages payload exceeds the current balance
|
||||||
|
|
|
||||||
|
|
@ -581,6 +581,7 @@ see: **[Token Usage](../../features/token_usage.md)**
|
||||||
|
|
||||||
- To manually add balances, run the following command:`npm run add-balance`
|
- To manually add balances, run the following command:`npm run add-balance`
|
||||||
- You can also specify the email and token credit amount to add, e.g.:`npm run add-balance example@example.com 1000`
|
- You can also specify the email and token credit amount to add, e.g.:`npm run add-balance example@example.com 1000`
|
||||||
|
- To list the balance of every user: `npm run list-balances`
|
||||||
|
|
||||||
> **Note:** 1000 credits = $0.001 (1 mill USD)
|
> **Note:** 1000 credits = $0.001 (1 mill USD)
|
||||||
|
|
||||||
|
|
@ -602,6 +603,7 @@ see: **[User/Auth System](../configuration/user_auth_system.md)**
|
||||||
- `ALLOW_SOCIAL_REGISTRATION`: Enable or disable registration of new user using various social network. Set to `true` or `false` to enable or disable.
|
- `ALLOW_SOCIAL_REGISTRATION`: Enable or disable registration of new user using various social network. Set to `true` or `false` to enable or disable.
|
||||||
|
|
||||||
> **Quick Tip:** Even with registration disabled, add users directly to the database using `npm run create-user`.
|
> **Quick Tip:** Even with registration disabled, add users directly to the database using `npm run create-user`.
|
||||||
|
> **Quick Tip:** With registration disabled, you can delete a user with `npm run delete-user email@domain.com`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ALLOW_EMAIL_LOGIN=true
|
ALLOW_EMAIL_LOGIN=true
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ Here's an overview of the general configuration, located in the `.env` file at t
|
||||||
> **Note:** OpenID does not support the ability to disable only registration.
|
> **Note:** OpenID does not support the ability to disable only registration.
|
||||||
|
|
||||||
>> **Quick Tip:** Even with registration disabled, add users directly to the database using `npm run create-user`. If you can't get npm to work, try `sudo docker exec -ti LibreChat sh` first to "ssh" into the container.
|
>> **Quick Tip:** Even with registration disabled, add users directly to the database using `npm run create-user`. If you can't get npm to work, try `sudo docker exec -ti LibreChat sh` first to "ssh" into the container.
|
||||||
|
>> **Quick Tip:** To delete a user, you can run `docker-compose exec api npm run delete-user email@domain.com`
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"update": "node config/update.js",
|
"update": "node config/update.js",
|
||||||
"add-balance": "node config/add-balance.js",
|
"add-balance": "node config/add-balance.js",
|
||||||
|
"list-balances": "node config/list-balances.js",
|
||||||
"rebuild:package-lock": "node config/packages",
|
"rebuild:package-lock": "node config/packages",
|
||||||
"reinstall": "node config/update.js -l -g",
|
"reinstall": "node config/update.js -l -g",
|
||||||
"b:reinstall": "bun config/update.js -b -l -g",
|
"b:reinstall": "bun config/update.js -b -l -g",
|
||||||
|
|
@ -25,6 +26,7 @@
|
||||||
"upgrade": "node config/upgrade.js",
|
"upgrade": "node config/upgrade.js",
|
||||||
"create-user": "node config/create-user.js",
|
"create-user": "node config/create-user.js",
|
||||||
"ban-user": "node config/ban-user.js",
|
"ban-user": "node config/ban-user.js",
|
||||||
|
"delete-user": "node config/delete-user.js",
|
||||||
"backend": "cross-env NODE_ENV=production node api/server/index.js",
|
"backend": "cross-env NODE_ENV=production node api/server/index.js",
|
||||||
"backend:dev": "cross-env NODE_ENV=development npx nodemon api/server/index.js",
|
"backend:dev": "cross-env NODE_ENV=development npx nodemon api/server/index.js",
|
||||||
"backend:stop": "node config/stop-backend.js",
|
"backend:stop": "node config/stop-backend.js",
|
||||||
|
|
@ -53,7 +55,8 @@
|
||||||
"b:client:dev": "cd client && bun run b:dev",
|
"b:client:dev": "cd client && bun run b:dev",
|
||||||
"b:test:client": "cd client && bun run b:test",
|
"b:test:client": "cd client && bun run b:test",
|
||||||
"b:test:api": "cd api && bun run b:test",
|
"b:test:api": "cd api && bun run b:test",
|
||||||
"b:balance": "bun config/add-balance.js"
|
"b:balance": "bun config/add-balance.js",
|
||||||
|
"b:list-balances": "bun config/list-balances.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue