Skip to content

Commit

Permalink
[S-8952] Biometric KYC Models (#92)
Browse files Browse the repository at this point in the history
* Biometric KYC Models

* Update

* Add Consent Info
  • Loading branch information
vanshg authored Jun 6, 2023
1 parent b5bab73 commit 3b93688
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 5 deletions.
40 changes: 40 additions & 0 deletions lib/src/main/java/com/smileidentity/compose/SmileIDExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import com.smileidentity.compose.document.OrchestratedDocumentCaptureScreen
import com.smileidentity.compose.theme.colorScheme
import com.smileidentity.compose.theme.typography
import com.smileidentity.models.Document
import com.smileidentity.models.IdInfo
import com.smileidentity.randomJobId
import com.smileidentity.randomUserId
import com.smileidentity.results.BiometricKycResult
import com.smileidentity.results.DocumentVerificationResult
import com.smileidentity.results.SmartSelfieResult
import com.smileidentity.results.SmileIDCallback
Expand Down Expand Up @@ -157,3 +159,41 @@ fun SmileID.DocumentVerification(
)
}
}

/**
* Perform a Biometric KYC: Verify the ID information of your user and confirm that the ID actually
* belongs to the user. This is achieved by comparing the user's SmartSelfie™ to the user's photo in
* an ID authority database
*
* [Docs](https://docs.smileidentity.com/products/for-individuals-kyc/biometric-kyc)
*
* @param userId The user ID to associate with the Biometric KYC. Most often, this will correspond
* to a unique User ID within your own system. If not provided, a random user ID will be generated
* @param jobId The job ID to associate with the Biometric KYC. Most often, this will correspond
* to a unique Job ID within your own system. If not provided, a random job ID will be generated
* @param idInfo The ID information to look up in the ID Authority
* @param allowAgentMode Whether to allow Agent Mode or not. If allowed, a switch will be displayed
* allowing toggling between the back camera and front camera. If not allowed, only the front
* camera will be used.
* @param showAttribution Whether to show the Smile ID attribution or not on the Instructions screen
* @param colorScheme The color scheme to use for the UI. This is passed in so that we show a Smile
* ID branded UI by default, but allow the user to override it if they want.
* @param typography The typography to use for the UI. This is passed in so that we show a Smile ID
* branded UI by default, but allow the user to override it if they want.
* @param onResult Callback to be invoked when the Biometric KYC is complete.
*/
@Composable
fun SmileID.BiometricKYC(
userId: String = rememberSaveable { randomUserId() },
jobId: String = rememberSaveable { randomJobId() },
idInfo: IdInfo,
allowAgentMode: Boolean = false,
showAttribution: Boolean = true,
colorScheme: ColorScheme = SmileID.colorScheme,
typography: Typography = SmileID.typography,
onResult: SmileIDCallback<BiometricKycResult> = {},
) {
MaterialTheme(colorScheme = colorScheme, typography = typography) {
TODO("Orchestrated Biometric KYC Screen")
}
}
38 changes: 37 additions & 1 deletion lib/src/main/java/com/smileidentity/models/Authentication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,41 @@ package com.smileidentity.models

import android.os.Parcelable
import com.smileidentity.SmileID
import com.smileidentity.models.JobType.SmartSelfieEnrollment
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.parcelize.Parcelize

