package be.simplenotes.app.routes import be.simplenotes.app.controllers.BaseController import be.simplenotes.app.controllers.NoteController import be.simplenotes.app.controllers.SettingsController import be.simplenotes.app.controllers.UserController import be.simplenotes.app.filters.ImmutableFilter import be.simplenotes.app.filters.SecurityFilter import be.simplenotes.app.filters.jwtPayload import be.simplenotes.domain.security.JwtPayload import org.http4k.core.* import org.http4k.core.Method.GET import org.http4k.core.Method.POST import org.http4k.filter.ResponseFilters import org.http4k.filter.ServerFilters.InitialiseRequestContext import org.http4k.routing.* class Router( private val baseController: BaseController, private val userController: UserController, private val noteController: NoteController, private val settingsController: SettingsController, private val requiredAuth: Filter, private val optionalAuth: Filter, private val errorFilter: Filter, private val contexts: RequestContexts, ) { operator fun invoke(): RoutingHttpHandler { val resourceLoader = ResourceLoader.Classpath(("/static")) val basicRoutes = routes( ImmutableFilter().then(static(resourceLoader, "woff2" to ContentType("font/woff2"))), ) infix fun PathMethod.public(handler: PublicHandler) = this to { handler(it, it.jwtPayload(contexts)) } infix fun PathMethod.protected(handler: ProtectedHandler) = this to { handler(it, it.jwtPayload(contexts)!!) } val publicRoutes: RoutingHttpHandler = routes( "/" bind GET public baseController::index, "/register" bind GET public userController::register, "/register" bind POST public userController::register, "/login" bind GET public userController::login, "/login" bind POST public userController::login, "/logout" bind POST to userController::logout, "/notes/public/{uuid}" bind GET public noteController::public, ) val protectedRoutes = routes( "/settings" bind GET protected settingsController::settings, "/settings" bind POST protected settingsController::settings, "/export" bind POST protected settingsController::export, "/notes" bind GET protected noteController::list, "/notes" bind POST protected noteController::search, "/notes/new" bind GET protected noteController::new, "/notes/new" bind POST protected noteController::new, "/notes/trash" bind GET protected noteController::trash, "/notes/{uuid}" bind GET protected noteController::note, "/notes/{uuid}" bind POST protected noteController::note, "/notes/{uuid}/edit" bind GET protected noteController::edit, "/notes/{uuid}/edit" bind POST protected noteController::edit, "/notes/deleted/{uuid}" bind POST protected noteController::deleted, ) val routes = routes( basicRoutes, optionalAuth.then(publicRoutes), requiredAuth.then(protectedRoutes), ) val globalFilters = errorFilter .then(InitialiseRequestContext(contexts)) .then(SecurityFilter()) .then(ResponseFilters.GZip()) return globalFilters.then(routes) } } private typealias PublicHandler = (Request, JwtPayload?) -> Response private typealias ProtectedHandler = (Request, JwtPayload) -> Response