Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
aeea2c4
chore(deps): bump com.google.android.gms.oss-licenses-plugin
dependabot[bot] Mar 22, 2026
ab0f672
chore(deps): bump com.google.android.gms:oss-licenses-plugin
dependabot[bot] Mar 22, 2026
44bac20
chore(deps): bump gradle-wrapper from 9.4.0 to 9.4.1
dependabot[bot] Mar 22, 2026
988a071
chore(deps): bump koin from 4.1.1 to 4.2.0
dependabot[bot] Mar 22, 2026
bd2fd96
chore(deps): bump com.google.android.gms.oss-licenses-plugin from 0.1…
JeelDobariya38 Mar 24, 2026
52d1f0e
chore(deps): bump com.google.android.gms:oss-licenses-plugin from 0.1…
JeelDobariya38 Mar 24, 2026
7266b7d
chore(deps): bump koin from 4.1.1 to 4.2.0 (#119)
JeelDobariya38 Mar 24, 2026
0e18044
chore(deps): bump kotlin from 2.3.10 to 2.3.20
dependabot[bot] Mar 24, 2026
0214f8c
chore(deps): bump kotlin from 2.3.10 to 2.3.20 (#115)
JeelDobariya38 Mar 24, 2026
b13abcc
chore(deps): bump gradle-wrapper from 9.4.0 to 9.4.1 (#118)
JeelDobariya38 Mar 29, 2026
a3dbe6d
chore(deps): bump org.jetbrains.compose from 1.10.2 to 1.10.3
dependabot[bot] Mar 29, 2026
71ff70f
chore: renamed database module to android database module
JeelDobariya38 Mar 18, 2026
6b7d1d7
refactor: database module to kmp
JeelDobariya38 Mar 19, 2026
eac345d
chore(test): add todo for migrating test
JeelDobariya38 Mar 19, 2026
650d8b4
chore(deps): bump org.jetbrains.compose from 1.10.2 to 1.10.3 (#120)
JeelDobariya38 Mar 30, 2026
bbfc7e0
chore(deps): bump androidx.compose:compose-bom
dependabot[bot] Mar 30, 2026
db77b44
chore(deps): bump androidx.compose:compose-bom from 2026.03.00 to 202…
JeelDobariya38 Mar 30, 2026
db01e6a
fix(deps): fix a wrong version definition
JeelDobariya38 Apr 3, 2026
730a3cc
test: made database module test work
JeelDobariya38 Apr 4, 2026
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
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
> Please, consider using it for fun, and not for real password management. (until, we officially
> release a stable release)
>
> Cuz, **`data is stored unencrypted`.. we planning to add encryption soon.**
> Cuz, **`data is stored unencrypted`.. we're planning to add encryption soon.**

> [!NOTE]
> Currently, we are android-only, we will soon provide support for desktop (windows-only) using kotlin-multiplatform. but development will remain to android-first.
>
> then later-after will migrate to react-native and then passcodes will be multiplatform rather than being android-first. more information will be given in docs soon.

<div align="center">

Expand Down
1 change: 0 additions & 1 deletion autofill/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ dependencies {
implementation(libs.material)

// Data/Persistence (Room Bundle)
ksp(libs.room.compiler)
implementation(libs.room.ktx)

implementation(libs.coroutines.core)
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ plugins {
alias(libs.plugins.androidKmpLibrary) apply false
alias(libs.plugins.kotlinSerialization) apply false
alias(libs.plugins.ksp) apply false
alias (libs.plugins.androidx.room) apply false
alias(libs.plugins.ossLicenses) apply false
}

Expand Down
5 changes: 5 additions & 0 deletions database/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Test Notice.

All the database code will be tested in android context. meaning, all migration and things will be tested based on android platform. as we are android first. and to some extent android-only.

This is also true cuz, room migration are hard to test on every platform. there is no convenient way to test room migration for all platform.
95 changes: 42 additions & 53 deletions database/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,77 +1,66 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.gradle.kotlin.dsl.provideDelegate

plugins {
alias(libs.plugins.androidLibrary)
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidKmpLibrary)
alias(libs.plugins.ksp)
alias (libs.plugins.androidx.room)
}

kotlin {
compilerOptions {
jvmTarget = JvmTarget.JVM_21
}
}

android {
namespace = "com.jeeldobariya.passcodes.database"
compileSdk {
version = release(36)
}

defaultConfig {
android {
compileSdk = 36
minSdk = 26
namespace = "com.jeeldobariya.passcodes.database"
experimentalProperties["android.experimental.kmp.enableAndroidResources"] = true

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}
withHostTest {
isIncludeAndroidResources = true
}

sourceSets {
getByName("androidTest") {
assets.directories += "$projectDir/schemas"
// Opt-in to enable and configure device-side (instrumented) tests
withDeviceTest {
instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
execution = "HOST"
}
}

buildTypes {
getByName("release") {
isMinifyEnabled = false
sourceSets {
androidMain.dependencies {
implementation(libs.koin)
}

create("staging") {
isMinifyEnabled = false
getByName("androidDeviceTest").dependencies {
implementation(libs.bundles.unit.test)
implementation(libs.androidx.junit)
implementation(libs.androidx.junit.ktx)
implementation(libs.androidx.runner)
implementation(libs.coroutines.test)
implementation(libs.androidx.room.testing)
}

getByName("debug") {
isMinifyEnabled = false
commonMain.dependencies {
// Coroutines
implementation(libs.bundles.coroutines)

// Room
implementation(libs.androidx.room.runtime)
implementation(libs.sqlite.bundled)

// Dependency Injection
implementation(libs.koin)
}
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
commonTest.dependencies {
implementation(kotlin("test"))
}
}
}

ksp {
val location = "$projectDir/schemas"
arg("room.schemaLocation", location)
}
room {
schemaDirectory("$projectDir/schemas")
}

dependencies {
implementation(libs.androidx.core.ktx)

// Data/Persistence (Room Bundle)
ksp(libs.room.compiler)
implementation(libs.room.ktx)

// Concurrency (Coroutines Bundle)
implementation(libs.bundles.coroutines)

// Dependency Injection
implementation(libs.koin)

androidTestImplementation(libs.bundles.unit.test)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.junit.ktx)
androidTestImplementation(libs.androidx.runner)
androidTestImplementation(libs.coroutines.test)
androidTestImplementation(libs.room.testing)
add("kspAndroid", libs.androidx.room.compiler)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,17 @@ package com.jeeldobariya.passcodes.database.master
import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.io.IOException

/**
* Instrumented test for the Room database, specifically testing the PasswordsDao.
*/
@RunWith(AndroidJUnit4::class)
class MasterDatabasePasswordsDaoTest {

private lateinit var passwordsDao: PasswordsDao
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class MasterDatabaseMigration1To2Test {

private val TEST_DB = "migration-1-2-test"

@get:Rule
val helper = MigrationTestHelper(
InstrumentationRegistry.getInstrumentation(),
Expand All @@ -22,7 +20,9 @@ class MasterDatabaseMigration1To2Test {

@Test
fun migrate_basicData() {
helper.createDatabase(TEST_DB, 1).apply {
val dbName = "test_db_migrate_basicData"

helper.createDatabase(dbName, 1).apply {
execSQL("""
INSERT INTO passwords (id, domain, username, password, notes)
VALUES (1, 'example.com', 'user', 'pass', 'note')
Expand All @@ -31,7 +31,7 @@ class MasterDatabaseMigration1To2Test {
}

val migratedDb = helper.runMigrationsAndValidate(
TEST_DB, 2, true, MIGRATION_1_2
dbName, 2, true, MIGRATION_1_2
)

val cursor = migratedDb.query("SELECT * FROM passwords")
Expand All @@ -41,15 +41,17 @@ class MasterDatabaseMigration1To2Test {

@Test
fun migrate_emptyNotes_becomesNull() {
helper.createDatabase(TEST_DB, 1).apply {
val dbName = "test_db_migrate_emptyNotes_becomesNull"

helper.createDatabase(dbName, 1).apply {
execSQL("""
INSERT INTO passwords (id, domain, username, password, notes)
VALUES (1, 'd', 'u', 'p', '')
""")
close()
}

val db = helper.runMigrationsAndValidate(TEST_DB, 2, true, MIGRATION_1_2)
val db = helper.runMigrationsAndValidate(dbName, 2, true, MIGRATION_1_2)

val cursor = db.query("SELECT notes FROM passwords WHERE id = 1")
cursor.moveToFirst()
Expand All @@ -61,15 +63,17 @@ class MasterDatabaseMigration1To2Test {

@Test
fun migrate_urlGenerated() {
helper.createDatabase(TEST_DB, 1).apply {
val dbName = "test_db_migrate_urlGenerated"

helper.createDatabase(dbName, 1).apply {
execSQL("""
INSERT INTO passwords (id, domain, username, password, notes)
VALUES (1, 'google.com', 'u', 'p', 'n')
""")
close()
}

val db = helper.runMigrationsAndValidate(TEST_DB, 2, true, MIGRATION_1_2)
val db = helper.runMigrationsAndValidate(dbName, 2, true, MIGRATION_1_2)

val cursor = db.query("SELECT url FROM passwords WHERE id = 1")
cursor.moveToFirst()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.jeeldobariya.passcodes.database.di

import androidx.room.Room
import com.jeeldobariya.passcodes.database.master.MasterDatabase
import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module

actual val databaseModule = module {
single {
MasterDatabase.createNewDatabase(
getDatabaseBuilder = {
val appContext = androidContext()
val dbFile = appContext.getDatabasePath("master.db")

Room.databaseBuilder<MasterDatabase>(
context = appContext,
name = dbFile.absolutePath
)
}
)
}

single {
get<MasterDatabase>().passwordsDao
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.jeeldobariya.passcodes.database.di

import org.koin.core.module.Module


expect val databaseModule: Module
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.jeeldobariya.passcodes.database.master

// import android.content.Context
import androidx.room.ConstructedBy
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.RoomDatabaseConstructor
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
import com.jeeldobariya.passcodes.database.master.migration.MIGRATION_1_2

@Database(
entities = [PasswordEntity::class],
version = 2,
exportSchema = true
)
@ConstructedBy(MasterDatabaseConstructor::class)
abstract class MasterDatabase : RoomDatabase() {
abstract val passwordsDao: PasswordsDao

companion object {
fun createNewDatabase(
getDatabaseBuilder: () -> Builder<MasterDatabase>
): MasterDatabase {
return getDatabaseBuilder()
.setDriver(BundledSQLiteDriver())
.addMigrations(MIGRATION_1_2)
.build()
}
}
}

@Suppress("KotlinNoActualForExpect")
expect object MasterDatabaseConstructor : RoomDatabaseConstructor<MasterDatabase> {
override fun initialize(): MasterDatabase
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "passwords")
data class PasswordEntity(
data class
PasswordEntity(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
var domain: String,
Expand All @@ -18,4 +19,4 @@ data class PasswordEntity(
var createdAt: String? = null,
@ColumnInfo(name = "updated_at", defaultValue = "CURRENT_TIMESTAMP")
var updatedAt: String? = null
)
)
4 changes: 0 additions & 4 deletions database/src/main/AndroidManifest.xml

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Loading