diff --git a/backend/endpoints/client_tokens.py b/backend/endpoints/client_tokens.py index 9447a1ad5..325b7d1bc 100644 --- a/backend/endpoints/client_tokens.py +++ b/backend/endpoints/client_tokens.py @@ -1,7 +1,7 @@ import json from fastapi import HTTPException, Request, status -from pydantic import BaseModel +from pydantic import BaseModel, Field from decorators.auth import protected_route from endpoints.responses.client_token import ( @@ -16,6 +16,7 @@ from handler.database import db_client_token_handler from handler.redis_handler import sync_cache from models.client_token import ClientToken from utils.client_tokens import ( + PAIR_CODE_TTL_SECONDS, build_admin_schema, build_create_schema, build_schema, @@ -32,12 +33,11 @@ router = APIRouter( ) MAX_TOKENS_PER_USER = 25 -PAIR_CODE_TTL_SECONDS = 60 class ClientTokenCreatePayload(BaseModel): name: str - scopes: list[str] + scopes: list[str] = Field(min_length=1) expires_in: str | None = None diff --git a/frontend/src/components/Settings/ClientApiTokens/ClientTokensTable.vue b/frontend/src/components/Settings/ClientApiTokens/ClientTokensTable.vue index b52719a13..f529d974c 100644 --- a/frontend/src/components/Settings/ClientApiTokens/ClientTokensTable.vue +++ b/frontend/src/components/Settings/ClientApiTokens/ClientTokensTable.vue @@ -57,10 +57,6 @@ function fetchTokens() { onMounted(fetchTokens); -emitter?.on("showCreateClientTokenDialog", () => { - // Refetch after dialog closes via snackbar events -}); - function onTokenCreated() { fetchTokens(); } diff --git a/frontend/src/components/Settings/ClientApiTokens/Dialog/CreateClientToken.vue b/frontend/src/components/Settings/ClientApiTokens/Dialog/CreateClientToken.vue index 115bb9004..d62ea35a2 100644 --- a/frontend/src/components/Settings/ClientApiTokens/Dialog/CreateClientToken.vue +++ b/frontend/src/components/Settings/ClientApiTokens/Dialog/CreateClientToken.vue @@ -29,7 +29,6 @@ const rawToken = ref(""); const tokenId = ref(null); const pairCode = ref(""); -const pairExpiresIn = ref(0); const pairTimer = ref | null>(null); const pairCountdown = ref(0); const pairStatus = ref<"pending" | "claimed" | "expired">("pending"); @@ -227,7 +226,6 @@ async function startPairing() { try { const { data } = await clientTokenApi.pairToken(tokenId.value); pairCode.value = data.code; - pairExpiresIn.value = data.expires_in; pairCountdown.value = data.expires_in; pairLoading.value = false; @@ -282,7 +280,6 @@ async function regeneratePairCode() { try { const { data } = await clientTokenApi.pairToken(tokenId.value!); pairCode.value = data.code; - pairExpiresIn.value = data.expires_in; pairCountdown.value = data.expires_in; pairLoading.value = false; diff --git a/frontend/src/views/Pair.vue b/frontend/src/views/Pair.vue index 5ba73f382..c11f5dfd7 100644 --- a/frontend/src/views/Pair.vue +++ b/frontend/src/views/Pair.vue @@ -8,8 +8,7 @@ const route = useRoute(); const code = computed(() => (route.query.code as string) || ""); const callback = computed(() => (route.query.callback as string) || ""); -const status = ref<"idle" | "exchanging" | "success" | "error">("idle"); -const rawToken = ref(""); +const status = ref<"idle" | "exchanging" | "error">("idle"); const errorMessage = ref(""); function isCustomScheme(url: string): boolean { @@ -64,7 +63,7 @@ onMounted(async () => { const formattedCode = computed(() => { const c = code.value.replace("-", "").toUpperCase(); if (c.length === 8) return c.slice(0, 4) + "-" + c.slice(4); - return code.value; + return c; });