mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-04-05 10:59:33 +00:00
Dynamically configure cookie and base-url
When `base-url` is the default (i.e. localhost), the cookie is now configured with the domain doing the request and the webapp is configured to run requests against the host in the address bar of the browser.
This commit is contained in:
parent
7104323e7e
commit
d8bb6dcba3
@ -83,6 +83,9 @@ case class LenientUri(
|
||||
}
|
||||
)
|
||||
|
||||
def isLocal: Boolean =
|
||||
host.exists(_.equalsIgnoreCase("localhost"))
|
||||
|
||||
def asString: String = {
|
||||
val schemePart = scheme.toList.mkString(":")
|
||||
val authPart = authority.map(a => s"//$a").getOrElse("")
|
||||
|
@ -11,8 +11,8 @@ case class CookieData(auth: AuthToken) {
|
||||
def accountId: AccountId = auth.account
|
||||
def asString: String = auth.asString
|
||||
|
||||
def asCookie(cfg: Config): ResponseCookie = {
|
||||
val domain = cfg.baseUrl.host
|
||||
def asCookie(cfg: Config, host: Option[String]): ResponseCookie = {
|
||||
val domain = CookieData.getDomain(cfg, host)
|
||||
val sec = cfg.baseUrl.scheme.exists(_.endsWith("s"))
|
||||
val path = cfg.baseUrl.path / "api" / "v1" / "sec"
|
||||
ResponseCookie(
|
||||
@ -29,6 +29,10 @@ object CookieData {
|
||||
val cookieName = "docspell_auth"
|
||||
val headerName = "X-Docspell-Auth"
|
||||
|
||||
private def getDomain(cfg: Config, remote: Option[String]): Option[String] =
|
||||
if (cfg.baseUrl.isLocal) remote.orElse(cfg.baseUrl.host)
|
||||
else cfg.baseUrl.host
|
||||
|
||||
def authenticator[F[_]](r: Request[F]): Either[String, String] =
|
||||
fromCookie(r).orElse(fromHeader(r))
|
||||
|
||||
@ -47,11 +51,11 @@ object CookieData {
|
||||
.map(_.value)
|
||||
.toRight("Couldn't find an authenticator")
|
||||
|
||||
def deleteCookie(cfg: Config): ResponseCookie =
|
||||
def deleteCookie(cfg: Config, remoteHost: Option[String]): ResponseCookie =
|
||||
ResponseCookie(
|
||||
cookieName,
|
||||
"",
|
||||
domain = cfg.baseUrl.host,
|
||||
domain = getDomain(cfg, remoteHost),
|
||||
path = Some(cfg.baseUrl.path / "api" / "v1" / "sec").map(_.asString),
|
||||
httpOnly = true,
|
||||
secure = cfg.baseUrl.scheme.exists(_.endsWith("s")),
|
||||
|
@ -23,7 +23,8 @@ object LoginRoutes {
|
||||
for {
|
||||
up <- req.as[UserPass]
|
||||
res <- S.loginUserPass(cfg.auth)(Login.UserPass(up.account, up.password))
|
||||
resp <- makeResponse(dsl, cfg, res, up.account)
|
||||
remote = req.from.map(_.getHostName())
|
||||
resp <- makeResponse(dsl, cfg, remote, res, up.account)
|
||||
} yield resp
|
||||
}
|
||||
}
|
||||
@ -36,16 +37,17 @@ object LoginRoutes {
|
||||
case req @ POST -> Root / "session" =>
|
||||
Authenticate
|
||||
.authenticateRequest(S.loginSession(cfg.auth))(req)
|
||||
.flatMap(res => makeResponse(dsl, cfg, res, ""))
|
||||
.flatMap(res => makeResponse(dsl, cfg, req.from.map(_.getHostName), res, ""))
|
||||
|
||||
case POST -> Root / "logout" =>
|
||||
Ok().map(_.addCookie(CookieData.deleteCookie(cfg)))
|
||||
case req @ POST -> Root / "logout" =>
|
||||
Ok().map(_.addCookie(CookieData.deleteCookie(cfg, req.from.map(_.getHostName))))
|
||||
}
|
||||
}
|
||||
|
||||
def makeResponse[F[_]: Effect](
|
||||
dsl: Http4sDsl[F],
|
||||
cfg: Config,
|
||||
remoteHost: Option[String],
|
||||
res: Login.Result,
|
||||
account: String
|
||||
): F[Response[F]] = {
|
||||
@ -63,7 +65,7 @@ object LoginRoutes {
|
||||
Some(cd.asString),
|
||||
cfg.auth.sessionValid.millis
|
||||
)
|
||||
).map(_.addCookie(cd.asCookie(cfg)))
|
||||
).map(_.addCookie(cd.asCookie(cfg, remoteHost)))
|
||||
} yield resp
|
||||
case _ =>
|
||||
Ok(AuthResult("", account, false, "Login failed.", None, 0L))
|
||||
|
@ -11,7 +11,7 @@ import yamusca.imports._
|
||||
|
||||
case class Flags(
|
||||
appName: String,
|
||||
baseUrl: LenientUri,
|
||||
baseUrl: String,
|
||||
signupMode: SignupConfig.Mode,
|
||||
docspellAssetPath: String,
|
||||
integrationEnabled: Boolean,
|
||||
@ -25,7 +25,7 @@ object Flags {
|
||||
def apply(cfg: Config): Flags =
|
||||
Flags(
|
||||
cfg.appName,
|
||||
cfg.baseUrl,
|
||||
getBaseUrl(cfg),
|
||||
cfg.backend.signup.mode,
|
||||
s"/app/assets/docspell-webapp/${BuildInfo.version}",
|
||||
cfg.integrationEndpoint.enabled,
|
||||
@ -35,6 +35,10 @@ object Flags {
|
||||
cfg.showClassificationSettings
|
||||
)
|
||||
|
||||
private def getBaseUrl(cfg: Config): String =
|
||||
if (cfg.baseUrl.isLocal) cfg.baseUrl.path.asString
|
||||
else cfg.baseUrl.asString
|
||||
|
||||
implicit val jsonEncoder: Encoder[Flags] =
|
||||
deriveEncoder[Flags]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user