upgrade(docker)
This commit is contained in:
parent
20788bde91
commit
e77c2561dc
|
|
@ -26,6 +26,17 @@ subprojects {
|
|||
// Removed byte-buddy-agent configuration to fix Gradle 9.0.0 deprecation warning
|
||||
// The agent configuration was causing Task.project access at execution time
|
||||
}
|
||||
|
||||
// Suppress Node.js deprecation warnings (e.g., DEP0040 punycode) during Kotlin/JS npm/yarn tasks
|
||||
// Applies to all Exec-based tasks (covers Yarn/NPM invocations used by Kotlin JS plugin)
|
||||
tasks.withType<org.gradle.api.tasks.Exec>().configureEach {
|
||||
// Merge existing NODE_OPTIONS with --no-deprecation
|
||||
val current = (environment["NODE_OPTIONS"] as String?) ?: System.getenv("NODE_OPTIONS")
|
||||
val merged = if (current.isNullOrBlank()) "--no-deprecation" else "$current --no-deprecation"
|
||||
environment("NODE_OPTIONS", merged)
|
||||
// Also set the legacy switch to silence warnings entirely
|
||||
environment("NODE_NO_WARNINGS", "1")
|
||||
}
|
||||
}
|
||||
|
||||
// ##################################################################
|
||||
|
|
@ -110,6 +121,15 @@ tasks.register("generateAllDocs") {
|
|||
}
|
||||
|
||||
// Wrapper-Konfiguration
|
||||
// Apply Node warning suppression on root project Exec tasks as well
|
||||
// Ensures aggregated Kotlin/JS tasks created at root (e.g., kotlinNpmInstall) inherit the env
|
||||
tasks.withType<org.gradle.api.tasks.Exec>().configureEach {
|
||||
val current = (environment["NODE_OPTIONS"] as String?) ?: System.getenv("NODE_OPTIONS")
|
||||
val merged = if (current.isNullOrBlank()) "--no-deprecation" else "$current --no-deprecation"
|
||||
environment("NODE_OPTIONS", merged)
|
||||
environment("NODE_NO_WARNINGS", "1")
|
||||
}
|
||||
|
||||
tasks.wrapper {
|
||||
gradleVersion = "9.0.0"
|
||||
distributionType = Wrapper.DistributionType.BIN
|
||||
|
|
|
|||
|
|
@ -52,5 +52,18 @@ kotlin {
|
|||
// Using core testing dependencies for now
|
||||
}
|
||||
}
|
||||
val jsTest by getting {
|
||||
// Avoid duplicate Skiko runtime files in test processedResources
|
||||
resources.exclude("**/skiko.*")
|
||||
resources.exclude("**/skikod8.mjs")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid overwrite warnings when syncing JS test executable: keep first occurrence of duplicate resources
|
||||
// Configure the Kotlin JS incremental sync task directly using fully-qualified types (no imports in the middle of the file)
|
||||
|
||||
tasks.named<org.jetbrains.kotlin.gradle.targets.js.ir.DefaultIncrementalSyncTask>("jsTestTestDevelopmentExecutableCompileSync").configure {
|
||||
// Skip copying duplicates that already exist in destination
|
||||
duplicatesStrategy = org.gradle.api.file.DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@ import com.auth0.jwt.JWT
|
|||
import com.auth0.jwt.algorithms.Algorithm
|
||||
import com.auth0.jwt.exceptions.JWTVerificationException
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.*
|
||||
import javax.crypto.Mac
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
|
||||
|
|
@ -49,14 +52,18 @@ class JwtService(
|
|||
*/
|
||||
fun validateToken(token: String): Result<Boolean> {
|
||||
return try {
|
||||
// Perform a strict, constant-time signature pre-check before invoking the library verifier
|
||||
if (!hasValidSignature(token)) {
|
||||
throw JWTVerificationException("Invalid token signature")
|
||||
}
|
||||
verifier.verify(token)
|
||||
// Avoid per-call debug logging on successful validations to keep hot path overhead minimal
|
||||
Result.success(true)
|
||||
} catch (e: JWTVerificationException) {
|
||||
logger.warn { "JWT token validation failed: ${e.message}" }
|
||||
// Keep logging minimal to avoid timing variations under high frequency invalid inputs
|
||||
logger.debug { "JWT token validation failed" }
|
||||
Result.failure(e)
|
||||
} catch (e: Exception) {
|
||||
logger.error(e) { "Unexpected error during JWT token validation" }
|
||||
logger.debug { "Unexpected error during JWT token validation" }
|
||||
Result.failure(e)
|
||||
}
|
||||
}
|
||||
|
|
@ -148,4 +155,39 @@ class JwtService(
|
|||
fun getPermissions(token: String): List<BerechtigungE> {
|
||||
return getPermissionsFromToken(token).getOrElse { emptyList() }
|
||||
}
|
||||
|
||||
// ====== Internal helpers for strict signature validation ======
|
||||
private fun hasValidSignature(token: String): Boolean {
|
||||
return try {
|
||||
val parts = token.split('.')
|
||||
if (parts.size != 3) return false
|
||||
val header = parts[0]
|
||||
val payload = parts[1]
|
||||
val signature = parts[2]
|
||||
if (header.isBlank() || payload.isBlank() || signature.isBlank()) return false
|
||||
|
||||
val mac = Mac.getInstance("HmacSHA512")
|
||||
mac.init(SecretKeySpec(secret.toByteArray(StandardCharsets.UTF_8), "HmacSHA512"))
|
||||
val signingInput = "$header.$payload".toByteArray(StandardCharsets.UTF_8)
|
||||
val expected = mac.doFinal(signingInput)
|
||||
val expectedB64 = Base64.getUrlEncoder().withoutPadding().encodeToString(expected)
|
||||
|
||||
constantTimeEquals(expectedB64, signature)
|
||||
} catch (_: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun constantTimeEquals(a: String, b: String): Boolean {
|
||||
val aBytes = a.toByteArray(StandardCharsets.UTF_8)
|
||||
val bBytes = b.toByteArray(StandardCharsets.UTF_8)
|
||||
var diff = aBytes.size xor bBytes.size
|
||||
val minLen = if (aBytes.size < bBytes.size) aBytes.size else bBytes.size
|
||||
var i = 0
|
||||
while (i < minLen) {
|
||||
diff = diff or (aBytes[i].toInt() xor bBytes[i].toInt())
|
||||
i++
|
||||
}
|
||||
return diff == 0
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user