import { disable2FASchema, enable2FACodeSchema, startVerificationSchema, verifyCodeSchema, } from "./data"; import { sValidator } from "@hono/standard-validator"; import { HonoContext } from "@/core/hono.helpers"; import { getTwofaController } from "./controller"; import { auth } from "@domains/auth/config.base"; import { Hono } from "hono"; const twofaController = getTwofaController(); export const twofaRouter = new Hono() .post("/setup", async (c) => { const res = await twofaController.setup2FA( c.env.locals.fCtx, c.env.locals.user, ); return c.json( res.isOk() ? { data: res.value, error: null } : { data: null, error: res.error }, res.isOk() ? 200 : 400, ); }) .post( "/verify-and-enable", sValidator("json", enable2FACodeSchema), async (c) => { const data = c.req.valid("json"); const res = await twofaController.verifyAndEnable2FA( c.env.locals.fCtx, c.env.locals.user, data.code, c.req.raw.headers, ); return c.json( res.isOk() ? { data: res.value, error: null } : { data: null, error: res.error }, res.isOk() ? 200 : 400, ); }, ) .get("/generate-backup-codes", async (c) => { const res = await twofaController.generateBackupCodes( c.env.locals.fCtx, c.env.locals.user, ); return c.json( res.isOk() ? { data: res.value, error: null } : { data: null, error: res.error }, res.isOk() ? 200 : 400, ); }) .delete("/disable", sValidator("json", disable2FASchema), async (c) => { const data = c.req.valid("json"); const res = await twofaController.disable( c.env.locals.fCtx, c.env.locals.user, data.code, ); return c.json( res.isOk() ? { data: res.value, error: null } : { data: null, error: res.error }, res.isOk() ? 200 : 400, ); }) .get("/requires-verification", async (c) => { const user = c.env.locals.user; const sessionId = c.req.query("sessionId")?.toString() ?? ""; const res = await twofaController.requiresInitialVerification( c.env.locals.fCtx, user, sessionId, ); return c.json( res.isOk() ? { data: res.value, error: null } : { data: null, error: res.error }, res.isOk() ? 200 : 400, ); }) .get("/requires-sensitive-action", async (c) => { const res = await twofaController.requiresSensitiveActionVerification( c.env.locals.fCtx, c.env.locals.user, ); return c.json( res.isOk() ? { data: res.value, error: null } : { data: null, error: res.error }, res.isOk() ? 200 : 400, ); }) .post( "/start-verification-session", sValidator("json", startVerificationSchema), async (c) => { const data = c.req.valid("json"); const ipAddress = c.req.header("x-forwarded-for") || c.req.header("x-real-ip") || "unknown"; const userAgent = c.req.header("user-agent") || "unknown"; const res = await twofaController.startVerification( c.env.locals.fCtx, { userId: data.userId, sessionId: data.sessionId, ipAddress, userAgent, }, ); return c.json( res.isOk() ? { data: res.value, error: null } : { data: null, error: res.error }, ); }, ) .post( "/verify-session-code", sValidator("json", verifyCodeSchema), async (c) => { const data = c.req.valid("json"); let user = c.env.locals.user; if (!user) { const out = await auth.api.getSession({ headers: c.req.raw.headers, }); user = out?.user as any; } const res = await twofaController.verifyCode( c.env.locals.fCtx, { verificationSessToken: data.verificationToken, code: data.code, }, user, ); return c.json( res.isOk() ? { data: res.value, error: null } : { data: null, error: res.error }, res.isOk() ? 200 : 400, ); }, ) .post("/cleanup-expired-sessions", async (c) => { const res = await twofaController.cleanupExpiredSessions( c.env.locals.fCtx, ); return c.json( res.isOk() ? { data: res.value, error: null } : { data: null, error: res.error }, res.isOk() ? 200 : 400, ); });