Core vs. React Sub-packages
Relevant source files
The following files were used as context for generating this wiki page:
The @cellarnode/auth repository is architected into two distinct layers: a framework-agnostic Core package and a specialized React sub-package. This separation allows developers to use the core authentication logic (token management, API communication, and state) in any TypeScript/JavaScript environment, while providing pre-built UI components for React-based dashboards.
The distribution of these layers is handled via package exports, where the root export @cellarnode/auth serves the Core logic and the @cellarnode/auth/react export serves the UI components and hooks.
Sources: package.json:15-24, README.md:15-32
Architecture Overview
The system follows a hierarchical dependency model where React components consume the Core logic via dependency injection. This ensures that the UI layer remains decoupled from the specific implementation of the storage and network layers.
System Hierarchy Diagram
This diagram shows the relationship between the various modules across both sub-packages.
Core Sub-package (@cellarnode/auth)
The Core sub-package contains the business logic for OTP-based authentication, JWT lifecycle management, and HTTP communication. It is designed to be framework-agnostic.
Key Components
| Component | Purpose | File Path |
|---|---|---|
AuthStore | Manages the access token in memory and handles scheduled background refreshes before expiry. | src/auth-store.ts |
AuthClient | A fetch wrapper that injects Bearer tokens and handles automatic 401 retry logic. | src/auth-client.ts |
AuthApi | High-level methods for register, requestOtp, verifyOtp, and logout. | src/auth-api.ts |
validateUserType | A guard utility to check if an authenticated user meets specific role requirements. | src/auth-guard.ts |
Token Refresh Logic
The AuthStore includes a scheduleRefresh mechanism that triggers a token update based on the expiresIn value and a configurable refreshBuffer (defaulting to 60 seconds).
Sources: src/auth-store.ts:12-20, src/auth-store.ts:60-64
Sources: src/auth-store.ts:12-42
React Sub-package (@cellarnode/auth/react)
The React sub-package provides a suite of "use client" components. These components are styled using Tailwind CSS and rely on several peer dependencies for specialized functionality.
UI Components and Peer Dependencies
Unlike the Core package, the React sub-package requires specific peer dependencies to be installed by the consumer.
- Components:
LoginForm,RegisterForm,UnauthorizedPage,SquircleShift. - Peer Dependencies:
react,lucide-react,input-otp,@react-three/fiber,three,tailwindcss.
Sources: package.json:34-42, src/react/index.ts:1-15
Component Integration
React components like LoginForm require instances of AuthApi and AuthStore passed as props, reinforcing the dependency injection pattern.
// Example of passing Core instances to a React Component
import { createAuthStore, createAuthClient, createAuthApi } from "@cellarnode/auth";
import { LoginForm } from "@cellarnode/auth/react";
const authStore = createAuthStore({ baseUrl: "..." });
const authClient = createAuthClient({ baseUrl: "...", store: authStore });
const authApi = createAuthApi({ client: authClient, store: authStore });
// Usage in JSX
<LoginForm authApi={authApi} authStore={authStore} userType="producer" ... />
Sources: README.md:15-32, src/react/login-form.tsx:32-33
Specialized React Features
- OTP Input: Uses a custom
InputOTPcomponent with 6-digit slotting and "shake" animation on error. - Visual Effects: Includes a
SquircleShiftcomponent using WebGL (via Three.js/Fiber) for animated background visuals in the login flow. - Portal Awareness: The
UnauthorizedPagecan detect if a user is logged in but on the wrong dashboard, providing contextual "Wrong Portal" links.
Sources: src/react/input-otp-slots.tsx:68-80, src/react/squircle-shift.tsx:210-244, src/react/unauthorized.tsx:23-45
Shared Types and Constants
Both sub-packages share a common type definition file to ensure type safety across the logic and UI layers.
| Type | Description |
|---|---|
AuthUser | Defines the user profile (id, email, userType, orgId, roles). |
UserType | Union type of "importer" | "producer" | "admin". |
AuthError | Custom class extending Error including status and code. |
DashboardLink | Structure for cross-linking between different user dashboards. |
| Sources: src/types.ts:1-67 |
Conclusion
The project structure prioritizes flexibility by isolating state and network logic within the Core layer and providing a highly interactive, customizable UI layer in the React sub-package. This allows the core logic to be tested and used independently of the React ecosystem, while ensuring that CellarNode dashboards maintain a consistent and secure authentication experience.