197 lines
5.4 KiB
JavaScript
197 lines
5.4 KiB
JavaScript
const { Memory } = require("../models/memory");
|
|
const { SystemSettings } = require("../models/systemSettings");
|
|
const { userFromSession, reqBody } = require("../utils/http");
|
|
const { validatedRequest } = require("../utils/middleware/validatedRequest");
|
|
const {
|
|
flexUserRoleValid,
|
|
ROLES,
|
|
} = require("../utils/middleware/multiUserProtected");
|
|
const { validWorkspaceSlug } = require("../utils/middleware/validWorkspace");
|
|
|
|
async function memoryFeatureEnabled(_req, response, next) {
|
|
const enabled = await SystemSettings.memoriesEnabled();
|
|
if (!enabled)
|
|
return response.status(403).json({ error: "Personalization is disabled." });
|
|
next();
|
|
}
|
|
|
|
/**
|
|
* Loads the memory by :memoryId and, in multi-user mode, scopes the query to the requester's userId.
|
|
* A memory owned by another user returns null here and is indistinguishable from "not found" — 404 either way.
|
|
*/
|
|
async function validateMemoryOwner(request, response, next) {
|
|
try {
|
|
const clause = { id: Number(request.params.memoryId) };
|
|
if (response.locals.multiUserMode) {
|
|
const user = await userFromSession(request, response);
|
|
clause.userId = user?.id ?? null;
|
|
}
|
|
|
|
const memory = await Memory.get(clause);
|
|
if (!memory)
|
|
return response.status(404).json({ error: "Memory not found." });
|
|
|
|
next();
|
|
} catch (e) {
|
|
console.error(e);
|
|
return response.sendStatus(500);
|
|
}
|
|
}
|
|
|
|
function memoryEndpoints(app) {
|
|
if (!app) return;
|
|
|
|
app.get(
|
|
"/workspaces/:slug/memories",
|
|
[
|
|
validatedRequest,
|
|
flexUserRoleValid([ROLES.all]),
|
|
memoryFeatureEnabled,
|
|
validWorkspaceSlug,
|
|
],
|
|
async (request, response) => {
|
|
try {
|
|
const user = await userFromSession(request, response);
|
|
const workspace = response.locals.workspace;
|
|
|
|
const [globalMemories, workspaceMemories] = await Promise.all([
|
|
Memory.globalForUser(user?.id),
|
|
Memory.forUserWorkspace(user?.id, workspace.id),
|
|
]);
|
|
response.status(200).json({
|
|
memories: { global: globalMemories, workspace: workspaceMemories },
|
|
});
|
|
} catch (e) {
|
|
console.error(e);
|
|
return response.sendStatus(500);
|
|
}
|
|
}
|
|
);
|
|
|
|
app.post(
|
|
"/workspaces/:slug/memories",
|
|
[
|
|
validatedRequest,
|
|
flexUserRoleValid([ROLES.all]),
|
|
memoryFeatureEnabled,
|
|
validWorkspaceSlug,
|
|
],
|
|
async (request, response) => {
|
|
try {
|
|
const user = await userFromSession(request, response);
|
|
const workspace = response.locals.workspace;
|
|
const { content, scope = "workspace" } = reqBody(request);
|
|
const { memory, message } = await Memory.create({
|
|
userId: user?.id,
|
|
workspaceId: scope === "global" ? null : workspace.id,
|
|
scope,
|
|
content: content.trim(),
|
|
});
|
|
|
|
if (!memory) return response.status(400).json({ error: message });
|
|
response.status(200).json({ memory });
|
|
} catch (e) {
|
|
console.error(e);
|
|
return response.sendStatus(500);
|
|
}
|
|
}
|
|
);
|
|
|
|
app.put(
|
|
"/memories/:memoryId",
|
|
[
|
|
validatedRequest,
|
|
flexUserRoleValid([ROLES.all]),
|
|
memoryFeatureEnabled,
|
|
validateMemoryOwner,
|
|
],
|
|
async (request, response) => {
|
|
try {
|
|
const memoryId = Number(request.params.memoryId);
|
|
const { content } = reqBody(request);
|
|
const { memory, message } = await Memory.update(memoryId, {
|
|
content: content.trim(),
|
|
});
|
|
|
|
if (!memory) return response.status(400).json({ error: message });
|
|
response.status(200).json({ memory });
|
|
} catch (e) {
|
|
console.error(e);
|
|
return response.sendStatus(500);
|
|
}
|
|
}
|
|
);
|
|
|
|
app.delete(
|
|
"/memories/:memoryId",
|
|
[
|
|
validatedRequest,
|
|
flexUserRoleValid([ROLES.all]),
|
|
memoryFeatureEnabled,
|
|
validateMemoryOwner,
|
|
],
|
|
async (request, response) => {
|
|
try {
|
|
const memoryId = Number(request.params.memoryId);
|
|
await Memory.delete(memoryId);
|
|
response.status(200).json({ success: true });
|
|
} catch (e) {
|
|
console.error(e);
|
|
return response.sendStatus(500);
|
|
}
|
|
}
|
|
);
|
|
|
|
app.post(
|
|
"/memories/:memoryId/promote",
|
|
[
|
|
validatedRequest,
|
|
flexUserRoleValid([ROLES.all]),
|
|
memoryFeatureEnabled,
|
|
validateMemoryOwner,
|
|
],
|
|
async (request, response) => {
|
|
try {
|
|
const memoryId = Number(request.params.memoryId);
|
|
const { memory, message } = await Memory.promoteToGlobal(memoryId);
|
|
if (!memory) return response.status(400).json({ error: message });
|
|
|
|
response.status(200).json({ memory });
|
|
} catch (e) {
|
|
console.error(e);
|
|
return response.sendStatus(500);
|
|
}
|
|
}
|
|
);
|
|
|
|
app.post(
|
|
"/memories/:memoryId/demote/:slug",
|
|
[
|
|
validatedRequest,
|
|
flexUserRoleValid([ROLES.all]),
|
|
memoryFeatureEnabled,
|
|
validateMemoryOwner,
|
|
validWorkspaceSlug,
|
|
],
|
|
async (request, response) => {
|
|
try {
|
|
const memoryId = Number(request.params.memoryId);
|
|
const targetWorkspace = response.locals.workspace;
|
|
|
|
const { memory, message } = await Memory.demoteToWorkspace(
|
|
memoryId,
|
|
targetWorkspace.id
|
|
);
|
|
|
|
if (!memory) return response.status(400).json({ error: message });
|
|
response.status(200).json({ memory });
|
|
} catch (e) {
|
|
console.error(e);
|
|
return response.sendStatus(500);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
module.exports = { memoryEndpoints };
|