mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
added missing email and email test files
This commit is contained in:
parent
c921db7d9c
commit
7e9193313b
3 changed files with 81 additions and 0 deletions
|
|
@ -65,6 +65,69 @@ export async function GET(
|
|||
}
|
||||
}
|
||||
|
||||
// DELETE: remove a collaborator from this portfolio.
|
||||
export async function DELETE(
|
||||
req: NextRequest,
|
||||
props: { params: Promise<{ portfolioId: string }> }
|
||||
) {
|
||||
const { portfolioId } = await props.params;
|
||||
|
||||
const session = await getServerSession(AuthOptions);
|
||||
if (!session?.user?.dbId) {
|
||||
return NextResponse.json({ error: "Not authenticated" }, { status: 401 });
|
||||
}
|
||||
|
||||
const bodySchema = z.object({ portfolioUserId: z.string() });
|
||||
let body: z.infer<typeof bodySchema>;
|
||||
try {
|
||||
body = bodySchema.parse(await req.json());
|
||||
} catch {
|
||||
return NextResponse.json({ error: "Invalid body" }, { status: 400 });
|
||||
}
|
||||
|
||||
try {
|
||||
const pId = BigInt(portfolioId);
|
||||
const puId = BigInt(body.portfolioUserId);
|
||||
|
||||
// Refuse to remove the creator — they own the portfolio.
|
||||
const [target] = await db
|
||||
.select({ id: portfolioUsers.id, role: portfolioUsers.role })
|
||||
.from(portfolioUsers)
|
||||
.where(
|
||||
and(
|
||||
eq(portfolioUsers.id, puId),
|
||||
eq(portfolioUsers.portfolioId, pId),
|
||||
),
|
||||
)
|
||||
.limit(1);
|
||||
if (!target) {
|
||||
return NextResponse.json(
|
||||
{ error: "Membership not found in this portfolio" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
if (target.role === "creator") {
|
||||
return NextResponse.json(
|
||||
{ error: "Cannot remove the portfolio creator" },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
await db.delete(portfolioUsers).where(eq(portfolioUsers.id, puId));
|
||||
|
||||
return NextResponse.json(
|
||||
{ success: true, portfolioUserId: body.portfolioUserId },
|
||||
{ status: 200 },
|
||||
);
|
||||
} catch (err) {
|
||||
console.error("DELETE /colloborators error:", err);
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to remove user" },
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// PUT: update a collaborator’s role
|
||||
export async function PUT(
|
||||
req: NextRequest,
|
||||
|
|
|
|||
15
src/app/lib/email.test.ts
Normal file
15
src/app/lib/email.test.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { normaliseEmail } from "./email";
|
||||
|
||||
describe("normaliseEmail", () => {
|
||||
it("lowercases mixed-case addresses", () => {
|
||||
expect(normaliseEmail("Craig.Williams@Example.com")).toBe(
|
||||
"craig.williams@example.com",
|
||||
);
|
||||
});
|
||||
|
||||
it("trims surrounding whitespace (common from copy-paste into invite forms)", () => {
|
||||
expect(normaliseEmail(" user@example.com ")).toBe("user@example.com");
|
||||
expect(normaliseEmail("\tuser@example.com\n")).toBe("user@example.com");
|
||||
});
|
||||
});
|
||||
3
src/app/lib/email.ts
Normal file
3
src/app/lib/email.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export function normaliseEmail(email: string): string {
|
||||
return email.trim().toLowerCase();
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue