This commit is contained in:
2025-01-12 17:59:27 +01:00
parent 9dfaa38aa5
commit aebe64829a
5 changed files with 113 additions and 9 deletions

View File

@@ -1,4 +1,4 @@
.authorize__container {
.flex__container__center {
display: flex;
justify-content: center;
align-items: center;
@@ -14,3 +14,16 @@ a.authorize__twitch_btn {
text-decoration: none;
font-size: 1.5rem;
}
.settings__container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
}
.settings__header {
display: flex;
justify-content: end;
}

View File

@@ -8,7 +8,8 @@
{
"imports": {
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.prod.js",
"vue-router": "https://unpkg.com/vue-router@4.5.0/dist/vue-router.esm-browser.prod.js"
"vue-router": "https://unpkg.com/vue-router@4.5.0/dist/vue-router.esm-browser.prod.js",
"jwt-decode": "https://www.unpkg.com/jwt-decode@4.0.0/build/esm/index.js"
}
}
</script>

View File

@@ -1,6 +1,48 @@
import { createApp, ref, onMounted } from 'vue';
import { createRouter, createWebHistory, RouterView, useRouter } from 'vue-router';
import { jwtDecode } from "jwt-decode";
class TokenManager {
static TOKEN_KEY = "token";
static getToken() {
return localStorage.getItem(this.TOKEN_KEY);
}
static getAndValidate() {
const token = this.getToken();
if (token === null) {
return null;
}
let decoded;
try {
decoded = jwtDecode(token);
} catch (e) {
return null;
}
if (decoded.exp < Date.now() / 1000) {
this.removeToken();
return null;
}
return token;
}
static setToken(token) {
localStorage.setItem(this.TOKEN_KEY, token);
}
static removeToken() {
localStorage.removeItem(this.TOKEN_KEY);
}
}
const Authorize = {
setup() {
@@ -19,7 +61,7 @@ const Authorize = {
}
},
template: `
<div class="authorize__container">
<div class="flex__container__center">
<a v-if="loginLink" :href="loginLink" class="authorize__twitch_btn">Login with Twitch</a>
<div v-else>Loading...</div>
</div>
@@ -28,8 +70,24 @@ const Authorize = {
const Settings = {
setup() {
const router = useRouter();
const logout = () => {
TokenManager.removeToken();
router.push('/');
}
return {
logout,
};
},
template: `
<div>Settings</div>
<div class="settings__container">
<div class="settings__header">
<button @click="logout">Logout</button>
</div>
</div>
`
}
@@ -40,7 +98,7 @@ const Main = {
Settings
},
setup() {
const authorized = localStorage.getItem('token') !== null;
const authorized = TokenManager.getAndValidate() !== null;
return {
authorized
@@ -63,14 +121,16 @@ const AuthCallbackTwitch = {
fetch('/api/auth/callback/twitch/' + window.location.search)
.then(response => response.json())
.then(data => {
localStorage.setItem('token', data.token);
localStorage.setItem(TOKEN_KEY, data.token);
router.push('/');
});
});
},
template: `
<div>AuthCallbackTwitch</div>
<div class="flex__container__center">
<div>Loading...</div>
</div>
`
};

View File

@@ -1,5 +1,10 @@
from pydantic import BaseModel
class TwitchSerializer(BaseModel):
id: int
name: str
class StreamerSerializer(BaseModel):
pass
twitch: TwitchSerializer

View File

@@ -2,7 +2,7 @@ from fastapi import APIRouter, Depends
from authx import RequestToken
from modules.web_app.auth.authx import auth
from modules.web_app.serializers.streamer import StreamerSerializer
from modules.web_app.serializers.streamer import StreamerSerializer, TwitchSerializer
from repositories.streamers import StreamerConfigRepository
from repositories.users import UserRepository
from domain.auth import OAuthProvider
@@ -35,3 +35,28 @@ async def get_streamers(
)]
return [StreamerSerializer(**streamer.model_dump()) for streamer in streamers]
@streamer_router.get("/me/")
async def get_me(
token: RequestToken = Depends(RequestToken)
) -> StreamerSerializer:
payload = auth.verify_token(token)
u_id = payload.sub
user = await UserRepository.get(u_id)
twith_oauth = user.oauths.get(OAuthProvider.TWITCH)
if not twith_oauth:
raise Exception("Twitch account not linked")
streamer = await StreamerConfigRepository.get_by_twitch_id(
int(twith_oauth.id)
)
return StreamerSerializer(
twitch=TwitchSerializer(
id=streamer.twitch.id,
name=streamer.twitch.name
)
)