React SDK (@aurisid/react)

Componentes y hooks pre-construidos de Auris para aplicaciones React.

📦 Versión actual: 0.7.0 | Ver en npm

Instalación

npm install @aurisid/react
# o
yarn add @aurisid/react
# o
pnpm add @aurisid/react

Bot Protection (Opcional)

Para soporte de protección contra bots con Cloudflare Turnstile:

npm install @marsidev/react-turnstile

Configuración

1. Agregar Provider

Envuelve tu aplicación con AurisProvider:

// main.tsx (Vite) o index.tsx (CRA)
import React from 'react';
import ReactDOM from 'react-dom/client';
import { AurisProvider } from '@aurisid/react';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <AurisProvider apiUrl="https://api.aurisid.com">
      <App />
    </AurisProvider>
  </React.StrictMode>
);

2. Agregar Banner de Impersonación (Opcional)

Para soporte de impersonación de usuarios por administradores:

import { AurisProvider, ImpersonationBanner } from '@aurisid/react';

<AurisProvider apiUrl="https://api.aurisid.com">
  <ImpersonationBanner />
  <App />
</AurisProvider>

Componentes de Autenticación

<SignIn />

Formulario completo de inicio de sesión con:

  • Email/contraseña
  • Login social (Google, GitHub)
  • Enlace de "Olvidé mi contraseña"
  • Protección automática contra bots (si está habilitado)
import { SignIn } from '@aurisid/react';

function SignInPage() {
  return (
    <div className="auth-container">
      <SignIn
        redirectUrl="/dashboard"
        signUpUrl="/sign-up"
        forgotPasswordUrl="/forgot-password"
        appearance={{ baseColor: '#4f46e5' }}
        onSuccess={(user) => console.log('Usuario autenticado:', user)}
      />
    </div>
  );
}

<SignUp />

Formulario completo de registro con:

  • Campos de nombre y apellido
  • Email/contraseña
  • Registro social (Google, GitHub)
  • Checkbox de términos y condiciones
  • Detección automática de contraseñas filtradas
  • Protección automática contra bots (si está habilitado)
import { SignUp } from '@aurisid/react';

function SignUpPage() {
  return (
    <div className="auth-container">
      <SignUp
        redirectUrl="/dashboard"
        signInUrl="/sign-in"
        appearance={{ baseColor: '#4f46e5' }}
        onSuccess={(user) => console.log('Cuenta creada:', user)}
      />
    </div>
  );
}

<MagicLink />

Autenticación sin contraseña mediante enlaces mágicos:

import { MagicLink } from '@aurisid/react';

function MagicLinkPage() {
  return (
    <div className="auth-container">
      <MagicLink
        redirectUrl="/dashboard"
        callbackUrl="https://myapp.com/magic-link/verify"
        appearance={{ baseColor: '#8b5cf6' }}
        onSent={(email) => console.log('Enlace enviado a:', email)}
      />
    </div>
  );
}

<UserButton />

Avatar de usuario con menú desplegable:

import { UserButton } from '@aurisid/react';

function Header() {
  return (
    <header>
      <nav>
        <Logo />
        <UserButton showName afterSignOutUrl="/" />
      </nav>
    </header>
  );
}

<SignInButton /> y <SignUpButton />

Botones que redirigen a las páginas de autenticación:

import { SignInButton, SignUpButton } from '@aurisid/react';

function LandingPage() {
  return (
    <div>
      <SignInButton>
        Iniciar sesión
      </SignInButton>
      <SignUpButton>
        Crear cuenta gratis
      </SignUpButton>
    </div>
  );
}

<SignedIn /> y <SignedOut />

Wrappers condicionales basados en el estado de autenticación:

import { SignedIn, SignedOut, UserButton, SignInButton } from '@aurisid/react';

function Header() {
  return (
    <header>
      <SignedOut>
        <SignInButton />
      </SignedOut>

      <SignedIn>
        <UserButton showName />
      </SignedIn>
    </header>
  );
}

<ImpersonationBanner />

Banner que se muestra cuando un admin está impersonando a otro usuario:

import { AurisProvider, ImpersonationBanner } from '@aurisid/react';

// En tu layout principal
<AurisProvider apiUrl="https://api.aurisid.com">
  <ImpersonationBanner position="top" />
  <App />
</AurisProvider>

Hooks

useAuris()

Hook principal para acceder al estado de autenticación:

