Skip to content

Commit

Permalink
Update for test 2 and test 10
Browse files Browse the repository at this point in the history
  • Loading branch information
bibash28 committed Sep 8, 2023
1 parent 3780e0f commit b9e867c
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 33 deletions.
2 changes: 1 addition & 1 deletion lib/app/shared/constants/parameters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Parameters {
);

static const oidc4vcUniversalLink =
'https://app.altme.io/app/download/oidc4vc/';
'https://app.altme.io/app/download/oidc4vc';

static const web3RpcMainnetUrl = 'https://mainnet.infura.io/v3/';

Expand Down
2 changes: 1 addition & 1 deletion lib/app/shared/enum/type/oidc4vc_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ enum OIDC4VCType {
EBSIV3(
issuerVcType: 'jwt_vc',
verifierVpType: 'jwt_vp',
offerPrefix: 'openid://initiate_issuance',
offerPrefix: 'openid-credential-offer://',
presentationPrefix: 'openid-vc://',
publicJWKNeeded: false,
),
Expand Down
45 changes: 40 additions & 5 deletions lib/app/shared/helper_functions/helper_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:altme/dashboard/home/home.dart';
import 'package:altme/oidc4vc/oidc4vc.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:convert/convert.dart';
import 'package:credential_manifest/credential_manifest.dart';
import 'package:crypto/crypto.dart';
import 'package:dartez/dartez.dart';
import 'package:device_info_plus/device_info_plus.dart';
Expand Down Expand Up @@ -463,12 +464,43 @@ bool isSIOPV2OROIDC4VPUrl(Uri uri) {
uri.toString().startsWith('openid-hedera://?'));
}

