/
x_color_scheme.go
80 lines (64 loc) · 1.77 KB
/
x_color_scheme.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package webapp
import (
"context"
"net/http"
"github.com/authgear/authgear-server/pkg/util/httputil"
)
func isValidColorScheme(s string) bool {
return s == "light" || s == "dark"
}
// ColorSchemeCookieDef is a HTTP session cookie.
var ColorSchemeCookieDef = &httputil.CookieDef{
NameSuffix: "x_color_scheme",
Path: "/",
SameSite: http.SameSiteNoneMode,
}
type colorSchemeContextKeyType struct{}
var colorSchemeContextKey = colorSchemeContextKeyType{}
type colorSchemeContext struct {
ColorScheme string
}
func WithColorScheme(ctx context.Context, colorScheme string) context.Context {
v, ok := ctx.Value(colorSchemeContextKey).(*colorSchemeContext)
if ok {
v.ColorScheme = colorScheme
return ctx
}
return context.WithValue(ctx, colorSchemeContextKey, &colorSchemeContext{
ColorScheme: colorScheme,
})
}
func GetColorScheme(ctx context.Context) string {
v, ok := ctx.Value(colorSchemeContextKey).(*colorSchemeContext)
if !ok {
return ""
}
return v.ColorScheme
}
type ColorSchemeMiddleware struct {
Cookies CookieManager
}
func (m *ColorSchemeMiddleware) Handle(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
colorScheme := q.Get("x_color_scheme")
if isValidColorScheme(colorScheme) {
// Persist to cookie.
cookie := m.Cookies.ValueCookie(ColorSchemeCookieDef, colorScheme)
httputil.UpdateCookie(w, cookie)
}
// Restore from cookie.
if colorScheme == "" {
cookie, err := m.Cookies.GetCookie(r, ColorSchemeCookieDef)
if err == nil {
colorScheme = cookie.Value
}
}
// Restore into request context.
if isValidColorScheme(colorScheme) {
ctx := WithColorScheme(r.Context(), colorScheme)
r = r.WithContext(ctx)
}
next.ServeHTTP(w, r)
})
}