mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
fix: Add webOrigin, fix title and add verification state
This commit is contained in:
@@ -24,38 +24,96 @@ import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class AppOrigin(
|
||||
val appIdentifiers: MutableList<AppIdentifier> = mutableListOf(),
|
||||
val webDomains: MutableList<String> = mutableListOf()
|
||||
val androidOrigins: MutableList<AndroidOrigin> = mutableListOf(),
|
||||
val webOrigins: MutableList<WebOrigin> = mutableListOf()
|
||||
) : Parcelable {
|
||||
|
||||
fun addIdentifier(appIdentifier: AppIdentifier) {
|
||||
appIdentifiers.add(appIdentifier)
|
||||
fun addAndroidOrigin(androidOrigin: AndroidOrigin) {
|
||||
androidOrigins.add(androidOrigin)
|
||||
}
|
||||
|
||||
fun addWebDomain(webDomain: String) {
|
||||
this.webDomains.add(webDomain)
|
||||
fun addWebOrigin(webOrigin: WebOrigin) {
|
||||
this.webOrigins.add(webOrigin)
|
||||
}
|
||||
|
||||
fun removeAppElement(appIdentifier: AppIdentifier) {
|
||||
appIdentifiers.remove(appIdentifier)
|
||||
fun containsVerifiedAndroidOrigin(androidOrigin: AndroidOrigin): Boolean {
|
||||
return androidOrigins.any {
|
||||
it.packageName == androidOrigin.packageName
|
||||
&& it.signature == androidOrigin.signature
|
||||
&& it.verification.verified
|
||||
}
|
||||
}
|
||||
|
||||
fun removeWebDomain(webDomain: String) {
|
||||
this.webDomains.remove(webDomain)
|
||||
fun containsVerifiedWebOrigin(webOrigin: WebOrigin): Boolean {
|
||||
return this.webOrigins.any {
|
||||
it.origin == webOrigin.origin
|
||||
&& it.verification.verified
|
||||
}
|
||||
}
|
||||
|
||||
fun firstVerifiedWebOrigin(): WebOrigin? {
|
||||
return webOrigins.first {
|
||||
it.verification.verified
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
appIdentifiers.clear()
|
||||
webDomains.clear()
|
||||
androidOrigins.clear()
|
||||
webOrigins.clear()
|
||||
}
|
||||
|
||||
fun isEmpty(): Boolean {
|
||||
return appIdentifiers.isEmpty() && webDomains.isEmpty()
|
||||
return androidOrigins.isEmpty() && webOrigins.isEmpty()
|
||||
}
|
||||
|
||||
fun toName(): String? {
|
||||
return if (androidOrigins.isNotEmpty()) {
|
||||
androidOrigins.first().packageName
|
||||
} else if (webOrigins.isNotEmpty()){
|
||||
webOrigins.first().origin
|
||||
} else null
|
||||
}
|
||||
}
|
||||
|
||||
enum class Verification {
|
||||
MANUALLY_VERIFIED, AUTOMATICALLY_VERIFIED, NOT_VERIFIED;
|
||||
|
||||
val verified: Boolean
|
||||
get() = this == MANUALLY_VERIFIED || this == AUTOMATICALLY_VERIFIED
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class AndroidOrigin(
|
||||
val packageName: String,
|
||||
val signature: String? = null,
|
||||
val verification: Verification = Verification.AUTOMATICALLY_VERIFIED,
|
||||
) : Parcelable {
|
||||
|
||||
fun toAndroidOrigin(): String {
|
||||
return "androidapp://${packageName}"
|
||||
}
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class AppIdentifier(
|
||||
val id: String,
|
||||
val signature: String? = null,
|
||||
) : Parcelable
|
||||
data class WebOrigin(
|
||||
val origin: String,
|
||||
val assetLinks: String? = null,
|
||||
val verification: Verification = Verification.AUTOMATICALLY_VERIFIED,
|
||||
) : Parcelable {
|
||||
|
||||
fun toWebOrigin(): String {
|
||||
return origin
|
||||
}
|
||||
|
||||
fun defaultAssetLinks(): String {
|
||||
return "${origin}/.well-known/assetlinks.json"
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val RELYING_PARTY_DEFAULT_PROTOCOL = "https"
|
||||
fun fromRelyingParty(relyingParty: String, verification: Verification): WebOrigin = WebOrigin(
|
||||
origin ="$RELYING_PARTY_DEFAULT_PROTOCOL://$relyingParty",
|
||||
verification = verification
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -48,8 +48,8 @@ object AppOriginEntryField {
|
||||
}
|
||||
}.takeWhile { it != null }
|
||||
.forEach { pair ->
|
||||
appOrigin.addIdentifier(
|
||||
AppIdentifier(pair!!.first, pair.second)
|
||||
appOrigin.addAndroidOrigin(
|
||||
AndroidOrigin(pair!!.first, pair.second)
|
||||
)
|
||||
}
|
||||
// Get Domains
|
||||
@@ -58,7 +58,7 @@ object AppOriginEntryField {
|
||||
val domainKey = WEB_DOMAIN_FIELD_NAME + suffixFieldNamePosition(domainFieldPosition)
|
||||
val domainValue = getField(domainKey)
|
||||
if (domainValue != null) {
|
||||
appOrigin.addWebDomain(domainValue)
|
||||
appOrigin.addWebOrigin(WebOrigin(origin = domainValue))
|
||||
domainFieldPosition++
|
||||
} else {
|
||||
break // No more domain found
|
||||
@@ -137,11 +137,12 @@ object AppOriginEntryField {
|
||||
* Only if [customFieldsAllowed] is true
|
||||
*/
|
||||
fun EntryInfo.setAppOrigin(appOrigin: AppOrigin?, customFieldsAllowed: Boolean) {
|
||||
appOrigin?.appIdentifiers?.forEach { appIdentifier ->
|
||||
setApplicationId(appIdentifier.id, appIdentifier.signature)
|
||||
appOrigin?.androidOrigins?.forEach { appIdentifier ->
|
||||
setApplicationId(appIdentifier.packageName, appIdentifier.signature)
|
||||
}
|
||||
appOrigin?.webDomains?.forEach { webDomain ->
|
||||
setWebDomain(webDomain, null, customFieldsAllowed)
|
||||
appOrigin?.webOrigins?.forEach { webOrigin ->
|
||||
if (webOrigin.verification.verified)
|
||||
setWebDomain(webOrigin.origin, null, customFieldsAllowed)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,7 +176,16 @@ class EntryInfo : NodeInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add searchInfo to current EntryInfo, return true if new data, false if no modification
|
||||
* Capitalize and remove suffix of a title
|
||||
*/
|
||||
fun String.toTitle(): String {
|
||||
return this.replaceFirstChar {
|
||||
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add searchInfo to current EntryInfo
|
||||
*/
|
||||
fun saveSearchInfo(database: Database?, searchInfo: SearchInfo) {
|
||||
searchInfo.otpString?.let { otpString ->
|
||||
@@ -191,20 +200,13 @@ class EntryInfo : NodeInfo {
|
||||
setApplicationId(applicationId)
|
||||
}
|
||||
if (title.isEmpty()) {
|
||||
title = searchInfo.toTitle()
|
||||
title = searchInfo.toString().toTitle()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Capitalize and remove suffix of web domain to create a title
|
||||
* Add registerInfo to current EntryInfo
|
||||
*/
|
||||
fun SearchInfo.toTitle(): String {
|
||||
val webDomain = this.webDomain
|
||||
return webDomain?.substring(0, webDomain.lastIndexOf('.'))?.replaceFirstChar {
|
||||
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
|
||||
} ?: this.toString()
|
||||
}
|
||||
|
||||
fun saveRegisterInfo(database: Database?, registerInfo: RegisterInfo) {
|
||||
saveSearchInfo(database, registerInfo.searchInfo)
|
||||
registerInfo.username?.let { username = it }
|
||||
@@ -215,6 +217,9 @@ class EntryInfo : NodeInfo {
|
||||
registerInfo.appOrigin,
|
||||
database?.allowEntryCustomFields() == true
|
||||
)
|
||||
if (title.isEmpty()) {
|
||||
title = registerInfo.toString().toTitle()
|
||||
}
|
||||
}
|
||||
|
||||
fun getVisualTitle(): String {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.kunzisoft.keepass.model
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.kunzisoft.keepass.utils.ObjectNameResource
|
||||
import com.kunzisoft.keepass.utils.readParcelableCompat
|
||||
|
||||
data class RegisterInfo(
|
||||
@@ -11,12 +13,12 @@ data class RegisterInfo(
|
||||
val creditCard: CreditCard? = null,
|
||||
val passkey: Passkey? = null,
|
||||
val appOrigin: AppOrigin? = null
|
||||
): Parcelable {
|
||||
) : ObjectNameResource, Parcelable {
|
||||
|
||||
constructor(parcel: Parcel) : this(
|
||||
searchInfo = parcel.readParcelableCompat() ?: SearchInfo(),
|
||||
username = parcel.readString() ?: "",
|
||||
password = parcel.readString() ?: "",
|
||||
username = parcel.readString(),
|
||||
password = parcel.readString(),
|
||||
creditCard = parcel.readParcelableCompat(),
|
||||
passkey = parcel.readParcelableCompat(),
|
||||
appOrigin = parcel.readParcelableCompat()
|
||||
@@ -35,6 +37,20 @@ data class RegisterInfo(
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun getName(resources: Resources): String {
|
||||
return username
|
||||
?: passkey?.relyingParty
|
||||
?: appOrigin?.toName()
|
||||
?: searchInfo.getName(resources)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return username
|
||||
?: passkey?.relyingParty
|
||||
?: appOrigin?.toName()
|
||||
?: searchInfo.toString()
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<RegisterInfo> {
|
||||
override fun createFromParcel(parcel: Parcel): RegisterInfo {
|
||||
return RegisterInfo(parcel)
|
||||
|
||||
Reference in New Issue
Block a user