4.7 KiB
4.7 KiB
title, tags
| title | tags | |||||
|---|---|---|---|---|---|---|
| Task 5.10 Telegram First-Class Authentication |
|
Task 5.10 Telegram First-Class Authentication
Date: 2026-05-24
Scope
Task 5.10 implemented Telegram as a first-class Amanat auth provider.
- Backend now exposes
POST /api/auth/telegram. - The endpoint accepts Telegram Mini App
initDataor Telegram Login Widget payloads. - Telegram signatures are verified server-side.
- Telegram-only users can be created without email/password.
- Standard Amanat JWT and refresh tokens are returned.
- Frontend Mini App sessions auto-authenticate from raw signed
initData. - The web login view includes a Telegram continuation button.
Backend Implementation
Changed project: backend
src/models/User.tsemailis now optional with a sparse unique index.- Added
authProvider: "email" | "google" | "telegram". - Added
telegramVerified.
src/models/TelegramLink.ts- Added
login_widgetas a supported source.
- Added
src/services/telegram/telegramService.ts- Added Telegram Login Widget verification.
- Added normalized Telegram auth identity helpers.
src/services/auth/authController.ts- Added
telegramAuth. - Auto-provisions Telegram users with nullable email.
- Rejects replayed Mini App data, stale auth dates, invalid signatures, bot accounts, blocked links, and inactive users.
- Added
src/services/auth/authRoutes.ts- Added public
POST /telegram, mounted externally as/api/auth/telegram.
- Added public
Frontend Implementation
Changed project: frontend
src/lib/axios.ts- Added
/auth/telegramas a public endpoint. - Added
endpoints.auth.telegram.
- Added
src/auth/context/jwt/action.ts- Added
signInWithTelegram. - Stores returned access/refresh tokens using the existing auth storage path.
- Added
src/sections/telegram/telegram-mini-app-shell.tsx- Auto-authenticates Mini App sessions once from raw
initData. - Shows an onboarding dialog for newly provisioned Telegram accounts.
- Keeps standard sign-in/dashboard fallbacks.
- Auto-authenticates Mini App sessions once from raw
src/auth/components/form-socials.tsx- Added Telegram icon button.
src/auth/view/jwt/jwt-sign-in-view.tsx- Added Telegram sign-in handler for both Mini App
initDataand browser Login Widget payloads.
- Added Telegram sign-in handler for both Mini App
Security Notes
- Frontend never trusts
initDataUnsafefor auth; it only sends raw signedinitData. - Backend validates Telegram HMAC signatures using the configured bot token.
- Mini App
auth_datefreshness and replay window are enforced before JWT issuance. - Login Widget
auth_datefreshness is enforced. - Telegram bot accounts are rejected.
- Blocked
TelegramLinkrecords are rejected with 403. - Telegram phone numbers are neither requested nor persisted.
- High-risk escrow and wallet actions still use the existing protected API and step-up rules.
Verification
Backend:
npm run typecheck
npx jest __tests__/telegram-auth.test.ts __tests__/telegram-service.test.ts --runInBand --forceExit
Result:
- Backend typecheck passed.
__tests__/telegram-auth.test.tspassed.__tests__/telegram-service.test.tspassed.- 14 targeted backend tests passed.
Frontend:
npm test -- __tests__/auth/telegram-auth-action.test.ts __tests__/sections/telegram/telegram-mini-app-shell.test.tsx --runInBand
npx tsc --noEmit -p tsconfig.json
Result:
- Targeted frontend Jest tests passed.
- 7 targeted frontend tests passed.
- Full frontend typecheck still reports unrelated pre-existing errors in payment UI code outside Task 5.10:
src/components/payment/shkeeper-payment-widget.tsxsrc/web3/components/provider-payment.tsx
Acceptance Coverage
| Requirement | Status |
|---|---|
| New Telegram user auto-provisions and receives JWT | Covered by backend test |
| Returning user authenticates via Mini App initData | Covered through same route and link lookup |
| Returning user authenticates via Login Widget | Covered by backend test |
| Replayed Mini App initData rejected | Covered by backend test |
Stale auth_date rejected |
Covered by backend test |
| Blocked Telegram account returns 403 | Covered by backend test |
| Existing email/password users unaffected | Covered by backend test |
| Email optional for Telegram users | Covered by backend test and sparse user model |
isNewUser triggers onboarding overlay |
Covered by frontend shell behavior |
| High-risk actions retain step-up requirements | No high-risk action code changed |
Operational Follow-up
If a deployed MongoDB already has an old non-sparse unique email index, replace it with the sparse unique index before creating multiple Telegram-only users:
db.users.dropIndex("email_1")
db.users.createIndex({ email: 1 }, { unique: true, sparse: true })
Run this only after confirming the existing index name in the target database.