2023-08-24 04:15:07 +02:00
|
|
|
const { ApiKey } = require("../models/apiKeys");
|
2023-07-25 19:37:04 +02:00
|
|
|
const { Document } = require("../models/documents");
|
[FEAT] Automated audit logging (#667)
* WIP event logging - new table for events and new settings view for viewing
* WIP add logging
* UI for log rows
* rename files to Logging to prevent getting gitignore
* add metadata for all logging events and colored badges in logs page
* remove unneeded comment
* cleanup namespace for logging
* clean up backend calls
* update logging to show to => from settings changes
* add logging for invitations, created, deleted, and accepted
* add logging for user created, updated, suspended, or removed
* add logging for workspace deleted
* add logging for chat logs exported
* add logging for API keys, LLM, embedder, vector db, embed chat, and reset button
* modify event logs
* update to event log types
* simplify rendering of event badges
---------
Co-authored-by: timothycarambat <rambat1010@gmail.com>
2024-02-07 00:21:40 +01:00
|
|
|
const { EventLogs } = require("../models/eventLogs");
|
2023-07-25 19:37:04 +02:00
|
|
|
const { Invite } = require("../models/invite");
|
|
|
|
const { SystemSettings } = require("../models/systemSettings");
|
[FEAT] Automated audit logging (#667)
* WIP event logging - new table for events and new settings view for viewing
* WIP add logging
* UI for log rows
* rename files to Logging to prevent getting gitignore
* add metadata for all logging events and colored badges in logs page
* remove unneeded comment
* cleanup namespace for logging
* clean up backend calls
* update logging to show to => from settings changes
* add logging for invitations, created, deleted, and accepted
* add logging for user created, updated, suspended, or removed
* add logging for workspace deleted
* add logging for chat logs exported
* add logging for API keys, LLM, embedder, vector db, embed chat, and reset button
* modify event logs
* update to event log types
* simplify rendering of event badges
---------
Co-authored-by: timothycarambat <rambat1010@gmail.com>
2024-02-07 00:21:40 +01:00
|
|
|
const { Telemetry } = require("../models/telemetry");
|
2023-07-25 19:37:04 +02:00
|
|
|
const { User } = require("../models/user");
|
|
|
|
const { DocumentVectors } = require("../models/vectors");
|
|
|
|
const { Workspace } = require("../models/workspace");
|
|
|
|
const { WorkspaceChats } = require("../models/workspaceChats");
|
2024-04-07 01:38:07 +02:00
|
|
|
const {
|
|
|
|
getVectorDbClass,
|
|
|
|
getEmbeddingEngineSelection,
|
|
|
|
} = require("../utils/helpers");
|
2024-01-22 23:14:01 +01:00
|
|
|
const {
|
|
|
|
validRoleSelection,
|
|
|
|
canModifyAdmin,
|
|
|
|
validCanModify,
|
|
|
|
} = require("../utils/helpers/admin");
|
2024-04-16 19:50:10 +02:00
|
|
|
const { reqBody, userFromSession, safeJsonParse } = require("../utils/http");
|
2023-11-13 23:51:16 +01:00
|
|
|
const {
|
|
|
|
strictMultiUserRoleValid,
|
2024-02-08 21:17:01 +01:00
|
|
|
flexUserRoleValid,
|
2024-01-22 23:14:01 +01:00
|
|
|
ROLES,
|
2023-11-13 23:51:16 +01:00
|
|
|
} = require("../utils/middleware/multiUserProtected");
|
2023-07-25 19:37:04 +02:00
|
|
|
const { validatedRequest } = require("../utils/middleware/validatedRequest");
|
2024-09-11 02:06:02 +02:00
|
|
|
const ImportedPlugin = require("../utils/agents/imported");
|
2023-07-25 19:37:04 +02:00
|
|
|
|
|
|
|
function adminEndpoints(app) {
|
|
|
|
if (!app) return;
|
|
|
|
|
2023-11-13 23:51:16 +01:00
|
|
|
app.get(
|
|
|
|
"/admin/users",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-11-13 23:51:16 +01:00
|
|
|
async (_request, response) => {
|
|
|
|
try {
|
2024-05-22 19:32:39 +02:00
|
|
|
const users = await User.where();
|
2023-11-13 23:51:16 +01:00
|
|
|
response.status(200).json({ users });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
2023-07-25 19:37:04 +02:00
|
|
|
}
|
|
|
|
}
|
2023-11-13 23:51:16 +01:00
|
|
|
);
|
2023-07-25 19:37:04 +02:00
|
|
|
|
|
|
|
app.post(
|
|
|
|
"/admin/users/new",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-07-25 19:37:04 +02:00
|
|
|
async (request, response) => {
|
|
|
|
try {
|
2024-01-22 23:14:01 +01:00
|
|
|
const currUser = await userFromSession(request, response);
|
2023-07-25 19:37:04 +02:00
|
|
|
const newUserParams = reqBody(request);
|
2024-01-22 23:14:01 +01:00
|
|
|
const roleValidation = validRoleSelection(currUser, newUserParams);
|
|
|
|
|
|
|
|
if (!roleValidation.valid) {
|
|
|
|
response
|
|
|
|
.status(200)
|
|
|
|
.json({ user: null, error: roleValidation.error });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-07-25 19:37:04 +02:00
|
|
|
const { user: newUser, error } = await User.create(newUserParams);
|
2024-03-07 02:14:17 +01:00
|
|
|
if (!!newUser) {
|
|
|
|
await EventLogs.logEvent(
|
|
|
|
"user_created",
|
|
|
|
{
|
|
|
|
userName: newUser.username,
|
|
|
|
createdBy: currUser.username,
|
|
|
|
},
|
|
|
|
currUser.id
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-07-25 19:37:04 +02:00
|
|
|
response.status(200).json({ user: newUser, error });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2023-11-13 23:51:16 +01:00
|
|
|
app.post(
|
|
|
|
"/admin/user/:id",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-11-13 23:51:16 +01:00
|
|
|
async (request, response) => {
|
|
|
|
try {
|
2024-01-22 23:14:01 +01:00
|
|
|
const currUser = await userFromSession(request, response);
|
2023-11-13 23:51:16 +01:00
|
|
|
const { id } = request.params;
|
|
|
|
const updates = reqBody(request);
|
2023-11-14 23:43:40 +01:00
|
|
|
const user = await User.get({ id: Number(id) });
|
|
|
|
|
2024-01-22 23:14:01 +01:00
|
|
|
const canModify = validCanModify(currUser, user);
|
|
|
|
if (!canModify.valid) {
|
|
|
|
response.status(200).json({ success: false, error: canModify.error });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const roleValidation = validRoleSelection(currUser, updates);
|
|
|
|
if (!roleValidation.valid) {
|
|
|
|
response
|
|
|
|
.status(200)
|
|
|
|
.json({ success: false, error: roleValidation.error });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const validAdminRoleModification = await canModifyAdmin(user, updates);
|
|
|
|
if (!validAdminRoleModification.valid) {
|
|
|
|
response
|
|
|
|
.status(200)
|
|
|
|
.json({ success: false, error: validAdminRoleModification.error });
|
|
|
|
return;
|
2023-11-14 23:43:40 +01:00
|
|
|
}
|
|
|
|
|
2023-11-13 23:51:16 +01:00
|
|
|
const { success, error } = await User.update(id, updates);
|
|
|
|
response.status(200).json({ success, error });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
2023-07-25 19:37:04 +02:00
|
|
|
}
|
|
|
|
}
|
2023-11-13 23:51:16 +01:00
|
|
|
);
|
2023-07-25 19:37:04 +02:00
|
|
|
|
|
|
|
app.delete(
|
|
|
|
"/admin/user/:id",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-07-25 19:37:04 +02:00
|
|
|
async (request, response) => {
|
|
|
|
try {
|
2024-01-22 23:14:01 +01:00
|
|
|
const currUser = await userFromSession(request, response);
|
2023-07-25 19:37:04 +02:00
|
|
|
const { id } = request.params;
|
2024-01-22 23:14:01 +01:00
|
|
|
const user = await User.get({ id: Number(id) });
|
|
|
|
|
|
|
|
const canModify = validCanModify(currUser, user);
|
|
|
|
if (!canModify.valid) {
|
|
|
|
response.status(200).json({ success: false, error: canModify.error });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-09-28 23:00:03 +02:00
|
|
|
await User.delete({ id: Number(id) });
|
[FEAT] Automated audit logging (#667)
* WIP event logging - new table for events and new settings view for viewing
* WIP add logging
* UI for log rows
* rename files to Logging to prevent getting gitignore
* add metadata for all logging events and colored badges in logs page
* remove unneeded comment
* cleanup namespace for logging
* clean up backend calls
* update logging to show to => from settings changes
* add logging for invitations, created, deleted, and accepted
* add logging for user created, updated, suspended, or removed
* add logging for workspace deleted
* add logging for chat logs exported
* add logging for API keys, LLM, embedder, vector db, embed chat, and reset button
* modify event logs
* update to event log types
* simplify rendering of event badges
---------
Co-authored-by: timothycarambat <rambat1010@gmail.com>
2024-02-07 00:21:40 +01:00
|
|
|
await EventLogs.logEvent(
|
|
|
|
"user_deleted",
|
|
|
|
{
|
|
|
|
userName: user.username,
|
|
|
|
deletedBy: currUser.username,
|
|
|
|
},
|
|
|
|
currUser.id
|
|
|
|
);
|
2023-07-25 19:37:04 +02:00
|
|
|
response.status(200).json({ success: true, error: null });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2023-11-13 23:51:16 +01:00
|
|
|
app.get(
|
|
|
|
"/admin/invites",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-11-13 23:51:16 +01:00
|
|
|
async (_request, response) => {
|
|
|
|
try {
|
|
|
|
const invites = await Invite.whereWithUsers();
|
|
|
|
response.status(200).json({ invites });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
2023-07-25 19:37:04 +02:00
|
|
|
}
|
|
|
|
}
|
2023-11-13 23:51:16 +01:00
|
|
|
);
|
2023-07-25 19:37:04 +02:00
|
|
|
|
2024-03-27 00:38:32 +01:00
|
|
|
app.post(
|
2023-07-25 19:37:04 +02:00
|
|
|
"/admin/invite/new",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-07-25 19:37:04 +02:00
|
|
|
async (request, response) => {
|
|
|
|
try {
|
|
|
|
const user = await userFromSession(request, response);
|
2024-03-27 00:38:32 +01:00
|
|
|
const body = reqBody(request);
|
|
|
|
const { invite, error } = await Invite.create({
|
|
|
|
createdByUserId: user.id,
|
|
|
|
workspaceIds: body?.workspaceIds || [],
|
|
|
|
});
|
|
|
|
|
[FEAT] Automated audit logging (#667)
* WIP event logging - new table for events and new settings view for viewing
* WIP add logging
* UI for log rows
* rename files to Logging to prevent getting gitignore
* add metadata for all logging events and colored badges in logs page
* remove unneeded comment
* cleanup namespace for logging
* clean up backend calls
* update logging to show to => from settings changes
* add logging for invitations, created, deleted, and accepted
* add logging for user created, updated, suspended, or removed
* add logging for workspace deleted
* add logging for chat logs exported
* add logging for API keys, LLM, embedder, vector db, embed chat, and reset button
* modify event logs
* update to event log types
* simplify rendering of event badges
---------
Co-authored-by: timothycarambat <rambat1010@gmail.com>
2024-02-07 00:21:40 +01:00
|
|
|
await EventLogs.logEvent(
|
|
|
|
"invite_created",
|
|
|
|
{
|
|
|
|
inviteCode: invite.code,
|
|
|
|
createdBy: response.locals?.user?.username,
|
|
|
|
},
|
|
|
|
response.locals?.user?.id
|
|
|
|
);
|
2023-07-25 19:37:04 +02:00
|
|
|
response.status(200).json({ invite, error });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
app.delete(
|
|
|
|
"/admin/invite/:id",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-07-25 19:37:04 +02:00
|
|
|
async (request, response) => {
|
|
|
|
try {
|
|
|
|
const { id } = request.params;
|
|
|
|
const { success, error } = await Invite.deactivate(id);
|
[FEAT] Automated audit logging (#667)
* WIP event logging - new table for events and new settings view for viewing
* WIP add logging
* UI for log rows
* rename files to Logging to prevent getting gitignore
* add metadata for all logging events and colored badges in logs page
* remove unneeded comment
* cleanup namespace for logging
* clean up backend calls
* update logging to show to => from settings changes
* add logging for invitations, created, deleted, and accepted
* add logging for user created, updated, suspended, or removed
* add logging for workspace deleted
* add logging for chat logs exported
* add logging for API keys, LLM, embedder, vector db, embed chat, and reset button
* modify event logs
* update to event log types
* simplify rendering of event badges
---------
Co-authored-by: timothycarambat <rambat1010@gmail.com>
2024-02-07 00:21:40 +01:00
|
|
|
await EventLogs.logEvent(
|
|
|
|
"invite_deleted",
|
|
|
|
{ deletedBy: response.locals?.user?.username },
|
|
|
|
response.locals?.user?.id
|
|
|
|
);
|
2023-07-25 19:37:04 +02:00
|
|
|
response.status(200).json({ success, error });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
app.get(
|
|
|
|
"/admin/workspaces",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-11-13 23:51:16 +01:00
|
|
|
async (_request, response) => {
|
2023-07-25 19:37:04 +02:00
|
|
|
try {
|
|
|
|
const workspaces = await Workspace.whereWithUsers();
|
|
|
|
response.status(200).json({ workspaces });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2024-04-02 23:53:35 +02:00
|
|
|
app.get(
|
|
|
|
"/admin/workspaces/:workspaceId/users",
|
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
|
|
|
async (request, response) => {
|
|
|
|
try {
|
|
|
|
const { workspaceId } = request.params;
|
|
|
|
const users = await Workspace.workspaceUsers(workspaceId);
|
|
|
|
response.status(200).json({ users });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2023-07-25 19:37:04 +02:00
|
|
|
app.post(
|
|
|
|
"/admin/workspaces/new",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-07-25 19:37:04 +02:00
|
|
|
async (request, response) => {
|
|
|
|
try {
|
|
|
|
const user = await userFromSession(request, response);
|
|
|
|
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",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-07-25 19:37:04 +02:00
|
|
|
async (request, response) => {
|
|
|
|
try {
|
|
|
|
const { workspaceId } = request.params;
|
|
|
|
const { userIds } = reqBody(request);
|
|
|
|
const { success, error } = await Workspace.updateUsers(
|
2023-09-28 23:00:03 +02:00
|
|
|
workspaceId,
|
2023-07-25 19:37:04 +02:00
|
|
|
userIds
|
|
|
|
);
|
|
|
|
response.status(200).json({ success, error });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
app.delete(
|
|
|
|
"/admin/workspaces/:id",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-07-25 19:37:04 +02:00
|
|
|
async (request, response) => {
|
|
|
|
try {
|
|
|
|
const { id } = request.params;
|
|
|
|
const VectorDb = getVectorDbClass();
|
2023-09-28 23:00:03 +02:00
|
|
|
const workspace = await Workspace.get({ id: Number(id) });
|
2023-07-25 19:37:04 +02:00
|
|
|
if (!workspace) {
|
|
|
|
response.sendStatus(404).end();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-09-28 23:00:03 +02:00
|
|
|
await WorkspaceChats.delete({ workspaceId: Number(workspace.id) });
|
|
|
|
await DocumentVectors.deleteForWorkspace(Number(workspace.id));
|
|
|
|
await Document.delete({ workspaceId: Number(workspace.id) });
|
|
|
|
await Workspace.delete({ id: Number(workspace.id) });
|
2023-07-25 19:37:04 +02:00
|
|
|
try {
|
|
|
|
await VectorDb["delete-namespace"]({ namespace: workspace.slug });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e.message);
|
|
|
|
}
|
|
|
|
|
2023-09-28 23:00:03 +02:00
|
|
|
response.status(200).json({ success: true, error: null });
|
2023-07-25 19:37:04 +02:00
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2024-09-11 02:06:02 +02:00
|
|
|
// System preferences but only by array of labels
|
|
|
|
app.get(
|
|
|
|
"/admin/system-preferences-for",
|
|
|
|
[validatedRequest, flexUserRoleValid([ROLES.admin, ROLES.manager])],
|
|
|
|
async (request, response) => {
|
|
|
|
try {
|
|
|
|
const requestedSettings = {};
|
|
|
|
const labels = request.query.labels?.split(",") || [];
|
|
|
|
const needEmbedder = [
|
|
|
|
"text_splitter_chunk_size",
|
|
|
|
"max_embed_chunk_size",
|
|
|
|
];
|
|
|
|
const noRecord = [
|
|
|
|
"max_embed_chunk_size",
|
|
|
|
"agent_sql_connections",
|
|
|
|
"imported_agent_skills",
|
|
|
|
"feature_flags",
|
|
|
|
"meta_page_title",
|
|
|
|
"meta_page_favicon",
|
|
|
|
];
|
|
|
|
|
|
|
|
for (const label of labels) {
|
|
|
|
// Skip any settings that are not explicitly defined as public
|
|
|
|
if (!SystemSettings.publicFields.includes(label)) continue;
|
|
|
|
|
|
|
|
// Only get the embedder if the setting actually needs it
|
|
|
|
let embedder = needEmbedder.includes(label)
|
|
|
|
? getEmbeddingEngineSelection()
|
|
|
|
: null;
|
|
|
|
// Only get the record from db if the setting actually needs it
|
|
|
|
let setting = noRecord.includes(label)
|
|
|
|
? null
|
|
|
|
: await SystemSettings.get({ label });
|
|
|
|
|
|
|
|
switch (label) {
|
|
|
|
case "footer_data":
|
|
|
|
requestedSettings[label] = setting?.value ?? JSON.stringify([]);
|
|
|
|
break;
|
|
|
|
case "support_email":
|
|
|
|
requestedSettings[label] = setting?.value || null;
|
|
|
|
break;
|
|
|
|
case "text_splitter_chunk_size":
|
|
|
|
requestedSettings[label] =
|
|
|
|
setting?.value || embedder?.embeddingMaxChunkLength || null;
|
|
|
|
break;
|
|
|
|
case "text_splitter_chunk_overlap":
|
|
|
|
requestedSettings[label] = setting?.value || null;
|
|
|
|
break;
|
|
|
|
case "max_embed_chunk_size":
|
|
|
|
requestedSettings[label] =
|
|
|
|
embedder?.embeddingMaxChunkLength || 1000;
|
|
|
|
break;
|
|
|
|
case "agent_search_provider":
|
|
|
|
requestedSettings[label] = setting?.value || null;
|
|
|
|
break;
|
|
|
|
case "agent_sql_connections":
|
|
|
|
requestedSettings[label] =
|
|
|
|
await SystemSettings.brief.agent_sql_connections();
|
|
|
|
break;
|
|
|
|
case "default_agent_skills":
|
|
|
|
requestedSettings[label] = safeJsonParse(setting?.value, []);
|
|
|
|
break;
|
|
|
|
case "imported_agent_skills":
|
|
|
|
requestedSettings[label] = ImportedPlugin.listImportedPlugins();
|
|
|
|
break;
|
|
|
|
case "custom_app_name":
|
|
|
|
requestedSettings[label] = setting?.value || null;
|
|
|
|
break;
|
|
|
|
case "feature_flags":
|
|
|
|
requestedSettings[label] =
|
|
|
|
(await SystemSettings.getFeatureFlags()) || {};
|
|
|
|
break;
|
|
|
|
case "meta_page_title":
|
|
|
|
requestedSettings[label] =
|
|
|
|
await SystemSettings.getValueOrFallback({ label }, null);
|
|
|
|
break;
|
|
|
|
case "meta_page_favicon":
|
|
|
|
requestedSettings[label] =
|
|
|
|
await SystemSettings.getValueOrFallback({ label }, null);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
response.status(200).json({ settings: requestedSettings });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
// TODO: Delete this endpoint
|
|
|
|
// DEPRECATED - use /admin/system-preferences-for instead with ?labels=... comma separated string of labels
|
2023-07-25 19:37:04 +02:00
|
|
|
app.get(
|
|
|
|
"/admin/system-preferences",
|
2024-02-08 21:17:01 +01:00
|
|
|
[validatedRequest, flexUserRoleValid([ROLES.admin, ROLES.manager])],
|
|
|
|
async (_, response) => {
|
2023-07-25 19:37:04 +02:00
|
|
|
try {
|
2024-06-12 19:52:32 +02:00
|
|
|
const embedder = getEmbeddingEngineSelection();
|
2023-07-25 19:37:04 +02:00
|
|
|
const settings = {
|
2024-02-08 21:17:01 +01:00
|
|
|
footer_data:
|
|
|
|
(await SystemSettings.get({ label: "footer_data" }))?.value ||
|
|
|
|
JSON.stringify([]),
|
2024-02-19 19:30:41 +01:00
|
|
|
support_email:
|
|
|
|
(await SystemSettings.get({ label: "support_email" }))?.value ||
|
|
|
|
null,
|
2024-04-07 01:38:07 +02:00
|
|
|
text_splitter_chunk_size:
|
|
|
|
(await SystemSettings.get({ label: "text_splitter_chunk_size" }))
|
|
|
|
?.value ||
|
2024-06-12 19:52:32 +02:00
|
|
|
embedder?.embeddingMaxChunkLength ||
|
2024-04-07 01:38:07 +02:00
|
|
|
null,
|
|
|
|
text_splitter_chunk_overlap:
|
|
|
|
(await SystemSettings.get({ label: "text_splitter_chunk_overlap" }))
|
|
|
|
?.value || null,
|
2024-06-12 19:52:32 +02:00
|
|
|
max_embed_chunk_size: embedder?.embeddingMaxChunkLength || 1000,
|
2024-04-16 19:50:10 +02:00
|
|
|
agent_search_provider:
|
|
|
|
(await SystemSettings.get({ label: "agent_search_provider" }))
|
|
|
|
?.value || null,
|
2024-05-16 19:38:21 +02:00
|
|
|
agent_sql_connections:
|
|
|
|
await SystemSettings.brief.agent_sql_connections(),
|
2024-04-16 19:50:10 +02:00
|
|
|
default_agent_skills:
|
|
|
|
safeJsonParse(
|
|
|
|
(await SystemSettings.get({ label: "default_agent_skills" }))
|
|
|
|
?.value,
|
|
|
|
[]
|
|
|
|
) || [],
|
2024-09-11 02:06:02 +02:00
|
|
|
imported_agent_skills: ImportedPlugin.listImportedPlugins(),
|
2024-05-23 23:14:53 +02:00
|
|
|
custom_app_name:
|
|
|
|
(await SystemSettings.get({ label: "custom_app_name" }))?.value ||
|
|
|
|
null,
|
2024-06-21 22:38:50 +02:00
|
|
|
feature_flags: (await SystemSettings.getFeatureFlags()) || {},
|
2024-07-20 00:58:43 +02:00
|
|
|
meta_page_title: await SystemSettings.getValueOrFallback(
|
|
|
|
{ label: "meta_page_title" },
|
|
|
|
null
|
|
|
|
),
|
|
|
|
meta_page_favicon: await SystemSettings.getValueOrFallback(
|
|
|
|
{ label: "meta_page_favicon" },
|
|
|
|
null
|
|
|
|
),
|
2023-07-25 19:37:04 +02:00
|
|
|
};
|
|
|
|
response.status(200).json({ settings });
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
app.post(
|
|
|
|
"/admin/system-preferences",
|
2024-02-08 21:17:01 +01:00
|
|
|
[validatedRequest, flexUserRoleValid([ROLES.admin, ROLES.manager])],
|
2023-07-25 19:37:04 +02:00
|
|
|
async (request, response) => {
|
|
|
|
try {
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
2023-08-24 04:15:07 +02:00
|
|
|
|
2023-11-13 23:51:16 +01:00
|
|
|
app.get(
|
|
|
|
"/admin/api-keys",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin])],
|
2023-11-13 23:51:16 +01:00
|
|
|
async (_request, response) => {
|
|
|
|
try {
|
|
|
|
const apiKeys = await ApiKey.whereWithUser({});
|
|
|
|
return response.status(200).json({
|
|
|
|
apiKeys,
|
|
|
|
error: null,
|
|
|
|
});
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
response.status(500).json({
|
|
|
|
apiKey: null,
|
|
|
|
error: "Could not find an API Keys.",
|
|
|
|
});
|
2023-08-24 04:15:07 +02:00
|
|
|
}
|
|
|
|
}
|
2023-11-13 23:51:16 +01:00
|
|
|
);
|
2023-08-24 04:15:07 +02:00
|
|
|
|
|
|
|
app.post(
|
|
|
|
"/admin/generate-api-key",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin])],
|
2023-08-24 04:15:07 +02:00
|
|
|
async (request, response) => {
|
|
|
|
try {
|
|
|
|
const user = await userFromSession(request, response);
|
|
|
|
const { apiKey, error } = await ApiKey.create(user.id);
|
[FEAT] Automated audit logging (#667)
* WIP event logging - new table for events and new settings view for viewing
* WIP add logging
* UI for log rows
* rename files to Logging to prevent getting gitignore
* add metadata for all logging events and colored badges in logs page
* remove unneeded comment
* cleanup namespace for logging
* clean up backend calls
* update logging to show to => from settings changes
* add logging for invitations, created, deleted, and accepted
* add logging for user created, updated, suspended, or removed
* add logging for workspace deleted
* add logging for chat logs exported
* add logging for API keys, LLM, embedder, vector db, embed chat, and reset button
* modify event logs
* update to event log types
* simplify rendering of event badges
---------
Co-authored-by: timothycarambat <rambat1010@gmail.com>
2024-02-07 00:21:40 +01:00
|
|
|
|
|
|
|
await Telemetry.sendTelemetry("api_key_created");
|
|
|
|
await EventLogs.logEvent(
|
|
|
|
"api_key_created",
|
|
|
|
{ createdBy: user?.username },
|
|
|
|
user?.id
|
|
|
|
);
|
2023-08-24 04:15:07 +02:00
|
|
|
return response.status(200).json({
|
|
|
|
apiKey,
|
|
|
|
error,
|
|
|
|
});
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
app.delete(
|
|
|
|
"/admin/delete-api-key/:id",
|
2024-01-22 23:14:01 +01:00
|
|
|
[validatedRequest, strictMultiUserRoleValid([ROLES.admin])],
|
2023-08-24 04:15:07 +02:00
|
|
|
async (request, response) => {
|
|
|
|
try {
|
|
|
|
const { id } = request.params;
|
2023-09-28 23:00:03 +02:00
|
|
|
await ApiKey.delete({ id: Number(id) });
|
[FEAT] Automated audit logging (#667)
* WIP event logging - new table for events and new settings view for viewing
* WIP add logging
* UI for log rows
* rename files to Logging to prevent getting gitignore
* add metadata for all logging events and colored badges in logs page
* remove unneeded comment
* cleanup namespace for logging
* clean up backend calls
* update logging to show to => from settings changes
* add logging for invitations, created, deleted, and accepted
* add logging for user created, updated, suspended, or removed
* add logging for workspace deleted
* add logging for chat logs exported
* add logging for API keys, LLM, embedder, vector db, embed chat, and reset button
* modify event logs
* update to event log types
* simplify rendering of event badges
---------
Co-authored-by: timothycarambat <rambat1010@gmail.com>
2024-02-07 00:21:40 +01:00
|
|
|
|
|
|
|
await EventLogs.logEvent(
|
|
|
|
"api_key_deleted",
|
|
|
|
{ deletedBy: response.locals?.user?.username },
|
|
|
|
response?.locals?.user?.id
|
|
|
|
);
|
2023-08-24 04:15:07 +02:00
|
|
|
return response.status(200).end();
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
response.sendStatus(500).end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
2023-07-25 19:37:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = { adminEndpoints };
|