feat: implement multi-factor authentication (MFA) setup and verification flow

- Add SecurityPage component for managing MFA settings, including enrollment and verification.
- Create MfaLoginGate to handle MFA verification state during login.
- Develop MfaVerificationPopup for user input of verification codes.
- Implement VerifyMfaPage for the MFA verification process after login.
- Introduce reusable VerificationCodeInput component for entering verification codes.
- Integrate Supabase MFA API for managing factors and verification.
- Add loading states and error handling for a better user experience.
This commit is contained in:
willchen96 2026-06-10 03:48:08 +08:00
parent 15c96b0dd4
commit 3a10943200
32 changed files with 3704 additions and 311 deletions

View file

@ -15,6 +15,7 @@ import {
import { docxToPdf, convertedPdfKey } from "../lib/convert";
import { checkProjectAccess } from "../lib/access";
import { singleFileUpload } from "../lib/upload";
import { deleteUserProjects } from "../lib/userDataCleanup";
export const projectsRouter = Router();
const ALLOWED_TYPES = new Set(["pdf", "docx", "doc"]);
@ -345,13 +346,15 @@ projectsRouter.delete("/:projectId", requireAuth, async (req, res) => {
const userId = res.locals.userId as string;
const { projectId } = req.params;
const db = createServerSupabase();
const { error } = await db
.from("projects")
.delete()
.eq("id", projectId)
.eq("user_id", userId);
if (error) return void res.status(500).json({ detail: error.message });
res.status(204).send();
try {
const deletedCount = await deleteUserProjects(db, userId, [projectId]);
if (deletedCount === 0)
return void res.status(404).json({ detail: "Project not found" });
res.status(204).send();
} catch (err) {
const detail = err instanceof Error ? err.message : String(err);
res.status(500).json({ detail });
}
});
// GET /projects/:projectId/documents