diff --git a/lib/app/shared/constants/urls.dart b/lib/app/shared/constants/urls.dart index 64a3733e7..bcd605125 100644 --- a/lib/app/shared/constants/urls.dart +++ b/lib/app/shared/constants/urls.dart @@ -121,4 +121,10 @@ class Urls { // wallet provider static const walletProvider = 'https://wallet-provider.talao.co'; static const walletTestProvider = 'https://preprod.wallet-provider.talao.co'; + + // wallet provider + static const walletConfigurationAltme = 'https://app.altme.io/configuration'; + static const walletConfigurationTalao = 'https://app.talao.co/configuration'; + + } diff --git a/lib/app/shared/enum/status/app_status.dart b/lib/app/shared/enum/status/app_status.dart index e4d129104..570065aa4 100644 --- a/lib/app/shared/enum/status/app_status.dart +++ b/lib/app/shared/enum/status/app_status.dart @@ -9,4 +9,5 @@ enum AppStatus { idle, goBack, revoked, + walletProviderApproval, } diff --git a/lib/enterprise/cubit/enterprise_cubit.dart b/lib/enterprise/cubit/enterprise_cubit.dart index 0f2c887be..40bda715f 100644 --- a/lib/enterprise/cubit/enterprise_cubit.dart +++ b/lib/enterprise/cubit/enterprise_cubit.dart @@ -56,19 +56,6 @@ class EnterpriseCubit extends Cubit { SecureStorageKeys.enterpriseEmail, ); - // if (savedEmail != null) { - // if (email == savedEmail) { - // /// if email is matched then update the configuration - // await updateTheConfiguration(); - // return; - // } else { - // throw ResponseMessage( - // message: - // ResponseString.RESPONSE_STRING_thisWalleIsAlreadyConfigured, - // ); - // } - // } - if (savedEmail != null) { throw ResponseMessage( message: ResponseString.RESPONSE_STRING_thisWalleIsAlreadyConfigured, @@ -95,29 +82,6 @@ class EnterpriseCubit extends Cubit { await profileCubit.secureStorageProvider .set(SecureStorageKeys.enterpriseWalletProvider, url); - - /// uprade wallet to enterprise - await profileCubit.setWalletType( - walletType: WalletType.enterprise, - ); - - // if enterprise and walletAttestation data is available and added - await credentialsCubit.addWalletCredential( - blockchainType: - credentialsCubit.walletCubit.state.currentAccount?.blockchainType, - qrCodeScanCubit: qrCodeScanCubit, - ); - - emit( - state.copyWith( - message: StateMessage.success( - messageHandler: ResponseMessage( - message: ResponseString - .RESPONSE_STRING_successfullyAddedEnterpriseAccount, - ), - ), - ), - ); } catch (e) { emitError(e); } @@ -144,51 +108,86 @@ class EnterpriseCubit extends Cubit { }; final response = await client.post( - '${url}configuration', + '$url/configuration', headers: headers, data: data, ); final profileSettingJson = profileCubit.jwtDecode.parseJwt(response as String); - - await profileCubit.secureStorageProvider.set( - SecureStorageKeys.enterpriseProfileSetting, - jsonEncode(profileSettingJson), + // we emit new state, waiting for user approval + emit( + state.copyWith( + status: AppStatus.walletProviderApproval, + profileSettingJson: jsonEncode(profileSettingJson), + ), ); + } - final profileSetting = ProfileSetting.fromJson(profileSettingJson); + Future applyConfiguration( + QRCodeScanCubit qrCodeScanCubit, + ) async { + assert(state.profileSettingJson != null, 'Profile setting is missing.'); + emit(state.loading()); - ///save to profileCubit - await profileCubit.setProfileSetting( - profileSetting: profileSetting, - profileType: ProfileType.enterprise, - ); - final helpCenterOptions = profileSetting.helpCenterOptions; + final setting = state.profileSettingJson; + if (setting != null) { + await profileCubit.secureStorageProvider.set( + SecureStorageKeys.enterpriseProfileSetting, + setting, + ); - if (helpCenterOptions.customChatSupport && - helpCenterOptions.customChatSupportName != null) { - await altmeChatSupportCubit.init(); - } + final profileSetting = + ProfileSetting.fromJson(jsonDecode(setting) as Map); - if (helpCenterOptions.customNotification != null && - helpCenterOptions.customNotification! && - helpCenterOptions.customNotificationRoom != null) { - await matrixNotificationCubit.init(); - } + ///save to profileCubit + await profileCubit.setProfileSetting( + profileSetting: profileSetting, + profileType: ProfileType.enterprise, + ); + final helpCenterOptions = profileSetting.helpCenterOptions; - // chat is not initiatied at start + if (helpCenterOptions.customChatSupport && + helpCenterOptions.customChatSupportName != null) { + await altmeChatSupportCubit.init(); + } - emit( - state.copyWith( - status: AppStatus.success, - message: null, - ), - ); + if (helpCenterOptions.customNotification != null && + helpCenterOptions.customNotification! && + helpCenterOptions.customNotificationRoom != null) { + await matrixNotificationCubit.init(); + } + + // chat is not initiatied at start + + /// uprade wallet to enterprise + await profileCubit.setWalletType( + walletType: WalletType.enterprise, + ); + + // if enterprise and walletAttestation data is available and added + await credentialsCubit.addWalletCredential( + blockchainType: + credentialsCubit.walletCubit.state.currentAccount?.blockchainType, + qrCodeScanCubit: qrCodeScanCubit, + ); + + emit( + state.copyWith( + status: AppStatus.success, + message: StateMessage.success( + messageHandler: ResponseMessage( + message: ResponseString + .RESPONSE_STRING_successfullyAddedEnterpriseAccount, + ), + ), + ), + ); + } } Future getNonce(String url) async { - final dynamic getRepsponse = await client.get('${url}nonce'); + final dynamic getRepsponse = await client.get('$url/nonce'); final nonce = getRepsponse['nonce'].toString(); return nonce; } @@ -257,7 +256,7 @@ class EnterpriseCubit extends Cubit { /// get vc final response = await client.post( - '${url}token', + '$url/token', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, @@ -559,4 +558,31 @@ class EnterpriseCubit extends Cubit { ), ); } + + Future getWalletProviderAccount( + QRCodeScanCubit qrCodeScanCubit, + ) async { + late final dynamic configurationResponse; + // check if wallet is Altme or Talao + if (Parameters.appName == 'Altme') { + // get configuration file for this device + configurationResponse = await client.get(Urls.walletConfigurationAltme); + } + if (Parameters.appName == 'Talao') { + // get configuration file for this device + configurationResponse = await client.get(Urls.walletConfigurationTalao); + } + if (configurationResponse != null && + configurationResponse is Map) { + if (configurationResponse['login'] != null && + configurationResponse['password'] != null && + configurationResponse['wallet-provider'] != null) { + final uri = Uri.https('example.com', '/path', configurationResponse); + await requestTheConfiguration( + uri: uri, + qrCodeScanCubit: qrCodeScanCubit, + ); + } + } + } } diff --git a/lib/enterprise/cubit/enterprise_state.dart b/lib/enterprise/cubit/enterprise_state.dart index a26c0e97a..87f7e1d7d 100644 --- a/lib/enterprise/cubit/enterprise_state.dart +++ b/lib/enterprise/cubit/enterprise_state.dart @@ -5,6 +5,7 @@ class EnterpriseState extends Equatable { const EnterpriseState({ this.status = AppStatus.init, this.message, + this.profileSettingJson, }); factory EnterpriseState.fromJson(Map json) => @@ -12,6 +13,7 @@ class EnterpriseState extends Equatable { final AppStatus status; final StateMessage? message; + final String? profileSettingJson; EnterpriseState loading() { return copyWith( @@ -30,10 +32,12 @@ class EnterpriseState extends Equatable { EnterpriseState copyWith({ StateMessage? message, AppStatus? status, + String? profileSettingJson, }) { return EnterpriseState( status: status ?? this.status, message: message, + profileSettingJson: profileSettingJson ?? this.profileSettingJson, ); } @@ -43,5 +47,6 @@ class EnterpriseState extends Equatable { List get props => [ status, message, + profileSettingJson, ]; } diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 1c2c0348b..accf2db08 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -1074,5 +1074,15 @@ "data": "Data", "keyBindingHeader": "Key Binding Header", "keyBindingPayload": "Key Binding Payload", - "ebsiV4DecentralizedId": "did:key EBSI V4 P-256" + "ebsiV4DecentralizedId": "did:key EBSI V4 P-256", + "approveProfileTitle": "Install configuration", + "approveProfileDescription": "Do you consent to install the configuration of {company}?", + "@approveProfileDescription": { + "description": "name of the company owning the configuration", + "type": "text", + "placeholders": { + "company": {} + } + } + } diff --git a/lib/l10n/untranslated.json b/lib/l10n/untranslated.json index 8784f590f..14cc63254 100644 --- a/lib/l10n/untranslated.json +++ b/lib/l10n/untranslated.json @@ -44,7 +44,9 @@ "data", "keyBindingHeader", "keyBindingPayload", - "ebsiV4DecentralizedId" + "ebsiV4DecentralizedId", + "approveProfileTitle", + "approveProfileDescription" ], "es": [ @@ -92,7 +94,9 @@ "data", "keyBindingHeader", "keyBindingPayload", - "ebsiV4DecentralizedId" + "ebsiV4DecentralizedId", + "approveProfileTitle", + "approveProfileDescription" ], "fr": [ @@ -145,6 +149,8 @@ "data", "keyBindingHeader", "keyBindingPayload", - "ebsiV4DecentralizedId" + "ebsiV4DecentralizedId", + "approveProfileTitle", + "approveProfileDescription" ] } diff --git a/lib/onboarding/wallet_ready/view/wallet_ready_page.dart b/lib/onboarding/wallet_ready/view/wallet_ready_page.dart index b85463e8c..e3067585e 100644 --- a/lib/onboarding/wallet_ready/view/wallet_ready_page.dart +++ b/lib/onboarding/wallet_ready/view/wallet_ready_page.dart @@ -1,5 +1,6 @@ import 'package:altme/app/app.dart'; import 'package:altme/dashboard/dashboard.dart'; +import 'package:altme/enterprise/cubit/enterprise_cubit.dart'; import 'package:altme/l10n/l10n.dart'; import 'package:altme/onboarding/cubit/onboarding_cubit.dart'; import 'package:altme/onboarding/onboarding.dart'; @@ -209,6 +210,14 @@ class _WalletReadyViewState extends State { DashboardPage.route(), (Route route) => route.isFirst, ); + // Check with API if it is an organization + // wallet + + context + .read() + .getWalletProviderAccount( + context.read(), + ); } : null, ), diff --git a/lib/splash/bloclisteners/blocklisteners.dart b/lib/splash/bloclisteners/blocklisteners.dart index 14d415cce..878b37206 100644 --- a/lib/splash/bloclisteners/blocklisteners.dart +++ b/lib/splash/bloclisteners/blocklisteners.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:convert'; import 'package:altme/app/app.dart'; import 'package:altme/connection_bridge/connection_bridge.dart'; @@ -860,7 +861,7 @@ final polygonIdBlocListener = BlocListener( ); final enterpriseBlocListener = BlocListener( - listener: (BuildContext context, EnterpriseState state) { + listener: (BuildContext context, EnterpriseState state) async { if (state.status == AppStatus.loading) { LoadingView().show(context: context); } else { @@ -872,13 +873,48 @@ final enterpriseBlocListener = BlocListener( } if (state.status == AppStatus.revoked) { - showDialog( + await showDialog( context: context, barrierDismissible: false, builder: (_) => const WalletRevokedDialog(), ); } + if (state.status == AppStatus.walletProviderApproval) { + final settingJson = state.profileSettingJson; + if (settingJson != null) { + final l10n = context.l10n; + final profileSetting = ProfileSetting.fromJson( + jsonDecode(settingJson) as Map, + ); + final confirm = await showDialog( + context: context, + builder: (_) => ConfirmDialog( + title: l10n.approveProfileTitle, + subtitle: l10n.approveProfileDescription( + profileSetting.generalOptions.companyName, + ), + yes: l10n.showDialogYes, + no: l10n.showDialogNo, + ), + ) ?? + false; + + if (confirm) { + await context + .read() + .applyConfiguration(context.read()); + } else { + /// Need to remove the enterprise email from secure storage + /// because we may think later that the entreprise profile is + /// already installed. + await getSecureStorage.delete( + SecureStorageKeys.enterpriseEmail, + ); + } + } + } + if (state.message != null) { AlertMessage.showStateMessage( context: context,