Skip to content

Commit

Permalink
Document Validation flow (#72)
Browse files Browse the repository at this point in the history
* Prepare DocumentValidationStrip

* Update change log + version

* pub upgrade

* Prepare separate DocumentValidationFragment

* Made response nullable

* Update value getter

* pub upgrade

* Impl. also case for not signed document

* Update impl. to work with latest API client

* Update UI to display signatures

* Impl. custom AVM Chip widget

* Simplify code to use type alias

* Update AGP for latest Android Studio support

* Update existing code

* Update paddings

* Extract PreviewDocumentFragment

* Screen uses two separate fragments with its onw lifecycle

* Include new feature in main screen body

* Impl strip hiding on tap

* Update DocumentValidationInfo label

* Update padding

* Using AVM modal bottom sheet for list

* Prepare CertificateDetails

* Displaying only certificate CN in labels

* Rename one widget

* Extract strings

* Cleanup ctor

* Update change log

* Tune Chip UX

* Tune validation info strip UI

* Explicitly specify compatible NDK version

* Setup ProGuard to fix Android build

* Cherry pick e6e69ce

Fix infinite loading state for remote signing

* Cleanup

---------

Co-authored-by: mkepes <[email protected]>
  • Loading branch information
Matej-Hlatky and matejkepes authored Nov 18, 2024
1 parent e8b3fef commit dba8431
Show file tree
Hide file tree
Showing 33 changed files with 1,507 additions and 284 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## NEXT - 1.1.0(36)

- Update AGP and Gradle version for latest Android Studio Ladybug (2024.2.1 Patch 1)
- #35 | Android - opening only specific file types
- #39 | When sharing document, set file name
- #36 | Implement first version of Document validation

## 2024-07-16 - v1.0.4(35)

- #32 | Cleanup
Expand Down
14 changes: 5 additions & 9 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ android {
ndkVersion flutter.ndkVersion

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = '1.8'
jvmTarget = '17'
}

sourceSets {
Expand Down Expand Up @@ -72,25 +72,21 @@ android {
buildTypes {
release {
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}

debug {
// no signing config for debug builds
}
}
ndkVersion "25.1.8937393"
}

repositories {
google()
mavenCentral()
maven {
// Local distribution
url = uri("../../../eidmsdk_flutter/android/libs")
}
}

flutter {
source '../..'
}

dependencies {}
38 changes: 38 additions & 0 deletions android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
-dontwarn com.google.android.play.core.splitcompat.SplitCompatApplication
-dontwarn com.google.android.play.core.splitinstall.SplitInstallException
-dontwarn com.google.android.play.core.splitinstall.SplitInstallManager
-dontwarn com.google.android.play.core.splitinstall.SplitInstallManagerFactory
-dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest$Builder
-dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest
-dontwarn com.google.android.play.core.splitinstall.SplitInstallSessionState
-dontwarn com.google.android.play.core.splitinstall.SplitInstallStateUpdatedListener
-dontwarn com.google.android.play.core.tasks.OnFailureListener
-dontwarn com.google.android.play.core.tasks.OnSuccessListener
-dontwarn com.google.android.play.core.tasks.Task
-dontwarn com.google.api.client.http.GenericUrl
-dontwarn com.google.api.client.http.HttpHeaders
-dontwarn com.google.api.client.http.HttpRequest
-dontwarn com.google.api.client.http.HttpRequestFactory
-dontwarn com.google.api.client.http.HttpResponse
-dontwarn com.google.api.client.http.HttpTransport
-dontwarn com.google.api.client.http.javanet.NetHttpTransport$Builder
-dontwarn com.google.api.client.http.javanet.NetHttpTransport
-dontwarn javax.naming.Binding
-dontwarn javax.naming.NamingEnumeration
-dontwarn javax.naming.NamingException
-dontwarn javax.naming.directory.Attribute
-dontwarn javax.naming.directory.Attributes
-dontwarn javax.naming.directory.DirContext
-dontwarn javax.naming.directory.InitialDirContext
-dontwarn javax.naming.directory.SearchControls
-dontwarn javax.naming.directory.SearchResult
-dontwarn org.bouncycastle.jsse.BCSSLParameters
-dontwarn org.bouncycastle.jsse.BCSSLSocket
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
-dontwarn org.conscrypt.Conscrypt$Version
-dontwarn org.conscrypt.Conscrypt
-dontwarn org.conscrypt.ConscryptHostnameVerifier
-dontwarn org.joda.time.Instant
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
2 changes: 1 addition & 1 deletion android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pluginManagement {

plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.4.2" apply false
id "com.android.application" version "8.3.2" apply false
// START: FlutterFire Configuration
id "com.google.gms.google-services" version "4.3.15" apply false
id "com.google.firebase.crashlytics" version "2.8.1" apply false
Expand Down
53 changes: 53 additions & 0 deletions lib/bloc/document_validation_cubit.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import 'dart:async';

import 'package:autogram_sign/autogram_sign.dart';
import 'package:flutter_bloc/flutter_bloc.dart' show Cubit;
import 'package:injectable/injectable.dart';
import 'package:logging/logging.dart';

import '../ui/fragment/document_validation_fragment.dart';
import 'document_validation_state.dart';
import 'preview_document_cubit.dart';

export 'document_validation_state.dart';

/// Cubit for the [DocumentValidationFragment] with [validateDocument] function.
///
/// See also:
/// - [PreviewDocumentCubit]
@injectable
class DocumentValidationCubit extends Cubit<DocumentValidationState> {
static final _log = Logger((DocumentValidationCubit).toString());

final IAutogramService _service;

DocumentValidationCubit({
required IAutogramService service,
}) : _service = service,
super(const DocumentValidationInitialState());

Future<void> validateDocument(String documentId) async {
_log.info("Requesting to validate Document Id: '$documentId'.");
emit(const DocumentValidationLoadingState());

try {
final response = await _service.getDocumentValidation(documentId);

_log.info(
"Got Document validation: (signatureForm: ${response.signatureForm?.value}, signatures: ${response.signatures?.map((e) => e.validationResult.value)}).");

emit(DocumentValidationSuccessState(response));
} catch (error, stackTrace) {
if (error is ServiceException &&
error.errorCode == "DOCUMENT_NOT_SIGNED") {
_log.info("Cannot validate unsigned Document.");

emit(const DocumentValidationNotSignedState());
} else {
_log.severe("Error validating Document.", error, stackTrace);

emit(DocumentValidationErrorState(error));
}
}
}
}
50 changes: 50 additions & 0 deletions lib/bloc/document_validation_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'package:autogram_sign/autogram_sign.dart'
show DocumentValidationResponseBody;
import 'package:flutter/foundation.dart';

import 'document_validation_cubit.dart';

/// State for [DocumentValidationCubit].
@immutable
sealed class DocumentValidationState {
const DocumentValidationState();

@override
String toString() {
return "$runtimeType()";
}
}

class DocumentValidationInitialState extends DocumentValidationState {
const DocumentValidationInitialState();
}

class DocumentValidationLoadingState extends DocumentValidationState {
const DocumentValidationLoadingState();
}

class DocumentValidationErrorState extends DocumentValidationState {
final Object error;

const DocumentValidationErrorState(this.error);

@override
String toString() {
return "$runtimeType(error: $error)";
}
}

class DocumentValidationNotSignedState extends DocumentValidationState {
const DocumentValidationNotSignedState();
}

class DocumentValidationSuccessState extends DocumentValidationState {
final DocumentValidationResponseBody response;

const DocumentValidationSuccessState(this.response);

@override
String toString() {
return "$runtimeType(response: $response)";
}
}
10 changes: 5 additions & 5 deletions lib/bloc/present_signed_document_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ class PresentSignedDocumentCubit extends Cubit<PresentSignedDocumentState> {

final SignDocumentResponseBody signedDocument;

PresentSignedDocumentCubit(
{required AppService appService,
@factoryParam required this.signedDocument,
@factoryParam required DocumentSigningType signingType})
: _appService = appService,
PresentSignedDocumentCubit({
required AppService appService,
@factoryParam required this.signedDocument,
@factoryParam required DocumentSigningType signingType,
}) : _appService = appService,
super(
signingType == DocumentSigningType.local
? const PresentSignedDocumentInitialState()
Expand Down
7 changes: 2 additions & 5 deletions lib/bloc/present_signed_document_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import 'dart:io' show File;

import 'package:flutter/foundation.dart';

import 'present_signed_document_cubit.dart';

/// State for [PresentSignedDocumentCubit].
@immutable
sealed class PresentSignedDocumentState {
Expand Down Expand Up @@ -59,9 +61,4 @@ class PresentSignedLocalDocumentSuccessState
class PresentSignedRemoteDocumentSuccessState
extends PresentSignedDocumentState {
const PresentSignedRemoteDocumentSuccessState();

@override
String toString() {
return "$runtimeType()";
}
}
2 changes: 1 addition & 1 deletion lib/bloc/preview_document_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class PreviewDocumentCubit extends Cubit<PreviewDocumentState> {
emit(state.toLoading());

try {
_log.info("Getting Document Visualisation for DocumentId: $documentId");
_log.info("Getting Document Visualisation for Document Id: $documentId");

final visualization = await _service.getDocumentVisualization(documentId);

Expand Down
21 changes: 12 additions & 9 deletions lib/di.config.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit dba8431

Please sign in to comment.