diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index faa8d89..252bda1 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -5,17 +5,18 @@ application { mainClass.set("com.infendro.account.ApplicationKt") } -repositories { - maven("https://git.infendro.com/api/packages/Infendro/maven") - mavenCentral() -} - plugins { + alias(libs.plugins.infendro) alias(libs.plugins.kotlin) alias(libs.plugins.ktor) alias(libs.plugins.serialization) } +repositories { + maven("https://git.infendro.com/api/packages/Infendro/maven") + mavenCentral() +} + dependencies { implementation(libs.ktor.server) implementation(libs.ktor.server.cio) @@ -31,16 +32,18 @@ dependencies { implementation(libs.exposed.jdbc) implementation(libs.migration) implementation(libs.postgres) - implementation(libs.random) + implementation(libs.prng) implementation(libs.otp) implementation(libs.kdf) implementation(libs.hash) + implementation(libs.bytearray) implementation(libs.encoding) implementation(libs.logback) } kotlin { compilerOptions { + freeCompilerArgs.add("-opt-in=kotlin.ExperimentalUnsignedTypes") freeCompilerArgs.add("-opt-in=kotlin.time.ExperimentalTime") } } diff --git a/backend/gradle/libs.versions.toml b/backend/gradle/libs.versions.toml index c8c881c..37ededa 100644 --- a/backend/gradle/libs.versions.toml +++ b/backend/gradle/libs.versions.toml @@ -1,17 +1,20 @@ [versions] -kotlin = "2.2.10" -ktor = "3.2.3" +infendro = "1.0.0" +kotlin = "2.2.21" +ktor = "3.3.3" exposed = "0.61.0" migration = "1.1.0" -postgres = "42.7.5" -random = "1.0.0" -otp = "1.1.1" +postgres = "42.7.8" +prng = "1.2.0" +otp = "1.2.0" kdf = "1.0.3" -hash = "1.2.2" -encoding = "1.1.0" -logback = "1.5.18" +hash = "1.3.2" +bytearray = "1.2.4" +encoding = "1.2.0" +logback = "1.5.22" [plugins] +infendro = { id = "com.infendro.plugin", version.ref = "infendro" } kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } ktor = { id = "io.ktor.plugin", version.ref = "ktor" } serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } @@ -30,13 +33,14 @@ ktor-server-validation = { module = "io.ktor:ktor-server-request-validation", ve exposed = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" } exposed-dao = { module = "org.jetbrains.exposed:exposed-dao", version.ref = "exposed" } exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" } -migration = { module = "com.infendro:ktor-migration", version.ref = "migration" } +migration = { module = "com.infendro:migration-ktor", version.ref = "migration" } postgres = { module = "org.postgresql:postgresql", version.ref = "postgres" } -random = { module = "com.infendro:random", version.ref = "random" } +prng = { module = "com.infendro:prng", version.ref = "prng" } otp = { module = "com.infendro:otp", version.ref = "otp" } kdf = { module = "com.infendro:kdf", version.ref = "kdf" } hash = { module = "com.infendro:hash", version.ref = "hash" } +bytearray = { module = "com.infendro:bytearray", version.ref = "bytearray" } encoding = { module = "com.infendro:encoding", version.ref = "encoding" } logback = { module = "ch.qos.logback:logback-classic", version.ref = "logback" } diff --git a/backend/settings.gradle.kts b/backend/settings.gradle.kts index 2401f0a..cabfe21 100644 --- a/backend/settings.gradle.kts +++ b/backend/settings.gradle.kts @@ -1 +1,7 @@ rootProject.name = "backend" + +pluginManagement.repositories { + maven("https://git.infendro.com/api/packages/Infendro/maven") + gradlePluginPortal() + mavenCentral() +} diff --git a/backend/src/main/kotlin/com/infendro/account/util/Hasher.kt b/backend/src/main/kotlin/com/infendro/account/util/Hasher.kt index be306a2..37bb75d 100644 --- a/backend/src/main/kotlin/com/infendro/account/util/Hasher.kt +++ b/backend/src/main/kotlin/com/infendro/account/util/Hasher.kt @@ -1,13 +1,15 @@ package com.infendro.account.util -import com.infendro.encoding.Hex -import com.infendro.hash.SHA256 +import com.infendro.bytearray.decodeToString +import com.infendro.bytearray.encodeToUByteArray +import com.infendro.encoding.Base16 +import com.infendro.hash.sha2.`SHA-256` object Hasher { fun hash( value: String, ): String { - val bytes = SHA256.hash(value.toByteArray()) - return Hex.encode(bytes).decodeToString() + val bytes = `SHA-256`.hash(value.encodeToUByteArray()) + return Base16.encode(bytes).decodeToString() } } diff --git a/backend/src/main/kotlin/com/infendro/account/util/OTP.kt b/backend/src/main/kotlin/com/infendro/account/util/OTP.kt index d6b8e88..9cb82a5 100644 --- a/backend/src/main/kotlin/com/infendro/account/util/OTP.kt +++ b/backend/src/main/kotlin/com/infendro/account/util/OTP.kt @@ -1,15 +1,18 @@ package com.infendro.account.util +import com.infendro.bytearray.decodeToString +import com.infendro.bytearray.encodeToUByteArray import com.infendro.encoding.Base32 -import com.infendro.hash.SHA256 +import com.infendro.hash.sha2.`SHA-256` import com.infendro.otp.SecretGenerator import com.infendro.otp.TOTP import kotlin.time.Clock import kotlin.time.Duration.Companion.seconds object OTP { + private val generator = SecretGenerator(`SHA-256`) private val totp = TOTP( - function = SHA256, + function = `SHA-256`, length = 8, period = 30.seconds, ) @@ -18,12 +21,12 @@ object OTP { secret: String, otp: String, ): Boolean { - val bytes = Base32.decode(secret.toByteArray()) + val bytes = Base32.decode(secret.encodeToUByteArray()) return totp.verify(bytes, Clock.System.now(), otp) } fun generateSecret(): String { - val bytes = SecretGenerator.generate(totp.hotp.function) + val bytes = generator.generate() return Base32.encode(bytes).decodeToString() } } diff --git a/backend/src/main/kotlin/com/infendro/account/util/SecureHasher.kt b/backend/src/main/kotlin/com/infendro/account/util/SecureHasher.kt index 5086466..0a332f4 100644 --- a/backend/src/main/kotlin/com/infendro/account/util/SecureHasher.kt +++ b/backend/src/main/kotlin/com/infendro/account/util/SecureHasher.kt @@ -1,26 +1,28 @@ package com.infendro.account.util -import com.infendro.encoding.Hex -import com.infendro.hash.SHA256 +import com.infendro.bytearray.decodeToString +import com.infendro.bytearray.encodeToUByteArray +import com.infendro.encoding.Base16 +import com.infendro.hash.sha2.`SHA-256` import com.infendro.kdf.PBKDF2 -import com.infendro.random.PRNG +import com.infendro.random.csprng.CSPRNG object SecureHasher { - private val random = PRNG.HMAC - private val kdf = PBKDF2(SHA256) + private val random = CSPRNG.HMAC(`SHA-256`) + private val kdf = PBKDF2(`SHA-256`) fun hash( value: String, salt: String, ): String { val value = value.encodeToByteArray() - val salt = Hex.decode(salt.encodeToByteArray()) + val salt = Base16.decode(salt.encodeToUByteArray()) return kdf.hash(value, salt, 100_000, 32) - .let { Hex.encode(it).decodeToString() } + .let { Base16.encode(it).decodeToString() } } fun generateSalt(): String { return random.nextBytes(16) - .let { Hex.encode(it).decodeToString() } + .let { Base16.encode(it).decodeToString() } } } diff --git a/backend/src/main/kotlin/com/infendro/account/util/TokenGenerator.kt b/backend/src/main/kotlin/com/infendro/account/util/TokenGenerator.kt index 24560a2..cb937ab 100644 --- a/backend/src/main/kotlin/com/infendro/account/util/TokenGenerator.kt +++ b/backend/src/main/kotlin/com/infendro/account/util/TokenGenerator.kt @@ -1,13 +1,15 @@ package com.infendro.account.util -import com.infendro.encoding.Hex -import com.infendro.random.PRNG +import com.infendro.bytearray.decodeToString +import com.infendro.encoding.Base16 +import com.infendro.hash.sha2.`SHA-256` +import com.infendro.random.csprng.CSPRNG object TokenGenerator { - private val random = PRNG.HMAC + private val random = CSPRNG.HMAC(`SHA-256`) fun generate(): String { return random.nextBytes(32) - .let { Hex.encode(it).decodeToString() } + .let { Base16.encode(it).decodeToString() } } }