Skip to content

Commit

Permalink
Merge branch 'main' into main_android
Browse files Browse the repository at this point in the history
  • Loading branch information
hawkbee1 committed Oct 19, 2023
2 parents ab48032 + 7e0fabf commit a77027c
Show file tree
Hide file tree
Showing 24 changed files with 654 additions and 155 deletions.
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 33
compileSdkVersion 34

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand Down
204 changes: 173 additions & 31 deletions lib/app/shared/helper_functions/helper_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,8 @@ bool isSIOPV2OROIDC4VPUrl(Uri uri) {
return isOpenIdUrl || isAuthorizeEndPoint || isSiopv2Url;
}

Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({
Future<(OIDC4VCType?, Map<String, dynamic>?, Map<String, dynamic>?, dynamic)>
getIssuanceData({
required String url,
required DioClient client,
}) async {
Expand All @@ -509,12 +510,13 @@ Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({
final keys = <String>[];
uri.queryParameters.forEach((key, value) => keys.add(key));

dynamic credentialOfferJson;
String? issuer;

if (keys.contains('credential_offer') ||
keys.contains('credential_offer_uri')) {
/// issuance case 2
final dynamic credentialOfferJson = await getCredentialOfferJson(
credentialOfferJson = await getCredentialOfferJson(
scannedResponse: uri.toString(),
dioClient: client,
);
Expand All @@ -529,14 +531,81 @@ Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({
}

if (issuer == null) {
return null;
return (null, null, null, null);
}

final openidConfigurationResponse = await getOpenIdConfig(
baseUrl: issuer,
client: client.dio,
);

final authorizationServer =
openidConfigurationResponse['authorization_server'];

Map<String, dynamic>? authorizationServerConfiguration;

if (authorizationServer != null) {
authorizationServerConfiguration = await getOpenIdConfig(
baseUrl: authorizationServer.toString(),
client: client.dio,
);
}

final credentialsSupported =
openidConfigurationResponse['credentials_supported'] as List<dynamic>;

final credSupported = credentialsSupported[0] as Map<String, dynamic>;
for (final oidc4vcType in OIDC4VCType.values) {
if (oidc4vcType.isEnabled && url.startsWith(oidc4vcType.offerPrefix)) {
if (oidc4vcType == OIDC4VCType.DEFAULT ||
oidc4vcType == OIDC4VCType.EBSIV3) {
if (credSupported['trust_framework'] == null) {
return (
OIDC4VCType.DEFAULT,
openidConfigurationResponse,
authorizationServerConfiguration,
credentialOfferJson,
);
}

if (credSupported['trust_framework']['name'] == 'ebsi') {
return (
OIDC4VCType.EBSIV3,
openidConfigurationResponse,
authorizationServerConfiguration,
credentialOfferJson,
);
} else {
return (
OIDC4VCType.DEFAULT,
openidConfigurationResponse,
authorizationServerConfiguration,
credentialOfferJson,
);
}
}
return (
oidc4vcType,
openidConfigurationResponse,
authorizationServerConfiguration,
credentialOfferJson,
);
}
}

return (
null,
openidConfigurationResponse,
authorizationServerConfiguration,
credentialOfferJson,
);
}

Future<void> handleErrorForOID4VCI({
required String url,
required Map<String, dynamic> openidConfigurationResponse,
required Map<String, dynamic>? authorizationServerConfiguration,
}) async {
final authorizationServer =
openidConfigurationResponse['authorization_server'];

Expand All @@ -554,24 +623,19 @@ Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({
tokenEndpoint = openidConfigurationResponse['token_endpoint'].toString();
}

if (authorizationServer != null) {
final openidConfigurationResponseSecond = await getOpenIdConfig(
baseUrl: authorizationServer.toString(),
client: client.dio,
);

if (authorizationServer != null && authorizationServerConfiguration != null) {
if (subjectSyntaxTypesSupported == null &&
openidConfigurationResponseSecond
authorizationServerConfiguration
.containsKey('subject_syntax_types_supported')) {
subjectSyntaxTypesSupported =
openidConfigurationResponseSecond['subject_syntax_types_supported']
authorizationServerConfiguration['subject_syntax_types_supported']
as List<dynamic>;
}

if (tokenEndpoint == null &&
openidConfigurationResponseSecond.containsKey('token_endpoint')) {
authorizationServerConfiguration.containsKey('token_endpoint')) {
tokenEndpoint =
openidConfigurationResponseSecond['token_endpoint'].toString();
authorizationServerConfiguration['token_endpoint'].toString();
}
}

Expand Down Expand Up @@ -624,29 +688,40 @@ Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({
},
);
}
}

final credentialsSupported =
openidConfigurationResponse['credentials_supported'] as List<dynamic>;
Future<Map<String, dynamic>?> getPresentationDefinition({
required Uri uri,
required DioClient client,
}) async {
try {
final keys = <String>[];
uri.queryParameters.forEach((key, value) => keys.add(key));

final credSupported = credentialsSupported[0] as Map<String, dynamic>;
for (final oidc4vcType in OIDC4VCType.values) {
if (oidc4vcType.isEnabled && url.startsWith(oidc4vcType.offerPrefix)) {
if (oidc4vcType == OIDC4VCType.DEFAULT ||
oidc4vcType == OIDC4VCType.EBSIV3) {
if (credSupported['trust_framework'] == null) {
return OIDC4VCType.DEFAULT;
}
if (keys.contains('presentation_definition')) {
final String presentationDefinitionValue =
uri.queryParameters['presentation_definition'] ?? '';

if (credSupported['trust_framework']['name'] == 'ebsi') {
return OIDC4VCType.EBSIV3;
} else {
return OIDC4VCType.DEFAULT;
}
}
return oidc4vcType;
final json = jsonDecode(presentationDefinitionValue.replaceAll("'", '"'))
as Map<String, dynamic>;

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

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;
}
return null;
}

Future<bool?> isEBSIV3ForVerifiers({
Expand Down Expand Up @@ -910,3 +985,70 @@ bool hasVPToken(String responseType) {
bool hasIDTokenOrVPToken(String responseType) {
return responseType.contains('id_token') || responseType.contains('vp_token');
}

String getFormattedStringOIDC4VCI({
required String url,
Map<String, dynamic>? openidConfigurationResponse,
Map<String, dynamic>? authorizationServerConfiguration,
dynamic credentialOfferJson,
}) {
return '''
SCHEME : ${getSchemeFromUrl(url)}
\n
CREDENTIAL OFFER :
${credentialOfferJson != null ? const JsonEncoder.withIndent(' ').convert(credentialOfferJson) : 'None'}
\n
ENDPOINTS :
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 :
${openidConfigurationResponse != null ? const JsonEncoder.withIndent(' ').convert(openidConfigurationResponse) : 'None'}
''';
}

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'}
''';
}

String getSchemeFromUrl(String url) {
final parts = url.split(':');
return parts.length > 1 ? '${parts[0]}://' : '';
}

Future<dynamic> fetchRequestUriPayload({
required String url,
required DioClient client,
}) async {
final log = getLogger('QRCodeScanCubit - fetchRequestUriPayload');
late final dynamic data;

try {
final dynamic response = await client.get(url);
data = response.toString();
} catch (e, s) {
log.e(
'An error occurred while connecting to the server.',
error: e,
stackTrace: s,
);
}
return data;
}
1 change: 1 addition & 0 deletions lib/dashboard/dashboard.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export 'discover/discover.dart';
export 'drawer/drawer.dart';
export 'general_information/general_information.dart';
export 'home/home.dart';
export 'json_viewer/json_viewer.dart';
export 'missing_creentials/missing_credentials.dart';
export 'mnemonic_verification/mnemonic_verification.dart';
export 'profile/profile.dart';
Expand Down
22 changes: 22 additions & 0 deletions lib/dashboard/drawer/src/view/drawer_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:altme/dashboard/dashboard.dart';
import 'package:altme/l10n/l10n.dart';
import 'package:altme/theme/theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class DrawerPage extends StatelessWidget {
const DrawerPage({super.key});
Expand Down Expand Up @@ -72,6 +73,27 @@ class DrawerView extends StatelessWidget {
Navigator.of(context).push<void>(SSIMenu.route());
},
),
const SizedBox(height: Sizes.spaceSmall),
DrawerCategoryItem(
title: l10n.developerMode,
subTitle: l10n.developerModeSubtitle,
trailing: SizedBox(
height: 25,
child: BlocBuilder<ProfileCubit, ProfileState>(
builder: (context, state) {
return Switch(
onChanged: (value) async {
await context
.read<ProfileCubit>()
.setDeveloperModeStatus(enabled: value);
},
value: state.model.isDeveloperMode,
activeColor: Theme.of(context).colorScheme.primary,
);
},
),
),
),
// const SizedBox(height: Sizes.spaceSmall),
// DrawerCategoryItem(
// title: l10n.checkLinkedinProfile,
Expand Down
13 changes: 8 additions & 5 deletions lib/dashboard/drawer/src/widgets/drawer_category_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ class DrawerCategoryItem extends StatelessWidget {
required this.title,
required this.subTitle,
this.onClick,
this.trailing,
});

final String title;
final String subTitle;
final VoidCallback? onClick;
final Widget? trailing;

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -49,15 +51,16 @@ class DrawerCategoryItem extends StatelessWidget {
],
),
),
Container(
width: Sizes.icon3x,
alignment: Alignment.center,
child: Icon(
if (trailing != null)
trailing!
else ...[
const SizedBox(width: 16),
Icon(
Icons.chevron_right,
size: Sizes.icon2x,
color: Theme.of(context).colorScheme.unSelectedLabel,
),
),
],
],
),
),
Expand Down
5 changes: 3 additions & 2 deletions lib/dashboard/drawer/src/widgets/drawer_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class DrawerItem extends StatelessWidget {
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
Expand All @@ -61,7 +62,7 @@ class DrawerItem extends StatelessWidget {
: null,
),
),
const SizedBox(height: 20),
const SizedBox(height: 10),
],
],
),
Expand All @@ -72,7 +73,7 @@ class DrawerItem extends StatelessWidget {
const SizedBox(width: 16),
Icon(
Icons.chevron_right,
size: 26,
size: Sizes.icon2x,
color: isDisabled
? Theme.of(context).colorScheme.lightGrey
: Theme.of(context).colorScheme.unSelectedLabel,
Expand Down
Loading

0 comments on commit a77027c

Please sign in to comment.