ios build, connected data (not finished)
This commit is contained in:
@@ -1,46 +1,114 @@
|
||||
import 'package:flutter_appauth/flutter_appauth.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http_interceptor/http_interceptor.dart';
|
||||
import 'package:jwt_decoder/jwt_decoder.dart';
|
||||
import '../models/user_profile.dart';
|
||||
import '../utils/logging_interceptor.dart';
|
||||
|
||||
class AuthService {
|
||||
static const String _tokenKey = 'auth_token';
|
||||
static const String _refreshTokenKey = 'refresh_token';
|
||||
static const String _tokenEndpoint = 'https://auth.goutezplanb.com/realms/planb-internal/protocol/openid-connect/token';
|
||||
static const String _clientId = 'delivery-mobile-app';
|
||||
|
||||
final FlutterAppAuth _appAuth;
|
||||
final FlutterSecureStorage _secureStorage;
|
||||
final http.Client _httpClient;
|
||||
|
||||
AuthService({
|
||||
FlutterAppAuth? appAuth,
|
||||
FlutterSecureStorage? secureStorage,
|
||||
}) : _appAuth = appAuth ?? const FlutterAppAuth(),
|
||||
_secureStorage = secureStorage ?? const FlutterSecureStorage();
|
||||
|
||||
Future<AuthResult> login() async {
|
||||
try {
|
||||
final result = await _appAuth.authorizeAndExchangeCode(
|
||||
AuthorizationTokenRequest(
|
||||
'delivery-mobile-app',
|
||||
'com.goutezplanb.delivery://callback',
|
||||
discoveryUrl: 'https://auth.goutezplanb.com/realms/planb-internal/.well-known/openid-configuration',
|
||||
scopes: const ['openid', 'profile', 'offline_access'],
|
||||
promptValues: const ['login'],
|
||||
http.Client? httpClient,
|
||||
}) : _secureStorage = secureStorage ?? const FlutterSecureStorage(
|
||||
aOptions: AndroidOptions(
|
||||
encryptedSharedPreferences: true,
|
||||
),
|
||||
iOptions: IOSOptions(
|
||||
accessibility: KeychainAccessibility.first_unlock,
|
||||
),
|
||||
mOptions: MacOsOptions(
|
||||
accessibility: KeychainAccessibility.first_unlock,
|
||||
),
|
||||
),
|
||||
_httpClient = httpClient ?? InterceptedClient.build(
|
||||
interceptors: [LoggingInterceptor()],
|
||||
);
|
||||
|
||||
Future<AuthResult> login({
|
||||
required String username,
|
||||
required String password,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _httpClient.post(
|
||||
Uri.parse(_tokenEndpoint),
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: {
|
||||
'grant_type': 'password',
|
||||
'client_id': _clientId,
|
||||
'username': username,
|
||||
'password': password,
|
||||
'scope': 'openid profile offline_access',
|
||||
},
|
||||
);
|
||||
|
||||
// ignore: unnecessary_null_comparison
|
||||
if (result == null) {
|
||||
return const AuthResult.cancelled();
|
||||
}
|
||||
if (response.statusCode == 200) {
|
||||
final data = json.decode(response.body) as Map<String, dynamic>;
|
||||
final accessToken = data['access_token'] as String;
|
||||
final refreshToken = data['refresh_token'] as String?;
|
||||
|
||||
await _secureStorage.write(key: _tokenKey, value: result.accessToken ?? '');
|
||||
if (result.refreshToken != null) {
|
||||
await _secureStorage.write(key: _refreshTokenKey, value: result.refreshToken!);
|
||||
}
|
||||
await _secureStorage.write(key: _tokenKey, value: accessToken);
|
||||
if (refreshToken != null) {
|
||||
await _secureStorage.write(key: _refreshTokenKey, value: refreshToken);
|
||||
}
|
||||
|
||||
return AuthResult.success(token: result.accessToken ?? '');
|
||||
return AuthResult.success(token: accessToken);
|
||||
} else if (response.statusCode == 401) {
|
||||
return AuthResult.error(error: 'Invalid username or password');
|
||||
} else {
|
||||
return AuthResult.error(error: 'Authentication failed: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
return AuthResult.error(error: e.toString());
|
||||
return AuthResult.error(error: 'Network error: ${e.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
Future<AuthResult> refreshAccessToken() async {
|
||||
try {
|
||||
final refreshToken = await getRefreshToken();
|
||||
if (refreshToken == null) {
|
||||
return AuthResult.error(error: 'No refresh token available');
|
||||
}
|
||||
|
||||
final response = await _httpClient.post(
|
||||
Uri.parse(_tokenEndpoint),
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: {
|
||||
'grant_type': 'refresh_token',
|
||||
'client_id': _clientId,
|
||||
'refresh_token': refreshToken,
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = json.decode(response.body) as Map<String, dynamic>;
|
||||
final accessToken = data['access_token'] as String;
|
||||
final newRefreshToken = data['refresh_token'] as String?;
|
||||
|
||||
await _secureStorage.write(key: _tokenKey, value: accessToken);
|
||||
if (newRefreshToken != null) {
|
||||
await _secureStorage.write(key: _refreshTokenKey, value: newRefreshToken);
|
||||
}
|
||||
|
||||
return AuthResult.success(token: accessToken);
|
||||
} else {
|
||||
await logout();
|
||||
return AuthResult.error(error: 'Token refresh failed');
|
||||
}
|
||||
} catch (e) {
|
||||
return AuthResult.error(error: 'Token refresh error: ${e.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user