Compare commits

4 Commits
Author SHA1 Message Date
sergeych de3baedf0c readme fix 2023-09-25 14:38:04 +01:00
sergeych bbb7acad68 release version bump 2023-09-25 14:35:54 +01:00
sergeych cef5e06f0b support for extra reasons of registration failure 2023-09-25 14:14:50 +01:00
sergeych 13436ccedd minor release 2023-07-21 16:11:23 +01:00
6 changed files with 33 additions and 17 deletions

No files matched your search

+4 -2
View File
@@ -2,7 +2,9 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
> Current stable version 0.2.3 We have moved off github due to growing tensions in the world. Thanks for understanding.
> Current stable version 0.2.6
This project targets to provide command set of multiplatform tools to faciliate restore access with non-recoverable passwords by providing a backup `secret` string as the only way to reset the password. It is ready to use in android, web and server apps (native target is not yet supported because of the encryption layer not yet supporting it) This project targets to provide command set of multiplatform tools to faciliate restore access with non-recoverable passwords by providing a backup `secret` string as the only way to reset the password. It is ready to use in android, web and server apps (native target is not yet supported because of the encryption layer not yet supporting it)
@@ -35,7 +37,7 @@ and add in dependencies like:
~~~ ~~~
dependencies { dependencies {
//... //...
implementation("net.sergeych:superlogin:0.2.3") implementation("net.sergeych:superlogin:0.2.6")
} }
~~~ ~~~
+9 -10
View File
@@ -9,7 +9,7 @@ val logback_version="1.2.10"
group = "net.sergeych" group = "net.sergeych"
version = "0.2.2" version = "0.2.6"
repositories { repositories {
mavenCentral() mavenCentral()
@@ -24,9 +24,9 @@ repositories {
kotlin { kotlin {
jvm { jvm {
compilations.all { // compilations.all {
kotlinOptions.jvmTarget = "1.8" // kotlinOptions.jvmTarget = "1.8"
} // }
withJava() withJava()
testRuns["test"].executionTask.configure { testRuns["test"].executionTask.configure {
useJUnitPlatform() useJUnitPlatform()
@@ -34,9 +34,9 @@ kotlin {
} }
js(IR) { js(IR) {
browser { browser {
commonWebpackConfig { // commonWebpackConfig {
cssSupport.enabled = true // cssSupport.enabled = true
} // }
testTask { testTask {
useMocha { useMocha {
timeout = "30000" timeout = "30000"
@@ -51,9 +51,8 @@ kotlin {
val commonMain by getting { val commonMain by getting {
dependencies { dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
api("net.sergeych:unikrypto:1.2.2-SNAPSHOT") // api("net.sergeych:unikrypto:1.2.2-SNAPSHOT")
api("net.sergeych:parsec3:0.4.3-SNAPSHOT") api("net.sergeych:parsec3:0.4.6")
api("net.sergeych:boss-serialization-mp:0.2.4-SNAPSHOT")
api("net.sergeych:unikrypto:1.2.5") api("net.sergeych:unikrypto:1.2.5")
} }
} }
@@ -19,14 +19,19 @@ data class RegistrationArgs(
val packedACO: ByteArray, val packedACO: ByteArray,
val extraData: ByteArray? = null val extraData: ByteArray? = null
) { ) {
@Suppress("unused")
inline fun <reified T>toSuccess(loginToken: ByteArray, extraData: T): AuthenticationResult.Success { inline fun <reified T>toSuccess(loginToken: ByteArray, extraData: T): AuthenticationResult.Success {
return AuthenticationResult.Success( return AuthenticationResult.Success(
loginName, loginToken, BossEncoder.encode(extraData) loginName, loginToken, BossEncoder.encode(extraData)
) )
} }
inline fun <reified T>decodeOrNull(): T? = extraData?.let { it.decodeBoss<T>() } @Suppress("unused")
inline fun <reified T: Any>decodeOrThrow(): T = extraData?.let { it.decodeBoss<T>() } inline fun <reified T>decodeOrNull(): T? = extraData?.decodeBoss<T>()
@Suppress("unused")
inline fun <reified T: Any>decodeOrThrow(): T = extraData?.decodeBoss<T>()
?: throw IllegalArgumentException("missing require extra data of type ${T::class.simpleName}") ?: throw IllegalArgumentException("missing require extra data of type ${T::class.simpleName}")
} }
@@ -44,6 +49,11 @@ sealed class AuthenticationResult {
@SerialName("LoginUnavailable") @SerialName("LoginUnavailable")
object LoginUnavailable: AuthenticationResult() object LoginUnavailable: AuthenticationResult()
@Serializable
@SerialName("OtherError")
class OtherError(val reason: String,val packedData: ByteArray?=null): AuthenticationResult()
@Serializable @Serializable
@SerialName("LoginIdUnavailable") @SerialName("LoginIdUnavailable")
object LoginIdUnavailable: AuthenticationResult() object LoginIdUnavailable: AuthenticationResult()
@@ -34,6 +34,7 @@ class Registration(
val pbkdfRounds: Int = 15000, val pbkdfRounds: Int = 15000,
) : LogTag("SLREG") { ) : LogTag("SLREG") {
@Suppress("unused")
sealed class Result { sealed class Result {
/** /**
* Login is already in use or is somehow else invalid * Login is already in use or is somehow else invalid
@@ -53,6 +54,8 @@ class Registration(
val encodedData: ByteArray?) : Result() { val encodedData: ByteArray?) : Result() {
inline fun <reified D>data() = encodedData?.let { BossDecoder.decodeFrom<D>(it)} inline fun <reified D>data() = encodedData?.let { BossDecoder.decodeFrom<D>(it)}
} }
class OtherError(val code: String,val packedData: ByteArray?=null): Result()
} }
private var lastPasswordHash: ByteArray? = null private var lastPasswordHash: ByteArray? = null
@@ -90,7 +93,7 @@ class Registration(
val nonce = adapter.invokeCommand(api.slGetNonce) val nonce = adapter.invokeCommand(api.slGetNonce)
val loginPrivateKey = deferredLoginKey.await() val loginPrivateKey = deferredLoginKey.await()
val spl = SuperloginRestoreAccessPayload(login, loginPrivateKey, dataKey) val spl = SuperloginRestoreAccessPayload(login, loginPrivateKey, dataKey)
repeat(10) { repeat(3) {
val (restoreKey, restoreData) = AccessControlObject.pack(passwordKeys!!.loginAccessKey, spl) val (restoreKey, restoreData) = AccessControlObject.pack(passwordKeys!!.loginAccessKey, spl)
try { try {
val packedArgs = SignedRecord.pack( val packedArgs = SignedRecord.pack(
@@ -122,6 +125,8 @@ class Registration(
AuthenticationResult.LoginUnavailable -> return Result.InvalidLogin AuthenticationResult.LoginUnavailable -> return Result.InvalidLogin
is AuthenticationResult.OtherError -> return Result.OtherError(result.reason, result.packedData)
is AuthenticationResult.Success -> { is AuthenticationResult.Success -> {
return Result.Success( return Result.Success(
restoreKey.secret, restoreKey.secret,
@@ -18,7 +18,7 @@ internal class AccessControlObjectTest {
val pk1 = SymmetricKeys.random() val pk1 = SymmetricKeys.random()
val pk2 = SymmetricKeys.random() val pk2 = SymmetricKeys.random()
val (rk, packed1) = AccessControlObject.pack(pk1, 117) val (rk, packed1) = AccessControlObject.pack(pk1, 117)
println(rk.secret) // println(rk.secret)
val ac1 = AccessControlObject.unpackWithKey<Int>(packed1,pk1) val ac1 = AccessControlObject.unpackWithKey<Int>(packed1,pk1)
assertNotNull(ac1) assertNotNull(ac1)
assertEquals(117, ac1.payload) assertEquals(117, ac1.payload)
@@ -59,7 +59,7 @@ data class TestSession(val s: TestStorage) : SLServerSession<TestData>() {
} }
override suspend fun loginByToken(token: ByteArray): AuthenticationResult { override suspend fun loginByToken(token: ByteArray): AuthenticationResult {
println("requested login by tokeb ${token.encodeToBase64Compact()}") println("requested login by token ${token.encodeToBase64Compact()}")
println(" ${s.byToken[token.toList()]}") println(" ${s.byToken[token.toList()]}")
println(" ${s.byToken.size} / ${s.byLoginId.size}") println(" ${s.byToken.size} / ${s.byLoginId.size}")