- password validation

- Adding and refactoring tests
This commit is contained in:
aldemirm 2026-09-14 09:58:46 +02:00
parent c3fc1e3178
commit b71ce98ede
2 changed files with 70 additions and 3 deletions

View file

@ -13,6 +13,25 @@ import io.ktor.server.routing.*
import org.mindrot.jbcrypt.BCrypt import org.mindrot.jbcrypt.BCrypt
import java.util.UUID import java.util.UUID
fun isValidPassword(password: String): Boolean {
if (password.length < 8) return false
val hasUppercase = password.any { it.isUpperCase() }
val hasEmoji = password.any { char ->
val type = Character.getType(char).toByte()
type == Character.SURROGATE ||
type == Character.OTHER_SYMBOL ||
char.code in 0x1F600..0x1F64F ||
char.code in 0x1F300..0x1F5FF ||
char.code in 0x1F680..0x1F6FF ||
char.code in 0x2600..0x26FF
}
val hasSpecialChar = password.any { !it.isLetterOrDigit() && !hasEmoji }
return hasUppercase && hasSpecialChar && !hasEmoji
}
fun Application.configureRouting(repository: KidioRepository, jwtService : JwtService) { fun Application.configureRouting(repository: KidioRepository, jwtService : JwtService) {
routing { routing {
post("/api/v1/auth/register") { post("/api/v1/auth/register") {
@ -21,6 +40,13 @@ fun Application.configureRouting(repository: KidioRepository, jwtService : JwtSe
call.respond(HttpStatusCode.BadRequest, "Bitte füllen Sie alle Felder aus") call.respond(HttpStatusCode.BadRequest, "Bitte füllen Sie alle Felder aus")
return@post return@post
} }
if (!isValidPassword(registerRequest.passwordPlain)) {
call.respond(
HttpStatusCode.BadRequest,
"Das Passwort muss mindestens 8 Zeichen lang sein, mindestens einen Großbuchstaben und ein Sonderzeichen enthalten und darf keine Emojis enthalten."
)
return@post
}
if (registerRequest.parentPin.length != 4) { if (registerRequest.parentPin.length != 4) {
call.respond(HttpStatusCode.BadRequest, "Die Eltern-PIN muss genau 4 Ziffern lang sein") call.respond(HttpStatusCode.BadRequest, "Die Eltern-PIN muss genau 4 Ziffern lang sein")
return@post return@post

View file

@ -71,7 +71,7 @@ class ServerTest {
setBody( setBody(
"""{ """{
"email": "test@family.de", "email": "test@family.de",
"passwordPlain": "strengGeheim1", "passwordPlain": "StrengGeheim1!",
"familyName": "Familie Schmidt", "familyName": "Familie Schmidt",
"childAge": 8, "childAge": 8,
"parentPin": "4321" "parentPin": "4321"
@ -87,7 +87,7 @@ class ServerTest {
setBody( setBody(
"""{ """{
"email": "test@family.de", "email": "test@family.de",
"passwordPlain": "strengGeheim1" "passwordPlain": "StrengGeheim1!"
}""" }"""
) )
} }
@ -97,6 +97,47 @@ class ServerTest {
assertEquals("Familie Schmidt", loginJson.familyName) assertEquals("Familie Schmidt", loginJson.familyName)
} }
@Test
fun `test registration rejects invalid passwords`() = testApplication {
val jwtService = JwtService()
val repository = InMemoryKidioRepository()
application {
install(ServerContentNegotiation) {
json()
}
configureSecurity(jwtService)
configureRouting(repository, jwtService)
}
val invalidPasswords = listOf(
"Kurz1!",
"keingrossbuch1!",
"KeinSonder12",
"Passwort123!😊"
)
for (password in invalidPasswords) {
val response = client.post("/api/v1/auth/register") {
header(HttpHeaders.ContentType, ContentType.Application.Json.toString())
setBody(
"""{
"email": "test_${System.currentTimeMillis()}@family.de",
"passwordPlain": "$password",
"familyName": "Familie Schmidt",
"childAge": 8,
"parentPin": "4321"
}"""
)
}
assertEquals(
HttpStatusCode.BadRequest,
response.status,
"Passwort '$password' hätte abgelehnt werden müssen!"
)
}
}
@Test @Test
fun `test tasks endpoint and verify with jwt`() = testApplication { fun `test tasks endpoint and verify with jwt`() = testApplication {
val jwtService = JwtService() val jwtService = JwtService()