Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Preparing Ring Platform content
Preparing Ring Platform content
Preparing Ring Platform content
Use Founder / Developer tabs in the docs sidebar to filter this page.
Ring uses Auth.js v5 for JWT sessions and OAuth. Members can sign in with Ring Mailer (OTP / magic link / password), Google, Telegram (web OIDC or Mini App initData), Apple, or a crypto wallet. Email is not Resend — see Ring Mailer & RingdomX Mail.
| Layer | Role |
|---|---|
proxy.ts | Locale rewrite + optimistic redirect to ROUTES.LOGIN(locale) (cookie presence only) |
proxy.ts soft-gate | If JWT needsOnboarding === true, redirect to /{locale}/login/onboarding (exempt: /login*, /auth*, /register*, home /) |
(authenticated)/[locale]/layout.tsx | await auth() — canonical session gate |
(admin)/[locale]/layout.tsx | Role check (admin / superadmin) |
/login | LoginAuthenticatedRedirect — client useSession bounce (skips during OAuth callback params) |
/register | Redirects to /login (password signup demoted; OTP/magic is the product surface) |
| API routes | Per-handler auth() |
OAuth callbacks live under /api/auth/* (excluded from intl middleware). See Proxy and intl.
Login path SSOT: ROUTES.LOGIN(locale) with unified from / callbackUrl / returnTo (features/auth/components/login-authenticated-redirect.tsx).
After first sign-in, some providers require profile vitals (name, etc.) before the rest of the app. isVitalsGatedProvider() in features/auth/lib/vitals-onboarding.ts includes:
| Provider id | Gated? |
|---|---|
google, google-one-tap, apple | Yes |
email-otp, email-magic, telegram, crypto-wallet | Yes |
| Others | Not in the shared gate set |
Incomplete vitals set JWT/session needsOnboarding. Client redirects (email-login-form, verify-client, wallet-connect) and the proxy soft-gate both honor it. Own profile Avatar uses editable={true} so members can finish photo vitals on /profile.
| Provider | How members sign in |
|---|---|
| Ring Mailer | OTP, magic link (/verify#token=…), or password — Credentials email-otp / email-magic / credentials |
| OAuth redirect + Google One Tap (GIS JWT verified server-side) | |
| Telegram (web) | OIDC Authorization Code + PKCE at oauth.telegram.org — signIn('telegram') |
| Telegram Mini App | Credentials telegram-miniapp — signIn('telegram-miniapp', { initData, redirect: false }) |
| Apple | Sign in with Apple OAuth |
| Crypto wallet | Nonce + signature (crypto-wallet Credentials) |
GitHub/Discord OAuth are not in the default auth.ts provider list.
| Surface | Purpose | Crypto / secret |
|---|---|---|
| Login via Telegram (web) | Unauthenticated member opens a Ring session in the browser | OIDC id_token — AUTH_TELEGRAM_ID / AUTH_TELEGRAM_SECRET |
| Mini App initData | Silent session inside a Telegram WebApp client | HMAC with secret key WebAppData — bot API token (TELEGRAM_MINI_APP_BOT_TOKEN preferred) |
| Link Telegram (profile) | Already logged-in member binds Telegram id | Login Widget HMAC SHA256(bot_token) — ADMIN_BOT_TOKEN / TELEGRAM_LOGIN_BOT_TOKEN |
| Admin bot | Platform admins moderate from chat | Bot API + whitelist — Manage via Telegram |
Do not reuse Mini App initData (WebAppData) HMAC for Login Widget linking, and do not use Login Widget SHA256(bot_token) math for Mini App auth.
SMTP setup, Ethereal, calculator mail add-on, token migration 038.
Adapter selection, JWT callbacks, Telegram OIDC modules.
Integrator snippets for providers and mailer flows.
users.id); email can link accounts across providers when Auth.js linking is enabled. Telegram-only users may have an empty email (allowed by the partial unique index).https://your.domain) and OIDC callback https://your.domain/api/auth/callback/telegram..env.local as AUTH_TELEGRAM_ID / AUTH_TELEGRAM_SECRET.ADMIN_BOT_TOKEN or TELEGRAM_LOGIN_BOT_TOKEN) for profile “Link Telegram” widget hash — it is not the OIDC client secret.from URL).TELEGRAM_MINI_APP_BOT_TOKEN to that bot’s API token (preferred). Fallbacks used by getTelegramMiniAppBotToken(): TELEGRAM_BOT_TOKEN → ADMIN_BOT_TOKEN → TELEGRAM_LOGIN_BOT_TOKEN → N9LIFE_BOT_TOKEN.Deep-dive: Auth.js file split, adapters, OIDC + Mini App modules.
Next-step: copy-paste signIn('telegram') and signIn('telegram-miniapp') snippets.
Same-workflow: email OTP / magic link when members skip social login.
See-also: community inbox SMTP is a separate plane from Auth Ring Mailer.
Use Founder / Developer tabs in the docs sidebar to filter this page.
Ring uses Auth.js v5 for JWT sessions and OAuth. Members can sign in with Ring Mailer (OTP / magic link / password), Google, Telegram (web OIDC or Mini App initData), Apple, or a crypto wallet. Email is not Resend — see Ring Mailer & RingdomX Mail.
| Layer | Role |
|---|---|
proxy.ts | Locale rewrite + optimistic redirect to ROUTES.LOGIN(locale) (cookie presence only) |
proxy.ts soft-gate | If JWT needsOnboarding === true, redirect to /{locale}/login/onboarding (exempt: /login*, /auth*, /register*, home /) |
(authenticated)/[locale]/layout.tsx | await auth() — canonical session gate |
(admin)/[locale]/layout.tsx | Role check (admin / superadmin) |
/login | LoginAuthenticatedRedirect — client useSession bounce (skips during OAuth callback params) |
/register | Redirects to /login (password signup demoted; OTP/magic is the product surface) |
| API routes | Per-handler auth() |
OAuth callbacks live under /api/auth/* (excluded from intl middleware). See Proxy and intl.
Login path SSOT: ROUTES.LOGIN(locale) with unified from / callbackUrl / returnTo (features/auth/components/login-authenticated-redirect.tsx).
After first sign-in, some providers require profile vitals (name, etc.) before the rest of the app. isVitalsGatedProvider() in features/auth/lib/vitals-onboarding.ts includes:
| Provider id | Gated? |
|---|---|
google, google-one-tap, apple | Yes |
email-otp, email-magic, telegram, crypto-wallet | Yes |
| Others | Not in the shared gate set |
Incomplete vitals set JWT/session needsOnboarding. Client redirects (email-login-form, verify-client, wallet-connect) and the proxy soft-gate both honor it. Own profile Avatar uses editable={true} so members can finish photo vitals on /profile.
| Provider | How members sign in |
|---|---|
| Ring Mailer | OTP, magic link (/verify#token=…), or password — Credentials email-otp / email-magic / credentials |
| OAuth redirect + Google One Tap (GIS JWT verified server-side) | |
| Telegram (web) | OIDC Authorization Code + PKCE at oauth.telegram.org — signIn('telegram') |
| Telegram Mini App | Credentials telegram-miniapp — signIn('telegram-miniapp', { initData, redirect: false }) |
| Apple | Sign in with Apple OAuth |
| Crypto wallet | Nonce + signature (crypto-wallet Credentials) |
GitHub/Discord OAuth are not in the default auth.ts provider list.
| Surface | Purpose | Crypto / secret |
|---|---|---|
| Login via Telegram (web) | Unauthenticated member opens a Ring session in the browser | OIDC id_token — AUTH_TELEGRAM_ID / AUTH_TELEGRAM_SECRET |
| Mini App initData | Silent session inside a Telegram WebApp client | HMAC with secret key WebAppData — bot API token (TELEGRAM_MINI_APP_BOT_TOKEN preferred) |
| Link Telegram (profile) | Already logged-in member binds Telegram id | Login Widget HMAC SHA256(bot_token) — ADMIN_BOT_TOKEN / TELEGRAM_LOGIN_BOT_TOKEN |
| Admin bot | Platform admins moderate from chat | Bot API + whitelist — Manage via Telegram |
Do not reuse Mini App initData (WebAppData) HMAC for Login Widget linking, and do not use Login Widget SHA256(bot_token) math for Mini App auth.
SMTP setup, Ethereal, calculator mail add-on, token migration 038.
Adapter selection, JWT callbacks, Telegram OIDC modules.
Integrator snippets for providers and mailer flows.
users.id); email can link accounts across providers when Auth.js linking is enabled. Telegram-only users may have an empty email (allowed by the partial unique index).https://your.domain) and OIDC callback https://your.domain/api/auth/callback/telegram..env.local as AUTH_TELEGRAM_ID / AUTH_TELEGRAM_SECRET.ADMIN_BOT_TOKEN or TELEGRAM_LOGIN_BOT_TOKEN) for profile “Link Telegram” widget hash — it is not the OIDC client secret.from URL).TELEGRAM_MINI_APP_BOT_TOKEN to that bot’s API token (preferred). Fallbacks used by getTelegramMiniAppBotToken(): TELEGRAM_BOT_TOKEN → ADMIN_BOT_TOKEN → TELEGRAM_LOGIN_BOT_TOKEN → N9LIFE_BOT_TOKEN.Deep-dive: Auth.js file split, adapters, OIDC + Mini App modules.
Next-step: copy-paste signIn('telegram') and signIn('telegram-miniapp') snippets.
Same-workflow: email OTP / magic link when members skip social login.
See-also: community inbox SMTP is a separate plane from Auth Ring Mailer.
Use Founder / Developer tabs in the docs sidebar to filter this page.
Ring uses Auth.js v5 for JWT sessions and OAuth. Members can sign in with Ring Mailer (OTP / magic link / password), Google, Telegram (web OIDC or Mini App initData), Apple, or a crypto wallet. Email is not Resend — see Ring Mailer & RingdomX Mail.
| Layer | Role |
|---|---|
proxy.ts | Locale rewrite + optimistic redirect to ROUTES.LOGIN(locale) (cookie presence only) |
proxy.ts soft-gate | If JWT needsOnboarding === true, redirect to /{locale}/login/onboarding (exempt: /login*, /auth*, /register*, home /) |
(authenticated)/[locale]/layout.tsx | await auth() — canonical session gate |
(admin)/[locale]/layout.tsx | Role check (admin / superadmin) |
/login | LoginAuthenticatedRedirect — client useSession bounce (skips during OAuth callback params) |
/register | Redirects to /login (password signup demoted; OTP/magic is the product surface) |
| API routes | Per-handler auth() |
OAuth callbacks live under /api/auth/* (excluded from intl middleware). See Proxy and intl.
Login path SSOT: ROUTES.LOGIN(locale) with unified from / callbackUrl / returnTo (features/auth/components/login-authenticated-redirect.tsx).
After first sign-in, some providers require profile vitals (name, etc.) before the rest of the app. isVitalsGatedProvider() in features/auth/lib/vitals-onboarding.ts includes:
| Provider id | Gated? |
|---|---|
google, google-one-tap, apple | Yes |
email-otp, email-magic, telegram, crypto-wallet | Yes |
| Others | Not in the shared gate set |
Incomplete vitals set JWT/session needsOnboarding. Client redirects (email-login-form, verify-client, wallet-connect) and the proxy soft-gate both honor it. Own profile Avatar uses editable={true} so members can finish photo vitals on /profile.
| Provider | How members sign in |
|---|---|
| Ring Mailer | OTP, magic link (/verify#token=…), or password — Credentials email-otp / email-magic / credentials |
| OAuth redirect + Google One Tap (GIS JWT verified server-side) | |
| Telegram (web) | OIDC Authorization Code + PKCE at oauth.telegram.org — signIn('telegram') |
| Telegram Mini App | Credentials telegram-miniapp — signIn('telegram-miniapp', { initData, redirect: false }) |
| Apple | Sign in with Apple OAuth |
| Crypto wallet | Nonce + signature (crypto-wallet Credentials) |
GitHub/Discord OAuth are not in the default auth.ts provider list.
| Surface | Purpose | Crypto / secret |
|---|---|---|
| Login via Telegram (web) | Unauthenticated member opens a Ring session in the browser | OIDC id_token — AUTH_TELEGRAM_ID / AUTH_TELEGRAM_SECRET |
| Mini App initData | Silent session inside a Telegram WebApp client | HMAC with secret key WebAppData — bot API token (TELEGRAM_MINI_APP_BOT_TOKEN preferred) |
| Link Telegram (profile) | Already logged-in member binds Telegram id | Login Widget HMAC SHA256(bot_token) — ADMIN_BOT_TOKEN / TELEGRAM_LOGIN_BOT_TOKEN |
| Admin bot | Platform admins moderate from chat | Bot API + whitelist — Manage via Telegram |
Do not reuse Mini App initData (WebAppData) HMAC for Login Widget linking, and do not use Login Widget SHA256(bot_token) math for Mini App auth.
SMTP setup, Ethereal, calculator mail add-on, token migration 038.
Adapter selection, JWT callbacks, Telegram OIDC modules.
Integrator snippets for providers and mailer flows.
users.id); email can link accounts across providers when Auth.js linking is enabled. Telegram-only users may have an empty email (allowed by the partial unique index).https://your.domain) and OIDC callback https://your.domain/api/auth/callback/telegram..env.local as AUTH_TELEGRAM_ID / AUTH_TELEGRAM_SECRET.ADMIN_BOT_TOKEN or TELEGRAM_LOGIN_BOT_TOKEN) for profile “Link Telegram” widget hash — it is not the OIDC client secret.from URL).TELEGRAM_MINI_APP_BOT_TOKEN to that bot’s API token (preferred). Fallbacks used by getTelegramMiniAppBotToken(): TELEGRAM_BOT_TOKEN → ADMIN_BOT_TOKEN → TELEGRAM_LOGIN_BOT_TOKEN → N9LIFE_BOT_TOKEN.Deep-dive: Auth.js file split, adapters, OIDC + Mini App modules.
Next-step: copy-paste signIn('telegram') and signIn('telegram-miniapp') snippets.
Same-workflow: email OTP / magic link when members skip social login.
See-also: community inbox SMTP is a separate plane from Auth Ring Mailer.
| Recurring / one-shot XTR invoice via SubscriptionConductor |
| Same Mini App bot token family — SubscriptionConductor |
signIn('telegram-miniapp', { initData, redirect: false })Telegram.WebApp.initData/tg-mini-appresolveOrCreateTelegramUser (accounts + communication.telegramId).Soft-launch OIDC scopes are openid profile — Ring reads Telegram id, name, username, and photo. Phone is not requested until you opt into the phone scope later. Mini App auth only uses fields present in verified initData (no phone by default).
Do not create a Resend API key. AUTH_RESEND_KEY is deprecated. Configure Auth SMTP_* or EMAIL_MODE=ethereal instead. CRM inbox SMTP is a separate channel plane — see Email AI-CRM.
Bookmarks to /register land on /login (locale + from / callbackUrl preserved). EmailSignupForm is removed from the auth barrel — use OTP / magic on the login form.
| Recurring / one-shot XTR invoice via SubscriptionConductor |
| Same Mini App bot token family — SubscriptionConductor |
signIn('telegram-miniapp', { initData, redirect: false })Telegram.WebApp.initData/tg-mini-appresolveOrCreateTelegramUser (accounts + communication.telegramId).Soft-launch OIDC scopes are openid profile — Ring reads Telegram id, name, username, and photo. Phone is not requested until you opt into the phone scope later. Mini App auth only uses fields present in verified initData (no phone by default).
Do not create a Resend API key. AUTH_RESEND_KEY is deprecated. Configure Auth SMTP_* or EMAIL_MODE=ethereal instead. CRM inbox SMTP is a separate channel plane — see Email AI-CRM.
Bookmarks to /register land on /login (locale + from / callbackUrl preserved). EmailSignupForm is removed from the auth barrel — use OTP / magic on the login form.
| Recurring / one-shot XTR invoice via SubscriptionConductor |
| Same Mini App bot token family — SubscriptionConductor |
signIn('telegram-miniapp', { initData, redirect: false })Telegram.WebApp.initData/tg-mini-appresolveOrCreateTelegramUser (accounts + communication.telegramId).Soft-launch OIDC scopes are openid profile — Ring reads Telegram id, name, username, and photo. Phone is not requested until you opt into the phone scope later. Mini App auth only uses fields present in verified initData (no phone by default).
Do not create a Resend API key. AUTH_RESEND_KEY is deprecated. Configure Auth SMTP_* or EMAIL_MODE=ethereal instead. CRM inbox SMTP is a separate channel plane — see Email AI-CRM.
Bookmarks to /register land on /login (locale + from / callbackUrl preserved). EmailSignupForm is removed from the auth barrel — use OTP / magic on the login form.