From 5b7dd05acd9ae813acfc9b7ba8ab5bd34aa447dc Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 9 Jul 2024 17:51:08 +0545 Subject: [PATCH] fix: Avoid double scan to get and present #2668 --- lib/credentials/cubit/credentials_cubit.dart | 9 + .../verify_age/view/camera_page.dart | 1 + lib/dashboard/home/home/cubit/home_cubit.dart | 5 + .../detail/view/credentials_details_page.dart | 2 + .../helper_functions/discover_credential.dart | 2 + .../view/oid4c4vc_credential_pick_page.dart | 2 + .../polygon_id_credential_offer_view.dart | 4 +- .../view/credentials_receive_page.dart | 13 +- .../view/missing_credentials_page.dart | 3 +- .../cubit/qr_code_scan_cubit.dart | 218 ++++++++++++------ .../qr_code_scan/view/qr_code_scan_page.dart | 7 +- .../self_issued_credential_button_cubit.dart | 3 + lib/enterprise/cubit/enterprise_cubit.dart | 8 +- lib/oidc4vc/add_credential_data.dart | 3 + lib/oidc4vc/add_oidc4vc_credential.dart | 4 +- .../get_and_add_deffered_credential.dart | 2 + .../initiate_oidv4vc_credential_issuance.dart | 2 + lib/polygon_id/cubit/polygon_id_cubit.dart | 7 +- lib/scan/cubit/scan_cubit.dart | 5 +- lib/splash/bloclisteners/blocklisteners.dart | 4 +- lib/splash/view/splash_page.dart | 5 +- 21 files changed, 221 insertions(+), 88 deletions(-) diff --git a/lib/credentials/cubit/credentials_cubit.dart b/lib/credentials/cubit/credentials_cubit.dart index 1176414a9..a484ae69e 100644 --- a/lib/credentials/cubit/credentials_cubit.dart +++ b/lib/credentials/cubit/credentials_cubit.dart @@ -112,6 +112,7 @@ class CredentialsCubit extends Cubit { Future addWalletCredential({ required BlockchainType? blockchainType, + required QRCodeScanCubit qrCodeScanCubit, }) async { final log = getLogger('addRequiredCredentials'); @@ -175,6 +176,7 @@ class CredentialsCubit extends Cubit { credential: walletCredential, showMessage: false, blockchainType: blockchainType, + qrCodeScanCubit: qrCodeScanCubit, ); } } @@ -261,6 +263,7 @@ class CredentialsCubit extends Cubit { Future insertCredential({ required CredentialModel credential, required BlockchainType? blockchainType, + required QRCodeScanCubit qrCodeScanCubit, bool showMessage = true, bool showStatus = true, bool isPendingCredential = false, @@ -335,6 +338,10 @@ class CredentialsCubit extends Cubit { : null, ), ); + + if (qrCodeScanCubit.missingCredentialCompleter != null) { + qrCodeScanCubit.missingCredentialCompleter!.complete(true); + } } void enableCredentialCategory({required CredentialCategory category}) { @@ -503,6 +510,7 @@ class CredentialsCubit extends Cubit { Future insertAssociatedWalletCredential({ required CryptoAccountData cryptoAccountData, + required QRCodeScanCubit qrCodeScanCubit, }) async { final supportAssociatedCredential = supportCryptoCredential(profileCubit.state.model); @@ -549,6 +557,7 @@ class CredentialsCubit extends Cubit { await insertCredential( credential: credential, blockchainType: cryptoAccountData.blockchainType, + qrCodeScanCubit: qrCodeScanCubit, ); } } diff --git a/lib/dashboard/ai_age_verification/verify_age/view/camera_page.dart b/lib/dashboard/ai_age_verification/verify_age/view/camera_page.dart index 636d7a9c3..8a358c7a9 100644 --- a/lib/dashboard/ai_age_verification/verify_age/view/camera_page.dart +++ b/lib/dashboard/ai_age_verification/verify_age/view/camera_page.dart @@ -127,6 +127,7 @@ class _CameraViewState extends State { .currentAccount! .blockchainType, vcFormatType: customOidc4vcProfile.vcFormatType, + qrCodeScanCubit: context.read(), ); LoadingView().hide(); await Navigator.pushReplacement( diff --git a/lib/dashboard/home/home/cubit/home_cubit.dart b/lib/dashboard/home/home/cubit/home_cubit.dart index e40e10b81..e72b4f464 100644 --- a/lib/dashboard/home/home/cubit/home_cubit.dart +++ b/lib/dashboard/home/home/cubit/home_cubit.dart @@ -5,6 +5,7 @@ import 'package:altme/app/app.dart'; import 'package:altme/credentials/credentials.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/dashboard/home/tab_bar/credentials/models/activity/activity.dart'; +import 'package:altme/dashboard/qr_code/qr_code.dart'; import 'package:bloc/bloc.dart'; import 'package:credential_manifest/credential_manifest.dart'; import 'package:crypto/crypto.dart'; @@ -44,6 +45,7 @@ class HomeCubit extends Cubit { required OIDC4VCIDraftType oidc4vciDraftType, required BlockchainType blockchainType, required VCFormatType vcFormatType, + required QRCodeScanCubit qrCodeScanCubit, }) async { // launch url to get Over18, Over15, Over13,Over21,Over50,Over65, // AgeRange Credentials @@ -101,6 +103,7 @@ class HomeCubit extends Cubit { oidc4vciDraftType: oidc4vciDraftType, blockchainType: blockchainType, vcFormatType: vcFormatType, + qrCodeScanCubit: qrCodeScanCubit, ); await ageEstimate( @@ -160,6 +163,7 @@ class HomeCubit extends Cubit { required OIDC4VCIDraftType oidc4vciDraftType, required BlockchainType blockchainType, required VCFormatType vcFormatType, + required QRCodeScanCubit qrCodeScanCubit, }) async { /// if credential of this type is already in the wallet do nothing /// Ensure credentialType = name of credential type in CredentialModel @@ -216,6 +220,7 @@ class HomeCubit extends Cubit { credential: credentialModel, showMessage: true, blockchainType: blockchainType, + qrCodeScanCubit: qrCodeScanCubit, ); await cameraCubit.incrementAcquiredCredentialsQuantity(); emit(state.copyWith(status: AppStatus.success)); diff --git a/lib/dashboard/home/tab_bar/credentials/detail/view/credentials_details_page.dart b/lib/dashboard/home/tab_bar/credentials/detail/view/credentials_details_page.dart index aaaabc18e..3c4235bdb 100644 --- a/lib/dashboard/home/tab_bar/credentials/detail/view/credentials_details_page.dart +++ b/lib/dashboard/home/tab_bar/credentials/detail/view/credentials_details_page.dart @@ -468,6 +468,8 @@ class _CredentialsDetailsViewState extends State { .read() .startOIDC4VCDeferedCredentialIssuance( credentialModel: widget.credentialModel, + qrCodeScanCubit: + context.read(), ); }, ), diff --git a/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart b/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart index 11fa32783..79d062db2 100644 --- a/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart +++ b/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart @@ -15,12 +15,14 @@ Future discoverCredential({ if (dummyCredential.credentialSubjectType.isBlockchainAccount) { final credentialCubit = context.read(); final walletCubit = context.read(); + final qrCodeScanCubit = context.read(); final cryptoAccountData = walletCubit.state.currentAccount; if (cryptoAccountData != null) { await credentialCubit.insertAssociatedWalletCredential( cryptoAccountData: cryptoAccountData, + qrCodeScanCubit: qrCodeScanCubit, ); } diff --git a/lib/dashboard/home/tab_bar/credentials/oid4c4vc_pick/oid4c4vc_credential_pick/view/oid4c4vc_credential_pick_page.dart b/lib/dashboard/home/tab_bar/credentials/oid4c4vc_pick/oid4c4vc_credential_pick/view/oid4c4vc_credential_pick_page.dart index 033ae203e..97e94a9c8 100644 --- a/lib/dashboard/home/tab_bar/credentials/oid4c4vc_pick/oid4c4vc_credential_pick/view/oid4c4vc_credential_pick_page.dart +++ b/lib/dashboard/home/tab_bar/credentials/oid4c4vc_pick/oid4c4vc_credential_pick/view/oid4c4vc_credential_pick_page.dart @@ -199,6 +199,8 @@ class Oidc4vcCredentialPickView extends StatelessWidget { preAuthorizedCode: preAuthorizedCode, isEBSIV3: isEBSIV3, credentialOfferJson: credentialOfferJson, + qrCodeScanCubit: + context.read(), ); }, text: l10n.proceed, diff --git a/lib/dashboard/home/tab_bar/credentials/polygon_id/polygon_id_credential_offer/view/polygon_id_credential_offer_view.dart b/lib/dashboard/home/tab_bar/credentials/polygon_id/polygon_id_credential_offer/view/polygon_id_credential_offer_view.dart index c67074da1..eb56b2380 100644 --- a/lib/dashboard/home/tab_bar/credentials/polygon_id/polygon_id_credential_offer/view/polygon_id_credential_offer_view.dart +++ b/lib/dashboard/home/tab_bar/credentials/polygon_id/polygon_id_credential_offer/view/polygon_id_credential_offer_view.dart @@ -146,7 +146,9 @@ class PolygonIdCredentialOfferPage extends StatelessWidget { context: context, localAuthApi: LocalAuthApi(), onSuccess: () { - context.read().addPolygonIdCredentials(); + context.read().addPolygonIdCredentials( + qrCodeScanCubit: context.read(), + ); }, ); }, diff --git a/lib/dashboard/home/tab_bar/credentials/receive/view/credentials_receive_page.dart b/lib/dashboard/home/tab_bar/credentials/receive/view/credentials_receive_page.dart index 86dc3018f..415e3f903 100644 --- a/lib/dashboard/home/tab_bar/credentials/receive/view/credentials_receive_page.dart +++ b/lib/dashboard/home/tab_bar/credentials/receive/view/credentials_receive_page.dart @@ -143,12 +143,13 @@ class _CredentialsReceivePageState extends State { ); } else { context.read().credentialOfferOrPresent( - uri: widget.uri, - credentialModel: credentialModel, - keyId: SecureStorageKeys.ssiKey, - issuer: widget.issuer, - credentialsToBePresented: [], - ); + uri: widget.uri, + credentialModel: credentialModel, + keyId: SecureStorageKeys.ssiKey, + issuer: widget.issuer, + credentialsToBePresented: [], + qrCodeScanCubit: context.read(), + ); } }, ), diff --git a/lib/dashboard/missing_creentials/view/missing_credentials_page.dart b/lib/dashboard/missing_creentials/view/missing_credentials_page.dart index 11f226f67..cd3d4c789 100644 --- a/lib/dashboard/missing_creentials/view/missing_credentials_page.dart +++ b/lib/dashboard/missing_creentials/view/missing_credentials_page.dart @@ -62,7 +62,6 @@ class MissingCredentialsView extends StatelessWidget { Widget build(BuildContext context) { final l10n = context.l10n; - return BlocBuilder( builder: (context, state) { return BasePage( @@ -123,7 +122,7 @@ class MissingCredentialsView extends StatelessWidget { ), ); } - Navigator.pop(context); + Navigator.pop(context, true); }, text: l10n.getItNow, ), diff --git a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart index 7d1045ba4..c309c292b 100644 --- a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart +++ b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart @@ -72,7 +72,10 @@ class QRCodeScanCubit extends Cubit { return super.close(); } - Future process({required String? scannedResponse}) async { + Future process({ + required String? scannedResponse, + required QRCodeScanCubit qrCodeScanCubit, + }) async { log.i('processing scanned qr code - $scannedResponse'); goBack(); await Future.delayed(const Duration(milliseconds: 1000)); @@ -114,7 +117,10 @@ class QRCodeScanCubit extends Cubit { /// enterprise final uri = Uri.parse(scannedResponse); emit(state.copyWith(qrScanStatus: QrScanStatus.goBack)); - await enterpriseCubit.requestTheConfiguration(uri); + await enterpriseCubit.requestTheConfiguration( + uri: uri, + qrCodeScanCubit: qrCodeScanCubit, + ); } else { final uri = Uri.parse(scannedResponse); await verify(uri: uri); @@ -214,6 +220,7 @@ class QRCodeScanCubit extends Cubit { required OpenIdConfiguration? openIdConfiguration, required String? issuer, required String? preAuthorizedCode, + required Uri uri, OIDC4VCType? oidcType, }) async { emit(state.loading()); @@ -221,8 +228,11 @@ class QRCodeScanCubit extends Cubit { late final dynamic data; + final customOidc4vcProfile = profileCubit.state.model.profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile; + try { - if (isOIDC4VCIUrl(state.uri!) && oidcType != null) { + if (isOIDC4VCIUrl(uri) && oidcType != null) { /// issuer side (oidc4VCI) if (issuer == null) { @@ -235,11 +245,10 @@ class QRCodeScanCubit extends Cubit { } await startOIDC4VCCredentialIssuance( - scannedResponse: state.uri.toString(), + scannedResponse: uri.toString(), isEBSIV3: oidcType == OIDC4VCType.EBSIV3, qrCodeScanCubit: qrCodeScanCubit, - oidc4vciDraftType: profileCubit.state.model.profileSetting - .selfSovereignIdentityOptions.customOidc4vcProfile.oidc4vciDraft, + oidc4vciDraftType: customOidc4vcProfile.oidc4vciDraft, credentialOfferJson: credentialOfferJson, openIdConfiguration: openIdConfiguration, issuer: issuer, @@ -248,13 +257,13 @@ class QRCodeScanCubit extends Cubit { return; } - if (isSIOPV2OROIDC4VPUrl(state.uri!)) { - await startSIOPV2OIDC4VPProcess(state.uri!); + if (isSIOPV2OROIDC4VPUrl(uri)) { + await startSIOPV2OIDC4VPProcess(uri); return; } /// did credential addition and presentation - final dynamic response = await client.get(state.uri!.toString()); + final dynamic response = await client.get(uri.toString()); data = response is String ? jsonDecode(response) : response; log.i('data - $data'); @@ -266,11 +275,11 @@ class QRCodeScanCubit extends Cubit { ); final PresentationDefinition? presentationDefinition = credentialManifest.presentationDefinition; + final isPresentable = await isVCPresentable( presentationDefinition: presentationDefinition, clientMetaData: null, - vcFormatType: profileCubit.state.model.profileSetting - .selfSovereignIdentityOptions.customOidc4vcProfile.vcFormatType, + vcFormatType: customOidc4vcProfile.vcFormatType, ); if (!isPresentable) { @@ -282,7 +291,30 @@ class QRCodeScanCubit extends Cubit { ), ), ); - return; + + missingCredentialCompleter = Completer(); + final value = await missingCredentialCompleter!.future; + missingCredentialCompleter = null; + + if (value) { + final isPresentable = await isVCPresentable( + presentationDefinition: presentationDefinition, + clientMetaData: null, + vcFormatType: customOidc4vcProfile.vcFormatType, + ); + + if (!isPresentable) { + throw ResponseMessage( + message: ResponseString + .RESPONSE_STRING_SOMETHING_WENT_WRONG_TRY_AGAIN_LATER, + ); + } + } else { + throw ResponseMessage( + message: ResponseString + .RESPONSE_STRING_SOMETHING_WENT_WRONG_TRY_AGAIN_LATER, + ); + } } } @@ -293,7 +325,7 @@ class QRCodeScanCubit extends Cubit { state.copyWith( qrScanStatus: QrScanStatus.success, route: CredentialsReceivePage.route( - uri: state.uri!, + uri: uri, preview: data as Map, issuer: approvedIssuer, ), @@ -316,14 +348,9 @@ class QRCodeScanCubit extends Cubit { final isPresentable = await isCredentialPresentable( credentialSubjectType: credentialSubjectType, - vcFormatType: profileCubit - .state - .model - .profileSetting - .selfSovereignIdentityOptions - .customOidc4vcProfile - .vcFormatType, + vcFormatType: customOidc4vcProfile.vcFormatType, ); + if (!isPresentable) { emit( state.copyWith( @@ -331,49 +358,70 @@ class QRCodeScanCubit extends Cubit { route: MissingCredentialsPage.route(query: query), ), ); - return; - } - } - queryByExampleCubit.setQueryByExampleCubit(query); + missingCredentialCompleter = Completer(); + final value = await missingCredentialCompleter!.future; + missingCredentialCompleter = null; - log.i(data['query']); - if (data['query'].first['type'] == 'DIDAuth') { - log.i('DIDAuth'); - await scanCubit.askPermissionDIDAuthCHAPI( - keyId: SecureStorageKeys.ssiKey, - done: (done) { - log.i('done'); - }, - uri: state.uri!, - challenge: data['challenge'] as String, - domain: data['domain'] as String, - ); - emit(state.copyWith(qrScanStatus: QrScanStatus.idle)); - } else if (data['query'].first['type'] == 'QueryByExample') { - log.i('QueryByExample'); - emit( - state.copyWith( - qrScanStatus: QrScanStatus.success, - route: QueryByExamplePresentPage.route( - uri: state.uri!, - preview: data as Map, - issuer: approvedIssuer, + if (value) { + final isPresentable = await isCredentialPresentable( + credentialSubjectType: credentialSubjectType, + vcFormatType: customOidc4vcProfile.vcFormatType, + ); + if (!isPresentable) { + throw ResponseMessage( + message: ResponseString + .RESPONSE_STRING_SOMETHING_WENT_WRONG_TRY_AGAIN_LATER, + ); + } + } else { + throw ResponseMessage( + message: ResponseString + .RESPONSE_STRING_SOMETHING_WENT_WRONG_TRY_AGAIN_LATER, + ); + } + } + + queryByExampleCubit.setQueryByExampleCubit(query); + + log.i(data['query']); + if (data['query'].first['type'] == 'DIDAuth') { + log.i('DIDAuth'); + await scanCubit.askPermissionDIDAuthCHAPI( + keyId: SecureStorageKeys.ssiKey, + done: (done) { + log.i('done'); + }, + uri: uri, + challenge: data['challenge'] as String, + domain: data['domain'] as String, + ); + emit(state.copyWith(qrScanStatus: QrScanStatus.idle)); + } else if (data['query'].first['type'] == 'QueryByExample') { + log.i('QueryByExample'); + emit( + state.copyWith( + qrScanStatus: QrScanStatus.success, + route: QueryByExamplePresentPage.route( + uri: uri, + preview: data as Map, + issuer: approvedIssuer, + ), ), - ), - ); - } else { - throw ResponseMessage( - message: - ResponseString.RESPONSE_STRING_UNIMPLEMENTED_QUERY_TYPE, - ); + ); + } else { + throw ResponseMessage( + message: + ResponseString.RESPONSE_STRING_UNIMPLEMENTED_QUERY_TYPE, + ); + } } } else { emit( state.copyWith( qrScanStatus: QrScanStatus.success, route: QueryByExamplePresentPage.route( - uri: state.uri!, + uri: uri, preview: data as Map, issuer: approvedIssuer, ), @@ -386,7 +434,7 @@ class QRCodeScanCubit extends Cubit { state.copyWith( qrScanStatus: QrScanStatus.success, route: CredentialsReceivePage.route( - uri: state.uri!, + uri: uri, preview: data as Map, issuer: approvedIssuer, ), @@ -744,7 +792,10 @@ class QRCodeScanCubit extends Cubit { /// responseType == 'id_token vp_token' => verifier side (oidc4vp) /// or (oidc4vp and siopv2) - await launchOIDC4VPAndSIOPV2Flow(keys); + await launchOIDC4VPAndSIOPV2Flow( + keys: keys, + uri: state.uri!, + ); } else { throw ResponseMessage( data: { @@ -758,6 +809,7 @@ class QRCodeScanCubit extends Cubit { Future startOIDC4VCDeferedCredentialIssuance({ required CredentialModel credentialModel, + required QRCodeScanCubit qrCodeScanCubit, }) async { try { emit(state.loading()); @@ -797,6 +849,7 @@ class QRCodeScanCubit extends Cubit { jwtDecode: jwtDecode, blockchainType: walletCubit.state.currentAccount!.blockchainType, oidc4vciDraftType: customOidc4vcProfile.oidc4vciDraft, + qrCodeScanCubit: qrCodeScanCubit, ); } catch (e) { emitError(e); @@ -857,7 +910,12 @@ class QRCodeScanCubit extends Cubit { ); } - Future launchOIDC4VPAndSIOPV2Flow(List keys) async { + Completer? missingCredentialCompleter; + + Future launchOIDC4VPAndSIOPV2Flow({ + required List keys, + required Uri uri, + }) async { if (!keys.contains('presentation_definition') && !keys.contains('presentation_definition_uri')) { throw ResponseMessage( @@ -871,10 +929,7 @@ class QRCodeScanCubit extends Cubit { } final Map? presentationDefinitionData = - await getPresentationDefinition( - client: client, - uri: state.uri!, - ); + await getPresentationDefinition(client: client, uri: uri); if (presentationDefinitionData == null) { throw ResponseMessage( @@ -913,10 +968,7 @@ class QRCodeScanCubit extends Cubit { Map? clientMetaData; if (presentationDefinition.format == null) { - clientMetaData = await getClientMetada( - client: client, - uri: state.uri!, - ); + clientMetaData = await getClientMetada(client: client, uri: uri); if (clientMetaData != null) { if (!clientMetaData.containsKey('vp_formats')) { @@ -964,7 +1016,31 @@ class QRCodeScanCubit extends Cubit { ), ), ); - return; + + missingCredentialCompleter = Completer(); + final value = await missingCredentialCompleter!.future; + missingCredentialCompleter = null; + + if (value) { + final isPresentable = await isVCPresentable( + presentationDefinition: presentationDefinition, + clientMetaData: clientMetaData, + vcFormatType: profileCubit.state.model.profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile.vcFormatType, + ); + + if (!isPresentable) { + throw ResponseMessage( + message: ResponseString + .RESPONSE_STRING_SOMETHING_WENT_WRONG_TRY_AGAIN_LATER, + ); + } + } else { + throw ResponseMessage( + message: ResponseString + .RESPONSE_STRING_SOMETHING_WENT_WRONG_TRY_AGAIN_LATER, + ); + } } final CredentialModel credentialPreview = CredentialModel( @@ -985,13 +1061,13 @@ class QRCodeScanCubit extends Cubit { credentialManifest: credentialManifest, ); - final host = await getHost(uri: state.uri!, client: client); + final host = await getHost(uri: uri, client: client); emit( state.copyWith( qrScanStatus: QrScanStatus.success, route: CredentialManifestOfferPickPage.route( - uri: state.uri!, + uri: uri, credential: credentialPreview, issuer: Issuer.emptyIssuer(host), inputDescriptorIndex: 0, @@ -1183,6 +1259,7 @@ class QRCodeScanCubit extends Cubit { required String? preAuthorizedCode, required String issuer, required dynamic credentialOfferJson, + required QRCodeScanCubit qrCodeScanCubit, }) async { try { final ( @@ -1214,6 +1291,7 @@ class QRCodeScanCubit extends Cubit { clientSecret: clientSecret, oAuthClientAttestation: oAuthClientAttestation, oAuthClientAttestationPop: oAuthClientAttestationPop, + qrCodeScanCubit: qrCodeScanCubit, ); } else { emit(state.loading()); @@ -1261,6 +1339,7 @@ class QRCodeScanCubit extends Cubit { required String? authorization, required String? clientId, required String? clientSecret, + required QRCodeScanCubit qrCodeScanCubit, String? oAuthClientAttestation, String? oAuthClientAttestationPop, }) async { @@ -1418,6 +1497,7 @@ class QRCodeScanCubit extends Cubit { encodedCredentialOrFutureTokens: encodedCredentialOrFutureTokens, format: format, openIdConfiguration: openIdConfiguration, + qrCodeScanCubit: qrCodeScanCubit, ); } else { throw ResponseMessage( @@ -1469,6 +1549,7 @@ class QRCodeScanCubit extends Cubit { Future authorizedFlowCompletion({ required Map statePayload, required String codeForAuthorisedFlow, + required QRCodeScanCubit qrCodeScanCubit, }) async { try { final containsAllRequiredKey = statePayload.containsKey('credentials') && @@ -1510,6 +1591,7 @@ class QRCodeScanCubit extends Cubit { clientSecret: clientSecret, oAuthClientAttestation: oAuthClientAttestation, oAuthClientAttestationPop: oAuthClientAttestationPop, + qrCodeScanCubit: qrCodeScanCubit, ); } catch (e) { emitError(e); diff --git a/lib/dashboard/qr_code/qr_code_scan/view/qr_code_scan_page.dart b/lib/dashboard/qr_code/qr_code_scan/view/qr_code_scan_page.dart index 7dac2636c..f57b3b1c2 100644 --- a/lib/dashboard/qr_code/qr_code_scan/view/qr_code_scan_page.dart +++ b/lib/dashboard/qr_code/qr_code_scan/view/qr_code_scan_page.dart @@ -82,9 +82,10 @@ class _QrCodeScanPageState extends State { if (isScanned) return; isScanned = true; - await context - .read() - .process(scannedResponse: barcodes.first.rawValue); + await context.read().process( + scannedResponse: barcodes.first.rawValue, + qrCodeScanCubit: context.read(), + ); } }, initialCameraLensDirection: _cameraLensDirection, diff --git a/lib/dashboard/self_issued_credential_button/cubit/self_issued_credential_button_cubit.dart b/lib/dashboard/self_issued_credential_button/cubit/self_issued_credential_button_cubit.dart index 2e4f758ba..1d16d092c 100644 --- a/lib/dashboard/self_issued_credential_button/cubit/self_issued_credential_button_cubit.dart +++ b/lib/dashboard/self_issued_credential_button/cubit/self_issued_credential_button_cubit.dart @@ -22,12 +22,14 @@ class SelfIssuedCredentialCubit extends Cubit { required this.profileCubit, required this.walletCubit, required this.jwtDecode, + required this.qrCodeScanCubit, }) : super(const SelfIssuedCredentialButtonState()); final CredentialsCubit credentialsCubit; final ProfileCubit profileCubit; final WalletCubit walletCubit; final JWTDecode jwtDecode; + final QRCodeScanCubit qrCodeScanCubit; Future createSelfIssuedCredential({ required SelfIssuedCredentialDataModel selfIssuedCredentialDataModel, @@ -150,6 +152,7 @@ class SelfIssuedCredentialCubit extends Cubit { await credentialsCubit.insertCredential( credential: credentialModel, blockchainType: walletCubit.state.currentAccount!.blockchainType, + qrCodeScanCubit: qrCodeScanCubit, ); emit( state.success( diff --git a/lib/enterprise/cubit/enterprise_cubit.dart b/lib/enterprise/cubit/enterprise_cubit.dart index 9519fc0bc..402a7b669 100644 --- a/lib/enterprise/cubit/enterprise_cubit.dart +++ b/lib/enterprise/cubit/enterprise_cubit.dart @@ -2,7 +2,7 @@ import 'dart:convert'; import 'package:altme/app/app.dart'; import 'package:altme/credentials/credentials.dart'; -import 'package:altme/dashboard/profile/profile.dart'; +import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/oidc4vc/oidc4vc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -25,7 +25,10 @@ class EnterpriseCubit extends Cubit { final ProfileCubit profileCubit; final CredentialsCubit credentialsCubit; - Future requestTheConfiguration(Uri uri) async { + Future requestTheConfiguration({ + required Uri uri, + required QRCodeScanCubit qrCodeScanCubit, + }) async { try { emit(state.loading()); @@ -96,6 +99,7 @@ class EnterpriseCubit extends Cubit { await credentialsCubit.addWalletCredential( blockchainType: credentialsCubit.walletCubit.state.currentAccount?.blockchainType, + qrCodeScanCubit: qrCodeScanCubit, ); emit( diff --git a/lib/oidc4vc/add_credential_data.dart b/lib/oidc4vc/add_credential_data.dart index bd724a908..5b5ce0dc6 100644 --- a/lib/oidc4vc/add_credential_data.dart +++ b/lib/oidc4vc/add_credential_data.dart @@ -22,6 +22,7 @@ Future addCredentialData({ required bool isLastCall, required JWTDecode jwtDecode, required BlockchainType blockchainType, + required QRCodeScanCubit qrCodeScanCubit, }) async { for (int i = 0; i < encodedCredentialOrFutureTokens.length; i++) { final data = encodedCredentialOrFutureTokens[i]; @@ -91,6 +92,7 @@ Future addCredentialData({ isLastCall && i + 1 == encodedCredentialOrFutureTokens.length, isPendingCredential: true, blockchainType: blockchainType, + qrCodeScanCubit: qrCodeScanCubit, ); } else { await addOIDC4VCCredential( @@ -104,6 +106,7 @@ Future addCredentialData({ openIdConfiguration: openIdConfiguration, jwtDecode: jwtDecode, blockchainType: blockchainType, + qrCodeScanCubit: qrCodeScanCubit, ); } } diff --git a/lib/oidc4vc/add_oidc4vc_credential.dart b/lib/oidc4vc/add_oidc4vc_credential.dart index 22484f55e..f409f378c 100644 --- a/lib/oidc4vc/add_oidc4vc_credential.dart +++ b/lib/oidc4vc/add_oidc4vc_credential.dart @@ -18,6 +18,7 @@ Future addOIDC4VCCredential({ required String format, required OpenIdConfiguration? openIdConfiguration, required JWTDecode jwtDecode, + required QRCodeScanCubit qrCodeScanCubit, String? credentialIdToBeDeleted, String? issuer, }) async { @@ -32,7 +33,7 @@ Future addOIDC4VCCredential({ final jsonContent = jwtDecode.parseJwt(data); if (format == VCFormatType.vcSdJWT.vcValue) { - final sdAlg = jsonContent['_sd_alg']??'sha-256'; + final sdAlg = jsonContent['_sd_alg'] ?? 'sha-256'; if (sdAlg != 'sha-256') { throw ResponseMessage( @@ -201,5 +202,6 @@ Future addOIDC4VCCredential({ showStatus: false, showMessage: isLastCall, blockchainType: blockchainType, + qrCodeScanCubit: qrCodeScanCubit, ); } diff --git a/lib/oidc4vc/get_and_add_deffered_credential.dart b/lib/oidc4vc/get_and_add_deffered_credential.dart index 81915e146..67d6edb51 100644 --- a/lib/oidc4vc/get_and_add_deffered_credential.dart +++ b/lib/oidc4vc/get_and_add_deffered_credential.dart @@ -15,6 +15,7 @@ Future getAndAddDefferedCredential({ required OIDC4VCIDraftType oidc4vciDraftType, required BlockchainType blockchainType, required String? issuer, + required QRCodeScanCubit qrCodeScanCubit, }) async { Map? credentialHeaders; Map? body; @@ -68,5 +69,6 @@ Future getAndAddDefferedCredential({ openIdConfiguration: null, jwtDecode: jwtDecode, blockchainType: blockchainType, + qrCodeScanCubit: qrCodeScanCubit, ); } diff --git a/lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart b/lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart index f81f0228f..aa62d62ac 100644 --- a/lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart +++ b/lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart @@ -139,6 +139,7 @@ Future initiateOIDC4VCCredentialIssuance({ clientSecret: clientSecret, oAuthClientAttestation: oAuthClientAttestation, oAuthClientAttestationPop: oAuthClientAttestationPop, + qrCodeScanCubit: qrCodeScanCubit, ); } } @@ -151,6 +152,7 @@ Future initiateOIDC4VCCredentialIssuance({ isEBSIV3: isEBSIV3, credentialOfferJson: credentialOfferJson, selectedCredentials: [credentials], + qrCodeScanCubit: qrCodeScanCubit, ); } } diff --git a/lib/polygon_id/cubit/polygon_id_cubit.dart b/lib/polygon_id/cubit/polygon_id_cubit.dart index 458370e98..885d3388c 100644 --- a/lib/polygon_id/cubit/polygon_id_cubit.dart +++ b/lib/polygon_id/cubit/polygon_id_cubit.dart @@ -498,7 +498,9 @@ class PolygonIdCubit extends Cubit { return claims; } - Future addPolygonIdCredentials() async { + Future addPolygonIdCredentials({ + required QRCodeScanCubit qrCodeScanCubit, + }) async { try { log.i('add Claims'); emit(state.copyWith(status: AppStatus.loading)); @@ -506,6 +508,7 @@ class PolygonIdCubit extends Cubit { await addToList( claimEntity: state.claims![i], credentialManifest: state.credentialManifests![i], + qrCodeScanCubit: qrCodeScanCubit, ); } emit(state.copyWith(status: AppStatus.goBack)); @@ -531,6 +534,7 @@ class PolygonIdCubit extends Cubit { Future addToList({ required ClaimEntity claimEntity, required CredentialManifest credentialManifest, + required QRCodeScanCubit qrCodeScanCubit, }) async { final jsonCredential = claimEntity.info; final credentialPreview = Credential.fromJson(jsonCredential); @@ -551,6 +555,7 @@ class PolygonIdCubit extends Cubit { await credentialsCubit.insertCredential( credential: credentialModel, blockchainType: walletCubit.state.currentAccount!.blockchainType, + qrCodeScanCubit: qrCodeScanCubit, ); } diff --git a/lib/scan/cubit/scan_cubit.dart b/lib/scan/cubit/scan_cubit.dart index 7f67490c4..075a60dd5 100644 --- a/lib/scan/cubit/scan_cubit.dart +++ b/lib/scan/cubit/scan_cubit.dart @@ -59,7 +59,7 @@ class ScanCubit extends Cubit { required String keyId, required List? credentialsToBePresented, required Issuer issuer, - QRCodeScanCubit? qrCodeScanCubit, + required QRCodeScanCubit qrCodeScanCubit, }) async { emit(state.loading()); await Future.delayed(const Duration(milliseconds: 500)); @@ -110,7 +110,7 @@ class ScanCubit extends Cubit { privateKey: privateKey, stateValue: stateValue, idTokenNeeded: hasIDToken(responseType), - qrCodeScanCubit: qrCodeScanCubit!, + qrCodeScanCubit: qrCodeScanCubit, ); return; } else { @@ -282,6 +282,7 @@ class ScanCubit extends Cubit { activities: activities, credentialManifest: credentialManifest, ), + qrCodeScanCubit: qrCodeScanCubit, ); if (credentialsToBePresented != null) { diff --git a/lib/splash/bloclisteners/blocklisteners.dart b/lib/splash/bloclisteners/blocklisteners.dart index fd1344a12..79184ecd9 100644 --- a/lib/splash/bloclisteners/blocklisteners.dart +++ b/lib/splash/bloclisteners/blocklisteners.dart @@ -434,6 +434,7 @@ final qrCodeBlocListener = BlocListener( openIdConfiguration: openIdConfigurationForIssuance, issuer: issuerForIssuance, preAuthorizedCode: preAuthorizedCodeForIssuance, + uri: state.uri!, ); } else { context.read().emitError( @@ -495,6 +496,7 @@ final qrCodeBlocListener = BlocListener( await context.read().authorizedFlowCompletion( statePayload: statePayload, codeForAuthorisedFlow: codeForAuthorisedFlow, + qrCodeScanCubit: context.read(), ); } } catch (e) { @@ -570,7 +572,7 @@ final qrCodeBlocListener = BlocListener( ) ?? true; - context.read().completer!.complete(moveAhead); + context.read().completer?.complete(moveAhead); LoadingView().show(context: context); } diff --git a/lib/splash/view/splash_page.dart b/lib/splash/view/splash_page.dart index 6a778b77f..4a54d0733 100644 --- a/lib/splash/view/splash_page.dart +++ b/lib/splash/view/splash_page.dart @@ -130,7 +130,10 @@ class _SplashViewState extends State { } if (uri.toString().startsWith('configuration://?')) { - await context.read().requestTheConfiguration(uri!); + await context.read().requestTheConfiguration( + uri: uri!, + qrCodeScanCubit: context.read(), + ); return; }