// routes/api/create/lease.ts import { define } from "../../../utils.ts"; import { createLease } from "../../../services/leaseService.ts"; import { getProperty } from "../../../services/propertyService.ts"; import { SessionCookie } from "../../auth/callback.ts"; export const handler = define.handlers({ async POST(ctx) { try { const stateData: SessionCookie = ctx.state.data; const { user_id } = stateData; // Check authentication if (!user_id) { return new Response( JSON.stringify({ success: false, error: "Unauthorized: No session found", }), { status: 401, headers: { "Content-Type": "application/json" }, }, ); } const form = await ctx.req.formData(); const sender = form.get("sender"); const tenant_id = form.get("tenant_id")?.toString(); const propertyId = form.get("property_id")?.toString() || ""; const title = form.get("title")?.toString() || ""; const rent = Number(form.get("rent")); const start_date = form.get("start_date") ? Date.parse(form.get("start_date")?.toString() + "T00:00:00") : null; const end_date = form.get("end_date") ? Date.parse(form.get("end_date")?.toString() + "T00:00:00") : null; const security_deposit = Number(form.get("security_deposit")) || 0; // Validate required fields if (!propertyId) { return new Response( JSON.stringify({ success: false, error: "Property ID is required", }), { status: 400, headers: { "Content-Type": "application/json" }, }, ); } if (!start_date || !end_date || isNaN(start_date) || isNaN(end_date)) { return new Response( JSON.stringify({ success: false, error: "Valid start and end dates are required", }), { status: 400, headers: { "Content-Type": "application/json" }, }, ); } const property = await getProperty(propertyId); if (property.length !== 1) { return new Response( JSON.stringify({ success: false, error: "Property not found", }), { status: 404, headers: { "Content-Type": "application/json" }, }, ); } const owner_id = property[0].owner_id as string; // OWNERSHIP VALIDATION: Only property owner can create leases if (owner_id !== user_id) { return new Response( JSON.stringify({ success: false, error: "Forbidden: You do not own this property", details: { user_id, property_owner_id: owner_id, property_id: propertyId, }, }), { status: 403, headers: { "Content-Type": "application/json" }, }, ); } // Create lease with ownership validated await createLease( title, propertyId, owner_id, start_date, end_date, rent, security_deposit, tenant_id, ); const senderPath = sender?.toString() || "/"; let redirectUrl = senderPath; try { if (senderPath.startsWith("/")) { const url = new URL(ctx.req.url); redirectUrl = url.origin + senderPath; } } catch (_) { // fallback: just use senderPath } return Response.redirect(redirectUrl, 303); } catch (e) { console.error("Error creating lease:", e); return new Response( JSON.stringify({ success: false, error: "Internal server error", details: e instanceof Error ? e.message : String(e), }), { status: 500, headers: { "Content-Type": "application/json" }, }, ); } }, });