Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions server/src/main/kotlin/suwayomi/tachidesk/server/JavalinSetup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.future.future
import kotlinx.coroutines.runBlocking
import org.eclipse.jetty.server.ServerConnector
import org.eclipse.jetty.server.session.SessionHandler
import suwayomi.tachidesk.global.GlobalAPI
import suwayomi.tachidesk.graphql.GraphQL
import suwayomi.tachidesk.graphql.types.AuthMode
Expand All @@ -40,6 +41,7 @@ import java.util.Locale
import java.util.concurrent.CompletableFuture
import kotlin.concurrent.thread
import kotlin.time.Duration.Companion.days
import xyz.nulldev.ts.config.GlobalConfigManager

object JavalinSetup {
private val logger = KotlinLogging.logger {}
Expand Down Expand Up @@ -73,6 +75,17 @@ object JavalinSetup {
}

var connectorAdded = false
// Configure Jetty session cookie: 0 = default behavior, >0 = persistent Max-Age in minutes
config.jetty.modifyServletContextHandler { context ->
val sessionHandler = context.sessionHandler ?: SessionHandler()
sessionHandler.sessionCookieConfig.apply {
val cookieMaxAgeMinutes: Int = serverConfig.sessionCookieMaxAgeMinutes.value
if (cookieMaxAgeMinutes > 0) maxAge = (cookieMaxAgeMinutes * 60)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (cookieMaxAgeMinutes > 0) maxAge = (cookieMaxAgeMinutes * 60)
if (cookieMaxAgeMinutes > 0) maxAge = cookieMaxAgeMinutes.minutes.inWholeSeconds.toInt()

isHttpOnly = true
// Keep defaults for name/path; JSESSIONID and "/" are used by default
}
context.sessionHandler = sessionHandler
}
config.jetty.modifyServer { server ->
if (!connectorAdded) {
val connector =
Expand Down Expand Up @@ -102,7 +115,6 @@ object JavalinSetup {
connectorAdded = true
}
}

config.bundledPlugins.enableCors { cors ->
cors.addRule {
it.allowCredentials = true
Expand Down Expand Up @@ -146,11 +158,12 @@ object JavalinSetup {

if (isValid) {
val redirect = ctx.queryParam("redirect") ?: "/"
// NOTE: We currently have no session handler attached.
// Thus, all sessions are stored in memory and not persisted.
// Furthermore, default session timeout appears to be 30m
// NOTE: We currently have no session persistence configured.
// Sessions are in-memory; server-side inactivity timeout is extended below.
ctx.header("Location", redirect)
ctx.sessionAttribute("logged-in", username)
// Extend server-side session inactivity timeout from ~30 minutes to 30 days
ctx.req().session.maxInactiveInterval = 30.days.inWholeSeconds.toInt()
throw RedirectResponse(HttpStatus.SEE_OTHER)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ class ServerConfig(
val authMode: MutableStateFlow<AuthMode> by OverrideConfigValue()
val authUsername: MutableStateFlow<String> by OverrideConfigValue()
val authPassword: MutableStateFlow<String> by OverrideConfigValue()
// Sessions
val sessionCookieMaxAgeMinutes: MutableStateFlow<Int> by OverrideConfigValue()
val basicAuthEnabled: MutableStateFlow<Boolean> by MigratedConfigValue({
authMode.value == AuthMode.BASIC_AUTH
}) {
Expand Down
4 changes: 4 additions & 0 deletions server/src/main/resources/server-reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ server.authMode = "none" # none, basic_auth or simple_login
server.authUsername = ""
server.authPassword = ""

# Sessions
# 0 = default session cookie behavior (no persistent Max-Age); >0 = persistent JSESSIONID with given max-age in minutes
server.sessionCookieMaxAgeMinutes = 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say put it under authentication and name it simpleAuthSessionCookieMaxAge, add a comment after it similar to the other comments


# misc
server.debugLogsEnabled = false
server.systemTrayEnabled = true
Expand Down
Loading