feat(workspace): integrate persisted canvas, element editing and session renewal
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import { sessionCookie, sessionMaxAge, SESSION_EXPIRY_HEADER } from "@/lib/session-cookie";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
const allowed =
|
||||
/^(profile|auth\/(login|register|verify-email|exchange|me|logout)|workspaces(?:\/[a-zA-Z0-9_-]+(?:\/(?:materials|search)(?:\/[a-zA-Z0-9_-]+)?)?)?)$/;
|
||||
/^(profile|auth\/(login|register|verify-email|exchange|me|logout)|workspaces(?:\/[a-zA-Z0-9_-]+(?:\/(?:materials(?:\/[a-zA-Z0-9_-]+(?:\/canvas)?)?|search))?)?)$/;
|
||||
const bodyLimit = 1024 * 1024;
|
||||
|
||||
// Route Handlers do not have the Pages Router bodyParser size limit.
|
||||
async function readBody(req: NextRequest) {
|
||||
async function readBody(req: NextRequest, limit = bodyLimit) {
|
||||
const reader = req.body?.getReader();
|
||||
if (!reader) return {};
|
||||
const chunks: Uint8Array[] = [];
|
||||
@@ -15,7 +16,7 @@ async function readBody(req: NextRequest) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
size += value.byteLength;
|
||||
if (size > bodyLimit) {
|
||||
if (size > limit) {
|
||||
await reader.cancel();
|
||||
throw new Error("body_too_large");
|
||||
}
|
||||
@@ -49,7 +50,7 @@ async function handler(
|
||||
let requestBody: unknown;
|
||||
if (req.method !== "GET") {
|
||||
try {
|
||||
requestBody = await readBody(req);
|
||||
requestBody = await readBody(req, path.endsWith("/canvas") ? 5 * 1024 * 1024 : bodyLimit);
|
||||
} catch (error) {
|
||||
const tooLarge = error instanceof Error && error.message === "body_too_large";
|
||||
return json({ error: tooLarge ? "body_too_large" : "invalid_json" }, tooLarge ? 413 : 400);
|
||||
@@ -83,18 +84,21 @@ async function handler(
|
||||
cache: "no-store",
|
||||
},
|
||||
);
|
||||
const etag = upstream.headers.get("etag");
|
||||
if (etag) responseHeaders.set("ETag", etag);
|
||||
const headersReceived = performance.now();
|
||||
const body = upstream.status === 204 ? null : await upstream.json();
|
||||
responseHeaders.set(
|
||||
"Server-Timing",
|
||||
`upstream;dur=${(headersReceived - started).toFixed(1)}, total;dur=${(performance.now() - started).toFixed(1)}`,
|
||||
);
|
||||
const secure = process.env.NODE_ENV === "production" && req.headers.get("x-forwarded-proto") === "https";
|
||||
if (body?.access_token) {
|
||||
responseHeaders.set(
|
||||
"Set-Cookie",
|
||||
`foundry_session=${encodeURIComponent(body.access_token)}; HttpOnly; SameSite=Lax; Path=/; Max-Age=${Math.min(body.expires_in || 28800, 28800)}${process.env.NODE_ENV === "production" && req.headers.get("x-forwarded-proto") === "https" ? "; Secure" : ""}`,
|
||||
);
|
||||
responseHeaders.set("Set-Cookie", sessionCookie(body.access_token, sessionMaxAge(body.expires_in), secure));
|
||||
delete body.access_token;
|
||||
} else if (session && upstream.status !== 401) {
|
||||
const renewed = upstream.headers.get(SESSION_EXPIRY_HEADER);
|
||||
if (renewed !== null && /^\d+$/.test(renewed)) responseHeaders.set("Set-Cookie", sessionCookie(session, sessionMaxAge(renewed), secure));
|
||||
}
|
||||
if (path === "auth/logout" && upstream.ok)
|
||||
responseHeaders.set(
|
||||
|
||||
Reference in New Issue
Block a user