Skip to content

Commit

Permalink
feat: Add deferred credential
Browse files Browse the repository at this point in the history
  • Loading branch information
bibash28 committed Sep 1, 2023
1 parent 1bde696 commit 26b821f
Show file tree
Hide file tree
Showing 29 changed files with 439 additions and 133 deletions.
2 changes: 1 addition & 1 deletion ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum NetworkError {
NETWORK_ERROR_REQUEST_TIMEOUT,
NETWORK_ERROR_NO_INTERNET_CONNECTION,
NETWORK_ERROR_CONFLICT,
NETWORK_ERROR_NOT_READY,
NETWORK_ERROR_PRECONDITION_FAILED,
NETWORK_ERROR_SEND_TIMEOUT,
NETWORK_ERROR_UNABLE_TO_PROCESS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ extension NetworkErrorX on NetworkError {
return globalMessage.NETWORK_ERROR_NOT_FOUND;
case NetworkError.NETWORK_ERROR_PRECONDITION_FAILED:
return globalMessage.NETWORK_ERROR_PRECONDITION_FAILED;
case NetworkError.NETWORK_ERROR_NOT_READY:
return globalMessage.NETWORK_ERROR_NOT_READY;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,6 @@ enum ResponseString {
RESPONSE_STRING_pleaseSwitchToRightOIDC4VCProfile,
RESPONSE_STRING_authenticationSuccess,
RESPONSE_STRING_youcanSelectOnlyXCredential,
RESPONSE_STRING_theCredentialIsNotReady,
RESPONSE_STRING_theCredentialIsNoMoreReady,
}
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,12 @@ extension ResponseStringX on ResponseString {
return globalMessage.RESPONSE_STRING_youcanSelectOnlyXCredential(
injectedMessage ?? '',
);

case ResponseString.RESPONSE_STRING_theCredentialIsNotReady:
return globalMessage.RESPONSE_STRING_theCredentialIsNotReady;

case ResponseString.RESPONSE_STRING_theCredentialIsNoMoreReady:
return globalMessage.RESPONSE_STRING_theCredentialIsNoMoreReady;
}
}
}
39 changes: 39 additions & 0 deletions lib/app/shared/helper_functions/helper_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -548,3 +548,42 @@ Future<String> getHost({
}
}
}

