Skip to content
Permalink
Browse files

Added support for session id in URL and caching and retrieval in loca…

…l storage in the browser
  • Loading branch information...
darkfrog26 committed Jul 30, 2019
1 parent 9e82fde commit a41ebd1b59455884943ac11e75c53bf9df203c11
@@ -2,7 +2,7 @@ package io.youi.app

import io.youi.ajax.AjaxRequest
import io.youi.app.screen.ScreenManager
import io.youi.{History, JavaScriptError, JavaScriptLog}
import io.youi.{History, JavaScriptError, JavaScriptLog, LocalStorage}
import io.youi.app.sourceMap.ErrorTrace
import org.scalajs.dom._
import io.youi.dom._
@@ -53,6 +53,21 @@ trait ClientApplication extends YouIApplication with ScreenManager {
}
}

// Client-side management and caching of URL-based session id
LocalStorage.get[String]("sessionId") match {
case Some(sessionId) => if (History.url().param("sessionId").contains(sessionId)) {
// Already set, nothing needed
} else {
// Redirect to stored session id
val url = History.url().withParam("sessionId", sessionId, append = false)
History.set(url)
}
case None => History.url.param("sessionId").foreach { sessionId =>
// Store the session id in local storage
LocalStorage("sessionId") = sessionId
}
}

def autoReload: Boolean = true

override def cached(url: URL): String = url.asPath()
@@ -11,5 +11,7 @@ class MySession {
}

object MySession extends InMemorySessionManager[MySession] {
override protected def applyToURL: Boolean = true

override protected def create(sessionId: String): Future[MySession] = Future.successful(new MySession)
}
@@ -14,6 +14,11 @@ import scribe.Execution.global
* @tparam Session the type of session
*/
trait SessionManager[Session] {
/**
* Set to true to apply the session id to the URL. Defaults to false.
*/
protected def applyToURL: Boolean = false

/**
* Functional use of a Session via a transaction that is fully managed with the result being updated to the manager
*
@@ -133,14 +138,15 @@ trait SessionManager[Session] {
protected def generateSessionId: String = Unique()

/**
* Retrieves the session id from the request / response cookies if available.
* Retrieves the session id from the request / response cookies if available and from the URL if applyToURL is true.
*
* @param connection the HttpConnection to look in
* @return the session id if found
*/
protected def sessionId(connection: HttpConnection): Option[String] = {
connection.store.get[String]("sessionId") match {
case Some(id) => Some(id)
case _ if applyToURL => connection.request.url.param("sessionId")
case None => {
val config = connection.server.config.session
connection.request.cookies.find(_.name == config.name()).map(_.value) match {
@@ -155,7 +161,8 @@ trait SessionManager[Session] {
}

/**
* Applies a new session id to an HttpConnection. Creates a cookie and sets it on the HttpResponse.
* Applies a new session id to an HttpConnection. Creates a cookie and sets it on the HttpResponse. Also updates the
* URL if applyToURL is true.
*
* @param id the session id to apply
* @param connection the HttpConnection to use
@@ -178,7 +185,11 @@ trait SessionManager[Session] {
httpOnly = config.httpOnly(),
sameSite = config.sameSite()
)
response.withHeader(Headers.Response.`Set-Cookie`(cookie))
if (applyToURL) {
response.withRedirect(connection.request.url.withParam("sessionId", id).toString)
} else {
response.withHeader(Headers.Response.`Set-Cookie`(cookie))
}
}
}
}

0 comments on commit a41ebd1

Please sign in to comment.
You can’t perform that action at this time.