diff --git a/flutter/lib/common/widgets/address_book.dart b/flutter/lib/common/widgets/address_book.dart index 1b26acb57..c37fe9ccb 100644 --- a/flutter/lib/common/widgets/address_book.dart +++ b/flutter/lib/common/widgets/address_book.dart @@ -54,6 +54,9 @@ class _AddressBookState extends State { if (gFFI.abModel.abError.isNotEmpty) { return _buildShowError(gFFI.abModel.abError.value); } + if (gFFI.userModel.fromServer.isFalse) { + return Offstage(); + } return isDesktop ? _buildAddressBookDesktop() : _buildAddressBookMobile(); diff --git a/flutter/lib/common/widgets/login.dart b/flutter/lib/common/widgets/login.dart index c9ac48069..59c4d3c4a 100644 --- a/flutter/lib/common/widgets/login.dart +++ b/flutter/lib/common/widgets/login.dart @@ -96,7 +96,7 @@ class ConfigOP { class WidgetOP extends StatefulWidget { final ConfigOP config; final RxString curOP; - final Function(String) cbLogin; + final Function(Map) cbLogin; const WidgetOP({ Key? key, required this.config, @@ -153,9 +153,8 @@ class _WidgetOPState extends State { } if (authBody != null) { _updateTimer?.cancel(); - final String username = authBody['user']['name']; widget.curOP.value = ''; - widget.cbLogin(username); + widget.cbLogin(authBody as Map); } setState(() { @@ -255,7 +254,7 @@ class _WidgetOPState extends State { class LoginWidgetOP extends StatelessWidget { final List ops; final RxString curOP; - final Function(String) cbLogin; + final Function(Map) cbLogin; LoginWidgetOP({ Key? key, @@ -368,7 +367,8 @@ const kAuthReqTypeOidc = 'oidc/'; /// common login dialog for desktop /// call this directly Future loginDialog() async { - var username = TextEditingController(); + var username = + TextEditingController(text: UserModel.getLocalUserInfo()?['name'] ?? ''); var password = TextEditingController(); final userFocusNode = FocusNode()..requestFocus(); Timer(Duration(milliseconds: 100), () => userFocusNode..requestFocus()); @@ -480,8 +480,17 @@ Future loginDialog() async { .where((op) => oidcOptions.contains(op.op.toLowerCase())) .toList(), curOP: curOP, - cbLogin: (String username) { - gFFI.userModel.userName.value = username; + cbLogin: (Map authBody) { + try { + final loginResp = + gFFI.userModel.getLoginResponseFromAuthBody(authBody); + if (loginResp.access_token != null) { + bind.mainSetLocalOption( + key: 'access_token', value: loginResp.access_token!); + } + } catch (e) { + debugPrint('Failed too parse oidc login body: "$authBody"'); + } close(true); }, ), @@ -567,6 +576,7 @@ Future verificationCodeDialog(UserPayload? user) async { if (resp.access_token != null) { await bind.mainSetLocalOption( key: 'access_token', value: resp.access_token!); + gFFI.userModel.refreshCurrentUser(); close(true); return; } diff --git a/flutter/lib/models/user_model.dart b/flutter/lib/models/user_model.dart index bbb805826..63989ace6 100644 --- a/flutter/lib/models/user_model.dart +++ b/flutter/lib/models/user_model.dart @@ -14,6 +14,7 @@ import 'platform_model.dart'; class UserModel { final RxString userName = ''.obs; final RxBool isAdmin = false.obs; + final RxBool fromServer = false.obs; WeakReference parent; UserModel(this.parent); @@ -48,7 +49,7 @@ class UserModel { } final user = UserPayload.fromJson(data); - await _parseAndUpdateUser(user); + _parseAndUpdateUser(user); } catch (e) { print('Failed to refreshCurrentUser: $e'); } finally { @@ -56,6 +57,22 @@ class UserModel { } } + static Map? 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']; + } + } + Future reset() async { await bind.mainSetLocalOption(key: 'access_token', value: ''); await gFFI.abModel.reset(); @@ -64,9 +81,10 @@ class UserModel { gFFI.peerTabModel.check_dynamic_tabs(); } - Future _parseAndUpdateUser(UserPayload user) async { + _parseAndUpdateUser(UserPayload user) { userName.value = user.name; isAdmin.value = user.isAdmin; + fromServer.value = true; } Future _updateOtherModels() async { @@ -110,11 +128,14 @@ class UserModel { print("login: jsonDecode resp body failed: ${e.toString()}"); rethrow; } - if (resp.statusCode != 200) { throw RequestException(resp.statusCode, body['error'] ?? ''); } + return getLoginResponseFromAuthBody(body); + } + + LoginResponse getLoginResponseFromAuthBody(Map body) { final LoginResponse loginResponse; try { loginResponse = LoginResponse.fromJson(body); @@ -124,7 +145,7 @@ class UserModel { } if (loginResponse.user != null) { - await _parseAndUpdateUser(loginResponse.user!); + _parseAndUpdateUser(loginResponse.user!); } return loginResponse;