135 lines
3.4 KiB
Dart
135 lines
3.4 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:mileograph_flutter/objects/objects.dart';
|
|
import 'package:mileograph_flutter/services/apiService.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
class AuthService extends ChangeNotifier {
|
|
final ApiService api;
|
|
static const _tokenKey = 'auth_token';
|
|
bool _restoring = false;
|
|
|
|
AuthService({required this.api});
|
|
|
|
AuthenticatedUserData? _user;
|
|
|
|
bool get isLoggedIn => _user != null;
|
|
String? get token => _user?.access_token;
|
|
String? get userId => _user?.user_id;
|
|
String? get username => _user?.username;
|
|
String? get fullName => _user?.full_name;
|
|
|
|
void setLoginData({
|
|
required String userId,
|
|
required String username,
|
|
required String fullName,
|
|
required String accessToken,
|
|
required String email,
|
|
}) {
|
|
_user = AuthenticatedUserData(
|
|
user_id: userId,
|
|
username: username,
|
|
full_name: fullName,
|
|
access_token: accessToken,
|
|
email: email,
|
|
);
|
|
_persistToken(accessToken);
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> login(String username, String password) async {
|
|
final formData = {
|
|
'grant_type': 'password',
|
|
'username': username,
|
|
'password': password,
|
|
'scope': '',
|
|
'client_id': 'string',
|
|
'client_secret': 'string',
|
|
};
|
|
|
|
// 1. Get token
|
|
final tokenResponse = await api.postForm('/token', formData);
|
|
final accessToken = tokenResponse['access_token'];
|
|
|
|
// 2. Get user details
|
|
final userResponse = await api.get(
|
|
'/users/me',
|
|
headers: {
|
|
'Authorization': 'Bearer $accessToken',
|
|
'accept': 'application/json',
|
|
},
|
|
);
|
|
|
|
// 3. Populate state
|
|
setLoginData(
|
|
userId: userResponse['user_id'],
|
|
username: userResponse['username'],
|
|
fullName: userResponse['full_name'],
|
|
accessToken: accessToken,
|
|
email: userResponse['email'],
|
|
);
|
|
}
|
|
|
|
Future<void> tryRestoreSession() async {
|
|
if (_restoring || _user != null) return;
|
|
_restoring = true;
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final token = prefs.getString(_tokenKey);
|
|
if (token == null || token.isEmpty) return;
|
|
final userResponse = await api.get(
|
|
'/users/me',
|
|
headers: {
|
|
'Authorization': 'Bearer $token',
|
|
'accept': 'application/json',
|
|
},
|
|
);
|
|
setLoginData(
|
|
userId: userResponse['user_id'],
|
|
username: userResponse['username'],
|
|
fullName: userResponse['full_name'],
|
|
accessToken: token,
|
|
email: userResponse['email'],
|
|
);
|
|
} catch (_) {
|
|
await _clearToken();
|
|
} finally {
|
|
_restoring = false;
|
|
}
|
|
}
|
|
|
|
Future<void> _persistToken(String token) async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.setString(_tokenKey, token);
|
|
}
|
|
|
|
Future<void> _clearToken() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.remove(_tokenKey);
|
|
}
|
|
|
|
Future<void> register({
|
|
required String username,
|
|
required String email,
|
|
required String fullName,
|
|
required String password,
|
|
String inviteCode = '',
|
|
}) async {
|
|
final formData = {
|
|
'user_name': username,
|
|
'email': email,
|
|
'full_name': fullName,
|
|
'password': password,
|
|
'invitation_code': inviteCode,
|
|
'empty': '',
|
|
'empty2': '',
|
|
};
|
|
await api.postForm('/register', formData);
|
|
}
|
|
|
|
void logout() {
|
|
_user = null;
|
|
_clearToken();
|
|
notifyListeners();
|
|
}
|
|
}
|