Skip to content

Commit

Permalink
feat: OIDC4VCI screening developer option shown #1986
Browse files Browse the repository at this point in the history
  • Loading branch information
bibash28 committed Oct 18, 2023
1 parent 06673a7 commit 0803348
Show file tree
Hide file tree
Showing 11 changed files with 343 additions and 36 deletions.
97 changes: 84 additions & 13 deletions lib/app/shared/helper_functions/helper_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,14 @@ bool isSIOPV2OROIDC4VPUrl(Uri uri) {
return isOpenIdUrl || isAuthorizeEndPoint || isSiopv2Url;
}

Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({
Future<
(
OIDC4VCType?,
Map<String, dynamic>?,
Map<String, dynamic>?,
dynamic,
String?,
)> getIssuanceData({
required String url,
required DioClient client,
}) async {
Expand All @@ -509,12 +516,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,7 +537,7 @@ Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({
}

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

final openidConfigurationResponse = await getOpenIdConfig(
Expand All @@ -542,6 +550,7 @@ Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({

List<dynamic>? subjectSyntaxTypesSupported;
String? tokenEndpoint;
Map<String, dynamic>? authorizationServerConfiguration;

if (openidConfigurationResponse
.containsKey('subject_syntax_types_supported')) {
Expand All @@ -555,23 +564,23 @@ Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({
}

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

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 @@ -634,19 +643,51 @@ Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({
if (oidc4vcType == OIDC4VCType.DEFAULT ||
oidc4vcType == OIDC4VCType.EBSIV3) {
if (credSupported['trust_framework'] == null) {
return OIDC4VCType.DEFAULT;
return (
OIDC4VCType.DEFAULT,
openidConfigurationResponse,
authorizationServerConfiguration,
credentialOfferJson,
issuer
);
}

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

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

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

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

String getFormattedStringOIDC4VCI({
OIDC4VCType? oidc4vcType,
Map<String, dynamic>? openidConfigurationResponse,
Map<String, dynamic>? authorizationServerConfiguration,
dynamic credentialOfferJson,
}) {
return '''
SCHEME : ${oidc4vcType!.offerPrefix}
\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'}
''';
}
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
1 change: 1 addition & 0 deletions lib/dashboard/json_viewer/json_viewer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'view/json_viewer_page.dart';
59 changes: 59 additions & 0 deletions lib/dashboard/json_viewer/view/json_viewer_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'package:altme/app/app.dart';
import 'package:flutter/material.dart';

class JsonViewerPage extends StatelessWidget {
const JsonViewerPage({
super.key,
required this.title,
required this.data,
});

final String title;
final String data;

static Route<dynamic> route({
required String title,
required String data,
}) =>
MaterialPageRoute<void>(
builder: (_) => JsonViewerPage(
title: title,
data: data,
),
settings: const RouteSettings(name: '/JsonViewerPage'),
);

@override
Widget build(BuildContext context) {
return JsonViewerView(
title: title,
data: data,
);
}
}

class JsonViewerView extends StatelessWidget {
const JsonViewerView({
super.key,
required this.title,
required this.data,
});

final String title;
final String data;

@override
Widget build(BuildContext context) {
return BasePage(
title: title,
titleAlignment: Alignment.topCenter,
scrollView: true,
titleLeading: const BackLeadingButton(),
padding: const EdgeInsets.symmetric(horizontal: 10),
body: Text(
data,
style: Theme.of(context).textTheme.bodyMedium,
),
);
}
}
1 change: 1 addition & 0 deletions lib/dashboard/qr_code/qr_code.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export 'qr_code_scan/qr_code_scan.dart';
export 'qr_display/qr_display.dart';
export 'widget/widget.dart';
21 changes: 9 additions & 12 deletions lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -226,17 +226,14 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
late final dynamic data;

try {
if (isOIDC4VCIUrl(state.uri!)) {
if (isOIDC4VCIUrl(state.uri!) && oidcType != null) {
/// issuer side (oidc4VCI)
if (oidcType != null) {
await startOIDC4VCCredentialIssuance(
scannedResponse: state.uri.toString(),
isEBSIV3: oidcType == OIDC4VCType.EBSIV3,
qrCodeScanCubit: qrCodeScanCubit,
);
return;
}
await startOIDC4VCCredentialIssuance(
scannedResponse: state.uri.toString(),
isEBSIV3: oidcType == OIDC4VCType.EBSIV3,
qrCodeScanCubit: qrCodeScanCubit,
);
return;
}

if (isSIOPV2OROIDC4VPUrl(state.uri!)) {
Expand Down Expand Up @@ -749,8 +746,8 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
try {
emit(state.loading());

final OIDC4VCType? currentOIIDC4VCTypeForIssuance =
await getOIDC4VCTypeForIssuance(
final (OIDC4VCType? currentOIIDC4VCTypeForIssuance, _, _, _, _) =
await getIssuanceData(
url: credentialModel.pendingInfo!.url,
client: client,
);
Expand Down
76 changes: 76 additions & 0 deletions lib/dashboard/qr_code/widget/developer_mode_dialog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import 'package:altme/app/app.dart';
import 'package:altme/l10n/l10n.dart';
import 'package:altme/theme/theme.dart';
import 'package:flutter/material.dart';

class DeveloperModeDialog extends StatelessWidget {
const DeveloperModeDialog({
super.key,
required this.onDisplay,
required this.onDownload,
required this.onSkip,
});

final VoidCallback onDisplay;
final VoidCallback onDownload;
final VoidCallback onSkip;

@override
Widget build(BuildContext context) {
final color = Theme.of(context).colorScheme.primary;
final background = Theme.of(context).colorScheme.popupBackground;
final textColor = Theme.of(context).colorScheme.dialogText;

final l10n = context.l10n;
return AlertDialog(
backgroundColor: background,
surfaceTintColor: Colors.transparent,
contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(25)),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Image.asset(
IconStrings.cardReceive,
width: 50,
height: 50,
color: textColor,
),
const SizedBox(height: 15),
MyElevatedButton(
text: l10n.displayConfiguration,
verticalSpacing: 14,
backgroundColor: color,
borderRadius: Sizes.smallRadius,
fontSize: 15,
elevation: 0,
onPressed: onDisplay,
),
const SizedBox(height: Sizes.spaceSmall),
MyElevatedButton(
text: l10n.downloadConfiguration,
verticalSpacing: 14,
backgroundColor: color,
borderRadius: Sizes.smallRadius,
fontSize: 15,
elevation: 0,
onPressed: onDownload,
),
const SizedBox(height: Sizes.spaceSmall),
MyElevatedButton(
text: l10n.skip,
verticalSpacing: 14,
backgroundColor: color,
borderRadius: Sizes.smallRadius,
fontSize: 15,
elevation: 0,
onPressed: onSkip,
),
const SizedBox(height: 15),
],
),
);
}
}
1 change: 1 addition & 0 deletions lib/dashboard/qr_code/widget/widget.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'developer_mode_dialog.dart';
6 changes: 4 additions & 2 deletions lib/l10n/arb/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,9 @@
"type": "Type",
"credentialExpired": "Credential Expired",
"incorrectSignature": "Incorrect Signature",
"revokedOrSuspendedCredential": "Revoked or Suspended Credential"

"revokedOrSuspendedCredential": "Revoked or Suspended Credential",
"displayConfiguration": "Display configuration",
"downloadConfiguration": "Download configuration",
"successfullyDownloaded": "Successfully Downloaded"
}

Loading

0 comments on commit 0803348

Please sign in to comment.