Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
2a22227
[Dependencies] Dependency preparation
OffRange Nov 11, 2023
e072769
[SecureElementDetails] Moved to database package
OffRange Nov 11, 2023
c0efff4
Rename .java to .kt
OffRange Nov 11, 2023
6e91fd4
[Tag] Implemented Tag Entity
OffRange Nov 11, 2023
d8f7d78
[Renamed dto package] Renamed to dtos
OffRange Nov 18, 2023
7bf6479
[TagView] Introduce UI Component for Tag Entry
OffRange Nov 18, 2023
02cc962
[ProGuard] Adjusted rules
OffRange Nov 18, 2023
ba342b5
Rename .java to .kt
OffRange Nov 18, 2023
acd4fce
[Strength Estimation] Improved performance
OffRange Nov 18, 2023
04071fa
Rename .java to .kt
OffRange Nov 18, 2023
cc734bc
[FilterBottomSheet] Converted to Kotlin
OffRange Nov 18, 2023
ad7bf4c
[FilterBottomSheet] Added Tag filter option
OffRange Nov 21, 2023
f3192b8
[SecureElement] Added data class
OffRange Nov 24, 2023
5f605e3
[TagEntity] Changed tagID to Long
OffRange Dec 1, 2023
7490b44
[LifecycleOwner] Added doFlowInLifecycle Function
OffRange Dec 21, 2023
6dbe1a4
[OptionBottomSheet] Refactored to BottomSheetDialogFragment
OffRange Dec 21, 2023
daf5282
[Tag] Converted to data class
OffRange Dec 21, 2023
2565560
[Strings] Added Items: %d
OffRange Dec 21, 2023
d1232b1
[Dependencies] Added recyclerview 1.3.2
OffRange Dec 21, 2023
02ae73b
[Kotlin Utilization] Relocated getPaddingBottom function to utility K…
OffRange Dec 22, 2023
a8858db
[Kotlin Utilization] Enhanced code with bundleOf for streamlined argu…
OffRange Dec 22, 2023
3ebe7b9
[SecureElementDiffCallback] Improved logic
OffRange Dec 22, 2023
2fc5466
[SlidingBackPaneManager] Added Update State Callback
OffRange Dec 22, 2023
8932c6a
[SlidingBackPaneManager] Improved state update logic
OffRange Dec 22, 2023
46993a5
[Filter] Converted and improved Filter
OffRange Dec 22, 2023
02ca0e9
[Database] Added Tag infrastructure
OffRange Dec 23, 2023
3455cc8
[Tag View] Implemented tag view
OffRange Dec 23, 2023
9bbcdea
[EditDialogBuilder] Enhance setPositiveButton with Text Input
OffRange Dec 24, 2023
7c5db64
[EditDialogBuilder] Added Custom Listener Support Without Auto-Dismiss
OffRange Dec 24, 2023
262ea39
[OptionBottomSheet] Added support for Tag-View
OffRange Dec 24, 2023
01fc97e
[DashboardAdapter] Enhanced SelectionPredicate for Restricted Tag Han…
OffRange Dec 24, 2023
756f606
[OptionBottomSheet] Enhanced Tag Validation
OffRange Dec 24, 2023
9c3e020
[Preferences] Implemented Dashboard View Switching Option
OffRange Dec 24, 2023
d24440b
[Kotlin 9] Use entries
OffRange Dec 25, 2023
686858e
[ProGuard] Added Rule for ElementDetail Interface Retention
OffRange Dec 25, 2023
8a7b842
[Database] Enabled Kotlin Generation for Room
OffRange Dec 25, 2023
5821631
[Database] Enhanced DAO with @Transaction for Efficient Operations
OffRange Dec 25, 2023
9b3602a
[Database] Improved inserting logic
OffRange Dec 25, 2023
a1a874f
[Code Visibility] Restricted Access
OffRange Dec 25, 2023
4c937cd
[KeyGoDatabase] Removed allowMainThreadQueries
OffRange Dec 25, 2023
5cdf602
[Database Migration] Implemented Tag Management
OffRange Dec 25, 2023
c4cc187
[OptionBottomSheet] Added tag prefix policy
OffRange Dec 25, 2023
3963865
[OptionBottomSheet] Added tag merge feature
OffRange Dec 26, 2023
d556c0c
[SecureElement] Fixed tag list initiation issue
OffRange Dec 26, 2023
d401430
[KeyGoDatabaseTest] Added tag merge test
OffRange Dec 26, 2023
66c3d4a
[Dashboard Files] Moved to UI package
OffRange Dec 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ dependencies {

implementation("com.google.android.gms:play-services-oss-licenses:17.0.1")
implementation("com.google.code.gson:gson:2.10.1")
implementation("androidx.recyclerview:recyclerview:1.3.2")
implementation("androidx.recyclerview:recyclerview-selection:1.1.0")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.4")
implementation("androidx.navigation:navigation-ui-ktx:2.7.4")
Expand All @@ -120,15 +121,23 @@ dependencies {
implementation("com.opencsv:opencsv:5.8")

implementation("androidx.room:room-runtime:2.6.0")
implementation("androidx.room:room-ktx:2.6.0")
ksp("androidx.room:room-compiler:2.6.0")
implementation("androidx.room:room-rxjava3:2.6.0")
androidTestImplementation("androidx.room:room-testing:2.6.0")

androidTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.1")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2") //Used to convert flow to livedata -> TODO delete when migrated Dashboard to kotlin

testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

room {
schemaDirectory("$projectDir/schemas")
}

ksp {
arg("room.generateKotlin", "true")
}
5 changes: 4 additions & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class de.davis.passwordmanager.security.element.** { <fields>; }
-keep class * implements de.davis.passwordmanager.database.entities.details.ElementDetail{
*;
}
-keep class de.davis.passwordmanager.database.dtos.**

# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
Expand Down
141 changes: 123 additions & 18 deletions app/schemas/de.davis.passwordmanager.database.KeyGoDatabase/3.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,29 @@
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "59baef5dbb558a99b1e55c1f957119f0",
"identityHash": "0a97d13a94575bc2ed2ab009853b0086",
"entities": [
{
"tableName": "SecureElement",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`data` BLOB, `title` TEXT, `type` INTEGER NOT NULL, `favorite` INTEGER NOT NULL DEFAULT false, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `created_at` INTEGER, `modified_at` INTEGER)",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`title` TEXT NOT NULL, `data` BLOB NOT NULL, `favorite` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `created_at` INTEGER DEFAULT CURRENT_TIMESTAMP, `modified_at` INTEGER)",
"fields": [
{
"fieldPath": "detail",
"columnName": "data",
"affinity": "BLOB",
"notNull": false
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": false
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"fieldPath": "detail",
"columnName": "data",
"affinity": "BLOB",
"notNull": true
},
{
"fieldPath": "favorite",
"columnName": "favorite",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "false"
"notNull": true
},
{
"fieldPath": "id",
Expand All @@ -40,13 +33,20 @@
"notNull": true
},
{
"fieldPath": "createdAt",
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamps.createdAt",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": false
"notNull": false,
"defaultValue": "CURRENT_TIMESTAMP"
},
{
"fieldPath": "modifiedAt",
"fieldPath": "timestamps.modifiedAt",
"columnName": "modified_at",
"affinity": "INTEGER",
"notNull": false
Expand All @@ -60,12 +60,117 @@
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Tag",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`name` TEXT NOT NULL, `tagId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
"fields": [
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "tagId",
"columnName": "tagId",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"tagId"
]
},
"indices": [
{
"name": "index_Tag_name",
"unique": true,
"columnNames": [
"name"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Tag_name` ON `${TABLE_NAME}` (`name`)"
}
],
"foreignKeys": []
},
{
"tableName": "SecureElementTagCrossRef",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `tagId` INTEGER NOT NULL, PRIMARY KEY(`id`, `tagId`), FOREIGN KEY(`id`) REFERENCES `SecureElement`(`id`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`tagId`) REFERENCES `Tag`(`tagId`) ON UPDATE CASCADE ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tagId",
"columnName": "tagId",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id",
"tagId"
]
},
"indices": [
{
"name": "index_SecureElementTagCrossRef_id",
"unique": false,
"columnNames": [
"id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_SecureElementTagCrossRef_id` ON `${TABLE_NAME}` (`id`)"
},
{
"name": "index_SecureElementTagCrossRef_tagId",
"unique": false,
"columnNames": [
"tagId"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_SecureElementTagCrossRef_tagId` ON `${TABLE_NAME}` (`tagId`)"
}
],
"foreignKeys": [
{
"table": "SecureElement",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"id"
],
"referencedColumns": [
"id"
]
},
{
"table": "Tag",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"tagId"
],
"referencedColumns": [
"tagId"
]
}
]
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '59baef5dbb558a99b1e55c1f957119f0')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0a97d13a94575bc2ed2ab009853b0086')"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import androidx.room.testing.MigrationTestHelper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import de.davis.passwordmanager.database.converter.Converters
import de.davis.passwordmanager.database.entities.details.password.PasswordDetails
import de.davis.passwordmanager.database.entities.wrappers.CombinedElement
import de.davis.passwordmanager.database.migration.MigrationSpec1To2
import de.davis.passwordmanager.database.migration.MigrationSpec2To3
import de.davis.passwordmanager.security.element.SecureElement
import de.davis.passwordmanager.security.element.password.PasswordDetails
import kotlinx.coroutines.test.runTest
import org.junit.Assert.*
import org.junit.Rule
import org.junit.Test
Expand Down Expand Up @@ -39,14 +40,20 @@ class DatabaseMigrationTest {

@Test
@Throws(IOException::class)
fun testAllMigrations() {
fun testAllMigrations() = runTest {
helper.createDatabase(TEST_DB, 1).apply {
val contentValues = ContentValues().apply {
put("title", TITLE)
put("type", SecureElement.TYPE_PASSWORD)
put("type", ElementType.PASSWORD.typeId)
put(
"data",
Converters.convertDetails(PasswordDetails(PASSWORD, ORIGIN, USERNAME))
Converters.convertDetails(
PasswordDetails(
PASSWORD,
ORIGIN,
USERNAME
)
)
)
}
insert("SecureElement", SQLiteDatabase.CONFLICT_REPLACE, contentValues)
Expand All @@ -58,12 +65,12 @@ class DatabaseMigrationTest {
TEST_DB
).build().apply {
openHelper.writableDatabase
val element: SecureElement = secureElementDao().getById(1)
element.run {
val element: CombinedElement = combinedDao().getCombinedElement().first()
element.secureElementEntity.run {
assertEquals(TITLE, title)
assertFalse(isFavorite)
assertNull(modifiedAt)
assertNotNull(createdAt)
assertFalse(favorite)
assertNull(timestamps.modifiedAt)
assertNotNull(timestamps.createdAt)
(detail as PasswordDetails).run {
assertEquals(PASSWORD, password)
assertEquals(ORIGIN, origin)
Expand Down

This file was deleted.

Loading