Compare commits
7 Commits
f113ae6cba
...
master
Author | SHA1 | Date | |
---|---|---|---|
413ad0629a | |||
aa3c0a9dbf | |||
00ef003be9 | |||
e21ec2e81c | |||
4350d197f9 | |||
d5422ab5b0 | |||
4a08fd8f1c |
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,4 +3,5 @@
|
|||||||
/default.etcd
|
/default.etcd
|
||||||
/keys
|
/keys
|
||||||
|
|
||||||
|
.idea
|
||||||
.DS_Store
|
.DS_Store
|
@ -6,10 +6,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.solsynth.dev/hypernet/nexus/pkg/internal/cache"
|
|
||||||
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
|
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
|
||||||
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
"git.solsynth.dev/hypernet/nexus/pkg/nex/cachekit"
|
|
||||||
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
|
||||||
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
@ -22,19 +20,6 @@ func userinfoFetch(c *fiber.Ctx) error {
|
|||||||
return fiber.NewError(fiber.StatusUnauthorized, "user principal data was not found")
|
return fiber.NewError(fiber.StatusUnauthorized, "user principal data was not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, err := cachekit.Get[sec.UserInfo](
|
|
||||||
cache.Kcc,
|
|
||||||
cachekit.FKey(cachekit.DAUserInfoPrefix, claims.Session),
|
|
||||||
); err == nil {
|
|
||||||
c.Locals("nex_user", &val)
|
|
||||||
tk, err := IWriter.WriteUserInfoJwt(val)
|
|
||||||
if err != nil {
|
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("unable to sign userinfo: %v", err))
|
|
||||||
}
|
|
||||||
c.Locals("nex_token", tk)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
service := directory.GetServiceInstanceByType(nex.ServiceTypeAuth)
|
service := directory.GetServiceInstanceByType(nex.ServiceTypeAuth)
|
||||||
if service != nil {
|
if service != nil {
|
||||||
conn, err := service.GetGrpcConn()
|
conn, err := service.GetGrpcConn()
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func MapControllers(app *fiber.App) {
|
func MapControllers(app *fiber.App) {
|
||||||
|
app.Get("/meet/:channel", renderMeetRoom)
|
||||||
app.Get("/captcha", renderCaptcha)
|
app.Get("/captcha", renderCaptcha)
|
||||||
app.Post("/captcha", validateCaptcha)
|
app.Post("/captcha", validateCaptcha)
|
||||||
app.Get("/check-ip", getClientIP)
|
app.Get("/check-ip", getClientIP)
|
||||||
|
55
pkg/internal/web/api/meet.go
Normal file
55
pkg/internal/web/api/meet.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type meetRoomArgs struct {
|
||||||
|
RoomName string `json:"room_name"`
|
||||||
|
User meetRoomUser `json:"user"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type meetRoomUser struct {
|
||||||
|
Avatar string `json:"avatar"`
|
||||||
|
Nick string `json:"nick"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderMeetRoom(c *fiber.Ctx) error {
|
||||||
|
if err := sec.EnsureAuthenticated(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user := c.Locals("nex_user").(*sec.UserInfo)
|
||||||
|
|
||||||
|
channel := c.Params("channel")
|
||||||
|
|
||||||
|
var nick string
|
||||||
|
if val, ok := user.Metadata["nick"].(string); ok {
|
||||||
|
nick = val
|
||||||
|
} else {
|
||||||
|
nick = user.Name
|
||||||
|
}
|
||||||
|
var avatar string
|
||||||
|
if val, ok := user.Metadata["avatar"].(string); ok {
|
||||||
|
if strings.HasPrefix(val, "http") {
|
||||||
|
avatar = val
|
||||||
|
} else {
|
||||||
|
endpoint := viper.GetString("resources_endpoint")
|
||||||
|
avatar = fmt.Sprintf("%s/attachments/%s", endpoint, val)
|
||||||
|
}
|
||||||
|
avatar = fmt.Sprintf("\"%s\"", avatar) // Make the avatar a string to embed into the js
|
||||||
|
} else {
|
||||||
|
avatar = "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Render("meet", meetRoomArgs{
|
||||||
|
RoomName: fmt.Sprintf("%s-%s", "sn-chat", channel),
|
||||||
|
User: meetRoomUser{
|
||||||
|
Avatar: avatar,
|
||||||
|
Nick: nick,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
@ -63,7 +63,7 @@ func NewServer() *WebApp {
|
|||||||
Expiration: 60 * time.Second,
|
Expiration: 60 * time.Second,
|
||||||
LimiterMiddleware: limiter.SlidingWindow{},
|
LimiterMiddleware: limiter.SlidingWindow{},
|
||||||
Next: func(c *fiber.Ctx) bool {
|
Next: func(c *fiber.Ctx) bool {
|
||||||
return lo.Contains([]string{"GET", "HEAD", "OPTIONS", "CONNECT", "TRACE"}, c.Method())
|
return lo.Contains([]string{"POST", "PUT", "DELETE", "PATCH"}, c.Method())
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
app.Use(limiter.New(limiter.Config{
|
app.Use(limiter.New(limiter.Config{
|
||||||
@ -71,7 +71,7 @@ func NewServer() *WebApp {
|
|||||||
Expiration: 60 * time.Second,
|
Expiration: 60 * time.Second,
|
||||||
LimiterMiddleware: limiter.SlidingWindow{},
|
LimiterMiddleware: limiter.SlidingWindow{},
|
||||||
Next: func(c *fiber.Ctx) bool {
|
Next: func(c *fiber.Ctx) bool {
|
||||||
return lo.Contains([]string{"POST", "PUT", "DELETE", "PATCH"}, c.Method())
|
return lo.Contains([]string{"GET", "HEAD", "OPTIONS", "CONNECT", "TRACE"}, c.Method())
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -5,7 +5,9 @@ import "fmt"
|
|||||||
// Those constants are used to directly get the cached data from redis
|
// Those constants are used to directly get the cached data from redis
|
||||||
// Formatted like {prefix}#{key}
|
// Formatted like {prefix}#{key}
|
||||||
const (
|
const (
|
||||||
DAUserInfoPrefix = "userinfo"
|
DAAttachment = "attachment"
|
||||||
|
DAUser = "account"
|
||||||
|
DARealm = "realm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FKey(prefix string, key any) string {
|
func FKey(prefix string, key any) string {
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
// And able to recreate the conn with different options
|
// And able to recreate the conn with different options
|
||||||
var (
|
var (
|
||||||
rdc *redis.Client
|
rdc *redis.Client
|
||||||
rdl *sync.Mutex
|
rdl sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
type Conn struct {
|
type Conn struct {
|
||||||
|
@ -2,6 +2,8 @@ bind = "0.0.0.0:8001"
|
|||||||
grpc_bind = "0.0.0.0:7001"
|
grpc_bind = "0.0.0.0:7001"
|
||||||
domain = "localhost"
|
domain = "localhost"
|
||||||
|
|
||||||
|
resources_endpoint = "https://api.sn.solsynth.dev/cgi/uc"
|
||||||
|
|
||||||
templates_dir = "./templates"
|
templates_dir = "./templates"
|
||||||
ip_block_path = "./ip_block.list"
|
ip_block_path = "./ip_block.list"
|
||||||
|
|
||||||
|
52
templates/meet.tmpl
Normal file
52
templates/meet.tmpl
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Solar Network Meet</title>
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src='https://meet.element.io/external_api.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="parent">
|
||||||
|
<div class="container" id="meet">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function getQueryParam(name) {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
return urlParams.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const node = document.querySelector('#meet');
|
||||||
|
|
||||||
|
const domain = 'meet.element.io';
|
||||||
|
const options = {
|
||||||
|
roomName: "{{ .RoomName }}",
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
parentNode: node,
|
||||||
|
userInfo: {
|
||||||
|
avatar: {{ .User.Avatar }},
|
||||||
|
displayName: "{{ .User.Nick }}"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const api = new JitsiMeetExternalAPI(domain, options)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Reference in New Issue
Block a user