diff --git a/lib/app/shared/enum/status/scan_status.dart b/lib/app/shared/enum/status/scan_status.dart index f2375eff9..0e516e8a6 100644 --- a/lib/app/shared/enum/status/scan_status.dart +++ b/lib/app/shared/enum/status/scan_status.dart @@ -5,4 +5,5 @@ enum ScanStatus { error, warning, success, + goBack, } diff --git a/lib/dashboard/home/tab_bar/credentials/present/pick/credential_manifest/view/credential_manifest_credential_offer_pick_page.dart b/lib/dashboard/home/tab_bar/credentials/present/pick/credential_manifest/view/credential_manifest_credential_offer_pick_page.dart index b8f04e29b..6348bd68d 100644 --- a/lib/dashboard/home/tab_bar/credentials/present/pick/credential_manifest/view/credential_manifest_credential_offer_pick_page.dart +++ b/lib/dashboard/home/tab_bar/credentials/present/pick/credential_manifest/view/credential_manifest_credential_offer_pick_page.dart @@ -310,6 +310,7 @@ class CredentialManifestOfferPickView extends StatelessWidget { keyId: SecureStorageKeys.ssiKey, credentialsToBePresented: updatedCredentials, issuer: issuer, + qrCodeScanCubit: context.read(), ); } } diff --git a/lib/scan/cubit/scan_cubit.dart b/lib/scan/cubit/scan_cubit.dart index 6876aef28..e16f52cd6 100644 --- a/lib/scan/cubit/scan_cubit.dart +++ b/lib/scan/cubit/scan_cubit.dart @@ -55,6 +55,7 @@ class ScanCubit extends Cubit { required String keyId, required List? credentialsToBePresented, required Issuer issuer, + QRCodeScanCubit? qrCodeScanCubit, }) async { emit(state.loading()); await Future.delayed(const Duration(milliseconds: 500)); @@ -99,6 +100,7 @@ class ScanCubit extends Cubit { privateKey: privateKey, stateValue: stateValue, idTokenNeeded: false, + qrCodeScanCubit: qrCodeScanCubit!, ); return; } else if (isIDTokenAndVPToken(responseType)) { @@ -116,6 +118,7 @@ class ScanCubit extends Cubit { privateKey: privateKey, stateValue: stateValue, idTokenNeeded: true, + qrCodeScanCubit: qrCodeScanCubit!, ); return; @@ -451,6 +454,7 @@ class ScanCubit extends Cubit { required Uri uri, required String? stateValue, required bool idTokenNeeded, + required QRCodeScanCubit qrCodeScanCubit, }) async { final log = getLogger('ScanCubit - presentCredentialToOIDC4VPAndSIOPV2Request'); @@ -503,17 +507,21 @@ class ScanCubit extends Cubit { responseData['state'] = stateValue; } - final formData = FormData.fromMap(responseData); - - final result = await client.post( + final response = await client.dio.post( responseOrRedirectUri, - data: formData, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, + data: responseData, + options: Options( + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + followRedirects: false, + validateStatus: (status) { + return status != null && status < 400; + }, + ), ); - if (result['status_code'] == 200) { + if (response.statusCode == 200) { await presentationActivity( credentialModels: credentialsToBePresented, issuer: issuer, @@ -529,6 +537,33 @@ class ScanCubit extends Cubit { ), ), ); + } else if (response.statusCode == 302) { + await presentationActivity( + credentialModels: credentialsToBePresented, + issuer: issuer, + ); + + String? url; + + if (response.headers.map.containsKey('location') && + response.headers.map['location'] != null && + response.headers.map['location'] is List && + (response.headers.map['location']!).isNotEmpty) { + url = response.headers.map['location']![0]; + } + + if (url != null) { + final uri = Uri.parse(url); + if (uri.toString().startsWith(Parameters.oidc4vcUniversalLink)) { + emit(state.copyWith(status: ScanStatus.goBack)); + await qrCodeScanCubit.authorizedFlowCompletion(uri); + return; + } + } else { + throw ResponseMessage( + message: ResponseString.RESPONSE_STRING_thisRequestIsNotSupported, + ); + } } else { throw ResponseMessage( message: ResponseString @@ -536,7 +571,7 @@ class ScanCubit extends Cubit { ); } } catch (e, s) { - log.e('something went wrong', error: e, stackTrace: s); + log.e('something went wrong - $e', error: e, stackTrace: s); emitError(e); } } @@ -587,6 +622,7 @@ class ScanCubit extends Cubit { 'format': 'jwt_vp', 'path': r'$', 'path_nested': { + 'id': descriptor.id, 'format': format, 'path': r'$.verifiableCredential', }, @@ -598,10 +634,12 @@ class ScanCubit extends Cubit { for (final InputDescriptor inputDescriptor in presentationDefinition.inputDescriptors) { for (final Field field in inputDescriptor.constraints!.fields!) { + final credentialName = + field.filter!.pattern ?? field.filter!.contains!.containsConst; if (credentialsToBePresented[i] .credentialPreview .type - .contains(field.filter!.pattern)) { + .contains(credentialName)) { descriptor = inputDescriptor; } } @@ -612,6 +650,7 @@ class ScanCubit extends Cubit { 'format': 'jwt_vp', 'path': r'$', 'path_nested': { + 'id': descriptor.id, 'format': format, // ignore: prefer_interpolation_to_compose_strings 'path': r'$.verifiableCredential[' + i.toString() + ']', diff --git a/lib/splash/bloclisteners/blocklisteners.dart b/lib/splash/bloclisteners/blocklisteners.dart index 6febf608a..e87db3a83 100644 --- a/lib/splash/bloclisteners/blocklisteners.dart +++ b/lib/splash/bloclisteners/blocklisteners.dart @@ -193,6 +193,10 @@ final scanBlocListener = BlocListener( if (state.status == ScanStatus.error) { Navigator.of(context).pop(); } + + if (state.status == ScanStatus.goBack) { + Navigator.of(context).pop(); + } }, );