auto login

This commit is contained in:
Dmitry 2025-11-28 00:06:26 +03:00
parent a3a63fea61
commit a807d0f90f
7 changed files with 155 additions and 16 deletions

View file

@ -38,6 +38,6 @@ _flutter.buildConfig = {"engineRevision":"d3d45dcf251823c1769909cd43698d126db38d
_flutter.loader.load({ _flutter.loader.load({
serviceWorkerSettings: { serviceWorkerSettings: {
serviceWorkerVersion: "2889484362" serviceWorkerVersion: "3923216343"
} }
}); });

View file

@ -2,6 +2,7 @@ import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mnemo_cards_web_v2/di/user_scope/user_scope.dart'; import 'package:mnemo_cards_web_v2/di/user_scope/user_scope.dart';
import 'package:telegram_web_app/telegram_web_app.dart';
import 'package:yx_scope_flutter/yx_scope_flutter.dart'; import 'package:yx_scope_flutter/yx_scope_flutter.dart';
import 'package:yx_state_flutter/yx_state_flutter.dart'; import 'package:yx_state_flutter/yx_state_flutter.dart';
@ -65,10 +66,47 @@ class _AppInitializerState extends State<_AppInitializer> {
} }
} }
Future<void> _tryTelegramWebAppAuth() async {
try {
log('Checking Telegram Web App authentication...', name: 'App');
// Try to authenticate with Telegram Web App
final user = await widget.appScope.authService.loginWithTelegramWebApp();
if (user != null) {
log('Telegram Web App authentication successful', name: 'App');
// Create UserScope if it doesn't exist
if (widget.appScope.userScopeHolder.scope == null) {
await widget.appScope.userScopeHolder.create();
}
// Set authenticated user
final userScope = widget.appScope.userScopeHolder.scope;
if (userScope != null) {
userScope.userStateManager.setUser(user);
// Notify router about auth change
widget.appScope.userScopeHolder.notifyAuthChanged();
}
// Don't continue with normal auto-login if Telegram auth succeeded
return;
} else {
log('Telegram Web App authentication not available or failed', name: 'App');
}
} catch (e, s) {
log('Error during Telegram Web App authentication', error: e, stackTrace: s);
// Continue with normal flow - this is not a critical error
}
}
Future<void> _initialize() async { Future<void> _initialize() async {
try { try {
log('Starting app initialization...', name: 'App'); log('Starting app initialization...', name: 'App');
// Try Telegram Web App authentication first
await _tryTelegramWebAppAuth();
// Try auto-login first with timeout // Try auto-login first with timeout
log('Attempting auto-login...', name: 'App'); log('Attempting auto-login...', name: 'App');
UserDto? user; UserDto? user;
@ -89,7 +127,7 @@ class _AppInitializerState extends State<_AppInitializer> {
log('Creating UserScope...', name: 'App'); log('Creating UserScope...', name: 'App');
await widget.appScope.userScopeHolder.create(); await widget.appScope.userScopeHolder.create();
} }
if (user != null) { if (user != null) {
log('Auto-login successful, creating UserScope', name: 'App'); log('Auto-login successful, creating UserScope', name: 'App');
// Create UserScope only for authenticated users // Create UserScope only for authenticated users

View file

@ -5,6 +5,7 @@ import 'package:google_sign_in/google_sign_in.dart';
import 'package:mnemo_cards_common/mnemo_cards_common.dart'; import 'package:mnemo_cards_common/mnemo_cards_common.dart';
import 'package:mnemo_cards_web_v2/domain/models/telegram_auth_code_status.dart'; import 'package:mnemo_cards_web_v2/domain/models/telegram_auth_code_status.dart';
import 'package:mnemo_cards_web_v2/domain/services/http_repository_v2.dart'; import 'package:mnemo_cards_web_v2/domain/services/http_repository_v2.dart';
import 'package:telegram_web_app/telegram_web_app.dart';
/// Service for user authentication /// Service for user authentication
/// ///
@ -22,6 +23,53 @@ class AuthService {
final GoogleSignIn _googleSignIn; final GoogleSignIn _googleSignIn;
final HttpRepositoryV2 _httpRepository; final HttpRepositoryV2 _httpRepository;
/// Login with Telegram Web App
///
/// Automatically authenticates user using Telegram Web App data
/// Returns the authenticated user or null if login failed
Future<UserDto?> loginWithTelegramWebApp() async {
try {
log('Starting Telegram Web App authentication', name: 'AuthService');
// Check if Telegram Web App is supported
if (!TelegramWebApp.instance.isSupported) {
log('Telegram Web App is not supported', name: 'AuthService');
return null;
}
// Get init data from Telegram Web App
final webAppData = TelegramWebApp.instance;
final initData = webAppData.initData.toString();
if (initData.isEmpty) {
log('No Telegram Web App init data available', name: 'AuthService');
return null;
}
log('Telegram Web App init data received, sending to backend', name: 'AuthService');
// Authenticate with backend using Telegram Web App data
final authResponse = await _httpRepository.authenticateWithTelegramWebApp(
initData: initData,
);
if (authResponse == null) {
log('Telegram Web App authentication failed - no response', name: 'AuthService');
return null;
}
log('Telegram Web App authentication successful', name: 'AuthService');
return authResponse.user;
} catch (e, s) {
log(
'Error during Telegram Web App authentication',
error: e,
stackTrace: s,
name: 'AuthService',
);
return null;
}
}
/// Login with Google account /// Login with Google account
/// ///
/// Returns the authenticated user or null if login failed/cancelled /// Returns the authenticated user or null if login failed/cancelled

View file

@ -394,6 +394,56 @@ class HttpRepositoryV2 {
// ==================== Authentication Endpoints ==================== // ==================== Authentication Endpoints ====================
/// Authenticate with Telegram Web App
/// Returns auth response with user, access token, and refresh token
Future<AuthResponseV2?> authenticateWithTelegramWebApp({
required String initData,
}) async {
try {
final response = await _dio.post<Map<String, dynamic>>(
'/auth/telegram/web-app',
data: {'initData': initData},
);
if (response.data != null) {
final data = response.data!;
final userDto = UserDto.fromJson(data['user'] as Map<String, dynamic>);
final accessToken = data['accessToken'] as String;
final refreshToken = data['refreshToken'] as String;
final expiresIn = data['expiresIn'] as int?;
// Save tokens
await saveTokens(
accessToken: accessToken,
refreshToken: refreshToken,
expiresIn: expiresIn,
);
final expiresAt = expiresIn != null
? DateTime.now().add(Duration(seconds: expiresIn))
: null;
return AuthResponseV2(
user: userDto,
accessToken: accessToken,
refreshToken: refreshToken,
expiresAt: expiresAt,
);
}
return null;
} on DioException catch (e) {
if (e.error is ApiException) {
rethrow;
}
throw NetworkException(
message: e.message ?? 'Failed to authenticate with Telegram Web App',
originalError: e,
);
}
}
/// Authenticate with Google ID token /// Authenticate with Google ID token
/// Returns auth response with user, access token, and refresh token /// Returns auth response with user, access token, and refresh token
Future<AuthResponseV2> authenticateWithGoogle(String googleIdToken) async { Future<AuthResponseV2> authenticateWithGoogle(String googleIdToken) async {

View file

@ -2,9 +2,7 @@ import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
// Telegram integration temporarily disabled due to compilation errors import 'package:telegram_web_app/telegram_web_app.dart';
// TODO: Re-enable when telegram_web_app package is updated
// import 'package:telegram_web_app/telegram_web_app.dart';
import 'app.dart'; import 'app.dart';
import 'di/app_scope/app_scope_holder.dart'; import 'di/app_scope/app_scope_holder.dart';
@ -15,13 +13,12 @@ final scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
// Telegram Web App integration temporarily disabled // Telegram Web App integration
// TODO: Re-enable when telegram_web_app package is updated if (TelegramWebApp.instance.isSupported) {
// if (TelegramWebApp.instance.isSupported) { TelegramWebApp.instance.ready();
// TelegramWebApp.instance.ready(); await Future<void>.delayed(const Duration(seconds: 1));
// await Future<void>.delayed(const Duration(seconds: 1)); TelegramWebApp.instance.disableVerticalSwipes();
// TelegramWebApp.instance.disableVerticalSwipes(); }
// }
// Настройка логирования ошибок // Настройка логирования ошибок
FlutterError.onError = (details) { FlutterError.onError = (details) {

View file

@ -1216,6 +1216,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.1" version: "1.4.1"
telegram_web_app:
dependency: "direct main"
description:
name: telegram_web_app
sha256: "5c33aaa07d776552ce55b49b401d0e835115fbeb136877c6d19b3b1491000535"
url: "https://pub.dev"
source: hosted
version: "0.3.3"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:

View file

@ -11,9 +11,7 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
# Telegram integration temporarily disabled due to compilation errors telegram_web_app: ^0.3.3
# TODO: Re-enable when package is updated or find alternative
# telegram_web_app: ^0.3.3
# YX Framework # YX Framework
yx_scope: ^1.1.2 yx_scope: ^1.1.2