-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2d1ad99
Showing
167 changed files
with
8,500 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.DS_Store | ||
/.idea | ||
/build | ||
/app/build | ||
/app/release | ||
/.gradle | ||
/local.properties | ||
/app/plugins/internal/build/ | ||
/app/plugins/internal/.gradle/ | ||
google-services.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2023 TurtlPass <turtlpass.com> | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<p align="center"> | ||
<img src="https://raw.githubusercontent.com/TurtlPass/turtlpass-firmware-arduino/main/assets/icon.png" alt="logo" width=90> | ||
<h3 align="center">TurtlPass Android</h3> | ||
<p align="center"> | ||
TurtlPass Android sends a hash of the user's inputs (App Domain, Account ID, and PIN) to the TurtlPass Firmware via USB connection. When the physical button on the device is pressed, the firmware emulates an external keyboard and types the generated password.</p> | ||
<p align="center"> | ||
<a href="https://github.com/TurtlPass/turtlpass-android/releases"><img src="https://img.shields.io/badge/Android%20App-v1.0.0-green?logo=android" alt="Releases"/></a></p> | ||
<p align="center"> | ||
<a href="https://github.com/TurtlPass/turtlpass-firmware-arduino"><img src="https://img.shields.io/badge/Arduino%20Firmware-v1.0.0-blue?logo=arduino" alt="Firmware Repo"/></a> | ||
<a href="https://github.com/TurtlPass/turtlpass-chrome-extension"><img src="https://img.shields.io/badge/Chrome%20Extension-v1.0.0-blue?logo=googlechrome" alt="Chrome Extension Repo"/></a> | ||
</p> | ||
|
||
|
||
## ⚡ Features | ||
|
||
* Easy app selection: Choose the app you want to generate a password for from the list of installed apps on your device. | ||
* Gravar integration: Load image associated to the user account when the account doesn't have a contact photo already. | ||
* Communication with hardware: Use the TurtlPass firmware device to communicate with the app via USB serial port. | ||
* Secure password generation: The TurtlPass device generates unique, secure passwords using the HKDF algorithm and a seed stored in the flash memory. | ||
* Automatic typing: Don't worry about remembering or typing your passwords - TurtlPass device will do it for you! | ||
* User-friendly design: Enjoy a smooth and intuitive user experience. | ||
|
||
|
||
## 🔑 How to Use | ||
|
||
<img src="how-to.gif" width="300px"> | ||
|
||
1. Plug the TurtlPass device into your phone's USB port & enable USB connections | ||
2. Choose the App you want a password for | ||
3. Type in your Account ID, typically your email address | ||
4. Click `Unlock` & type in your 6-digit PIN | ||
6. (TurtlPass device generates your password) | ||
7. Now press the button on the TurtlPass device to have it type your password | ||
|
||
|
||
## 🏛️ Clean Architecture | ||
|
||
* [Kotlin](https://kotlinlang.org/) | ||
* [MVVM](https://developer.android.com/topic/libraries/architecture/viewmodel) | ||
* [Use Cases](https://developer.android.com/topic/architecture/domain-layer#use-cases-kotlin) | ||
* [Repositories](https://developer.android.com/topic/architecture#data-layer) | ||
* [Dependency Injection](https://developer.android.com/training/dependency-injection/hilt-android) | ||
* [Coroutines](https://github.com/Kotlin/kotlinx.coroutines) | ||
* [Flow & StateFlow](https://kotlinlang.org/docs/flow.html) | ||
* [Compose UI](https://developer.android.com/jetpack/androidx/releases/compose-ui) | ||
* [Navigation](https://developer.android.com/jetpack/compose/navigation) | ||
|
||
**Third-party libraries used in the project:** | ||
|
||
[Hilt](https://dagger.dev/hilt/), [Coil](https://github.com/coil-kt/coil), [OkHttp](https://github.com/square/okhttp), [UsbSerial](https://github.com/felHR85/UsbSerial), [Lottie](https://github.com/airbnb/lottie-android), etc. | ||
|
||
**Libraries used in the Unit Tests:** | ||
|
||
[JUnit](https://junit.org/junit5/), [Mockk](https://github.com/mockk/mockk), [Truth](https://github.com/google/truth) & [Turbine](https://github.com/cashapp/turbine) | ||
|
||
|
||
## 🔮 Future improvements | ||
|
||
* Add support for Browser Apps | ||
* Read NDEF message ID from an external NFC Tag | ||
* Hash user inputs with Argon2 instead of SHA-512 | ||
|
||
|
||
## 📦 Lottie Animations | ||
|
||
* [USB Memory Stick Animation](https://lottiefiles.com/20358-usb-memory-stick-animation) | ||
* [Loading/Success/Error Animation](https://lottiefiles.com/627-loading-success-failed) | ||
|
||
|
||
## 📄 License | ||
|
||
TurtlPass Android is released under the [MIT License](https://github.com/TurtlPass/turtlpass-android/blob/master/LICENSE). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
plugins { | ||
id("com.android.application") | ||
id("kotlin-android") | ||
id("kotlin-parcelize") | ||
id("internal") | ||
id("de.mannodermaus.android-junit5") | ||
id("dagger.hilt.android.plugin") | ||
kotlin("plugin.serialization") | ||
id("org.jetbrains.kotlin.android") | ||
kotlin("kapt") | ||
} | ||
|
||
android { | ||
compileSdk = internal.Android.compileSdk | ||
buildToolsVersion = internal.Android.buildTools | ||
|
||
defaultConfig { | ||
applicationId = "com.turtlpass" | ||
minSdk = internal.Android.minSdk | ||
targetSdk = internal.Android.targetSdk | ||
versionCode = 10000 | ||
versionName = "1.0.0" | ||
vectorDrawables { useSupportLibrary = true } | ||
missingDimensionStrategy("device", "anyDevice") | ||
buildConfigField("Long", "TIMEOUT_MILLIS", "5000L") | ||
resValue("bool", "uses_clear_text_traffic", "false") | ||
resValue("string", "gravatar_base_url", "https://s.gravatar.com") | ||
buildConfigField("String", "GRAVATAR_BASE_URL", "\"https://s.gravatar.com\"") | ||
buildConfigField("String", "GRAVATAR_PIN_SET", "\"sha256/sSAE6ZWFQvZ1mQB8kh4utc/VpbMVSPQEuedwea9FrtM=\"") | ||
} | ||
buildTypes { | ||
release { | ||
getByName("release") { | ||
// Enables code shrinking, obfuscation, and optimization | ||
isMinifyEnabled = true | ||
// Enables resource shrinking, performed by the Android Gradle plugin | ||
isShrinkResources = true | ||
// Includes ProGuard rules files that are packaged with Android Gradle plugin | ||
proguardFiles( | ||
getDefaultProguardFile("proguard-android-optimize.txt"), | ||
"proguard-rules.pro" | ||
) | ||
} | ||
} | ||
} | ||
buildFeatures { | ||
compose = true | ||
} | ||
composeOptions { | ||
kotlinCompilerExtensionVersion = internal.Versions.compose | ||
} | ||
packagingOptions { | ||
resources { | ||
excludes.add("META-INF/AL2.0") | ||
excludes.add("META-INF/LGPL2.1") | ||
} | ||
} | ||
compileOptions { | ||
targetCompatibility = JavaVersion.VERSION_11 | ||
sourceCompatibility = JavaVersion.VERSION_11 | ||
} | ||
testOptions { | ||
unitTests.isReturnDefaultValues = true | ||
} | ||
} | ||
|
||
dependencies { | ||
internal.Dependencies.kotlin.apply { | ||
implementation(jetpackCore) | ||
implementation(splashscreen) | ||
implementation(kotlinStdlib) | ||
implementation(coroutinesAndroid) | ||
implementation(serialization) | ||
} | ||
internal.Dependencies.compose.apply { | ||
implementation(material) | ||
implementation(material3) | ||
implementation(ui) | ||
implementation(uiToolingPreview) | ||
debugImplementation(uiTooling) | ||
implementation(activityCompose) | ||
implementation(runtime) | ||
implementation(foundation) | ||
implementation(foundationLayout) | ||
implementation(constraintLayout) | ||
implementation(animation) | ||
implementation(navigationAnimation) | ||
implementation(systemUiController) | ||
implementation(permissions) | ||
implementation(placeholder) | ||
implementation(navigationMaterial) | ||
implementation(navigationCompose) | ||
implementation(coil) | ||
implementation(lottie) | ||
} | ||
internal.Dependencies.di.apply { | ||
implementation(daggerHiltAndroid) | ||
kapt(daggerHiltAndroidCompiler) | ||
implementation(hiltNavigationCompose) | ||
// test | ||
androidTestImplementation(daggerHiltAndroidTesting) | ||
kaptAndroidTest(daggerHiltAndroidCompiler) | ||
} | ||
internal.Dependencies.network.apply { | ||
implementation(okhttp) | ||
implementation(interceptor) | ||
} | ||
internal.Dependencies.security.apply { | ||
implementation(crypto) | ||
} | ||
internal.Dependencies.other.apply { | ||
implementation(appcompat) | ||
implementation(annotation) | ||
implementation(material) | ||
implementation(lifecycleViewModelKtx) | ||
implementation(lifecycleViewModelCompose) | ||
implementation(lifecycleViewModelSavedState) | ||
implementation(lifecycleRuntime) | ||
implementation(datastorePreferences) | ||
implementation(preferenceKtx) | ||
implementation(timber) | ||
implementation(usbSerial) | ||
implementation(guava) | ||
debugImplementation(leakcanary) | ||
debugImplementation(chucker) | ||
releaseImplementation(chuckerNoOp) | ||
} | ||
internal.Dependencies.test.apply { | ||
testImplementation(truth) | ||
testImplementation(turbine) | ||
testImplementation(coreTesting) | ||
testImplementation(coroutines) | ||
testImplementation(mockitoKotlin) | ||
testImplementation(mockk) | ||
testImplementation(mockkAgentJvm) | ||
// androidTestImplementation(mockkAndroid) | ||
// androidTestImplementation(mockkAgentJvm) | ||
testImplementation(junit5JupiterApi) | ||
testRuntimeOnly(junit5JupiterEngine) | ||
testImplementation(junit5JupiterParams) | ||
testRuntimeOnly(junit5VintageEngine) | ||
// androidTestImplementation(junit5Core) | ||
// androidTestRuntimeOnly(junit5Runner) | ||
testImplementation(sharedPreferencesMock) | ||
} | ||
} | ||
// Allow references to generated code (Hilt) | ||
kapt { | ||
correctErrorTypes = true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
plugins { | ||
`kotlin-dsl` | ||
`java-gradle-plugin` | ||
} | ||
|
||
group = "internal" | ||
version = "2.0.2.3" | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
gradlePlugin { | ||
plugins.register("internal") { | ||
id = "internal" | ||
implementationClass = "internal.InternalPlugin" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
rootProject.name = "Internal" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
@file:Suppress("unused") | ||
package internal | ||
|
||
object Android { | ||
const val buildTools = "33.0.0" | ||
const val minSdk = 23 | ||
const val targetSdk = 33 | ||
const val compileSdk = 33 | ||
} |
12 changes: 12 additions & 0 deletions
12
app/plugins/internal/src/main/kotlin/internal/Dependencies.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
@file:Suppress("unused") | ||
package internal | ||
|
||
object Dependencies { | ||
val kotlin = internal.dependencies.Kotlin | ||
val compose = internal.dependencies.Compose | ||
val di = internal.dependencies.Di | ||
val network = internal.dependencies.Network | ||
val security = internal.dependencies.Security | ||
val other = internal.dependencies.Other | ||
val test = internal.dependencies.Test | ||
} |
9 changes: 9 additions & 0 deletions
9
app/plugins/internal/src/main/kotlin/internal/InternalPlugin.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package internal | ||
|
||
import org.gradle.api.* | ||
|
||
|
||
class InternalPlugin : Plugin<Project> { | ||
|
||
override fun apply(target: Project) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
@file:Suppress("unused") | ||
|
||
package internal | ||
|
||
object Versions { | ||
const val jetpackCore = "1.9.0" // https://developer.android.com/jetpack/androidx/releases/core | ||
const val ktxCore = "1.7.21" // https://kotlinlang.org/docs/releases.html#release-details | ||
const val compose = "1.4.0-alpha02" // https://developer.android.com/jetpack/androidx/versions/all-channel | ||
//|> 1.4.0-alpha02 compatible with Kotlin 1.7.21 | ||
const val ktxCoroutinesAndroid = "1.6.0" | ||
const val hilt = "1.0.0" | ||
const val hiltCore = "2.44" // https://github.com/google/dagger/releases | ||
const val hiltComposeNavigation = "1.0.0-beta01" // https://developer.android.com/jetpack/androidx/releases/hilt | ||
const val accompanist = "0.28.0" | ||
const val material3 = "1.0.0-alpha02" // https://developer.android.com/jetpack/androidx/releases/compose-material3 | ||
const val constraint = "1.0.0-alpha08" | ||
const val pagingCompose = "1.0.0-alpha09" | ||
const val lifecycle = "2.6.0-alpha03" | ||
const val paging = "3.0.0" | ||
const val lottie = "4.2.2" // http://airbnb.io/lottie/#/android-compose | ||
const val material = "1.5.0" | ||
const val startup = "1.0.0" | ||
const val room = "2.3.0" | ||
const val okhttp = "4.9.3" | ||
const val retrofit2 = "2.9.0" | ||
const val interceptor = "4.9.1" | ||
const val sandwich = "1.1.0" | ||
const val serialization = "1.2.1" | ||
const val browserCustomTabs = "1.3.0" | ||
const val kotlinxDatetime = "0.2.1" | ||
const val securityCrypto = "1.1.0-alpha04" | ||
const val securityIdentityCredential = "1.0.0-alpha02" | ||
const val timber = "4.7.1" | ||
// test | ||
const val testManifest = "1.1.0-beta04" | ||
const val mockWebServer = "4.9.1" | ||
const val mockitoCore = "3.10.0" | ||
const val junit5 = "5.9.1" | ||
const val mockk = "1.13.3" | ||
} |
28 changes: 28 additions & 0 deletions
28
app/plugins/internal/src/main/kotlin/internal/dependencies/Compose.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
@file:Suppress("unused") | ||
|
||
package internal.dependencies | ||
|
||
import internal.Versions | ||
|
||
object Compose { | ||
const val material = "androidx.compose.material:material:1.4.0-alpha03" | ||
const val material3 = "androidx.compose.material3:material3:1.1.0-alpha03" | ||
const val materialIcons = "androidx.compose.material:material-icons-extended:1.4.0-alpha03" | ||
const val ui = "androidx.compose.ui:ui:1.4.0-alpha03" | ||
const val foundation = "androidx.compose.foundation:foundation:1.4.0-alpha03" | ||
const val foundationLayout = "androidx.compose.foundation:foundation-layout:1.4.0-alpha03" | ||
const val uiToolingPreview = "androidx.compose.ui:ui-tooling-preview:1.4.0-alpha03" | ||
const val uiTooling = "androidx.compose.ui:ui-tooling:1.4.0-alpha03" | ||
const val activityCompose = "androidx.activity:activity-compose:1.6.1" | ||
const val runtime = "androidx.compose.runtime:runtime:${Versions.compose}" | ||
const val animation = "androidx.compose.animation:animation:1.4.0-alpha03" | ||
const val constraintLayout = "androidx.constraintlayout:constraintlayout-compose:1.0.1" | ||
const val coil = "io.coil-kt:coil-compose:2.2.2" | ||
const val lottie = "com.airbnb.android:lottie-compose:5.2.0" | ||
const val systemUiController = "com.google.accompanist:accompanist-systemuicontroller:${Versions.accompanist}" | ||
const val navigationAnimation = "com.google.accompanist:accompanist-navigation-animation:${Versions.accompanist}" | ||
const val permissions = "com.google.accompanist:accompanist-permissions:${Versions.accompanist}" | ||
const val placeholder = "com.google.accompanist:accompanist-placeholder:${Versions.accompanist}" | ||
const val navigationMaterial = "com.google.accompanist:accompanist-navigation-material:${Versions.accompanist}" | ||
const val navigationCompose = "androidx.navigation:navigation-compose:2.5.3" | ||
} |
15 changes: 15 additions & 0 deletions
15
app/plugins/internal/src/main/kotlin/internal/dependencies/Di.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
@file:Suppress("unused") | ||
package internal.dependencies | ||
|
||
import internal.* | ||
|
||
/** | ||
* Dagger - Hilt | ||
*/ | ||
object Di { | ||
const val daggerHiltAndroid = "com.google.dagger:hilt-android:${Versions.hiltCore}" | ||
const val daggerHiltAndroidCompiler = "com.google.dagger:hilt-android-compiler:${Versions.hiltCore}" | ||
const val hiltCompiler = "androidx.hilt:hilt-compiler:${Versions.hilt}" | ||
const val hiltNavigationCompose = "androidx.hilt:hilt-navigation-compose:1.0.0" | ||
const val daggerHiltAndroidTesting = "com.google.dagger:hilt-android-testing:${Versions.hiltCore}" | ||
} |
Oops, something went wrong.