113 lines
4.8 KiB
Kotlin
113 lines
4.8 KiB
Kotlin
package be.simplenotes.app.routes
|
|
|
|
import be.simplenotes.app.api.ApiNoteController
|
|
import be.simplenotes.app.api.ApiUserController
|
|
import be.simplenotes.app.controllers.*
|
|
import be.simplenotes.app.filters.*
|
|
import be.simplenotes.types.LoggedInUser
|
|
import org.http4k.core.*
|
|
import org.http4k.core.Method.*
|
|
import org.http4k.filter.ResponseFilters.GZip
|
|
import org.http4k.filter.ServerFilters.InitialiseRequestContext
|
|
import org.http4k.routing.*
|
|
import org.http4k.routing.ResourceLoader.Companion.Classpath
|
|
|
|
class Router(
|
|
private val baseController: BaseController,
|
|
private val userController: UserController,
|
|
private val noteController: NoteController,
|
|
private val settingsController: SettingsController,
|
|
private val apiUserController: ApiUserController,
|
|
private val apiNoteController: ApiNoteController,
|
|
private val healthCheckController: HealthCheckController,
|
|
private val requiredAuth: Filter,
|
|
private val optionalAuth: Filter,
|
|
private val apiAuth: Filter,
|
|
private val errorFilter: ErrorFilter,
|
|
private val transactionFilter: TransactionFilter,
|
|
private val contexts: RequestContexts,
|
|
) {
|
|
operator fun invoke(): RoutingHttpHandler {
|
|
|
|
val basicRoutes =
|
|
routes(
|
|
"/health" bind GET to healthCheckController::healthCheck,
|
|
ImmutableFilter.then(
|
|
static(
|
|
Classpath("/static"),
|
|
"woff2" to ContentType("font/woff2"),
|
|
"webmanifest" to ContentType("application/manifest+json")
|
|
)
|
|
)
|
|
)
|
|
|
|
val publicRoutes = routes(
|
|
"/" bind GET public baseController::index,
|
|
"/register" bind GET public userController::register,
|
|
"/register" bind POST `public transactional` 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 transactional 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 transactional noteController::new,
|
|
"/notes/trash" bind GET protected noteController::trash,
|
|
"/notes/{uuid}" bind GET protected noteController::note,
|
|
"/notes/{uuid}" bind POST transactional noteController::note,
|
|
"/notes/{uuid}/edit" bind GET protected noteController::edit,
|
|
"/notes/{uuid}/edit" bind POST transactional noteController::edit,
|
|
"/notes/deleted/{uuid}" bind POST transactional noteController::deleted,
|
|
)
|
|
|
|
val apiRoutes = routes(
|
|
"/api/login" bind POST to apiUserController::login,
|
|
)
|
|
|
|
val protectedApiRoutes = routes(
|
|
"/api/notes" bind GET protected apiNoteController::notes,
|
|
"/api/notes" bind POST transactional apiNoteController::createNote,
|
|
"/api/notes/search" bind POST transactional apiNoteController::search,
|
|
"/api/notes/{uuid}" bind GET protected apiNoteController::note,
|
|
"/api/notes/{uuid}" bind PUT transactional apiNoteController::update,
|
|
)
|
|
|
|
val routes = routes(
|
|
basicRoutes,
|
|
optionalAuth.then(publicRoutes),
|
|
requiredAuth.then(protectedRoutes),
|
|
apiAuth.then(protectedApiRoutes),
|
|
apiRoutes,
|
|
)
|
|
|
|
val globalFilters = errorFilter
|
|
.then(InitialiseRequestContext(contexts))
|
|
.then(SecurityFilter)
|
|
.then(GZip())
|
|
|
|
return globalFilters.then(routes)
|
|
}
|
|
|
|
private inline infix fun PathMethod.public(crossinline handler: PublicHandler) =
|
|
this to { handler(it, it.jwtPayload(contexts)) }
|
|
|
|
private inline infix fun PathMethod.protected(crossinline handler: ProtectedHandler) =
|
|
this to { handler(it, it.jwtPayload(contexts)!!) }
|
|
|
|
private inline infix fun PathMethod.transactional(crossinline handler: ProtectedHandler) =
|
|
this to transactionFilter.then { handler(it, it.jwtPayload(contexts)!!) }
|
|
|
|
private inline infix fun PathMethod.`public transactional`(crossinline handler: PublicHandler) =
|
|
this to transactionFilter.then { handler(it, it.jwtPayload(contexts)) }
|
|
}
|
|
|
|
private typealias PublicHandler = (Request, LoggedInUser?) -> Response
|
|
private typealias ProtectedHandler = (Request, LoggedInUser) -> Response
|