import { useAuris } from '@aurisid/react';

function ProtectedComponent() {
  const {
    user,
    isSignedIn,
    isLoaded,
    signOut,
    isImpersonating,
    impersonator,
    impersonate,
    exitImpersonation
  } = useAuris();

  if (!isLoaded) {
    return <div>Cargando...</div>;
  }

  if (!isSignedIn) {
    return <Navigate to="/sign-in" />;
  }

  return (
    <div>
      <p>Bienvenido, {user.firstName || user.email}</p>

      {isImpersonating && (
        <div className="alert">
          Viendo como {user.email} (originalmente {impersonator?.email})
          <button onClick={exitImpersonation}>Salir</button>
        </div>
      )}

      <button onClick={signOut}>Cerrar sesión</button>
    </div>
  );
}

Valores retornados:

  • user: Objeto del usuario actual o null
  • isSignedIn: Boolean indicando si hay sesión activa
  • isLoaded: Boolean indicando si el estado ya se cargó
  • signOut(): Función para cerrar sesión
  • isImpersonating: Boolean indicando si es una sesión de impersonación
  • impersonator: Usuario admin original (cuando hay impersonación)
  • impersonate(userId): Función para impersonar a otro usuario (solo admins)
  • exitImpersonation(): Función para salir del modo impersonación

useMagicLink()

Hook para verificar enlaces mágicos en páginas de callback:

import { useMagicLink } from '@aurisid/react';

function MagicLinkVerifyPage() {
  const { loading, error, success, user } = useMagicLink({
    redirectUrl: '/dashboard',
    onSuccess: (user) => console.log('Usuario verificado:', user),
  });

  if (loading) {
    return (
      <div>
        <h2>Verificando tu enlace mágico...</h2>
        <p>Por favor espera</p>
      </div>
    );
  }

  if (error) {
    return (
      <div>
        <h2>Error de verificación</h2>
        <p>{error}</p>
        <a href="/sign-in">Intentar de nuevo</a>
      </div>
    );
  }

  if (success) {
    return (
      <div>
        <h2>¡Éxito!</h2>
        <p>Redirigiendo al dashboard...</p>
      </div>
    );
  }

  return null;
}

Proteger Rutas

Con React Router

import { useAuris } from '@aurisid/react';
import { Navigate, Outlet } from 'react-router-dom';

function ProtectedRoute() {
  const { isLoaded, isSignedIn } = useAuris();

  if (!isLoaded) {
    return <div>Cargando...</div>;
  }

  if (!isSignedIn) {
    return <Navigate to="/sign-in" replace />;
  }

  return <Outlet />;
}

// En tu router
<Routes>
  <Route path="/sign-in" element={<SignInPage />} />
  <Route path="/sign-up" element={<SignUpPage />} />
  <Route path="/magic-link" element={<MagicLinkPage />} />
  <Route path="/magic-link/verify" element={<MagicLinkVerifyPage />} />

  <Route element={<ProtectedRoute />}>
    <Route path="/dashboard" element={<Dashboard />} />
    <Route path="/settings" element={<Settings />} />
  </Route>
</Routes>

Características de Seguridad

🔐 Protección contra Bots (Turnstile)

Los componentes <SignIn /> y <SignUp /> detectan automáticamente si tu backend tiene protección contra bots habilitada y muestran el captcha de Cloudflare Turnstile cuando es necesario.

# Instalar dependencia opcional
npm install @marsidev/react-turnstile

# Los componentes detectan automáticamente si está instalado
# y si el backend lo requiere

🔑 Detección de Contraseñas Filtradas

El componente <SignUp /> valida automáticamente que las contraseñas no hayan sido filtradas en brechas de seguridad conocidas y muestra un error si la contraseña está comprometida.

👥 Impersonación de Usuarios (Admin)

Los administradores pueden impersonar usuarios para debugging y soporte, con un banner visible que indica claramente el modo impersonación:

import { useAuris } from '@aurisid/react';

function AdminUserList({ users }) {
  const { impersonate } = useAuris();

  const handleViewAsUser = async (userId: string) => {
    try {
      await impersonate(userId);
      // La página se recarga con la sesión del usuario impersonado
    } catch (error) {
      console.error('Error al impersonar:', error);
    }
  };

  return (
    <div>
      {users.map(user => (
        <div key={user.id}>
          <span>{user.email}</span>
          <button onClick={() => handleViewAsUser(user.id)}>
            Ver como usuario
          </button>
        </div>
      ))}
    </div>
  );
}

