116 lines
3.9 KiB
Kotlin

package be.simplenotes.app.controllers
import be.simplenotes.app.extensions.html
import be.simplenotes.app.extensions.isSecure
import be.simplenotes.app.extensions.redirect
import be.simplenotes.config.JwtConfig
import be.simplenotes.domain.usecases.UserService
import be.simplenotes.domain.usecases.users.login.*
import be.simplenotes.domain.usecases.users.register.InvalidRegisterForm
import be.simplenotes.domain.usecases.users.register.RegisterForm
import be.simplenotes.domain.usecases.users.register.UserExists
import be.simplenotes.types.LoggedInUser
import be.simplenotes.views.UserView
import org.http4k.core.Method.GET
import org.http4k.core.Request
import org.http4k.core.Response
import org.http4k.core.Status.Companion.OK
import org.http4k.core.body.form
import org.http4k.core.cookie.Cookie
import org.http4k.core.cookie.SameSite
import org.http4k.core.cookie.cookie
import org.http4k.core.cookie.invalidateCookie
import java.util.concurrent.TimeUnit
import javax.inject.Singleton
@Singleton
class UserController(
private val userService: UserService,
private val userView: UserView,
private val jwtConfig: JwtConfig,
) {
fun register(request: Request, loggedInUser: LoggedInUser?): Response {
if (request.method == GET) return Response(OK).html(
userView.register(loggedInUser)
)
val result = userService.register(request.registerForm())
return result.fold(
{
val html = when (it) {
UserExists -> userView.register(
loggedInUser,
error = "User already exists"
)
is InvalidRegisterForm ->
userView.register(
loggedInUser,
validationErrors = it.validationErrors
)
}
Response(OK).html(html)
},
{
Response.redirect("/login")
}
)
}
private fun Request.registerForm() = RegisterForm(form("username"), form("password"))
private fun Request.loginForm(): LoginForm = registerForm()
fun login(request: Request, loggedInUser: LoggedInUser?): Response {
if (request.method == GET) return Response(OK).html(
userView.login(loggedInUser)
)
val result = userService.login(request.loginForm())
return result.fold(
{
val html = when (it) {
Unregistered ->
userView.login(
loggedInUser,
error = "User does not exist"
)
WrongPassword ->
userView.login(
loggedInUser,
error = "Wrong password"
)
is InvalidLoginForm ->
userView.login(
loggedInUser,
validationErrors = it.validationErrors
)
}
Response(OK).html(html)
},
{ token ->
Response.redirect("/notes").loginCookie(token, request.isSecure())
}
)
}
private fun Response.loginCookie(token: Token, secure: Boolean): Response {
val validityInSeconds = TimeUnit.SECONDS.convert(jwtConfig.validity, jwtConfig.timeUnit)
return this.cookie(
Cookie(
name = "Bearer",
value = token,
path = "/",
httpOnly = true,
sameSite = SameSite.Lax,
maxAge = validityInSeconds,
secure = secure
)
)
}
fun logout(@Suppress("UNUSED_PARAMETER") request: Request) = Response.redirect("/")
.invalidateCookie("Bearer")
}