Future<(String?, String)> getIssuerAndPreAuthorizedCode({
required OIDC4VCType oidc4vcType,
required String scannedResponse,
required DioClient dioClient,
}) async {
String? preAuthorizedCode;
late String issuer;

final Uri uriFromScannedResponse = Uri.parse(scannedResponse);

switch (oidc4vcType) {
case OIDC4VCType.DEFAULT:
case OIDC4VCType.HEDERA:
case OIDC4VCType.EBSIV3:
final dynamic credentialOfferJson = await getCredentialOfferJson(
scannedResponse: scannedResponse,
dioClient: dioClient,
);
if (credentialOfferJson == null) throw Exception();

preAuthorizedCode = credentialOfferJson['grants']
['urn:ietf:params:oauth:grant-type:pre-authorized_code']
['pre-authorized_code']
.toString();
issuer = credentialOfferJson['credential_issuer'].toString();

case OIDC4VCType.GAIAX:
case OIDC4VCType.EBSIV2:
issuer = uriFromScannedResponse.queryParameters['issuer'].toString();
preAuthorizedCode =
uriFromScannedResponse.queryParameters['pre-authorized_code'];

case OIDC4VCType.JWTVC:
throw Exception();
}

return (preAuthorizedCode, issuer);
}
6 changes: 6 additions & 0 deletions lib/app/shared/message_handler/global_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ class GlobalMessage {

String get NETWORK_ERROR_NOT_FOUND => l10n.networkErrorNotFound;

String get NETWORK_ERROR_NOT_READY => '';

String get RESPONSE_STRING_FAILED_TO_LOAD_PROFILE => l10n.failedToLoadProfile;

String get RESPONSE_STRING_FAILED_TO_DO_OPERATION => l10n.failedToDoOperation;
Expand Down Expand Up @@ -379,4 +381,8 @@ class GlobalMessage {

String RESPONSE_STRING_youcanSelectOnlyXCredential(String value) =>
l10n.youcanSelectOnlyXCredential(value);
String get RESPONSE_STRING_theCredentialIsNotReady =>
l10n.theCredentialIsNotReady;
String get RESPONSE_STRING_theCredentialIsNoMoreReady =>
l10n.theCredentialIsNoMoreReady;
}
7 changes: 7 additions & 0 deletions lib/app/shared/message_handler/network_exception.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ class NetworkException with MessageHandler {
message: NetworkError.NETWORK_ERROR_CONFLICT,
data: error?.response?.data,
);
case 410:
return NetworkException(
message: NetworkError.NETWORK_ERROR_NOT_READY,
data: error?.response?.data,
);
case 412:
return NetworkException(
message: NetworkError.NETWORK_ERROR_PRECONDITION_FAILED,
Expand Down Expand Up @@ -205,6 +210,8 @@ class NetworkException with MessageHandler {
case NetworkError.NETWORK_ERROR_PRECONDITION_FAILED:
return NetworkError.NETWORK_ERROR_PRECONDITION_FAILED
.localise(context);
case NetworkError.NETWORK_ERROR_NOT_READY:
return NetworkError.NETWORK_ERROR_NOT_READY.localise(context);
}
}
return '';
Expand Down
12 changes: 12 additions & 0 deletions lib/app/shared/message_handler/response_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,18 @@ class ResponseMessage with MessageHandler {
context,
injectedMessage: injectedMessage,
);

case ResponseString.RESPONSE_STRING_theCredentialIsNotReady:
return ResponseString.RESPONSE_STRING_theCredentialIsNotReady
.localise(
context,
);

case ResponseString.RESPONSE_STRING_theCredentialIsNoMoreReady:
return ResponseString.RESPONSE_STRING_theCredentialIsNoMoreReady
.localise(
context,
);
}
}
return '';
Expand Down
10 changes: 5 additions & 5 deletions lib/credentials/cubit/credentials_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,13 @@ class CredentialsCubit extends Cubit<CredentialsState> {
}

