Skip to content

Commit

Permalink
Get enterprise configuration at smartphone installation (first downlo…
Browse files Browse the repository at this point in the history
…ad from store) without QR code scan

#2899
  • Loading branch information
hawkbee1 committed Oct 1, 2024
1 parent 3e6799f commit 56e2fdf
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 @@ -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": {}
}
}

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

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

"fr": [
Expand Down Expand Up @@ -145,6 +149,8 @@
"data",
"keyBindingHeader",
"keyBindingPayload",
"ebsiV4DecentralizedId"
"ebsiV4DecentralizedId",
"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 56e2fdf

Please sign in to comment.