🪄 Magic Links (Passwordless)

Autenticación sin contraseña mediante enlaces seguros enviados por email. Los enlaces expiran en 15 minutos y son de un solo uso.

Llamadas a tu API

El token de autenticación se guarda automáticamente en localStorage como auris_token:

function Dashboard() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const token = localStorage.getItem('auris_token');

      const response = await fetch('https://api.tuapp.com/data', {
        headers: {
          'Authorization': `Bearer ${token}`,
        },
      });

      const result = await response.json();
      setData(result);
    };

    fetchData();
  }, []);

  return <div>{/* Renderizar datos */}</div>;
}

Organizations

Auris proporciona soporte completo para multi-tenancy con organizaciones:

<OrganizationSwitcher />

Dropdown para cambiar entre organizaciones y crear nuevas:

import { OrganizationSwitcher } from '@aurisid/react';

function Navbar() {
  return (
    <nav>
      <OrganizationSwitcher
        showCreateOrganization={true}
        organizationProfileUrl="/settings/organization"
      />
    </nav>
  );
}

<OrganizationProfile />

Página completa de configuración de organización:

import { OrganizationProfile } from '@aurisid/react';

function SettingsPage() {
  return (
    <OrganizationProfile
      organizationId="org_123"
      onUpdate={() => console.log('Actualizado!')}
      onDelete={() => window.location.href = '/'}
    />
  );
}

<OrganizationMembers />

Gestión de miembros, roles e invitaciones:

import { OrganizationMembers } from '@aurisid/react';

function MembersPage() {
  return (
    <OrganizationMembers
      organizationId="org_123"
      showInvitations={true}
    />
  );
}

Hooks de Organizations

useOrganizationList()

import { useOrganizationList } from '@aurisid/react';

function MyComponent() {
  const {
    organizations,        // Array de organizaciones
    activeOrganization,   // ID de org activa
    isLoading,
    error,
    createOrganization,   // Crear nueva org
    setActiveOrganization, // Cambiar org activa
    reloadOrganizations   // Refrescar lista
  } = useOrganizationList();

  const handleCreate = async () => {
    await createOrganization({
      name: 'Mi Organización',
      slug: 'mi-org',
      description: 'Descripción opcional'
    });
  };

  return (
    <div>
      {organizations.map(org => (
        <button
          key={org.id}
          onClick={() => setActiveOrganization(org.id)}
        >
          {org.name}
        </button>
      ))}
    </div>
  );
}

useOrganization()

import { useOrganization } from '@aurisid/react';

function OrgManager() {
  const {
    organization,        // Objeto organization
    members,            // Array de miembros
    invitations,        // Invitaciones pendientes
    isLoading,
    error,
    updateOrganization, // Actualizar org
    deleteOrganization, // Eliminar org
    loadMembers,        // Refrescar miembros
    inviteMember,       // Invitar por email
    updateMemberRole,   // Cambiar rol
    removeMember,       // Remover miembro
    loadInvitations,    // Refrescar invitaciones
    cancelInvitation    // Cancelar invitación
  } = useOrganization({
    organizationId: 'org_123'
  });

  const handleInvite = async () => {
    await inviteMember({
      email: 'user@example.com',
      role: 'member' // 'owner' | 'admin' | 'member'
    });
  };

  return (
    <div>
      <h1>{organization?.name}</h1>
      <p>{members.length} miembros</p>
      <button onClick={handleInvite}>Invitar</button>
    </div>
  );
}

💡 Demo interactiva: Ver demos de Organizations →

Multi-Factor Authentication (MFA)

Auris proporciona componentes completos de MFA con TOTP y códigos de respaldo:

<MFASetup />

Wizard completo para configurar MFA (QR code + backup codes + verificación):

import { MFASetup } from '@aurisid/react';

function SecurityPage() {
  return (
    <MFASetup
      onEnabled={() => {
        console.log('MFA enabled successfully');
        // Redirigir o mostrar éxito
      }}
      onCancel={() => {
        console.log('Setup cancelled');
      }}
    />
  );
}

<MFAVerify />

Componente de verificación para el flujo de signin:

import { MFAVerify } from '@aurisid/react';

