mirror of
https://github.com/hanzoai/id.git
synced 2026-11-03 00:42:22 +00:00
Replaces the Cloudflare Worker (hanzo.id-worker) and the Next.js portal
with a pnpm monorepo following the a-monorepo/id pattern.
Layout:
apps/web/ Vite + React 19 SPA, embeds @hanzo/gui shell
k8s/ Deployment(2) + Service + Ingress (4 hosts, 4 TLS)
pkgs/shared/ @hanzo/id-shared — TenantConfig, resolveTenant,
loadBrand (browser + node)
pkgs/auth/ @hanzo/id-auth — AuthClient (wraps @hanzo/iam REST)
+ LoginForm/SignupForm/ForgotForm/OTPForm
pkgs/idv/ @hanzo/id-idv — pluggable IDV (stub, persona,
onfido, veriff) behind one
IDVProvider interface
legacy-nextjs/ Frozen — Next.js predecessor. Delete after v0.1.0 ships.
Dockerfile Two-stage: pnpm build → hanzoai/static:0.4.1 serves /spa
README.md
LLM.md Architecture, dev, deploy, cutover plan
Tenant resolution: hostname → TenantConfig (orgId, iamUrl, clientId,
appName, publicOrigin, brandPackage). Built-in defaults for
hanzo.id/lux.id/zoo.id/pars.id; runtime override via
IAM_TENANT_CONFIG_JSON env (served as /config.json at pod startup).
Brand resolution: each per-org brand pkg (@hanzo/brand, @luxfi/brand,
@zooai/brand, @parsdao/brand) ships brand.json. The Vite plugin
brandJsonPlugin emits /brand/<pkg>/brand.json verbatim; the browser
fetches the right one based on the resolved tenant. No bundle bloat.
IDV: stub (default for dev), persona, onfido, veriff. Each adapter
implements `IDVProvider` from pkgs/idv/src/provider.ts. Swap providers
with one registration call at boot — portal code unchanged.
Cutover (separate ops PR — not in this commit):
1. Tag + push image ghcr.io/hanzoai/id:0.1.0
2. Apply k8s manifests, cert-manager issues TLS
3. Remove CF Worker routes for hanzo.id/lux.id/zoo.id/pars.id
4. CF A records → 129.212.164.5 (hanzo ingress LB)
5. Archive hanzo.id-worker repo
4.0 KiB
4.0 KiB
Hanzo ID - Hosted Login Pages
Configurable, white-label login pages for Hanzo IAM. Each organization can customize their login experience based on their domain (CNAME).
Architecture
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ hanzo.id │ │ pars.id │ │ lux.id │
│ (CNAME) │ │ (CNAME) │ │ (CNAME) │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└───────────────────┴───────────────────┘
│
┌──────▼──────┐
│ Hanzo ID │ ← This repo (frontend)
│ (Next.js) │
└──────┬──────┘
│
┌──────▼──────┐
│ Hanzo IAM │ ← Backend auth services
│ (Go API) │
└─────────────┘
Features
- Domain-based branding: Logo, colors, content based on CNAME
- Configurable auth methods: Password, code, WebAuthn, Face ID
- Social providers: Google, GitHub, and more
- Customizable content: Quotes, testimonials, feature highlights
- Dark mode by default: Clean, modern design
- Easy to fork: Simple structure for white-labeling
Configuration
Branding can be configured in two ways:
1. Static Configuration (for known domains)
Edit lib/branding.ts to add your domain:
export const staticBranding: Record<string, Partial<BrandingConfig>> = {
'your-domain.com': {
orgId: 'your-org',
orgName: 'Your Organization',
logo: '/logos/your-logo.svg',
colors: {
primary: '#3b82f6',
primaryText: '#ffffff',
background: '#000000',
surface: '#0a0a0a',
text: '#ffffff',
textMuted: '#a1a1aa',
border: '#27272a',
error: '#dc2626',
},
content: {
title: 'Welcome to Your App',
subtitle: 'Sign in to continue',
},
},
}
2. Dynamic Configuration (from IAM backend)
The login page fetches branding from IAM API:
GET https://api.hanzo.id/api/branding?domain=your-domain.com
Response:
{
"orgId": "your-org",
"orgName": "Your Organization",
"logo": "https://...",
"colors": { ... },
"content": { ... },
"links": { ... },
"auth": { ... }
}
Development
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Start production server
npm start
Environment Variables
# IAM backend URL
HANZO_IAM_URL=https://api.hanzo.id
# Public IAM URL (for client-side redirects)
NEXT_PUBLIC_IAM_URL=https://api.hanzo.id
Forking for White-Label
- Fork this repository
- Update
lib/branding.tswith your default branding - Add your logo to
public/logos/ - Update
app/globals.cssfor custom styling - Deploy to your infrastructure
Directory Structure
hanzo-id/
├── app/
│ ├── layout.tsx # Root layout with metadata
│ ├── page.tsx # Redirects to /login
│ ├── login/
│ │ └── page.tsx # Main login page
│ ├── signup/ # Sign up page
│ ├── forgot-password # Password reset
│ └── callback/ # OAuth callback handler
├── components/
│ ├── LoginForm.tsx # Login form component
│ └── MarketingPanel.tsx # Right side marketing content
├── lib/
│ └── branding.ts # Branding configuration
├── public/
│ └── logos/ # Organization logos
└── config/ # Additional configuration
License
MIT - Fork and customize freely!