mirror of
https://github.com/yogeshpaliyal/KeyPass.git
synced 2025-12-30 00:59:48 -06:00
* Precise choice about what special characters I need to use #862 * List Of Symbols Bug * Changed * Code Formatted * SpotlessApply Checked
This commit is contained in:
@@ -41,12 +41,11 @@ android {
|
||||
applicationIdSuffix = ".staging"
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
productFlavors {
|
||||
create("free") {
|
||||
isDefault=true
|
||||
isDefault = true
|
||||
}
|
||||
create("pro") {
|
||||
applicationIdSuffix = ".pro"
|
||||
@@ -61,7 +60,7 @@ android {
|
||||
jvmTarget = "17"
|
||||
|
||||
freeCompilerArgs = listOf(
|
||||
"-Xopt-in=androidx.compose.material3.ExperimentalMaterial3Api"
|
||||
"-Xopt-in=androidx.compose.material3.ExperimentalMaterial3Api",
|
||||
)
|
||||
}
|
||||
buildFeatures {
|
||||
@@ -71,8 +70,6 @@ android {
|
||||
|
||||
flavorDimensions("default")
|
||||
|
||||
|
||||
|
||||
packagingOptions {
|
||||
resources {
|
||||
excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
||||
@@ -89,11 +86,10 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
lint{
|
||||
lint {
|
||||
disable += "MissingTranslation"
|
||||
abortOnError = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ruler {
|
||||
@@ -103,10 +99,9 @@ ruler {
|
||||
sdkVersion.set(27)
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
|
||||
//api(project(":shared"))
|
||||
// api(project(":shared"))
|
||||
api(project(":common"))
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||
@@ -151,12 +146,10 @@ dependencies {
|
||||
kapt("androidx.hilt:hilt-compiler:1.2.0")
|
||||
implementation("androidx.hilt:hilt-navigation-compose:1.2.0")
|
||||
|
||||
|
||||
// zxing library
|
||||
// implementation "com.googl.ezxing:android-core:3.4.1"
|
||||
implementation("com.journeyapps:zxing-android-embedded:4.3.0")
|
||||
|
||||
|
||||
// For instrumented tests.
|
||||
androidTestImplementation("com.google.dagger:hilt-android-testing:2.51.1")
|
||||
// ...with Kotlin.
|
||||
@@ -171,6 +164,4 @@ dependencies {
|
||||
implementation("me.saket.cascade:cascade-compose:2.2.0")
|
||||
|
||||
implementation("androidx.biometric:biometric:1.1.0")
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ fun KeyPassInputField(
|
||||
leadingIcon: @Composable (() -> Unit)? = null,
|
||||
trailingIcon: @Composable (() -> Unit)? = null,
|
||||
visualTransformation: VisualTransformation = VisualTransformation.None,
|
||||
copyToClipboardClicked: ((String) -> Unit) ? = null
|
||||
copyToClipboardClicked: ((String) -> Unit)? = null
|
||||
) {
|
||||
OutlinedTextField(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
|
||||
@@ -89,20 +89,22 @@ fun Fields(
|
||||
},
|
||||
leadingIcon = if (accountModel.id != null) {
|
||||
null
|
||||
} else (
|
||||
{
|
||||
IconButton(
|
||||
onClick = {
|
||||
updateAccountModel(accountModel.copy(password = PasswordGenerator(passwordConfig).generatePassword()))
|
||||
} else {
|
||||
(
|
||||
{
|
||||
IconButton(
|
||||
onClick = {
|
||||
updateAccountModel(accountModel.copy(password = PasswordGenerator(passwordConfig).generatePassword()))
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painter = rememberVectorPainter(image = Icons.Rounded.Refresh),
|
||||
contentDescription = ""
|
||||
)
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painter = rememberVectorPainter(image = Icons.Rounded.Refresh),
|
||||
contentDescription = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
),
|
||||
)
|
||||
},
|
||||
visualTransformation = visualTransformation,
|
||||
copyToClipboardClicked = copyToClipboardClicked
|
||||
)
|
||||
|
||||
@@ -52,6 +52,38 @@ class GeneratePasswordViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun selectSymbolForPassword(symbol: Char) {
|
||||
val tempList = _viewState.value.listOfSymbols.toMutableList()
|
||||
|
||||
if (tempList.size == PasswordGenerator.totalSymbol.size && tempList.contains(symbol)) {
|
||||
tempList.clear()
|
||||
}
|
||||
if (symbol == 's') {
|
||||
_viewState.update {
|
||||
it.copy(
|
||||
listOfSymbols = PasswordGenerator.totalSymbol
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
if (tempList.contains(symbol)) {
|
||||
tempList.remove(symbol)
|
||||
|
||||
if (tempList.isEmpty()) {
|
||||
selectSymbolForPassword('s')
|
||||
return
|
||||
}
|
||||
} else {
|
||||
tempList.add(symbol)
|
||||
}
|
||||
|
||||
_viewState.update {
|
||||
it.copy(
|
||||
listOfSymbols = tempList.toList()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun onPasswordLengthSliderChange(value: Float) {
|
||||
_viewState.update {
|
||||
it.copy(length = value)
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.yogeshpaliyal.keypass.ui.generate.ui
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@@ -14,16 +16,19 @@ import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedCard
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.google.accompanist.themeadapter.material3.Mdc3Theme
|
||||
import com.yogeshpaliyal.common.data.PasswordConfig
|
||||
import com.yogeshpaliyal.common.utils.PasswordGenerator
|
||||
import com.yogeshpaliyal.keypass.ui.generate.ui.components.CheckboxWithLabel
|
||||
import com.yogeshpaliyal.keypass.ui.generate.ui.components.PasswordLengthInput
|
||||
|
||||
@@ -37,6 +42,7 @@ fun GeneratePasswordContent(
|
||||
onLowercaseCheckedChange: (Boolean) -> Unit,
|
||||
onNumbersCheckedChange: (Boolean) -> Unit,
|
||||
onSymbolsCheckedChange: (Boolean) -> Unit,
|
||||
selectSymbolForPassword: (Char) -> Unit = {},
|
||||
onBlankSpacesCheckedChange: (Boolean) -> Unit
|
||||
) {
|
||||
Scaffold(
|
||||
@@ -56,6 +62,7 @@ fun GeneratePasswordContent(
|
||||
onLowercaseCheckedChange = onLowercaseCheckedChange,
|
||||
onNumbersCheckedChange = onNumbersCheckedChange,
|
||||
onSymbolsCheckedChange = onSymbolsCheckedChange,
|
||||
selectSymbolForPassword = selectSymbolForPassword,
|
||||
onBlankSpacesCheckedChange = onBlankSpacesCheckedChange
|
||||
)
|
||||
}
|
||||
@@ -84,6 +91,7 @@ private fun FormInputCard(
|
||||
onLowercaseCheckedChange: (Boolean) -> Unit,
|
||||
onNumbersCheckedChange: (Boolean) -> Unit,
|
||||
onSymbolsCheckedChange: (Boolean) -> Unit,
|
||||
selectSymbolForPassword: (Char) -> Unit = {},
|
||||
onBlankSpacesCheckedChange: (Boolean) -> Unit
|
||||
) {
|
||||
OutlinedCard(
|
||||
@@ -107,7 +115,7 @@ private fun FormInputCard(
|
||||
|
||||
NumberInput(viewState.includeNumbers, onNumbersCheckedChange)
|
||||
|
||||
SymbolInput(viewState.includeSymbols, onSymbolsCheckedChange)
|
||||
SymbolInput(viewState.includeSymbols, onSymbolsCheckedChange, selectSymbolForPassword, viewState.listOfSymbols)
|
||||
|
||||
BlankSpaceInput(viewState.includeBlankSpaces, onBlankSpacesCheckedChange)
|
||||
}
|
||||
@@ -176,16 +184,55 @@ private fun NumberInput(
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
private fun SymbolInput(
|
||||
includeSymbols: Boolean,
|
||||
onSymbolsCheckedChange: (Boolean) -> Unit
|
||||
onSymbolsCheckedChange: (Boolean) -> Unit,
|
||||
selectSymbolForPassword: (Char) -> Unit = {},
|
||||
selectedSymbols: List<Char>
|
||||
) {
|
||||
CheckboxWithLabel(
|
||||
label = "Symbols",
|
||||
checked = includeSymbols,
|
||||
onCheckedChange = onSymbolsCheckedChange
|
||||
)
|
||||
Column {
|
||||
CheckboxWithLabel(
|
||||
label = "Symbols",
|
||||
checked = includeSymbols,
|
||||
onCheckedChange = onSymbolsCheckedChange
|
||||
)
|
||||
if (includeSymbols) {
|
||||
FlowRow(modifier = Modifier.fillMaxWidth()) {
|
||||
OutlinedCard(
|
||||
onClick = {
|
||||
selectSymbolForPassword('s')
|
||||
},
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
colors = CardDefaults.outlinedCardColors(
|
||||
containerColor = if (selectedSymbols.size == PasswordGenerator.totalSymbol.size) MaterialTheme.colorScheme.primary else Color.Unspecified
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = "All",
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
}
|
||||
PasswordGenerator.totalSymbol.forEach { symbol ->
|
||||
OutlinedCard(
|
||||
onClick = {
|
||||
selectSymbolForPassword(symbol)
|
||||
},
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
colors = CardDefaults.outlinedCardColors(
|
||||
if (symbol in selectedSymbols && selectedSymbols.size != PasswordGenerator.totalSymbol.size) MaterialTheme.colorScheme.primary else Color.Unspecified
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = "$symbol",
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -31,6 +31,7 @@ fun GeneratePasswordScreen(viewModel: GeneratePasswordViewModel = hiltViewModel(
|
||||
onLowercaseCheckedChange = viewModel::onLowercaseCheckedChange,
|
||||
onNumbersCheckedChange = viewModel::onNumbersCheckedChange,
|
||||
onSymbolsCheckedChange = viewModel::onSymbolsCheckedChange,
|
||||
selectSymbolForPassword = viewModel::selectSymbolForPassword,
|
||||
onBlankSpacesCheckedChange = viewModel::onBlankSpacesCheckedChange
|
||||
)
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ dependencies {
|
||||
// apache common codec
|
||||
implementation("commons-codec:commons-codec:1.17.0")
|
||||
|
||||
//Androidx Security
|
||||
// Androidx Security
|
||||
implementation("androidx.security:security-crypto:1.1.0-alpha06")
|
||||
|
||||
api("androidx.documentfile:documentfile:1.0.1")
|
||||
@@ -76,6 +76,4 @@ dependencies {
|
||||
implementation("androidx.sqlite:sqlite:2.3.1")
|
||||
|
||||
api("com.opencsv:opencsv:5.8")
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.yogeshpaliyal.common.constants
|
||||
annotation class AccountType {
|
||||
companion object {
|
||||
const val DEFAULT = 1 // used to store password and user information
|
||||
|
||||
@Deprecated("TOTP type removed, added TOTP support in Default")
|
||||
const val TOTP = 2 // used to store Time base - One time Password
|
||||
/* const val HOTP = 3
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.yogeshpaliyal.common.data
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.yogeshpaliyal.common.utils.PasswordGenerator
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Keep
|
||||
@@ -10,6 +11,7 @@ data class PasswordConfig(
|
||||
val includeUppercaseLetters: Boolean,
|
||||
val includeLowercaseLetters: Boolean,
|
||||
val includeSymbols: Boolean,
|
||||
val listOfSymbols: List<Char>,
|
||||
val includeNumbers: Boolean,
|
||||
val includeBlankSpaces: Boolean,
|
||||
val password: String
|
||||
@@ -20,6 +22,7 @@ data class PasswordConfig(
|
||||
includeUppercaseLetters = true,
|
||||
includeLowercaseLetters = true,
|
||||
includeSymbols = true,
|
||||
listOfSymbols = PasswordGenerator.totalSymbol,
|
||||
includeNumbers = true,
|
||||
includeBlankSpaces = true,
|
||||
password = ""
|
||||
|
||||
@@ -11,6 +11,10 @@ class PasswordGenerator(
|
||||
private val SYMBOLS = 3
|
||||
private val BLANKSPACES = 4
|
||||
|
||||
companion object {
|
||||
val totalSymbol = listOf('!', '@', '#', '$', '%', '&', '*', '+', '=', '-', '~', '?', '/', '_')
|
||||
}
|
||||
|
||||
fun generatePassword(): String {
|
||||
var password = ""
|
||||
val list = ArrayList<Int>()
|
||||
@@ -37,7 +41,7 @@ class PasswordGenerator(
|
||||
UPPER_CASE -> password += ('A'..'Z').random().toString()
|
||||
LOWER_CASE -> password += ('a'..'z').random().toString()
|
||||
NUMBERS -> password += ('0'..'9').random().toString()
|
||||
SYMBOLS -> password += listOf('!', '@', '#', '$', '%', '&', '*', '+', '=', '-', '~', '?', '/', '_').random().toString()
|
||||
SYMBOLS -> password += passwordConfig.listOfSymbols.random().toString()
|
||||
BLANKSPACES -> password += (' ').toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
# Location of the SDK. This is only used by Gradle.
|
||||
# For customization when using a Version Control System, please read the
|
||||
# header note.
|
||||
#Tue May 09 21:09:59 IST 2023
|
||||
sdk.dir=/Users/yogesh.choudhary3/Library/Android/sdk
|
||||
#Tue Jun 04 13:10:19 IST 2024
|
||||
sdk.dir=C\:\\Users\\win10\\AppData\\Local\\Android\\Sdk
|
||||
|
||||
@@ -39,7 +39,6 @@ kotlin {
|
||||
}
|
||||
val desktopMain by getting {
|
||||
dependencies {
|
||||
|
||||
}
|
||||
}
|
||||
val desktopTest by getting
|
||||
|
||||
Reference in New Issue
Block a user