2023-02-06 04:26:36 +00:00
|
|
|
package chat
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"code.nonshy.com/nonshy/website/pkg/config"
|
2023-02-13 06:23:51 +00:00
|
|
|
"code.nonshy.com/nonshy/website/pkg/models"
|
2023-02-06 04:26:36 +00:00
|
|
|
"code.nonshy.com/nonshy/website/pkg/photo"
|
|
|
|
"code.nonshy.com/nonshy/website/pkg/session"
|
|
|
|
"code.nonshy.com/nonshy/website/pkg/templates"
|
|
|
|
"github.com/golang-jwt/jwt/v4"
|
|
|
|
)
|
|
|
|
|
|
|
|
// JWT claims.
|
|
|
|
type Claims struct {
|
|
|
|
// Custom claims.
|
|
|
|
IsAdmin bool `json:"op"`
|
|
|
|
Avatar string `json:"img"`
|
|
|
|
ProfileURL string `json:"url"`
|
|
|
|
|
|
|
|
// Standard claims. Notes:
|
|
|
|
// subject = username
|
|
|
|
jwt.RegisteredClaims
|
|
|
|
}
|
|
|
|
|
|
|
|
// Landing page for chat rooms.
|
|
|
|
func Landing() http.HandlerFunc {
|
|
|
|
tmpl := templates.Must("chat.html")
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
// Get the current user.
|
|
|
|
currentUser, err := session.CurrentUser(r)
|
|
|
|
if err != nil {
|
|
|
|
session.FlashError(w, r, "Couldn't get current user: %s", err)
|
|
|
|
templates.Redirect(w, "/")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Are they logging into the chat room?
|
2023-02-14 06:19:18 +00:00
|
|
|
var (
|
|
|
|
intent = r.FormValue("intent")
|
|
|
|
isShy = currentUser.IsShy()
|
|
|
|
)
|
2023-02-06 04:26:36 +00:00
|
|
|
if intent == "join" {
|
2023-02-14 06:19:18 +00:00
|
|
|
// If we are shy, block chat for now.
|
|
|
|
if isShy {
|
|
|
|
session.FlashError(w, r,
|
|
|
|
"You have a Shy Account and are not allowed in the chat room at this time where our non-shy members may "+
|
|
|
|
"be on camera.",
|
|
|
|
)
|
|
|
|
templates.Redirect(w, "/chat")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-02-06 04:26:36 +00:00
|
|
|
// Get our Chat JWT secret.
|
|
|
|
var (
|
|
|
|
secret = []byte(config.Current.BareRTC.JWTSecret)
|
|
|
|
chatURL = config.Current.BareRTC.URL
|
|
|
|
)
|
|
|
|
if len(secret) == 0 || chatURL == "" {
|
|
|
|
session.FlashError(w, r, "Couldn't sign you into the chat: JWT secret key or chat URL not configured!")
|
|
|
|
templates.Redirect(w, r.URL.Path)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-02-13 06:23:51 +00:00
|
|
|
// Avatar URL - masked if non-public.
|
|
|
|
avatar := photo.URLPath(currentUser.ProfilePhoto.CroppedFilename)
|
|
|
|
switch currentUser.ProfilePhoto.Visibility {
|
|
|
|
case models.PhotoPrivate:
|
|
|
|
avatar = "/static/img/shy-private.png"
|
|
|
|
case models.PhotoFriends:
|
|
|
|
avatar = "/static/img/shy-friends.png"
|
|
|
|
}
|
|
|
|
|
2023-02-06 04:26:36 +00:00
|
|
|
// Create the JWT claims.
|
|
|
|
claims := Claims{
|
|
|
|
IsAdmin: currentUser.IsAdmin,
|
2023-02-13 06:23:51 +00:00
|
|
|
Avatar: avatar,
|
2023-02-06 04:26:36 +00:00
|
|
|
ProfileURL: "/u/" + currentUser.Username,
|
|
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
|
|
// TODO: ExpiresAt 60 minutes to work around chat server reliability,
|
|
|
|
// should be shorter like 5 minutes.
|
|
|
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(60 * time.Minute)),
|
|
|
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
|
|
|
NotBefore: jwt.NewNumericDate(time.Now()),
|
|
|
|
Issuer: config.Title,
|
|
|
|
Subject: currentUser.Username,
|
|
|
|
ID: fmt.Sprintf("%d", currentUser.ID),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
|
|
ss, err := token.SignedString(secret)
|
|
|
|
if err != nil {
|
|
|
|
session.FlashError(w, r, "Couldn't sign you into the chat: %s", err)
|
|
|
|
templates.Redirect(w, r.URL.Path)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Redirect them to the chat room.
|
|
|
|
templates.Redirect(w, strings.TrimSuffix(chatURL, "/")+"/?jwt="+ss)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-02-10 07:07:07 +00:00
|
|
|
var vars = map[string]interface{}{
|
2023-02-14 06:19:18 +00:00
|
|
|
"ChatAPI": strings.TrimSuffix(config.Current.BareRTC.URL, "/") + "/api/statistics",
|
|
|
|
"IsShyUser": isShy,
|
2023-02-10 07:07:07 +00:00
|
|
|
}
|
2023-02-06 04:26:36 +00:00
|
|
|
if err := tmpl.Execute(w, r, vars); err != nil {
|
|
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|