Future<void> deleteById({
required CredentialModel credential,
required String id,
bool showMessage = true,
}) async {
emit(state.loading());
await credentialsRepository.deleteById(credential.id);
await credentialsRepository.deleteById(id);
final credentials = List.of(state.credentials)
..removeWhere((element) => element.id == credential.id);
..removeWhere((element) => element.id == id);
final dummies = _getAvalaibleDummyCredentials(credentials);
emit(
state.copyWith(
Expand Down Expand Up @@ -335,7 +335,7 @@ class CredentialsCubit extends Cubit<CredentialsState> {
if (email ==
(iteratedCredentialSubjectModel as EmailPassModel).email) {
await deleteById(
credential: storedCredential,
id: storedCredential.id,
showMessage: false,
);
break;
Expand Down Expand Up @@ -363,7 +363,7 @@ class CredentialsCubit extends Cubit<CredentialsState> {
storedCredential.credentialPreview.credentialSubjectModel;
if (credentialSubjectModel.credentialSubjectType == card) {
await deleteById(
credential: storedCredential,
id: storedCredential.id,
showMessage: false,
);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ class CredentialDetailsCubit extends Cubit<CredentialDetailsState> {
}

Future<void> verifyProofOfPurpose(CredentialModel item) async {
if (item.data.isEmpty) {
return emit(
state.copyWith(
credentialStatus: CredentialStatus.pending,
status: AppStatus.idle,
),
);
}
final vcStr = jsonEncode(item.data);
final optStr = jsonEncode({'proofPurpose': 'assertionMethod'});
final result = await didKitProvider.verifyCredential(vcStr, optStr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class _CredentialsDetailsViewState extends State<CredentialsDetailsView> {

if (confirm) {
final credentialsCubit = context.read<CredentialsCubit>();
await credentialsCubit.deleteById(credential: widget.credentialModel);
await credentialsCubit.deleteById(id: widget.credentialModel.id);
}
}

Expand Down Expand Up @@ -258,18 +258,20 @@ class _CredentialsDetailsViewState extends State<CredentialsDetailsView> {
credentialModel: widget.credentialModel,
),
],
CredentialField(
padding: const EdgeInsets.symmetric(
horizontal: 0,
vertical: 8,
if (widget.credentialModel.pendingInfo == null) ...[
CredentialField(
padding: const EdgeInsets.symmetric(
horizontal: 0,
vertical: 8,
),
title: l10n.format,
value: format,
titleColor:
Theme.of(context).colorScheme.titleColor,
valueColor:
Theme.of(context).colorScheme.valueColor,
),
title: l10n.format,
value: format,
titleColor:
Theme.of(context).colorScheme.titleColor,
valueColor:
Theme.of(context).colorScheme.valueColor,
),
],
],
if (state.credentialDetailTabStatus ==
CredentialDetailTabStatus.activity) ...[
Expand Down Expand Up @@ -309,48 +311,65 @@ class _CredentialsDetailsViewState extends State<CredentialsDetailsView> {
text: l10n.credentialDetailDeleteCard,
),
const SizedBox(height: 8),
MyOutlinedButton(
text: widget.credentialModel.isLinkeInCard
? l10n.exportToLinkedIn
: l10n.share,
onPressed: () {
if (widget.credentialModel.isLinkeInCard) {
Navigator.of(context).push<void>(
GetLinkedinInfoPage.route(
credentialModel: widget.credentialModel,
),
);
} else {
if (widget.credentialModel.isEbsiCard) {
/// removing type that was added in add_ebsi_credential.dart
widget.credentialModel.data['credentialSubject']
.remove('type');
}

late String data;
final String? jwt = widget.credentialModel.jwt;
if (jwt != null) {
data = jwt;
if (widget.credentialModel.pendingInfo == null) ...[
MyOutlinedButton(
text: widget.credentialModel.isLinkeInCard
? l10n.exportToLinkedIn
: l10n.share,
onPressed: () {
if (widget.credentialModel.isLinkeInCard) {
Navigator.of(context).push<void>(
GetLinkedinInfoPage.route(
credentialModel: widget.credentialModel,
),
);
} else {
data = jsonEncode(widget.credentialModel.data);
}
if (widget.credentialModel.isEbsiCard) {
/// removing type that was added in add_ebsi_credential.dart
widget
.credentialModel.data['credentialSubject']
.remove('type');
}

getLogger('CredentialDetailsPage - shared date')
.i(data);
late String data;
final String? jwt = widget.credentialModel.jwt;
if (jwt != null) {
data = jwt;
} else {
data =
jsonEncode(widget.credentialModel.data);
}

final box =
context.findRenderObject() as RenderBox?;
final subject = l10n.shareWith;
getLogger('CredentialDetailsPage - shared date')
.i(data);

Share.share(
data,
subject: subject,
sharePositionOrigin:
box!.localToGlobal(Offset.zero) & box.size,
);
}
},
),
final box =
context.findRenderObject() as RenderBox?;
final subject = l10n.shareWith;

Share.share(
data,
subject: subject,
sharePositionOrigin:
box!.localToGlobal(Offset.zero) &
box.size,
);
}
},
),
] else ...[
MyOutlinedButton(
text: l10n.getItNow,
onPressed: () {
Navigator.of(context).pop();
context
.read<QRCodeScanCubit>()
.startOIDC4VCDeferedCredentialIssuance(
credentialModel: widget.credentialModel,
);
},
),
],
if (widget.credentialModel.shareLink != '')
MyOutlinedButton.icon(
icon: SvgPicture.asset(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ class Credential {
[
Proof.dummy(),
],
DefaultCredentialSubjectModel('dummy', 'dummy', const Author('')),
DefaultCredentialSubjectModel(
id: 'dummy7',
type: 'dummy8',
issuedBy: const Author(''),
),
[Translation('en', '')],
[Translation('en', '')],
CredentialStatusField.emptyCredentialStatusField(),
Expand Down
Loading

0 comments on commit 26b821f

Please sign in to comment.