mirror of
https://github.com/Pandipipas/scoreko-dev.git
synced 2026-06-06 03:32:06 +00:00
Add start.gg OAuth login flow for local users
This commit is contained in:
@@ -4,7 +4,7 @@ import { useHead } from '@unhead/vue';
|
||||
defineOptions({ name: 'PlayersView' });
|
||||
|
||||
import type { QTableColumn } from 'quasar';
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
||||
import { computed, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue';
|
||||
import { countryOptions, getCountryLabel } from '../../../shared/countries';
|
||||
import type { Schemas } from '../../../types';
|
||||
import { usePlayersStore } from '../stores/players';
|
||||
@@ -96,6 +96,21 @@ const selectedTournament = ref<StartGGTournament | null>(null);
|
||||
const startGGPlayers = ref<StartGGImportedPlayer[]>([]);
|
||||
const selectedStartGGPlayerIds = ref<string[]>([]);
|
||||
|
||||
const oauthLoading = ref(false);
|
||||
const oauthSessionId = ref('');
|
||||
let oauthPollingTimer: ReturnType<typeof setInterval> | null = null;
|
||||
|
||||
interface OAuthSessionResponse {
|
||||
sessionId: string;
|
||||
authUrl: string;
|
||||
}
|
||||
|
||||
interface OAuthStatusResponse {
|
||||
status: 'pending' | 'completed' | 'error' | 'expired';
|
||||
token?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
watch(startGGToken, (value) => {
|
||||
localStorage.setItem(STARTGG_TOKEN_STORAGE_KEY, value);
|
||||
});
|
||||
@@ -111,6 +126,66 @@ const sendNodeCGMessage = <T>(messageName: string, payload: unknown): Promise<T>
|
||||
});
|
||||
});
|
||||
|
||||
const clearOAuthPolling = () => {
|
||||
if (oauthPollingTimer) {
|
||||
clearInterval(oauthPollingTimer);
|
||||
oauthPollingTimer = null;
|
||||
}
|
||||
};
|
||||
|
||||
const checkOAuthStatus = async () => {
|
||||
if (!oauthSessionId.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const status = await sendNodeCGMessage<OAuthStatusResponse>('startgg:getOAuthSessionStatus', {
|
||||
sessionId: oauthSessionId.value,
|
||||
});
|
||||
|
||||
if (status.status === 'completed' && status.token) {
|
||||
startGGToken.value = status.token;
|
||||
oauthLoading.value = false;
|
||||
clearOAuthPolling();
|
||||
oauthSessionId.value = '';
|
||||
tournamentsError.value = '';
|
||||
await loadRecentTournaments();
|
||||
return;
|
||||
}
|
||||
|
||||
if (status.status === 'error' || status.status === 'expired') {
|
||||
oauthLoading.value = false;
|
||||
clearOAuthPolling();
|
||||
oauthSessionId.value = '';
|
||||
tournamentsError.value = status.error || 'No se pudo completar el login OAuth con start.gg.';
|
||||
}
|
||||
} catch (error) {
|
||||
oauthLoading.value = false;
|
||||
clearOAuthPolling();
|
||||
oauthSessionId.value = '';
|
||||
tournamentsError.value = error instanceof Error ? error.message : 'No se pudo verificar el estado OAuth.';
|
||||
}
|
||||
};
|
||||
|
||||
const connectWithStartGGOAuth = async () => {
|
||||
oauthLoading.value = true;
|
||||
tournamentsError.value = '';
|
||||
clearOAuthPolling();
|
||||
|
||||
try {
|
||||
const session = await sendNodeCGMessage<OAuthSessionResponse>('startgg:createOAuthSession', {});
|
||||
oauthSessionId.value = session.sessionId;
|
||||
window.open(session.authUrl, '_blank', 'noopener,noreferrer');
|
||||
|
||||
oauthPollingTimer = setInterval(() => {
|
||||
void checkOAuthStatus();
|
||||
}, 1500);
|
||||
} catch (error) {
|
||||
oauthLoading.value = false;
|
||||
tournamentsError.value = error instanceof Error ? error.message : 'No se pudo iniciar OAuth con start.gg.';
|
||||
}
|
||||
};
|
||||
|
||||
const loadRecentTournaments = async () => {
|
||||
const token = startGGToken.value.trim();
|
||||
if (!token) {
|
||||
@@ -252,6 +327,10 @@ onMounted(() => {
|
||||
void loadRecentTournaments();
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
clearOAuthPolling();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -346,7 +425,7 @@ onMounted(() => {
|
||||
Integración start.gg
|
||||
</div>
|
||||
<div class="text-caption q-mb-md">
|
||||
Pega tu token personal de start.gg para cargar automáticamente tus torneos creados o donde eres admin.
|
||||
Conecta por OAuth (recomendado) o pega tu token personal para cargar tus torneos creados o donde eres admin.
|
||||
</div>
|
||||
<div class="row q-col-gutter-sm items-center">
|
||||
<div class="col-12">
|
||||
@@ -358,6 +437,15 @@ onMounted(() => {
|
||||
type="password"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<QBtn
|
||||
color="primary"
|
||||
icon="login"
|
||||
label="Conectar con start.gg"
|
||||
:loading="oauthLoading"
|
||||
@click="connectWithStartGGOAuth"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<QBtn
|
||||
color="secondary"
|
||||
|
||||
Reference in New Issue
Block a user