route.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /**
  2. * First-party session gate for the portal dashboard.
  3. * Used by email OTP, Konnos (after return), MetaMask, and later mavi wallet.
  4. *
  5. * GET → { authenticated, userId?, method?, email?, walletAddress? }
  6. * POST → mint krypco_uid (+ optional email / method / wallet cookies)
  7. * DELETE → clear all portal auth cookies
  8. */
  9. import { cookies } from "next/headers";
  10. import { NextRequest, NextResponse } from "next/server";
  11. import {
  12. KRYPCO_UID_COOKIE,
  13. krypcoUidCookieOptions,
  14. readCookie,
  15. signUserId,
  16. verifyUserIdToken,
  17. } from "@/lib/session-cookie";
  18. export const dynamic = "force-dynamic";
  19. const METHOD_COOKIE = "krypco_method";
  20. const EMAIL_COOKIE = "krypco_email";
  21. const WALLET_COOKIE = "krypco_wallet";
  22. export async function GET(req: NextRequest) {
  23. const jar = await cookies();
  24. const access =
  25. jar.get("sAccessToken")?.value ||
  26. readCookie(req.headers.get("cookie"), "sAccessToken");
  27. const uidTok =
  28. jar.get(KRYPCO_UID_COOKIE)?.value ||
  29. readCookie(req.headers.get("cookie"), KRYPCO_UID_COOKIE);
  30. const userId = verifyUserIdToken(uidTok);
  31. const method =
  32. jar.get(METHOD_COOKIE)?.value ||
  33. readCookie(req.headers.get("cookie"), METHOD_COOKIE);
  34. const email =
  35. jar.get(EMAIL_COOKIE)?.value ||
  36. readCookie(req.headers.get("cookie"), EMAIL_COOKIE);
  37. const walletAddress =
  38. jar.get(WALLET_COOKIE)?.value ||
  39. readCookie(req.headers.get("cookie"), WALLET_COOKIE);
  40. if (access && userId) {
  41. return NextResponse.json({
  42. authenticated: true,
  43. userId,
  44. method,
  45. email,
  46. walletAddress,
  47. engine: "briven-engine",
  48. });
  49. }
  50. if (access) {
  51. return NextResponse.json({
  52. authenticated: true,
  53. userId: userId || "session",
  54. method: method || "email",
  55. email,
  56. walletAddress,
  57. engine: "briven-engine",
  58. soft: !userId,
  59. });
  60. }
  61. if (userId) {
  62. return NextResponse.json({
  63. authenticated: true,
  64. userId,
  65. method: method || "wallet",
  66. email,
  67. walletAddress,
  68. engine: "portal",
  69. soft: true,
  70. });
  71. }
  72. return NextResponse.json({ authenticated: false });
  73. }
  74. export async function POST(req: NextRequest) {
  75. let body: {
  76. userId?: string;
  77. email?: string;
  78. method?: string;
  79. walletAddress?: string;
  80. } = {};
  81. try {
  82. body = (await req.json()) as typeof body;
  83. } catch {
  84. /* empty */
  85. }
  86. const userId = String(body.userId || "").trim();
  87. if (!userId || userId.length < 4) {
  88. return NextResponse.json(
  89. { ok: false, code: "invalid_user", message: "userId required." },
  90. { status: 400 },
  91. );
  92. }
  93. const secure =
  94. req.nextUrl.protocol === "https:" ||
  95. process.env.NODE_ENV === "production";
  96. const opts = krypcoUidCookieOptions(secure);
  97. const method = (body.method || "email").trim() || "email";
  98. const res = NextResponse.json({
  99. ok: true,
  100. userId,
  101. authenticated: true,
  102. method,
  103. email: body.email ?? null,
  104. walletAddress: body.walletAddress ?? null,
  105. });
  106. res.cookies.set(KRYPCO_UID_COOKIE, signUserId(userId), opts);
  107. res.cookies.set(METHOD_COOKIE, method, { ...opts, httpOnly: false });
  108. if (body.email?.includes("@")) {
  109. res.cookies.set(EMAIL_COOKIE, body.email.trim().toLowerCase(), {
  110. ...opts,
  111. httpOnly: false,
  112. });
  113. }
  114. if (body.walletAddress?.startsWith("0x")) {
  115. res.cookies.set(WALLET_COOKIE, body.walletAddress, {
  116. ...opts,
  117. httpOnly: false,
  118. });
  119. }
  120. return res;
  121. }
  122. export async function DELETE(req: NextRequest) {
  123. const secure =
  124. req.nextUrl.protocol === "https:" ||
  125. process.env.NODE_ENV === "production";
  126. const opts = { ...krypcoUidCookieOptions(secure), maxAge: 0 };
  127. const res = NextResponse.json({ ok: true });
  128. res.cookies.set(KRYPCO_UID_COOKIE, "", opts);
  129. res.cookies.set(EMAIL_COOKIE, "", { ...opts, httpOnly: false });
  130. res.cookies.set(METHOD_COOKIE, "", { ...opts, httpOnly: false });
  131. res.cookies.set(WALLET_COOKIE, "", { ...opts, httpOnly: false });
  132. return res;
  133. }