29 lines
2.0 KiB
TypeScript
29 lines
2.0 KiB
TypeScript
import type { Router } from "express";
|
|
import { getLocalAgentContext } from "../context/localContext.js";
|
|
import { AnswerViewStateError, AnswerViewStateStore, answerViewStateIdentitySchema } from "../sessions/answer-view-state-store.js";
|
|
import { SessionContextMismatchError, type SessionMetadataStore } from "../sessions/metadataStore.js";
|
|
|
|
export function registerAnswerViewStateRoutes(router: Router, options: { sessions: SessionMetadataStore; states: AnswerViewStateStore }) {
|
|
const handle = (method: "get" | "put") => {
|
|
router[method]("/session/:session_id/ui-state", async (req, res) => {
|
|
res.setHeader("Cache-Control", "private, no-store");
|
|
try {
|
|
const session = await options.sessions.get(getLocalAgentContext(req), req.params.session_id);
|
|
if (!session) { res.status(404).json({ code: "SESSION_NOT_FOUND", detail: "session not found" }); return; }
|
|
const context = { sessionId: session.sessionId, actorKey: session.actorKey, projectKey: session.projectKey };
|
|
if (method === "get") {
|
|
const parsed = answerViewStateIdentitySchema.safeParse(req.query);
|
|
if (!parsed.success) { res.status(400).json({ code: "ANSWER_VIEW_STATE_INVALID", detail: "invalid answer view identity" }); return; }
|
|
res.json(await options.states.get(context, parsed.data));
|
|
} else res.json(await options.states.put(context, req.body));
|
|
} catch (error) {
|
|
if (error instanceof AnswerViewStateError) { res.status(error.status).json({ code: error.code, detail: error.message, ...(error.current ? { current: error.current } : {}) }); return; }
|
|
if (error instanceof SessionContextMismatchError) { res.status(404).json({ code: "SESSION_NOT_FOUND", detail: "session not found" }); return; }
|
|
// Filesystem or corrupt record errors must not disclose host paths or saved form values.
|
|
res.status(503).json({ code: "ANSWER_VIEW_STATE_UNAVAILABLE", detail: "answer view state unavailable" });
|
|
}
|
|
});
|
|
};
|
|
handle("get"); handle("put");
|
|
}
|