Skip to content

Commit

Permalink
Fix OtpUri
Browse files Browse the repository at this point in the history
  • Loading branch information
SanmerDev committed Aug 17, 2024
1 parent fba856e commit fec772a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,9 @@ class EditViewModel @Inject constructor(

runCatching {
val uri = uriString.toOtpUri()
val type = uri.type.let(Auth.Type::valueOf)
val hash = uri.algorithm.let(HOTP.Hash::valueOf)
val hash = HOTP.Hash.valueOf(uri.algorithm)

when (type) {
when (Auth.Type.valueOf(uri.type)) {
Auth.Type.HOTP -> HotpSerializable(
issuer = uri.issuer,
name = uri.name,
Expand All @@ -113,6 +112,8 @@ class EditViewModel @Inject constructor(
}
}.onSuccess {
updateFromAuth(it.auth)
}.onFailure {
Timber.e(it)
}
}

Expand Down
73 changes: 36 additions & 37 deletions core/src/main/kotlin/dev/sanmer/otp/OtpUri.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,6 @@ class OtpUri private constructor() {
this.period = period
}

constructor(uri: Uri) : this() {
val label = uri.getOrDefault("") { path?.substring(1) }
if (label.contains(":")) {
val strings = label.split(":".toRegex(), limit = 2)
if (strings.size == 2) {
issuer = strings.first()
name = strings.last()
} else {
issuer = ""
name = label
}
} else {
issuer = uri.getQueryParameterOrDefault("issuer", "")
name = label
}

type = uri.getOrDefault("") { host }.uppercase()
secret = uri.getQueryParameterOrDefault("secret", "")
algorithm = uri.getQueryParameterOrDefault("algorithm", "").uppercase()
digits = uri.getQueryParameterOrDefault("digits", "0").let(String::toInt)

counter = uri.getQueryParameter("counter")?.let(String::toLong)
period = uri.getQueryParameter("period")?.let(String::toLong)
}

var issuer: String = ""
private set

Expand All @@ -72,7 +47,34 @@ class OtpUri private constructor() {
var period: Long? = null
private set

fun toUri(): Uri {
private fun parse(uri: Uri): OtpUri {
val label = uri.getOrDefault("") { path?.substring(1) }
if (label.contains(":")) {
val values = label.split(":".toRegex(), limit = 2)
if (values.size >= 2) {
issuer = values[0]
name = values[1]
} else {
issuer = ""
name = label
}
} else {
issuer = uri.getQueryParameterOrDefault("issuer", "")
name = label
}

type = uri.getOrDefault("") { host }.uppercase()
secret = uri.getQueryParameterOrDefault("secret", "")
algorithm = uri.getQueryParameterOrDefault("algorithm", "").uppercase()
digits = uri.getQueryParameterOrDefault("digits", "0").let(String::toInt)

counter = uri.getQueryParameter("counter")?.let(String::toLong)
period = uri.getQueryParameter("period")?.let(String::toLong)

return this
}

private fun toUri(): Uri {
val builder = Uri.Builder()
builder.scheme(SCHEME)
builder.authority(type.lowercase())
Expand Down Expand Up @@ -106,25 +108,22 @@ class OtpUri private constructor() {
companion object Default {
const val SCHEME = "otpauth"

internal inline fun <T> Uri.getOrDefault(default: T, block: Uri.() -> T?) =
block(this) ?: default

internal inline fun Uri.getQueryParameterOrDefault(key: String, default: String) =
getQueryParameter(key) ?: default

fun parse(uriString: String): OtpUri {
val uri = Uri.parse(uriString)
if (!uri.isOtpUri()) {
throw IllegalArgumentException("Unsupported ${uri.scheme}")
}

return OtpUri(uri)
require(uri.isOtpUri()) { "Expected scheme = $SCHEME" }
return OtpUri().parse(uri)
}

inline fun String.toOtpUri() = parse(this)

inline fun String.isOtpUri() = startsWith(SCHEME)

inline fun Uri.isOtpUri() = scheme == SCHEME

private inline fun <T> Uri.getOrDefault(default: T, block: Uri.() -> T?) =
block(this) ?: default

private inline fun Uri.getQueryParameterOrDefault(key: String, default: String) =
getQueryParameter(key) ?: default
}
}

0 comments on commit fec772a

Please sign in to comment.