/**
* The Auth Smile request. Auth Smile serves multiple purposes:
* - It is used to fetch the signature needed for subsequent API requests
* - It indicates the type of job that will being performed
* - It is used to fetch consent information for the partner
*
* @param jobType The type of job that will be performed
* @param enrollment Whether or not this is an enrollment job
* @param country The country code of the country where the job is being performed. This value is
* required in order to get back consent information for the partner
* @param idType The type of ID that will be used for the job. This value is required in order to
* get back consent information for the partner
* @param updateEnrolledImage Whether or not the enrolled image should be updated with image
* submitted for this job
* @param jobId The job ID to associate with the job. Most often, this will correspond to a unique
* Job ID within your own system. If not provided, a random job ID will be generated
* @param userId The user ID to associate with the job. Most often, this will correspond to a unique
* User ID within your own system. If not provided, a random user ID will be generated
* @param signature Whether or not to fetch the signature for the job
* @param production Whether or not to use the production environment
* @param partnerId The partner ID
* @param authToken The auth token from smile_config.json
*/
@Parcelize
@JsonClass(generateAdapter = true)
data class AuthenticationRequest(
@Json(name = "job_type") val jobType: JobType,
@Json(name = "enrollment") val enrollment: Boolean,
@Json(name = "enrollment") val enrollment: Boolean = jobType == SmartSelfieEnrollment,
@Json(name = "country") val country: String? = null,
@Json(name = "id_type") val idType: String? = null,
@Json(name = "update_enrolled_image") val updateEnrolledImage: Boolean? = null,
@Json(name = "job_id") val jobId: String? = null,
@Json(name = "user_id") val userId: String? = null,
Expand All @@ -27,4 +53,14 @@ data class AuthenticationResponse(
@Json(name = "signature") val signature: String,
@Json(name = "timestamp") val timestamp: String,
@Json(name = "partner_params") val partnerParams: PartnerParams,
@Json(name = "consent_info") val consentInfo: ConsentInfo? = null,
) : Parcelable

@Parcelize
@JsonClass(generateAdapter = true)
data class ConsentInfo(
@Json(name = "can_access") val canAccess: Boolean,
@Json(name = "consent_required") val consentRequired: Boolean,
) : Parcelable {
fun isRequired(): Boolean = canAccess && consentRequired
}
1 change: 1 addition & 0 deletions lib/src/main/java/com/smileidentity/models/Models.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ data class PartnerParams(
) : Parcelable

enum class JobType(val value: Int) {
BiometricKyc(1),
SmartSelfieAuthentication(2),
SmartSelfieEnrollment(4),
EnhancedKyc(5),
Expand Down
17 changes: 17 additions & 0 deletions lib/src/main/java/com/smileidentity/models/Upload.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,27 @@ data class UploadImageInfo(
@Json(name = "file_name") val image: File,
)

/**
* @param country The 2 letter country code of the user's ID (ISO 3166-1 alpha-2 format)
* @param idType The ID type from the list [here](https://docs.smileidentity.com/supported-id-types/for-individuals-kyc/backed-by-id-authority)
* @param idNumber The ID number of the user's ID
* @param firstName The first name of the user
* @param middleName The middle name of the user
* @param lastName The last name of the user
* @param dob The date of birth of the user in the **ID type specific format**
* @param entered Whether to submit the verification to the ID authority or not. For Biometric KYC
* jobs, this should be set to true
*/
@JsonClass(generateAdapter = true)
data class IdInfo(
@Json(name = "country") val country: String,
@Json(name = "id_type") val idType: String,
@Json(name = "id_number") val idNumber: String? = null,
@Json(name = "first_name") val firstName: String? = null,
@Json(name = "middle_name") val middleName: String? = null,
@Json(name = "last_name") val lastName: String? = null,
@Json(name = "dob") val dob: String? = null,
@Json(name = "entered") val entered: Boolean? = null,
)

enum class ImageType {
Expand Down
22 changes: 18 additions & 4 deletions lib/src/main/java/com/smileidentity/results/SmileIDResult.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import java.io.File
* This callback is only consumed from Kotlin code, so typealias is fine. Java code will use the
* Fragment compatibility layer (e.g. [com.smileidentity.fragment.SmartSelfieRegistrationFragment]),
* in which the result is delivered via the Fragment Result API. Our Fragment compatibility layer
* is written in Kotlin
* is written in Kotlin.
*/
typealias SmileIDCallback<T> = (SmileIDResult<T>) -> Unit

Expand All @@ -29,7 +29,7 @@ sealed interface SmileIDResult<out T : Parcelable> : Parcelable {
* NB! The Job itself may or may not be complete yet. This can be checked with
* [com.smileidentity.models.JobStatusResponse.jobComplete]. If not yet complete, the job status
* will need to be fetched again later. If the job is complete, the final job success can be
* checked with [com.smileidentity.models.JobStatusResponse.jobSuccess]
* checked with [com.smileidentity.models.JobStatusResponse.jobSuccess].
*/
@Parcelize
data class Success<T : Parcelable>(val data: T) : SmileIDResult<T>
Expand All @@ -47,7 +47,7 @@ sealed interface SmileIDResult<out T : Parcelable> : Parcelable {
* capture and network requests were successful. The Job itself may or may not be complete yet. This
* can be checked with [JobStatusResponse.jobComplete]. If not yet complete, the job status will
* need to be fetched again later. If the job is complete, the final job success can be checked with
* [JobStatusResponse.jobSuccess]
* [JobStatusResponse.jobSuccess].
*/
@Parcelize
data class SmartSelfieResult(
Expand All @@ -70,7 +70,7 @@ data class EnhancedKycResult(
* the capture and network requests were successful. The Job itself may or may not be complete yet.
* This can be checked with [DocVJobStatusResponse.jobComplete]. If not yet complete, the job status
* will need to be fetched again later. If the job is complete, the final job success can be checked
* with [DocVJobStatusResponse.jobSuccess]
* with [DocVJobStatusResponse.jobSuccess].
*/
@Parcelize
data class DocumentVerificationResult(
Expand All @@ -79,3 +79,17 @@ data class DocumentVerificationResult(
val documentBackFile: File? = null,
val jobStatusResponse: DocVJobStatusResponse,
) : Parcelable

/**
* The result of a Biometric KYC capture and submission to the Smile ID API. Indicates that the
* capture and network requests were successful. The Job itself may or may not be complete yet. This
* can be checked with [JobStatusResponse.jobComplete]. If not yet complete, the job status will
* need to be fetched again later. If the job is complete, the final job success can be checked with
* [JobStatusResponse.jobSuccess].
*/
@Parcelize
data class BiometricKycResult(
val selfieFile: File,
val livenessFiles: List<File>,
val jobStatusResponse: JobStatusResponse,
) : Parcelable

0 comments on commit 3b93688

Please sign in to comment.