feat(security): implement CSRF protection

This commit is contained in:
AdrianAcala
2025-12-21 02:47:14 -08:00
parent e75b727a5a
commit 8a78b2bb2e
25 changed files with 1157 additions and 580 deletions
+11 -12
View File
@@ -1,6 +1,5 @@
import { test, expect, type BrowserContext, type Page } from "@playwright/test";
import { test, expect } from "@playwright/test";
import {
API_URL,
createDrawing,
deleteDrawing,
getDrawing,
@@ -22,7 +21,7 @@ test.describe("Real-time Collaboration", () => {
for (const id of createdDrawingIds) {
try {
await deleteDrawing(request, id);
} catch (e) {
} catch {
// Ignore cleanup errors
}
}
@@ -63,7 +62,7 @@ test.describe("Real-time Collaboration", () => {
// At least one page should show the other user
const hasCollaborator1 = await collaboratorIndicator1.count();
const hasCollaborator2 = await collaboratorIndicator2.count();
// Socket.io presence should eventually show users
// This test validates the socket connection works
expect(hasCollaborator1 + hasCollaborator2).toBeGreaterThanOrEqual(0);
@@ -75,7 +74,7 @@ test.describe("Real-time Collaboration", () => {
test("should sync drawing changes between two users", async ({ browser, request }) => {
// Create a test drawing
const drawing = await createDrawing(request, {
const drawing = await createDrawing(request, {
name: `Collab_Sync_${Date.now()}`,
elements: [],
});
@@ -121,10 +120,10 @@ test.describe("Real-time Collaboration", () => {
// Verify the drawing was saved (via API)
const updatedDrawing = await getDrawing(request, drawing.id);
// The drawing should have elements now
const elements = updatedDrawing.elements || [];
// Element sync happens via socket and periodic save
// The test validates the drawing flow works end-to-end
expect(elements).toBeDefined();
@@ -136,7 +135,7 @@ test.describe("Real-time Collaboration", () => {
test("should persist drawing changes across page reload", async ({ page, request }) => {
// Create a test drawing
const drawing = await createDrawing(request, {
const drawing = await createDrawing(request, {
name: `Collab_Persist_${Date.now()}`,
elements: [],
});
@@ -149,7 +148,7 @@ test.describe("Real-time Collaboration", () => {
// Draw something - use the interactive canvas layer
const canvas = page.locator("canvas.excalidraw__canvas.interactive");
// Select rectangle tool
await page.keyboard.press("r");
await page.waitForTimeout(200);
@@ -157,7 +156,7 @@ test.describe("Real-time Collaboration", () => {
// Draw a rectangle - click on the interactive canvas
const box = await canvas.boundingBox();
if (!box) throw new Error("Canvas not found");
await page.mouse.move(box.x + 150, box.y + 150);
await page.mouse.down();
await page.mouse.move(box.x + 350, box.y + 250, { steps: 5 });
@@ -205,7 +204,7 @@ test.describe("Real-time Collaboration", () => {
const canvas1 = page1.locator("canvas.excalidraw__canvas.interactive");
const box = await canvas1.boundingBox();
if (!box) throw new Error("Canvas not found");
await page1.mouse.move(box.x + 300, box.y + 300);
await page1.waitForTimeout(500);
await page1.mouse.move(box.x + 400, box.y + 400);
@@ -214,7 +213,7 @@ test.describe("Real-time Collaboration", () => {
// The cursor position should be broadcasted to page2
// Excalidraw shows collaborator cursors with names
// This test validates the socket connection for cursor sync
// Wait for potential cursor updates
await page2.waitForTimeout(1000);