Skip to content

Commit

Permalink
[Android][iOS] Verification reporting log (#55)
Browse files Browse the repository at this point in the history
This adds verification logs that can be stored, displayed, and exported.
  • Loading branch information
Juliano1612 authored Nov 27, 2024
1 parent e541af6 commit d0f9757
Show file tree
Hide file tree
Showing 26 changed files with 1,006 additions and 361 deletions.
16 changes: 14 additions & 2 deletions example/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INTERNET" />


<application
Expand Down Expand Up @@ -44,21 +44,33 @@
<intent-filter>
<!-- Intent action and categories -->
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Deep link data -->
<data android:scheme="spruceid" />
<data android:scheme="openid4vp" />
</intent-filter>
</activity>

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data android:name="app.rive.runtime.kotlin.RiveInitializer"
<meta-data
android:name="app.rive.runtime.kotlin.RiveInitializer"
android:value="androidx.startup" />
</provider>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.spruceid.mobilesdkexample.db.AppDatabase
import com.spruceid.mobilesdkexample.db.VerificationActivityLogsRepository
import com.spruceid.mobilesdkexample.db.VerificationMethodsRepository
import com.spruceid.mobilesdkexample.navigation.Screen
import com.spruceid.mobilesdkexample.navigation.SetupNavGraph
import com.spruceid.mobilesdkexample.ui.theme.ColorBase1
import com.spruceid.mobilesdkexample.ui.theme.MobileSdkTheme
import com.spruceid.mobilesdkexample.viewmodels.CredentialPacksViewModel
import com.spruceid.mobilesdkexample.viewmodels.CredentialPacksViewModelFactory
import com.spruceid.mobilesdkexample.viewmodels.HelpersViewModel
import com.spruceid.mobilesdkexample.viewmodels.VerificationActivityLogsViewModel
import com.spruceid.mobilesdkexample.viewmodels.VerificationActivityLogsViewModelFactory
import com.spruceid.mobilesdkexample.viewmodels.VerificationMethodsViewModel
import com.spruceid.mobilesdkexample.viewmodels.VerificationMethodsViewModelFactory

Expand Down Expand Up @@ -71,14 +75,22 @@ class MainActivity : ComponentActivity() {
VerificationMethodsViewModelFactory((application as MainApplication).verificationMethodsRepository)
}

val verificationActivityLogsViewModel: VerificationActivityLogsViewModel by viewModels {
VerificationActivityLogsViewModelFactory((application as MainApplication).verificationActivityLogsRepository)
}

val credentialPacksViewModel: CredentialPacksViewModel by viewModels {
CredentialPacksViewModelFactory(application as MainApplication)
}

val helpersViewModel: HelpersViewModel by viewModels<HelpersViewModel>()

SetupNavGraph(
navController,
verificationMethodsViewModel = verificationMethodsViewModel,
credentialPacksViewModel = credentialPacksViewModel
verificationActivityLogsViewModel = verificationActivityLogsViewModel,
credentialPacksViewModel = credentialPacksViewModel,
helpersViewModel = helpersViewModel
)
}
}
Expand All @@ -92,4 +104,5 @@ class MainApplication : Application() {
// val rawCredentialsRepository by lazy { RawCredentialsRepository(db.rawCredentialsDao()) }

val verificationMethodsRepository by lazy { VerificationMethodsRepository(db.verificationMethodsDao()) }
val verificationActivityLogsRepository by lazy { VerificationActivityLogsRepository(db.verificationActivityLogsDao()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase
RawCredentials::class,
VerificationMethods::class
],
version = 3
version = 4
)
@TypeConverters(*[DateConverter::class])
abstract class AppDatabase : RoomDatabase() {
Expand All @@ -35,6 +35,7 @@ abstract class AppDatabase : RoomDatabase() {
"referenceAppDb",
)
.addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.allowMainThreadQueries()
.build()
dbInstance = instance
Expand All @@ -46,13 +47,30 @@ abstract class AppDatabase : RoomDatabase() {

val MIGRATION_2_3 = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE `verification_methods` (" +
"`id` INTEGER NOT NULL, " +
"`type` TEXT NOT NULL, " +
"`name` TEXT NOT NULL, " +
"`description` TEXT NOT NULL, " +
"`verifierName` TEXT NOT NULL, " +
"`url` TEXT NOT NULL, " +
"PRIMARY KEY(`id`))")
database.execSQL(
"CREATE TABLE `verification_methods` (" +
"`id` INTEGER NOT NULL, " +
"`type` TEXT NOT NULL, " +
"`name` TEXT NOT NULL, " +
"`description` TEXT NOT NULL, " +
"`verifierName` TEXT NOT NULL, " +
"`url` TEXT NOT NULL, " +
"PRIMARY KEY(`id`))"
)
}
}

val MIGRATION_3_4 = object : Migration(3, 4) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE verification_activity_logs")
database.execSQL(
"CREATE TABLE `verification_activity_logs` (" +
"`id` INTEGER NOT NULL, " +
"`credentialTitle` TEXT NOT NULL, " +
"`issuer` TEXT NOT NULL, " +
"`verificationDateTime` INTEGER NOT NULL, " +
"`additionalInformation` TEXT NOT NULL, " +
"PRIMARY KEY(`id`))"
)
}
}
12 changes: 11 additions & 1 deletion example/src/main/java/com/spruceid/mobilesdkexample/db/Daos.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,18 @@ interface VerificationActivityLogsDao {
@Insert
suspend fun insertVerificationActivity(verificationActivityLogs: VerificationActivityLogs)

@Query("SELECT * FROM verification_activity_logs")
@Query("SELECT * FROM verification_activity_logs ORDER BY verificationDateTime DESC")
fun getAllVerificationActivityLogs(): List<VerificationActivityLogs>

@Query(
"SELECT * FROM verification_activity_logs " +
"WHERE verificationDateTime > :fromDate " +
"ORDER BY verificationDateTime DESC"
)
fun getFilteredVerificationActivityLogs(fromDate: Long): List<VerificationActivityLogs>

@Query("SELECT DISTINCT credentialTitle FROM verification_activity_logs")
fun getDistinctCredentialTitles(): List<String>
}

