security: WS membership check, rate limiting, Zod WS validation, remove /repair
- WebSocket upgrade now verifies user is member of the household (prevents cross-household access) - Rate limiting: invite/join 10/h, scanner 50/h, auth sign-in 10/min - WebSocket commands validated via Zod discriminatedUnion (no unsafe cast) - Removed /repair endpoint (dev artifact, bypassed tenant middleware) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -31,9 +31,12 @@ export type ShoppingServerEvent =
|
||||
| { type: "sync"; items: ShoppingItem[] };
|
||||
|
||||
// WebSocket command types sent from client → server
|
||||
export type ShoppingClientCommand =
|
||||
| { type: "item:add"; label: string; quantity?: string }
|
||||
| { type: "item:check"; itemId: string }
|
||||
| { type: "item:uncheck"; itemId: string }
|
||||
| { type: "item:delete"; itemId: string }
|
||||
| { type: "item:clear" };
|
||||
export const shoppingClientCommandSchema = z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("item:add"), label: z.string().min(1), quantity: z.string().optional() }),
|
||||
z.object({ type: z.literal("item:check"), itemId: z.string() }),
|
||||
z.object({ type: z.literal("item:uncheck"), itemId: z.string() }),
|
||||
z.object({ type: z.literal("item:delete"), itemId: z.string() }),
|
||||
z.object({ type: z.literal("item:clear") }),
|
||||
]);
|
||||
|
||||
export type ShoppingClientCommand = z.infer<typeof shoppingClientCommandSchema>;
|
||||
|
||||
Reference in New Issue
Block a user