Files
nick-doc/09 - Audits/Task 5.10 Telegram First-Class Authentication.md
2026-05-24 16:15:40 +04:00

4.7 KiB

title, tags
title tags
Task 5.10 Telegram First-Class Authentication
audit
taskmaster
telegram
auth
testing

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 initData or 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.ts
    • email is now optional with a sparse unique index.
    • Added authProvider: "email" | "google" | "telegram".
    • Added telegramVerified.
  • src/models/TelegramLink.ts
    • Added login_widget as a supported source.
  • 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.
  • src/services/auth/authRoutes.ts
    • Added public POST /telegram, mounted externally as /api/auth/telegram.

Frontend Implementation

Changed project: frontend

  • src/lib/axios.ts
    • Added /auth/telegram as a public endpoint.
    • Added endpoints.auth.telegram.
  • src/auth/context/jwt/action.ts
    • Added signInWithTelegram.
    • Stores returned access/refresh tokens using the existing auth storage path.
  • 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.
  • 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 initData and browser Login Widget payloads.

Security Notes

  • Frontend never trusts initDataUnsafe for auth; it only sends raw signed initData.
  • Backend validates Telegram HMAC signatures using the configured bot token.
  • Mini App auth_date freshness and replay window are enforced before JWT issuance.
  • Login Widget auth_date freshness is enforced.
  • Telegram bot accounts are rejected.
  • Blocked TelegramLink records 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.ts passed.
  • __tests__/telegram-service.test.ts passed.
  • 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.tsx
    • src/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.