function SignInPage() {
  const [challengeToken, setChallengeToken] = useState<string | null>(null);

  // Después del signin, si requiresMFA: true
  if (challengeToken) {
    return (
      <MFAVerify
        challengeToken={challengeToken}
        onSuccess={() => {
          console.log('MFA verified');
          // La página se recarga automáticamente
        }}
        onCancel={() => setChallengeToken(null)}
      />
    );
  }

  return <SignInForm onSubmit={handleSignIn} />;
}

<MFAManage />

Interfaz completa de gestión de MFA para configuración del usuario:

import { MFAManage } from '@aurisid/react';

function SecuritySettingsPage() {
  return (
    <MFAManage
      onEnabled={() => console.log('MFA enabled')}
      onDisabled={() => console.log('MFA disabled')}
    />
  );
}

Hook useMFA()

Hook para gestionar MFA programáticamente:

import { useMFA } from '@aurisid/react';

function CustomMFAFlow() {
  const {
    setupData,      // QR code y backup codes
    status,         // Estado de MFA
    setupTOTP,      // Iniciar setup
    enableTOTP,     // Habilitar con código
    disableTOTP,    // Deshabilitar con código
    getStatus,      // Refrescar estado
    verifyMFA       // Verificar durante signin
  } = useMFA();

  const handleSetup = async () => {
    const setup = await setupTOTP();
    console.log('QR:', setup.qrCode);
    console.log('Backup codes:', setup.backupCodes);

    // Después de que el usuario escanee el QR
    await enableTOTP('123456'); // Código del usuario
  };

  return (
    <div>
      <button onClick={handleSetup}>Setup MFA</button>
      {status?.totpEnabled && (
        <p>MFA habilitado. {status.backupCodesCount} códigos restantes</p>
      )}
    </div>
  );
}

💡 Demo interactiva: Ver demos de MFA →

Session Management

Gestiona todas las sesiones activas del usuario:

<SessionList />

Componente completo para visualizar y gestionar sesiones activas:

import { SessionList } from '@aurisid/react';

function SecurityPage() {
  return (
    <SessionList
      onSessionRevoked={(sessionId) => {
        console.log('Session revoked:', sessionId);
      }}
      onAllOthersRevoked={() => {
        console.log('All other sessions revoked');
      }}
    />
  );
}

Hook useSessions()

Hook para gestionar sesiones programáticamente:

import { useSessions } from '@aurisid/react';

function CustomSessionManager() {
  const {
    sessions,         // List of active sessions
    isLoading,
    error,
    getSessions,      // Load sessions
    revokeSession,    // Revoke a specific session
    revokeAllOtherSessions  // Revoke all except current
  } = useSessions();

  useEffect(() => {
    getSessions();
  }, []);

  const handleRevoke = async (sessionId: string) => {
    try {
      await revokeSession(sessionId);
      console.log('Session revoked');
    } catch (err) {
      console.error('Failed to revoke session');
    }
  };

  return (
    <div>
      {sessions?.map((session) => (
        <div key={session.id}>
          <p>{session.device?.browser} on {session.device?.os}</p>
          <p>Last activity: {new Date(session.lastActivityAt).toLocaleString()}</p>
          {!session.isCurrent && (
            <button onClick={() => handleRevoke(session.id)}>
              Revoke
            </button>
          )}
        </div>
      ))}
    </div>
  );
}

💡 Demo interactiva: Ver demo de Sessions →

Webhooks

Configura webhooks para recibir eventos en tiempo real:

<WebhookList />

Componente completo para gestionar webhooks con CRUD:

import { WebhookList } from '@aurisid/react';

function DeveloperSettingsPage() {
  return (
    <WebhookList
      onWebhookCreated={(webhook) => {
        console.log('Webhook created:', webhook);
      }}
      onWebhookUpdated={(webhook) => {
        console.log('Webhook updated:', webhook);
      }}
      onWebhookDeleted={(webhookId) => {
        console.log('Webhook deleted:', webhookId);
      }}
    />
  );
}

Hook useWebhooks()

Hook para gestionar webhooks programáticamente:

import { useWebhooks } from '@aurisid/react';

