| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- "use client";
- import {
- useCallback,
- useEffect,
- useState,
- type ReactNode,
- } from "react";
- import { usePortalAuth } from "@/components/auth/portal-auth-provider";
- import {
- clearPortalSession,
- fetchPortalSession,
- type AuthMethod,
- } from "@/lib/portal-session";
- export type PortalIdentity = {
- isLoading: boolean;
- isSignedIn: boolean;
- label: string | null;
- source: "briven" | "demo" | "wallet" | "konnos" | null;
- userId: string | null;
- walletAddress: string | null;
- method: AuthMethod | null;
- signOut: () => Promise<void>;
- };
- /**
- * Identity for dashboard gates. Any login method (email OTP, Konnos, MetaMask,
- * later mavi) mints first-party /api/session so the user stays signed in.
- */
- export function IdentityConsumer({
- children,
- }: {
- children: (identity: PortalIdentity) => ReactNode;
- }) {
- const { brivenConfigured } = usePortalAuth();
- if (brivenConfigured) {
- return <SessionIdentityConsumer>{children}</SessionIdentityConsumer>;
- }
- return <DemoIdentityConsumer>{children}</DemoIdentityConsumer>;
- }
- function DemoIdentityConsumer({
- children,
- }: {
- children: (identity: PortalIdentity) => ReactNode;
- }) {
- const portal = usePortalAuth();
- const identity: PortalIdentity = {
- isLoading: false,
- isSignedIn: Boolean(portal.demoSession),
- label: portal.demoSession?.label ?? null,
- source: portal.demoSession?.kind ?? null,
- userId: portal.demoSession?.userId ?? null,
- walletAddress: portal.demoSession?.walletAddress ?? null,
- method: portal.demoSession?.kind === "wallet" ? "wallet" : "demo",
- signOut: async () => {
- portal.clearDemo();
- },
- };
- return <>{children(identity)}</>;
- }
- function SessionIdentityConsumer({
- children,
- }: {
- children: (identity: PortalIdentity) => ReactNode;
- }) {
- const portal = usePortalAuth();
- const [loading, setLoading] = useState(true);
- const [userId, setUserId] = useState<string | null>(null);
- const [email, setEmail] = useState<string | null>(null);
- const [method, setMethod] = useState<AuthMethod | null>(null);
- const [walletAddress, setWalletAddress] = useState<string | null>(null);
- const refresh = useCallback(async () => {
- const s = await fetchPortalSession();
- if (s.authenticated) {
- setUserId(s.userId);
- setEmail(s.email ?? null);
- setMethod(s.method ?? null);
- setWalletAddress(s.walletAddress ?? null);
- } else if (portal.demoSession) {
- setUserId(portal.demoSession.userId);
- setEmail(
- portal.demoSession.kind === "demo" ? portal.demoSession.label : null,
- );
- setMethod(
- portal.demoSession.kind === "wallet" ? "wallet" : "demo",
- );
- setWalletAddress(portal.demoSession.walletAddress ?? null);
- } else {
- setUserId(null);
- setEmail(null);
- setMethod(null);
- setWalletAddress(null);
- }
- setLoading(false);
- }, [portal.demoSession]);
- useEffect(() => {
- void refresh();
- const onFocus = () => void refresh();
- window.addEventListener("focus", onFocus);
- window.addEventListener("krypco-auth-change", onFocus);
- return () => {
- window.removeEventListener("focus", onFocus);
- window.removeEventListener("krypco-auth-change", onFocus);
- };
- }, [refresh]);
- const signedIn = Boolean(userId) || Boolean(portal.demoSession);
- const source: PortalIdentity["source"] = (() => {
- if (method === "wallet" || portal.demoSession?.kind === "wallet")
- return "wallet";
- if (method === "konnos") return "konnos";
- if (method === "demo" || portal.demoSession?.kind === "demo") return "demo";
- if (userId) return "briven";
- return null;
- })();
- const label =
- email ||
- (walletAddress
- ? `${walletAddress.slice(0, 6)}…${walletAddress.slice(-4)}`
- : null) ||
- portal.demoSession?.label ||
- userId;
- const identity: PortalIdentity = {
- isLoading: loading,
- isSignedIn: signedIn,
- label,
- source,
- userId: userId || portal.demoSession?.userId || null,
- walletAddress:
- walletAddress || portal.demoSession?.walletAddress || null,
- method:
- method ||
- (portal.demoSession?.kind === "wallet" ? "wallet" : null),
- signOut: async () => {
- try {
- await fetch("/api/auth/signout", {
- method: "POST",
- credentials: "include",
- headers: {
- "content-type": "application/json",
- rid: "session",
- },
- body: "{}",
- }).catch(() => null);
- await clearPortalSession();
- } finally {
- portal.clearDemo();
- setUserId(null);
- setEmail(null);
- setMethod(null);
- setWalletAddress(null);
- window.dispatchEvent(new Event("krypco-auth-change"));
- }
- },
- };
- return <>{children(identity)}</>;
- }
|