2022-07-27 14:29:47 +08:00
|
|
|
import 'dart:async';
|
|
|
|
import 'dart:convert';
|
|
|
|
|
2023-06-17 20:48:58 +08:00
|
|
|
import 'package:flutter/material.dart';
|
2023-01-06 18:26:19 +08:00
|
|
|
import 'package:flutter_hbb/common/hbbs/hbbs.dart';
|
2022-12-11 21:40:35 +08:00
|
|
|
import 'package:flutter_hbb/common/widgets/peer_tab_page.dart';
|
2022-07-27 14:29:47 +08:00
|
|
|
import 'package:get/get.dart';
|
|
|
|
import 'package:http/http.dart' as http;
|
|
|
|
|
2022-09-27 17:52:36 +08:00
|
|
|
import '../common.dart';
|
2022-07-27 14:29:47 +08:00
|
|
|
import 'model.dart';
|
2022-08-03 22:03:31 +08:00
|
|
|
import 'platform_model.dart';
|
2022-07-27 14:29:47 +08:00
|
|
|
|
2022-10-09 18:41:50 +08:00
|
|
|
class UserModel {
|
2022-12-11 21:40:35 +08:00
|
|
|
final RxString userName = ''.obs;
|
|
|
|
final RxBool isAdmin = false.obs;
|
2022-07-27 14:29:47 +08:00
|
|
|
WeakReference<FFI> parent;
|
|
|
|
|
2022-12-11 21:40:35 +08:00
|
|
|
UserModel(this.parent);
|
2022-10-09 18:41:50 +08:00
|
|
|
|
|
|
|
void refreshCurrentUser() async {
|
2022-11-10 21:25:12 +08:00
|
|
|
final token = bind.mainGetLocalOption(key: 'access_token');
|
2022-12-11 21:40:35 +08:00
|
|
|
if (token == '') {
|
2023-06-21 18:28:52 +08:00
|
|
|
await updateOtherModels();
|
2022-12-11 21:40:35 +08:00
|
|
|
return;
|
|
|
|
}
|
2023-06-21 11:39:48 +08:00
|
|
|
_updateLocalUserInfo();
|
2022-10-09 18:41:50 +08:00
|
|
|
final url = await bind.mainGetApiServer();
|
|
|
|
final body = {
|
|
|
|
'id': await bind.mainGetMyId(),
|
|
|
|
'uuid': await bind.mainGetUuid()
|
|
|
|
};
|
|
|
|
try {
|
|
|
|
final response = await http.post(Uri.parse('$url/api/currentUser'),
|
|
|
|
headers: {
|
2022-10-22 22:19:14 +08:00
|
|
|
'Content-Type': 'application/json',
|
|
|
|
'Authorization': 'Bearer $token'
|
2022-10-09 18:41:50 +08:00
|
|
|
},
|
|
|
|
body: json.encode(body));
|
|
|
|
final status = response.statusCode;
|
|
|
|
if (status == 401 || status == 400) {
|
2022-12-11 21:40:35 +08:00
|
|
|
reset();
|
2022-10-09 18:41:50 +08:00
|
|
|
return;
|
|
|
|
}
|
2023-06-18 13:53:03 +08:00
|
|
|
final data = json.decode(utf8.decode(response.bodyBytes));
|
2022-12-11 21:40:35 +08:00
|
|
|
final error = data['error'];
|
|
|
|
if (error != null) {
|
|
|
|
throw error;
|
|
|
|
}
|
2023-01-06 18:26:19 +08:00
|
|
|
|
|
|
|
final user = UserPayload.fromJson(data);
|
2023-06-21 11:32:50 +08:00
|
|
|
_parseAndUpdateUser(user);
|
2022-10-09 18:41:50 +08:00
|
|
|
} catch (e) {
|
|
|
|
print('Failed to refreshCurrentUser: $e');
|
2022-12-11 21:40:35 +08:00
|
|
|
} finally {
|
2023-06-21 18:28:52 +08:00
|
|
|
await updateOtherModels();
|
2022-10-09 18:41:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-21 11:32:50 +08:00
|
|
|
static Map<String, dynamic>? getLocalUserInfo() {
|
|
|
|
try {
|
|
|
|
return json.decode(bind.mainGetLocalOption(key: 'user_info'));
|
|
|
|
} catch (e) {
|
|
|
|
print('Failed to get local user info: $e');
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
_updateLocalUserInfo() {
|
|
|
|
final userInfo = getLocalUserInfo();
|
|
|
|
if (userInfo != null) {
|
|
|
|
userName.value = userInfo['name'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-11 21:40:35 +08:00
|
|
|
Future<void> reset() async {
|
2022-10-22 22:19:14 +08:00
|
|
|
await bind.mainSetLocalOption(key: 'access_token', value: '');
|
2022-12-11 21:40:35 +08:00
|
|
|
await gFFI.abModel.reset();
|
|
|
|
await gFFI.groupModel.reset();
|
2022-10-22 22:19:14 +08:00
|
|
|
userName.value = '';
|
2023-02-03 15:07:45 +08:00
|
|
|
gFFI.peerTabModel.check_dynamic_tabs();
|
2022-10-09 18:41:50 +08:00
|
|
|
}
|
|
|
|
|
2023-06-21 11:32:50 +08:00
|
|
|
_parseAndUpdateUser(UserPayload user) {
|
2023-01-06 18:26:19 +08:00
|
|
|
userName.value = user.name;
|
|
|
|
isAdmin.value = user.isAdmin;
|
2022-10-09 18:41:50 +08:00
|
|
|
}
|
2022-07-27 14:29:47 +08:00
|
|
|
|
2023-06-21 18:28:52 +08:00
|
|
|
// update ab and group status
|
|
|
|
static Future<void> updateOtherModels() async {
|
2022-12-11 21:40:35 +08:00
|
|
|
await gFFI.abModel.pullAb();
|
|
|
|
await gFFI.groupModel.pull();
|
2022-07-27 14:29:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> logOut() async {
|
2022-10-09 18:57:38 +08:00
|
|
|
final tag = gFFI.dialogManager.showLoading(translate('Waiting'));
|
2022-12-16 22:18:30 +08:00
|
|
|
try {
|
|
|
|
final url = await bind.mainGetApiServer();
|
2023-01-28 21:02:42 +08:00
|
|
|
final authHeaders = getHttpHeaders();
|
|
|
|
authHeaders['Content-Type'] = "application/json";
|
2022-12-20 22:36:04 +08:00
|
|
|
await http
|
|
|
|
.post(Uri.parse('$url/api/logout'),
|
2023-01-28 21:02:42 +08:00
|
|
|
body: jsonEncode({
|
2022-12-20 22:36:04 +08:00
|
|
|
'id': await bind.mainGetMyId(),
|
|
|
|
'uuid': await bind.mainGetUuid(),
|
2023-01-28 21:02:42 +08:00
|
|
|
}),
|
|
|
|
headers: authHeaders)
|
2022-12-20 22:36:04 +08:00
|
|
|
.timeout(Duration(seconds: 2));
|
|
|
|
} catch (e) {
|
|
|
|
print("request /api/logout failed: err=$e");
|
2022-12-16 22:18:30 +08:00
|
|
|
} finally {
|
|
|
|
await reset();
|
|
|
|
gFFI.dialogManager.dismissByTag(tag);
|
|
|
|
}
|
2022-07-27 14:29:47 +08:00
|
|
|
}
|
|
|
|
|
2023-01-06 18:26:19 +08:00
|
|
|
/// throw [RequestException]
|
|
|
|
Future<LoginResponse> login(LoginRequest loginRequest) async {
|
2022-07-27 14:29:47 +08:00
|
|
|
final url = await bind.mainGetApiServer();
|
2023-01-06 18:26:19 +08:00
|
|
|
final resp = await http.post(Uri.parse('$url/api/login'),
|
|
|
|
headers: {'Content-Type': 'application/json'},
|
|
|
|
body: jsonEncode(loginRequest.toJson()));
|
|
|
|
|
|
|
|
final Map<String, dynamic> body;
|
2022-07-27 14:29:47 +08:00
|
|
|
try {
|
2023-06-18 13:53:03 +08:00
|
|
|
body = jsonDecode(utf8.decode(resp.bodyBytes));
|
2023-01-06 18:26:19 +08:00
|
|
|
} catch (e) {
|
2023-06-14 15:17:20 +08:00
|
|
|
print("login: jsonDecode resp body failed: ${e.toString()}");
|
2023-01-06 18:26:19 +08:00
|
|
|
rethrow;
|
|
|
|
}
|
|
|
|
if (resp.statusCode != 200) {
|
|
|
|
throw RequestException(resp.statusCode, body['error'] ?? '');
|
2022-07-27 14:29:47 +08:00
|
|
|
}
|
2023-01-06 18:26:19 +08:00
|
|
|
|
2023-06-21 11:32:50 +08:00
|
|
|
return getLoginResponseFromAuthBody(body);
|
|
|
|
}
|
|
|
|
|
|
|
|
LoginResponse getLoginResponseFromAuthBody(Map<String, dynamic> body) {
|
2023-01-06 18:26:19 +08:00
|
|
|
final LoginResponse loginResponse;
|
|
|
|
try {
|
|
|
|
loginResponse = LoginResponse.fromJson(body);
|
|
|
|
} catch (e) {
|
2023-06-14 15:17:20 +08:00
|
|
|
print("login: jsonDecode LoginResponse failed: ${e.toString()}");
|
2023-01-06 18:26:19 +08:00
|
|
|
rethrow;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (loginResponse.user != null) {
|
2023-06-21 11:32:50 +08:00
|
|
|
_parseAndUpdateUser(loginResponse.user!);
|
2023-01-06 18:26:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return loginResponse;
|
2022-07-27 14:29:47 +08:00
|
|
|
}
|
2023-06-14 15:17:20 +08:00
|
|
|
|
|
|
|
static Future<List<dynamic>> queryLoginOptions() async {
|
|
|
|
try {
|
2023-06-15 15:28:53 +08:00
|
|
|
final url = await bind.mainGetApiServer();
|
|
|
|
final resp = await http.get(Uri.parse('$url/api/login-options'));
|
2023-06-14 15:17:20 +08:00
|
|
|
return jsonDecode(resp.body);
|
|
|
|
} catch (e) {
|
|
|
|
print("queryLoginOptions: jsonDecode resp body failed: ${e.toString()}");
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
}
|
2022-07-27 14:29:47 +08:00
|
|
|
}
|