@Dao
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ import java.sql.Date
@Entity(tableName = "verification_activity_logs")
data class VerificationActivityLogs(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val name: String,
val credentialTitle: String,
val date: Date,
val expirationDate: Date,
val status: String,
val issuer: String,
val verificationDateTime: Date,
val additionalInformation: String,
)

@Entity(tableName = "raw_credentials")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.spruceid.mobilesdkexample.db

import androidx.annotation.WorkerThread
import java.sql.Date

class VerificationActivityLogsRepository(private val verificationActivityLogsDao: VerificationActivityLogsDao) {
val verificationActivityLogs: List<VerificationActivityLogs> =
Expand All @@ -15,6 +16,19 @@ class VerificationActivityLogsRepository(private val verificationActivityLogsDao
suspend fun getVerificationActivityLogs(): List<VerificationActivityLogs> {
return verificationActivityLogsDao.getAllVerificationActivityLogs()
}

// TODO: Add fromDate and credentialType filter params
@WorkerThread
fun getFilteredVerificationActivityLogs(): List<VerificationActivityLogs> {
return verificationActivityLogsDao.getFilteredVerificationActivityLogs(
fromDate = Date(Long.MIN_VALUE).time
)
}

@WorkerThread
fun getDistinctCredentialTitles(): List<String> {
return verificationActivityLogsDao.getDistinctCredentialTitles()
}
}

class RawCredentialsRepository(private val rawCredentialsDao: RawCredentialsDao) {
Expand Down Expand Up @@ -42,7 +56,8 @@ class RawCredentialsRepository(private val rawCredentialsDao: RawCredentialsDao)
}

class VerificationMethodsRepository(private val verificationMethodsDao: VerificationMethodsDao) {
val verificationMethods: List<VerificationMethods> = verificationMethodsDao.getAllVerificationMethods()
val verificationMethods: List<VerificationMethods> =
verificationMethodsDao.getAllVerificationMethods()

@WorkerThread
suspend fun insertVerificationMethod(verificationMethod: VerificationMethods) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const val VERIFY_VC_PATH = "verify_vc"
const val VERIFY_MDOC_PATH = "verify_mdoc"
const val VERIFY_DELEGATED_OID4VP_PATH = "verify_delegated_oid4vp/{id}"
const val VERIFIER_SETTINGS_HOME_PATH = "verifier_settings_home"
const val VERIFIER_SETTINGS_ACTIVITY_LOG = "verifier_settings_activity_log"
const val ADD_VERIFICATION_METHOD_PATH = "add_verification_method"
const val WALLET_SETTINGS_HOME_PATH = "wallet_settings_home"
const val ADD_TO_WALLET_PATH = "add_to_wallet/{rawCredential}"
Expand All @@ -22,6 +23,7 @@ sealed class Screen(val route: String) {
object VerifyMDocScreen : Screen(VERIFY_MDOC_PATH)
object VerifyDelegatedOid4vpScreen : Screen(VERIFY_DELEGATED_OID4VP_PATH)
object VerifierSettingsHomeScreen : Screen(VERIFIER_SETTINGS_HOME_PATH)
object VerifierSettingsActivityLogScreen : Screen(VERIFIER_SETTINGS_ACTIVITY_LOG)
object AddVerificationMethodScreen : Screen(ADD_VERIFICATION_METHOD_PATH)
object WalletSettingsHomeScreen : Screen(WALLET_SETTINGS_HOME_PATH)
object AddToWalletScreen : Screen(ADD_TO_WALLET_PATH)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ import com.spruceid.mobilesdkexample.verifier.VerifyDelegatedOid4vpView
import com.spruceid.mobilesdkexample.verifier.VerifyEAView
import com.spruceid.mobilesdkexample.verifier.VerifyMDocView
import com.spruceid.mobilesdkexample.verifier.VerifyVCView
import com.spruceid.mobilesdkexample.verifiersettings.VerifierSettingsActivityLogScreen
import com.spruceid.mobilesdkexample.verifiersettings.VerifierSettingsHomeView
import com.spruceid.mobilesdkexample.viewmodels.CredentialPacksViewModel
import com.spruceid.mobilesdkexample.viewmodels.HelpersViewModel
import com.spruceid.mobilesdkexample.viewmodels.VerificationActivityLogsViewModel
import com.spruceid.mobilesdkexample.viewmodels.VerificationMethodsViewModel
import com.spruceid.mobilesdkexample.wallet.DispatchQRView
import com.spruceid.mobilesdkexample.wallet.HandleOID4VCIView
Expand All @@ -27,7 +30,9 @@ import com.spruceid.mobilesdkexample.walletsettings.WalletSettingsHomeView
fun SetupNavGraph(
navController: NavHostController,
verificationMethodsViewModel: VerificationMethodsViewModel,
credentialPacksViewModel: CredentialPacksViewModel
verificationActivityLogsViewModel: VerificationActivityLogsViewModel,
credentialPacksViewModel: CredentialPacksViewModel,
helpersViewModel: HelpersViewModel
) {
NavHost(navController = navController, startDestination = Screen.HomeScreen.route) {
composable(
Expand All @@ -48,24 +53,42 @@ fun SetupNavGraph(
}
composable(
route = Screen.VerifyDLScreen.route,
) { VerifyDLView(navController) }
) {
VerifyDLView(
navController,
verificationActivityLogsViewModel = verificationActivityLogsViewModel
)
}
composable(
route = Screen.VerifyEAScreen.route,
) { VerifyEAView(navController) }
) {
VerifyEAView(
navController,
verificationActivityLogsViewModel = verificationActivityLogsViewModel
)
}
composable(
route = Screen.VerifyVCScreen.route,
) { VerifyVCView(navController) }
) {
VerifyVCView(navController)
}
composable(
route = Screen.VerifyMDocScreen.route,
) { VerifyMDocView(navController) }
) {
VerifyMDocView(
navController,
verificationActivityLogsViewModel = verificationActivityLogsViewModel
)
}
composable(
route = Screen.VerifyDelegatedOid4vpScreen.route,
) { backStackEntry ->
val id = backStackEntry.arguments?.getString("id")!!
VerifyDelegatedOid4vpView(
navController,
verificationId = id,
verificationMethodsViewModel
verificationMethodsViewModel = verificationMethodsViewModel,
verificationActivityLogsViewModel = verificationActivityLogsViewModel
)
}
composable(
Expand All @@ -76,6 +99,15 @@ fun SetupNavGraph(
verificationMethodsViewModel = verificationMethodsViewModel
)
}
composable(
route = Screen.VerifierSettingsActivityLogScreen.route,
) {
VerifierSettingsActivityLogScreen(
navController,
verificationActivityLogsViewModel = verificationActivityLogsViewModel,
helpersViewModel = helpersViewModel
)
}
composable(
route = Screen.AddVerificationMethodScreen.route,
) {
Expand Down
Loading

0 comments on commit d0f9757

Please sign in to comment.