OIDC4VCType? getOIDC4VCTypeForIssuance(String url) {
Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({
required String url,
required DioClient client,
}) async {
for (final oidc4vcType in OIDC4VCType.values) {
if (oidc4vcType.isEnabled && url.startsWith(oidc4vcType.offerPrefix)) {
if (oidc4vcType == OIDC4VCType.DEFAULT &&
url.contains('api-conformance.ebsi.eu')) {
return OIDC4VCType.EBSIV3;
if (oidc4vcType == OIDC4VCType.DEFAULT ||
oidc4vcType == OIDC4VCType.EBSIV3) {
final dynamic credentialOfferJson = await getCredentialOfferJson(
scannedResponse: url,
dioClient: client,
);

final issuer = credentialOfferJson['credential_issuer'].toString();
if (credentialOfferJson == null) throw Exception();
final openidConfigurationResponse = await getOpenIdConfig(
baseUrl: issuer,
client: client.dio,
);

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

if (credentialsSupported.isEmpty) throw Exception();

final credSupported = credentialsSupported[0] as Map<String, dynamic>;

if (credSupported['trust_framework'] == null) {
return OIDC4VCType.DEFAULT;
}

if (credSupported['trust_framework']['name'] == 'ebsi') {
return OIDC4VCType.EBSIV3;
} else {
throw Exception();
}
}
return oidc4vcType;
}
Expand Down Expand Up @@ -498,7 +530,10 @@ Future<String> getHost({
required DioClient client,
}) async {
final OIDC4VCType? currentOIIDC4VCTypeForIssuance =
getOIDC4VCTypeForIssuance(uri.toString());
await getOIDC4VCTypeForIssuance(
url: uri.toString(),
client: client,
);

/// OIDC4VCI Case
if (currentOIIDC4VCTypeForIssuance != null) {
Expand Down
12 changes: 9 additions & 3 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 @@ -8,7 +8,6 @@ import 'package:altme/dashboard/dashboard.dart';
import 'package:altme/deep_link/deep_link.dart';
import 'package:altme/did/did.dart';
import 'package:altme/oidc4vc/oidc4vc.dart';
import 'package:altme/pin_code/pin_code.dart';
import 'package:altme/polygon_id/polygon_id.dart';
import 'package:altme/query_by_example/query_by_example.dart';
import 'package:altme/scan/scan.dart';
Expand Down Expand Up @@ -253,7 +252,10 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
try {
if (isOIDC4VCIUrl(state.uri!)) {
final OIDC4VCType? currentOIIDC4VCTypeForIssuance =
getOIDC4VCTypeForIssuance(state.uri.toString());
await getOIDC4VCTypeForIssuance(
url: state.uri.toString(),
client: dioClient,
);

if (currentOIIDC4VCTypeForIssuance != null) {
/// issuer side (oidc4VCI)
Expand Down Expand Up @@ -581,8 +583,12 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
}) async {
try {
emit(state.loading());

final OIDC4VCType? currentOIIDC4VCTypeForIssuance =
getOIDC4VCTypeForIssuance(credentialModel.pendingInfo!.url);
await getOIDC4VCTypeForIssuance(
url: credentialModel.pendingInfo!.url,
client: client,
);

if (currentOIIDC4VCTypeForIssuance != null) {
await getAndAddDefferedCredential(
Expand Down
6 changes: 5 additions & 1 deletion lib/oidc4vc/get_and_add_credential.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ Future<void> getAndAddCredential({

final codeForAuthorisedFlow =
Uri.parse(scannedResponse).queryParameters['code'];
final codeVerifier =
Uri.parse(scannedResponse).queryParameters['code_verifier'];

if (preAuthorizedCode != null || codeForAuthorisedFlow != null) {
if (preAuthorizedCode != null ||
(codeForAuthorisedFlow != null && codeVerifier != null)) {
/// codeForAuthorisedFlow != null
/// this is second phase flow for authorization_code
/// first phase is need for the authentication
Expand All @@ -60,6 +63,7 @@ Future<void> getAndAddCredential({
indexValue: oidc4vcType.indexValue,
userPin: userPin,
code: codeForAuthorisedFlow,
codeVerifier: codeVerifier,
);
final String credentialName = getCredentialData(credential);
final acceptanceToken = encodedCredentialOrFutureToken['acceptance_token'];
Expand Down
5 changes: 3 additions & 2 deletions lib/oidc4vc/get_authorization_uri_for_issuer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ Future<void> getAuthorizationUriForIssuer({
final Uri ebsiAuthenticationUri = await oidc4vc.getAuthorizationUriForIssuer(
selectedCredentials: selectedCredentials,
clientId: did,
redirectUrl: '${Parameters.oidc4vcUniversalLink}$scannedResponse',
webLink: Parameters.oidc4vcUniversalLink,
schema: scannedResponse,
issuer: issuer,
issuerState: issuerState,
nonce: nonce,
state: selectedCredentialsIndex.toString(),
options: selectedCredentialsIndex.toString(),
);
await LaunchUrl.launchUri(ebsiAuthenticationUri);
}
2 changes: 1 addition & 1 deletion lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Future<void> initiateOIDC4VCCredentialIssuance({
final codeForAuthorisedFlow =
Uri.parse(scannedResponse).queryParameters['code'];
final stateOfCredentialsSelected =
Uri.parse(scannedResponse).queryParameters['state'];
Uri.parse(scannedResponse).queryParameters['options'];

if (preAuthorizedCode != null) {
/// full phase flow of preAuthorized
Expand Down
5 changes: 4 additions & 1 deletion lib/splash/bloclisteners/blocklisteners.dart
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,10 @@ final qrCodeBlocListener = BlocListener<QRCodeScanCubit, QRCodeScanState>(
userConsentForVerifierAccess;

final OIDC4VCType? currentOIIDC4VCTypeForIssuance =
getOIDC4VCTypeForIssuance(state.uri.toString());
await getOIDC4VCTypeForIssuance(
url: state.uri.toString(),
client: DioClient('', Dio()),
);

final bool isOpenIDUrl = state.uri.toString().startsWith('openid');

Expand Down
14 changes: 11 additions & 3 deletions lib/splash/view/splash_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:altme/l10n/l10n.dart';
import 'package:altme/polygon_id/polygon_id.dart';
import 'package:altme/splash/splash.dart';
import 'package:altme/theme/app_theme/app_theme.dart';
import 'package:dio/dio.dart';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -91,14 +92,18 @@ class _SplashViewState extends State<SplashView> {
}

if (uri.toString().startsWith(Parameters.oidc4vcUniversalLink)) {
final url = uri.toString().split(Parameters.oidc4vcUniversalLink)[1];
final url =
uri.toString().split('${Parameters.oidc4vcUniversalLink}?uri=')[1];

final List<String> parts = url.split('?');

final String modifiedUrl = '${parts[0]}?${parts.sublist(1).join('&')}';

final OIDC4VCType? currentOIIDC4VCTypeForIssuance =
getOIDC4VCTypeForIssuance(modifiedUrl);
await getOIDC4VCTypeForIssuance(
url: modifiedUrl,
client: DioClient('', Dio()),
);

if (currentOIIDC4VCTypeForIssuance != null) {
/// issuer side (oidc4VCI)
Expand Down Expand Up @@ -170,7 +175,10 @@ class _SplashViewState extends State<SplashView> {
}
if (uri.scheme == 'openid' && uri.authority == 'initiate_issuance') {
final OIDC4VCType? currentOIIDC4VCTypeForIssuance =
getOIDC4VCTypeForIssuance(uri.toString());
await getOIDC4VCTypeForIssuance(
url: uri.toString(),
client: DioClient('', Dio()),
);

if (currentOIIDC4VCTypeForIssuance != null) {
// ignore: require_trailing_commas
Expand Down
43 changes: 28 additions & 15 deletions packages/oidc4vc/lib/src/oidc4vc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import 'package:oidc4vc/src/issuer_token_parameters.dart';
import 'package:oidc4vc/src/token_parameters.dart';
import 'package:oidc4vc/src/verification_type.dart';
import 'package:oidc4vc/src/verifier_token_parameters.dart';
import 'package:pkce/pkce.dart';
import 'package:secp256k1/secp256k1.dart';
import 'package:uuid/uuid.dart';

Expand All @@ -23,10 +24,7 @@ import 'package:uuid/uuid.dart';
/// {@endtemplate}
class OIDC4VC {
/// {@macro ebsi}
OIDC4VC({
required this.client,
required this.oidc4vcModel,
});
OIDC4VC({required this.client, required this.oidc4vcModel});

///
final Dio client;
Expand Down Expand Up @@ -93,11 +91,12 @@ class OIDC4VC {
Future<Uri> getAuthorizationUriForIssuer({
required List<dynamic> selectedCredentials,
required String clientId,
required String redirectUrl,
required String webLink,
required String schema,
required String issuer,
required String issuerState,
required String nonce,
String? state,
String? options,
}) async {
try {
final openidConfigurationResponse = await getOpenIdConfig(issuer);
Expand All @@ -107,13 +106,16 @@ class OIDC4VC {

final authorizationRequestParemeters = getAuthorizationRequestParemeters(
selectedCredentials: selectedCredentials,
authorizationEndpoint:
'https://app.altme.io/app/download/authorization',
openidConfigurationResponse: openidConfigurationResponse,
clientId: clientId,
redirectUrl: redirectUrl,
issuer: issuer,
schema: schema,
webLink: webLink,
issuerState: issuerState,
nonce: nonce,
state: state,
options: options,
);

final url = Uri.parse(authorizationEndpoint);
Expand All @@ -128,13 +130,15 @@ class OIDC4VC {
@visibleForTesting
Map<String, dynamic> getAuthorizationRequestParemeters({
required List<dynamic> selectedCredentials,
required String authorizationEndpoint,
required String clientId,
required String redirectUrl,
required String issuer,
required String issuerState,
required String nonce,
required Map<String, dynamic> openidConfigurationResponse,
String? state,
required String webLink,
required String schema,
String? options,
}) {
//https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#name-successful-authorization-re

Expand Down Expand Up @@ -182,19 +186,24 @@ class OIDC4VC {
authorizationDetails.add(data);
}

final pkcePair = PkcePair.generate();
final codeChallenge = pkcePair.codeChallenge;
final codeVerifier = pkcePair.codeVerifier;

final myRequest = <String, dynamic>{
'response_type': 'code',
'client_id': clientId,
'redirect_uri': redirectUrl,
'redirect_uri':
'$webLink?uri=$schema&code_verifier=$codeVerifier&options=$options',
'scope': 'openid',
'issuer_state': issuerState,
'state': state,
'state': const Uuid().v4(),
'nonce': nonce,
'code_challenge': 'lf3q5-NObcyp41iDSIL51qI7pBLmeYNeyWnNcY2FlW4',
'code_challenge': codeChallenge,
'code_challenge_method': 'S256',
'authorization_details': jsonEncode(authorizationDetails),
'client_metadata': jsonEncode({
'authorization_endpoint': 'openid:',
'authorization_endpoint': authorizationEndpoint,
'scopes_supported': ['openid'],
'response_types_supported': ['vp_token', 'id_token'],
'subject_types_supported': ['public'],
Expand Down Expand Up @@ -233,11 +242,13 @@ class OIDC4VC {
String? privateKey,
String? userPin,
String? code,
String? codeVerifier,
}) async {
final tokenData = buildTokenData(
preAuthorizedCode: preAuthorizedCode,
userPin: userPin,
code: code,
codeVerifier: codeVerifier,
);

final openidConfigurationResponse = await getOpenIdConfig(issuer);
Expand Down Expand Up @@ -324,6 +335,7 @@ class OIDC4VC {
String? preAuthorizedCode,
String? userPin,
String? code,
String? codeVerifier,
}) {
late Map<String, dynamic> tokenData;

Expand All @@ -332,10 +344,11 @@ class OIDC4VC {
'pre-authorized_code': preAuthorizedCode,
'grant_type': 'urn:ietf:params:oauth:grant-type:pre-authorized_code',
};
} else if (code != null) {
} else if (code != null && codeVerifier != null) {
tokenData = <String, dynamic>{
'code': code,
'grant_type': 'authorization_code',
'code_verifier': codeVerifier,
};
} else {
throw Exception();
Expand Down
1 change: 1 addition & 0 deletions packages/oidc4vc/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies:
http_mock_adapter: ^0.6.0
jose: ^0.3.3
json_path: ^0.4.4 #latest version creates test issue
pkce: ^1.1.0+1
secp256k1: ^0.3.0
tezart:
git:
Expand Down
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.3.4"
pkce:
dependency: transitive
description:
name: pkce
sha256: "5af8f4598aeaf033da4c87cb28bc9046262ddcbc0ba8d185d34d07e1aeb8c504"
url: "https://pub.dev"
source: hosted
version: "1.1.0+1"
platform:
dependency: transitive
description:
Expand Down

0 comments on commit b9e867c

Please sign in to comment.