Skip to content

Commit

Permalink
Get enterprise configuration at smartphone installation (first downlo… (
Browse files Browse the repository at this point in the history
#2919)

* Get enterprise configuration at smartphone installation (first download from store) without QR code scan
#2899

* chore
  • Loading branch information
hawkbee1 authored Oct 2, 2024
1 parent acec87a commit 55a76ef
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 72 deletions.
6 changes: 6 additions & 0 deletions lib/app/shared/constants/urls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';


}
1 change: 1 addition & 0 deletions lib/app/shared/enum/status/app_status.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ enum AppStatus {
idle,
goBack,
revoked,
walletProviderApproval,
}
158 changes: 92 additions & 66 deletions lib/enterprise/cubit/enterprise_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,6 @@ class EnterpriseCubit extends Cubit<EnterpriseState> {
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,
Expand All @@ -95,29 +82,6 @@ class EnterpriseCubit extends Cubit<EnterpriseState> {

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);
}
Expand All @@ -144,51 +108,86 @@ class EnterpriseCubit extends Cubit<EnterpriseState> {
};

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<void> 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<String, dynamic>);

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<String> 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;
}
Expand Down Expand Up @@ -257,7 +256,7 @@ class EnterpriseCubit extends Cubit<EnterpriseState> {

/// get vc
final response = await client.post(
'${url}token',
'$url/token',
headers: <String, dynamic>{
'Content-Type': 'application/x-www-form-urlencoded',
},
Expand Down Expand Up @@ -559,4 +558,31 @@ class EnterpriseCubit extends Cubit<EnterpriseState> {
),
);
}

Future<void> 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<String, dynamic>) {
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,
);
}
}
}
}
5 changes: 5 additions & 0 deletions lib/enterprise/cubit/enterprise_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ class EnterpriseState extends Equatable {
const EnterpriseState({
this.status = AppStatus.init,
this.message,
this.profileSettingJson,
});

factory EnterpriseState.fromJson(Map<String, dynamic> json) =>
_$EnterpriseStateFromJson(json);

final AppStatus status;
final StateMessage? message;
final String? profileSettingJson;

EnterpriseState loading() {
return copyWith(
Expand All @@ -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,
);
}

Expand All @@ -43,5 +47,6 @@ class EnterpriseState extends Equatable {
List<Object?> get props => [
status,
message,
profileSettingJson,
];
}
12 changes: 11 additions & 1 deletion lib/l10n/arb/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1075,5 +1075,15 @@
"keyBindingHeader": "Key Binding Header",
"keyBindingPayload": "Key Binding Payload",
"ebsiV4DecentralizedId": "did:key EBSI V4 P-256",
"noNotificationsYet": "No notifications yet"
"noNotificationsYet": "No notifications yet",
"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": {}
}
}

}
12 changes: 9 additions & 3 deletions lib/l10n/untranslated.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
"keyBindingHeader",
"keyBindingPayload",
"ebsiV4DecentralizedId",
"noNotificationsYet"
"noNotificationsYet",
"approveProfileTitle",
"approveProfileDescription"
],

"es": [
Expand Down Expand Up @@ -94,7 +96,9 @@
"keyBindingHeader",
"keyBindingPayload",
"ebsiV4DecentralizedId",
"noNotificationsYet"
"noNotificationsYet",
"approveProfileTitle",
"approveProfileDescription"
],

"fr": [
Expand Down Expand Up @@ -148,6 +152,8 @@
"keyBindingHeader",
"keyBindingPayload",
"ebsiV4DecentralizedId",
"noNotificationsYet"
"noNotificationsYet",
"approveProfileTitle",
"approveProfileDescription"
]
}
9 changes: 9 additions & 0 deletions lib/onboarding/wallet_ready/view/wallet_ready_page.dart
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -209,6 +210,14 @@ class _WalletReadyViewState extends State<WalletReadyView> {
DashboardPage.route(),
(Route<dynamic> route) => route.isFirst,
);
// Check with API if it is an organization
// wallet

context
.read<EnterpriseCubit>()
.getWalletProviderAccount(
context.read<QRCodeScanCubit>(),
);
}
: null,
),
Expand Down
40 changes: 38 additions & 2 deletions lib/splash/bloclisteners/blocklisteners.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:convert';

import 'package:altme/app/app.dart';
import 'package:altme/connection_bridge/connection_bridge.dart';
Expand Down Expand Up @@ -860,7 +861,7 @@ final polygonIdBlocListener = BlocListener<PolygonIdCubit, PolygonIdState>(
);

final enterpriseBlocListener = BlocListener<EnterpriseCubit, EnterpriseState>(
listener: (BuildContext context, EnterpriseState state) {
listener: (BuildContext context, EnterpriseState state) async {
if (state.status == AppStatus.loading) {
LoadingView().show(context: context);
} else {
Expand All @@ -872,13 +873,48 @@ final enterpriseBlocListener = BlocListener<EnterpriseCubit, EnterpriseState>(
}

if (state.status == AppStatus.revoked) {
showDialog<void>(
await showDialog<void>(
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<String, dynamic>,
);
final confirm = await showDialog<bool>(
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<EnterpriseCubit>()
.applyConfiguration(context.read<QRCodeScanCubit>());
} 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,
Expand Down

0 comments on commit 55a76ef

Please sign in to comment.