From c1cc00574396baf1c2f6c0f162ead3eb1222d6f3 Mon Sep 17 00:00:00 2001 From: hawkbee1 Date: Fri, 8 Mar 2024 06:24:11 +0000 Subject: [PATCH] get claims --- ...l_manifest_credential_offer_pick_page.dart | 166 ++++++++++++------ .../view/selective_disclosure_pick_page.dart | 138 +++++++++++++++ lib/lang/cubit/lang_cubit.dart | 13 +- .../src/helpers/get_text_from_credential.dart | 2 +- .../lib/src/models/format.dart | 3 + pubspec.lock | 108 +++++++----- 6 files changed, 328 insertions(+), 102 deletions(-) create mode 100644 lib/dashboard/home/tab_bar/credentials/present/pick/credential_manifest/view/selective_disclosure_pick_page.dart 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 da79575d4..ba2b805a5 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 @@ -1,12 +1,14 @@ 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/present/pick/credential_manifest/view/selective_disclosure_pick_page.dart'; import 'package:altme/l10n/l10n.dart'; import 'package:altme/scan/cubit/scan_cubit.dart'; import 'package:altme/theme/theme.dart'; import 'package:credential_manifest/credential_manifest.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:oidc4vc/oidc4vc.dart'; class CredentialManifestOfferPickPage extends StatelessWidget { const CredentialManifestOfferPickPage({ @@ -174,70 +176,84 @@ class CredentialManifestOfferPickView extends StatelessWidget { ), navigation: credentialManifestState .filteredCredentialList.isNotEmpty - ? SafeArea( - child: Container( - padding: const EdgeInsets.all(16), - child: Tooltip( - message: l10n.credentialPickPresent, - child: Builder( - builder: (context) { - final inputDescriptor = - presentationDefinition!.inputDescriptors[ - inputDescriptorIndex]; + ? context + .read() + .state + .model + .profileSetting + .selfSovereignIdentityOptions + .customOidc4vcProfile + .vcFormatType == + VCFormatType.vcSdJWT + ? vcSdJwtCredentialPickButton( + context: context, + credentialManifestState: credentialManifestState, + ) + : SafeArea( + child: Container( + padding: const EdgeInsets.all(16), + child: Tooltip( + message: l10n.credentialPickPresent, + child: Builder( + builder: (context) { + final inputDescriptor = + presentationDefinition! + .inputDescriptors[ + inputDescriptorIndex]; - final bool isOptional = inputDescriptor - .constraints - ?.fields - ?.first - .optional ?? - false; + final bool isOptional = inputDescriptor + .constraints + ?.fields + ?.first + .optional ?? + false; - final bool isOngoingStep = - inputDescriptorIndex + 1 != - presentationDefinition - .inputDescriptors.length; + final bool isOngoingStep = + inputDescriptorIndex + 1 != + presentationDefinition + .inputDescriptors.length; - if (isOptional) { - return MyGradientButton( - onPressed: () => present( - context: context, - credentialManifestState: - credentialManifestState, - presentationDefinition: - presentationDefinition, - skip: credentialManifestState - .selected.isEmpty, - ), - text: credentialManifestState - .selected.isEmpty - ? l10n.skip - : isOngoingStep + if (isOptional) { + return MyGradientButton( + onPressed: () => present( + context: context, + credentialManifestState: + credentialManifestState, + presentationDefinition: + presentationDefinition, + skip: credentialManifestState + .selected.isEmpty, + ), + text: credentialManifestState + .selected.isEmpty + ? l10n.skip + : isOngoingStep + ? l10n.next + : l10n.credentialPickPresent, + ); + } else { + return MyGradientButton( + onPressed: !credentialManifestState + .isButtonEnabled + ? null + : () => present( + context: context, + credentialManifestState: + credentialManifestState, + presentationDefinition: + presentationDefinition, + skip: false, + ), + text: isOngoingStep ? l10n.next : l10n.credentialPickPresent, - ); - } else { - return MyGradientButton( - onPressed: !credentialManifestState - .isButtonEnabled - ? null - : () => present( - context: context, - credentialManifestState: - credentialManifestState, - presentationDefinition: - presentationDefinition, - skip: false, - ), - text: isOngoingStep - ? l10n.next - : l10n.credentialPickPresent, - ); - } - }, + ); + } + }, + ), + ), ), - ), - ), - ) + ) : const SizedBox.shrink(), ), ); @@ -317,4 +333,38 @@ class CredentialManifestOfferPickView extends StatelessWidget { ); } } + + Widget vcSdJwtCredentialPickButton({ + required BuildContext context, + required CredentialManifestPickState credentialManifestState, + }) { + final l10n = context.l10n; + + final button = SafeArea( + child: Container( + padding: const EdgeInsets.all(16), + child: Tooltip( + message: l10n.credentialPickPresent, + child: MyGradientButton( + onPressed: !credentialManifestState.isButtonEnabled + ? null + : () => Navigator.of(context).pushReplacement( + SelectiveDisclosurePickPage.route( + uri: uri, + issuer: issuer, + credential: credential, + credentialToBePresented: + credentialManifestState.filteredCredentialList[ + credentialManifestState.selected.first], + ), + ), + + /// next button because we will now choose the claims we will present + /// from the selected credential + text: l10n.next, + ), + ), + )); + return button; + } } diff --git a/lib/dashboard/home/tab_bar/credentials/present/pick/credential_manifest/view/selective_disclosure_pick_page.dart b/lib/dashboard/home/tab_bar/credentials/present/pick/credential_manifest/view/selective_disclosure_pick_page.dart new file mode 100644 index 000000000..af5f13d45 --- /dev/null +++ b/lib/dashboard/home/tab_bar/credentials/present/pick/credential_manifest/view/selective_disclosure_pick_page.dart @@ -0,0 +1,138 @@ +import 'package:altme/app/app.dart'; +import 'package:altme/credentials/credentials.dart'; +import 'package:altme/dashboard/dashboard.dart'; +import 'package:altme/l10n/l10n.dart'; +import 'package:altme/scan/cubit/scan_cubit.dart'; +import 'package:altme/theme/theme.dart'; +import 'package:credential_manifest/credential_manifest.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class SelectiveDisclosurePickPage extends StatelessWidget { + const SelectiveDisclosurePickPage({ + super.key, + required this.uri, + required this.credential, + required this.issuer, + required this.credentialToBePresented, + }); + + final Uri uri; + final CredentialModel credential; + final Issuer issuer; + final CredentialModel credentialToBePresented; + + static Route route({ + required Uri uri, + required CredentialModel credential, + required Issuer issuer, + required CredentialModel credentialToBePresented, + }) { + return MaterialPageRoute( + builder: (context) => SelectiveDisclosurePickPage( + uri: uri, + credential: credential, + issuer: issuer, + credentialToBePresented: credentialToBePresented, + ), + settings: const RouteSettings(name: '/SelectiveDisclosurePickPage'), + ); + } + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) { + return CredentialManifestPickCubit( + credential: credential, + credentialList: context.read().state.credentials, + inputDescriptorIndex: 0, + ); + }, + child: SelectiveDisclosurePickView( + uri: uri, + credential: credential, + issuer: issuer, + credentialToBePresented: credentialToBePresented, + ), + ); + } +} + +class SelectiveDisclosurePickView extends StatelessWidget { + const SelectiveDisclosurePickView({ + super.key, + required this.uri, + required this.credential, + required this.issuer, + required this.credentialToBePresented, + }); + + final Uri uri; + final CredentialModel credential; + final Issuer issuer; + final CredentialModel credentialToBePresented; + + @override + Widget build(BuildContext context) { + final l10n = context.l10n; + + return BlocConsumer( + listener: (context, state) { + if (state.message != null) { + AlertMessage.showStateMessage( + context: context, + stateMessage: state.message!, + ); + } + }, + builder: (context, credentialManifestState) { + final PresentationDefinition? presentationDefinition = + credentialManifestState.presentationDefinition; + + return BlocListener( + listener: (context, scanState) { + if (scanState.status == ScanStatus.loading) { + LoadingView().show(context: context); + } else { + LoadingView().hide(); + } + if (scanState.message != null) { + AlertMessage.showStateMessage( + context: context, + stateMessage: scanState.message!, + ); + } + }, + child: credentialManifestState.filteredCredentialList.isEmpty + ? const RequiredCredentialNotFound() + : BasePage( + title: l10n.credentialPickTitle, + titleAlignment: Alignment.topCenter, + titleTrailing: const WhiteCloseButton(), + padding: const EdgeInsets.symmetric( + vertical: 24, + horizontal: 16, + ), + body: ClaimsData( + credentialModel: credentialToBePresented, + ), + navigation: SafeArea( + child: Container( + padding: const EdgeInsets.all(16), + child: Tooltip( + message: l10n.credentialPickPresent, + child: MyGradientButton( + onPressed: () => (), + text: l10n.credentialPickPresent, + ), + ), + ), + ), + ), + ); + }, + ); + } +} diff --git a/lib/lang/cubit/lang_cubit.dart b/lib/lang/cubit/lang_cubit.dart index 0abd28e65..05921ce29 100644 --- a/lib/lang/cubit/lang_cubit.dart +++ b/lib/lang/cubit/lang_cubit.dart @@ -22,7 +22,18 @@ class LangCubit extends Cubit { /// emit new state if language recorded is dufferent than english Future checkLocale() async { final languageType = await getRecordedLanguage(); - emit(state.copyWith(languageType: languageType)); + if (languageType == LanguageType.phone) { + emit(state.copyWith(languageType: languageType)); + } else { + emit( + state.copyWith( + languageType: languageType, + locale: Locale( + languageType.name, + ), + ), + ); + } } Future getRecordedLanguage() async { diff --git a/packages/credential_manifest/lib/src/helpers/get_text_from_credential.dart b/packages/credential_manifest/lib/src/helpers/get_text_from_credential.dart index ab418ec98..c30ddc3ae 100644 --- a/packages/credential_manifest/lib/src/helpers/get_text_from_credential.dart +++ b/packages/credential_manifest/lib/src/helpers/get_text_from_credential.dart @@ -6,7 +6,7 @@ List getTextsFromCredential( ) { final textList = []; try { - final fieldsPath = JsonPath(jsonPath.replaceAll('.vc', '')); + final fieldsPath = JsonPath(jsonPath); fieldsPath.read(data).forEach((a) { final dynamic value = a.value; if (value is String) { diff --git a/packages/credential_manifest/lib/src/models/format.dart b/packages/credential_manifest/lib/src/models/format.dart index 599378253..e9d86cd6f 100644 --- a/packages/credential_manifest/lib/src/models/format.dart +++ b/packages/credential_manifest/lib/src/models/format.dart @@ -10,6 +10,7 @@ class Format { this.jwtVc, this.ldpVp, this.ldpVc, + this.vcSdJwt, }); factory Format.fromJson(Map json) => _$FormatFromJson(json); @@ -22,6 +23,8 @@ class Format { FormatType? ldpVp; @JsonKey(name: 'ldp_vc') FormatType? ldpVc; + @JsonKey(name: 'vc+sd-jwt') + FormatType? vcSdJwt; Map toJson() => _$FormatToJson(this); } diff --git a/pubspec.lock b/pubspec.lock index dceed54c1..c3fe0d4b8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" url: "https://pub.dev" source: hosted - version: "64.0.0" + version: "67.0.0" adaptive_number: dependency: transitive description: @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: analyzer - sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.4.1" android_intent_plus: dependency: transitive description: @@ -310,10 +310,10 @@ packages: dependency: transitive description: name: camera_avfoundation - sha256: "7d0763dfcbf060f56aa254a68c103210280bee9e97bbe4fdef23e257a4f70ab9" + sha256: "8b113e43ee4434c9244c03c905432a0d5956cedaded3cd7381abaab89ce50297" url: "https://pub.dev" source: hosted - version: "0.9.14" + version: "0.9.14+1" camera_platform_interface: dependency: transitive description: @@ -437,10 +437,10 @@ packages: dependency: transitive description: name: cross_file - sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e + sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" url: "https://pub.dev" source: hosted - version: "0.3.3+8" + version: "0.3.4+1" crypto: dependency: "direct main" description: @@ -771,10 +771,10 @@ packages: dependency: "direct main" description: name: file_picker - sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6" + sha256: caa6bc229eab3e32eb2f37b53a5f9d22a6981474afd210c512a7546c1e1a04f6 url: "https://pub.dev" source: hosted - version: "6.1.1" + version: "6.2.0" file_saver: dependency: "direct main" description: @@ -944,10 +944,10 @@ packages: dependency: "direct main" description: name: flutter_local_notifications - sha256: c18f1de98fe0bb9dd5ba91e1330d4febc8b6a7de6aae3ffe475ef423723e72f3 + sha256: "55b9b229307a10974b26296ff29f2e132256ba4bd74266939118eaefa941cb00" url: "https://pub.dev" source: hosted - version: "16.3.2" + version: "16.3.3" flutter_local_notifications_linux: dependency: transitive description: @@ -973,10 +973,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: "5b24061317f850af858ef7151dadbb6eb77c1c449c954c7bb064e8a5e0e7d81f" + sha256: cb44f7831b23a6bdd0f501718b0d2e8045cbc625a15f668af37ddb80314821db url: "https://pub.dev" source: hosted - version: "0.6.20" + version: "0.6.21" flutter_native_timezone: dependency: "direct main" description: @@ -1199,10 +1199,10 @@ packages: dependency: "direct overridden" description: name: http - sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba + sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" http_mock_adapter: dependency: "direct dev" description: @@ -1255,10 +1255,10 @@ packages: dependency: transitive description: name: image_picker_for_web - sha256: e2423c53a68b579a7c37a1eda967b8ae536c3d98518e5db95ca1fe5719a730a3 + sha256: "6a1704fdd75022272e7e7a897a9068e9c2ff3cd6a66820bf3ded810633eac954" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" image_picker_ios: dependency: transitive description: @@ -1287,10 +1287,10 @@ packages: dependency: transitive description: name: image_picker_platform_interface - sha256: fa4e815e6fcada50e35718727d83ba1c92f1edf95c0b4436554cec301b56233b + sha256: "3d2c323daea9d60608f1caf30be32a938916f4975434b8352e6f73dae496da38" url: "https://pub.dev" source: hosted - version: "2.9.3" + version: "2.9.4" image_picker_windows: dependency: transitive description: @@ -1385,6 +1385,30 @@ packages: relative: true source: path version: "1.0.0+1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" linkify: dependency: transitive description: @@ -1461,34 +1485,34 @@ packages: dependency: "direct main" description: name: markdown - sha256: "1b134d9f8ff2da15cb298efe6cd8b7d2a78958c1b00384ebcbdf13fe340a6c90" + sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051 url: "https://pub.dev" source: hosted - version: "7.2.1" + version: "7.2.2" matcher: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" matrix: dependency: "direct main" description: name: matrix - sha256: baefc62fd4ea6e857fd8cfe6f8b0421a08cd58223dbf94c9b3cc3bc29497a8ff + sha256: "02a21edb9b35881081734ea33de004334b55642299ddd4a9b2640cfd62764ccd" url: "https://pub.dev" source: hosted - version: "0.25.12" + version: "0.25.13" matrix_api_lite: dependency: transitive description: @@ -1509,10 +1533,10 @@ packages: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: "direct main" description: @@ -1660,10 +1684,10 @@ packages: dependency: "direct main" description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_drawing: dependency: transitive description: @@ -2115,10 +2139,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" + sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.0" shared_preferences_windows: dependency: transitive description: @@ -2449,10 +2473,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b + sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.0" url_launcher_windows: dependency: transitive description: @@ -2553,10 +2577,10 @@ packages: dependency: transitive description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.5.1" web3dart: dependency: transitive description: @@ -2569,10 +2593,10 @@ packages: dependency: transitive description: name: web_socket_channel - sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + sha256: "1d8e795e2a8b3730c41b8a98a2dff2e0fb57ae6f0764a1c46ec5915387d257b2" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.4" webkit_inspection_protocol: dependency: transitive description: @@ -2686,5 +2710,5 @@ packages: source: hosted version: "2.2.0" sdks: - dart: ">=3.2.3 <4.0.0" - flutter: ">=3.16.6" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0"