kopia lustrzana https://codeberg.org/nmkj/audon
add static url
rodzic
073510d4b5
commit
17e07d28a1
|
@ -2,7 +2,7 @@ audon.localhost {
|
||||||
tls /etc/caddy/certs/cert.pem /etc/caddy/certs/key.pem
|
tls /etc/caddy/certs/cert.pem /etc/caddy/certs/key.pem
|
||||||
encode zstd gzip
|
encode zstd gzip
|
||||||
@backend {
|
@backend {
|
||||||
path /app/* /api/* /storage/*
|
path /app/* /api/* /storage/* /u/*
|
||||||
}
|
}
|
||||||
handle @backend {
|
handle @backend {
|
||||||
reverse_proxy devcontainer:8100
|
reverse_proxy devcontainer:8100
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "audon-fe",
|
"name": "audon-fe",
|
||||||
"version": "0.2.0",
|
"version": "0.2.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "audon-fe",
|
"name": "audon-fe",
|
||||||
"version": "0.2.0",
|
"version": "0.2.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@intlify/unplugin-vue-i18n": "^0.8.1",
|
"@intlify/unplugin-vue-i18n": "^0.8.1",
|
||||||
"@picmo/popup-picker": "^5.7.2",
|
"@picmo/popup-picker": "^5.7.2",
|
||||||
|
@ -809,9 +809,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.8.1",
|
"version": "8.8.2",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
|
||||||
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
|
"integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
|
@ -895,9 +895,9 @@
|
||||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.5.tgz",
|
||||||
"integrity": "sha512-pdDkMYJeuXLZ6Xj/Q5J3Phpe+jbGdsSzlQaFVkMQzRUL05+6+tetX8TV3p4HrU4kzuO9bt+io/yGQxuyxA/xcw==",
|
"integrity": "sha512-9pU/8mmjSSOb4CXVsvGIevN+MlO/t9OWtKadTaLuN85Gge3HGorUckgp8A/2FH4V4hJ7JuQ3LIeI7KAV9ITZrQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.0",
|
"follow-redirects": "^1.15.0",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
|
@ -2342,9 +2342,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/livekit-client": {
|
"node_modules/livekit-client": {
|
||||||
"version": "1.6.2",
|
"version": "1.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/livekit-client/-/livekit-client-1.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/livekit-client/-/livekit-client-1.6.3.tgz",
|
||||||
"integrity": "sha512-OJIcBY8fzS8tf4vvBL/LNjmEHMFRLivnRjBDjbSiJ8nqV7UB7iSN40RMAejp/OPjhB5ys1u8tt6m3RIXrG2TJA==",
|
"integrity": "sha512-hnVN/rQ9pVWK0L1lemLSOzBI6IXoJepgHP/USqmGJ6eucaoLMx1jK0iMWpR5T2/pg97GmZaUaRSUcXlELNSsoA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async-await-queue": "^1.2.1",
|
"async-await-queue": "^1.2.1",
|
||||||
"events": "^3.3.0",
|
"events": "^3.3.0",
|
||||||
|
@ -2465,9 +2465,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/masto": {
|
"node_modules/masto": {
|
||||||
"version": "5.6.0",
|
"version": "5.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/masto/-/masto-5.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/masto/-/masto-5.6.1.tgz",
|
||||||
"integrity": "sha512-+5t6bSt/V0HyL3hDowxabVszfLjkrKVunhgWXC4LrCBMjMKIOF4vrFJriXSPKOprB6VCZztvGGuy02zSy7oRcQ==",
|
"integrity": "sha512-mQxuOLCWP0TSswZEmmrbHbV2+Olt2N+lr1V2C3FO0QCrPGAhx3KLAXRLArajeGtcVtu66/k8gtTWKksYfkQu5Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mastojs/ponyfills": "^1.0.4",
|
"@mastojs/ponyfills": "^1.0.4",
|
||||||
"change-case": "^4.1.2",
|
"change-case": "^4.1.2",
|
||||||
|
@ -2963,9 +2963,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/protobufjs": {
|
"node_modules/protobufjs": {
|
||||||
"version": "7.1.2",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.0.tgz",
|
||||||
"integrity": "sha512-4ZPTPkXCdel3+L81yw3dG6+Kq3umdWKh7Dc7GW/CpNk4SX3hK58iPCWeCyhVTDrbkNeKrYNZ7EojM5WDaEWTLQ==",
|
"integrity": "sha512-hYCqTDuII4iJ4stZqiuGCSU8xxWl5JeXYpwARGtn/tWcKCAro6h3WQz+xpsNbXW0UYqpmTQFEyFWO0G0Kjt64g==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@protobufjs/aspromise": "^1.1.2",
|
"@protobufjs/aspromise": "^1.1.2",
|
||||||
|
@ -3365,24 +3365,10 @@
|
||||||
"rxjs": "*"
|
"rxjs": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
|
||||||
"version": "4.9.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
|
|
||||||
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
|
||||||
"tsc": "bin/tsc",
|
|
||||||
"tsserver": "bin/tsserver"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ua-parser-js": {
|
"node_modules/ua-parser-js": {
|
||||||
"version": "1.0.32",
|
"version": "1.0.33",
|
||||||
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.32.tgz",
|
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.33.tgz",
|
||||||
"integrity": "sha512-dXVsz3M4j+5tTiovFVyVqssXBu5HM47//YSOeZ9fQkdDKkfzv2v3PP1jmH6FUyPW+yCSn7aBVK1fGGKNhowdDA==",
|
"integrity": "sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
|
|
|
@ -46,6 +46,7 @@ roomReady:
|
||||||
header: "Your room is ready!"
|
header: "Your room is ready!"
|
||||||
message: "Your room \"{title}\" is now ready. Share the following URL with other participants."
|
message: "Your room \"{title}\" is now ready. Share the following URL with other participants."
|
||||||
errors:
|
errors:
|
||||||
|
offline: "This user is offline now."
|
||||||
invalidAddress: "Invalid address"
|
invalidAddress: "Invalid address"
|
||||||
serverNotFound: "Instance not found"
|
serverNotFound: "Instance not found"
|
||||||
notFound: "{value} not found"
|
notFound: "{value} not found"
|
||||||
|
|
|
@ -46,6 +46,7 @@ roomReady:
|
||||||
header: "お部屋の用意ができました!"
|
header: "お部屋の用意ができました!"
|
||||||
message: "{title} を作りました。参加者に以下の URL を共有してください。"
|
message: "{title} を作りました。参加者に以下の URL を共有してください。"
|
||||||
errors:
|
errors:
|
||||||
|
offline: "このユーザーは現在オフラインです。"
|
||||||
invalidAddress: "アドレスが有効ではありません"
|
invalidAddress: "アドレスが有効ではありません"
|
||||||
serverNotFound: "サーバーが見つかりません"
|
serverNotFound: "サーバーが見つかりません"
|
||||||
notFound: "{value} が見つかりません"
|
notFound: "{value} が見つかりません"
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { createRouter, createWebHistory } from "vue-router";
|
import { createRouter, createWebHistory } from "vue-router";
|
||||||
import LoginView from "../views/LoginView.vue";
|
import LoginView from "../views/LoginView.vue";
|
||||||
import RoomView from "../views/RoomView.vue";
|
import RoomView from "../views/RoomView.vue";
|
||||||
import NotFoundView from "../views/NotFoundView.vue";
|
import ErrorView from "../views/ErrorView.vue";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
|
@ -12,7 +13,15 @@ const router = createRouter({
|
||||||
meta: {
|
meta: {
|
||||||
noauth: true,
|
noauth: true,
|
||||||
},
|
},
|
||||||
component: NotFoundView,
|
component: ErrorView,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/error/:type",
|
||||||
|
name: "error",
|
||||||
|
meta: {
|
||||||
|
noauth: true,
|
||||||
|
},
|
||||||
|
component: ErrorView,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
|
@ -40,6 +49,27 @@ const router = createRouter({
|
||||||
},
|
},
|
||||||
component: RoomView,
|
component: RoomView,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/u/:webfinger",
|
||||||
|
name: "currentHosting",
|
||||||
|
meta: {
|
||||||
|
noauth: true,
|
||||||
|
},
|
||||||
|
redirect: async (to) => {
|
||||||
|
try {
|
||||||
|
const resp = await axios.get(`/u/${to.params.webfinger}`);
|
||||||
|
if (resp.status === 302) {
|
||||||
|
return {
|
||||||
|
name: "room",
|
||||||
|
params: { id: resp.headers.location },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
return { name: "notfound" };
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,15 @@ export default {
|
||||||
clipboard: useClipboard(),
|
clipboard: useClipboard(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
async created() {
|
||||||
|
const resp = await axios.get("/api/room");
|
||||||
|
if (resp.data.length > 0) {
|
||||||
|
const canCreate = !some(resp.data, { role: "host" });
|
||||||
|
if (!canCreate) {
|
||||||
|
alert(this.$t("errors.alreadyAdded"));
|
||||||
|
this.$router.replace({ name: "home" });
|
||||||
|
}
|
||||||
|
}
|
||||||
this.cohostSearch = debounce(this.search, 1000);
|
this.cohostSearch = debounce(this.search, 1000);
|
||||||
},
|
},
|
||||||
unmounted() {
|
unmounted() {
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
name: this.$route.name,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
const type = this.$route.params.type;
|
||||||
|
if (!type) return;
|
||||||
|
|
||||||
|
if (type === "offline") {
|
||||||
|
const target = new URL(decodeURI(this.$route.query.url));
|
||||||
|
alert(this.$t("errors.offline"));
|
||||||
|
window.location.href = target.toString();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<v-alert v-if="this.name === 'notfound'" type="error">Page not found</v-alert>
|
||||||
|
</template>
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { useMastodonStore } from "../stores/mastodon";
|
import { useMastodonStore } from "../stores/mastodon";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { some } from "lodash-es";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
@ -10,9 +11,16 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
canCreate: true,
|
||||||
query: "",
|
query: "",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
async created() {
|
||||||
|
const resp = await axios.get("/api/room");
|
||||||
|
if (resp.data.length > 0) {
|
||||||
|
this.canCreate = !some(resp.data, { role: "host" });
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async onLogout() {
|
async onLogout() {
|
||||||
// if (!confirm(this.$t("logoutConfirm"))) return;
|
// if (!confirm(this.$t("logoutConfirm"))) return;
|
||||||
|
@ -63,9 +71,13 @@ export default {
|
||||||
<v-text-field v-mode="query"></v-text-field>
|
<v-text-field v-mode="query"></v-text-field>
|
||||||
</v-col> -->
|
</v-col> -->
|
||||||
<v-col cols="12">
|
<v-col cols="12">
|
||||||
<v-btn block :to="{ name: 'create' }" color="indigo">{{
|
<v-btn
|
||||||
$t("createNewRoom")
|
:disabled="!canCreate"
|
||||||
}}</v-btn>
|
block
|
||||||
|
:to="{ name: 'create' }"
|
||||||
|
color="indigo"
|
||||||
|
>{{ $t("createNewRoom") }}</v-btn
|
||||||
|
>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<script></script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<v-alert type="error">Page not found</v-alert>
|
|
||||||
</template>
|
|
|
@ -557,11 +557,7 @@ export default {
|
||||||
return metadata;
|
return metadata;
|
||||||
},
|
},
|
||||||
async fetchMastoData(identity) {
|
async fetchMastoData(identity) {
|
||||||
if (
|
if (this.roomInfo.accounts[identity] === undefined) return;
|
||||||
this.cachedMastoData[identity] !== undefined ||
|
|
||||||
this.roomInfo.accounts[identity] === undefined
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
try {
|
try {
|
||||||
const resp = await axios.get(`/app/user/${identity}`);
|
const resp = await axios.get(`/app/user/${identity}`);
|
||||||
const account = this.roomInfo.accounts[identity];
|
const account = this.roomInfo.accounts[identity];
|
||||||
|
|
1
auth.go
1
auth.go
|
@ -174,7 +174,6 @@ func oauthHandler(c echo.Context) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Redirect(http.StatusFound, req.Redirect)
|
return c.Redirect(http.StatusFound, req.Redirect)
|
||||||
// return c.Redirect(http.StatusFound, "http://localhost:5173")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUserTokenHandler(c echo.Context) (err error) {
|
func getUserTokenHandler(c echo.Context) (err error) {
|
||||||
|
|
17
room.go
17
room.go
|
@ -35,6 +35,23 @@ func createRoomHandler(c echo.Context) error {
|
||||||
host := c.Get("user").(*AudonUser)
|
host := c.Get("user").(*AudonUser)
|
||||||
room.Host = host
|
room.Host = host
|
||||||
|
|
||||||
|
// check if user is already hosting
|
||||||
|
lkRooms, err := host.GetCurrentLivekitRooms(c.Request().Context())
|
||||||
|
if err != nil {
|
||||||
|
c.Logger().Error(err)
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
for _, r := range lkRooms {
|
||||||
|
meta, err := getRoomMetadataFromLivekitRoom(r)
|
||||||
|
if err != nil {
|
||||||
|
c.Logger().Error(err)
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
if meta.Host.Equal(host) {
|
||||||
|
return ErrOperationNotPermitted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
coll := mainDB.Collection(COLLECTION_ROOM)
|
coll := mainDB.Collection(COLLECTION_ROOM)
|
||||||
|
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
|
|
18
schema.go
18
schema.go
|
@ -133,6 +133,15 @@ func (r *Room) IsHost(u *AudonUser) bool {
|
||||||
return r != nil && r.Host.Equal(u)
|
return r != nil && r.Host.Equal(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *RoomMetadata) IsSpeaker(u *AudonUser) bool {
|
||||||
|
for _, s := range r.Speakers {
|
||||||
|
if s.Equal(u) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func getRoomMetadataFromLivekitRoom(lkRoom *livekit.Room) (*RoomMetadata, error) {
|
func getRoomMetadataFromLivekitRoom(lkRoom *livekit.Room) (*RoomMetadata, error) {
|
||||||
metadata := new(RoomMetadata)
|
metadata := new(RoomMetadata)
|
||||||
if err := json.Unmarshal([]byte(lkRoom.GetMetadata()), metadata); err != nil {
|
if err := json.Unmarshal([]byte(lkRoom.GetMetadata()), metadata); err != nil {
|
||||||
|
@ -240,3 +249,12 @@ func findUserByID(ctx context.Context, audonID string) (*AudonUser, error) {
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findUserByWebfinger(ctx context.Context, webfinger string) (*AudonUser, error) {
|
||||||
|
var result AudonUser
|
||||||
|
coll := mainDB.Collection(COLLECTION_USER)
|
||||||
|
if err := coll.FindOne(ctx, bson.D{{Key: "webfinger", Value: webfinger}}).Decode(&result); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &result, nil
|
||||||
|
}
|
||||||
|
|
|
@ -182,6 +182,7 @@ func main() {
|
||||||
e.Static("/static", "audon-fe/dist/static")
|
e.Static("/static", "audon-fe/dist/static")
|
||||||
e.Static("/storage", mainConfig.StorageDir)
|
e.Static("/storage", mainConfig.StorageDir)
|
||||||
e.GET("/r/:id", renderRoomHandler)
|
e.GET("/r/:id", renderRoomHandler)
|
||||||
|
e.GET("/u/:webfinger", redirectUserHandler)
|
||||||
e.GET("/*", func(c echo.Context) error {
|
e.GET("/*", func(c echo.Context) error {
|
||||||
return c.Render(http.StatusOK, "tmpl", &TemplateData{Config: &mainConfig.AppConfigBase})
|
return c.Render(http.StatusOK, "tmpl", &TemplateData{Config: &mainConfig.AppConfigBase})
|
||||||
})
|
})
|
||||||
|
|
74
user.go
74
user.go
|
@ -2,7 +2,9 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
@ -51,13 +53,56 @@ func getUserHandler(c echo.Context) error {
|
||||||
func getStatusHandler(c echo.Context) error {
|
func getStatusHandler(c echo.Context) error {
|
||||||
u := c.Get("user").(*AudonUser)
|
u := c.Get("user").(*AudonUser)
|
||||||
|
|
||||||
ids, err := u.GetCurrentRoomIDs(c.Request().Context())
|
status, err := u.GetCurrentRoomStatus(c.Request().Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger().Error(err)
|
c.Logger().Error(err)
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError)
|
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, ids)
|
return c.JSON(http.StatusOK, status)
|
||||||
|
}
|
||||||
|
|
||||||
|
func redirectUserHandler(c echo.Context) error {
|
||||||
|
input := c.Param("webfinger")
|
||||||
|
if err := mainValidator.Var(&input, "required,startswith=@,min=4"); err != nil {
|
||||||
|
return wrapValidationError(err)
|
||||||
|
}
|
||||||
|
webfinger := input[1:]
|
||||||
|
if err := mainValidator.Var(&webfinger, "email"); err != nil {
|
||||||
|
return wrapValidationError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := findUserByWebfinger(c.Request().Context(), webfinger)
|
||||||
|
if err != nil || user == nil {
|
||||||
|
return ErrUserNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
rooms, err := user.GetCurrentLivekitRooms(c.Request().Context())
|
||||||
|
if err != nil {
|
||||||
|
c.Logger().Error(err)
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, r := range rooms {
|
||||||
|
meta, err := getRoomMetadataFromLivekitRoom(r)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if meta.Host.Equal(user) {
|
||||||
|
return c.Redirect(http.StatusFound, fmt.Sprintf("/r/%s", r.GetName()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query := make(url.Values)
|
||||||
|
query.Add("url", user.RemoteURL)
|
||||||
|
result := url.URL{
|
||||||
|
Path: "/error/offline",
|
||||||
|
ForceQuery: true,
|
||||||
|
OmitHost: true,
|
||||||
|
RawQuery: query.Encode(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Redirect(http.StatusFound, result.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AudonUser) Equal(u *AudonUser) bool {
|
func (a *AudonUser) Equal(u *AudonUser) bool {
|
||||||
|
@ -90,14 +135,31 @@ func (a *AudonUser) ClearUserAvatar(ctx context.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AudonUser) GetCurrentRoomIDs(ctx context.Context) ([]string, error) {
|
type UserStatus struct {
|
||||||
|
RoomID string `json:"roomID"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AudonUser) GetCurrentRoomStatus(ctx context.Context) ([]UserStatus, error) {
|
||||||
rooms, err := a.GetCurrentLivekitRooms(ctx)
|
rooms, err := a.GetCurrentLivekitRooms(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
roomIDs := make([]string, len(rooms))
|
roomList := make([]UserStatus, len(rooms))
|
||||||
for i, r := range rooms {
|
for i, r := range rooms {
|
||||||
roomIDs[i] = r.GetName()
|
meta, _ := getRoomMetadataFromLivekitRoom(r)
|
||||||
|
role := "listener"
|
||||||
|
if meta.Room.IsHost(a) {
|
||||||
|
role = "host"
|
||||||
|
} else if meta.Room.IsCoHost(a) {
|
||||||
|
role = "cohost"
|
||||||
|
} else if meta.IsSpeaker(a) {
|
||||||
|
role = "speaker"
|
||||||
|
}
|
||||||
|
roomList[i] = UserStatus{
|
||||||
|
RoomID: r.GetName(),
|
||||||
|
Role: role,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return roomIDs, nil
|
return roomList, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,13 +64,13 @@ func livekitWebhookHandler(c echo.Context) error {
|
||||||
<-oldTimer.C
|
<-oldTimer.C
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
countdown := time.NewTimer(10 * time.Second)
|
countdown := time.NewTimer(60 * time.Second)
|
||||||
webhookTimerCache.Set(audonID, countdown, ttlcache.DefaultTTL)
|
webhookTimerCache.Set(audonID, countdown, ttlcache.DefaultTTL)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
<-countdown.C
|
<-countdown.C
|
||||||
webhookTimerCache.Delete(audonID)
|
webhookTimerCache.Delete(audonID)
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
stillAgain, err := user.InLivekit(ctx)
|
stillAgain, err := user.InLivekit(ctx)
|
||||||
|
|
Ładowanie…
Reference in New Issue