kopia lustrzana https://codeberg.org/nmkj/audon
fix error of signing into mstdn.jp
rodzic
165cee2a6a
commit
b02710d5b1
|
@ -0,0 +1 @@
|
||||||
|
node_modules/
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "audon-fe",
|
"name": "audon-fe",
|
||||||
"version": "0.0.0",
|
"version": "0.1.0-dev",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "audon-fe",
|
"name": "audon-fe",
|
||||||
"version": "0.0.0",
|
"version": "0.1.0-dev",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vuelidate/core": "^2.0.0",
|
"@vuelidate/core": "^2.0.0",
|
||||||
"@vuelidate/validators": "^2.0.0",
|
"@vuelidate/validators": "^2.0.0",
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { RouterView, RouterLink } from 'vue-router'
|
||||||
<h2><RouterLink :to="{name: 'home'}" style="text-decoration: inherit; color: inherit;">Audon</RouterLink></h2>
|
<h2><RouterLink :to="{name: 'home'}" style="text-decoration: inherit; color: inherit;">Audon</RouterLink></h2>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<div style="position:fixed">v0.1.0-dev</div>
|
<div style="position:fixed">v0.1.0-dev2</div>
|
||||||
</v-system-bar>
|
</v-system-bar>
|
||||||
<v-main>
|
<v-main>
|
||||||
<v-container class="fill-height">
|
<v-container class="fill-height">
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { mdiMicrophone, mdiMicrophoneOff } from "@mdi/js";
|
import { mdiMicrophone, mdiMicrophoneOff } from "@mdi/js";
|
||||||
|
import { webfinger } from "../assets/utils";
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
talking: Boolean,
|
talking: Boolean,
|
||||||
|
@ -42,6 +43,9 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
webfinger
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -66,7 +70,7 @@ export default {
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
<h4 :class="canSpeak ? 'mt-1' : 'mt-2'">
|
<h4 :class="canSpeak ? 'mt-1' : 'mt-2'">
|
||||||
<v-icon v-if="canSpeak" :icon="muted ? mdiMicrophoneOff : mdiMicrophone"></v-icon>
|
<v-icon v-if="canSpeak" :icon="muted ? mdiMicrophoneOff : mdiMicrophone"></v-icon>
|
||||||
<a :href="data?.url" target="_blank">{{ data?.displayName }}</a>
|
<a :href="data?.url" target="_blank">{{ data?.displayName ?? webfinger(data) }}</a>
|
||||||
</h4>
|
</h4>
|
||||||
</v-col>
|
</v-col>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -91,7 +91,7 @@ export default {
|
||||||
if (!donURL) return "";
|
if (!donURL) return "";
|
||||||
const url = new URL(donURL);
|
const url = new URL(donURL);
|
||||||
const texts = [
|
const texts = [
|
||||||
`Audon で部屋を作りました!\n視聴リンク: ${this.roomURL}`,
|
`Audon で部屋を作りました!\n参加用リンク: ${this.roomURL}`,
|
||||||
`タイトル:${this.title}`,
|
`タイトル:${this.title}`,
|
||||||
];
|
];
|
||||||
if (this.description)
|
if (this.description)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { useMastodonStore } from "../stores/mastodon";
|
import { useMastodonStore } from "../stores/mastodon";
|
||||||
import { mdiLogout } from "@mdi/js";
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -11,7 +10,6 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
mdiLogout,
|
|
||||||
query: "",
|
query: "",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -40,7 +38,6 @@ export default {
|
||||||
<main>
|
<main>
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<v-btn
|
<v-btn
|
||||||
:append-icon="mdiLogout"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="red"
|
color="red"
|
||||||
@click="onLogout"
|
@click="onLogout"
|
||||||
|
|
|
@ -7,13 +7,13 @@ import Participant from "../components/Participant.vue";
|
||||||
import {
|
import {
|
||||||
mdiMicrophone,
|
mdiMicrophone,
|
||||||
mdiMicrophoneOff,
|
mdiMicrophoneOff,
|
||||||
mdiPhoneRemove,
|
|
||||||
mdiMicrophoneQuestion,
|
mdiMicrophoneQuestion,
|
||||||
mdiDoorClosed,
|
mdiDoorClosed,
|
||||||
mdiVolumeOff,
|
mdiVolumeOff,
|
||||||
mdiClose,
|
mdiClose,
|
||||||
mdiCheck,
|
mdiCheck,
|
||||||
mdiAccountVoice,
|
mdiAccountVoice,
|
||||||
|
mdiLogout
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import {
|
import {
|
||||||
Room,
|
Room,
|
||||||
|
@ -51,10 +51,10 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
mdiLogout,
|
||||||
mdiAccountVoice,
|
mdiAccountVoice,
|
||||||
mdiMicrophone,
|
mdiMicrophone,
|
||||||
mdiMicrophoneOff,
|
mdiMicrophoneOff,
|
||||||
mdiPhoneRemove,
|
|
||||||
mdiMicrophoneQuestion,
|
mdiMicrophoneQuestion,
|
||||||
mdiDoorClosed,
|
mdiDoorClosed,
|
||||||
mdiVolumeOff,
|
mdiVolumeOff,
|
||||||
|
@ -358,7 +358,7 @@ export default {
|
||||||
await this.publishDataToHostAndCohosts(data);
|
await this.publishDataToHostAndCohosts(data);
|
||||||
},
|
},
|
||||||
async requestSpeak() {
|
async requestSpeak() {
|
||||||
if (confirm("通話をリクエストしますか?")) {
|
if (confirm("発言をリクエストしますか?")) {
|
||||||
await this.publishDataToHostAndCohosts({ kind: "speak_request" });
|
await this.publishDataToHostAndCohosts({ kind: "speak_request" });
|
||||||
this.showRequestedNotification = true;
|
this.showRequestedNotification = true;
|
||||||
}
|
}
|
||||||
|
@ -476,7 +476,7 @@ export default {
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
<v-dialog v-model="showRequestDialog" max-width="500">
|
<v-dialog v-model="showRequestDialog" max-width="500">
|
||||||
<v-card max-height="600" class="d-flex flex-column">
|
<v-card max-height="600" class="d-flex flex-column">
|
||||||
<v-card-title>通話リクエスト</v-card-title>
|
<v-card-title>発言リクエスト</v-card-title>
|
||||||
<v-card-text class="flex-grow-1 overflow-auto py-0">
|
<v-card-text class="flex-grow-1 overflow-auto py-0">
|
||||||
<v-list v-if="speakRequests.size > 0" lines="two" variant="tonal">
|
<v-list v-if="speakRequests.size > 0" lines="two" variant="tonal">
|
||||||
<v-list-item
|
<v-list-item
|
||||||
|
@ -531,7 +531,7 @@ export default {
|
||||||
v-model="showRequestedNotification"
|
v-model="showRequestedNotification"
|
||||||
color="info"
|
color="info"
|
||||||
>
|
>
|
||||||
<strong>通話リクエストを送信しました!</strong>
|
<strong>発言リクエストを送信しました!</strong>
|
||||||
<template v-slot:actions>
|
<template v-slot:actions>
|
||||||
<v-btn
|
<v-btn
|
||||||
variant="text"
|
variant="text"
|
||||||
|
@ -554,7 +554,7 @@ export default {
|
||||||
showRequestNotification = false;
|
showRequestNotification = false;
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<strong>新しい通話リクエストがあります</strong>
|
<strong>新しい発言リクエストがあります</strong>
|
||||||
</div>
|
</div>
|
||||||
<template v-slot:actions>
|
<template v-slot:actions>
|
||||||
<v-btn
|
<v-btn
|
||||||
|
@ -588,7 +588,7 @@ export default {
|
||||||
style="height: 100px"
|
style="height: 100px"
|
||||||
>
|
>
|
||||||
<v-container class="py-0">
|
<v-container class="py-0">
|
||||||
<pre class="text-body-1">{{ roomInfo.description }}</pre>
|
<p style="white-space: pre-wrap;">{{ roomInfo.description }}</p>
|
||||||
</v-container>
|
</v-container>
|
||||||
</div>
|
</div>
|
||||||
<v-divider></v-divider>
|
<v-divider></v-divider>
|
||||||
|
@ -638,7 +638,7 @@ export default {
|
||||||
@click="onToggleMute"
|
@click="onToggleMute"
|
||||||
></v-btn>
|
></v-btn>
|
||||||
<v-btn
|
<v-btn
|
||||||
:icon="mdiPhoneRemove"
|
:icon="mdiLogout"
|
||||||
color="red"
|
color="red"
|
||||||
@click="roomClient.disconnect()"
|
@click="roomClient.disconnect()"
|
||||||
variant="flat"
|
variant="flat"
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
# Use root/example as user/password credentials
|
||||||
|
version: '3.1'
|
||||||
|
|
||||||
|
services:
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: mongo:6
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "27017:27017"
|
||||||
|
environment:
|
||||||
|
MONGO_INITDB_ROOT_USERNAME: mongo
|
||||||
|
MONGO_INITDB_ROOT_PASSWORD: mongo
|
||||||
|
# volumes:
|
||||||
|
# - ./mongo:/data/db
|
||||||
|
|
||||||
|
mongo-express:
|
||||||
|
image: mongo-express
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- 8081:8081
|
||||||
|
environment:
|
||||||
|
ME_CONFIG_MONGODB_ADMINUSERNAME:
|
||||||
|
ME_CONFIG_MONGODB_ADMINPASSWORD: example
|
||||||
|
ME_CONFIG_MONGODB_URL: mongodb://mongo:mongo@db:27017/
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
command: redis-server
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
# volumes:
|
||||||
|
# - ./redis:/data
|
||||||
|
# - ./config/redis.conf:/etc/redis.conf
|
||||||
|
|
||||||
|
redisinsight:
|
||||||
|
image: redislabs/redisinsight:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- 8001:8001
|
||||||
|
# volumes:
|
||||||
|
# - redisinsight:/db
|
|
@ -18,9 +18,9 @@ services:
|
||||||
# ports:
|
# ports:
|
||||||
# - 8081:8081
|
# - 8081:8081
|
||||||
# environment:
|
# environment:
|
||||||
# ME_CONFIG_MONGODB_ADMINUSERNAME: root
|
# ME_CONFIG_MONGODB_ADMINUSERNAME:
|
||||||
# ME_CONFIG_MONGODB_ADMINPASSWORD: example
|
# ME_CONFIG_MONGODB_ADMINPASSWORD: example
|
||||||
# ME_CONFIG_MONGODB_URL: mongodb://root:example@mongo:27017/
|
# ME_CONFIG_MONGODB_URL: mongodb://mongo:mongo@db:27017/
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
|
|
5
oauth.go
5
oauth.go
|
@ -22,6 +22,7 @@ func verifyTokenInSession(c echo.Context) (bool, *mastodon.Account, error) {
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
}
|
}
|
||||||
mastoClient := mastodon.NewClient(data.MastodonConfig)
|
mastoClient := mastodon.NewClient(data.MastodonConfig)
|
||||||
|
mastoClient.UserAgent = USER_AGENT
|
||||||
|
|
||||||
acc, err := mastoClient.GetAccountCurrentUser(c.Request().Context())
|
acc, err := mastoClient.GetAccountCurrentUser(c.Request().Context())
|
||||||
user, dbErr := findUserByID(c.Request().Context(), data.AudonID)
|
user, dbErr := findUserByID(c.Request().Context(), data.AudonID)
|
||||||
|
@ -64,7 +65,8 @@ func loginHandler(c echo.Context) (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrInvalidRequestFormat
|
return ErrInvalidRequestFormat
|
||||||
}
|
}
|
||||||
mastApp, err := mastodon.RegisterApp(c.Request().Context(), appConfig)
|
// mastApp, err := mastodon.RegisterApp(c.Request().Context(), appConfig)
|
||||||
|
mastApp, err := registerApp(c.Request().Context(), appConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger().Error(err)
|
c.Logger().Error(err)
|
||||||
return echo.NewHTTPError(http.StatusNotFound, "server_not_found")
|
return echo.NewHTTPError(http.StatusNotFound, "server_not_found")
|
||||||
|
@ -122,6 +124,7 @@ func oauthHandler(c echo.Context) (err error) {
|
||||||
|
|
||||||
data.AuthCode = req.Code
|
data.AuthCode = req.Code
|
||||||
client := mastodon.NewClient(data.MastodonConfig)
|
client := mastodon.NewClient(data.MastodonConfig)
|
||||||
|
client.UserAgent = USER_AGENT
|
||||||
err = client.AuthenticateToken(c.Request().Context(), req.Code, appConf.RedirectURIs)
|
err = client.AuthenticateToken(c.Request().Context(), req.Code, appConf.RedirectURIs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return echo.NewHTTPError(http.StatusForbidden, err.Error())
|
return echo.NewHTTPError(http.StatusForbidden, err.Error())
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
mastodon "github.com/mattn/go-mastodon"
|
||||||
|
)
|
||||||
|
|
||||||
|
const USER_AGENT = "Audon/0.1.0"
|
||||||
|
|
||||||
|
// RegisterApp returns the mastodon application.
|
||||||
|
func registerApp(ctx context.Context, appConfig *mastodon.AppConfig) (*mastodon.Application, error) {
|
||||||
|
params := url.Values{}
|
||||||
|
params.Set("client_name", appConfig.ClientName)
|
||||||
|
if appConfig.RedirectURIs == "" {
|
||||||
|
params.Set("redirect_uris", "urn:ietf:wg:oauth:2.0:oob")
|
||||||
|
} else {
|
||||||
|
params.Set("redirect_uris", appConfig.RedirectURIs)
|
||||||
|
}
|
||||||
|
params.Set("scopes", appConfig.Scopes)
|
||||||
|
params.Set("website", appConfig.Website)
|
||||||
|
|
||||||
|
u, err := url.Parse(appConfig.Server)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u.Path = path.Join(u.Path, "/api/v1/apps")
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(params.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req = req.WithContext(ctx)
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
req.Header.Set("User-Agent", USER_AGENT)
|
||||||
|
resp, err := appConfig.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, errors.New("bad request")
|
||||||
|
}
|
||||||
|
|
||||||
|
var app mastodon.Application
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(&app)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err = url.Parse(appConfig.Server)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u.Path = path.Join(u.Path, "/oauth/authorize")
|
||||||
|
u.RawQuery = url.Values{
|
||||||
|
"scope": {appConfig.Scopes},
|
||||||
|
"response_type": {"code"},
|
||||||
|
"redirect_uri": {app.RedirectURI},
|
||||||
|
"client_id": {app.ClientID},
|
||||||
|
}.Encode()
|
||||||
|
|
||||||
|
app.AuthURI = u.String()
|
||||||
|
|
||||||
|
return &app, nil
|
||||||
|
}
|
Ładowanie…
Reference in New Issue