Documentation

    Concepts, value, and typical clone scenarios — less code.

    Welcome to Ring
    Quick Reference
    Getting Started
    Prerequisites
    Installation
    First Success Validation
    Next Steps
    Features
    Multi-Vendor Store
    SubscriptionConductor
    PaymentConductor
    Payments Overview
    WayForPay Payment Integration
    Wallet & Credit System
    WalletConductor
    Affiliate & Referral Enablement
    Referral Codes (Refcodes)
    NFT Exhibition Marketplace
    Solana NFT Gates
    Token Staking System
    Owner Project Lab
    Entities
    Opportunities
    Real-Time Messaging
    Ring Tasks
    WebRTC Calls & STUNner TURN
    News Module
    Member Blogs
    Public Profile Pages
    Username Reservation System
    Scientific Editor
    Notifications
    Push Notifications with FCM (Ring-Powered)
    Email AI-CRM
    Ring Mailer & RingdomX Mail
    Tunnel Protocol
    VideoConductor
    MediaConductor
    Generative Gallery
    Authentication
    Security & Compliance
    Admin console
    Admin Wiki
    Manage via Telegram
    Locale System
    Mobile Experience
    Performance Optimization Patterns
    Examples
    Quick Start
    Basic Setup
    White Label
    Custom Branding
    Web3 Integration
    Real World
    Advanced Features
    Customization
    Quick Start — Your First Ring Clone
    Customization Guide
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    Web3
    Token launch jurisdictions
    Wallet
    Wallet Security Tips
    Integrations
    Ethereum wallets (Wagmi v3)
    RingFileBase (object storage API)
    Ring CDN (RingFileBase edge)
    Deployment
    Self-hosted deployment
    Vercel
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    Development
    Ring MCP Server

    Quick entry (CTOs · auditors · agents)

    Welcome — mission & audiences
    Quick Reference
    Getting started
    Architecture & Auth.js
    Backend modes & databases (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Security & compliance reads
    ringdom.org — LegioX homebase
    Source — MIT license (GitHub)

    Documentation

    Concepts, value, and typical clone scenarios — less code.

    Welcome to Ring
    Quick Reference
    Getting Started
    Prerequisites
    Installation
    First Success Validation
    Next Steps
    Features
    Multi-Vendor Store
    SubscriptionConductor
    PaymentConductor
    Payments Overview
    WayForPay Payment Integration
    Wallet & Credit System
    WalletConductor
    Affiliate & Referral Enablement
    Referral Codes (Refcodes)
    NFT Exhibition Marketplace
    Solana NFT Gates
    Token Staking System
    Owner Project Lab
    Entities
    Opportunities
    Real-Time Messaging
    Ring Tasks
    WebRTC Calls & STUNner TURN
    News Module
    Member Blogs
    Public Profile Pages
    Username Reservation System
    Scientific Editor
    Notifications
    Push Notifications with FCM (Ring-Powered)
    Email AI-CRM
    Ring Mailer & RingdomX Mail
    Tunnel Protocol
    VideoConductor
    MediaConductor
    Generative Gallery
    Authentication
    Security & Compliance
    Admin console
    Admin Wiki
    Manage via Telegram
    Locale System
    Mobile Experience
    Performance Optimization Patterns
    Examples
    Quick Start
    Basic Setup
    White Label
    Custom Branding
    Web3 Integration
    Real World
    Advanced Features
    Customization
    Quick Start — Your First Ring Clone
    Customization Guide
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    Web3
    Token launch jurisdictions
    Wallet
    Wallet Security Tips
    Integrations
    Ethereum wallets (Wagmi v3)
    RingFileBase (object storage API)
    Ring CDN (RingFileBase edge)
    Deployment
    Self-hosted deployment
    Vercel
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    Development
    Ring MCP Server

    Quick entry (CTOs · auditors · agents)

    Welcome — mission & audiences
    Quick Reference
    Getting started
    Architecture & Auth.js
    Backend modes & databases (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Security & compliance reads
    ringdom.org — LegioX homebase
    Source — MIT license (GitHub)

    Documentation

    Concepts, value, and typical clone scenarios — less code.

    Welcome to Ring
    Quick Reference
    Getting Started
    Prerequisites
    Installation
    First Success Validation
    Next Steps
    Features
    Multi-Vendor Store
    SubscriptionConductor
    PaymentConductor
    Payments Overview
    WayForPay Payment Integration
    Wallet & Credit System
    WalletConductor
    Affiliate & Referral Enablement
    Referral Codes (Refcodes)
    NFT Exhibition Marketplace
    Solana NFT Gates
    Token Staking System
    Owner Project Lab
    Entities
    Opportunities
    Real-Time Messaging
    Ring Tasks
    WebRTC Calls & STUNner TURN
    News Module
    Member Blogs
    Public Profile Pages
    Username Reservation System
    Scientific Editor
    Notifications
    Push Notifications with FCM (Ring-Powered)
    Email AI-CRM
    Ring Mailer & RingdomX Mail
    Tunnel Protocol
    VideoConductor
    MediaConductor
    Generative Gallery
    Authentication
    Security & Compliance
    Admin console
    Admin Wiki
    Manage via Telegram
    Locale System
    Mobile Experience
    Performance Optimization Patterns
    Examples
    Quick Start
    Basic Setup
    White Label
    Custom Branding
    Web3 Integration
    Real World
    Advanced Features
    Customization
    Quick Start — Your First Ring Clone
    Customization Guide
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    Web3
    Token launch jurisdictions
    Wallet
    Wallet Security Tips
    Integrations
    Ethereum wallets (Wagmi v3)
    RingFileBase (object storage API)
    Ring CDN (RingFileBase edge)
    Deployment
    Self-hosted deployment
    Vercel
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    Development
    Ring MCP Server

    Quick entry (CTOs · auditors · agents)

    Welcome — mission & audiences
    Quick Reference
    Getting started
    Architecture & Auth.js
    Backend modes & databases (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Security & compliance reads
    ringdom.org — LegioX homebase
    Source — MIT license (GitHub)
    1. Docs
    2. /Architecture
    3. /Authentication Architecture

    Updated Jul 20, 20264 min listen

    Ring Platform Logo

    Завантаження документації...

    Підготовка контенту платформи Ring

    1. Docs
    2. /Architecture
    3. /Authentication Architecture

    Updated Jul 20, 20264 min listen

    Ring Platform Logo

    Завантаження документації...

    Підготовка контенту платформи Ring

    1. Docs
    2. /Architecture
    3. /Authentication Architecture

    Updated Jul 20, 20264 min listen

    Ring Platform Logo

    Завантаження документації...

    Підготовка контенту платформи Ring

    Authentication Architecture

    Ring Platform uses Auth.js v5 (NextAuth) with a JWT session strategy. The adapter (PostgreSQL or Firebase) is selected by DB_BACKEND_MODE. Use Founder / Developer tabs in the docs sidebar to filter by audience.

    Providers

    ProviderFlowAuth.js provider
    Google OAuthFull OAuth 2.0 redirect + Google Identity Services (GIS) One TapGoogleProvider + CredentialsProvider("google-one-tap")
    Telegram (web)OIDC Authorization Code + PKCE (oauth.telegram.org)Custom TelegramOidcProvider (id: "telegram") when env set
    Telegram Mini AppWebApp initData HMAC (WebAppData secret)CredentialsProvider("telegram-miniapp")
    Apple Sign-InOAuth redirect, native iOS/macOSAppleProvider
    Ring MailerOTP + magic link / verify / reset via own SMTP (lib/mailer.ts)Credentials email-otp / email-magic / credentials
    Crypto WalletNonce-signature verification (MetaMask, WalletConnect)CredentialsProvider("crypto-wallet")

    Configuration lives in auth.ts and auth.config.ts at the project root. Auth.js v5 splits edge-safe config (auth.config.ts — no providers, minimal callbacks) from full server config (auth.ts — all providers, database adapters).

    Product overview and BotFather checklist: Authentication.

    How authentication works

    Auth.js v5 manages the entire authentication flow — the platform does not use Firebase Auth directly. Firebase Admin SDK is used only for server-side token verification and user document lookups in firebase-full mode.

    Session flow:

    1. User signs in via Google, Telegram (web OIDC or Mini App initData), Apple, Ring Mailer (OTP / magic link / password), or crypto wallet
    2. Auth.js v5 handles OAuth/OIDC exchange or Credentials authorize
    3. JWT session is created on the server, stored in an HTTP-only cookie
    4. PostgreSQL adapter persists user/account/session records when DB_BACKEND_MODE is PostgreSQL-based
    5. Firebase adapter persists to Firestore when DB_BACKEND_MODE=firebase-full

    Key design decisions:

    • JWT strategy (no database session store) for edge-compatible deployment
    • 30-day session max age with 24-hour update window
    • Identity is always a platform UUID (users.id), never Google sub, Apple sub, or Telegram id alone as the session primary key
    • Email-based account linking across providers when email exists; Telegram can create users without email
    • Telegram Login (OIDC), Mini App initData, Login Widget linking, and the admin Telegram bot use different secrets / crypto — see the surface table on Authentication

    Auth.js v5 file structure

    Provider configuration

    Google OAuth (dual mode)

    Traditional OAuth (redirect flow):

    Google Identity Services (GIS) One Tap (client-side popup):

    The GIS JWT is verified server-side in the signIn callback using google-auth-library:

    Telegram OIDC

    Registered only when AUTH_TELEGRAM_ID and AUTH_TELEGRAM_SECRET are set:

    • Discovery: https://oauth.telegram.org/.well-known/openid-configuration
    • Soft-launch scopes: openid profile
    • Token auth method: client_secret_basic
    • Checks: pkce, state
    • Profile from id_token claims (Telegram has no UserInfo endpoint)
    • Resolve: resolveOrCreateTelegramUser in features/auth/services/user-resolve.ts
    • Callback URI: {origin}/api/auth/callback/telegram (Auth.js) — do not confuse with /api/auth/telegram/callback (widget linking)

    Telegram Mini App initData

    Always registered as Credentials id: "telegram-miniapp" in auth.ts. Authorize:

    1. getTelegramMiniAppBotToken() — prefer TELEGRAM_MINI_APP_BOT_TOKEN, then TELEGRAM_BOT_TOKEN, ADMIN_BOT_TOKEN, TELEGRAM_LOGIN_BOT_TOKEN, N9LIFE_BOT_TOKEN
    2. verifyTelegramMiniAppInitData(initData, botToken) — secret key material is HMAC with key WebAppData (not )

    Related documentation

    Related documentation

    Authentication

    Prerequisite: product overview, BotFather checklist, Mini App, and Telegram surface boundary.

    Authentication Examples

    Next-step: integrator snippets for OIDC and telegram-miniapp Credentials.

    Backend modes and databases

    Depends-on: how DB_BACKEND_MODE picks the Auth.js adapter.

    Environment Configuration

    Same-workflow: complete AUTH_* and SMTP env blocks for clones.

    Authentication Architecture

    Ring Platform uses Auth.js v5 (NextAuth) with a JWT session strategy. The adapter (PostgreSQL or Firebase) is selected by DB_BACKEND_MODE. Use Founder / Developer tabs in the docs sidebar to filter by audience.

    Providers

    ProviderFlowAuth.js provider
    Google OAuthFull OAuth 2.0 redirect + Google Identity Services (GIS) One TapGoogleProvider + CredentialsProvider("google-one-tap")
    Telegram (web)OIDC Authorization Code + PKCE (oauth.telegram.org)Custom TelegramOidcProvider (id: "telegram") when env set
    Telegram Mini AppWebApp initData HMAC (WebAppData secret)CredentialsProvider("telegram-miniapp")
    Apple Sign-InOAuth redirect, native iOS/macOSAppleProvider
    Ring MailerOTP + magic link / verify / reset via own SMTP (lib/mailer.ts)Credentials email-otp / email-magic / credentials
    Crypto WalletNonce-signature verification (MetaMask, WalletConnect)CredentialsProvider("crypto-wallet")

    Configuration lives in auth.ts and auth.config.ts at the project root. Auth.js v5 splits edge-safe config (auth.config.ts — no providers, minimal callbacks) from full server config (auth.ts — all providers, database adapters).

    Product overview and BotFather checklist: Authentication.

    How authentication works

    Auth.js v5 manages the entire authentication flow — the platform does not use Firebase Auth directly. Firebase Admin SDK is used only for server-side token verification and user document lookups in firebase-full mode.

    Session flow:

    1. User signs in via Google, Telegram (web OIDC or Mini App initData), Apple, Ring Mailer (OTP / magic link / password), or crypto wallet
    2. Auth.js v5 handles OAuth/OIDC exchange or Credentials authorize
    3. JWT session is created on the server, stored in an HTTP-only cookie
    4. PostgreSQL adapter persists user/account/session records when DB_BACKEND_MODE is PostgreSQL-based
    5. Firebase adapter persists to Firestore when DB_BACKEND_MODE=firebase-full

    Key design decisions:

    • JWT strategy (no database session store) for edge-compatible deployment
    • 30-day session max age with 24-hour update window
    • Identity is always a platform UUID (users.id), never Google sub, Apple sub, or Telegram id alone as the session primary key
    • Email-based account linking across providers when email exists; Telegram can create users without email
    • Telegram Login (OIDC), Mini App initData, Login Widget linking, and the admin Telegram bot use different secrets / crypto — see the surface table on Authentication

    Auth.js v5 file structure

    Provider configuration

    Google OAuth (dual mode)

    Traditional OAuth (redirect flow):

    Google Identity Services (GIS) One Tap (client-side popup):

    The GIS JWT is verified server-side in the signIn callback using google-auth-library:

    Telegram OIDC

    Registered only when AUTH_TELEGRAM_ID and AUTH_TELEGRAM_SECRET are set:

    • Discovery: https://oauth.telegram.org/.well-known/openid-configuration
    • Soft-launch scopes: openid profile
    • Token auth method: client_secret_basic
    • Checks: pkce, state
    • Profile from id_token claims (Telegram has no UserInfo endpoint)
    • Resolve: resolveOrCreateTelegramUser in features/auth/services/user-resolve.ts
    • Callback URI: {origin}/api/auth/callback/telegram (Auth.js) — do not confuse with /api/auth/telegram/callback (widget linking)

    Telegram Mini App initData

    Always registered as Credentials id: "telegram-miniapp" in auth.ts. Authorize:

    1. getTelegramMiniAppBotToken() — prefer TELEGRAM_MINI_APP_BOT_TOKEN, then TELEGRAM_BOT_TOKEN, ADMIN_BOT_TOKEN, TELEGRAM_LOGIN_BOT_TOKEN, N9LIFE_BOT_TOKEN
    2. verifyTelegramMiniAppInitData(initData, botToken) — secret key material is HMAC with key WebAppData (not )

    Related documentation

    Related documentation

    Authentication

    Prerequisite: product overview, BotFather checklist, Mini App, and Telegram surface boundary.

    Authentication Examples

    Next-step: integrator snippets for OIDC and telegram-miniapp Credentials.

    Backend modes and databases

    Depends-on: how DB_BACKEND_MODE picks the Auth.js adapter.

    Environment Configuration

    Same-workflow: complete AUTH_* and SMTP env blocks for clones.

    Authentication Architecture

    Ring Platform uses Auth.js v5 (NextAuth) with a JWT session strategy. The adapter (PostgreSQL or Firebase) is selected by DB_BACKEND_MODE. Use Founder / Developer tabs in the docs sidebar to filter by audience.

    Providers

    ProviderFlowAuth.js provider
    Google OAuthFull OAuth 2.0 redirect + Google Identity Services (GIS) One TapGoogleProvider + CredentialsProvider("google-one-tap")
    Telegram (web)OIDC Authorization Code + PKCE (oauth.telegram.org)Custom TelegramOidcProvider (id: "telegram") when env set
    Telegram Mini AppWebApp initData HMAC (WebAppData secret)CredentialsProvider("telegram-miniapp")
    Apple Sign-InOAuth redirect, native iOS/macOSAppleProvider
    Ring MailerOTP + magic link / verify / reset via own SMTP (lib/mailer.ts)Credentials email-otp / email-magic / credentials
    Crypto WalletNonce-signature verification (MetaMask, WalletConnect)CredentialsProvider("crypto-wallet")

    Configuration lives in auth.ts and auth.config.ts at the project root. Auth.js v5 splits edge-safe config (auth.config.ts — no providers, minimal callbacks) from full server config (auth.ts — all providers, database adapters).

    Product overview and BotFather checklist: Authentication.

    How authentication works

    Auth.js v5 manages the entire authentication flow — the platform does not use Firebase Auth directly. Firebase Admin SDK is used only for server-side token verification and user document lookups in firebase-full mode.

    Session flow:

    1. User signs in via Google, Telegram (web OIDC or Mini App initData), Apple, Ring Mailer (OTP / magic link / password), or crypto wallet
    2. Auth.js v5 handles OAuth/OIDC exchange or Credentials authorize
    3. JWT session is created on the server, stored in an HTTP-only cookie
    4. PostgreSQL adapter persists user/account/session records when DB_BACKEND_MODE is PostgreSQL-based
    5. Firebase adapter persists to Firestore when DB_BACKEND_MODE=firebase-full

    Key design decisions:

    • JWT strategy (no database session store) for edge-compatible deployment
    • 30-day session max age with 24-hour update window
    • Identity is always a platform UUID (users.id), never Google sub, Apple sub, or Telegram id alone as the session primary key
    • Email-based account linking across providers when email exists; Telegram can create users without email
    • Telegram Login (OIDC), Mini App initData, Login Widget linking, and the admin Telegram bot use different secrets / crypto — see the surface table on Authentication

    Auth.js v5 file structure

    Provider configuration

    Google OAuth (dual mode)

    Traditional OAuth (redirect flow):

    Google Identity Services (GIS) One Tap (client-side popup):

    The GIS JWT is verified server-side in the signIn callback using google-auth-library:

    Telegram OIDC

    Registered only when AUTH_TELEGRAM_ID and AUTH_TELEGRAM_SECRET are set:

    • Discovery: https://oauth.telegram.org/.well-known/openid-configuration
    • Soft-launch scopes: openid profile
    • Token auth method: client_secret_basic
    • Checks: pkce, state
    • Profile from id_token claims (Telegram has no UserInfo endpoint)
    • Resolve: resolveOrCreateTelegramUser in features/auth/services/user-resolve.ts
    • Callback URI: {origin}/api/auth/callback/telegram (Auth.js) — do not confuse with /api/auth/telegram/callback (widget linking)

    Telegram Mini App initData

    Always registered as Credentials id: "telegram-miniapp" in auth.ts. Authorize:

    1. getTelegramMiniAppBotToken() — prefer TELEGRAM_MINI_APP_BOT_TOKEN, then TELEGRAM_BOT_TOKEN, ADMIN_BOT_TOKEN, TELEGRAM_LOGIN_BOT_TOKEN, N9LIFE_BOT_TOKEN
    2. verifyTelegramMiniAppInitData(initData, botToken) — secret key material is HMAC with key WebAppData (not )

    Related documentation

    Related documentation

    Authentication

    Prerequisite: product overview, BotFather checklist, Mini App, and Telegram surface boundary.

    Authentication Examples

    Next-step: integrator snippets for OIDC and telegram-miniapp Credentials.

    Backend modes and databases

    Depends-on: how DB_BACKEND_MODE picks the Auth.js adapter.

    Environment Configuration

    Same-workflow: complete AUTH_* and SMTP env blocks for clones.

    SHA256(bot_token)
  1. isTelegramMiniAppAuthDateFresh — default max age 86400 seconds
  2. resolveOrCreateTelegramUser with Telegram id / name / username / photo from parsed user JSON
  3. Client shape: signIn('telegram-miniapp', { initData, redirect: false }). Tests: __tests__/auth/telegram-miniapp-initdata.test.ts.

    Apple Sign-In

    Ring Mailer (OTP / magic link)

    Own SMTP via lib/mailer.ts. Tokens live in Postgres email_login_tokens (migration 038). Magic links use hash URLs (/verify#token=…) and are consumed only in Credentials authorize — never on GET.

    Server Actions: app/_actions/auth-email-actions.ts. Full setup: Ring Mailer.

    Crypto Wallet

    Nonce-based signature verification via Viem. Supports Ethereum, Polygon, Arbitrum, Optimism, and Base:

    Adapter selection

    The adapter is determined by DB_BACKEND_MODE:

    ModeAdapterSource
    k8s-postgres-fcmPostgreSQLAdapterlib/auth/postgres-adapter.ts
    firebase-fullFirestoreAdapter from @auth/firebase-adaptervia getAdminDb()
    supabase-fcmPostgreSQLAdapterSame PostgreSQL path

    Firebase Admin SDK integration

    Firebase Admin SDK is used in two contexts:

    1. Auth adapter (firebase-full mode only): FirestoreAdapter reads/writes user documents
    2. Crypto wallet auth: db().readDoc('users', storageId) for nonce lookup (BackendSelector routes Firebase or PostgreSQL)

    In k8s-postgres-fcm and supabase-fcm modes, getAdminDb() returns a mock Firestore — no real Firebase init happens. FCM push messaging still uses Firebase Admin through firebase-admin.server.ts (separate from the auth path).

    Server-side usage

    Client-side usage

    Environment variables

    Manage via Telegram

    See-also: admin bot whitelist — not member OIDC or Mini App Login.

    SubscriptionConductor

    See-also: telegram_stars reuses getTelegramMiniAppBotToken for XTR invoices.

    text
    
    auth.config.ts          — Edge-compatible config (empty providers, authorized callback, redirects)
    auth.ts                 — Full server config (all providers, database adapter, JWT/session callbacks)
    lib/auth-adapter-singleton.ts  — Cached adapter: PostgreSQLAdapter or FirestoreAdapter
    lib/auth/postgres-adapter.ts   — Custom PostgreSQL adapter for Auth.js v5
    lib/auth/telegram-oidc.ts      — Telegram OIDC provider + claim helpers
    lib/auth/telegram-miniapp-initdata.ts — Mini App WebAppData HMAC + getTelegramMiniAppBotToken
    lib/auth/telegram-login-widget-hash.ts — Legacy Login Widget HMAC
    lib/firebase-admin.server.ts   — Firebase Admin SDK instance (getAdminAuth, getAdminDb)
    app/api/auth/[...nextauth]/route.ts  — Auth.js API route handler
    app/api/auth/telegram/callback/route.ts — Session-required profile linking (widget)
    bash
    
    # Auth.js core
    AUTH_SECRET=your_auth_secret
    AUTH_TRUST_HOST=true
    
    # Google OAuth
    AUTH_GOOGLE_ID=your_google_client_id
    AUTH_GOOGLE_SECRET=your_google_client_secret
    
    # Telegram Web Login OIDC (BotFather → Web Login)
    AUTH_TELEGRAM_ID=your_telegram_oidc_client_id
    AUTH_TELEGRAM_SECRET=your_telegram_oidc_client_secret
    # ADMIN_BOT_TOKEN=...   # Login Widget hash / admin bot API
    # TELEGRAM_MINI_APP_BOT_TOKEN=...  # Mini App initData HMAC (+ Stars invoices)
    
    # Apple Sign-In
    AUTH_APPLE_ID=your_apple_client_id
    AUTH_APPLE_SECRET=your_apple_private_key
    
    # Ring Mailer (no AUTH_RESEND_*)
    # EMAIL_MODE=ethereal
    # SMTP_HOST= / SMTP_USER= / SMTP_PASSWORD= / SMTP_FROM=
    # OTP_HMAC_SECRET=
    
    # Firebase (for firebase-full mode only)
    AUTH_FIREBASE_PROJECT_ID=your_firebase_project_id
    AUTH_FIREBASE_CLIENT_EMAIL=your_firebase_client_email
    AUTH_FIREBASE_PRIVATE_KEY=your_firebase_private_key
    
    # WalletConnect
    NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_project_id
    SHA256(bot_token)
  4. isTelegramMiniAppAuthDateFresh — default max age 86400 seconds
  5. resolveOrCreateTelegramUser with Telegram id / name / username / photo from parsed user JSON
  6. Client shape: signIn('telegram-miniapp', { initData, redirect: false }). Tests: __tests__/auth/telegram-miniapp-initdata.test.ts.

    Apple Sign-In

    Ring Mailer (OTP / magic link)

    Own SMTP via lib/mailer.ts. Tokens live in Postgres email_login_tokens (migration 038). Magic links use hash URLs (/verify#token=…) and are consumed only in Credentials authorize — never on GET.

    Server Actions: app/_actions/auth-email-actions.ts. Full setup: Ring Mailer.

    Crypto Wallet

    Nonce-based signature verification via Viem. Supports Ethereum, Polygon, Arbitrum, Optimism, and Base:

    Adapter selection

    The adapter is determined by DB_BACKEND_MODE:

    ModeAdapterSource
    k8s-postgres-fcmPostgreSQLAdapterlib/auth/postgres-adapter.ts
    firebase-fullFirestoreAdapter from @auth/firebase-adaptervia getAdminDb()
    supabase-fcmPostgreSQLAdapterSame PostgreSQL path

    Firebase Admin SDK integration

    Firebase Admin SDK is used in two contexts:

    1. Auth adapter (firebase-full mode only): FirestoreAdapter reads/writes user documents
    2. Crypto wallet auth: db().readDoc('users', storageId) for nonce lookup (BackendSelector routes Firebase or PostgreSQL)

    In k8s-postgres-fcm and supabase-fcm modes, getAdminDb() returns a mock Firestore — no real Firebase init happens. FCM push messaging still uses Firebase Admin through firebase-admin.server.ts (separate from the auth path).

    Server-side usage

    Client-side usage

    Environment variables

    Manage via Telegram

    See-also: admin bot whitelist — not member OIDC or Mini App Login.

    SubscriptionConductor

    See-also: telegram_stars reuses getTelegramMiniAppBotToken for XTR invoices.

    text
    
    auth.config.ts          — Edge-compatible config (empty providers, authorized callback, redirects)
    auth.ts                 — Full server config (all providers, database adapter, JWT/session callbacks)
    lib/auth-adapter-singleton.ts  — Cached adapter: PostgreSQLAdapter or FirestoreAdapter
    lib/auth/postgres-adapter.ts   — Custom PostgreSQL adapter for Auth.js v5
    lib/auth/telegram-oidc.ts      — Telegram OIDC provider + claim helpers
    lib/auth/telegram-miniapp-initdata.ts — Mini App WebAppData HMAC + getTelegramMiniAppBotToken
    lib/auth/telegram-login-widget-hash.ts — Legacy Login Widget HMAC
    lib/firebase-admin.server.ts   — Firebase Admin SDK instance (getAdminAuth, getAdminDb)
    app/api/auth/[...nextauth]/route.ts  — Auth.js API route handler
    app/api/auth/telegram/callback/route.ts — Session-required profile linking (widget)
    bash
    
    # Auth.js core
    AUTH_SECRET=your_auth_secret
    AUTH_TRUST_HOST=true
    
    # Google OAuth
    AUTH_GOOGLE_ID=your_google_client_id
    AUTH_GOOGLE_SECRET=your_google_client_secret
    
    # Telegram Web Login OIDC (BotFather → Web Login)
    AUTH_TELEGRAM_ID=your_telegram_oidc_client_id
    AUTH_TELEGRAM_SECRET=your_telegram_oidc_client_secret
    # ADMIN_BOT_TOKEN=...   # Login Widget hash / admin bot API
    # TELEGRAM_MINI_APP_BOT_TOKEN=...  # Mini App initData HMAC (+ Stars invoices)
    
    # Apple Sign-In
    AUTH_APPLE_ID=your_apple_client_id
    AUTH_APPLE_SECRET=your_apple_private_key
    
    # Ring Mailer (no AUTH_RESEND_*)
    # EMAIL_MODE=ethereal
    # SMTP_HOST= / SMTP_USER= / SMTP_PASSWORD= / SMTP_FROM=
    # OTP_HMAC_SECRET=
    
    # Firebase (for firebase-full mode only)
    AUTH_FIREBASE_PROJECT_ID=your_firebase_project_id
    AUTH_FIREBASE_CLIENT_EMAIL=your_firebase_client_email
    AUTH_FIREBASE_PRIVATE_KEY=your_firebase_private_key
    
    # WalletConnect
    NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_project_id
    SHA256(bot_token)
  7. isTelegramMiniAppAuthDateFresh — default max age 86400 seconds
  8. resolveOrCreateTelegramUser with Telegram id / name / username / photo from parsed user JSON
  9. Client shape: signIn('telegram-miniapp', { initData, redirect: false }). Tests: __tests__/auth/telegram-miniapp-initdata.test.ts.

    Apple Sign-In

    Ring Mailer (OTP / magic link)

    Own SMTP via lib/mailer.ts. Tokens live in Postgres email_login_tokens (migration 038). Magic links use hash URLs (/verify#token=…) and are consumed only in Credentials authorize — never on GET.

    Server Actions: app/_actions/auth-email-actions.ts. Full setup: Ring Mailer.

    Crypto Wallet

    Nonce-based signature verification via Viem. Supports Ethereum, Polygon, Arbitrum, Optimism, and Base:

    Adapter selection

    The adapter is determined by DB_BACKEND_MODE:

    ModeAdapterSource
    k8s-postgres-fcmPostgreSQLAdapterlib/auth/postgres-adapter.ts
    firebase-fullFirestoreAdapter from @auth/firebase-adaptervia getAdminDb()
    supabase-fcmPostgreSQLAdapterSame PostgreSQL path

    Firebase Admin SDK integration

    Firebase Admin SDK is used in two contexts:

    1. Auth adapter (firebase-full mode only): FirestoreAdapter reads/writes user documents
    2. Crypto wallet auth: db().readDoc('users', storageId) for nonce lookup (BackendSelector routes Firebase or PostgreSQL)

    In k8s-postgres-fcm and supabase-fcm modes, getAdminDb() returns a mock Firestore — no real Firebase init happens. FCM push messaging still uses Firebase Admin through firebase-admin.server.ts (separate from the auth path).

    Server-side usage

    Client-side usage

    Environment variables

    Manage via Telegram

    See-also: admin bot whitelist — not member OIDC or Mini App Login.

    SubscriptionConductor

    See-also: telegram_stars reuses getTelegramMiniAppBotToken for XTR invoices.

    text
    
    auth.config.ts          — Edge-compatible config (empty providers, authorized callback, redirects)
    auth.ts                 — Full server config (all providers, database adapter, JWT/session callbacks)
    lib/auth-adapter-singleton.ts  — Cached adapter: PostgreSQLAdapter or FirestoreAdapter
    lib/auth/postgres-adapter.ts   — Custom PostgreSQL adapter for Auth.js v5
    lib/auth/telegram-oidc.ts      — Telegram OIDC provider + claim helpers
    lib/auth/telegram-miniapp-initdata.ts — Mini App WebAppData HMAC + getTelegramMiniAppBotToken
    lib/auth/telegram-login-widget-hash.ts — Legacy Login Widget HMAC
    lib/firebase-admin.server.ts   — Firebase Admin SDK instance (getAdminAuth, getAdminDb)
    app/api/auth/[...nextauth]/route.ts  — Auth.js API route handler
    app/api/auth/telegram/callback/route.ts — Session-required profile linking (widget)
    bash
    
    # Auth.js core
    AUTH_SECRET=your_auth_secret
    AUTH_TRUST_HOST=true
    
    # Google OAuth
    AUTH_GOOGLE_ID=your_google_client_id
    AUTH_GOOGLE_SECRET=your_google_client_secret
    
    # Telegram Web Login OIDC (BotFather → Web Login)
    AUTH_TELEGRAM_ID=your_telegram_oidc_client_id
    AUTH_TELEGRAM_SECRET=your_telegram_oidc_client_secret
    # ADMIN_BOT_TOKEN=...   # Login Widget hash / admin bot API
    # TELEGRAM_MINI_APP_BOT_TOKEN=...  # Mini App initData HMAC (+ Stars invoices)
    
    # Apple Sign-In
    AUTH_APPLE_ID=your_apple_client_id
    AUTH_APPLE_SECRET=your_apple_private_key
    
    # Ring Mailer (no AUTH_RESEND_*)
    # EMAIL_MODE=ethereal
    # SMTP_HOST= / SMTP_USER= / SMTP_PASSWORD= / SMTP_FROM=
    # OTP_HMAC_SECRET=
    
    # Firebase (for firebase-full mode only)
    AUTH_FIREBASE_PROJECT_ID=your_firebase_project_id
    AUTH_FIREBASE_CLIENT_EMAIL=your_firebase_client_email
    AUTH_FIREBASE_PRIVATE_KEY=your_firebase_private_key
    
    # WalletConnect
    NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_project_id