From d2698c6e64acd4575bc61d4349f826f8bada99eb Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 14 May 2024 17:31:57 +0300 Subject: [PATCH 01/24] added smart selfie models --- .../flutter/generated/SmileIDMessages.g.kt | 194 +++++++++++++++- ios/Classes/SmileIDMessages.g.swift | 177 +++++++++++++- lib/smile_id_service.dart | 12 + lib/smileid_messages.g.dart | 216 +++++++++++++++++- pigeon/messages.dart | 98 +++++++- 5 files changed, 661 insertions(+), 36 deletions(-) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt b/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt index c0184173..e35ebca6 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt @@ -57,6 +57,17 @@ enum class FlutterJobType(val raw: Int) { } } +enum class FlutterJobTypeV2(val raw: Int) { + SMART_SELFIE_AUTHENTICATION(0), + SMART_SELFIE_ENROLLMENT(1); + + companion object { + fun ofRaw(raw: Int): FlutterJobTypeV2? { + return values().firstOrNull { it.raw == raw } + } + } +} + enum class FlutterImageType(val raw: Int) { SELFIEJPGFILE(0), IDCARDJPGFILE(1), @@ -99,6 +110,19 @@ enum class FlutterActionResult(val raw: Int) { } } +enum class FlutterSmartSelfieStatus(val raw: Int) { + APPROVED(0), + PENDING(1), + REJECTED(2), + UNKNOWN(3); + + companion object { + fun ofRaw(raw: Int): FlutterSmartSelfieStatus? { + return values().firstOrNull { it.raw == raw } + } + } +} + /** * Custom values specific to partners can be placed in [extras] * @@ -786,6 +810,89 @@ data class FlutterSmartSelfieJobStatusResponse ( } } +/** Generated class from Pigeon that represents data sent in messages. */ +data class FlutterSmartSelfieRequest ( + val selfieImage: FlutterUploadImageInfo, + val livenessImages: List, + val userId: String? = null, + val partnerParams: Map? = null, + val callbackUrl: String? = null, + val sandboxResult: Long? = null, + val allowNewEnroll: Boolean? = null + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): FlutterSmartSelfieRequest { + val selfieImage = FlutterUploadImageInfo.fromList(list[0] as List) + val livenessImages = list[1] as List + val userId = list[2] as String? + val partnerParams = list[3] as Map? + val callbackUrl = list[4] as String? + val sandboxResult = list[5].let { if (it is Int) it.toLong() else it as Long? } + val allowNewEnroll = list[6] as Boolean? + return FlutterSmartSelfieRequest(selfieImage, livenessImages, userId, partnerParams, callbackUrl, sandboxResult, allowNewEnroll) + } + } + fun toList(): List { + return listOf( + selfieImage.toList(), + livenessImages, + userId, + partnerParams, + callbackUrl, + sandboxResult, + allowNewEnroll, + ) + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class FlutterSmartSelfieResponse ( + val code: String, + val createdAt: String, + val jobId: String, + val jobType: FlutterJobTypeV2, + val message: String, + val partnerId: String, + val partnerParams: Map? = null, + val status: FlutterSmartSelfieStatus, + val updatedAt: String, + val userId: String + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): FlutterSmartSelfieResponse { + val code = list[0] as String + val createdAt = list[1] as String + val jobId = list[2] as String + val jobType = FlutterJobTypeV2.ofRaw(list[3] as Int)!! + val message = list[4] as String + val partnerId = list[5] as String + val partnerParams = list[6] as Map? + val status = FlutterSmartSelfieStatus.ofRaw(list[7] as Int)!! + val updatedAt = list[8] as String + val userId = list[9] as String + return FlutterSmartSelfieResponse(code, createdAt, jobId, jobType, message, partnerId, partnerParams, status, updatedAt, userId) + } + } + fun toList(): List { + return listOf( + code, + createdAt, + jobId, + jobType.raw, + message, + partnerId, + partnerParams, + status.raw, + updatedAt, + userId, + ) + } +} + /** Generated class from Pigeon that represents data sent in messages. */ data class FlutterDocumentVerificationJobResult ( val actions: FlutterActions, @@ -1645,25 +1752,40 @@ private object SmileIDApiCodec : StandardMessageCodec() { } 164.toByte() -> { return (readValue(buffer) as? List)?.let { - FlutterSuspectUser.fromList(it) + FlutterSmartSelfieRequest.fromList(it) } } 165.toByte() -> { return (readValue(buffer) as? List)?.let { - FlutterUploadImageInfo.fromList(it) + FlutterSmartSelfieResponse.fromList(it) } } 166.toByte() -> { return (readValue(buffer) as? List)?.let { - FlutterUploadRequest.fromList(it) + FlutterSuspectUser.fromList(it) } } 167.toByte() -> { return (readValue(buffer) as? List)?.let { - FlutterValidDocument.fromList(it) + FlutterUploadImageInfo.fromList(it) } } 168.toByte() -> { + return (readValue(buffer) as? List)?.let { + FlutterUploadImageInfo.fromList(it) + } + } + 169.toByte() -> { + return (readValue(buffer) as? List)?.let { + FlutterUploadRequest.fromList(it) + } + } + 170.toByte() -> { + return (readValue(buffer) as? List)?.let { + FlutterValidDocument.fromList(it) + } + } + 171.toByte() -> { return (readValue(buffer) as? List)?.let { FlutterValidDocumentsResponse.fromList(it) } @@ -1817,26 +1939,38 @@ private object SmileIDApiCodec : StandardMessageCodec() { stream.write(163) writeValue(stream, value.toList()) } - is FlutterSuspectUser -> { + is FlutterSmartSelfieRequest -> { stream.write(164) writeValue(stream, value.toList()) } - is FlutterUploadImageInfo -> { + is FlutterSmartSelfieResponse -> { stream.write(165) writeValue(stream, value.toList()) } - is FlutterUploadRequest -> { + is FlutterSuspectUser -> { stream.write(166) writeValue(stream, value.toList()) } - is FlutterValidDocument -> { + is FlutterUploadImageInfo -> { stream.write(167) writeValue(stream, value.toList()) } - is FlutterValidDocumentsResponse -> { + is FlutterUploadImageInfo -> { stream.write(168) writeValue(stream, value.toList()) } + is FlutterUploadRequest -> { + stream.write(169) + writeValue(stream, value.toList()) + } + is FlutterValidDocument -> { + stream.write(170) + writeValue(stream, value.toList()) + } + is FlutterValidDocumentsResponse -> { + stream.write(171) + writeValue(stream, value.toList()) + } else -> super.writeValue(stream, value) } } @@ -1853,6 +1987,8 @@ interface SmileIDApi { fun doEnhancedKyc(request: FlutterEnhancedKycRequest, callback: (Result) -> Unit) fun doEnhancedKycAsync(request: FlutterEnhancedKycRequest, callback: (Result) -> Unit) fun getSmartSelfieJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) + fun doSmartSelfieEnrollment(request: FlutterSmartSelfieRequest, callback: (Result) -> Unit) + fun doSmartSelfieAuthentication(request: FlutterSmartSelfieRequest, callback: (Result) -> Unit) fun getDocumentVerificationJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) fun getBiometricKycJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) fun getEnhancedDocumentVerificationJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) @@ -2043,6 +2179,46 @@ interface SmileIDApi { channel.setMessageHandler(null) } } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.smileid.SmileIDApi.doSmartSelfieEnrollment", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val requestArg = args[0] as FlutterSmartSelfieRequest + api.doSmartSelfieEnrollment(requestArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.smileid.SmileIDApi.doSmartSelfieAuthentication", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val requestArg = args[0] as FlutterSmartSelfieRequest + api.doSmartSelfieAuthentication(requestArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.smileid.SmileIDApi.getDocumentVerificationJobStatus", codec) if (api != null) { diff --git a/ios/Classes/SmileIDMessages.g.swift b/ios/Classes/SmileIDMessages.g.swift index 04af2289..24d4b7cd 100644 --- a/ios/Classes/SmileIDMessages.g.swift +++ b/ios/Classes/SmileIDMessages.g.swift @@ -48,6 +48,11 @@ enum FlutterJobType: Int { case smartSelfieAuthentication = 5 } +enum FlutterJobTypeV2: Int { + case smartSelfieAuthentication = 0 + case smartSelfieEnrollment = 1 +} + enum FlutterImageType: Int { case selfieJpgFile = 0 case idCardJpgFile = 1 @@ -78,6 +83,13 @@ enum FlutterActionResult: Int { case unknown = 15 } +enum FlutterSmartSelfieStatus: Int { + case approved = 0 + case pending = 1 + case rejected = 2 + case unknown = 3 +} + /// Custom values specific to partners can be placed in [extras] /// /// Generated class from Pigeon that represents data sent in messages. @@ -833,6 +845,102 @@ struct FlutterSmartSelfieJobStatusResponse { } } +/// Generated class from Pigeon that represents data sent in messages. +struct FlutterSmartSelfieRequest { + var selfieImage: FlutterUploadImageInfo + var livenessImages: [FlutterUploadImageInfo?] + var userId: String? = nil + var partnerParams: [String?: String?]? = nil + var callbackUrl: String? = nil + var sandboxResult: Int64? = nil + var allowNewEnroll: Bool? = nil + + static func fromList(_ list: [Any?]) -> FlutterSmartSelfieRequest? { + let selfieImage = FlutterUploadImageInfo.fromList(list[0] as! [Any?])! + let livenessImages = list[1] as! [FlutterUploadImageInfo?] + let userId: String? = nilOrValue(list[2]) + let partnerParams: [String?: String?]? = nilOrValue(list[3]) + let callbackUrl: String? = nilOrValue(list[4]) + let sandboxResult: Int64? = isNullish(list[5]) ? nil : (list[5] is Int64? ? list[5] as! Int64? : Int64(list[5] as! Int32)) + let allowNewEnroll: Bool? = nilOrValue(list[6]) + + return FlutterSmartSelfieRequest( + selfieImage: selfieImage, + livenessImages: livenessImages, + userId: userId, + partnerParams: partnerParams, + callbackUrl: callbackUrl, + sandboxResult: sandboxResult, + allowNewEnroll: allowNewEnroll + ) + } + func toList() -> [Any?] { + return [ + selfieImage.toList(), + livenessImages, + userId, + partnerParams, + callbackUrl, + sandboxResult, + allowNewEnroll, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct FlutterSmartSelfieResponse { + var code: String + var createdAt: String + var jobId: String + var jobType: FlutterJobTypeV2 + var message: String + var partnerId: String + var partnerParams: [String?: String?]? = nil + var status: FlutterSmartSelfieStatus + var updatedAt: String + var userId: String + + static func fromList(_ list: [Any?]) -> FlutterSmartSelfieResponse? { + let code = list[0] as! String + let createdAt = list[1] as! String + let jobId = list[2] as! String + let jobType = FlutterJobTypeV2(rawValue: list[3] as! Int)! + let message = list[4] as! String + let partnerId = list[5] as! String + let partnerParams: [String?: String?]? = nilOrValue(list[6]) + let status = FlutterSmartSelfieStatus(rawValue: list[7] as! Int)! + let updatedAt = list[8] as! String + let userId = list[9] as! String + + return FlutterSmartSelfieResponse( + code: code, + createdAt: createdAt, + jobId: jobId, + jobType: jobType, + message: message, + partnerId: partnerId, + partnerParams: partnerParams, + status: status, + updatedAt: updatedAt, + userId: userId + ) + } + func toList() -> [Any?] { + return [ + code, + createdAt, + jobId, + jobType.rawValue, + message, + partnerId, + partnerParams, + status.rawValue, + updatedAt, + userId, + ] + } +} + /// Generated class from Pigeon that represents data sent in messages. struct FlutterDocumentVerificationJobResult { var actions: FlutterActions @@ -1677,14 +1785,20 @@ private class SmileIDApiCodecReader: FlutterStandardReader { case 163: return FlutterSmartSelfieJobStatusResponse.fromList(self.readValue() as! [Any?]) case 164: - return FlutterSuspectUser.fromList(self.readValue() as! [Any?]) + return FlutterSmartSelfieRequest.fromList(self.readValue() as! [Any?]) case 165: - return FlutterUploadImageInfo.fromList(self.readValue() as! [Any?]) + return FlutterSmartSelfieResponse.fromList(self.readValue() as! [Any?]) case 166: - return FlutterUploadRequest.fromList(self.readValue() as! [Any?]) + return FlutterSuspectUser.fromList(self.readValue() as! [Any?]) case 167: - return FlutterValidDocument.fromList(self.readValue() as! [Any?]) + return FlutterUploadImageInfo.fromList(self.readValue() as! [Any?]) case 168: + return FlutterUploadImageInfo.fromList(self.readValue() as! [Any?]) + case 169: + return FlutterUploadRequest.fromList(self.readValue() as! [Any?]) + case 170: + return FlutterValidDocument.fromList(self.readValue() as! [Any?]) + case 171: return FlutterValidDocumentsResponse.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) @@ -1802,21 +1916,30 @@ private class SmileIDApiCodecWriter: FlutterStandardWriter { } else if let value = value as? FlutterSmartSelfieJobStatusResponse { super.writeByte(163) super.writeValue(value.toList()) - } else if let value = value as? FlutterSuspectUser { + } else if let value = value as? FlutterSmartSelfieRequest { super.writeByte(164) super.writeValue(value.toList()) - } else if let value = value as? FlutterUploadImageInfo { + } else if let value = value as? FlutterSmartSelfieResponse { super.writeByte(165) super.writeValue(value.toList()) - } else if let value = value as? FlutterUploadRequest { + } else if let value = value as? FlutterSuspectUser { super.writeByte(166) super.writeValue(value.toList()) - } else if let value = value as? FlutterValidDocument { + } else if let value = value as? FlutterUploadImageInfo { super.writeByte(167) super.writeValue(value.toList()) - } else if let value = value as? FlutterValidDocumentsResponse { + } else if let value = value as? FlutterUploadImageInfo { super.writeByte(168) super.writeValue(value.toList()) + } else if let value = value as? FlutterUploadRequest { + super.writeByte(169) + super.writeValue(value.toList()) + } else if let value = value as? FlutterValidDocument { + super.writeByte(170) + super.writeValue(value.toList()) + } else if let value = value as? FlutterValidDocumentsResponse { + super.writeByte(171) + super.writeValue(value.toList()) } else { super.writeValue(value) } @@ -1848,6 +1971,8 @@ protocol SmileIDApi { func doEnhancedKyc(request: FlutterEnhancedKycRequest, completion: @escaping (Result) -> Void) func doEnhancedKycAsync(request: FlutterEnhancedKycRequest, completion: @escaping (Result) -> Void) func getSmartSelfieJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) + func doSmartSelfieEnrollment(request: FlutterSmartSelfieRequest, completion: @escaping (Result) -> Void) + func doSmartSelfieAuthentication(request: FlutterSmartSelfieRequest, completion: @escaping (Result) -> Void) func getDocumentVerificationJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) func getBiometricKycJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) func getEnhancedDocumentVerificationJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) @@ -2008,6 +2133,40 @@ class SmileIDApiSetup { } else { getSmartSelfieJobStatusChannel.setMessageHandler(nil) } + let doSmartSelfieEnrollmentChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.smileid.SmileIDApi.doSmartSelfieEnrollment", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + doSmartSelfieEnrollmentChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let requestArg = args[0] as! FlutterSmartSelfieRequest + api.doSmartSelfieEnrollment(request: requestArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + doSmartSelfieEnrollmentChannel.setMessageHandler(nil) + } + let doSmartSelfieAuthenticationChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.smileid.SmileIDApi.doSmartSelfieAuthentication", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + doSmartSelfieAuthenticationChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let requestArg = args[0] as! FlutterSmartSelfieRequest + api.doSmartSelfieAuthentication(request: requestArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + doSmartSelfieAuthenticationChannel.setMessageHandler(nil) + } let getDocumentVerificationJobStatusChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.smileid.SmileIDApi.getDocumentVerificationJobStatus", binaryMessenger: binaryMessenger, codec: codec) if let api = api { getDocumentVerificationJobStatusChannel.setMessageHandler { message, reply in diff --git a/lib/smile_id_service.dart b/lib/smile_id_service.dart index 01784282..fe644064 100644 --- a/lib/smile_id_service.dart +++ b/lib/smile_id_service.dart @@ -50,6 +50,18 @@ class SmileIDService { return platformInterface.getSmartSelfieJobStatus(request); } + /// Perform a synchronous SmartSelfie Enrollment. The response will include the final result of + /// the enrollment. + Future doSmartSelfieEnrollment(FlutterSmartSelfieRequest request) { + return platformInterface.doSmartSelfieEnrollment(request); + } + + /// Perform a synchronous SmartSelfie Authentication. The response will include the final result + /// of the authentication. + Future doSmartSelfieAuthentication(FlutterSmartSelfieRequest request) { + return platformInterface.doSmartSelfieAuthentication(request); + } + /// Fetches the status of a Job. This can be used to check if a Job is complete, and if so, /// whether it was successful. This should be called when the Job is known to be a /// Document Verification. diff --git a/lib/smileid_messages.g.dart b/lib/smileid_messages.g.dart index f0cde96c..bedc45a6 100644 --- a/lib/smileid_messages.g.dart +++ b/lib/smileid_messages.g.dart @@ -24,6 +24,11 @@ enum FlutterJobType { smartSelfieAuthentication, } +enum FlutterJobTypeV2 { + smart_selfie_authentication, + smart_selfie_enrollment, +} + enum FlutterImageType { selfieJpgFile, idCardJpgFile, @@ -54,6 +59,13 @@ enum FlutterActionResult { unknown, } +enum FlutterSmartSelfieStatus { + approved, + pending, + rejected, + unknown, +} + /// Custom values specific to partners can be placed in [extras] class FlutterPartnerParams { FlutterPartnerParams({ @@ -946,6 +958,123 @@ class FlutterSmartSelfieJobStatusResponse { } } +class FlutterSmartSelfieRequest { + FlutterSmartSelfieRequest({ + required this.selfieImage, + required this.livenessImages, + this.userId, + this.partnerParams, + this.callbackUrl, + this.sandboxResult, + this.allowNewEnroll, + }); + + FlutterUploadImageInfo selfieImage; + + List livenessImages; + + String? userId; + + Map? partnerParams; + + String? callbackUrl; + + int? sandboxResult; + + bool? allowNewEnroll; + + Object encode() { + return [ + selfieImage.encode(), + livenessImages, + userId, + partnerParams, + callbackUrl, + sandboxResult, + allowNewEnroll, + ]; + } + + static FlutterSmartSelfieRequest decode(Object result) { + result as List; + return FlutterSmartSelfieRequest( + selfieImage: FlutterUploadImageInfo.decode(result[0]! as List), + livenessImages: (result[1] as List?)!.cast(), + userId: result[2] as String?, + partnerParams: (result[3] as Map?)?.cast(), + callbackUrl: result[4] as String?, + sandboxResult: result[5] as int?, + allowNewEnroll: result[6] as bool?, + ); + } +} + +class FlutterSmartSelfieResponse { + FlutterSmartSelfieResponse({ + required this.code, + required this.createdAt, + required this.jobId, + required this.jobType, + required this.message, + required this.partnerId, + this.partnerParams, + required this.status, + required this.updatedAt, + required this.userId, + }); + + String code; + + String createdAt; + + String jobId; + + FlutterJobTypeV2 jobType; + + String message; + + String partnerId; + + Map? partnerParams; + + FlutterSmartSelfieStatus status; + + String updatedAt; + + String userId; + + Object encode() { + return [ + code, + createdAt, + jobId, + jobType.index, + message, + partnerId, + partnerParams, + status.index, + updatedAt, + userId, + ]; + } + + static FlutterSmartSelfieResponse decode(Object result) { + result as List; + return FlutterSmartSelfieResponse( + code: result[0]! as String, + createdAt: result[1]! as String, + jobId: result[2]! as String, + jobType: FlutterJobTypeV2.values[result[3]! as int], + message: result[4]! as String, + partnerId: result[5]! as String, + partnerParams: (result[6] as Map?)?.cast(), + status: FlutterSmartSelfieStatus.values[result[7]! as int], + updatedAt: result[8]! as String, + userId: result[9]! as String, + ); + } +} + class FlutterDocumentVerificationJobResult { FlutterDocumentVerificationJobResult({ required this.actions, @@ -1977,21 +2106,30 @@ class _SmileIDApiCodec extends StandardMessageCodec { } else if (value is FlutterSmartSelfieJobStatusResponse) { buffer.putUint8(163); writeValue(buffer, value.encode()); - } else if (value is FlutterSuspectUser) { + } else if (value is FlutterSmartSelfieRequest) { buffer.putUint8(164); writeValue(buffer, value.encode()); - } else if (value is FlutterUploadImageInfo) { + } else if (value is FlutterSmartSelfieResponse) { buffer.putUint8(165); writeValue(buffer, value.encode()); - } else if (value is FlutterUploadRequest) { + } else if (value is FlutterSuspectUser) { buffer.putUint8(166); writeValue(buffer, value.encode()); - } else if (value is FlutterValidDocument) { + } else if (value is FlutterUploadImageInfo) { buffer.putUint8(167); writeValue(buffer, value.encode()); - } else if (value is FlutterValidDocumentsResponse) { + } else if (value is FlutterUploadImageInfo) { buffer.putUint8(168); writeValue(buffer, value.encode()); + } else if (value is FlutterUploadRequest) { + buffer.putUint8(169); + writeValue(buffer, value.encode()); + } else if (value is FlutterValidDocument) { + buffer.putUint8(170); + writeValue(buffer, value.encode()); + } else if (value is FlutterValidDocumentsResponse) { + buffer.putUint8(171); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -2073,14 +2211,20 @@ class _SmileIDApiCodec extends StandardMessageCodec { case 163: return FlutterSmartSelfieJobStatusResponse.decode(readValue(buffer)!); case 164: - return FlutterSuspectUser.decode(readValue(buffer)!); + return FlutterSmartSelfieRequest.decode(readValue(buffer)!); case 165: - return FlutterUploadImageInfo.decode(readValue(buffer)!); + return FlutterSmartSelfieResponse.decode(readValue(buffer)!); case 166: - return FlutterUploadRequest.decode(readValue(buffer)!); + return FlutterSuspectUser.decode(readValue(buffer)!); case 167: - return FlutterValidDocument.decode(readValue(buffer)!); + return FlutterUploadImageInfo.decode(readValue(buffer)!); case 168: + return FlutterUploadImageInfo.decode(readValue(buffer)!); + case 169: + return FlutterUploadRequest.decode(readValue(buffer)!); + case 170: + return FlutterValidDocument.decode(readValue(buffer)!); + case 171: return FlutterValidDocumentsResponse.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -2321,6 +2465,60 @@ class SmileIDApi { } } + Future doSmartSelfieEnrollment(FlutterSmartSelfieRequest request) async { + const String __pigeon_channelName = 'dev.flutter.pigeon.smileid.SmileIDApi.doSmartSelfieEnrollment'; + final BasicMessageChannel __pigeon_channel = BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([request]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as FlutterSmartSelfieResponse?)!; + } + } + + Future doSmartSelfieAuthentication(FlutterSmartSelfieRequest request) async { + const String __pigeon_channelName = 'dev.flutter.pigeon.smileid.SmileIDApi.doSmartSelfieAuthentication'; + final BasicMessageChannel __pigeon_channel = BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([request]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as FlutterSmartSelfieResponse?)!; + } + } + Future getDocumentVerificationJobStatus(FlutterJobStatusRequest request) async { const String __pigeon_channelName = 'dev.flutter.pigeon.smileid.SmileIDApi.getDocumentVerificationJobStatus'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( diff --git a/pigeon/messages.dart b/pigeon/messages.dart index 35cc1771..597ebe33 100644 --- a/pigeon/messages.dart +++ b/pigeon/messages.dart @@ -9,7 +9,19 @@ import 'package:pigeon/pigeon.dart'; swiftOptions: SwiftOptions(), dartPackageName: 'smileid', )) -enum FlutterJobType { enhancedKyc, documentVerification, biometricKyc, enhancedDocumentVerification, smartSelfieEnrollment,smartSelfieAuthentication } +enum FlutterJobType { + enhancedKyc, + documentVerification, + biometricKyc, + enhancedDocumentVerification, + smartSelfieEnrollment, + smartSelfieAuthentication +} + +enum FlutterJobTypeV2 { + smart_selfie_authentication, + smart_selfie_enrollment +} /// Custom values specific to partners can be placed in [extras] class FlutterPartnerParams { @@ -392,6 +404,58 @@ class FlutterSmartSelfieJobStatusResponse { }); } +class FlutterSmartSelfieRequest { + final FlutterUploadImageInfo selfieImage; + final List livenessImages; + final String? userId; + final Map? partnerParams; + final String? callbackUrl; + final int? sandboxResult; + final bool? allowNewEnroll; + + FlutterSmartSelfieRequest( + {required this.selfieImage, + required this.livenessImages, + this.userId, + this.partnerParams, + this.callbackUrl, + this.sandboxResult, + this.allowNewEnroll}); +} + +enum FlutterSmartSelfieStatus { + approved, + pending, + rejected, + unknown +} + +class FlutterSmartSelfieResponse { + final String code; + final String createdAt; + final String jobId; + final FlutterJobTypeV2 jobType; + final String message; + final String partnerId; + final Map? partnerParams; + final FlutterSmartSelfieStatus status; + final String updatedAt; + final String userId; + + FlutterSmartSelfieResponse({ + required this.code, + required this.createdAt, + required this.jobId, + required this.jobType, + required this.message, + required this.partnerId, + required this.partnerParams, + required this.status, + required this.updatedAt, + required this.userId, + }); +} + class FlutterDocumentVerificationJobResult { final FlutterActions actions; final String resultCode; @@ -755,7 +819,8 @@ abstract class SmileIDApi { void setCallbackUrl(String callbackUrl); @async - FlutterAuthenticationResponse authenticate(FlutterAuthenticationRequest request); + FlutterAuthenticationResponse authenticate( + FlutterAuthenticationRequest request); @async FlutterPrepUploadResponse prepUpload(FlutterPrepUploadRequest request); @@ -767,25 +832,40 @@ abstract class SmileIDApi { FlutterEnhancedKycResponse doEnhancedKyc(FlutterEnhancedKycRequest request); @async - FlutterEnhancedKycAsyncResponse doEnhancedKycAsync(FlutterEnhancedKycRequest request); + FlutterEnhancedKycAsyncResponse doEnhancedKycAsync( + FlutterEnhancedKycRequest request); + + @async + FlutterSmartSelfieJobStatusResponse getSmartSelfieJobStatus( + FlutterJobStatusRequest request); + + @async + FlutterSmartSelfieResponse doSmartSelfieEnrollment( + FlutterSmartSelfieRequest request); @async - FlutterSmartSelfieJobStatusResponse getSmartSelfieJobStatus(FlutterJobStatusRequest request); + FlutterSmartSelfieResponse doSmartSelfieAuthentication( + FlutterSmartSelfieRequest request); @async - FlutterDocumentVerificationJobStatusResponse getDocumentVerificationJobStatus(FlutterJobStatusRequest request); + FlutterDocumentVerificationJobStatusResponse getDocumentVerificationJobStatus( + FlutterJobStatusRequest request); @async - FlutterBiometricKycJobStatusResponse getBiometricKycJobStatus(FlutterJobStatusRequest request); + FlutterBiometricKycJobStatusResponse getBiometricKycJobStatus( + FlutterJobStatusRequest request); @async - FlutterEnhancedDocumentVerificationJobStatusResponse getEnhancedDocumentVerificationJobStatus(FlutterJobStatusRequest request); + FlutterEnhancedDocumentVerificationJobStatusResponse + getEnhancedDocumentVerificationJobStatus(FlutterJobStatusRequest request); @async - FlutterProductsConfigResponse getProductsConfig(FlutterProductsConfigRequest request); + FlutterProductsConfigResponse getProductsConfig( + FlutterProductsConfigRequest request); @async - FlutterValidDocumentsResponse getValidDocuments(FlutterProductsConfigRequest request); + FlutterValidDocumentsResponse getValidDocuments( + FlutterProductsConfigRequest request); @async FlutterServicesResponse getServices(); From 811bc498ae2f5163dcf0f28cbd9bdc9fda3223cc Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 14 May 2024 17:33:07 +0300 Subject: [PATCH 02/24] setting up android JT4 setup --- android/build.gradle | 2 +- .../com/smileidentity/flutter/Mapper.kt | 40 +++++++++++++++++++ .../smileidentity/flutter/SmileIDPlugin.kt | 20 ++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index 87858091..423da98c 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ group "com.smileidentity.flutter" -version findProperty("SDK_VERSION") ?: "10.0.4" +version findProperty("SDK_VERSION") ?: "10.1.2" buildscript { ext.kotlin_version = "1.9.10" diff --git a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt index ffa6d744..d7cf6b7e 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt @@ -27,6 +27,7 @@ import FlutterImageLinks import FlutterImageType import FlutterJobStatusRequest import FlutterJobType +import FlutterJobTypeV2 import FlutterPartnerParams import FlutterPrepUploadRequest import FlutterPrepUploadResponse @@ -35,6 +36,9 @@ import FlutterProductsConfigResponse import FlutterServicesResponse import FlutterSmartSelfieJobResult import FlutterSmartSelfieJobStatusResponse +import FlutterSmartSelfieRequest +import FlutterSmartSelfieResponse +import FlutterSmartSelfieStatus import FlutterSuspectUser import FlutterUploadImageInfo import FlutterUploadRequest @@ -68,6 +72,7 @@ import com.smileidentity.models.ImageType import com.smileidentity.models.JobResult import com.smileidentity.models.JobStatusRequest import com.smileidentity.models.JobType +import com.smileidentity.models.v2.JobType as JobTypeV2 import com.smileidentity.models.PartnerParams import com.smileidentity.models.PrepUploadRequest import com.smileidentity.models.PrepUploadResponse @@ -81,6 +86,8 @@ import com.smileidentity.models.UploadImageInfo import com.smileidentity.models.UploadRequest import com.smileidentity.models.ValidDocument import com.smileidentity.models.ValidDocumentsResponse +import com.smileidentity.models.v2.SmartSelfieResponse +import com.smileidentity.models.v2.SmartSelfieStatus import java.io.File /** @@ -122,6 +129,17 @@ fun JobType.toResponse() = when (this) { else -> TODO("Not yet implemented") } +fun FlutterJobTypeV2.toRequest() = when (this) { + FlutterJobTypeV2.SMART_SELFIE_AUTHENTICATION -> JobTypeV2.SmartSelfieAuthentication + FlutterJobTypeV2.SMART_SELFIE_ENROLLMENT -> JobTypeV2.SmartSelfieEnrollment +} + +fun JobTypeV2.toResponse() = when (this) { + JobTypeV2.SmartSelfieAuthentication -> FlutterJobTypeV2.SMART_SELFIE_AUTHENTICATION + JobTypeV2.SmartSelfieEnrollment -> FlutterJobTypeV2.SMART_SELFIE_ENROLLMENT + else -> TODO("Not yet implemented") +} + fun FlutterAuthenticationRequest.toRequest() = AuthenticationRequest( jobType = jobType.toRequest(), country = country, @@ -330,6 +348,28 @@ fun SmartSelfieJobResult.toResponse(): Any = when (this) { ) } +fun FlutterSmartSelfieRequest.toRequest() = SmartSelfieRequest() + +fun SmartSelfieStatus.toResponse() = when (this) { + SmartSelfieStatus.Approved -> FlutterSmartSelfieStatus.APPROVED + SmartSelfieStatus.Pending -> FlutterSmartSelfieStatus.PENDING + SmartSelfieStatus.Rejected -> FlutterSmartSelfieStatus.REJECTED + SmartSelfieStatus.Unknown -> FlutterSmartSelfieStatus.UNKNOWN +} + +fun SmartSelfieResponse.toResponse() = FlutterSmartSelfieResponse( + code = code, + createdAt = createdAt, + jobId = jobId, + jobType = jobType.toResponse(), + message = message, + partnerId = partnerId, + partnerParams = convertNonNullMapToNullable(partnerParams), + status = status.toResponse(), + updatedAt = updatedAt, + userId = userId +) + fun DocumentVerificationJobStatusResponse.toResponse() = FlutterDocumentVerificationJobStatusResponse( timestamp = timestamp, diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt index 6482bff1..5ef7fbf2 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt @@ -15,12 +15,16 @@ import FlutterProductsConfigRequest import FlutterProductsConfigResponse import FlutterServicesResponse import FlutterSmartSelfieJobStatusResponse +import FlutterSmartSelfieRequest +import FlutterSmartSelfieResponse import FlutterUploadRequest import FlutterValidDocumentsResponse import SmileIDApi import android.app.Activity import android.content.Context import com.smileidentity.SmileID +import com.smileidentity.SmileIDOptIn +import com.smileidentity.networking.doSmartSelfieEnrollment import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding @@ -130,6 +134,22 @@ class SmileIDPlugin : FlutterPlugin, SmileIDApi, ActivityAware { callback = callback, ) + @OptIn(SmileIDOptIn::class) + override fun doSmartSelfieEnrollment( + request: FlutterSmartSelfieRequest, + callback: (Result) -> Unit, + ) = launch( + work = { SmileID.api.doSmartSelfieEnrollment(request.toRequest()).toResponse() }, + callback = callback + ) + + override fun doSmartSelfieAuthentication( + request: FlutterSmartSelfieRequest, + callback: (Result) -> Unit, + ) { + TODO("Not yet implemented") + } + override fun getDocumentVerificationJobStatus( request: FlutterJobStatusRequest, callback: (Result) -> Unit, From bff1f478dbcb3506f0418473772c9df2319fa0fd Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 14 May 2024 17:44:07 +0300 Subject: [PATCH 03/24] added jt4 endpoints on android --- .../main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt index 5ef7fbf2..8ae4aa4c 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt @@ -146,9 +146,10 @@ class SmileIDPlugin : FlutterPlugin, SmileIDApi, ActivityAware { override fun doSmartSelfieAuthentication( request: FlutterSmartSelfieRequest, callback: (Result) -> Unit, - ) { - TODO("Not yet implemented") - } + ) = launch( + work = { SmileID.api.doSmartSelfieAuthentication(request.toRequest()).toResponse() }, + callback = callback + ) override fun getDocumentVerificationJobStatus( request: FlutterJobStatusRequest, From b44c09cd3cd15907d149c6ec68d7ec7300d22832 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Thu, 23 May 2024 14:33:35 +0300 Subject: [PATCH 04/24] updated pigeon shared code --- .../flutter/generated/SmileIDMessages.g.kt | 95 +++++++----------- ios/Classes/SmileIDMessages.g.swift | 96 +++++++------------ lib/smileid_messages.g.dart | 86 +++-------------- pigeon/messages.dart | 73 +++++++------- 4 files changed, 111 insertions(+), 239 deletions(-) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt b/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt index e35ebca6..aadee71d 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt @@ -810,43 +810,6 @@ data class FlutterSmartSelfieJobStatusResponse ( } } -/** Generated class from Pigeon that represents data sent in messages. */ -data class FlutterSmartSelfieRequest ( - val selfieImage: FlutterUploadImageInfo, - val livenessImages: List, - val userId: String? = null, - val partnerParams: Map? = null, - val callbackUrl: String? = null, - val sandboxResult: Long? = null, - val allowNewEnroll: Boolean? = null - -) { - companion object { - @Suppress("UNCHECKED_CAST") - fun fromList(list: List): FlutterSmartSelfieRequest { - val selfieImage = FlutterUploadImageInfo.fromList(list[0] as List) - val livenessImages = list[1] as List - val userId = list[2] as String? - val partnerParams = list[3] as Map? - val callbackUrl = list[4] as String? - val sandboxResult = list[5].let { if (it is Int) it.toLong() else it as Long? } - val allowNewEnroll = list[6] as Boolean? - return FlutterSmartSelfieRequest(selfieImage, livenessImages, userId, partnerParams, callbackUrl, sandboxResult, allowNewEnroll) - } - } - fun toList(): List { - return listOf( - selfieImage.toList(), - livenessImages, - userId, - partnerParams, - callbackUrl, - sandboxResult, - allowNewEnroll, - ) - } -} - /** Generated class from Pigeon that represents data sent in messages. */ data class FlutterSmartSelfieResponse ( val code: String, @@ -1752,17 +1715,17 @@ private object SmileIDApiCodec : StandardMessageCodec() { } 164.toByte() -> { return (readValue(buffer) as? List)?.let { - FlutterSmartSelfieRequest.fromList(it) + FlutterSmartSelfieResponse.fromList(it) } } 165.toByte() -> { return (readValue(buffer) as? List)?.let { - FlutterSmartSelfieResponse.fromList(it) + FlutterSuspectUser.fromList(it) } } 166.toByte() -> { return (readValue(buffer) as? List)?.let { - FlutterSuspectUser.fromList(it) + FlutterUploadImageInfo.fromList(it) } } 167.toByte() -> { @@ -1771,21 +1734,16 @@ private object SmileIDApiCodec : StandardMessageCodec() { } } 168.toByte() -> { - return (readValue(buffer) as? List)?.let { - FlutterUploadImageInfo.fromList(it) - } - } - 169.toByte() -> { return (readValue(buffer) as? List)?.let { FlutterUploadRequest.fromList(it) } } - 170.toByte() -> { + 169.toByte() -> { return (readValue(buffer) as? List)?.let { FlutterValidDocument.fromList(it) } } - 171.toByte() -> { + 170.toByte() -> { return (readValue(buffer) as? List)?.let { FlutterValidDocumentsResponse.fromList(it) } @@ -1939,15 +1897,15 @@ private object SmileIDApiCodec : StandardMessageCodec() { stream.write(163) writeValue(stream, value.toList()) } - is FlutterSmartSelfieRequest -> { + is FlutterSmartSelfieResponse -> { stream.write(164) writeValue(stream, value.toList()) } - is FlutterSmartSelfieResponse -> { + is FlutterSuspectUser -> { stream.write(165) writeValue(stream, value.toList()) } - is FlutterSuspectUser -> { + is FlutterUploadImageInfo -> { stream.write(166) writeValue(stream, value.toList()) } @@ -1955,20 +1913,16 @@ private object SmileIDApiCodec : StandardMessageCodec() { stream.write(167) writeValue(stream, value.toList()) } - is FlutterUploadImageInfo -> { - stream.write(168) - writeValue(stream, value.toList()) - } is FlutterUploadRequest -> { - stream.write(169) + stream.write(168) writeValue(stream, value.toList()) } is FlutterValidDocument -> { - stream.write(170) + stream.write(169) writeValue(stream, value.toList()) } is FlutterValidDocumentsResponse -> { - stream.write(171) + stream.write(170) writeValue(stream, value.toList()) } else -> super.writeValue(stream, value) @@ -1987,8 +1941,8 @@ interface SmileIDApi { fun doEnhancedKyc(request: FlutterEnhancedKycRequest, callback: (Result) -> Unit) fun doEnhancedKycAsync(request: FlutterEnhancedKycRequest, callback: (Result) -> Unit) fun getSmartSelfieJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) - fun doSmartSelfieEnrollment(request: FlutterSmartSelfieRequest, callback: (Result) -> Unit) - fun doSmartSelfieAuthentication(request: FlutterSmartSelfieRequest, callback: (Result) -> Unit) + fun doSmartSelfieEnrollment(signature: String, timestamp: String, selfieImage: FlutterUploadImageInfo, livenessImages: List, userId: String, partnerParams: Map?, callbackUrl: String?, sandboxResult: Long?, allowNewEnroll: Boolean?, callback: (Result) -> Unit) + fun doSmartSelfieAuthentication(signature: String, timestamp: String, selfieImage: FlutterUploadImageInfo, livenessImages: List, userId: String, partnerParams: Map?, callbackUrl: String?, sandboxResult: Long?, callback: (Result) -> Unit) fun getDocumentVerificationJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) fun getBiometricKycJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) fun getEnhancedDocumentVerificationJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) @@ -2184,8 +2138,16 @@ interface SmileIDApi { if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val requestArg = args[0] as FlutterSmartSelfieRequest - api.doSmartSelfieEnrollment(requestArg) { result: Result -> + val signatureArg = args[0] as String + val timestampArg = args[1] as String + val selfieImageArg = args[2] as FlutterUploadImageInfo + val livenessImagesArg = args[3] as List + val userIdArg = args[4] as String + val partnerParamsArg = args[5] as Map? + val callbackUrlArg = args[6] as String? + val sandboxResultArg = args[7].let { if (it is Int) it.toLong() else it as Long? } + val allowNewEnrollArg = args[8] as Boolean? + api.doSmartSelfieEnrollment(signatureArg, timestampArg, selfieImageArg, livenessImagesArg, userIdArg, partnerParamsArg, callbackUrlArg, sandboxResultArg, allowNewEnrollArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) @@ -2204,8 +2166,15 @@ interface SmileIDApi { if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val requestArg = args[0] as FlutterSmartSelfieRequest - api.doSmartSelfieAuthentication(requestArg) { result: Result -> + val signatureArg = args[0] as String + val timestampArg = args[1] as String + val selfieImageArg = args[2] as FlutterUploadImageInfo + val livenessImagesArg = args[3] as List + val userIdArg = args[4] as String + val partnerParamsArg = args[5] as Map? + val callbackUrlArg = args[6] as String? + val sandboxResultArg = args[7].let { if (it is Int) it.toLong() else it as Long? } + api.doSmartSelfieAuthentication(signatureArg, timestampArg, selfieImageArg, livenessImagesArg, userIdArg, partnerParamsArg, callbackUrlArg, sandboxResultArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) diff --git a/ios/Classes/SmileIDMessages.g.swift b/ios/Classes/SmileIDMessages.g.swift index 24d4b7cd..6302652b 100644 --- a/ios/Classes/SmileIDMessages.g.swift +++ b/ios/Classes/SmileIDMessages.g.swift @@ -845,48 +845,6 @@ struct FlutterSmartSelfieJobStatusResponse { } } -/// Generated class from Pigeon that represents data sent in messages. -struct FlutterSmartSelfieRequest { - var selfieImage: FlutterUploadImageInfo - var livenessImages: [FlutterUploadImageInfo?] - var userId: String? = nil - var partnerParams: [String?: String?]? = nil - var callbackUrl: String? = nil - var sandboxResult: Int64? = nil - var allowNewEnroll: Bool? = nil - - static func fromList(_ list: [Any?]) -> FlutterSmartSelfieRequest? { - let selfieImage = FlutterUploadImageInfo.fromList(list[0] as! [Any?])! - let livenessImages = list[1] as! [FlutterUploadImageInfo?] - let userId: String? = nilOrValue(list[2]) - let partnerParams: [String?: String?]? = nilOrValue(list[3]) - let callbackUrl: String? = nilOrValue(list[4]) - let sandboxResult: Int64? = isNullish(list[5]) ? nil : (list[5] is Int64? ? list[5] as! Int64? : Int64(list[5] as! Int32)) - let allowNewEnroll: Bool? = nilOrValue(list[6]) - - return FlutterSmartSelfieRequest( - selfieImage: selfieImage, - livenessImages: livenessImages, - userId: userId, - partnerParams: partnerParams, - callbackUrl: callbackUrl, - sandboxResult: sandboxResult, - allowNewEnroll: allowNewEnroll - ) - } - func toList() -> [Any?] { - return [ - selfieImage.toList(), - livenessImages, - userId, - partnerParams, - callbackUrl, - sandboxResult, - allowNewEnroll, - ] - } -} - /// Generated class from Pigeon that represents data sent in messages. struct FlutterSmartSelfieResponse { var code: String @@ -1785,20 +1743,18 @@ private class SmileIDApiCodecReader: FlutterStandardReader { case 163: return FlutterSmartSelfieJobStatusResponse.fromList(self.readValue() as! [Any?]) case 164: - return FlutterSmartSelfieRequest.fromList(self.readValue() as! [Any?]) - case 165: return FlutterSmartSelfieResponse.fromList(self.readValue() as! [Any?]) - case 166: + case 165: return FlutterSuspectUser.fromList(self.readValue() as! [Any?]) + case 166: + return FlutterUploadImageInfo.fromList(self.readValue() as! [Any?]) case 167: return FlutterUploadImageInfo.fromList(self.readValue() as! [Any?]) case 168: - return FlutterUploadImageInfo.fromList(self.readValue() as! [Any?]) - case 169: return FlutterUploadRequest.fromList(self.readValue() as! [Any?]) - case 170: + case 169: return FlutterValidDocument.fromList(self.readValue() as! [Any?]) - case 171: + case 170: return FlutterValidDocumentsResponse.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) @@ -1916,29 +1872,26 @@ private class SmileIDApiCodecWriter: FlutterStandardWriter { } else if let value = value as? FlutterSmartSelfieJobStatusResponse { super.writeByte(163) super.writeValue(value.toList()) - } else if let value = value as? FlutterSmartSelfieRequest { + } else if let value = value as? FlutterSmartSelfieResponse { super.writeByte(164) super.writeValue(value.toList()) - } else if let value = value as? FlutterSmartSelfieResponse { + } else if let value = value as? FlutterSuspectUser { super.writeByte(165) super.writeValue(value.toList()) - } else if let value = value as? FlutterSuspectUser { + } else if let value = value as? FlutterUploadImageInfo { super.writeByte(166) super.writeValue(value.toList()) } else if let value = value as? FlutterUploadImageInfo { super.writeByte(167) super.writeValue(value.toList()) - } else if let value = value as? FlutterUploadImageInfo { - super.writeByte(168) - super.writeValue(value.toList()) } else if let value = value as? FlutterUploadRequest { - super.writeByte(169) + super.writeByte(168) super.writeValue(value.toList()) } else if let value = value as? FlutterValidDocument { - super.writeByte(170) + super.writeByte(169) super.writeValue(value.toList()) } else if let value = value as? FlutterValidDocumentsResponse { - super.writeByte(171) + super.writeByte(170) super.writeValue(value.toList()) } else { super.writeValue(value) @@ -1971,8 +1924,8 @@ protocol SmileIDApi { func doEnhancedKyc(request: FlutterEnhancedKycRequest, completion: @escaping (Result) -> Void) func doEnhancedKycAsync(request: FlutterEnhancedKycRequest, completion: @escaping (Result) -> Void) func getSmartSelfieJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) - func doSmartSelfieEnrollment(request: FlutterSmartSelfieRequest, completion: @escaping (Result) -> Void) - func doSmartSelfieAuthentication(request: FlutterSmartSelfieRequest, completion: @escaping (Result) -> Void) + func doSmartSelfieEnrollment(signature: String, timestamp: String, selfieImage: FlutterUploadImageInfo, livenessImages: [FlutterUploadImageInfo], userId: String, partnerParams: [String?: String?]?, callbackUrl: String?, sandboxResult: Int64?, allowNewEnroll: Bool?, completion: @escaping (Result) -> Void) + func doSmartSelfieAuthentication(signature: String, timestamp: String, selfieImage: FlutterUploadImageInfo, livenessImages: [FlutterUploadImageInfo], userId: String, partnerParams: [String?: String?]?, callbackUrl: String?, sandboxResult: Int64?, completion: @escaping (Result) -> Void) func getDocumentVerificationJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) func getBiometricKycJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) func getEnhancedDocumentVerificationJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) @@ -2137,8 +2090,16 @@ class SmileIDApiSetup { if let api = api { doSmartSelfieEnrollmentChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let requestArg = args[0] as! FlutterSmartSelfieRequest - api.doSmartSelfieEnrollment(request: requestArg) { result in + let signatureArg = args[0] as! String + let timestampArg = args[1] as! String + let selfieImageArg = args[2] as! FlutterUploadImageInfo + let livenessImagesArg = args[3] as! [FlutterUploadImageInfo] + let userIdArg = args[4] as! String + let partnerParamsArg: [String?: String?]? = nilOrValue(args[5]) + let callbackUrlArg: String? = nilOrValue(args[6]) + let sandboxResultArg: Int64? = isNullish(args[7]) ? nil : (args[7] is Int64? ? args[7] as! Int64? : Int64(args[7] as! Int32)) + let allowNewEnrollArg: Bool? = nilOrValue(args[8]) + api.doSmartSelfieEnrollment(signature: signatureArg, timestamp: timestampArg, selfieImage: selfieImageArg, livenessImages: livenessImagesArg, userId: userIdArg, partnerParams: partnerParamsArg, callbackUrl: callbackUrlArg, sandboxResult: sandboxResultArg, allowNewEnroll: allowNewEnrollArg) { result in switch result { case .success(let res): reply(wrapResult(res)) @@ -2154,8 +2115,15 @@ class SmileIDApiSetup { if let api = api { doSmartSelfieAuthenticationChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let requestArg = args[0] as! FlutterSmartSelfieRequest - api.doSmartSelfieAuthentication(request: requestArg) { result in + let signatureArg = args[0] as! String + let timestampArg = args[1] as! String + let selfieImageArg = args[2] as! FlutterUploadImageInfo + let livenessImagesArg = args[3] as! [FlutterUploadImageInfo] + let userIdArg = args[4] as! String + let partnerParamsArg: [String?: String?]? = nilOrValue(args[5]) + let callbackUrlArg: String? = nilOrValue(args[6]) + let sandboxResultArg: Int64? = isNullish(args[7]) ? nil : (args[7] is Int64? ? args[7] as! Int64? : Int64(args[7] as! Int32)) + api.doSmartSelfieAuthentication(signature: signatureArg, timestamp: timestampArg, selfieImage: selfieImageArg, livenessImages: livenessImagesArg, userId: userIdArg, partnerParams: partnerParamsArg, callbackUrl: callbackUrlArg, sandboxResult: sandboxResultArg) { result in switch result { case .success(let res): reply(wrapResult(res)) diff --git a/lib/smileid_messages.g.dart b/lib/smileid_messages.g.dart index bedc45a6..d124250a 100644 --- a/lib/smileid_messages.g.dart +++ b/lib/smileid_messages.g.dart @@ -958,57 +958,6 @@ class FlutterSmartSelfieJobStatusResponse { } } -class FlutterSmartSelfieRequest { - FlutterSmartSelfieRequest({ - required this.selfieImage, - required this.livenessImages, - this.userId, - this.partnerParams, - this.callbackUrl, - this.sandboxResult, - this.allowNewEnroll, - }); - - FlutterUploadImageInfo selfieImage; - - List livenessImages; - - String? userId; - - Map? partnerParams; - - String? callbackUrl; - - int? sandboxResult; - - bool? allowNewEnroll; - - Object encode() { - return [ - selfieImage.encode(), - livenessImages, - userId, - partnerParams, - callbackUrl, - sandboxResult, - allowNewEnroll, - ]; - } - - static FlutterSmartSelfieRequest decode(Object result) { - result as List; - return FlutterSmartSelfieRequest( - selfieImage: FlutterUploadImageInfo.decode(result[0]! as List), - livenessImages: (result[1] as List?)!.cast(), - userId: result[2] as String?, - partnerParams: (result[3] as Map?)?.cast(), - callbackUrl: result[4] as String?, - sandboxResult: result[5] as int?, - allowNewEnroll: result[6] as bool?, - ); - } -} - class FlutterSmartSelfieResponse { FlutterSmartSelfieResponse({ required this.code, @@ -2106,29 +2055,26 @@ class _SmileIDApiCodec extends StandardMessageCodec { } else if (value is FlutterSmartSelfieJobStatusResponse) { buffer.putUint8(163); writeValue(buffer, value.encode()); - } else if (value is FlutterSmartSelfieRequest) { + } else if (value is FlutterSmartSelfieResponse) { buffer.putUint8(164); writeValue(buffer, value.encode()); - } else if (value is FlutterSmartSelfieResponse) { + } else if (value is FlutterSuspectUser) { buffer.putUint8(165); writeValue(buffer, value.encode()); - } else if (value is FlutterSuspectUser) { + } else if (value is FlutterUploadImageInfo) { buffer.putUint8(166); writeValue(buffer, value.encode()); } else if (value is FlutterUploadImageInfo) { buffer.putUint8(167); writeValue(buffer, value.encode()); - } else if (value is FlutterUploadImageInfo) { - buffer.putUint8(168); - writeValue(buffer, value.encode()); } else if (value is FlutterUploadRequest) { - buffer.putUint8(169); + buffer.putUint8(168); writeValue(buffer, value.encode()); } else if (value is FlutterValidDocument) { - buffer.putUint8(170); + buffer.putUint8(169); writeValue(buffer, value.encode()); } else if (value is FlutterValidDocumentsResponse) { - buffer.putUint8(171); + buffer.putUint8(170); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -2211,20 +2157,18 @@ class _SmileIDApiCodec extends StandardMessageCodec { case 163: return FlutterSmartSelfieJobStatusResponse.decode(readValue(buffer)!); case 164: - return FlutterSmartSelfieRequest.decode(readValue(buffer)!); - case 165: return FlutterSmartSelfieResponse.decode(readValue(buffer)!); - case 166: + case 165: return FlutterSuspectUser.decode(readValue(buffer)!); + case 166: + return FlutterUploadImageInfo.decode(readValue(buffer)!); case 167: return FlutterUploadImageInfo.decode(readValue(buffer)!); case 168: - return FlutterUploadImageInfo.decode(readValue(buffer)!); - case 169: return FlutterUploadRequest.decode(readValue(buffer)!); - case 170: + case 169: return FlutterValidDocument.decode(readValue(buffer)!); - case 171: + case 170: return FlutterValidDocumentsResponse.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -2465,7 +2409,7 @@ class SmileIDApi { } } - Future doSmartSelfieEnrollment(FlutterSmartSelfieRequest request) async { + Future doSmartSelfieEnrollment(String signature, String timestamp, FlutterUploadImageInfo selfieImage, List livenessImages, String userId, Map? partnerParams, String? callbackUrl, int? sandboxResult, bool? allowNewEnroll) async { const String __pigeon_channelName = 'dev.flutter.pigeon.smileid.SmileIDApi.doSmartSelfieEnrollment'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -2473,7 +2417,7 @@ class SmileIDApi { binaryMessenger: __pigeon_binaryMessenger, ); final List? __pigeon_replyList = - await __pigeon_channel.send([request]) as List?; + await __pigeon_channel.send([signature, timestamp, selfieImage, livenessImages, userId, partnerParams, callbackUrl, sandboxResult, allowNewEnroll]) as List?; if (__pigeon_replyList == null) { throw _createConnectionError(__pigeon_channelName); } else if (__pigeon_replyList.length > 1) { @@ -2492,7 +2436,7 @@ class SmileIDApi { } } - Future doSmartSelfieAuthentication(FlutterSmartSelfieRequest request) async { + Future doSmartSelfieAuthentication(String signature, String timestamp, FlutterUploadImageInfo selfieImage, List livenessImages, String userId, Map? partnerParams, String? callbackUrl, int? sandboxResult) async { const String __pigeon_channelName = 'dev.flutter.pigeon.smileid.SmileIDApi.doSmartSelfieAuthentication'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -2500,7 +2444,7 @@ class SmileIDApi { binaryMessenger: __pigeon_binaryMessenger, ); final List? __pigeon_replyList = - await __pigeon_channel.send([request]) as List?; + await __pigeon_channel.send([signature, timestamp, selfieImage, livenessImages, userId, partnerParams, callbackUrl, sandboxResult]) as List?; if (__pigeon_replyList == null) { throw _createConnectionError(__pigeon_channelName); } else if (__pigeon_replyList.length > 1) { diff --git a/pigeon/messages.dart b/pigeon/messages.dart index 597ebe33..f931f3d9 100644 --- a/pigeon/messages.dart +++ b/pigeon/messages.dart @@ -3,7 +3,8 @@ import 'package:pigeon/pigeon.dart'; @ConfigurePigeon(PigeonOptions( dartOut: 'lib/smileid_messages.g.dart', dartOptions: DartOptions(), - kotlinOut: 'android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt', + kotlinOut: + 'android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt', kotlinOptions: KotlinOptions(errorClassName: "SmileFlutterError"), swiftOut: 'ios/Classes/SmileIDMessages.g.swift', swiftOptions: SwiftOptions(), @@ -18,10 +19,7 @@ enum FlutterJobType { smartSelfieAuthentication } -enum FlutterJobTypeV2 { - smart_selfie_authentication, - smart_selfie_enrollment -} +enum FlutterJobTypeV2 { smart_selfie_authentication, smart_selfie_enrollment } /// Custom values specific to partners can be placed in [extras] class FlutterPartnerParams { @@ -404,31 +402,7 @@ class FlutterSmartSelfieJobStatusResponse { }); } -class FlutterSmartSelfieRequest { - final FlutterUploadImageInfo selfieImage; - final List livenessImages; - final String? userId; - final Map? partnerParams; - final String? callbackUrl; - final int? sandboxResult; - final bool? allowNewEnroll; - - FlutterSmartSelfieRequest( - {required this.selfieImage, - required this.livenessImages, - this.userId, - this.partnerParams, - this.callbackUrl, - this.sandboxResult, - this.allowNewEnroll}); -} - -enum FlutterSmartSelfieStatus { - approved, - pending, - rejected, - unknown -} +enum FlutterSmartSelfieStatus { approved, pending, rejected, unknown } class FlutterSmartSelfieResponse { final String code; @@ -443,15 +417,15 @@ class FlutterSmartSelfieResponse { final String userId; FlutterSmartSelfieResponse({ - required this.code, - required this.createdAt, - required this.jobId, - required this.jobType, - required this.message, - required this.partnerId, - required this.partnerParams, - required this.status, - required this.updatedAt, + required this.code, + required this.createdAt, + required this.jobId, + required this.jobType, + required this.message, + required this.partnerId, + required this.partnerParams, + required this.status, + required this.updatedAt, required this.userId, }); } @@ -841,11 +815,28 @@ abstract class SmileIDApi { @async FlutterSmartSelfieResponse doSmartSelfieEnrollment( - FlutterSmartSelfieRequest request); + String signature, + String timestamp, + FlutterUploadImageInfo selfieImage, + List livenessImages, + String userId, + Map? partnerParams, + String? callbackUrl, + int? sandboxResult, + bool? allowNewEnroll, + ); @async FlutterSmartSelfieResponse doSmartSelfieAuthentication( - FlutterSmartSelfieRequest request); + String signature, + String timestamp, + FlutterUploadImageInfo selfieImage, + List livenessImages, + String userId, + Map? partnerParams, + String? callbackUrl, + int? sandboxResult, + ); @async FlutterDocumentVerificationJobStatusResponse getDocumentVerificationJobStatus( From 32a8ef951133e71bba04ae2c7f14583d31a04fcb Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Thu, 23 May 2024 14:36:00 +0300 Subject: [PATCH 05/24] added android platform code --- .../com/smileidentity/flutter/Mapper.kt | 3 - .../smileidentity/flutter/SmileIDPlugin.kt | 63 ++++++++++++++++--- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt index d7cf6b7e..38b71de2 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt @@ -36,7 +36,6 @@ import FlutterProductsConfigResponse import FlutterServicesResponse import FlutterSmartSelfieJobResult import FlutterSmartSelfieJobStatusResponse -import FlutterSmartSelfieRequest import FlutterSmartSelfieResponse import FlutterSmartSelfieStatus import FlutterSuspectUser @@ -348,8 +347,6 @@ fun SmartSelfieJobResult.toResponse(): Any = when (this) { ) } -fun FlutterSmartSelfieRequest.toRequest() = SmartSelfieRequest() - fun SmartSelfieStatus.toResponse() = when (this) { SmartSelfieStatus.Approved -> FlutterSmartSelfieStatus.APPROVED SmartSelfieStatus.Pending -> FlutterSmartSelfieStatus.PENDING diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt index 8ae4aa4c..e1f6ea01 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt @@ -15,8 +15,8 @@ import FlutterProductsConfigRequest import FlutterProductsConfigResponse import FlutterServicesResponse import FlutterSmartSelfieJobStatusResponse -import FlutterSmartSelfieRequest import FlutterSmartSelfieResponse +import FlutterUploadImageInfo import FlutterUploadRequest import FlutterValidDocumentsResponse import SmileIDApi @@ -24,7 +24,7 @@ import android.app.Activity import android.content.Context import com.smileidentity.SmileID import com.smileidentity.SmileIDOptIn -import com.smileidentity.networking.doSmartSelfieEnrollment +import com.smileidentity.networking.asFormDataPart import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding @@ -136,19 +136,66 @@ class SmileIDPlugin : FlutterPlugin, SmileIDApi, ActivityAware { @OptIn(SmileIDOptIn::class) override fun doSmartSelfieEnrollment( - request: FlutterSmartSelfieRequest, + signature: String, + timestamp: String, + selfieImage: FlutterUploadImageInfo, + livenessImages: List, + userId: String, + partnerParams: Map?, + callbackUrl: String?, + sandboxResult: Long?, + allowNewEnroll: Boolean?, callback: (Result) -> Unit, ) = launch( - work = { SmileID.api.doSmartSelfieEnrollment(request.toRequest()).toResponse() }, - callback = callback + work = { + SmileID.api.doSmartSelfieEnrollment( + userId = userId, + selfieImage = selfieImage.toRequest().image.asFormDataPart( + partName = "selfie_image", + mediaType = "image/jpeg", + ), + livenessImages = livenessImages.map { + it.toRequest().image.asFormDataPart( + partName = "liveness_images", + mediaType = "image/jpeg", + ) + }, + partnerParams = convertNullableMapToNonNull(partnerParams), + callbackUrl = callbackUrl, + sandboxResult = sandboxResult?.toInt(), + allowNewEnroll = allowNewEnroll, + ).toResponse() + }, + callback = callback, ) + @OptIn(SmileIDOptIn::class) override fun doSmartSelfieAuthentication( - request: FlutterSmartSelfieRequest, + signature: String, + timestamp: String, + selfieImage: FlutterUploadImageInfo, + livenessImages: List, + userId: String, + partnerParams: Map?, + callbackUrl: String?, + sandboxResult: Long?, callback: (Result) -> Unit, ) = launch( - work = { SmileID.api.doSmartSelfieAuthentication(request.toRequest()).toResponse() }, - callback = callback + work = { + SmileID.api.doSmartSelfieAuthentication( + userId = userId, + selfieImage = selfieImage.toRequest().image + .asFormDataPart("selfie_image", "image/jpeg"), + livenessImages = livenessImages.map { + it.toRequest().image + .asFormDataPart("liveness_images", "image/jpeg") + }, + partnerParams = convertNullableMapToNonNull(partnerParams), + callbackUrl = callbackUrl, + sandboxResult = sandboxResult?.toInt(), + ).toResponse() + }, + callback = callback, ) override fun getDocumentVerificationJobStatus( From 8235df0f3868ad1a62a968dd588ba5047f3dacf6 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Thu, 23 May 2024 14:59:12 +0300 Subject: [PATCH 06/24] updated dart platform interface --- lib/smile_id_service.dart | 46 +++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/lib/smile_id_service.dart b/lib/smile_id_service.dart index fe644064..8f72ab36 100644 --- a/lib/smile_id_service.dart +++ b/lib/smile_id_service.dart @@ -52,14 +52,52 @@ class SmileIDService { /// Perform a synchronous SmartSelfie Enrollment. The response will include the final result of /// the enrollment. - Future doSmartSelfieEnrollment(FlutterSmartSelfieRequest request) { - return platformInterface.doSmartSelfieEnrollment(request); + Future doSmartSelfieEnrollment( + String signature, + String timestamp, + FlutterUploadImageInfo selfieImage, + List livenessImages, + String userId, + Map? partnerParams, + String? callbackUrl, + int? sandboxResult, + bool? allowNewEnroll + ) { + return platformInterface.doSmartSelfieEnrollment( + signature, + timestamp, + selfieImage, + livenessImages, + userId, + partnerParams, + callbackUrl, + sandboxResult, + allowNewEnroll + ); } /// Perform a synchronous SmartSelfie Authentication. The response will include the final result /// of the authentication. - Future doSmartSelfieAuthentication(FlutterSmartSelfieRequest request) { - return platformInterface.doSmartSelfieAuthentication(request); + Future doSmartSelfieAuthentication( + String signature, + String timestamp, + FlutterUploadImageInfo selfieImage, + List livenessImages, + String userId, + Map? partnerParams, + String? callbackUrl, + int? sandboxResult, + ) { + return platformInterface.doSmartSelfieAuthentication( + signature, + timestamp, + selfieImage, + livenessImages, + userId, + partnerParams, + callbackUrl, + sandboxResult + ); } /// Fetches the status of a Job. This can be used to check if a Job is complete, and if so, From 2970ad15ef4ddbe8325e4448d03b446c3f5773cd Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Thu, 23 May 2024 18:11:24 +0300 Subject: [PATCH 07/24] iOS platform interface setup --- ios/Classes/Mapper.swift | 28 ++++++++++++++ ios/Classes/SmileIDPlugin.swift | 68 +++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/ios/Classes/Mapper.swift b/ios/Classes/Mapper.swift index dce53a2e..73180625 100644 --- a/ios/Classes/Mapper.swift +++ b/ios/Classes/Mapper.swift @@ -1,5 +1,16 @@ import SmileID +func convertNullableMapToNonNull(data: [String? : String?]?) -> [String : String]? { + guard let unwrappedData = data else { return nil } + var convertedDictionary = [String : String]() + for (key, value) in unwrappedData { + if let unwrappedKey = key, let unwrappedValue = value { + convertedDictionary[unwrappedKey] = unwrappedValue + } + } + return convertedDictionary +} + extension FlutterPartnerParams { func toRequest() -> PartnerParams { PartnerParams( @@ -214,6 +225,23 @@ extension EnhancedKycAsyncResponse { } } +extension SmartSelfieResponse { + func toResponse() -> FlutterSmartSelfieResponse { + FlutterSmartSelfieResponse( + code: code, + createdAt: createdAt, + jobId: jobId, + jobType: jobType, + message: message, + partnerId: partnerId, + partnerParams: partnerParams, + status: SmartSelfieStatus., + updatedAt: updatedAt, + userId: userId + ) + } +} + extension Actions { func toResponse() -> FlutterActions { FlutterActions( diff --git a/ios/Classes/SmileIDPlugin.swift b/ios/Classes/SmileIDPlugin.swift index 4d8c765a..971f97c9 100644 --- a/ios/Classes/SmileIDPlugin.swift +++ b/ios/Classes/SmileIDPlugin.swift @@ -157,6 +157,74 @@ public class SmileIDPlugin: NSObject, FlutterPlugin, SmileIDApi { }) .store(in: &subscribers) } + + func doSmartSelfieEnrollment( + signature: String, + timestamp: String, + selfieImage: FlutterUploadImageInfo, + livenessImages: [FlutterUploadImageInfo], + userId: String, + partnerParams: [String? : String?]?, + callbackUrl: String?, + sandboxResult: Int64?, + allowNewEnroll: Bool?, + completion: @escaping (Result) -> Void + ) { + SmileID.api.doSmartSelfieEnrollment( + signature: signature, + timestamp: timestamp, + selfieImage: selfieImage, + livenessImages: livenessImages, + userId: userId, + partnerParams: convertNullableMapToNonNull(data: partnerParams), + callbackUrl: callbackUrl, + sandboxResult: sandboxResult, + allowNewEnroll: allowNewEnroll + ).sink(receiveCompletion: { status in + switch status { + case .failure(let error): + completion(.failure(error)) + default: + break + } + + }, receiveValue: { response in + completion(.success(response.toResponse())) + }).store(in: &subscribers) + } + + func doSmartSelfieAuthentication( + signature: String, + timestamp: String, + selfieImage: FlutterUploadImageInfo, + livenessImages: [FlutterUploadImageInfo], + userId: String, + partnerParams: [String? : String?]?, + callbackUrl: String?, + sandboxResult: Int64?, + completion: @escaping (Result) -> Void + ) { + SmileID.api.doSmartSelfieAuthentication( + signature: signature, + timestamp: timestamp, + userId: userId, + selfieImage: selfieImage, + livenessImages: livenessImages, + partnerParams: convertNullableMapToNonNull(data: partnerParams), + callbackUrl: callbackUrl, + sandboxResult: Int?(sandboxResult) + ).sink(receiveCompletion: { status in + switch status { + case .failure(let error): + completion(.failure(error)) + default: + break + } + + }, receiveValue: { response in + completion(.success(response.toResponse())) + }).store(in: &subscribers) + } func getSmartSelfieJobStatus( request: FlutterJobStatusRequest, From 93725286b7bef5db4adefe19a893e1f53f157128 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Fri, 24 May 2024 15:15:32 +0300 Subject: [PATCH 08/24] Update Mapper.swift --- ios/Classes/Mapper.swift | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/ios/Classes/Mapper.swift b/ios/Classes/Mapper.swift index 73180625..b1b4bd32 100644 --- a/ios/Classes/Mapper.swift +++ b/ios/Classes/Mapper.swift @@ -96,6 +96,18 @@ extension JobType { } } +extension JobTypeV2 { + func toResponse() -> FlutterJobTypeV2 { + switch(self) { + case .smartSelfieAuthentication: + FlutterJobTypeV2.smartSelfieAuthentication + case .smartSelfieEnrollment: + FlutterJobTypeV2.smartSelfieEnrollment + default: fatalError("Not yet supported") + } + } +} + extension FlutterPrepUploadRequest { func toRequest() -> PrepUploadRequest { PrepUploadRequest( @@ -225,17 +237,32 @@ extension EnhancedKycAsyncResponse { } } +extension SmartSelfieStatus { + func toResponse() -> FlutterSmartSelfieStatus { + switch(self) { + case .approved: + FlutterSmartSelfieStatus.approved + case .pending: + FlutterSmartSelfieStatus.pending + case .rejected: + FlutterSmartSelfieStatus.rejected + case .unknown: + FlutterSmartSelfieStatus.unknown + } + } +} + extension SmartSelfieResponse { func toResponse() -> FlutterSmartSelfieResponse { FlutterSmartSelfieResponse( code: code, createdAt: createdAt, jobId: jobId, - jobType: jobType, + jobType: jobType.toResponse(), message: message, partnerId: partnerId, partnerParams: partnerParams, - status: SmartSelfieStatus., + status: status.toResponse(), updatedAt: updatedAt, userId: userId ) From ecc182e7d5288506ef2033f4a7cb74bcb110e3cc Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Fri, 24 May 2024 16:08:19 +0300 Subject: [PATCH 09/24] updated ios platform code --- ios/Classes/Mapper.swift | 5 +++++ ios/Classes/SmileIDPlugin.swift | 12 ++++++------ ios/Classes/SmileIDSmartSelfieAuthentication.swift | 5 ++--- ios/Classes/SmileIDSmartSelfieEnrollment.swift | 4 ++-- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/ios/Classes/Mapper.swift b/ios/Classes/Mapper.swift index b1b4bd32..fb3da014 100644 --- a/ios/Classes/Mapper.swift +++ b/ios/Classes/Mapper.swift @@ -150,6 +150,11 @@ extension FlutterUploadImageInfo { fileName: imageName ) } + func toMultiPartRequest() -> MultipartBody { + // do we need to expose a func that get's us a file here? + let dataUrl = try LocalStorage.getFileByType(jobId: <#T##String#>, fileType: imageTypeId.toRequest()) + MultipartBody(withImage: Data(contentsOf: dataUrl), forKey: imageName, forName: imageName) + } } extension FlutterImageType { diff --git a/ios/Classes/SmileIDPlugin.swift b/ios/Classes/SmileIDPlugin.swift index caad4596..f6b8f267 100644 --- a/ios/Classes/SmileIDPlugin.swift +++ b/ios/Classes/SmileIDPlugin.swift @@ -174,12 +174,12 @@ public class SmileIDPlugin: NSObject, FlutterPlugin, SmileIDApi { SmileID.api.doSmartSelfieEnrollment( signature: signature, timestamp: timestamp, - selfieImage: selfieImage, - livenessImages: livenessImages, + selfieImage: selfieImage.toMultiPartRequest(), + livenessImages: livenessImages.map { $0.toMultiPartRequest() }, userId: userId, partnerParams: convertNullableMapToNonNull(data: partnerParams), callbackUrl: callbackUrl, - sandboxResult: sandboxResult, + sandboxResult: sandboxResult.map { Int($0) }, allowNewEnroll: allowNewEnroll ).sink(receiveCompletion: { status in switch status { @@ -209,11 +209,11 @@ public class SmileIDPlugin: NSObject, FlutterPlugin, SmileIDApi { signature: signature, timestamp: timestamp, userId: userId, - selfieImage: selfieImage, - livenessImages: livenessImages, + selfieImage: selfieImage.toMultiPartRequest(), + livenessImages: livenessImages.map { $0.toMultiPartRequest() }, partnerParams: convertNullableMapToNonNull(data: partnerParams), callbackUrl: callbackUrl, - sandboxResult: Int?(sandboxResult) + sandboxResult: sandboxResult.map { Int($0) } ).sink(receiveCompletion: { status in switch status { case .failure(let error): diff --git a/ios/Classes/SmileIDSmartSelfieAuthentication.swift b/ios/Classes/SmileIDSmartSelfieAuthentication.swift index e54389d1..2bb697cc 100644 --- a/ios/Classes/SmileIDSmartSelfieAuthentication.swift +++ b/ios/Classes/SmileIDSmartSelfieAuthentication.swift @@ -48,13 +48,12 @@ class SmileIDSmartSelfieAuthentication : NSObject, FlutterPlatformView, SmartSel return _view } - - func didSucceed(selfieImage: URL, livenessImages: [URL], didSubmitSmartSelfieJob: Bool) { + func didSucceed(selfieImage: URL, livenessImages: [URL], apiResponse: SmartSelfieResponse?) { _childViewController?.removeFromParent() _channel.invokeMethod("onSuccess", arguments: """ {"selfieFile": "\(selfieImage.absoluteString)", "livenessImages": \(livenessImages.map{ $0.absoluteString }), - "didSubmitSmartSelfieJob": \(didSubmitSmartSelfieJob), + "apiResponse": \(apiResponse)}, """) } diff --git a/ios/Classes/SmileIDSmartSelfieEnrollment.swift b/ios/Classes/SmileIDSmartSelfieEnrollment.swift index 3cc6ec95..4f558a9e 100644 --- a/ios/Classes/SmileIDSmartSelfieEnrollment.swift +++ b/ios/Classes/SmileIDSmartSelfieEnrollment.swift @@ -48,12 +48,12 @@ class SmileIDSmartSelfieEnrollment : NSObject, FlutterPlatformView, SmartSelfieR return _view } - func didSucceed(selfieImage: URL, livenessImages: [URL], didSubmitSmartSelfieJob: Bool) { + func didSucceed(selfieImage: URL, livenessImages: [URL], apiResponse: SmartSelfieResponse?) { _childViewController?.removeFromParent() _channel.invokeMethod("onSuccess", arguments: """ {"selfieFile": "\(selfieImage.absoluteString)", "livenessImages": \(livenessImages.map{ $0.absoluteString }), - "didSubmitSmartSelfieJob": \(didSubmitSmartSelfieJob), + "apiResponse": \(apiResponse)}, """) } From 6c8b7d6851ca4da138689ddfbeb32f508e1e8b97 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Fri, 24 May 2024 16:10:12 +0300 Subject: [PATCH 10/24] Update SmileIDPlugin.kt --- .../src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt index 82018737..55f8fe78 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt @@ -23,6 +23,8 @@ import SmileIDApi import android.app.Activity import android.content.Context import com.smileidentity.SmileID +import com.smileidentity.SmileIDOptIn +import com.smileidentity.networking.asFormDataPart import com.smileidentity.networking.pollBiometricKycJobStatus import com.smileidentity.networking.pollDocumentVerificationJobStatus import com.smileidentity.networking.pollEnhancedDocumentVerificationJobStatus From 2e142a9cdbf5396a8ed99c8adde45b5bd3761f53 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Wed, 29 May 2024 16:36:38 +0300 Subject: [PATCH 11/24] pass image path on JT4 jobs --- .../smileidentity/flutter/SmileIDPlugin.kt | 25 +++++++------ .../flutter/generated/SmileIDMessages.g.kt | 31 ++++++---------- ios/Classes/Mapper.swift | 23 +++++++++--- ios/Classes/SmileIDMessages.g.swift | 27 ++++++-------- ios/Classes/SmileIDPlugin.swift | 36 ++++++++++++++----- lib/smile_id_service.dart | 8 ++--- lib/smileid_messages.g.dart | 19 ++++------ pigeon/messages.dart | 8 ++--- 8 files changed, 98 insertions(+), 79 deletions(-) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt index 55f8fe78..1f17a129 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt @@ -40,6 +40,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.single import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import java.io.File import java.net.URL import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds @@ -147,8 +148,8 @@ class SmileIDPlugin : FlutterPlugin, SmileIDApi, ActivityAware { override fun doSmartSelfieEnrollment( signature: String, timestamp: String, - selfieImage: FlutterUploadImageInfo, - livenessImages: List, + selfieImage: String, + livenessImages: List, userId: String, partnerParams: Map?, callbackUrl: String?, @@ -159,12 +160,12 @@ class SmileIDPlugin : FlutterPlugin, SmileIDApi, ActivityAware { work = { SmileID.api.doSmartSelfieEnrollment( userId = userId, - selfieImage = selfieImage.toRequest().image.asFormDataPart( + selfieImage = File(selfieImage).asFormDataPart( partName = "selfie_image", mediaType = "image/jpeg", ), livenessImages = livenessImages.map { - it.toRequest().image.asFormDataPart( + File(selfieImage).asFormDataPart( partName = "liveness_images", mediaType = "image/jpeg", ) @@ -182,8 +183,8 @@ class SmileIDPlugin : FlutterPlugin, SmileIDApi, ActivityAware { override fun doSmartSelfieAuthentication( signature: String, timestamp: String, - selfieImage: FlutterUploadImageInfo, - livenessImages: List, + selfieImage: String, + livenessImages: List, userId: String, partnerParams: Map?, callbackUrl: String?, @@ -193,11 +194,15 @@ class SmileIDPlugin : FlutterPlugin, SmileIDApi, ActivityAware { work = { SmileID.api.doSmartSelfieAuthentication( userId = userId, - selfieImage = selfieImage.toRequest().image - .asFormDataPart("selfie_image", "image/jpeg"), + selfieImage = File(selfieImage).asFormDataPart( + partName = "selfie_image", + mediaType = "image/jpeg", + ), livenessImages = livenessImages.map { - it.toRequest().image - .asFormDataPart("liveness_images", "image/jpeg") + File(selfieImage).asFormDataPart( + partName = "liveness_images", + mediaType = "image/jpeg", + ) }, partnerParams = convertNullableMapToNonNull(partnerParams), callbackUrl = callbackUrl, diff --git a/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt b/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt index 6dad559b..722425e7 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt @@ -1729,21 +1729,16 @@ private object SmileIDApiCodec : StandardMessageCodec() { } } 167.toByte() -> { - return (readValue(buffer) as? List)?.let { - FlutterUploadImageInfo.fromList(it) - } - } - 168.toByte() -> { return (readValue(buffer) as? List)?.let { FlutterUploadRequest.fromList(it) } } - 169.toByte() -> { + 168.toByte() -> { return (readValue(buffer) as? List)?.let { FlutterValidDocument.fromList(it) } } - 170.toByte() -> { + 169.toByte() -> { return (readValue(buffer) as? List)?.let { FlutterValidDocumentsResponse.fromList(it) } @@ -1909,20 +1904,16 @@ private object SmileIDApiCodec : StandardMessageCodec() { stream.write(166) writeValue(stream, value.toList()) } - is FlutterUploadImageInfo -> { - stream.write(167) - writeValue(stream, value.toList()) - } is FlutterUploadRequest -> { - stream.write(168) + stream.write(167) writeValue(stream, value.toList()) } is FlutterValidDocument -> { - stream.write(169) + stream.write(168) writeValue(stream, value.toList()) } is FlutterValidDocumentsResponse -> { - stream.write(170) + stream.write(169) writeValue(stream, value.toList()) } else -> super.writeValue(stream, value) @@ -1941,8 +1932,8 @@ interface SmileIDApi { fun doEnhancedKyc(request: FlutterEnhancedKycRequest, callback: (Result) -> Unit) fun doEnhancedKycAsync(request: FlutterEnhancedKycRequest, callback: (Result) -> Unit) fun getSmartSelfieJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) - fun doSmartSelfieEnrollment(signature: String, timestamp: String, selfieImage: FlutterUploadImageInfo, livenessImages: List, userId: String, partnerParams: Map?, callbackUrl: String?, sandboxResult: Long?, allowNewEnroll: Boolean?, callback: (Result) -> Unit) - fun doSmartSelfieAuthentication(signature: String, timestamp: String, selfieImage: FlutterUploadImageInfo, livenessImages: List, userId: String, partnerParams: Map?, callbackUrl: String?, sandboxResult: Long?, callback: (Result) -> Unit) + fun doSmartSelfieEnrollment(signature: String, timestamp: String, selfieImage: String, livenessImages: List, userId: String, partnerParams: Map?, callbackUrl: String?, sandboxResult: Long?, allowNewEnroll: Boolean?, callback: (Result) -> Unit) + fun doSmartSelfieAuthentication(signature: String, timestamp: String, selfieImage: String, livenessImages: List, userId: String, partnerParams: Map?, callbackUrl: String?, sandboxResult: Long?, callback: (Result) -> Unit) fun getDocumentVerificationJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) fun getBiometricKycJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) fun getEnhancedDocumentVerificationJobStatus(request: FlutterJobStatusRequest, callback: (Result) -> Unit) @@ -2144,8 +2135,8 @@ interface SmileIDApi { val args = message as List val signatureArg = args[0] as String val timestampArg = args[1] as String - val selfieImageArg = args[2] as FlutterUploadImageInfo - val livenessImagesArg = args[3] as List + val selfieImageArg = args[2] as String + val livenessImagesArg = args[3] as List val userIdArg = args[4] as String val partnerParamsArg = args[5] as Map? val callbackUrlArg = args[6] as String? @@ -2172,8 +2163,8 @@ interface SmileIDApi { val args = message as List val signatureArg = args[0] as String val timestampArg = args[1] as String - val selfieImageArg = args[2] as FlutterUploadImageInfo - val livenessImagesArg = args[3] as List + val selfieImageArg = args[2] as String + val livenessImagesArg = args[3] as List val userIdArg = args[4] as String val partnerParamsArg = args[5] as Map? val callbackUrlArg = args[6] as String? diff --git a/ios/Classes/Mapper.swift b/ios/Classes/Mapper.swift index fb3da014..c1498146 100644 --- a/ios/Classes/Mapper.swift +++ b/ios/Classes/Mapper.swift @@ -11,6 +11,24 @@ func convertNullableMapToNonNull(data: [String? : String?]?) -> [String : String return convertedDictionary } +func getFile(atPath path: String) -> Data? { + // Create a URL from the provided path + let fileURL = URL(fileURLWithPath: path) + do { + // Check if the file exists + let fileExists = try fileURL.checkResourceIsReachable() + if fileExists { + // Read the contents of the file + let fileData = try Data(contentsOf: fileURL) + return fileData + } else { + return nil + } + } catch { + return nil + } +} + extension FlutterPartnerParams { func toRequest() -> PartnerParams { PartnerParams( @@ -150,11 +168,6 @@ extension FlutterUploadImageInfo { fileName: imageName ) } - func toMultiPartRequest() -> MultipartBody { - // do we need to expose a func that get's us a file here? - let dataUrl = try LocalStorage.getFileByType(jobId: <#T##String#>, fileType: imageTypeId.toRequest()) - MultipartBody(withImage: Data(contentsOf: dataUrl), forKey: imageName, forName: imageName) - } } extension FlutterImageType { diff --git a/ios/Classes/SmileIDMessages.g.swift b/ios/Classes/SmileIDMessages.g.swift index 8040f1cd..b6cdd5dd 100644 --- a/ios/Classes/SmileIDMessages.g.swift +++ b/ios/Classes/SmileIDMessages.g.swift @@ -1749,12 +1749,10 @@ private class SmileIDApiCodecReader: FlutterStandardReader { case 166: return FlutterUploadImageInfo.fromList(self.readValue() as! [Any?]) case 167: - return FlutterUploadImageInfo.fromList(self.readValue() as! [Any?]) - case 168: return FlutterUploadRequest.fromList(self.readValue() as! [Any?]) - case 169: + case 168: return FlutterValidDocument.fromList(self.readValue() as! [Any?]) - case 170: + case 169: return FlutterValidDocumentsResponse.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) @@ -1881,17 +1879,14 @@ private class SmileIDApiCodecWriter: FlutterStandardWriter { } else if let value = value as? FlutterUploadImageInfo { super.writeByte(166) super.writeValue(value.toList()) - } else if let value = value as? FlutterUploadImageInfo { - super.writeByte(167) - super.writeValue(value.toList()) } else if let value = value as? FlutterUploadRequest { - super.writeByte(168) + super.writeByte(167) super.writeValue(value.toList()) } else if let value = value as? FlutterValidDocument { - super.writeByte(169) + super.writeByte(168) super.writeValue(value.toList()) } else if let value = value as? FlutterValidDocumentsResponse { - super.writeByte(170) + super.writeByte(169) super.writeValue(value.toList()) } else { super.writeValue(value) @@ -1924,8 +1919,8 @@ protocol SmileIDApi { func doEnhancedKyc(request: FlutterEnhancedKycRequest, completion: @escaping (Result) -> Void) func doEnhancedKycAsync(request: FlutterEnhancedKycRequest, completion: @escaping (Result) -> Void) func getSmartSelfieJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) - func doSmartSelfieEnrollment(signature: String, timestamp: String, selfieImage: FlutterUploadImageInfo, livenessImages: [FlutterUploadImageInfo], userId: String, partnerParams: [String?: String?]?, callbackUrl: String?, sandboxResult: Int64?, allowNewEnroll: Bool?, completion: @escaping (Result) -> Void) - func doSmartSelfieAuthentication(signature: String, timestamp: String, selfieImage: FlutterUploadImageInfo, livenessImages: [FlutterUploadImageInfo], userId: String, partnerParams: [String?: String?]?, callbackUrl: String?, sandboxResult: Int64?, completion: @escaping (Result) -> Void) + func doSmartSelfieEnrollment(signature: String, timestamp: String, selfieImage: String, livenessImages: [String], userId: String, partnerParams: [String?: String?]?, callbackUrl: String?, sandboxResult: Int64?, allowNewEnroll: Bool?, completion: @escaping (Result) -> Void) + func doSmartSelfieAuthentication(signature: String, timestamp: String, selfieImage: String, livenessImages: [String], userId: String, partnerParams: [String?: String?]?, callbackUrl: String?, sandboxResult: Int64?, completion: @escaping (Result) -> Void) func getDocumentVerificationJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) func getBiometricKycJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) func getEnhancedDocumentVerificationJobStatus(request: FlutterJobStatusRequest, completion: @escaping (Result) -> Void) @@ -2096,8 +2091,8 @@ class SmileIDApiSetup { let args = message as! [Any?] let signatureArg = args[0] as! String let timestampArg = args[1] as! String - let selfieImageArg = args[2] as! FlutterUploadImageInfo - let livenessImagesArg = args[3] as! [FlutterUploadImageInfo] + let selfieImageArg = args[2] as! String + let livenessImagesArg = args[3] as! [String] let userIdArg = args[4] as! String let partnerParamsArg: [String?: String?]? = nilOrValue(args[5]) let callbackUrlArg: String? = nilOrValue(args[6]) @@ -2121,8 +2116,8 @@ class SmileIDApiSetup { let args = message as! [Any?] let signatureArg = args[0] as! String let timestampArg = args[1] as! String - let selfieImageArg = args[2] as! FlutterUploadImageInfo - let livenessImagesArg = args[3] as! [FlutterUploadImageInfo] + let selfieImageArg = args[2] as! String + let livenessImagesArg = args[3] as! [String] let userIdArg = args[4] as! String let partnerParamsArg: [String?: String?]? = nilOrValue(args[5]) let callbackUrlArg: String? = nilOrValue(args[6]) diff --git a/ios/Classes/SmileIDPlugin.swift b/ios/Classes/SmileIDPlugin.swift index f6b8f267..9ef15ab8 100644 --- a/ios/Classes/SmileIDPlugin.swift +++ b/ios/Classes/SmileIDPlugin.swift @@ -162,8 +162,8 @@ public class SmileIDPlugin: NSObject, FlutterPlugin, SmileIDApi { func doSmartSelfieEnrollment( signature: String, timestamp: String, - selfieImage: FlutterUploadImageInfo, - livenessImages: [FlutterUploadImageInfo], + selfieImage: String, + livenessImages: [String], userId: String, partnerParams: [String? : String?]?, callbackUrl: String?, @@ -174,8 +174,18 @@ public class SmileIDPlugin: NSObject, FlutterPlugin, SmileIDApi { SmileID.api.doSmartSelfieEnrollment( signature: signature, timestamp: timestamp, - selfieImage: selfieImage.toMultiPartRequest(), - livenessImages: livenessImages.map { $0.toMultiPartRequest() }, + selfieImage: MultipartBody( + withImage: getFile(atPath: selfieImage)!, + forKey: URL(fileURLWithPath: selfieImage).lastPathComponent, + forName: URL(fileURLWithPath: selfieImage).lastPathComponent + )!, + livenessImages: livenessImages.map { + MultipartBody( + withImage: getFile(atPath: $0)!, + forKey: URL(fileURLWithPath: $0).lastPathComponent, + forName: URL(fileURLWithPath: $0).lastPathComponent + )! + }, userId: userId, partnerParams: convertNullableMapToNonNull(data: partnerParams), callbackUrl: callbackUrl, @@ -197,8 +207,8 @@ public class SmileIDPlugin: NSObject, FlutterPlugin, SmileIDApi { func doSmartSelfieAuthentication( signature: String, timestamp: String, - selfieImage: FlutterUploadImageInfo, - livenessImages: [FlutterUploadImageInfo], + selfieImage: String, + livenessImages: [String], userId: String, partnerParams: [String? : String?]?, callbackUrl: String?, @@ -209,8 +219,18 @@ public class SmileIDPlugin: NSObject, FlutterPlugin, SmileIDApi { signature: signature, timestamp: timestamp, userId: userId, - selfieImage: selfieImage.toMultiPartRequest(), - livenessImages: livenessImages.map { $0.toMultiPartRequest() }, + selfieImage: MultipartBody( + withImage: getFile(atPath: selfieImage)!, + forKey: URL(fileURLWithPath: selfieImage).lastPathComponent, + forName: URL(fileURLWithPath: selfieImage).lastPathComponent + )!, + livenessImages: livenessImages.map { + MultipartBody( + withImage: getFile(atPath: $0)!, + forKey: URL(fileURLWithPath: $0).lastPathComponent, + forName: URL(fileURLWithPath: $0).lastPathComponent + )! + }, partnerParams: convertNullableMapToNonNull(data: partnerParams), callbackUrl: callbackUrl, sandboxResult: sandboxResult.map { Int($0) } diff --git a/lib/smile_id_service.dart b/lib/smile_id_service.dart index 25918a91..dbdfd4d0 100644 --- a/lib/smile_id_service.dart +++ b/lib/smile_id_service.dart @@ -56,8 +56,8 @@ class SmileIDService { Future doSmartSelfieEnrollment( String signature, String timestamp, - FlutterUploadImageInfo selfieImage, - List livenessImages, + String selfieImage, + List livenessImages, String userId, Map? partnerParams, String? callbackUrl, @@ -82,8 +82,8 @@ class SmileIDService { Future doSmartSelfieAuthentication( String signature, String timestamp, - FlutterUploadImageInfo selfieImage, - List livenessImages, + String selfieImage, + List livenessImages, String userId, Map? partnerParams, String? callbackUrl, diff --git a/lib/smileid_messages.g.dart b/lib/smileid_messages.g.dart index eccf9900..a01eccc1 100644 --- a/lib/smileid_messages.g.dart +++ b/lib/smileid_messages.g.dart @@ -2064,17 +2064,14 @@ class _SmileIDApiCodec extends StandardMessageCodec { } else if (value is FlutterUploadImageInfo) { buffer.putUint8(166); writeValue(buffer, value.encode()); - } else if (value is FlutterUploadImageInfo) { - buffer.putUint8(167); - writeValue(buffer, value.encode()); } else if (value is FlutterUploadRequest) { - buffer.putUint8(168); + buffer.putUint8(167); writeValue(buffer, value.encode()); } else if (value is FlutterValidDocument) { - buffer.putUint8(169); + buffer.putUint8(168); writeValue(buffer, value.encode()); } else if (value is FlutterValidDocumentsResponse) { - buffer.putUint8(170); + buffer.putUint8(169); writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); @@ -2163,12 +2160,10 @@ class _SmileIDApiCodec extends StandardMessageCodec { case 166: return FlutterUploadImageInfo.decode(readValue(buffer)!); case 167: - return FlutterUploadImageInfo.decode(readValue(buffer)!); - case 168: return FlutterUploadRequest.decode(readValue(buffer)!); - case 169: + case 168: return FlutterValidDocument.decode(readValue(buffer)!); - case 170: + case 169: return FlutterValidDocumentsResponse.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -2409,7 +2404,7 @@ class SmileIDApi { } } - Future doSmartSelfieEnrollment(String signature, String timestamp, FlutterUploadImageInfo selfieImage, List livenessImages, String userId, Map? partnerParams, String? callbackUrl, int? sandboxResult, bool? allowNewEnroll) async { + Future doSmartSelfieEnrollment(String signature, String timestamp, String selfieImage, List livenessImages, String userId, Map? partnerParams, String? callbackUrl, int? sandboxResult, bool? allowNewEnroll) async { const String __pigeon_channelName = 'dev.flutter.pigeon.smileid.SmileIDApi.doSmartSelfieEnrollment'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -2436,7 +2431,7 @@ class SmileIDApi { } } - Future doSmartSelfieAuthentication(String signature, String timestamp, FlutterUploadImageInfo selfieImage, List livenessImages, String userId, Map? partnerParams, String? callbackUrl, int? sandboxResult) async { + Future doSmartSelfieAuthentication(String signature, String timestamp, String selfieImage, List livenessImages, String userId, Map? partnerParams, String? callbackUrl, int? sandboxResult) async { const String __pigeon_channelName = 'dev.flutter.pigeon.smileid.SmileIDApi.doSmartSelfieAuthentication'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, diff --git a/pigeon/messages.dart b/pigeon/messages.dart index d7467d18..5fbb59e4 100644 --- a/pigeon/messages.dart +++ b/pigeon/messages.dart @@ -818,8 +818,8 @@ abstract class SmileIDApi { FlutterSmartSelfieResponse doSmartSelfieEnrollment( String signature, String timestamp, - FlutterUploadImageInfo selfieImage, - List livenessImages, + String selfieImage, + List livenessImages, String userId, Map? partnerParams, String? callbackUrl, @@ -831,8 +831,8 @@ abstract class SmileIDApi { FlutterSmartSelfieResponse doSmartSelfieAuthentication( String signature, String timestamp, - FlutterUploadImageInfo selfieImage, - List livenessImages, + String selfieImage, + List livenessImages, String userId, Map? partnerParams, String? callbackUrl, From f87f054ca540a87913fbb47f5a4fca6c776488d9 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 4 Jun 2024 14:22:12 +0300 Subject: [PATCH 12/24] updated pigeon and ktlint --- .github/workflows/build.yaml | 2 +- .../src/main/kotlin/com/smileidentity/flutter/Mapper.kt | 8 ++++---- .../smileidentity/flutter/generated/SmileIDMessages.g.kt | 4 ++-- lib/smileid_messages.g.dart | 4 ++-- pigeon/messages.dart | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 34b82ca9..90371720 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -40,7 +40,7 @@ jobs: - name: Lint Android uses: musichin/ktlint-check@v3 with: - ktlint-version: "0.49.1" + ktlint-version: "1.1.1" patterns: | **/**.kt !**/generated/** diff --git a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt index 38b71de2..560f1ee2 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt @@ -129,13 +129,13 @@ fun JobType.toResponse() = when (this) { } fun FlutterJobTypeV2.toRequest() = when (this) { - FlutterJobTypeV2.SMART_SELFIE_AUTHENTICATION -> JobTypeV2.SmartSelfieAuthentication - FlutterJobTypeV2.SMART_SELFIE_ENROLLMENT -> JobTypeV2.SmartSelfieEnrollment + FlutterJobTypeV2.SMARTSELFIEAUTHENTICATION -> JobTypeV2.SmartSelfieAuthentication + FlutterJobTypeV2.SMARTSELFIEENROLLMENT -> JobTypeV2.SmartSelfieEnrollment } fun JobTypeV2.toResponse() = when (this) { - JobTypeV2.SmartSelfieAuthentication -> FlutterJobTypeV2.SMART_SELFIE_AUTHENTICATION - JobTypeV2.SmartSelfieEnrollment -> FlutterJobTypeV2.SMART_SELFIE_ENROLLMENT + JobTypeV2.SmartSelfieAuthentication -> FlutterJobTypeV2.SMARTSELFIEAUTHENTICATION + JobTypeV2.SmartSelfieEnrollment -> FlutterJobTypeV2.SMARTSELFIEENROLLMENT else -> TODO("Not yet implemented") } diff --git a/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt b/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt index 2fb5c0be..20c357de 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/generated/SmileIDMessages.g.kt @@ -58,8 +58,8 @@ enum class FlutterJobType(val raw: Int) { } enum class FlutterJobTypeV2(val raw: Int) { - SMART_SELFIE_AUTHENTICATION(0), - SMART_SELFIE_ENROLLMENT(1); + SMARTSELFIEAUTHENTICATION(0), + SMARTSELFIEENROLLMENT(1); companion object { fun ofRaw(raw: Int): FlutterJobTypeV2? { diff --git a/lib/smileid_messages.g.dart b/lib/smileid_messages.g.dart index 8c818d25..1395bb7f 100644 --- a/lib/smileid_messages.g.dart +++ b/lib/smileid_messages.g.dart @@ -25,8 +25,8 @@ enum FlutterJobType { } enum FlutterJobTypeV2 { - smart_selfie_authentication, - smart_selfie_enrollment, + smartSelfieAuthentication, + smartSelfieEnrollment, } enum FlutterImageType { diff --git a/pigeon/messages.dart b/pigeon/messages.dart index 04304c6d..7a5340c9 100644 --- a/pigeon/messages.dart +++ b/pigeon/messages.dart @@ -20,7 +20,7 @@ enum FlutterJobType { smartSelfieAuthentication } -enum FlutterJobTypeV2 { smart_selfie_authentication, smart_selfie_enrollment } +enum FlutterJobTypeV2 { smartSelfieAuthentication, smartSelfieEnrollment } /// Custom values specific to partners can be placed in [extras] class FlutterPartnerParams { From bc96a2abebdd191a9922d8017e40fedd7dd9e7eb Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 4 Jun 2024 14:26:20 +0300 Subject: [PATCH 13/24] revert back ktlint update --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 90371720..34b82ca9 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -40,7 +40,7 @@ jobs: - name: Lint Android uses: musichin/ktlint-check@v3 with: - ktlint-version: "1.1.1" + ktlint-version: "0.49.1" patterns: | **/**.kt !**/generated/** From 50aa40f499577c4341c9e0ee6db8f7faac59ce89 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 4 Jun 2024 14:30:43 +0300 Subject: [PATCH 14/24] cleanup unused import --- .../src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt index 219790f9..0199efde 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt @@ -16,7 +16,6 @@ import FlutterProductsConfigResponse import FlutterServicesResponse import FlutterSmartSelfieJobStatusResponse import FlutterSmartSelfieResponse -import FlutterUploadImageInfo import FlutterUploadRequest import FlutterValidDocumentsResponse import SmileIDApi From a5af30b609447cbee65c43150e68f8226bfbe7ac Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 4 Jun 2024 14:37:13 +0300 Subject: [PATCH 15/24] lint android code --- .../src/main/kotlin/com/smileidentity/flutter/Mapper.kt | 4 ++-- .../smileidentity/flutter/SmileIDDocumentVerification.kt | 2 +- .../kotlin/com/smileidentity/flutter/SmileIDPlugin.kt | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt index 560f1ee2..afc43e43 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt @@ -71,7 +71,6 @@ import com.smileidentity.models.ImageType import com.smileidentity.models.JobResult import com.smileidentity.models.JobStatusRequest import com.smileidentity.models.JobType -import com.smileidentity.models.v2.JobType as JobTypeV2 import com.smileidentity.models.PartnerParams import com.smileidentity.models.PrepUploadRequest import com.smileidentity.models.PrepUploadResponse @@ -85,6 +84,7 @@ import com.smileidentity.models.UploadImageInfo import com.smileidentity.models.UploadRequest import com.smileidentity.models.ValidDocument import com.smileidentity.models.ValidDocumentsResponse +import com.smileidentity.models.v2.JobType as JobTypeV2 import com.smileidentity.models.v2.SmartSelfieResponse import com.smileidentity.models.v2.SmartSelfieStatus import java.io.File @@ -364,7 +364,7 @@ fun SmartSelfieResponse.toResponse() = FlutterSmartSelfieResponse( partnerParams = convertNonNullMapToNullable(partnerParams), status = status.toResponse(), updatedAt = updatedAt, - userId = userId + userId = userId, ) fun DocumentVerificationJobStatusResponse.toResponse() = diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt index ea502024..88e8ed26 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt @@ -11,8 +11,8 @@ import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.StandardMessageCodec import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformViewFactory -import kotlinx.collections.immutable.toImmutableMap import java.io.File +import kotlinx.collections.immutable.toImmutableMap internal class SmileIDDocumentVerification private constructor( context: Context, diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt index 0199efde..abb84147 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt @@ -31,6 +31,10 @@ import com.smileidentity.networking.pollSmartSelfieJobStatus import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding +import java.io.File +import java.net.URL +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -39,10 +43,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.single import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import java.io.File -import java.net.URL -import kotlin.time.Duration -import kotlin.time.Duration.Companion.milliseconds class SmileIDPlugin : FlutterPlugin, SmileIDApi, ActivityAware { private var activity: Activity? = null From 47309e754539ed4c8d089e56a55b184e1efddf05 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Thu, 6 Jun 2024 18:38:52 +0300 Subject: [PATCH 16/24] updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 442745ac..d162e596 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Document verification * Enhanced document verification * Added an Offline Mode, enabled by calling `SmileID.setAllowOfflineMode(true)`. If a job is attempted while the device is offline, and offline mode has been enabled, the UI will complete successfully and the job can be submitted at a later time by calling `SmileID.submitJob(jobId)` +* Improved SmartSelfie Enrollment and Authentication times by moving to a synchronous API endpoint ## 10.0.12 From 023f9e0ef85e8a12c9f74ddc42cf0afaf91b2ce5 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 11 Jun 2024 15:27:57 +0300 Subject: [PATCH 17/24] updated import ordering --- .../com/smileidentity/flutter/Mapper.kt | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt index afc43e43..d7887bf5 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt @@ -1,48 +1,6 @@ package com.smileidentity.flutter -import FlutterActionResult -import FlutterActions -import FlutterAntifraud -import FlutterAuthenticationRequest -import FlutterAuthenticationResponse -import FlutterAvailableIdType -import FlutterBankCode -import FlutterBiometricKycJobResult -import FlutterBiometricKycJobStatusResponse -import FlutterConsentInfo -import FlutterCountry -import FlutterCountryInfo -import FlutterDocumentVerificationJobResult -import FlutterDocumentVerificationJobStatusResponse -import FlutterEnhancedDocumentVerificationJobResult -import FlutterEnhancedDocumentVerificationJobStatusResponse -import FlutterEnhancedKycAsyncResponse -import FlutterEnhancedKycRequest -import FlutterEnhancedKycResponse -import FlutterHostedWeb -import FlutterIdInfo -import FlutterIdSelection -import FlutterIdType -import FlutterImageLinks -import FlutterImageType -import FlutterJobStatusRequest -import FlutterJobType -import FlutterJobTypeV2 -import FlutterPartnerParams -import FlutterPrepUploadRequest -import FlutterPrepUploadResponse -import FlutterProductsConfigRequest -import FlutterProductsConfigResponse -import FlutterServicesResponse -import FlutterSmartSelfieJobResult -import FlutterSmartSelfieJobStatusResponse -import FlutterSmartSelfieResponse -import FlutterSmartSelfieStatus -import FlutterSuspectUser -import FlutterUploadImageInfo -import FlutterUploadRequest -import FlutterValidDocument -import FlutterValidDocumentsResponse +import java.io.File import com.smileidentity.models.ActionResult import com.smileidentity.models.Actions import com.smileidentity.models.Antifraud @@ -87,7 +45,49 @@ import com.smileidentity.models.ValidDocumentsResponse import com.smileidentity.models.v2.JobType as JobTypeV2 import com.smileidentity.models.v2.SmartSelfieResponse import com.smileidentity.models.v2.SmartSelfieStatus -import java.io.File +import FlutterActionResult +import FlutterActions +import FlutterAntifraud +import FlutterAuthenticationRequest +import FlutterAuthenticationResponse +import FlutterAvailableIdType +import FlutterBankCode +import FlutterBiometricKycJobResult +import FlutterBiometricKycJobStatusResponse +import FlutterConsentInfo +import FlutterCountry +import FlutterCountryInfo +import FlutterDocumentVerificationJobResult +import FlutterDocumentVerificationJobStatusResponse +import FlutterEnhancedDocumentVerificationJobResult +import FlutterEnhancedDocumentVerificationJobStatusResponse +import FlutterEnhancedKycAsyncResponse +import FlutterEnhancedKycRequest +import FlutterEnhancedKycResponse +import FlutterHostedWeb +import FlutterIdInfo +import FlutterIdSelection +import FlutterIdType +import FlutterImageLinks +import FlutterImageType +import FlutterJobStatusRequest +import FlutterJobType +import FlutterJobTypeV2 +import FlutterPartnerParams +import FlutterPrepUploadRequest +import FlutterPrepUploadResponse +import FlutterProductsConfigRequest +import FlutterProductsConfigResponse +import FlutterServicesResponse +import FlutterSmartSelfieJobResult +import FlutterSmartSelfieJobStatusResponse +import FlutterSmartSelfieResponse +import FlutterSmartSelfieStatus +import FlutterSuspectUser +import FlutterUploadImageInfo +import FlutterUploadRequest +import FlutterValidDocument +import FlutterValidDocumentsResponse /** * Pigeon does not allow non nullable types in this example here From 1cabbc1d28b43daa4cd314b8d3e96f6abfd02623 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 11 Jun 2024 15:39:52 +0300 Subject: [PATCH 18/24] updated ktlint --- .github/workflows/build.yaml | 7 +- .../com/smileidentity/flutter/Mapper.kt | 88 +++++++++---------- 2 files changed, 50 insertions(+), 45 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 34b82ca9..dc604b73 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -40,7 +40,12 @@ jobs: - name: Lint Android uses: musichin/ktlint-check@v3 with: - ktlint-version: "0.49.1" + ktlint-version: "1.1.1" + code-style: android_studio + relative: true + reporter: | + plain,output=ktlint_report.txt + json,output=ktlint_report.json patterns: | **/**.kt !**/generated/** diff --git a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt index d7887bf5..afc43e43 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt @@ -1,6 +1,48 @@ package com.smileidentity.flutter -import java.io.File +import FlutterActionResult +import FlutterActions +import FlutterAntifraud +import FlutterAuthenticationRequest +import FlutterAuthenticationResponse +import FlutterAvailableIdType +import FlutterBankCode +import FlutterBiometricKycJobResult +import FlutterBiometricKycJobStatusResponse +import FlutterConsentInfo +import FlutterCountry +import FlutterCountryInfo +import FlutterDocumentVerificationJobResult +import FlutterDocumentVerificationJobStatusResponse +import FlutterEnhancedDocumentVerificationJobResult +import FlutterEnhancedDocumentVerificationJobStatusResponse +import FlutterEnhancedKycAsyncResponse +import FlutterEnhancedKycRequest +import FlutterEnhancedKycResponse +import FlutterHostedWeb +import FlutterIdInfo +import FlutterIdSelection +import FlutterIdType +import FlutterImageLinks +import FlutterImageType +import FlutterJobStatusRequest +import FlutterJobType +import FlutterJobTypeV2 +import FlutterPartnerParams +import FlutterPrepUploadRequest +import FlutterPrepUploadResponse +import FlutterProductsConfigRequest +import FlutterProductsConfigResponse +import FlutterServicesResponse +import FlutterSmartSelfieJobResult +import FlutterSmartSelfieJobStatusResponse +import FlutterSmartSelfieResponse +import FlutterSmartSelfieStatus +import FlutterSuspectUser +import FlutterUploadImageInfo +import FlutterUploadRequest +import FlutterValidDocument +import FlutterValidDocumentsResponse import com.smileidentity.models.ActionResult import com.smileidentity.models.Actions import com.smileidentity.models.Antifraud @@ -45,49 +87,7 @@ import com.smileidentity.models.ValidDocumentsResponse import com.smileidentity.models.v2.JobType as JobTypeV2 import com.smileidentity.models.v2.SmartSelfieResponse import com.smileidentity.models.v2.SmartSelfieStatus -import FlutterActionResult -import FlutterActions -import FlutterAntifraud -import FlutterAuthenticationRequest -import FlutterAuthenticationResponse -import FlutterAvailableIdType -import FlutterBankCode -import FlutterBiometricKycJobResult -import FlutterBiometricKycJobStatusResponse -import FlutterConsentInfo -import FlutterCountry -import FlutterCountryInfo -import FlutterDocumentVerificationJobResult -import FlutterDocumentVerificationJobStatusResponse -import FlutterEnhancedDocumentVerificationJobResult -import FlutterEnhancedDocumentVerificationJobStatusResponse -import FlutterEnhancedKycAsyncResponse -import FlutterEnhancedKycRequest -import FlutterEnhancedKycResponse -import FlutterHostedWeb -import FlutterIdInfo -import FlutterIdSelection -import FlutterIdType -import FlutterImageLinks -import FlutterImageType -import FlutterJobStatusRequest -import FlutterJobType -import FlutterJobTypeV2 -import FlutterPartnerParams -import FlutterPrepUploadRequest -import FlutterPrepUploadResponse -import FlutterProductsConfigRequest -import FlutterProductsConfigResponse -import FlutterServicesResponse -import FlutterSmartSelfieJobResult -import FlutterSmartSelfieJobStatusResponse -import FlutterSmartSelfieResponse -import FlutterSmartSelfieStatus -import FlutterSuspectUser -import FlutterUploadImageInfo -import FlutterUploadRequest -import FlutterValidDocument -import FlutterValidDocumentsResponse +import java.io.File /** * Pigeon does not allow non nullable types in this example here From fc45b8f83672f2c50487fddc63141b76e5bbe0c0 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 11 Jun 2024 15:43:52 +0300 Subject: [PATCH 19/24] updated ktlint --- .github/workflows/build.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index dc604b73..87e5ea2a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -39,6 +39,7 @@ jobs: run: flutter pub get && cd example && flutter pub get && cd .. - name: Lint Android uses: musichin/ktlint-check@v3 + continue-on-error: true with: ktlint-version: "1.1.1" code-style: android_studio From 95530b607b344d36ae33f7b998f62c906cb06255 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 11 Jun 2024 15:56:38 +0300 Subject: [PATCH 20/24] fixed ktlint warnings --- .github/workflows/build.yaml | 8 +------- .../smileidentity/flutter/SmileIDDocumentVerification.kt | 2 +- .../kotlin/com/smileidentity/flutter/SmileIDPluginTest.kt | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 87e5ea2a..34b82ca9 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -39,14 +39,8 @@ jobs: run: flutter pub get && cd example && flutter pub get && cd .. - name: Lint Android uses: musichin/ktlint-check@v3 - continue-on-error: true with: - ktlint-version: "1.1.1" - code-style: android_studio - relative: true - reporter: | - plain,output=ktlint_report.txt - json,output=ktlint_report.json + ktlint-version: "0.49.1" patterns: | **/**.kt !**/generated/** diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt index 88e8ed26..5f7b1288 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt @@ -1,5 +1,6 @@ package com.smileidentity.flutter +import java.io.File import android.content.Context import androidx.compose.runtime.Composable import com.smileidentity.SmileID @@ -11,7 +12,6 @@ import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.StandardMessageCodec import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformViewFactory -import java.io.File import kotlinx.collections.immutable.toImmutableMap internal class SmileIDDocumentVerification private constructor( diff --git a/android/src/test/kotlin/com/smileidentity/flutter/SmileIDPluginTest.kt b/android/src/test/kotlin/com/smileidentity/flutter/SmileIDPluginTest.kt index 33335ad1..845de642 100644 --- a/android/src/test/kotlin/com/smileidentity/flutter/SmileIDPluginTest.kt +++ b/android/src/test/kotlin/com/smileidentity/flutter/SmileIDPluginTest.kt @@ -19,7 +19,6 @@ import kotlin.test.Test * you can run them directly from IDEs that support JUnit such as Android Studio. */ internal class SmileIDPluginTest { - @Test fun `when we call authenticate and pass a request object, we get a successful callback`() { val request = mockk() From 978a01358a7ff11a23d4e449a2e524f474ec01a8 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 11 Jun 2024 16:03:22 +0300 Subject: [PATCH 21/24] test ktlint fix --- .../com/smileidentity/flutter/SmileIDDocumentVerification.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt index 5f7b1288..485bf2aa 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt @@ -1,19 +1,24 @@ package com.smileidentity.flutter import java.io.File + import android.content.Context import androidx.compose.runtime.Composable + import com.smileidentity.SmileID import com.smileidentity.compose.DocumentVerification import com.smileidentity.results.SmileIDResult import com.smileidentity.util.randomJobId import com.smileidentity.util.randomUserId + import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.StandardMessageCodec import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformViewFactory + import kotlinx.collections.immutable.toImmutableMap + internal class SmileIDDocumentVerification private constructor( context: Context, viewId: Int, From cd6333481272aa0ef205b9c526a6c5fbabb1c12a Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 11 Jun 2024 16:06:03 +0300 Subject: [PATCH 22/24] updated ktlint config --- .editorconfig | 1 + .../src/main/kotlin/com/smileidentity/flutter/Mapper.kt | 2 +- .../smileidentity/flutter/SmileIDDocumentVerification.kt | 7 +------ .../kotlin/com/smileidentity/flutter/SmileIDPlugin.kt | 8 ++++---- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.editorconfig b/.editorconfig index 765c4cec..df8aef05 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,5 +2,6 @@ max_line_length=100 [{*.kt,*.kts}] +ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ ij_kotlin_allow_trailing_comma_on_call_site=true ij_kotlin_allow_trailing_comma=true \ No newline at end of file diff --git a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt index afc43e43..a7ccc14f 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/Mapper.kt @@ -84,10 +84,10 @@ import com.smileidentity.models.UploadImageInfo import com.smileidentity.models.UploadRequest import com.smileidentity.models.ValidDocument import com.smileidentity.models.ValidDocumentsResponse -import com.smileidentity.models.v2.JobType as JobTypeV2 import com.smileidentity.models.v2.SmartSelfieResponse import com.smileidentity.models.v2.SmartSelfieStatus import java.io.File +import com.smileidentity.models.v2.JobType as JobTypeV2 /** * Pigeon does not allow non nullable types in this example here diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt index 485bf2aa..ea502024 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt @@ -1,23 +1,18 @@ package com.smileidentity.flutter -import java.io.File - import android.content.Context import androidx.compose.runtime.Composable - import com.smileidentity.SmileID import com.smileidentity.compose.DocumentVerification import com.smileidentity.results.SmileIDResult import com.smileidentity.util.randomJobId import com.smileidentity.util.randomUserId - import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.StandardMessageCodec import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformViewFactory - import kotlinx.collections.immutable.toImmutableMap - +import java.io.File internal class SmileIDDocumentVerification private constructor( context: Context, diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt index abb84147..0199efde 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt @@ -31,10 +31,6 @@ import com.smileidentity.networking.pollSmartSelfieJobStatus import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding -import java.io.File -import java.net.URL -import kotlin.time.Duration -import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -43,6 +39,10 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.single import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import java.io.File +import java.net.URL +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds class SmileIDPlugin : FlutterPlugin, SmileIDApi, ActivityAware { private var activity: Activity? = null From 079bef48e51cd464fd46ad845ae8106e01deddac Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 11 Jun 2024 16:18:09 +0300 Subject: [PATCH 23/24] bump up ktlint version --- .github/workflows/build.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 34b82ca9..a95fe54c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -40,7 +40,8 @@ jobs: - name: Lint Android uses: musichin/ktlint-check@v3 with: - ktlint-version: "0.49.1" + ktlint-version: "1.1.1" + code-style: android_studio patterns: | **/**.kt !**/generated/** From 88c57412b39ba3e2f0e18b2a96b4c0f3a24aa8d5 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Tue, 11 Jun 2024 16:33:20 +0300 Subject: [PATCH 24/24] revert back ktlint version --- .github/workflows/build.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a95fe54c..34b82ca9 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -40,8 +40,7 @@ jobs: - name: Lint Android uses: musichin/ktlint-check@v3 with: - ktlint-version: "1.1.1" - code-style: android_studio + ktlint-version: "0.49.1" patterns: | **/**.kt !**/generated/**