feat/gitignore #9
|
|
@ -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,10 +40,17 @@ 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
|
||||||
}
|
}
|
||||||
val existingUser = repository.findByEmail(registerRequest.email)
|
val existingUser = repository.findByEmail(registerRequest.email)
|
||||||
if (existingUser != null) {
|
if (existingUser != null) {
|
||||||
call.respond(HttpStatusCode.Conflict, "Ein Benutzer mit dieser E-Mail-Adresse existiert bereits")
|
call.respond(HttpStatusCode.Conflict, "Ein Benutzer mit dieser E-Mail-Adresse existiert bereits")
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue