Skip to content

Commit

Permalink
feat: oidc4vc model and switch management #1744
Browse files Browse the repository at this point in the history
  • Loading branch information
bibash28 committed Jul 28, 2023
1 parent 7b7dc05 commit 8c45a0c
Show file tree
Hide file tree
Showing 18 changed files with 878 additions and 798 deletions.
31 changes: 29 additions & 2 deletions lib/app/shared/enum/type/oidc4vc_type.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
enum OIDC4VCTye {
import 'package:dio/dio.dart';
import 'package:oidc4vc/oidc4vc.dart';

enum OIDC4VCType {
EBSIV2(
issuerVcType: 'jwt_vc',
verifierVpType: 'jwt_vp',
Expand Down Expand Up @@ -151,7 +154,7 @@ enum OIDC4VCTye {
serviceDocumentation: '',
);

const OIDC4VCTye({
const OIDC4VCType({
required this.issuerVcType,
required this.verifierVpType,
required this.offerPrefix,
Expand Down Expand Up @@ -181,3 +184,27 @@ enum OIDC4VCTye {
final String siopv2Draft;
final String serviceDocumentation;
}

extension OIDC4VCTypeX on OIDC4VCType {
OIDC4VC get getOIDC4VC {
return OIDC4VC(
client: Dio(),
oidc4vcModel: OIDC4VCModel(
issuerVcType: issuerVcType,
verifierVpType: verifierVpType,
offerPrefix: offerPrefix,
presentationPrefix: presentationPrefix,
cryptographicBindingMethodsSupported:
cryptographicBindingMethodsSupported,
cryptographicSuitesSupported: cryptographicSuitesSupported,
subjectSyntaxTypesSupported: subjectSyntaxTypesSupported,
grantTypesSupported: grantTypesSupported,
credentialSupported: credentialSupported,
schemaForType: schemaForType,
oidc4VciDraft: oidc4VciDraft,
siopv2Draft: siopv2Draft,
serviceDocumentation: serviceDocumentation,
),
);
}
}
3 changes: 1 addition & 2 deletions lib/app/view/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'package:key_generator/key_generator.dart';
import 'package:oidc4vc/oidc4vc.dart';
import 'package:polygonid/polygonid.dart';
import 'package:secure_storage/secure_storage.dart' as secure_storage;
import 'package:secure_storage/secure_storage.dart';
Expand Down Expand Up @@ -144,7 +143,7 @@ class App extends StatelessWidget {
credentialsCubit: context.read<CredentialsCubit>(),
didKitProvider: DIDKitProvider(),
secureStorageProvider: secure_storage.getSecureStorage,
oidc4vc: OIDC4VC(Dio()),
profileCubit: context.read<ProfileCubit>(),
),
),
BlocProvider<QRCodeScanCubit>(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import 'package:altme/app/app.dart';
import 'package:altme/dashboard/dashboard.dart';
import 'package:altme/l10n/l10n.dart';
import 'package:altme/theme/theme.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:oidc4vc/oidc4vc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:secure_storage/secure_storage.dart';

class DidEbsiPrivateKeyPage extends StatefulWidget {
Expand All @@ -27,7 +27,8 @@ class _DidEbsiPrivateKeyPageState extends State<DidEbsiPrivateKeyPage>
late AnimationController animationController;

Future<String> getPrivateKey() async {
final oidc4vc = OIDC4VC(Dio());
final oidc4vc =
context.read<ProfileCubit>().state.model.oidc4vcType.getOIDC4VC;
final mnemonic = await getSecureStorage.get(SecureStorageKeys.ssiMnemonic);
final privateKey =
await oidc4vc.privateKeyFromMnemonic(mnemonic: mnemonic!);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import 'package:altme/app/app.dart';
import 'package:altme/dashboard/drawer/drawer.dart';
import 'package:altme/dashboard/dashboard.dart';
import 'package:altme/l10n/l10n.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:oidc4vc/oidc4vc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:secure_storage/secure_storage.dart';

class ManageDidEbsiPage extends StatelessWidget {
class ManageDidEbsiPage extends StatefulWidget {
const ManageDidEbsiPage({super.key});

static Route<dynamic> route() {
Expand All @@ -16,8 +15,14 @@ class ManageDidEbsiPage extends StatelessWidget {
);
}

@override
State<ManageDidEbsiPage> createState() => _ManageDidEbsiPageState();
}

class _ManageDidEbsiPageState extends State<ManageDidEbsiPage> {
Future<String> getDid() async {
final oidc4vc = OIDC4VC(Dio());
final oidc4vc =
context.read<ProfileCubit>().state.model.oidc4vcType.getOIDC4VC;
final mnemonic = await getSecureStorage.get(SecureStorageKeys.ssiMnemonic);
final privateKey =
await oidc4vc.privateKeyFromMnemonic(mnemonic: mnemonic!);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class OIDC4VCProfilePage extends StatelessWidget {
),
),
child: ListView.builder(
itemCount: OIDC4VCTye.values.length,
itemCount: OIDC4VCType.values.length,
shrinkWrap: true,
physics: const ScrollPhysics(),
itemBuilder: (context, index) {
Expand All @@ -51,28 +51,29 @@ class OIDC4VCProfilePage extends StatelessWidget {
onTap: () {
context
.read<ProfileCubit>()
.updateOIDC4VCType(OIDC4VCTye.values[index]);
.updateOIDC4VCType(OIDC4VCType.values[index]);
},
shape: const RoundedRectangleBorder(
side: BorderSide(
color: Color(0xFFDDDDEE), width: 0.5),
color: Color(0xFFDDDDEE),
width: 0.5,
),
),
title: Text(
OIDC4VCTye.values[index].name,
OIDC4VCType.values[index].name,
style: Theme.of(context)
.listTileTheme
.titleTextStyle
?.copyWith(color: const Color(0xFF080F33)),
),
trailing: Icon(
state.model.oidc4vcType ==
OIDC4VCTye.values[index].toString()
state.model.oidc4vcType == OIDC4VCType.values[index]
? Icons.radio_button_checked
: Icons.radio_button_unchecked,
size: Sizes.icon2x,
),
),
if (index < OIDC4VCTye.values.length - 1)
if (index < OIDC4VCType.values.length - 1)
Padding(
padding: const EdgeInsets.symmetric(
horizontal: Sizes.spaceSmall,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ class CredentialDetailsCubit extends Cubit<CredentialDetailsState> {
required this.secureStorageProvider,
required this.client,
required this.jwtDecode,
required this.polygonId,
required this.profileCubit,
required this.polygonIdCubit,
}) : super(const CredentialDetailsState());

final DIDKitProvider didKitProvider;
final SecureStorageProvider secureStorageProvider;
final DioClient client;
final JWTDecode jwtDecode;
final PolygonId polygonId;
final ProfileCubit profileCubit;
final PolygonIdCubit polygonIdCubit;

void changeTabStatus(CredentialDetailTabStatus credentialDetailTabStatus) {
Expand Down Expand Up @@ -70,6 +70,7 @@ class CredentialDetailsCubit extends Cubit<CredentialDetailsState> {
issuerDid,
issuerKid,
item.jwt!,
profileCubit,
);

late CredentialStatus credentialStatus;
Expand Down Expand Up @@ -103,7 +104,8 @@ class CredentialDetailsCubit extends Cubit<CredentialDetailsState> {
network = Parameters.POLYGON_TEST_NETWORK;
}

final List<ClaimEntity> claim = await polygonId.getClaimById(
final List<ClaimEntity> claim =
await polygonIdCubit.polygonId.getClaimById(
claimId: item.id,
mnemonic: mnemonic!,
network: network,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'package:polygonid/polygonid.dart';
import 'package:secure_storage/secure_storage.dart';
import 'package:share_plus/share_plus.dart';

Expand Down Expand Up @@ -55,7 +54,7 @@ class CredentialsDetailsPage extends StatelessWidget {
secureStorageProvider: getSecureStorage,
client: DioClient('', Dio()),
jwtDecode: JWTDecode(),
polygonId: PolygonId(),
profileCubit: context.read<ProfileCubit>(),
polygonIdCubit: context.read<PolygonIdCubit>(),
),
),
Expand Down
23 changes: 15 additions & 8 deletions lib/dashboard/profile/cubit/profile_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,18 @@ class ProfileCubit extends Cubit<ProfileState> {
(await secureStorageProvider.get(SecureStorageKeys.alertEnabled)) ==
'true';

final oidc4vcType =
(await secureStorageProvider.get(SecureStorageKeys.oidc4vcType)) ??
OIDC4VCTye.EBSIV2.toString();
var oidc4vcType = OIDC4VCType.EBSIV2;

for (final type in OIDC4VCType.values) {
final oidc4vcTypeName =
await secureStorageProvider.get(SecureStorageKeys.oidc4vcType);

if (oidc4vcTypeName != null) {
if (type.name == oidc4vcTypeName) {
oidc4vcType = type;
}
}
}

final profileModel = ProfileModel(
firstName: firstName,
Expand Down Expand Up @@ -192,7 +201,7 @@ class ProfileCubit extends Cubit<ProfileState> {

await secureStorageProvider.set(
SecureStorageKeys.oidc4vcType,
profileModel.oidc4vcType,
profileModel.oidc4vcType.name,
);

emit(
Expand Down Expand Up @@ -237,11 +246,9 @@ class ProfileCubit extends Cubit<ProfileState> {
await update(profileModel);
}

Future<void> updateOIDC4VCType(OIDC4VCTye oidc4vcTye) async {
Future<void> updateOIDC4VCType(OIDC4VCType oidc4vcTye) async {
emit(state.copyWith(status: AppStatus.loading));
final profileModel =
state.model.copyWith(oidc4vcType: oidc4vcTye.toString());

final profileModel = state.model.copyWith(oidc4vcType: oidc4vcTye);
await update(profileModel);
}

Expand Down
6 changes: 3 additions & 3 deletions lib/dashboard/profile/models/profile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class ProfileModel extends Equatable {
isBiometricEnabled: false,
isAlertEnabled: false,
tezosNetwork: TezosNetwork.mainNet(),
oidc4vcType: OIDC4VCTye.EBSIV2.toString(),
oidc4vcType: OIDC4VCType.EBSIV2,
);

final String firstName;
Expand All @@ -56,7 +56,7 @@ class ProfileModel extends Equatable {
final bool isEnterprise;
final bool isBiometricEnabled;
final bool isAlertEnabled;
final String oidc4vcType;
final OIDC4VCType oidc4vcType;

@override
List<Object> get props => [
Expand Down Expand Up @@ -92,7 +92,7 @@ class ProfileModel extends Equatable {
bool? isEnterprise,
bool? isBiometricEnabled,
bool? isAlertEnabled,
String? oidc4vcType,
OIDC4VCType? oidc4vcType,
}) {
return ProfileModel(
firstName: firstName ?? this.firstName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
issuerDid,
issuerKid,
encodedData.toString(),
profileCubit,
);

if (isVerified == VerificationType.verified) {
Expand All @@ -326,8 +327,8 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
state.uri.toString().startsWith('openid-initiate_issuance://')) {
await initiateEbsiCredentialIssuance(
state.uri.toString(),
client,
credentialsCubit,
profileCubit,
getSecureStorage,
);

Expand Down
7 changes: 4 additions & 3 deletions lib/ebsi/initiate_ebsi_credential_issuance.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import 'package:altme/app/app.dart';
import 'package:altme/credentials/credentials.dart';
import 'package:altme/dashboard/dashboard.dart';
import 'package:altme/ebsi/add_ebsi_credential.dart';
import 'package:dio/dio.dart';
import 'package:oidc4vc/oidc4vc.dart';
import 'package:secure_storage/secure_storage.dart';

Future<void> initiateEbsiCredentialIssuance(
String scannedResponse,
DioClient client,
CredentialsCubit credentialsCubit,
ProfileCubit profileCubit,
SecureStorageProvider secureStorage,
) async {
final OIDC4VC oidc4vc = OIDC4VC(Dio());
final OIDC4VC oidc4vc = profileCubit.state.model.oidc4vcType.getOIDC4VC;

final Uri uriFromScannedResponse = Uri.parse(scannedResponse);
if (uriFromScannedResponse.queryParameters['pre-authorized_code'] != null) {
final mnemonic = await getSecureStorage.get(SecureStorageKeys.ssiMnemonic);
Expand Down
6 changes: 4 additions & 2 deletions lib/ebsi/verify_encoded_data.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import 'package:dio/dio.dart';
import 'package:altme/app/app.dart';
import 'package:altme/dashboard/dashboard.dart';
import 'package:oidc4vc/oidc4vc.dart';

Future<VerificationType> verifyEncodedData(
String issuerDid,
String issuerKid,
String jwt,
ProfileCubit profileCubit,
) async {
final OIDC4VC oidc4vc = OIDC4VC(Dio());
final OIDC4VC oidc4vc = profileCubit.state.model.oidc4vcType.getOIDC4VC;

final VerificationType verificationType = await oidc4vc.verifyEncodedData(
issuerDid: issuerDid,
Expand Down
6 changes: 3 additions & 3 deletions lib/scan/cubit/scan_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ class ScanCubit extends Cubit<ScanState> {
required this.credentialsCubit,
required this.didKitProvider,
required this.secureStorageProvider,
required this.oidc4vc,
required this.profileCubit,
}) : super(const ScanState());

final DioClient client;
final CredentialsCubit credentialsCubit;
final DIDKitProvider didKitProvider;
final SecureStorageProvider secureStorageProvider;
final OIDC4VC oidc4vc;
final ProfileCubit profileCubit;

Future<void> credentialOffer({
required Uri uri,
Expand All @@ -59,7 +59,7 @@ class ScanCubit extends Cubit<ScanState> {
try {
if (uri.queryParameters['scope'] == 'openid' ||
uri.toString().startsWith('openid://?client_id')) {
final oidc4vc = OIDC4VC(Dio());
final OIDC4VC oidc4vc = profileCubit.state.model.oidc4vcType.getOIDC4VC;
final mnemonic =
await getSecureStorage.get(SecureStorageKeys.ssiMnemonic);
final privateKey =
Expand Down
4 changes: 1 addition & 3 deletions lib/splash/view/splash_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ 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';
import 'package:flutter/services.dart' as services;
Expand Down Expand Up @@ -147,11 +146,10 @@ class _SplashViewState extends State<SplashView> {
beaconData = value;
}
if (uri.scheme == 'openid' && uri.authority == 'initiate_issuance') {
final DioClient client = DioClient('', Dio());
await initiateEbsiCredentialIssuance(
uri.toString(),
client,
context.read<CredentialsCubit>(),
context.read<ProfileCubit>(),
secure_storage.getSecureStorage,
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/oidc4vc/lib/oidc4vc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/// EBSI wallet compliance
library ebsi;

export 'src/iodc4vc_model.dart';
export 'src/issuer_token_parameters.dart';
export 'src/oidc4vc.dart';
export 'src/token_parameters.dart';
Expand Down
Loading

0 comments on commit 8c45a0c

Please sign in to comment.