Skip to content

Commit

Permalink
October (#2038)
Browse files Browse the repository at this point in the history
* feat: Update wallet client metadata #1992

* feat: Added category for SIOPV2/OIDC4VP #1999

* feat: Replace download button with share option #2026

* feat: Drawer management #2030

* feat: Update json viewer page

* feat: Update whats new

* feat: Binding of credential switch added

* version update

* bug fix and version update

---------

Co-authored-by: Bibash Shrestha <[email protected]>
  • Loading branch information
hawkbee1 and bibash28 authored Oct 20, 2023
1 parent 04be760 commit bbe9616
Show file tree
Hide file tree
Showing 41 changed files with 692 additions and 311 deletions.
2 changes: 2 additions & 0 deletions lib/app/shared/constants/secure_storage_keys.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class SecureStorageKeys {
static const String enable4DigitPINCode = 'enable4DigitPINCode';
static const String isDeveloperMode = 'isDeveloperMode';
static const String enableJWKThumbprint = 'enableJWKThumbprint';
static const String enableCryptographicHolderBinding =
'enableCryptographicHolderBinding';

static const String pinCode = 'pinCode';
static const String data = 'data';
Expand Down
186 changes: 163 additions & 23 deletions lib/app/shared/helper_functions/helper_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,40 @@ Future<Map<String, dynamic>?> getPresentationDefinition({
}
}

Future<Map<String, dynamic>?> getClientMetada({
required Uri uri,
required DioClient client,
}) async {
try {
final keys = <String>[];
uri.queryParameters.forEach((key, value) => keys.add(key));

if (keys.contains('client_metadata')) {
final String clientMetaDataValue =
uri.queryParameters['client_metadata'] ?? '';

final json = jsonDecode(clientMetaDataValue.replaceAll("'", '"'))
as Map<String, dynamic>;

return json;
} else if (keys.contains('client_metadata_uri')) {
final clientMetaDataUri =
uri.queryParameters['client_metadata_uri'].toString();
final dynamic response = await client.get(clientMetaDataUri);

final Map<String, dynamic> data = response == String
? jsonDecode(response.toString()) as Map<String, dynamic>
: response as Map<String, dynamic>;

return data;
} else {
return null;
}
} catch (e) {
return null;
}
}

Future<bool?> isEBSIV3ForVerifiers({
required Uri uri,
required DioClient client,
Expand Down Expand Up @@ -993,39 +1027,59 @@ String getFormattedStringOIDC4VCI({
dynamic credentialOfferJson,
}) {
return '''
SCHEME : ${getSchemeFromUrl(url)}
\n
CREDENTIAL OFFER :
${credentialOfferJson != null ? const JsonEncoder.withIndent(' ').convert(credentialOfferJson) : 'None'}
\n
ENDPOINTS :
<b>SCHEME :</b> ${getSchemeFromUrl(url)}\n
<b>CREDENTIAL OFFER :</b>
${credentialOfferJson != null ? const JsonEncoder.withIndent(' ').convert(credentialOfferJson) : 'None'}\n
<b>ENDPOINTS :</b>
authorization server endpoint : ${openidConfigurationResponse?['authorization_server'] ?? 'None'}
token endpoint : ${openidConfigurationResponse?['token_endpoint'] ?? authorizationServerConfiguration?['token_endpoint'] ?? 'None'}
credential endpoint : ${openidConfigurationResponse?['credential_endpoint'] ?? 'None'}
deferred endpoint : ${openidConfigurationResponse?['deferred_endpoint'] ?? 'None'}
batch endpoint : ${openidConfigurationResponse?['batch_endpoint'] ?? 'None'}
\n
CREDENTIAL SUPPORTED :
${openidConfigurationResponse?['credentials_supported'] != null ? const JsonEncoder.withIndent(' ').convert(openidConfigurationResponse!['credentials_supported']) : 'None'}
\n
AUTHORIZATION SERVER CONFIGURATION :
${authorizationServerConfiguration != null ? const JsonEncoder.withIndent(' ').convert(authorizationServerConfiguration) : 'None'}
\n
CRDENTIAL ISSUER CONFIGURATION :
batch endpoint : ${openidConfigurationResponse?['batch_endpoint'] ?? 'None'}\n
<b>CREDENTIAL SUPPORTED :</b>
${openidConfigurationResponse?['credentials_supported'] != null ? const JsonEncoder.withIndent(' ').convert(openidConfigurationResponse!['credentials_supported']) : 'None'}\n
<b>AUTHORIZATION SERVER CONFIGURATION :</b>
${authorizationServerConfiguration != null ? const JsonEncoder.withIndent(' ').convert(authorizationServerConfiguration) : 'None'}\n
<b>CRDENTIAL ISSUER CONFIGURATION :</b>
${openidConfigurationResponse != null ? const JsonEncoder.withIndent(' ').convert(openidConfigurationResponse) : 'None'}
''';
}

String getFormattedStringOIDC4VPSIOPV2({
Future<String> getFormattedStringOIDC4VPSIOPV2({
required String url,
required Map<String, dynamic>? presentationDefinition,
}) {
return '''
SCHEME : ${getSchemeFromUrl(url)}
\n
PRESENTATION DEFINITION :
${presentationDefinition != null ? const JsonEncoder.withIndent(' ').convert(presentationDefinition) : 'None'}
required DioClient client,
required Map<String, dynamic>? response,
}) async {
final Map<String, dynamic>? presentationDefinition =
await getPresentationDefinition(
client: client,
uri: Uri.parse(url),
);

final Map<String, dynamic>? clientMetaData = await getClientMetada(
client: client,
uri: Uri.parse(url),
);

final registration = Uri.parse(url).queryParameters['registration'];

final registrationMap = registration != null
? jsonDecode(registration) as Map<String, dynamic>
: null;

final data = '''
<b>SCHEME :</b> ${getSchemeFromUrl(url)}\n
<b>AUTHORIZATION REQUEST :</b>
${response != null ? const JsonEncoder.withIndent(' ').convert(response) : 'None'}\n
<b>CLIENT METADATA :</b>
${clientMetaData != null ? const JsonEncoder.withIndent(' ').convert(clientMetaData) : 'None'}\n
PRESENTATION DEFINITION :</b>
${presentationDefinition != null ? const JsonEncoder.withIndent(' ').convert(presentationDefinition) : 'None'}\n
<b>REGISTRATION :</b>
${registrationMap != null ? const JsonEncoder.withIndent(' ').convert(registrationMap) : 'None'}
''';

return data;
}

String getSchemeFromUrl(String url) {
Expand All @@ -1052,3 +1106,89 @@ Future<dynamic> fetchRequestUriPayload({
}
return data;
}

String getUpdatedUrlForSIOPV2OIC4VP({
required String url,
required Map<String, dynamic> response,
}) {
final responseType = response['response_type'];
final redirectUri = response['redirect_uri'];
final scope = response['scope'];
final responseUri = response['response_uri'];
final responseMode = response['response_mode'];
final nonce = response['nonce'];
final clientId = response['client_id'];
final claims = response['claims'];
final stateValue = response['state'];
final presentationDefinition = response['presentation_definition'];
final presentationDefinitionUri = response['presentation_definition_uri'];
final registration = response['registration'];
final clientMetadata = response['client_metadata'];
final clientMetadataUri = response['client_metadata_uri'];

final queryJson = <String, dynamic>{};

if (scope != null) {
queryJson['scope'] = scope;
}

if (clientId != null) {
queryJson['client_id'] = clientId;
}

if (redirectUri != null) {
queryJson['redirect_uri'] = redirectUri;
}

if (responseUri != null) {
queryJson['response_uri'] = responseUri;
}

if (responseMode != null) {
queryJson['response_mode'] = responseMode;
}

if (nonce != null) {
queryJson['nonce'] = nonce;
}

if (stateValue != null) {
queryJson['state'] = stateValue;
}

if (responseType != null) {
queryJson['response_type'] = responseType;
}

if (claims != null) {
queryJson['claims'] = jsonEncode(claims).replaceAll('"', "'");
}

if (presentationDefinition != null) {
queryJson['presentation_definition'] =
jsonEncode(presentationDefinition).replaceAll('"', "'");
}

if (presentationDefinitionUri != null) {
queryJson['presentation_definition_uri'] = presentationDefinitionUri;
}

if (registration != null) {
queryJson['registration'] =
registration is Map ? jsonEncode(registration) : registration;
}

if (clientMetadata != null) {
queryJson['client_metadata'] =
jsonEncode(clientMetadata).replaceAll('"', "'");
}

if (clientMetadataUri != null) {
queryJson['client_metadata_uri'] = clientMetadataUri;
}

final String queryString = Uri(queryParameters: queryJson).query;

final String newUrl = '$url&$queryString';
return newUrl;
}
2 changes: 1 addition & 1 deletion lib/app/shared/widget/grouped_section.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class GroupedSection extends StatelessWidget {
padding: const EdgeInsets.all(Sizes.spaceSmall),
margin: const EdgeInsets.all(Sizes.spaceXSmall),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.cardHighlighted,
color: Theme.of(context).colorScheme.drawerSurface,
borderRadius: const BorderRadius.all(
Radius.circular(Sizes.largeRadius),
),
Expand Down
88 changes: 46 additions & 42 deletions lib/dashboard/drawer/src/widgets/drawer_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,53 +33,57 @@ class DrawerItem extends StatelessWidget {
),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.drawerItemTitle.copyWith(
color: isDisabled
? Theme.of(context).colorScheme.lightGrey
: null,
),
),
if (subtitle != null) ...[
const SizedBox(height: 10),
child: SizedBox(
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
subtitle!,
style: Theme.of(context)
.textTheme
.drawerItemSubtitle
.copyWith(
color: isDisabled
? Theme.of(context).colorScheme.lightGrey
: null,
),
title,
style:
Theme.of(context).textTheme.drawerItemTitle.copyWith(
color: isDisabled
? Theme.of(context).colorScheme.lightGrey
: null,
),
),
const SizedBox(height: 10),
if (subtitle != null) ...[
const SizedBox(height: 10),
Text(
subtitle!,
style: Theme.of(context)
.textTheme
.drawerItemSubtitle
.copyWith(
color: isDisabled
? Theme.of(context).colorScheme.lightGrey
: null,
),
),
const SizedBox(height: 10),
],
],
],
),
),
if (trailing != null)
trailing!
else ...[
const SizedBox(width: 16),
Icon(
Icons.chevron_right,
size: Sizes.icon2x,
color: isDisabled
? Theme.of(context).colorScheme.lightGrey
: Theme.of(context).colorScheme.unSelectedLabel,
),
),
if (trailing != null)
trailing!
else ...[
const SizedBox(width: 16),
Icon(
Icons.chevron_right,
size: Sizes.icon2x,
color: isDisabled
? Theme.of(context).colorScheme.lightGrey
: Theme.of(context).colorScheme.unSelectedLabel,
),
],
],
],
),
),
),
);
Expand Down
52 changes: 31 additions & 21 deletions lib/dashboard/drawer/src/widgets/drawer_item2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,40 @@ class DrawerItem2 extends StatelessWidget {
),
child: SizedBox(
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
style: Theme.of(context).textTheme.drawerItemTitle.copyWith(
color: isDisabled
? Theme.of(context).colorScheme.lightGrey
: null,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style:
Theme.of(context).textTheme.drawerItemTitle.copyWith(
color: isDisabled
? Theme.of(context).colorScheme.lightGrey
: null,
),
),
),
if (subtitle != null) ...[
const SizedBox(height: 10),
Text(
subtitle!,
style:
Theme.of(context).textTheme.drawerItemSubtitle.copyWith(
color: isDisabled
? Theme.of(context).colorScheme.lightGrey
: null,
),
if (subtitle != null) ...[
const SizedBox(height: 10),
Text(
subtitle!,
style: Theme.of(context)
.textTheme
.drawerItemSubtitle
.copyWith(
color: isDisabled
? Theme.of(context).colorScheme.lightGrey
: null,
),
),
const SizedBox(height: 20),
],
],
),
const SizedBox(height: 20),
],
),
if (trailing != null)
trailing!
else ...[
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export 'manage_issuers_registry/verifiable_data_registry.dart';
export 'oidc4vc_profile/oidc4vc_profile.dart';
export 'oidc4vc_settngs/oidc4vc_settings.dart';
export 'src/src.dart';
Loading

0 comments on commit bbe9616

Please sign in to comment.