BareRTC/pkg/pages.go

141 lines
3.6 KiB
Go

package barertc
import (
"fmt"
"html/template"
"net/http"
"strings"
"git.kirsle.net/apps/barertc/pkg/config"
"git.kirsle.net/apps/barertc/pkg/jwt"
"git.kirsle.net/apps/barertc/pkg/log"
"git.kirsle.net/apps/barertc/pkg/util"
)
// IndexPage returns the HTML template for the chat room.
func IndexPage() http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Load the template, TODO: once on server startup.
tmpl := template.New("index")
// Handle a JWT authentication token.
var (
tokenStr = r.FormValue("jwt")
claims = &jwt.Claims{}
authOK bool
blocklist = []string{} // cached blocklist from your website, for JWT auth only
)
if tokenStr != "" {
parsed, ok, err := jwt.ParseAndValidate(tokenStr)
if err != nil {
w.WriteHeader(http.StatusForbidden)
w.Write([]byte(
fmt.Sprintf("Error parsing your JWT token: %s", err),
))
return
}
authOK = ok
claims = parsed
blocklist = GetCachedBlocklist(claims.Subject)
}
// Are we enforcing strict JWT authentication?
if config.Current.JWT.Enabled && config.Current.JWT.Strict && !authOK {
// Do we have a landing page to redirect to?
if config.Current.JWT.LandingPageURL != "" {
w.Header().Add("Location", config.Current.JWT.LandingPageURL)
w.WriteHeader(http.StatusFound)
return
}
w.WriteHeader(http.StatusForbidden)
w.Write([]byte(
"Authentication denied. Please go back and try again.",
))
return
}
// Variables to give to the front-end page.
var values = map[string]interface{}{
// A cache-busting hash for JS and CSS includes.
"CacheHash": util.RandomString(8),
// The current website settings.
"Config": config.Current,
// Authentication settings.
"JWTTokenString": tokenStr,
"JWTAuthOK": authOK,
"JWTClaims": claims,
// Cached user blocklist sent by your website.
"CachedBlocklist": blocklist,
}
tmpl.Funcs(template.FuncMap{
"AsHTML": func(v string) template.HTML {
return template.HTML(v)
},
"AsJS": func(v interface{}) template.JS {
return template.JS(fmt.Sprintf("%v", v))
},
})
tmpl, err := tmpl.ParseFiles("dist/index.html")
if err != nil {
panic(err.Error())
}
// END load the template
log.Info("GET / [%s] %s", r.RemoteAddr, strings.Join([]string{
r.Header.Get("X-Forwarded-For"),
r.Header.Get("X-Real-IP"),
r.Header.Get("User-Agent"),
util.IPAddress(r),
}, " "))
tmpl.ExecuteTemplate(w, "index", values)
})
}
// AboutPage returns the HTML template for the about page.
func AboutPage() http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Load the template, TODO: once on server startup.
tmpl := template.New("index")
// Variables to give to the front-end page.
var values = map[string]interface{}{
// A cache-busting hash for JS and CSS includes.
"CacheHash": util.RandomString(8),
// The current website settings.
"Config": config.Current,
}
tmpl.Funcs(template.FuncMap{
"AsHTML": func(v string) template.HTML {
return template.HTML(v)
},
})
tmpl, err := tmpl.ParseFiles("web/templates/about.html")
if err != nil {
panic(err.Error())
}
tmpl.ExecuteTemplate(w, "index", values)
})
}
// LogoutPage returns the HTML template for the logout page.
func LogoutPage() http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Load the template, TODO: once on server startup.
tmpl := template.New("index")
tmpl, err := tmpl.ParseFiles("web/templates/logout.html")
if err != nil {
panic(err.Error())
}
tmpl.ExecuteTemplate(w, "index", nil)
})
}