function CustomWebhookManager() {
  const {
    webhooks,         // List of webhooks
    isLoading,
    error,
    getWebhooks,      // Load webhooks
    createWebhook,    // Create new webhook
    updateWebhook,    // Update existing webhook
    deleteWebhook,    // Delete webhook
    testWebhook,      // Send test event
    regenerateSecret  // Regenerate secret
  } = useWebhooks();

  useEffect(() => {
    getWebhooks();
  }, []);

  const handleCreate = async () => {
    try {
      const webhook = await createWebhook({
        url: 'https://example.com/webhooks',
        events: ['user.created', 'user.updated'],
        description: 'User sync webhook'
      });
      console.log('Webhook created:', webhook);
    } catch (err) {
      console.error('Failed to create webhook');
    }
  };

  return (
    <div>
      <button onClick={handleCreate}>Create Webhook</button>
      {webhooks?.map((webhook) => (
        <div key={webhook.id}>
          <p>{webhook.url}</p>
          <p>Events: {webhook.events.join(', ')}</p>
          <p>Status: {webhook.active ? 'Active' : 'Inactive'}</p>
        </div>
      ))}
    </div>
  );
}

Eventos disponibles: user.created, user.updated, user.deleted, session.created, session.revoked, organization.created, organization.updated, organization.deleted, organization.member.added, organization.member.removed, organization.member.role_updated

💡 Demo interactiva: Ver demo de Webhooks →

Products (Multi-tenancy)

Sistema completo de multi-tenancy para gestionar productos/aplicaciones, suscripciones y licencias:

Flujo típico: Producto (OxideFlow) → Organización suscribe → Admin asigna asientos → Usuario verifica acceso

<ProductList />

Lista de productos disponibles con CRUD para administradores:

import { ProductList } from '@aurisid/react';

function AdminProductsPage() {
  return (
    <ProductList
      showCreate={true}  // Mostrar botón de crear (admin)
      onSelect={(product) => {
        console.log('Selected:', product);
        // Navegar a detalles del producto
      }}
    />
  );
}

<ProductSubscriptionManager />

Gestiona qué organizaciones tienen acceso a qué productos:

import { ProductSubscriptionManager } from '@aurisid/react';

// Ver productos de una organización
function OrgProductsPage({ organizationId }) {
  return (
    <ProductSubscriptionManager
      organizationId={organizationId}
      mode="organization"
      onSelect={(subscription) => {
        // Ver detalles de suscripción
      }}
    />
  );
}

// Ver organizaciones suscritas a un producto
function ProductSubscribersPage({ productId }) {
  return (
    <ProductSubscriptionManager
      productId={productId}
      mode="product"
    />
  );
}

<ProductSeatManager />

Asigna y gestiona licencias/asientos de usuarios dentro de una suscripción:

import { ProductSeatManager } from '@aurisid/react';

function ManageSeatsPage({ subscriptionId, maxSeats }) {
  return (
    <ProductSeatManager
      subscriptionId={subscriptionId}
      maxSeats={maxSeats}  // Muestra disponibilidad
      onSelect={(seat) => {
        console.log('Seat selected:', seat);
      }}
    />
  );
}

Hooks de Products

useProducts()

CRUD completo de productos:

import { useProducts } from '@aurisid/react';

function AdminProducts() {
  const {
    products,
    loading,
    error,
    getProducts,
    getProduct,
    getProductBySlug,
    createProduct,
    updateProduct,
    deleteProduct
  } = useProducts();

  const handleCreate = async () => {
    await createProduct({
      name: 'MediScribe',
      slug: 'mediscribe',
      description: 'AI-powered medical transcription',
      logoUrl: 'https://...',
      websiteUrl: 'https://mediscribe.app'
    });
  };

  return (
    <div>
      <button onClick={handleCreate}>Crear Producto</button>
      {products.map(p => <div key={p.id}>{p.name}</div>)}
    </div>
  );
}

useProductSubscriptions()

Gestionar suscripciones de organizaciones a productos:

import { useProductSubscriptions } from '@aurisid/react';

function SubscriptionManager() {
  const {
    subscriptions,
    loading,
    error,
    getProductSubscriptions,    // Orgs suscritas a un producto
    getOrganizationProducts,    // Productos de una org
    subscribe,                  // Suscribir org a producto
    updateSubscription,
    cancelSubscription
  } = useProductSubscriptions();

  const handleSubscribe = async () => {
    await subscribe('product_123', {
      organizationId: 'org_456',
      plan: 'pro',
      maxSeats: 10,
      expiresAt: '2025-12-31T00:00:00Z'
    });
  };

  return (/* ... */);
}

useProductSeats()

Gestionar asientos/licencias de usuarios:

import { useProductSeats } from '@aurisid/react';

