mirror of
https://github.com/Mintplex-Labs/anything-llm
synced 2026-04-26 01:25:15 +02:00
[FEATURE] Enable the ability to have multi user instances (#158)
* multi user wip * WIP MUM features * invitation mgmt * suspend or unsuspend users * workspace mangement * manage chats * manage chats * add Support for admin system settings for users to delete workspaces and limit chats per user * fix issue ith system var update app to lazy load invite page * cleanup and bug fixes * wrong method * update readme * update readme * update readme * bump version to 0.1.0
This commit is contained in:
348
server/endpoints/admin.js
Normal file
348
server/endpoints/admin.js
Normal file
@@ -0,0 +1,348 @@
|
||||
const { Document } = require("../models/documents");
|
||||
const { Invite } = require("../models/invite");
|
||||
const { SystemSettings } = require("../models/systemSettings");
|
||||
const { User } = require("../models/user");
|
||||
const { DocumentVectors } = require("../models/vectors");
|
||||
const { Workspace } = require("../models/workspace");
|
||||
const { WorkspaceChats } = require("../models/workspaceChats");
|
||||
const { getVectorDbClass } = require("../utils/helpers");
|
||||
const { userFromSession, reqBody } = require("../utils/http");
|
||||
const { validatedRequest } = require("../utils/middleware/validatedRequest");
|
||||
|
||||
function adminEndpoints(app) {
|
||||
if (!app) return;
|
||||
|
||||
app.get("/admin/users", [validatedRequest], async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
const users = (await User.where()).map((user) => {
|
||||
const { password, ...rest } = user;
|
||||
return rest;
|
||||
});
|
||||
response.status(200).json({ users });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
});
|
||||
|
||||
app.post(
|
||||
"/admin/users/new",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const newUserParams = reqBody(request);
|
||||
const { user: newUser, error } = await User.create(newUserParams);
|
||||
response.status(200).json({ user: newUser, error });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.post("/admin/user/:id", [validatedRequest], async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const { id } = request.params;
|
||||
const updates = reqBody(request);
|
||||
const { success, error } = await User.update(id, updates);
|
||||
response.status(200).json({ success, error });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
});
|
||||
|
||||
app.delete(
|
||||
"/admin/user/:id",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
const { id } = request.params;
|
||||
await User.delete(`id = ${id}`);
|
||||
response.status(200).json({ success: true, error: null });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.get("/admin/invites", [validatedRequest], async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const invites = await Invite.whereWithUsers();
|
||||
response.status(200).json({ invites });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
});
|
||||
|
||||
app.get(
|
||||
"/admin/invite/new",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const { invite, error } = await Invite.create(user.id);
|
||||
response.status(200).json({ invite, error });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.delete(
|
||||
"/admin/invite/:id",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const { id } = request.params;
|
||||
const { success, error } = await Invite.deactivate(id);
|
||||
response.status(200).json({ success, error });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.get(
|
||||
"/admin/workspaces",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
const workspaces = await Workspace.whereWithUsers();
|
||||
response.status(200).json({ workspaces });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.post(
|
||||
"/admin/workspaces/new",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
const { name } = reqBody(request);
|
||||
const { workspace, message: error } = await Workspace.new(
|
||||
name,
|
||||
user.id
|
||||
);
|
||||
response.status(200).json({ workspace, error });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.post(
|
||||
"/admin/workspaces/:workspaceId/update-users",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const { workspaceId } = request.params;
|
||||
const { userIds } = reqBody(request);
|
||||
const { success, error } = await Workspace.updateUsers(
|
||||
workspaceId,
|
||||
userIds
|
||||
);
|
||||
response.status(200).json({ success, error });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.delete(
|
||||
"/admin/workspaces/:id",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const { id } = request.params;
|
||||
const VectorDb = getVectorDbClass();
|
||||
const workspace = Workspace.get(`id = ${id}`);
|
||||
if (!workspace) {
|
||||
response.sendStatus(404).end();
|
||||
return;
|
||||
}
|
||||
|
||||
await Workspace.delete(`id = ${id}`);
|
||||
await DocumentVectors.deleteForWorkspace(id);
|
||||
await Document.delete(`workspaceId = ${Number(id)}`);
|
||||
await WorkspaceChats.delete(`workspaceId = ${Number(id)}`);
|
||||
try {
|
||||
await VectorDb["delete-namespace"]({ namespace: workspace.slug });
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
}
|
||||
|
||||
response.status(200).json({ success, error });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.post(
|
||||
"/admin/workspace-chats",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
const { offset = 0 } = reqBody(request);
|
||||
const chats = await WorkspaceChats.whereWithData(`id >= ${offset}`, 20);
|
||||
const hasPages = (await WorkspaceChats.count()) > 20;
|
||||
response.status(200).json({ chats: chats.reverse(), hasPages });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.delete(
|
||||
"/admin/workspace-chats/:id",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const { id } = request.params;
|
||||
await WorkspaceChats.delete(`id = ${id}`);
|
||||
response.status(200).json({ success, error });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.get(
|
||||
"/admin/system-preferences",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const settings = {
|
||||
users_can_delete_workspaces:
|
||||
(await SystemSettings.get(`label = 'users_can_delete_workspaces'`))
|
||||
?.value === "true",
|
||||
limit_user_messages:
|
||||
(await SystemSettings.get(`label = 'limit_user_messages'`))
|
||||
?.value === "true",
|
||||
message_limit:
|
||||
Number(
|
||||
(await SystemSettings.get(`label = 'message_limit'`))?.value
|
||||
) || 10,
|
||||
};
|
||||
response.status(200).json({ settings });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.post(
|
||||
"/admin/system-preferences",
|
||||
[validatedRequest],
|
||||
async (request, response) => {
|
||||
try {
|
||||
const user = await userFromSession(request, response);
|
||||
if (!user || user?.role !== "admin") {
|
||||
response.sendStatus(401).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const updates = reqBody(request);
|
||||
await SystemSettings.updateSettings(updates);
|
||||
response.status(200).json({ success: true, error: null });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = { adminEndpoints };
|
||||
Reference in New Issue
Block a user