public async Task Invoke(HttpContext context)
        {
            CaliforniaClientSession clientSession = new CaliforniaClientSession();

            if (context.Request.Cookies.TryGetValue(_serviceOptions.CookieName, out var cookie))
            {
                try
                {
                    JsonConvert.PopulateObject(cookie, clientSession);
                    if (clientSession.Revision < CaliforniaClientSession.TargetRevision)
                    {
                        clientSession.UpdateCaliforniaOptionsCookie(context.Response, _serviceOptions.CookieName);
                    }
                }
                catch (JsonSerializationException)
                {
                    // bad cookie format
                    context.Response.Cookies.Delete(_serviceOptions.CookieName);
                    clientSession = new CaliforniaClientSession();
                }
            }
            context.Features.Set <CaliforniaClientSession>(clientSession);

            await this._next.Invoke(context);
        }
        public static void UpdateCaliforniaOptionsCookie(this CaliforniaClientSession currentSession, HttpResponse response, string cookieName)
        {
            var updatedCookieValue = MakeCookieValue(currentSession);

            if (!string.IsNullOrEmpty(updatedCookieValue))
            {
                response.Cookies.Append(cookieName, updatedCookieValue,
                                        new CookieOptions
                {
                    Expires  = DateTimeOffset.UtcNow.AddYears(1),
                    SameSite = SameSiteMode.Strict,
                    HttpOnly = false     // TODO security documentation
                });
            }
            else
            {
                response.Cookies.Delete(cookieName);
            }
        }
 public static string MakeCookieValue(this CaliforniaClientSession currentSession)
 => JsonConvert.SerializeObject(currentSession, new JsonSerializerSettings()
 {
     NullValueHandling = NullValueHandling.Ignore
 });