function SeatManager({ subscriptionId }) {
  const {
    seats,
    loading,
    error,
    getSeats,
    assignSeat,
    updateSeat,
    removeSeat
  } = useProductSeats();

  const handleAssign = async () => {
    await assignSeat(subscriptionId, {
      userId: 'user_789',
      role: 'admin',
      permissions: { canEdit: true, canExport: true }
    });
  };

  return (/* ... */);
}

useMyProducts()

Obtener productos del usuario actual y verificar acceso (lo más importante para tu app):

import { useMyProducts } from '@aurisid/react';

function App() {
  const {
    products,           // Productos a los que tengo acceso
    loading,
    error,
    getMyProducts,      // Cargar mis productos
    checkAccess,        // Verificar acceso a un producto específico
    hasAccess,          // Verificación síncrona (de caché)
    getProductAccess    // Obtener detalles de acceso
  } = useMyProducts({ autoLoad: true });

  // Verificación síncrona (después de cargar)
  if (hasAccess('mediscribe')) {
    return <MediScribeApp />;
  }

  // O verificación asíncrona
  const handleCheckAccess = async () => {
    const access = await checkAccess('mediscribe');
    if (access.hasAccess) {
      console.log('Role:', access.seat?.role);
      console.log('Permissions:', access.seat?.permissions);
      // Mostrar app con permisos según rol
    } else {
      console.log('No access:', access.reason);
      // Mostrar mensaje de "Contacta a tu admin"
    }
  };

  return <button onClick={handleCheckAccess}>Verificar Acceso</button>;
}

Ejemplo: Proteger una App por Producto

import { useMyProducts } from '@aurisid/react';

function ProductGate({ slug, children, fallback }) {
  const { hasAccess, loading } = useMyProducts({ autoLoad: true });

  if (loading) return <div>Verificando acceso...</div>;

  if (!hasAccess(slug)) {
    return fallback || (
      <div>
        <h2>Acceso Denegado</h2>
        <p>No tienes acceso a esta aplicación.</p>
        <p>Contacta a tu administrador para solicitar una licencia.</p>
      </div>
    );
  }

  return children;
}

// Uso
function MediScribePage() {
  return (
    <ProductGate slug="mediscribe">
      <MediScribeApp />
    </ProductGate>
  );
}

💡 Demo interactiva: Ver demo de Products →

TypeScript

Todos los componentes y hooks están completamente tipados:

import type {
  AurisUser,
  AurisContextValue,
  SignInProps,
  SignUpProps,
  MagicLinkProps,
  ImpersonationBannerProps,
  MagicLinkVerifyResult,
  UseMagicLinkOptions,
  // Organization types
  Organization,
  OrganizationMember,
  OrganizationInvitation,
  OrganizationRole,
  OrganizationSwitcherProps,
  OrganizationProfileProps,
  OrganizationMembersProps,
  // MFA types
  MFASetupResponse,
  MFAStatus,
  MFAVerifyParams,
  MFAVerifyResponse,
  MFASetupProps,
  MFAVerifyProps,
  MFAManageProps,
  // Session types
  Session,
  SessionsListResponse,
  SessionListProps,
  // Webhook types
  Webhook,
  WebhookEventType,
  WebhookDelivery,
  WebhookListProps,
  // Product types (Multi-tenancy)
  Product,
  OrganizationProduct,
  ProductSeat,
  ProductAccess,
  CreateProductRequest,
  SubscribeOrganizationRequest,
  AssignSeatRequest,
  ProductListProps,
  ProductSubscriptionManagerProps,
  ProductSeatManagerProps
} from '@aurisid/react';

// Ejemplo de tipo AurisUser
interface AurisUser {
  id: string;
  email: string;
  emailVerified: boolean;
  username?: string;
  firstName?: string;
  lastName?: string;
  avatarUrl?: string;
}

Personalización

Apariencia con baseColor

<SignIn
  appearance={{
    baseColor: '#10b981' // Verde
  }}
/>

<SignUp
  appearance={{
    baseColor: '#8b5cf6' // Púrpura
  }}
/>

<MagicLink
  appearance={{
    baseColor: '#ef4444' // Rojo
  }}
/>

CSS Classes

Cada componente tiene una clase CSS para personalización:

  • .auris-user-button
  • .auris-sign-in
  • .auris-sign-up
  • .auris-magic-link
  • .auris-impersonation-banner
  • .auris-org-switcher
  • .auris-org-profile
  • .auris-org-members